This commit is contained in:
Jesper Wilhelmsson 2017-08-28 21:46:12 +02:00
commit 70abf95350
2923 changed files with 171987 additions and 76585 deletions

View File

@ -444,3 +444,4 @@ e6d70017f5b9adbb2ec82d826973d0251800a3c3 jdk-10+12
7db699468b4f84abbcc01647e5a964409737411a jdk-10+17
3739654290616e533fc6f51bf9ad69ed47a6abba jdk-10+18
14df107500cc3b8ab238c3e4ad2c74e12bfe6067 jdk-10+19
4586bc5d28d13d3147b993e6237eaf29a7073bbb jdk-10+20

View File

@ -445,3 +445,4 @@ b803e6cff41e72a1e6d8782e1ef7c25a6e3e5ee3 jdk-10+19
d2982a786f53814367698e63efe6349c9128e1db jdk-9+180
b656dea9398ef601f7fc08d1a5157a560e0ccbe0 jdk-9+181
682e2a6df836f4731f92eb2ddcd467075047f6ea jdk-10+20
90cdfe56f1543267a8005e638bd1b44551fda189 jdk-10+21

View File

@ -444,3 +444,4 @@ a923b3f30e7bddb4f960059ddfc7978fc63e2e6e jdk-10+18
28488561cfbcfa4d0d9c489e8afe0155f4231360 jdk-10+19
6ce6cb8ff41c71c49f23b15e0f0468aca5d52b17 jdk-9+180
ba71941ad9dba53b8fffb30602ef673eee88696c jdk-9+181
7a54ec280513a33e49e60546c0cf9ca573925a43 jdk-10+20

View File

@ -604,3 +604,4 @@ c9d3317623d48da3327232c81e3f8cfc0d29d888 jdk-10+18
33b74e13c1457f36041addb8b850831f81ca6e9f jdk-10+19
d7baadc223e790c08bc69bf7e553bce65b4e7e40 jdk-9+180
4a443796f6f57842d6a0434ac27ca3d1033ccc20 jdk-9+181
e93ed1a092409351c90b3a76d80b9aa8b44d5e6a jdk-10+20

View File

@ -47,11 +47,10 @@ ifeq ($(INCLUDE_GRAAL), true)
$(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_MATCH_PROCESSOR, \
SETUP := GENERATE_OLDBYTECODE, \
SRC := \
$(SRC_DIR)/org.graalvm.compiler.common/src \
$(SRC_DIR)/org.graalvm.word/src \
$(SRC_DIR)/org.graalvm.compiler.core/src \
$(SRC_DIR)/org.graalvm.compiler.core.common/src \
$(SRC_DIR)/org.graalvm.compiler.core.match.processor/src \
$(SRC_DIR)/org.graalvm.compiler.api.collections/src \
$(SRC_DIR)/org.graalvm.compiler.api.replacements/src \
$(SRC_DIR)/org.graalvm.compiler.asm/src \
$(SRC_DIR)/org.graalvm.compiler.bytecode/src \
@ -68,6 +67,7 @@ ifeq ($(INCLUDE_GRAAL), true)
$(SRC_DIR)/org.graalvm.compiler.phases.common/src \
$(SRC_DIR)/org.graalvm.compiler.serviceprovider/src \
$(SRC_DIR)/org.graalvm.compiler.virtual/src \
$(SRC_DIR)/org.graalvm.util/src \
$(VM_CI_SRC_DIR)/jdk.vm.ci.code/src \
$(VM_CI_SRC_DIR)/jdk.vm.ci.common/src \
$(VM_CI_SRC_DIR)/jdk.vm.ci.meta/src \
@ -102,6 +102,7 @@ ifeq ($(INCLUDE_GRAAL), true)
SRC := \
$(SRC_DIR)/org.graalvm.compiler.options/src \
$(SRC_DIR)/org.graalvm.compiler.options.processor/src \
$(SRC_DIR)/org.graalvm.util/src \
, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.compiler.options.processor, \
JAR := $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.compiler.options.processor.jar, \
@ -114,9 +115,8 @@ ifeq ($(INCLUDE_GRAAL), true)
$(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_REPLACEMENTS_VERIFIER, \
SETUP := GENERATE_OLDBYTECODE, \
SRC := \
$(SRC_DIR)/org.graalvm.compiler.common/src \
$(SRC_DIR)/org.graalvm.word/src \
$(SRC_DIR)/org.graalvm.compiler.replacements.verifier/src \
$(SRC_DIR)/org.graalvm.compiler.api.collections/src \
$(SRC_DIR)/org.graalvm.compiler.api.replacements/src \
$(SRC_DIR)/org.graalvm.compiler.code/src \
$(SRC_DIR)/org.graalvm.compiler.core.common/src \
@ -125,6 +125,7 @@ ifeq ($(INCLUDE_GRAAL), true)
$(SRC_DIR)/org.graalvm.compiler.nodeinfo/src \
$(SRC_DIR)/org.graalvm.compiler.options/src \
$(SRC_DIR)/org.graalvm.compiler.serviceprovider/src \
$(SRC_DIR)/org.graalvm.util/src \
$(VM_CI_SRC_DIR)/jdk.vm.ci.code/src \
$(VM_CI_SRC_DIR)/jdk.vm.ci.common/src \
$(VM_CI_SRC_DIR)/jdk.vm.ci.meta/src \

View File

@ -37,7 +37,6 @@ SRC_DIR := $(HOTSPOT_TOPDIR)/src/$(MODULE)/share/classes
PROC_SRC_SUBDIRS := \
org.graalvm.compiler.code \
org.graalvm.compiler.common \
org.graalvm.compiler.core \
org.graalvm.compiler.core.aarch64 \
org.graalvm.compiler.core.amd64 \

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2013, 2017, 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
@ -73,7 +73,7 @@ ifeq ($(call check-jvm-feature, compiler2), true)
OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/adlc, \
PROGRAM := adlc, \
DEBUG_SYMBOLS := false, \
DISABLED_WARNINGS_clang := parentheses tautological-compare, \
DISABLED_WARNINGS_clang := tautological-compare, \
DISABLED_WARNINGS_solstudio := notemsource, \
))

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2013, 2017, 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
@ -52,7 +52,7 @@ ifeq ($(call check-jvm-feature, dtrace), true)
CXX := $(BUILD_CXX), \
LDEXE := $(BUILD_CXX), \
generateJvmOffsets.cpp_CXXFLAGS := $(JVM_CFLAGS) -mt -xnolib -norunpath, \
generateJvmOffsetsMain.c_CFLAGS := -library=%none -mt -m64 -norunpath -z nodefs, \
generateJvmOffsetsMain.c_CFLAGS := -mt -m64 -norunpath -z nodefs, \
LDFLAGS := -m64, \
LIBS := -lc, \
OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets/objs, \

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2016, 2017, 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
@ -52,7 +52,8 @@ else
$(call create-mapfile)
endif
# Disabling switch warning for clang because of test source.
# Disabling undef, switch, format-nonliteral and tautological-undefined-compare
# warnings for clang because of test source.
# Note: On AIX, the gtest test classes linked into the libjvm.so push the TOC
# size beyond 64k, so we need to link with bigtoc. However, this means that

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2013, 2017, 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
@ -69,6 +69,7 @@ JVM_CFLAGS_TARGET_DEFINES += \
-DTARGET_ARCH_$(HOTSPOT_TARGET_CPU_ARCH) \
-DINCLUDE_SUFFIX_OS=_$(HOTSPOT_TARGET_OS) \
-DINCLUDE_SUFFIX_CPU=_$(HOTSPOT_TARGET_CPU_ARCH) \
-DINCLUDE_SUFFIX_COMPILER=_$(HOTSPOT_TOOLCHAIN_TYPE) \
-DTARGET_COMPILER_$(HOTSPOT_TOOLCHAIN_TYPE) \
-D$(HOTSPOT_TARGET_CPU_DEFINE) \
-DHOTSPOT_LIB_ARCH='"$(OPENJDK_TARGET_CPU_LEGACY_LIB)"' \
@ -217,9 +218,7 @@ $(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \
CFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
CXXFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
vm_version.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
DISABLED_WARNINGS_clang := delete-non-virtual-dtor dynamic-class-memaccess \
empty-body format logical-op-parentheses parentheses \
parentheses-equality switch tautological-compare, \
DISABLED_WARNINGS_clang := tautological-compare, \
DISABLED_WARNINGS_xlc := 1540-0216 1540-0198 1540-1090 1540-1639 \
1540-1088 1500-010, \
ASFLAGS := $(JVM_ASFLAGS), \

View File

@ -1,53 +0,0 @@
#
# Copyright (c) 2016, 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.
#
include $(SPEC)
include NativeCompilation.gmk
$(eval $(call IncludeCustomExtension, hotspot, lib/Lib-jdk.aot.gmk))
##############################################################################
# Build libjelfshim only when AOT is enabled.
ifeq ($(ENABLE_AOT), true)
JELFSHIM_NAME := jelfshim
$(eval $(call SetupNativeCompilation, BUILD_LIBJELFSHIM, \
TOOLCHAIN := TOOLCHAIN_DEFAULT, \
OPTIMIZATION := LOW, \
LIBRARY := $(JELFSHIM_NAME), \
OUTPUT_DIR := $(call FindLibDirForModule, $(MODULE)), \
SRC := $(HOTSPOT_TOPDIR)/src/jdk.aot/unix/native/libjelfshim, \
CFLAGS := $(CFLAGS_JDKLIB) $(ELF_CFLAGS) \
-DAOT_VERSION_STRING='"$(VERSION_STRING)"' \
-I$(SUPPORT_OUTPUTDIR)/headers/$(MODULE), \
LDFLAGS := $(LDFLAGS_JDKLIB), \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/lib$(JELFSHIM_NAME), \
LIBS := $(ELF_LIBS) $(LIBS_JDKLIB), \
))
TARGETS += $(BUILD_LIBJELFSHIM)
endif
##############################################################################

View File

@ -35,12 +35,17 @@ include $(SPEC)
include MakeBase.gmk
include TestFilesCompilation.gmk
$(eval $(call IncludeCustomExtension, hotspot, test/JtregNative.gmk))
################################################################################
# Targets for building the native tests themselves.
################################################################################
# Add more directories here when needed.
BUILD_HOTSPOT_JTREG_NATIVE_SRC := \
BUILD_HOTSPOT_JTREG_NATIVE_SRC += \
$(HOTSPOT_TOPDIR)/test/gc/g1/TestJNIWeakG1 \
$(HOTSPOT_TOPDIR)/test/gc/stress/gclocker \
$(HOTSPOT_TOPDIR)/test/gc/cslocker \
$(HOTSPOT_TOPDIR)/test/native_sanity \
$(HOTSPOT_TOPDIR)/test/runtime/jni/8025979 \
$(HOTSPOT_TOPDIR)/test/runtime/jni/8033445 \
@ -53,8 +58,10 @@ BUILD_HOTSPOT_JTREG_NATIVE_SRC := \
$(HOTSPOT_TOPDIR)/test/runtime/modules/getModuleJNI \
$(HOTSPOT_TOPDIR)/test/runtime/SameObject \
$(HOTSPOT_TOPDIR)/test/runtime/BoolReturn \
$(HOTSPOT_TOPDIR)/test/runtime/noClassDefFoundMsg \
$(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \
$(HOTSPOT_TOPDIR)/test/compiler/calls \
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/GetOwnedMonitorInfo \
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/GetNamedModule \
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/IsModifiableModule \
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/AddModuleReads \
@ -66,6 +73,7 @@ BUILD_HOTSPOT_JTREG_NATIVE_SRC := \
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook \
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare \
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/ModuleAwareAgents/ThreadStart \
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/StartPhase/AllowedFunctions \
#
# Add conditional directories here when needed.
@ -85,6 +93,7 @@ endif
ifeq ($(TOOLCHAIN_TYPE), solstudio)
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_liboverflow := -lc
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libSimpleClassFileLoadHook := -lc
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libGetOwnedMonitorInfoTest := -lc
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libGetNamedModuleTest := -lc
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libIsModifiableModuleTest := -lc
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleReadsTest := -lc
@ -93,6 +102,7 @@ ifeq ($(TOOLCHAIN_TYPE), solstudio)
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMAAClassFileLoadHook := -lc
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMAAClassLoadPrepare := -lc
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMAAThreadStart := -lc
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libAllowedFunctions := -lc
endif
ifeq ($(OPENJDK_TARGET_OS), linux)

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2014, Red Hat Inc. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
@ -3564,7 +3564,7 @@ const int Matcher::min_vector_size(const BasicType bt) {
}
// Vector ideal reg.
const int Matcher::vector_ideal_reg(int len) {
const uint Matcher::vector_ideal_reg(int len) {
switch(len) {
case 8: return Op_VecD;
case 16: return Op_VecX;
@ -3573,7 +3573,7 @@ const int Matcher::vector_ideal_reg(int len) {
return 0;
}
const int Matcher::vector_shift_count_ideal_reg(int size) {
const uint Matcher::vector_shift_count_ideal_reg(int size) {
return Op_VecX;
}
@ -5218,7 +5218,7 @@ frame %{
// ppc port uses 0 but we definitely need to allow for fixed_slots
// which folds in the space used for monitors
return_addr(STACK - 2 +
round_to((Compile::current()->in_preserve_stack_slots() +
align_up((Compile::current()->in_preserve_stack_slots() +
Compile::current()->fixed_slots()),
stack_alignment_in_slots()));
@ -5343,6 +5343,17 @@ operand immI_M1()
interface(CONST_INTER);
%}
// Shift values for add/sub extension shift
operand immIExt()
%{
predicate(0 <= n->get_int() && (n->get_int() <= 4));
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand immI_le_4()
%{
predicate(n->get_int() <= 4);
@ -5423,6 +5434,16 @@ operand immI_56()
interface(CONST_INTER);
%}
operand immI_63()
%{
predicate(n->get_int() == 63);
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand immI_64()
%{
predicate(n->get_int() == 64);
@ -5453,20 +5474,10 @@ operand immI_65535()
interface(CONST_INTER);
%}
operand immL_63()
%{
predicate(n->get_int() == 63);
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand immL_255()
%{
predicate(n->get_int() == 255);
match(ConI);
predicate(n->get_long() == 255L);
match(ConL);
op_cost(0);
format %{ %}
@ -10951,7 +10962,7 @@ instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{
// Long Negation
instruct negL_reg(iRegLNoSp dst, iRegIorL2I src, immL0 zero, rFlagsReg cr) %{
instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{
match(Set dst (SubL zero src));
ins_cost(INSN_COST);
@ -11146,7 +11157,7 @@ instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
ins_pipe(ldiv_reg_reg);
%}
instruct signExtractL(iRegLNoSp dst, iRegL src1, immL_63 div1, immL_63 div2) %{
instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{
match(Set dst (URShiftL (RShiftL src1 div1) div2));
ins_cost(INSN_COST);
format %{ "lsr $dst, $src1, $div1" %}
@ -11156,7 +11167,7 @@ instruct signExtractL(iRegLNoSp dst, iRegL src1, immL_63 div1, immL_63 div2) %{
ins_pipe(ialu_reg_shift);
%}
instruct div2RoundL(iRegLNoSp dst, iRegL src, immL_63 div1, immL_63 div2) %{
instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{
match(Set dst (AddL src (URShiftL (RShiftL src div1) div2)));
ins_cost(INSN_COST);
format %{ "add $dst, $src, $div1" %}
@ -12789,7 +12800,7 @@ instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
%{
match(Set dst (AddL src1 (ConvI2L src2)));
ins_cost(INSN_COST);
format %{ "add $dst, $src1, sxtw $src2" %}
format %{ "add $dst, $src1, $src2, sxtw" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
@ -12802,7 +12813,7 @@ instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
%{
match(Set dst (SubL src1 (ConvI2L src2)));
ins_cost(INSN_COST);
format %{ "sub $dst, $src1, sxtw $src2" %}
format %{ "sub $dst, $src1, $src2, sxtw" %}
ins_encode %{
__ sub(as_Register($dst$$reg), as_Register($src1$$reg),
@ -12816,7 +12827,7 @@ instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 l
%{
match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
ins_cost(INSN_COST);
format %{ "add $dst, $src1, sxth $src2" %}
format %{ "add $dst, $src1, $src2, sxth" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
@ -12829,7 +12840,7 @@ instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 l
%{
match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
ins_cost(INSN_COST);
format %{ "add $dst, $src1, sxtb $src2" %}
format %{ "add $dst, $src1, $src2, sxtb" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
@ -12842,7 +12853,7 @@ instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 l
%{
match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift)));
ins_cost(INSN_COST);
format %{ "add $dst, $src1, uxtb $src2" %}
format %{ "add $dst, $src1, $src2, uxtb" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
@ -12855,7 +12866,7 @@ instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, imm
%{
match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
ins_cost(INSN_COST);
format %{ "add $dst, $src1, sxth $src2" %}
format %{ "add $dst, $src1, $src2, sxth" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
@ -12868,7 +12879,7 @@ instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, imm
%{
match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
ins_cost(INSN_COST);
format %{ "add $dst, $src1, sxtw $src2" %}
format %{ "add $dst, $src1, $src2, sxtw" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
@ -12881,7 +12892,7 @@ instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, imm
%{
match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
ins_cost(INSN_COST);
format %{ "add $dst, $src1, sxtb $src2" %}
format %{ "add $dst, $src1, $src2, sxtb" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
@ -12894,7 +12905,7 @@ instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, imm
%{
match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift)));
ins_cost(INSN_COST);
format %{ "add $dst, $src1, uxtb $src2" %}
format %{ "add $dst, $src1, $src2, uxtb" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
@ -13034,6 +13045,294 @@ instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295
ins_pipe(ialu_reg_reg);
%}
instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
%{
match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
ins_cost(1.9 * INSN_COST);
format %{ "add $dst, $src1, $src2, sxtb #lshift2" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
%{
match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
ins_cost(1.9 * INSN_COST);
format %{ "add $dst, $src1, $src2, sxth #lshift2" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
%{
match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
ins_cost(1.9 * INSN_COST);
format %{ "add $dst, $src1, $src2, sxtw #lshift2" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
%{
match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
ins_cost(1.9 * INSN_COST);
format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %}
ins_encode %{
__ sub(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
%{
match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
ins_cost(1.9 * INSN_COST);
format %{ "sub $dst, $src1, $src2, sxth #lshift2" %}
ins_encode %{
__ sub(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
%{
match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
ins_cost(1.9 * INSN_COST);
format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %}
ins_encode %{
__ sub(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
%{
match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
ins_cost(1.9 * INSN_COST);
format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %}
ins_encode %{
__ addw(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
%{
match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
ins_cost(1.9 * INSN_COST);
format %{ "addw $dst, $src1, $src2, sxth #lshift2" %}
ins_encode %{
__ addw(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
%{
match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
ins_cost(1.9 * INSN_COST);
format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %}
ins_encode %{
__ subw(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
%{
match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
ins_cost(1.9 * INSN_COST);
format %{ "subw $dst, $src1, $src2, sxth #lshift2" %}
ins_encode %{
__ subw(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "add $dst, $src1, $src2, sxtw #lshift" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%};
instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "sub $dst, $src1, $src2, sxtw #lshift" %}
ins_encode %{
__ sub(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%};
instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "add $dst, $src1, $src2, uxtb #lshift" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "add $dst, $src1, $src2, uxth #lshift" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "add $dst, $src1, $src2, uxtw #lshift" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "sub $dst, $src1, $src2, uxtb #lshift" %}
ins_encode %{
__ sub(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "sub $dst, $src1, $src2, uxth #lshift" %}
ins_encode %{
__ sub(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "sub $dst, $src1, $src2, uxtw #lshift" %}
ins_encode %{
__ sub(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "addw $dst, $src1, $src2, uxtb #lshift" %}
ins_encode %{
__ addw(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "addw $dst, $src1, $src2, uxth #lshift" %}
ins_encode %{
__ addw(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "subw $dst, $src1, $src2, uxtb #lshift" %}
ins_encode %{
__ subw(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
%{
match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "subw $dst, $src1, $src2, uxth #lshift" %}
ins_encode %{
__ subw(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}
// END This section of the file is automatically generated. Do not edit --------------
// ============================================================================
@ -15443,9 +15742,9 @@ instruct ShouldNotReachHere() %{
format %{ "ShouldNotReachHere" %}
ins_encode %{
// TODO
// implement proper trap call here
__ brk(999);
// +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't
// return true
__ dpcs1(0xdead + 1);
%}
ins_pipe(pipe_class_default);
@ -15803,6 +16102,16 @@ instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
ins_pipe(pipe_class_memory);
%}
instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr)
%{
match(Set result (HasNegatives ary1 len));
effect(USE_KILL ary1, USE_KILL len, KILL cr);
format %{ "has negatives byte[] $ary1,$len -> $result" %}
ins_encode %{
__ has_negatives($ary1$$Register, $len$$Register, $result$$Register);
%}
ins_pipe( pipe_slow );
%}
// fast char[] to byte[] compression
instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
@ -16833,6 +17142,48 @@ instruct vmla4I(vecX dst, vecX src1, vecX src2)
ins_pipe(vmla128);
%}
// dst + src1 * src2
instruct vmla2F(vecD dst, vecD src1, vecD src2) %{
predicate(UseFMA && n->as_Vector()->length() == 2);
match(Set dst (FmaVF dst (Binary src1 src2)));
format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %}
ins_cost(INSN_COST);
ins_encode %{
__ fmla(as_FloatRegister($dst$$reg), __ T2S,
as_FloatRegister($src1$$reg),
as_FloatRegister($src2$$reg));
%}
ins_pipe(vmuldiv_fp64);
%}
// dst + src1 * src2
instruct vmla4F(vecX dst, vecX src1, vecX src2) %{
predicate(UseFMA && n->as_Vector()->length() == 4);
match(Set dst (FmaVF dst (Binary src1 src2)));
format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %}
ins_cost(INSN_COST);
ins_encode %{
__ fmla(as_FloatRegister($dst$$reg), __ T4S,
as_FloatRegister($src1$$reg),
as_FloatRegister($src2$$reg));
%}
ins_pipe(vmuldiv_fp128);
%}
// dst + src1 * src2
instruct vmla2D(vecX dst, vecX src1, vecX src2) %{
predicate(UseFMA && n->as_Vector()->length() == 2);
match(Set dst (FmaVD dst (Binary src1 src2)));
format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %}
ins_cost(INSN_COST);
ins_encode %{
__ fmla(as_FloatRegister($dst$$reg), __ T2D,
as_FloatRegister($src1$$reg),
as_FloatRegister($src2$$reg));
%}
ins_pipe(vmuldiv_fp128);
%}
// --------------------------------- MLS --------------------------------------
instruct vmls4S(vecD dst, vecD src1, vecD src2)
@ -16892,6 +17243,51 @@ instruct vmls4I(vecX dst, vecX src1, vecX src2)
ins_pipe(vmla128);
%}
// dst - src1 * src2
instruct vmls2F(vecD dst, vecD src1, vecD src2) %{
predicate(UseFMA && n->as_Vector()->length() == 2);
match(Set dst (FmaVF dst (Binary (NegVF src1) src2)));
match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %}
ins_cost(INSN_COST);
ins_encode %{
__ fmls(as_FloatRegister($dst$$reg), __ T2S,
as_FloatRegister($src1$$reg),
as_FloatRegister($src2$$reg));
%}
ins_pipe(vmuldiv_fp64);
%}
// dst - src1 * src2
instruct vmls4F(vecX dst, vecX src1, vecX src2) %{
predicate(UseFMA && n->as_Vector()->length() == 4);
match(Set dst (FmaVF dst (Binary (NegVF src1) src2)));
match(Set dst (FmaVF dst (Binary src1 (NegVF src2))));
format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %}
ins_cost(INSN_COST);
ins_encode %{
__ fmls(as_FloatRegister($dst$$reg), __ T4S,
as_FloatRegister($src1$$reg),
as_FloatRegister($src2$$reg));
%}
ins_pipe(vmuldiv_fp128);
%}
// dst - src1 * src2
instruct vmls2D(vecX dst, vecX src1, vecX src2) %{
predicate(UseFMA && n->as_Vector()->length() == 2);
match(Set dst (FmaVD dst (Binary (NegVD src1) src2)));
match(Set dst (FmaVD dst (Binary src1 (NegVD src2))));
format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %}
ins_cost(INSN_COST);
ins_encode %{
__ fmls(as_FloatRegister($dst$$reg), __ T2D,
as_FloatRegister($src1$$reg),
as_FloatRegister($src2$$reg));
%}
ins_pipe(vmuldiv_fp128);
%}
// --------------------------------- DIV --------------------------------------
instruct vdiv2F(vecD dst, vecD src1, vecD src2)

View File

@ -268,21 +268,21 @@ instruct $2$1_rReg(iReg$1NoSp dst, iReg$1 src, iRegI shift, rFlagsReg cr)
ins_pipe(ialu_reg_reg_vshift);
%}')dnl
define(ROL_INSN, `
instruct $3$1_rReg_Var_C$2(iRegLNoSp dst, iRegL src, iRegI shift, immI$2 c$2, rFlagsReg cr)
instruct $3$1_rReg_Var_C$2(iReg$1NoSp dst, iReg$1 src, iRegI shift, immI$2 c$2, rFlagsReg cr)
%{
match(Set dst (Or$1 (LShift$1 src shift) (URShift$1 src (SubI c$2 shift))));
expand %{
$3L_rReg(dst, src, shift, cr);
$3$1_rReg(dst, src, shift, cr);
%}
%}')dnl
define(ROR_INSN, `
instruct $3$1_rReg_Var_C$2(iRegLNoSp dst, iRegL src, iRegI shift, immI$2 c$2, rFlagsReg cr)
instruct $3$1_rReg_Var_C$2(iReg$1NoSp dst, iReg$1 src, iRegI shift, immI$2 c$2, rFlagsReg cr)
%{
match(Set dst (Or$1 (URShift$1 src shift) (LShift$1 src (SubI c$2 shift))));
expand %{
$3L_rReg(dst, src, shift, cr);
$3$1_rReg(dst, src, shift, cr);
%}
%}')dnl
ROL_EXPAND(L, rol, rorv)
@ -305,7 +305,7 @@ instruct $3Ext$1(iReg$2NoSp dst, iReg$2`'ORL2I($2) src1, iReg$1`'ORL2I($1) src2,
%{
match(Set dst ($3$2 src1 (ConvI2L src2)));
ins_cost(INSN_COST);
format %{ "$4 $dst, $src1, $5 $src2" %}
format %{ "$4 $dst, $src1, $src2, $5" %}
ins_encode %{
__ $4(as_Register($dst$$reg), as_Register($src1$$reg),
@ -321,7 +321,7 @@ instruct $3Ext$1_$6(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) sr
%{
match(Set dst ($3$1 src1 EXTEND($1, $4, src2, lshift, rshift)));
ins_cost(INSN_COST);
format %{ "$5 $dst, $src1, $6 $src2" %}
format %{ "$5 $dst, $src1, $src2, $6" %}
ins_encode %{
__ $5(as_Register($dst$$reg), as_Register($src1$$reg),
@ -363,5 +363,82 @@ ADD_SUB_ZERO_EXTEND(I,65535,Sub,subw,uxth)
ADD_SUB_ZERO_EXTEND(L,255,Sub,sub,uxtb)
ADD_SUB_ZERO_EXTEND(L,65535,Sub,sub,uxth)
ADD_SUB_ZERO_EXTEND(L,4294967295,Sub,sub,uxtw)
dnl
dnl ADD_SUB_ZERO_EXTEND_SHIFT(mode, size, add node, insn, ext type)
define(`ADD_SUB_EXTENDED_SHIFT', `
instruct $3Ext$1_$6_shift(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, immIExt lshift2, immI_`'eval($7-$2) lshift1, immI_`'eval($7-$2) rshift1, rFlagsReg cr)
%{
match(Set dst ($3$1 src1 (LShift$1 EXTEND($1, $4, src2, lshift1, rshift1) lshift2)));
ins_cost(1.9 * INSN_COST);
format %{ "$5 $dst, $src1, $src2, $6 #lshift2" %}
ins_encode %{
__ $5(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::$6, ($lshift2$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}')
dnl $1 $2 $3 $4 $5 $6 $7
ADD_SUB_EXTENDED_SHIFT(L,8,Add,RShift,add,sxtb,64)
ADD_SUB_EXTENDED_SHIFT(L,16,Add,RShift,add,sxth,64)
ADD_SUB_EXTENDED_SHIFT(L,32,Add,RShift,add,sxtw,64)
dnl
ADD_SUB_EXTENDED_SHIFT(L,8,Sub,RShift,sub,sxtb,64)
ADD_SUB_EXTENDED_SHIFT(L,16,Sub,RShift,sub,sxth,64)
ADD_SUB_EXTENDED_SHIFT(L,32,Sub,RShift,sub,sxtw,64)
dnl
ADD_SUB_EXTENDED_SHIFT(I,8,Add,RShift,addw,sxtb,32)
ADD_SUB_EXTENDED_SHIFT(I,16,Add,RShift,addw,sxth,32)
dnl
ADD_SUB_EXTENDED_SHIFT(I,8,Sub,RShift,subw,sxtb,32)
ADD_SUB_EXTENDED_SHIFT(I,16,Sub,RShift,subw,sxth,32)
dnl
dnl ADD_SUB_CONV_SHIFT(mode, add node, insn, ext type)
define(`ADD_SUB_CONV_SHIFT', `
instruct $2ExtI_shift(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
%{
match(Set dst ($2$1 src1 (LShiftL (ConvI2L src2) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "$3 $dst, $src1, $src2, $4 #lshift" %}
ins_encode %{
__ $3(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::$4, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}')
dnl
ADD_SUB_CONV_SHIFT(L,Add,add,sxtw);
ADD_SUB_CONV_SHIFT(L,Sub,sub,sxtw);
dnl
dnl ADD_SUB_ZERO_EXTEND(mode, size, add node, insn, ext type)
define(`ADD_SUB_ZERO_EXTEND_SHIFT', `
instruct $3Ext$1_$5_and_shift(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, imm$1_$2 mask, immIExt lshift, rFlagsReg cr)
%{
match(Set dst ($3$1 src1 (LShift$1 (And$1 src2 mask) lshift)));
ins_cost(1.9 * INSN_COST);
format %{ "$4 $dst, $src1, $src2, $5 #lshift" %}
ins_encode %{
__ $4(as_Register($dst$$reg), as_Register($src1$$reg),
as_Register($src2$$reg), ext::$5, ($lshift$$constant));
%}
ins_pipe(ialu_reg_reg_shift);
%}')
dnl
dnl $1 $2 $3 $4 $5
ADD_SUB_ZERO_EXTEND_SHIFT(L,255,Add,add,uxtb)
ADD_SUB_ZERO_EXTEND_SHIFT(L,65535,Add,add,uxth)
ADD_SUB_ZERO_EXTEND_SHIFT(L,4294967295,Add,add,uxtw)
dnl
ADD_SUB_ZERO_EXTEND_SHIFT(L,255,Sub,sub,uxtb)
ADD_SUB_ZERO_EXTEND_SHIFT(L,65535,Sub,sub,uxth)
ADD_SUB_ZERO_EXTEND_SHIFT(L,4294967295,Sub,sub,uxtw)
dnl
ADD_SUB_ZERO_EXTEND_SHIFT(I,255,Add,addw,uxtb)
ADD_SUB_ZERO_EXTEND_SHIFT(I,65535,Add,addw,uxth)
dnl
ADD_SUB_ZERO_EXTEND_SHIFT(I,255,Sub,subw,uxtb)
ADD_SUB_ZERO_EXTEND_SHIFT(I,65535,Sub,subw,uxth)
dnl
// END This section of the file is automatically generated. Do not edit --------------

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -28,6 +28,7 @@
#include "oops/constMethod.hpp"
#include "oops/method.hpp"
#include "runtime/frame.inline.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"
#include "utilities/macros.hpp"
@ -53,27 +54,6 @@ int AbstractInterpreter::BasicType_as_index(BasicType type) {
return i;
}
// These should never be compiled since the interpreter will prefer
// the compiled version to the intrinsic version.
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
switch (method_kind(m)) {
case Interpreter::java_lang_math_sin : // fall thru
case Interpreter::java_lang_math_cos : // fall thru
case Interpreter::java_lang_math_tan : // fall thru
case Interpreter::java_lang_math_abs : // fall thru
case Interpreter::java_lang_math_log : // fall thru
case Interpreter::java_lang_math_log10 : // fall thru
case Interpreter::java_lang_math_sqrt : // fall thru
case Interpreter::java_lang_math_pow : // fall thru
case Interpreter::java_lang_math_exp : // fall thru
case Interpreter::java_lang_math_fmaD : // fall thru
case Interpreter::java_lang_math_fmaF :
return false;
default:
return true;
}
}
// How much stack a method activation needs in words.
int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
const int entry_size = frame::interpreter_frame_monitor_size();
@ -121,7 +101,7 @@ int AbstractInterpreter::size_activation(int max_stack,
// On AArch64 we always keep the stack pointer 16-aligned, so we
// must round up here.
size = round_to(size, 2);
size = align_up(size, 2);
return size;
}

View File

@ -2201,6 +2201,8 @@ public:
INSN(fdiv, 1, 0, 0b111111);
INSN(fmul, 1, 0, 0b110111);
INSN(fsub, 0, 1, 0b110101);
INSN(fmla, 0, 0, 0b110011);
INSN(fmls, 0, 1, 0b110011);
#undef INSN

View File

@ -30,12 +30,6 @@
class Bytes: AllStatic {
public:
// Returns true if the byte ordering used by Java is different from the native byte ordering
// of the underlying machine. For example, this is true for Intel x86, but false for Solaris
// on Sparc.
static inline bool is_Java_byte_ordering_different(){ return true; }
// Efficient reading and writing of unaligned unsigned data in platform-specific byte ordering
// (no special code is needed since x86 CPUs can access unaligned data)
static inline u2 get_native_u2(address p) { return *(u2*)p; }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -23,12 +23,6 @@
*
*/
#include "precompiled.hpp"
#include "c1/c1_FpuStackSim.hpp"
#include "c1/c1_FrameMap.hpp"
#include "utilities/array.hpp"
#include "utilities/ostream.hpp"
//--------------------------------------------------------
// FpuStackSim
//--------------------------------------------------------

View File

@ -2740,8 +2740,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
// set already but no need to check.
__ cbz(rscratch1, next);
__ andr(rscratch1, tmp, TypeEntries::type_unknown);
__ cbnz(rscratch1, next); // already unknown. Nothing to do anymore.
__ tbnz(tmp, exact_log2(TypeEntries::type_unknown), next); // already unknown. Nothing to do anymore.
if (TypeEntries::is_type_none(current_klass)) {
__ cbz(rscratch2, none);
@ -2761,8 +2760,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only");
__ ldr(tmp, mdo_addr);
__ andr(rscratch1, tmp, TypeEntries::type_unknown);
__ cbnz(rscratch1, next); // already unknown. Nothing to do anymore.
__ tbnz(tmp, exact_log2(TypeEntries::type_unknown), next); // already unknown. Nothing to do anymore.
}
// different than before. Cannot keep accurate profile.
@ -2812,8 +2810,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
__ ldr(tmp, mdo_addr);
__ andr(rscratch1, tmp, TypeEntries::type_unknown);
__ cbnz(rscratch1, next); // already unknown. Nothing to do anymore.
__ tbnz(tmp, exact_log2(TypeEntries::type_unknown), next); // already unknown. Nothing to do anymore.
__ orr(tmp, tmp, TypeEntries::type_unknown);
__ str(tmp, mdo_addr);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -784,6 +784,8 @@ extern "C" void pm(unsigned long fp, unsigned long bcx) {
frame::frame(void* sp, void* fp, void* pc) {
init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
}
void frame::pd_ps() {}
#endif
void JavaFrameAnchor::make_walkable(JavaThread* thread) {

View File

@ -154,8 +154,11 @@ define_pd_global(intx, InlineSmallCode, 1000);
product(intx, BlockZeroingLowLimit, 256, \
"Minimum size in bytes when block zeroing will be used") \
range(1, max_jint) \
product(bool, TraceTraps, false, "Trace all traps the signal handler")
product(bool, TraceTraps, false, "Trace all traps the signal handler")\
product(int, SoftwarePrefetchHintDistance, -1, \
"Use prfm hint with specified distance in compiled code." \
"Value -1 means off.") \
range(-1, 32760)
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -270,7 +270,8 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
get_constant_pool(result);
// load pointer for resolved_references[] objArray
ldr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
ldr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
ldr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
// JNIHandles::resolve(obj);
ldr(result, Address(result, 0));
// Add in the index
@ -278,6 +279,15 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
}
void InterpreterMacroAssembler::load_resolved_klass_at_offset(
Register cpool, Register index, Register klass, Register temp) {
add(temp, cpool, index, LSL, LogBytesPerWord);
ldrh(temp, Address(temp, sizeof(ConstantPool))); // temp = resolved_klass_index
ldr(klass, Address(cpool, ConstantPool::resolved_klasses_offset_in_bytes())); // klass = cpool->_resolved_klasses
add(klass, klass, temp, LSL, LogBytesPerWord);
ldr(klass, Address(klass, Array<Klass*>::base_offset_in_bytes()));
}
// Generate a subtype check: branch to ok_is_subtype if sub_klass is a
// subtype of super_klass.
//
@ -682,7 +692,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
}
// Load (object->mark() | 1) into swap_reg
ldr(rscratch1, Address(obj_reg, 0));
ldr(rscratch1, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
orr(swap_reg, rscratch1, 1);
// Save (object->mark() | 1) into BasicLock's displaced header
@ -694,14 +704,14 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
Label fail;
if (PrintBiasedLockingStatistics) {
Label fast;
cmpxchgptr(swap_reg, lock_reg, obj_reg, rscratch1, fast, &fail);
cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, rscratch1, fast, &fail);
bind(fast);
atomic_incw(Address((address)BiasedLocking::fast_path_entry_count_addr()),
rscratch2, rscratch1, tmp);
b(done);
bind(fail);
} else {
cmpxchgptr(swap_reg, lock_reg, obj_reg, rscratch1, done, /*fallthrough*/NULL);
cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, rscratch1, done, /*fallthrough*/NULL);
}
// Test if the oopMark is an obvious stack pointer, i.e.,
@ -791,7 +801,7 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
cbz(header_reg, done);
// Atomic swap back the old header
cmpxchgptr(swap_reg, header_reg, obj_reg, rscratch1, done, /*fallthrough*/NULL);
cmpxchg_obj_header(swap_reg, header_reg, obj_reg, rscratch1, done, /*fallthrough*/NULL);
// Call the runtime routine for slow case.
str(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // restore obj
@ -1744,8 +1754,7 @@ void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register t
// Load the offset of the area within the MDO used for
// parameters. If it's negative we're not profiling any parameters
ldr(tmp1, Address(mdp, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset())));
cmp(tmp1, 0u);
br(Assembler::LT, profile_continue);
tbnz(tmp1, 63, profile_continue); // i.e. sign bit set
// Compute a pointer to the area for parameters from the offset
// and move the pointer to the slot for the last

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -54,9 +54,6 @@ class InterpreterMacroAssembler: public MacroAssembler {
int number_of_arguments,
bool check_exceptions);
virtual void check_and_handle_popframe(Register java_thread);
virtual void check_and_handle_earlyret(Register java_thread);
// base routine for all dispatches
void dispatch_base(TosState state, address* table, bool verifyoop = true);
@ -67,6 +64,9 @@ class InterpreterMacroAssembler: public MacroAssembler {
void jump_to_entry(address entry);
virtual void check_and_handle_popframe(Register java_thread);
virtual void check_and_handle_earlyret(Register java_thread);
// Interpreter-specific registers
void save_bcp() {
str(rbcp, Address(rfp, frame::interpreter_frame_bcp_offset * wordSize));
@ -123,6 +123,9 @@ class InterpreterMacroAssembler: public MacroAssembler {
// load cpool->resolved_references(index);
void load_resolved_reference_at_index(Register result, Register index);
// load cpool->resolved_klass_at(index);
void load_resolved_klass_at_offset(Register cpool, Register index, Register klass, Register temp);
void pop_ptr(Register r = r0);
void pop_i(Register r = r0);
void pop_l(Register r = r0);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -369,7 +369,7 @@ class SlowSignatureHandler
}
public:
SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
: NativeSignatureIterator(method)
{
_from = from;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -47,7 +47,7 @@ class SignatureHandlerGenerator: public NativeSignatureIterator {
public:
// Creation
SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
_masm = new MacroAssembler(buffer);
_num_int_args = (method->is_static() ? 1 : 0);
_num_fp_args = 0;

View File

@ -76,8 +76,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
SafepointSynchronize::safepoint_counter_addr(), offset);
Address safepoint_counter_addr(rcounter_addr, offset);
__ ldrw(rcounter, safepoint_counter_addr);
__ andw(rscratch1, rcounter, 1);
__ cbnzw(rscratch1, slow);
__ tbnz(rcounter, 0, slow);
__ eor(robj, c_rarg1, rcounter);
__ eor(robj, robj, rcounter); // obj, since
// robj ^ rcounter ^ rcounter == robj

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, 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 +55,7 @@ void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS)
}
}
#endif // ASSERT
Handle obj = HotSpotObjectConstantImpl::object(constant);
Handle obj(THREAD, HotSpotObjectConstantImpl::object(constant));
jobject value = JNIHandles::make_local(obj());
MacroAssembler::patch_oop(pc, (address)obj());
int oop_index = _oop_recorder->find_index(value);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -38,6 +38,7 @@
#include "opto/compile.hpp"
#include "opto/intrinsicnode.hpp"
#include "opto/node.hpp"
#include "prims/jvm.h"
#include "runtime/biasedLocking.hpp"
#include "runtime/icache.hpp"
#include "runtime/interfaceSupport.hpp"
@ -515,7 +516,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg,
mov(rscratch1, markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place);
andr(swap_reg, swap_reg, rscratch1);
orr(tmp_reg, swap_reg, rthread);
cmpxchgptr(swap_reg, tmp_reg, obj_reg, rscratch1, here, slow_case);
cmpxchg_obj_header(swap_reg, tmp_reg, obj_reg, rscratch1, here, slow_case);
// If the biasing toward our thread failed, this means that
// another thread succeeded in biasing it toward itself and we
// need to revoke that bias. The revocation will occur in the
@ -542,7 +543,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg,
Label here;
load_prototype_header(tmp_reg, obj_reg);
orr(tmp_reg, rthread, tmp_reg);
cmpxchgptr(swap_reg, tmp_reg, obj_reg, rscratch1, here, slow_case);
cmpxchg_obj_header(swap_reg, tmp_reg, obj_reg, rscratch1, here, slow_case);
// If the biasing toward our thread failed, then another thread
// succeeded in biasing it toward itself and we need to revoke that
// bias. The revocation will occur in the runtime in the slow case.
@ -569,7 +570,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg,
{
Label here, nope;
load_prototype_header(tmp_reg, obj_reg);
cmpxchgptr(swap_reg, tmp_reg, obj_reg, rscratch1, here, &nope);
cmpxchg_obj_header(swap_reg, tmp_reg, obj_reg, rscratch1, here, &nope);
bind(here);
// Fall through to the normal CAS-based lock, because no matter what
@ -2011,6 +2012,12 @@ void MacroAssembler::stop(const char* msg) {
hlt(0);
}
void MacroAssembler::unimplemented(const char* what) {
char* b = new char[1024];
jio_snprintf(b, 1024, "unimplemented: %s", what);
stop(b);
}
// If a constant does not fit in an immediate field, generate some
// number of MOV instructions and then perform the operation.
void MacroAssembler::wrap_add_sub_imm_insn(Register Rd, Register Rn, unsigned imm,
@ -2141,6 +2148,12 @@ void MacroAssembler::cmpxchgptr(Register oldv, Register newv, Register addr, Reg
b(*fail);
}
void MacroAssembler::cmpxchg_obj_header(Register oldv, Register newv, Register obj, Register tmp,
Label &succeed, Label *fail) {
assert(oopDesc::mark_offset_in_bytes() == 0, "assumption");
cmpxchgptr(oldv, newv, obj, tmp, succeed, fail);
}
void MacroAssembler::cmpxchgw(Register oldv, Register newv, Register addr, Register tmp,
Label &succeed, Label *fail) {
// oldv holds comparison value
@ -4816,6 +4829,62 @@ void MacroAssembler::string_compare(Register str1, Register str2,
BLOCK_COMMENT("} string_compare");
}
// This method checks if provided byte array contains byte with highest bit set.
void MacroAssembler::has_negatives(Register ary1, Register len, Register result) {
// Simple and most common case of aligned small array which is not at the
// end of memory page is placed here. All other cases are in stub.
Label LOOP, END, STUB, STUB_LONG, SET_RESULT, DONE;
const uint64_t UPPER_BIT_MASK=0x8080808080808080;
assert_different_registers(ary1, len, result);
cmpw(len, 0);
br(LE, SET_RESULT);
cmpw(len, 4 * wordSize);
br(GE, STUB_LONG); // size > 32 then go to stub
int shift = 64 - exact_log2(os::vm_page_size());
lsl(rscratch1, ary1, shift);
mov(rscratch2, (size_t)(4 * wordSize) << shift);
adds(rscratch2, rscratch1, rscratch2); // At end of page?
br(CS, STUB); // at the end of page then go to stub
subs(len, len, wordSize);
br(LT, END);
BIND(LOOP);
ldr(rscratch1, Address(post(ary1, wordSize)));
tst(rscratch1, UPPER_BIT_MASK);
br(NE, SET_RESULT);
subs(len, len, wordSize);
br(GE, LOOP);
cmpw(len, -wordSize);
br(EQ, SET_RESULT);
BIND(END);
ldr(result, Address(ary1));
sub(len, zr, len, LSL, 3); // LSL 3 is to get bits from bytes
lslv(result, result, len);
tst(result, UPPER_BIT_MASK);
b(SET_RESULT);
BIND(STUB);
RuntimeAddress has_neg = RuntimeAddress(StubRoutines::aarch64::has_negatives());
assert(has_neg.target() != NULL, "has_negatives stub has not been generated");
trampoline_call(has_neg);
b(DONE);
BIND(STUB_LONG);
RuntimeAddress has_neg_long = RuntimeAddress(
StubRoutines::aarch64::has_negatives_long());
assert(has_neg_long.target() != NULL, "has_negatives stub has not been generated");
trampoline_call(has_neg_long);
b(DONE);
BIND(SET_RESULT);
cset(result, NE); // set true or false
BIND(DONE);
}
// Compare Strings or char/byte arrays.
// is_string is true iff this is a string comparison.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -77,12 +77,6 @@ class MacroAssembler: public Assembler {
bool check_exceptions // whether to check for pending exceptions after return
);
// These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code.
// The implementation is only non-empty for the InterpreterMacroAssembler,
// as only the interpreter handles PopFrame and ForceEarlyReturn requests.
virtual void check_and_handle_popframe(Register java_thread);
virtual void check_and_handle_earlyret(Register java_thread);
void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions = true);
// Maximum size of class area in Metaspace when compressed
@ -97,6 +91,12 @@ class MacroAssembler: public Assembler {
> (1u << log2_intptr(CompressedClassSpaceSize))));
}
// These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code.
// The implementation is only non-empty for the InterpreterMacroAssembler,
// as only the interpreter handles PopFrame and ForceEarlyReturn requests.
virtual void check_and_handle_popframe(Register java_thread);
virtual void check_and_handle_earlyret(Register java_thread);
// Biased locking support
// lock_reg and obj_reg must be loaded up with the appropriate values.
// swap_reg is killed.
@ -169,6 +169,7 @@ class MacroAssembler: public Assembler {
template<class T>
inline void cmpw(Register Rd, T imm) { subsw(zr, Rd, imm); }
// imm is limited to 12 bits.
inline void cmp(Register Rd, unsigned imm) { subs(zr, Rd, imm); }
inline void cmnw(Register Rd, unsigned imm) { addsw(zr, Rd, imm); }
@ -941,7 +942,7 @@ public:
void untested() { stop("untested"); }
void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, 1024, "unimplemented: %s", what); stop(b); }
void unimplemented(const char* what = "");
void should_not_reach_here() { stop("should not reach here"); }
@ -949,8 +950,8 @@ public:
void bang_stack_with_offset(int offset) {
// stack grows down, caller passes positive offset
assert(offset > 0, "must bang with negative offset");
mov(rscratch2, -offset);
str(zr, Address(sp, rscratch2));
sub(rscratch2, sp, offset);
str(zr, Address(rscratch2));
}
// Writes to stack successive pages until offset reached to check for
@ -974,6 +975,8 @@ public:
// Various forms of CAS
void cmpxchg_obj_header(Register oldv, Register newv, Register obj, Register tmp,
Label &suceed, Label *fail);
void cmpxchgptr(Register oldv, Register newv, Register addr, Register tmp,
Label &suceed, Label *fail);
@ -1207,6 +1210,8 @@ public:
Register tmp1,
FloatRegister vtmp, FloatRegister vtmpZ, int ae);
void has_negatives(Register ary1, Register len, Register result);
void arrays_equals(Register a1, Register a2,
Register result, Register cnt1,
int elem_size, bool is_string);

View File

@ -1,126 +0,0 @@
/*
* Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. 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.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "memory/metaspaceShared.hpp"
// Generate the self-patching vtable method:
//
// This method will be called (as any other Klass virtual method) with
// the Klass itself as the first argument. Example:
//
// oop obj;
// int size = obj->klass()->oop_size(this);
//
// for which the virtual method call is Klass::oop_size();
//
// The dummy method is called with the Klass object as the first
// operand, and an object as the second argument.
//
//=====================================================================
// All of the dummy methods in the vtable are essentially identical,
// differing only by an ordinal constant, and they bear no relationship
// to the original method which the caller intended. Also, there needs
// to be 'vtbl_list_size' instances of the vtable in order to
// differentiate between the 'vtable_list_size' original Klass objects.
#define __ masm->
extern "C" {
void aarch64_prolog(void);
}
void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
void** vtable,
char** md_top,
char* md_end,
char** mc_top,
char* mc_end) {
#ifdef BUILTIN_SIM
// Write a dummy word to the writable shared metaspace.
// MetaspaceShared::initialize_shared_spaces will fill it with the
// address of aarch64_prolog().
address *prolog_ptr = (address*)*md_top;
*(intptr_t *)(*md_top) = (intptr_t)0;
(*md_top) += sizeof(intptr_t);
#endif
intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
*(intptr_t *)(*md_top) = vtable_bytes;
*md_top += sizeof(intptr_t);
void** dummy_vtable = (void**)*md_top;
*vtable = dummy_vtable;
*md_top += vtable_bytes;
// Get ready to generate dummy methods.
CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
MacroAssembler* masm = new MacroAssembler(&cb);
Label common_code;
for (int i = 0; i < vtbl_list_size; ++i) {
for (int j = 0; j < num_virtuals; ++j) {
dummy_vtable[num_virtuals * i + j] = (void*)masm->pc();
// We're called directly from C code.
#ifdef BUILTIN_SIM
__ c_stub_prolog(8, 0, MacroAssembler::ret_type_integral, prolog_ptr);
#endif
// Load rscratch1 with a value indicating vtable/offset pair.
// -- bits[ 7..0] (8 bits) which virtual method in table?
// -- bits[12..8] (5 bits) which virtual method table?
__ mov(rscratch1, (i << 8) + j);
__ b(common_code);
}
}
__ bind(common_code);
Register tmp0 = r10, tmp1 = r11; // AAPCS64 temporary registers
__ enter();
__ lsr(tmp0, rscratch1, 8); // isolate vtable identifier.
__ mov(tmp1, (address)vtbl_list); // address of list of vtable pointers.
__ ldr(tmp1, Address(tmp1, tmp0, Address::lsl(LogBytesPerWord))); // get correct vtable pointer.
__ str(tmp1, Address(c_rarg0)); // update vtable pointer in obj.
__ add(rscratch1, tmp1, rscratch1, ext::uxtb, LogBytesPerWord); // address of real method pointer.
__ ldr(rscratch1, Address(rscratch1)); // get real method pointer.
__ blrt(rscratch1, 8, 0, 1); // jump to the real method.
__ leave();
__ ret(lr);
*mc_top = (char*)__ pc();
}
#ifdef BUILTIN_SIM
void MetaspaceShared::relocate_vtbl_list(char **buffer) {
void **sim_entry = (void**)*buffer;
*sim_entry = (void*)aarch64_prolog;
*buffer += sizeof(intptr_t);
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -63,7 +63,7 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,
Register obj, SystemDictionary::WKID klass_id,
const char* error_message) {
InstanceKlass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
Klass* klass = SystemDictionary::well_known_klass(klass_id);
Register temp = rscratch2;
Register temp2 = rscratch1; // used by MacroAssembler::cmpptr
Label L_ok, L_bad;
@ -137,8 +137,9 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
__ verify_oop(method_temp);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())));
__ verify_oop(method_temp);
// the following assumes that a Method* is normally compressed in the vmtarget field:
__ ldr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())));
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())));
__ verify_oop(method_temp);
__ ldr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())));
if (VerifyMethodHandles && !for_compiler_entry) {
// make sure recv is already on stack
@ -282,7 +283,8 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()));
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()));
Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()));
Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()));
Address vmtarget_method( rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()));
Register temp1_recv_klass = temp1;
if (iid != vmIntrinsics::_linkToStatic) {
@ -335,14 +337,16 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
}
__ ldr(rmethod, member_vmtarget);
__ load_heap_oop(rmethod, member_vmtarget);
__ ldr(rmethod, vmtarget_method);
break;
case vmIntrinsics::_linkToStatic:
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
}
__ ldr(rmethod, member_vmtarget);
__ load_heap_oop(rmethod, member_vmtarget);
__ ldr(rmethod, vmtarget_method);
break;
case vmIntrinsics::_linkToVirtual:

View File

@ -36,6 +36,7 @@
#include "oops/compiledICHolder.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
#include "vmreg_aarch64.inline.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
@ -123,7 +124,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
assert(!save_vectors, "vectors are generated only by C2 and JVMCI");
#endif
int frame_size_in_bytes = round_to(additional_frame_words*wordSize +
int frame_size_in_bytes = align_up(additional_frame_words*wordSize +
reg_save_size*BytesPerInt, 16);
// OopMap frame size is in compiler stack slots (jint's) not bytes or words
int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
@ -190,7 +191,7 @@ void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
__ ldr(r0, Address(sp, r0_offset_in_bytes()));
// Pop all of the register save are off the stack
__ add(sp, sp, round_to(return_offset_in_bytes(), 16));
__ add(sp, sp, align_up(return_offset_in_bytes(), 16));
}
// Is vector's size (in bytes) bigger than a size saved by default?
@ -317,7 +318,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
}
}
return round_to(stk_args, 2);
return align_up(stk_args, 2);
}
// Patch the callers callsite with entry to compiled code if it exists.
@ -375,7 +376,7 @@ static void gen_c2i_adapter(MacroAssembler *masm,
__ mov(r13, sp);
// stack is aligned, keep it that way
extraspace = round_to(extraspace, 2*wordSize);
extraspace = align_up(extraspace, 2*wordSize);
if (extraspace)
__ sub(sp, sp, extraspace);
@ -547,7 +548,7 @@ void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
}
// Cut-out for having no stack args.
int comp_words_on_stack = round_to(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord;
int comp_words_on_stack = align_up(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord;
if (comp_args_on_stack) {
__ sub(rscratch1, sp, comp_words_on_stack * wordSize);
__ andr(sp, rscratch1, -16);
@ -1206,7 +1207,7 @@ static void rt_call(MacroAssembler* masm, address dest, int gpargs, int fpargs,
}
static void verify_oop_args(MacroAssembler* masm,
methodHandle method,
const methodHandle& method,
const BasicType* sig_bt,
const VMRegPair* regs) {
Register temp_reg = r19; // not part of any compiled calling seq
@ -1228,7 +1229,7 @@ static void verify_oop_args(MacroAssembler* masm,
}
static void gen_special_dispatch(MacroAssembler* masm,
methodHandle method,
const methodHandle& method,
const BasicType* sig_bt,
const VMRegPair* regs) {
verify_oop_args(masm, method, sig_bt, regs);
@ -1486,7 +1487,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
total_save_slots = double_slots * 2 + single_slots;
// align the save area
if (double_slots != 0) {
stack_slots = round_to(stack_slots, 2);
stack_slots = align_up(stack_slots, 2);
}
}
@ -1543,7 +1544,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// Now compute actual number of stack words we need rounding to make
// stack properly aligned.
stack_slots = round_to(stack_slots, StackAlignmentInSlots);
stack_slots = align_up(stack_slots, StackAlignmentInSlots);
int stack_size = stack_slots * VMRegImpl::stack_slot_size;
@ -1842,7 +1843,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
}
// Load (object->mark() | 1) into swap_reg %r0
__ ldr(rscratch1, Address(obj_reg, 0));
__ ldr(rscratch1, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
__ orr(swap_reg, rscratch1, 1);
// Save (object->mark() | 1) into BasicLock's displaced header
@ -1850,7 +1851,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// src -> dest iff dest == r0 else r0 <- dest
{ Label here;
__ cmpxchgptr(r0, lock_reg, obj_reg, rscratch1, lock_done, /*fallthrough*/NULL);
__ cmpxchg_obj_header(r0, lock_reg, obj_reg, rscratch1, lock_done, /*fallthrough*/NULL);
}
// Hmm should this move to the slow path code area???
@ -2029,7 +2030,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// Atomic swap old header if oop still contains the stack lock
Label succeed;
__ cmpxchgptr(r0, old_hdr, obj_reg, rscratch1, succeed, &slow_path_unlock);
__ cmpxchg_obj_header(r0, old_hdr, obj_reg, rscratch1, succeed, &slow_path_unlock);
__ bind(succeed);
// slow path re-enters here
@ -2293,7 +2294,7 @@ int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals)
return 0; // No adjustment for negative locals
int diff = (callee_locals - callee_parameters) * Interpreter::stackElementWords;
// diff is counted in stack words
return round_to(diff, 2);
return align_up(diff, 2);
}

View File

@ -39,6 +39,7 @@
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
#include "utilities/align.hpp"
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
@ -619,19 +620,21 @@ class StubGenerator: public StubCodeGenerator {
// Generate code for an array write pre barrier
//
// addr - starting address
// count - element count
// tmp - scratch register
// addr - starting address
// count - element count
// tmp - scratch register
// saved_regs - registers to be saved before calling static_write_ref_array_pre
//
// Destroy no registers except rscratch1 and rscratch2
// Callers must specify which registers to preserve in saved_regs.
// Clobbers: r0-r18, v0-v7, v16-v31, except saved_regs.
//
void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized, RegSet saved_regs) {
BarrierSet* bs = Universe::heap()->barrier_set();
switch (bs->kind()) {
case BarrierSet::G1SATBCTLogging:
// With G1, don't generate the call if we statically know that the target in uninitialized
if (!dest_uninitialized) {
__ push_call_clobbered_registers();
__ push(saved_regs, sp);
if (count == c_rarg0) {
if (addr == c_rarg1) {
// exactly backwards!!
@ -647,7 +650,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(c_rarg1, count);
}
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
__ pop_call_clobbered_registers();
__ pop(saved_regs, sp);
break;
case BarrierSet::CardTableForRS:
case BarrierSet::CardTableExtension:
@ -664,20 +667,23 @@ class StubGenerator: public StubCodeGenerator {
// Generate code for an array write post barrier
//
// Input:
// start - register containing starting address of destination array
// end - register containing ending address of destination array
// scratch - scratch register
// start - register containing starting address of destination array
// end - register containing ending address of destination array
// scratch - scratch register
// saved_regs - registers to be saved before calling static_write_ref_array_post
//
// The input registers are overwritten.
// The ending address is inclusive.
void gen_write_ref_array_post_barrier(Register start, Register end, Register scratch) {
// Callers must specify which registers to preserve in saved_regs.
// Clobbers: r0-r18, v0-v7, v16-v31, except saved_regs.
void gen_write_ref_array_post_barrier(Register start, Register end, Register scratch, RegSet saved_regs) {
assert_different_registers(start, end, scratch);
BarrierSet* bs = Universe::heap()->barrier_set();
switch (bs->kind()) {
case BarrierSet::G1SATBCTLogging:
{
__ push_call_clobbered_registers();
__ push(saved_regs, sp);
// must compute element count unless barrier set interface is changed (other platforms supply count)
assert_different_registers(start, end, scratch);
__ lea(scratch, Address(end, BytesPerHeapOop));
@ -686,7 +692,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(c_rarg0, start);
__ mov(c_rarg1, scratch);
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
__ pop_call_clobbered_registers();
__ pop(saved_regs, sp);
}
break;
case BarrierSet::CardTableForRS:
@ -758,7 +764,7 @@ class StubGenerator: public StubCodeGenerator {
// alignment.
Label small;
int low_limit = MAX2(zva_length * 2, (int)BlockZeroingLowLimit);
__ cmp(cnt, low_limit >> 3);
__ subs(rscratch1, cnt, low_limit >> 3);
__ br(Assembler::LT, small);
__ zero_dcache_blocks(base, cnt);
__ bind(small);
@ -821,7 +827,7 @@ class StubGenerator: public StubCodeGenerator {
Label again, drain;
const char *stub_name;
if (direction == copy_forwards)
stub_name = "foward_copy_longs";
stub_name = "forward_copy_longs";
else
stub_name = "backward_copy_longs";
StubCodeMark mark(this, "StubRoutines", stub_name);
@ -1438,6 +1444,7 @@ class StubGenerator: public StubCodeGenerator {
address generate_disjoint_copy(size_t size, bool aligned, bool is_oop, address *entry,
const char *name, bool dest_uninitialized = false) {
Register s = c_rarg0, d = c_rarg1, count = c_rarg2;
RegSet saved_reg = RegSet::of(s, d, count);
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", name);
address start = __ pc();
@ -1450,9 +1457,9 @@ class StubGenerator: public StubCodeGenerator {
}
if (is_oop) {
gen_write_ref_array_pre_barrier(d, count, dest_uninitialized, saved_reg);
// save regs before copy_memory
__ push(RegSet::of(d, count), sp);
// no registers are destroyed by this call
gen_write_ref_array_pre_barrier(d, count, dest_uninitialized);
}
copy_memory(aligned, s, d, count, rscratch1, size);
if (is_oop) {
@ -1461,7 +1468,7 @@ class StubGenerator: public StubCodeGenerator {
verify_oop_array(size, d, count, r16);
__ sub(count, count, 1); // make an inclusive end pointer
__ lea(count, Address(d, count, Address::lsl(exact_log2(size))));
gen_write_ref_array_post_barrier(d, count, rscratch1);
gen_write_ref_array_post_barrier(d, count, rscratch1, RegSet());
}
__ leave();
__ mov(r0, zr); // return 0
@ -1494,7 +1501,7 @@ class StubGenerator: public StubCodeGenerator {
address *entry, const char *name,
bool dest_uninitialized = false) {
Register s = c_rarg0, d = c_rarg1, count = c_rarg2;
RegSet saved_regs = RegSet::of(s, d, count);
StubCodeMark mark(this, "StubRoutines", name);
address start = __ pc();
__ enter();
@ -1511,9 +1518,9 @@ class StubGenerator: public StubCodeGenerator {
__ br(Assembler::HS, nooverlap_target);
if (is_oop) {
gen_write_ref_array_pre_barrier(d, count, dest_uninitialized, saved_regs);
// save regs before copy_memory
__ push(RegSet::of(d, count), sp);
// no registers are destroyed by this call
gen_write_ref_array_pre_barrier(d, count, dest_uninitialized);
}
copy_memory(aligned, s, d, count, rscratch1, -size);
if (is_oop) {
@ -1522,7 +1529,7 @@ class StubGenerator: public StubCodeGenerator {
verify_oop_array(size, d, count, r16);
__ sub(count, count, 1); // make an inclusive end pointer
__ lea(count, Address(d, count, Address::lsl(exact_log2(size))));
gen_write_ref_array_post_barrier(d, count, rscratch1);
gen_write_ref_array_post_barrier(d, count, rscratch1, RegSet());
}
__ leave();
__ mov(r0, zr); // return 0
@ -1804,6 +1811,9 @@ class StubGenerator: public StubCodeGenerator {
const Register ckoff = c_rarg3; // super_check_offset
const Register ckval = c_rarg4; // super_klass
RegSet wb_pre_saved_regs = RegSet::range(c_rarg0, c_rarg4);
RegSet wb_post_saved_regs = RegSet::of(count);
// Registers used as temps (r18, r19, r20 are save-on-entry)
const Register count_save = r21; // orig elementscount
const Register start_to = r20; // destination array start address
@ -1861,7 +1871,7 @@ class StubGenerator: public StubCodeGenerator {
}
#endif //ASSERT
gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
gen_write_ref_array_pre_barrier(to, count, dest_uninitialized, wb_pre_saved_regs);
// save the original count
__ mov(count_save, count);
@ -1905,7 +1915,7 @@ class StubGenerator: public StubCodeGenerator {
__ BIND(L_do_card_marks);
__ add(to, to, -heapOopSize); // make an inclusive end pointer
gen_write_ref_array_post_barrier(start_to, to, rscratch1);
gen_write_ref_array_post_barrier(start_to, to, rscratch1, wb_post_saved_regs);
__ bind(L_done_pop);
__ pop(RegSet::of(r18, r19, r20, r21), sp);
@ -3660,6 +3670,167 @@ class StubGenerator: public StubCodeGenerator {
__ eor(result, __ T16B, lo, t0);
}
address generate_has_negatives(address &has_negatives_long) {
StubCodeMark mark(this, "StubRoutines", "has_negatives");
const int large_loop_size = 64;
const uint64_t UPPER_BIT_MASK=0x8080808080808080;
int dcache_line = VM_Version::dcache_line_size();
Register ary1 = r1, len = r2, result = r0;
__ align(CodeEntryAlignment);
address entry = __ pc();
__ enter();
Label RET_TRUE, RET_TRUE_NO_POP, RET_FALSE, ALIGNED, LOOP16, CHECK_16, DONE,
LARGE_LOOP, POST_LOOP16, LEN_OVER_15, LEN_OVER_8, POST_LOOP16_LOAD_TAIL;
__ cmp(len, 15);
__ br(Assembler::GT, LEN_OVER_15);
// The only case when execution falls into this code is when pointer is near
// the end of memory page and we have to avoid reading next page
__ add(ary1, ary1, len);
__ subs(len, len, 8);
__ br(Assembler::GT, LEN_OVER_8);
__ ldr(rscratch2, Address(ary1, -8));
__ sub(rscratch1, zr, len, __ LSL, 3); // LSL 3 is to get bits from bytes.
__ lsrv(rscratch2, rscratch2, rscratch1);
__ tst(rscratch2, UPPER_BIT_MASK);
__ cset(result, Assembler::NE);
__ leave();
__ ret(lr);
__ bind(LEN_OVER_8);
__ ldp(rscratch1, rscratch2, Address(ary1, -16));
__ sub(len, len, 8); // no data dep., then sub can be executed while loading
__ tst(rscratch2, UPPER_BIT_MASK);
__ br(Assembler::NE, RET_TRUE_NO_POP);
__ sub(rscratch2, zr, len, __ LSL, 3); // LSL 3 is to get bits from bytes
__ lsrv(rscratch1, rscratch1, rscratch2);
__ tst(rscratch1, UPPER_BIT_MASK);
__ cset(result, Assembler::NE);
__ leave();
__ ret(lr);
Register tmp1 = r3, tmp2 = r4, tmp3 = r5, tmp4 = r6, tmp5 = r7, tmp6 = r10;
const RegSet spilled_regs = RegSet::range(tmp1, tmp5) + tmp6;
has_negatives_long = __ pc(); // 2nd entry point
__ enter();
__ bind(LEN_OVER_15);
__ push(spilled_regs, sp);
__ andr(rscratch2, ary1, 15); // check pointer for 16-byte alignment
__ cbz(rscratch2, ALIGNED);
__ ldp(tmp6, tmp1, Address(ary1));
__ mov(tmp5, 16);
__ sub(rscratch1, tmp5, rscratch2); // amount of bytes until aligned address
__ add(ary1, ary1, rscratch1);
__ sub(len, len, rscratch1);
__ orr(tmp6, tmp6, tmp1);
__ tst(tmp6, UPPER_BIT_MASK);
__ br(Assembler::NE, RET_TRUE);
__ bind(ALIGNED);
__ cmp(len, large_loop_size);
__ br(Assembler::LT, CHECK_16);
// Perform 16-byte load as early return in pre-loop to handle situation
// when initially aligned large array has negative values at starting bytes,
// so LARGE_LOOP would do 4 reads instead of 1 (in worst case), which is
// slower. Cases with negative bytes further ahead won't be affected that
// much. In fact, it'll be faster due to early loads, less instructions and
// less branches in LARGE_LOOP.
__ ldp(tmp6, tmp1, Address(__ post(ary1, 16)));
__ sub(len, len, 16);
__ orr(tmp6, tmp6, tmp1);
__ tst(tmp6, UPPER_BIT_MASK);
__ br(Assembler::NE, RET_TRUE);
__ cmp(len, large_loop_size);
__ br(Assembler::LT, CHECK_16);
if (SoftwarePrefetchHintDistance >= 0
&& SoftwarePrefetchHintDistance >= dcache_line) {
// initial prefetch
__ prfm(Address(ary1, SoftwarePrefetchHintDistance - dcache_line));
}
__ bind(LARGE_LOOP);
if (SoftwarePrefetchHintDistance >= 0) {
__ prfm(Address(ary1, SoftwarePrefetchHintDistance));
}
// Issue load instructions first, since it can save few CPU/MEM cycles, also
// instead of 4 triples of "orr(...), addr(...);cbnz(...);" (for each ldp)
// better generate 7 * orr(...) + 1 andr(...) + 1 cbnz(...) which saves 3
// instructions per cycle and have less branches, but this approach disables
// early return, thus, all 64 bytes are loaded and checked every time.
__ ldp(tmp2, tmp3, Address(ary1));
__ ldp(tmp4, tmp5, Address(ary1, 16));
__ ldp(rscratch1, rscratch2, Address(ary1, 32));
__ ldp(tmp6, tmp1, Address(ary1, 48));
__ add(ary1, ary1, large_loop_size);
__ sub(len, len, large_loop_size);
__ orr(tmp2, tmp2, tmp3);
__ orr(tmp4, tmp4, tmp5);
__ orr(rscratch1, rscratch1, rscratch2);
__ orr(tmp6, tmp6, tmp1);
__ orr(tmp2, tmp2, tmp4);
__ orr(rscratch1, rscratch1, tmp6);
__ orr(tmp2, tmp2, rscratch1);
__ tst(tmp2, UPPER_BIT_MASK);
__ br(Assembler::NE, RET_TRUE);
__ cmp(len, large_loop_size);
__ br(Assembler::GE, LARGE_LOOP);
__ bind(CHECK_16); // small 16-byte load pre-loop
__ cmp(len, 16);
__ br(Assembler::LT, POST_LOOP16);
__ bind(LOOP16); // small 16-byte load loop
__ ldp(tmp2, tmp3, Address(__ post(ary1, 16)));
__ sub(len, len, 16);
__ orr(tmp2, tmp2, tmp3);
__ tst(tmp2, UPPER_BIT_MASK);
__ br(Assembler::NE, RET_TRUE);
__ cmp(len, 16);
__ br(Assembler::GE, LOOP16); // 16-byte load loop end
__ bind(POST_LOOP16); // 16-byte aligned, so we can read unconditionally
__ cmp(len, 8);
__ br(Assembler::LE, POST_LOOP16_LOAD_TAIL);
__ ldr(tmp3, Address(__ post(ary1, 8)));
__ sub(len, len, 8);
__ tst(tmp3, UPPER_BIT_MASK);
__ br(Assembler::NE, RET_TRUE);
__ bind(POST_LOOP16_LOAD_TAIL);
__ cbz(len, RET_FALSE); // Can't shift left by 64 when len==0
__ ldr(tmp1, Address(ary1));
__ mov(tmp2, 64);
__ sub(tmp4, tmp2, len, __ LSL, 3);
__ lslv(tmp1, tmp1, tmp4);
__ tst(tmp1, UPPER_BIT_MASK);
__ br(Assembler::NE, RET_TRUE);
// Fallthrough
__ bind(RET_FALSE);
__ pop(spilled_regs, sp);
__ leave();
__ mov(result, zr);
__ ret(lr);
__ bind(RET_TRUE);
__ pop(spilled_regs, sp);
__ bind(RET_TRUE_NO_POP);
__ leave();
__ mov(result, 1);
__ ret(lr);
__ bind(DONE);
__ pop(spilled_regs, sp);
__ leave();
__ ret(lr);
return entry;
}
/**
* Arguments:
*
@ -4676,6 +4847,7 @@ class StubGenerator: public StubCodeGenerator {
// }
};
// Initialization
void generate_initial() {
// Generate initial stubs and initializes the entry points
@ -4734,6 +4906,9 @@ class StubGenerator: public StubCodeGenerator {
// arraycopy stubs used by compilers
generate_arraycopy_stubs();
// has negatives stub for large arrays.
StubRoutines::aarch64::_has_negatives = generate_has_negatives(StubRoutines::aarch64::_has_negatives_long);
if (UseMultiplyToLenIntrinsic) {
StubRoutines::_multiplyToLen = generate_multiplyToLen();
}

View File

@ -44,6 +44,8 @@ address StubRoutines::aarch64::_float_sign_flip = NULL;
address StubRoutines::aarch64::_double_sign_mask = NULL;
address StubRoutines::aarch64::_double_sign_flip = NULL;
address StubRoutines::aarch64::_zero_blocks = NULL;
address StubRoutines::aarch64::_has_negatives = NULL;
address StubRoutines::aarch64::_has_negatives_long = NULL;
bool StubRoutines::aarch64::_completed = false;
/**

View File

@ -62,6 +62,9 @@ class aarch64 {
static address _double_sign_flip;
static address _zero_blocks;
static address _has_negatives;
static address _has_negatives_long;
static bool _completed;
public:
@ -120,6 +123,14 @@ class aarch64 {
return _zero_blocks;
}
static address has_negatives() {
return _has_negatives;
}
static address has_negatives_long() {
return _has_negatives_long;
}
static bool complete() {
return _completed;
}

View File

@ -402,14 +402,6 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(
return entry;
}
address TemplateInterpreterGenerator::generate_continuation_for(TosState state) {
address entry = __ pc();
// NULL last_sp until next java call
__ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
__ dispatch_next(state);
return entry;
}
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
address entry = __ pc();
@ -444,6 +436,10 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
__ notify(Assembler::method_reentry);
}
#endif
__ check_and_handle_popframe(rthread);
__ check_and_handle_earlyret(rthread);
__ get_dispatch();
__ dispatch_next(state, step);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -246,8 +246,7 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
assert(load_bc_into_bc_reg, "we use bc_reg as temp");
__ get_cache_and_index_and_bytecode_at_bcp(temp_reg, bc_reg, temp_reg, byte_no, 1);
__ movw(bc_reg, bc);
__ cmpw(temp_reg, (unsigned) 0);
__ br(Assembler::EQ, L_patch_done); // don't patch
__ cbzw(temp_reg, L_patch_done); // don't patch
}
break;
default:
@ -3418,8 +3417,7 @@ void TemplateTable::_new() {
__ br(Assembler::NE, slow_case);
// get InstanceKlass
__ lea(r4, Address(r4, r3, Address::lsl(3)));
__ ldr(r4, Address(r4, sizeof(ConstantPool)));
__ load_resolved_klass_at_offset(r4, r3, r4, rscratch1);
// make sure klass is initialized & doesn't have finalizer
// make sure klass is fully initialized
@ -3572,8 +3570,7 @@ void TemplateTable::checkcast()
// Get superklass in r0 and subklass in r3
__ bind(quicked);
__ mov(r3, r0); // Save object in r3; r0 needed for subtype check
__ lea(r0, Address(r2, r19, Address::lsl(3)));
__ ldr(r0, Address(r0, sizeof(ConstantPool)));
__ load_resolved_klass_at_offset(r2, r19, r0, rscratch1); // r0 = klass
__ bind(resolved);
__ load_klass(r19, r3);
@ -3629,8 +3626,7 @@ void TemplateTable::instanceof() {
// Get superklass in r0 and subklass in r3
__ bind(quicked);
__ load_klass(r3, r0);
__ lea(r0, Address(r2, r19, Address::lsl(3)));
__ ldr(r0, Address(r0, sizeof(ConstantPool)));
__ load_resolved_klass_at_offset(r2, r19, r0, rscratch1);
__ bind(resolved);

View File

@ -137,6 +137,8 @@ void VM_Version::get_processor_features() {
FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 3*dcache_line);
if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes))
FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 3*dcache_line);
if (FLAG_IS_DEFAULT(SoftwarePrefetchHintDistance))
FLAG_SET_DEFAULT(SoftwarePrefetchHintDistance, 3*dcache_line);
if (PrefetchCopyIntervalInBytes != -1 &&
((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768))) {
@ -146,6 +148,12 @@ void VM_Version::get_processor_features() {
PrefetchCopyIntervalInBytes = 32760;
}
if (SoftwarePrefetchHintDistance != -1 &&
(SoftwarePrefetchHintDistance & 7)) {
warning("SoftwarePrefetchHintDistance must be -1, or a multiple of 8");
SoftwarePrefetchHintDistance &= ~7;
}
unsigned long auxv = getauxval(AT_HWCAP);
char buf[512];

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, 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,6 +32,7 @@
#include "runtime/handles.inline.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/synchronizer.hpp"
#include "utilities/align.hpp"
#include "utilities/macros.hpp"
int AbstractInterpreter::BasicType_as_index(BasicType type) {
@ -68,23 +69,6 @@ int AbstractInterpreter::BasicType_as_index(BasicType type) {
return i;
}
// These should never be compiled since the interpreter will prefer
// the compiled version to the intrinsic version.
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
switch (method_kind(m)) {
case Interpreter::java_lang_math_sin : // fall thru
case Interpreter::java_lang_math_cos : // fall thru
case Interpreter::java_lang_math_tan : // fall thru
case Interpreter::java_lang_math_abs : // fall thru
case Interpreter::java_lang_math_log : // fall thru
case Interpreter::java_lang_math_log10 : // fall thru
case Interpreter::java_lang_math_sqrt :
return false;
default:
return true;
}
}
// How much stack a method activation needs in words.
int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
const int stub_code = AARCH64_ONLY(24) NOT_AARCH64(12); // see generate_call_stub
@ -125,7 +109,7 @@ int AbstractInterpreter::size_activation(int max_stack,
tempcount*Interpreter::stackElementWords + extra_args;
#ifdef AARCH64
size = round_to(size, StackAlignmentInBytes/BytesPerWord);
size = align_up(size, StackAlignmentInBytes/BytesPerWord);
#endif // AARCH64
return size;
@ -206,7 +190,7 @@ void AbstractInterpreter::layout_activation(Method* method,
}
if (caller->is_interpreted_frame()) {
intptr_t* locals_base = (locals - method->max_locals()*Interpreter::stackElementWords + 1);
locals_base = (intptr_t*)round_down((intptr_t)locals_base, StackAlignmentInBytes);
locals_base = align_down(locals_base, StackAlignmentInBytes);
assert(interpreter_frame->sender_sp() <= locals_base, "interpreter-to-interpreter frame chaining");
} else if (caller->is_compiled_frame()) {
@ -234,10 +218,17 @@ void AbstractInterpreter::layout_activation(Method* method,
#ifdef AARCH64
interpreter_frame->interpreter_frame_set_stack_top(stack_top);
// We have to add extra reserved slots to max_stack. There are 3 users of the extra slots,
// none of which are at the same time, so we just need to make sure there is enough room
// for the biggest user:
// -reserved slot for exception handler
// -reserved slots for JSR292. Method::extra_stack_entries() is the size.
// -3 reserved slots so get_method_counters() can save some registers before call_VM().
int max_stack = method->constMethod()->max_stack() + MAX2(3, Method::extra_stack_entries());
intptr_t* extended_sp = (intptr_t*) monbot -
(method->max_stack() + 1) * Interpreter::stackElementWords - // +1 is reserved slot for exception handler
(max_stack * Interpreter::stackElementWords) -
popframe_extra_args;
extended_sp = (intptr_t*)round_down((intptr_t)extended_sp, StackAlignmentInBytes);
extended_sp = align_down(extended_sp, StackAlignmentInBytes);
interpreter_frame->interpreter_frame_set_extended_sp(extended_sp);
#else
interpreter_frame->interpreter_frame_set_last_sp(stack_top);
@ -249,7 +240,7 @@ void AbstractInterpreter::layout_activation(Method* method,
#ifdef AARCH64
if (caller->is_interpreted_frame()) {
intptr_t* sender_sp = (intptr_t*)round_down((intptr_t)caller->interpreter_frame_tos_address(), StackAlignmentInBytes);
intptr_t* sender_sp = align_down(caller->interpreter_frame_tos_address(), StackAlignmentInBytes);
interpreter_frame->set_interpreter_frame_sender_sp(sender_sp);
} else {

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2008, 2017, 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
@ -1122,7 +1122,7 @@ const int Matcher::vector_width_in_bytes(BasicType bt) {
}
// Vector ideal reg corresponding to specified size in bytes
const int Matcher::vector_ideal_reg(int size) {
const uint Matcher::vector_ideal_reg(int size) {
assert(MaxVectorSize >= size, "");
switch(size) {
case 8: return Op_VecD;
@ -1132,7 +1132,7 @@ const int Matcher::vector_ideal_reg(int size) {
return 0;
}
const int Matcher::vector_shift_count_ideal_reg(int size) {
const uint Matcher::vector_shift_count_ideal_reg(int size) {
return vector_ideal_reg(size);
}
@ -1881,7 +1881,7 @@ frame %{
// Ret Addr is on stack in slot 0 if no locks or verification or alignment.
// Otherwise, it is above the locks and verification slot and alignment word
return_addr(STACK - 1*VMRegImpl::slots_per_word +
round_to((Compile::current()->in_preserve_stack_slots() +
align_up((Compile::current()->in_preserve_stack_slots() +
Compile::current()->fixed_slots()),
stack_alignment_in_slots()));
@ -11968,9 +11968,13 @@ instruct ShouldNotReachHere( )
size(4);
// Use the following format syntax
format %{ "breakpoint ; ShouldNotReachHere" %}
format %{ "ShouldNotReachHere" %}
ins_encode %{
__ breakpoint();
#ifdef AARCH64
__ dpcs1(0xdead);
#else
__ udf(0xdead);
#endif
%}
ins_pipe(tail_call);
%}

View File

@ -578,6 +578,11 @@ class Assembler : public AbstractAssembler {
F(bl, 0xb)
#undef F
void udf(int imm_16) {
assert((imm_16 >> 16) == 0, "encoding constraint");
emit_int32(0xe7f000f0 | (imm_16 & 0xfff0) << 8 | (imm_16 & 0xf));
}
// ARMv7 instructions
#define F(mnemonic, wt) \

View File

@ -1083,6 +1083,7 @@ class Assembler : public AbstractAssembler {
F(brk, 0b001, 0b000, 0b00)
F(hlt, 0b010, 0b000, 0b00)
F(dpcs1, 0b101, 0b000, 0b01)
#undef F
enum SystemRegister { // o0<1> op1<3> CRn<4> CRm<4> op2<3>

View File

@ -35,12 +35,6 @@
class Bytes: AllStatic {
public:
// Returns true if the byte ordering used by Java is different from the native byte ordering
// of the underlying machine.
static inline bool is_Java_byte_ordering_different() {
return VM_LITTLE_ENDIAN != 0;
}
static inline u2 get_Java_u2(address p) {
return (u2(p[0]) << 8) | u2(p[1]);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, 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
@ -22,10 +22,4 @@
*
*/
#include "precompiled.hpp"
#include "c1/c1_FpuStackSim.hpp"
#include "c1/c1_FrameMap.hpp"
#include "utilities/array.hpp"
#include "utilities/ostream.hpp"
// Nothing needed here

View File

@ -37,6 +37,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/signature.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
#include "vmreg_arm.inline.hpp"
#if INCLUDE_ALL_GCS
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
@ -250,7 +251,7 @@ static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers
__ sub(SP, SP, (reg_save_size - 2) * wordSize);
for (int i = 0; i < round_down(number_of_saved_gprs, 2); i += 2) {
for (int i = 0; i < align_down((int)number_of_saved_gprs, 2); i += 2) {
__ stp(as_Register(i), as_Register(i+1), Address(SP, (R0_offset + i) * wordSize));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, 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
@ -621,6 +621,8 @@ void frame::describe_pd(FrameValues& values, int frame_no) {
frame::frame(void* sp, void* fp, void* pc) {
init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
}
void frame::pd_ps() {}
#endif
intptr_t *frame::initial_deoptimization_info() {

View File

@ -298,7 +298,8 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
Register cache = result;
// load pointer for resolved_references[] objArray
ldr(cache, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
ldr(cache, Address(result, ConstantPool::cache_offset_in_bytes()));
ldr(cache, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
// JNIHandles::resolve(result)
ldr(cache, Address(cache, 0));
// Add in the index
@ -308,6 +309,15 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
load_heap_oop(result, Address(cache, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
}
void InterpreterMacroAssembler::load_resolved_klass_at_offset(
Register Rcpool, Register Rindex, Register Rklass) {
add(Rtemp, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
ldrh(Rtemp, Address(Rtemp, sizeof(ConstantPool))); // Rtemp = resolved_klass_index
ldr(Rklass, Address(Rcpool, ConstantPool::resolved_klasses_offset_in_bytes())); // Rklass = cpool->_resolved_klasses
add(Rklass, Rklass, AsmOperand(Rtemp, lsl, LogBytesPerWord));
ldr(Rklass, Address(Rklass, Array<Klass*>::base_offset_in_bytes()));
}
// Generate a subtype check: branch to not_subtype if sub_klass is
// not a subtype of super_klass.
// Profiling code for the subtype check failure (profile_typecheck_failed)
@ -2016,75 +2026,42 @@ void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
void InterpreterMacroAssembler::get_method_counters(Register method,
Register Rcounters,
Label& skip) {
Label& skip,
bool saveRegs,
Register reg1,
Register reg2,
Register reg3) {
const Address method_counters(method, Method::method_counters_offset());
Label has_counters;
ldr(Rcounters, method_counters);
cbnz(Rcounters, has_counters);
if (saveRegs) {
// Save and restore in use caller-saved registers since they will be trashed by call_VM
assert(reg1 != noreg, "must specify reg1");
assert(reg2 != noreg, "must specify reg2");
#ifdef AARCH64
const Register tmp = Rcounters;
const int saved_regs_size = 20*wordSize;
// Note: call_VM will cut SP according to Rstack_top value before call, and restore SP to
// extended_sp value from frame after the call.
// So make sure there is enough stack space to save registers and adjust Rstack_top accordingly.
{
Label enough_stack_space;
check_extended_sp(tmp);
sub(Rstack_top, Rstack_top, saved_regs_size);
cmp(SP, Rstack_top);
b(enough_stack_space, ls);
align_reg(tmp, Rstack_top, StackAlignmentInBytes);
mov(SP, tmp);
str(tmp, Address(FP, frame::interpreter_frame_extended_sp_offset * wordSize));
bind(enough_stack_space);
check_stack_top();
int offset = 0;
stp(R0, R1, Address(Rstack_top, offset)); offset += 2*wordSize;
stp(R2, R3, Address(Rstack_top, offset)); offset += 2*wordSize;
stp(R4, R5, Address(Rstack_top, offset)); offset += 2*wordSize;
stp(R6, R7, Address(Rstack_top, offset)); offset += 2*wordSize;
stp(R8, R9, Address(Rstack_top, offset)); offset += 2*wordSize;
stp(R10, R11, Address(Rstack_top, offset)); offset += 2*wordSize;
stp(R12, R13, Address(Rstack_top, offset)); offset += 2*wordSize;
stp(R14, R15, Address(Rstack_top, offset)); offset += 2*wordSize;
stp(R16, R17, Address(Rstack_top, offset)); offset += 2*wordSize;
stp(R18, LR, Address(Rstack_top, offset)); offset += 2*wordSize;
assert (offset == saved_regs_size, "should be");
}
assert(reg3 != noreg, "must specify reg3");
stp(reg1, reg2, Address(Rstack_top, -2*wordSize, pre_indexed));
stp(reg3, ZR, Address(Rstack_top, -2*wordSize, pre_indexed));
#else
push(RegisterSet(R0, R3) | RegisterSet(R12) | RegisterSet(R14));
#endif // AARCH64
assert(reg3 == noreg, "must not specify reg3");
push(RegisterSet(reg1) | RegisterSet(reg2));
#endif
}
mov(R1, method);
call_VM(noreg, CAST_FROM_FN_PTR(address,
InterpreterRuntime::build_method_counters), R1);
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters), R1);
if (saveRegs) {
#ifdef AARCH64
{
int offset = 0;
ldp(R0, R1, Address(Rstack_top, offset)); offset += 2*wordSize;
ldp(R2, R3, Address(Rstack_top, offset)); offset += 2*wordSize;
ldp(R4, R5, Address(Rstack_top, offset)); offset += 2*wordSize;
ldp(R6, R7, Address(Rstack_top, offset)); offset += 2*wordSize;
ldp(R8, R9, Address(Rstack_top, offset)); offset += 2*wordSize;
ldp(R10, R11, Address(Rstack_top, offset)); offset += 2*wordSize;
ldp(R12, R13, Address(Rstack_top, offset)); offset += 2*wordSize;
ldp(R14, R15, Address(Rstack_top, offset)); offset += 2*wordSize;
ldp(R16, R17, Address(Rstack_top, offset)); offset += 2*wordSize;
ldp(R18, LR, Address(Rstack_top, offset)); offset += 2*wordSize;
assert (offset == saved_regs_size, "should be");
add(Rstack_top, Rstack_top, saved_regs_size);
}
ldp(reg3, ZR, Address(Rstack_top, 2*wordSize, post_indexed));
ldp(reg1, reg2, Address(Rstack_top, 2*wordSize, post_indexed));
#else
pop(RegisterSet(R0, R3) | RegisterSet(R12) | RegisterSet(R14));
#endif // AARCH64
pop(RegisterSet(reg1) | RegisterSet(reg2));
#endif
}
ldr(Rcounters, method_counters);
cbz(Rcounters, skip); // No MethodCounters created, OutOfMemory

View File

@ -53,9 +53,6 @@ class InterpreterMacroAssembler: public MacroAssembler {
// Template interpreter specific version of call_VM_helper
virtual void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions);
virtual void check_and_handle_popframe();
virtual void check_and_handle_earlyret();
// base routine for all dispatches
typedef enum { DispatchDefault, DispatchNormal } DispatchTableMode;
void dispatch_base(TosState state, DispatchTableMode table_mode, bool verifyoop = true);
@ -63,6 +60,9 @@ class InterpreterMacroAssembler: public MacroAssembler {
public:
InterpreterMacroAssembler(CodeBuffer* code);
virtual void check_and_handle_popframe();
virtual void check_and_handle_earlyret();
// Interpreter-specific registers
#if defined(AARCH64) && defined(ASSERT)
@ -141,6 +141,9 @@ class InterpreterMacroAssembler: public MacroAssembler {
// Load object from cpool->resolved_references(*bcp+1)
void load_resolved_reference_at_index(Register result, Register tmp);
// load cpool->resolved_klass_at(index); Rtemp is corrupted upon return
void load_resolved_klass_at_offset(Register Rcpool, Register Rindex, Register Rklass);
void store_check_part1(Register card_table_base); // Sets card_table_base register.
void store_check_part2(Register obj, Register card_table_base, Register tmp);
@ -328,7 +331,13 @@ class InterpreterMacroAssembler: public MacroAssembler {
void trace_state(const char* msg) PRODUCT_RETURN;
void get_method_counters(Register method, Register Rcounters, Label& skip);
void get_method_counters(Register method,
Register Rcounters,
Label& skip,
bool saveRegs = false,
Register reg1 = noreg,
Register reg2 = noreg,
Register reg3 = noreg);
};
#endif // CPU_ARM_VM_INTERP_MASM_ARM_HPP

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, 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
@ -422,7 +422,7 @@ class SlowSignatureHandler: public NativeSignatureIterator {
#endif // !__ABI_HARD__
public:
SlowSignatureHandler(methodHandle method, address from, intptr_t* to) :
SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to) :
NativeSignatureIterator(method) {
_from = from;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, 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
@ -56,7 +56,7 @@ class SignatureHandlerGenerator: public NativeSignatureIterator {
#endif
public:
// Creation
SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
_masm = new MacroAssembler(buffer);
_abi_offset = 0;
_ireg = is_static() ? 2 : 1;

View File

@ -206,6 +206,9 @@ protected:
// may customize this version by overriding it for its purposes (e.g., to save/restore
// additional registers when doing a VM call).
virtual void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions);
public:
MacroAssembler(CodeBuffer* code) : Assembler(code) {}
// These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code.
// The implementation is only non-empty for the InterpreterMacroAssembler,
@ -213,10 +216,6 @@ protected:
virtual void check_and_handle_popframe() {}
virtual void check_and_handle_earlyret() {}
public:
MacroAssembler(CodeBuffer* code) : Assembler(code) {}
// By default, we do not need relocation information for non
// patchable absolute addresses. However, when needed by some
// extensions, ignore_non_patchable_relocations can be modified,

View File

@ -1,99 +0,0 @@
/*
* Copyright (c) 2008, 2015, 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.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "assembler_arm.inline.hpp"
#include "memory/metaspaceShared.hpp"
// Generate the self-patching vtable method:
//
// This method will be called (as any other Klass virtual method) with
// the Klass itself as the first argument. Example:
//
// oop obj;
// int size = obj->klass()->oop_size(this);
//
// for which the virtual method call is Klass::oop_size();
//
// The dummy method is called with the Klass object as the first
// operand, and an object as the second argument.
//
//=====================================================================
// All of the dummy methods in the vtable are essentially identical,
// differing only by an ordinal constant, and they bear no relationship
// to the original method which the caller intended. Also, there needs
// to be 'vtbl_list_size' instances of the vtable in order to
// differentiate between the 'vtable_list_size' original Klass objects.
#define __ masm->
void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
void** vtable,
char** md_top,
char* md_end,
char** mc_top,
char* mc_end) {
intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
*(intptr_t *)(*md_top) = vtable_bytes;
*md_top += sizeof(intptr_t);
void** dummy_vtable = (void**)*md_top;
*vtable = dummy_vtable;
*md_top += vtable_bytes;
CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
MacroAssembler* masm = new MacroAssembler(&cb);
for (int i = 0; i < vtbl_list_size; ++i) {
Label common_code;
for (int j = 0; j < num_virtuals; ++j) {
dummy_vtable[num_virtuals * i + j] = (void*) __ pc();
__ mov(Rtemp, j); // Rtemp contains an index of a virtual method in the table
__ b(common_code);
}
InlinedAddress vtable_address((address)&vtbl_list[i]);
__ bind(common_code);
const Register tmp2 = AARCH64_ONLY(Rtemp2) NOT_AARCH64(R4);
assert_different_registers(Rtemp, tmp2);
#ifndef AARCH64
__ push(tmp2);
#endif // !AARCH64
// Do not use ldr_global since the code must be portable across all ARM architectures
__ ldr_literal(tmp2, vtable_address);
__ ldr(tmp2, Address(tmp2)); // get correct vtable address
__ ldr(Rtemp, Address::indexed_ptr(tmp2, Rtemp)); // get real method pointer
__ str(tmp2, Address(R0)); // update vtable. R0 = "this"
#ifndef AARCH64
__ pop(tmp2);
#endif // !AARCH64
__ jump(Rtemp);
__ bind_literal(vtable_address);
}
__ flush();
*mc_top = (char*) __ pc();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, 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,6 +32,7 @@
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvm.h"
#include "prims/methodHandles.hpp"
#define __ _masm->
@ -67,7 +68,7 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,
Register obj, Register temp1, Register temp2, SystemDictionary::WKID klass_id,
const char* error_message) {
InstanceKlass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
Klass* klass = SystemDictionary::well_known_klass(klass_id);
Label L_ok, L_bad;
BLOCK_COMMENT("verify_klass {");
__ verify_oop(obj);
@ -157,8 +158,9 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
__ load_heap_oop(tmp, Address(tmp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())));
__ verify_oop(tmp);
// the following assumes that a Method* is normally compressed in the vmtarget field:
__ ldr(Rmethod, Address(tmp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())));
__ load_heap_oop(Rmethod, Address(tmp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())));
__ verify_oop(Rmethod);
__ ldr(Rmethod, Address(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())));
if (VerifyMethodHandles && !for_compiler_entry) {
// make sure recv is already on stack
@ -320,7 +322,8 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()));
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()));
Address member_vmtarget(member_reg, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()));
Address member_vmtarget(member_reg, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()));
Address vmtarget_method(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()));
Register temp1_recv_klass = temp1;
if (iid != vmIntrinsics::_linkToStatic) {
@ -375,14 +378,17 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
}
__ ldr(Rmethod, member_vmtarget);
__ load_heap_oop(Rmethod, member_vmtarget);
__ ldr(Rmethod, vmtarget_method);
break;
case vmIntrinsics::_linkToStatic:
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
}
__ ldr(Rmethod, member_vmtarget);
__ load_heap_oop(Rmethod, member_vmtarget);
__ ldr(Rmethod, vmtarget_method);
break;
break;
case vmIntrinsics::_linkToVirtual:

View File

@ -34,6 +34,7 @@
#include "oops/compiledICHolder.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
#include "vmreg_arm.inline.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
@ -747,7 +748,7 @@ void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
assert_different_registers(tmp, R0, R1, R2, R3, R4, R5, R6, R7, Rsender_sp, Rparams);
if (comp_args_on_stack) {
__ sub_slow(SP, SP, round_to(comp_args_on_stack * VMRegImpl::stack_slot_size, StackAlignmentInBytes));
__ sub_slow(SP, SP, align_up(comp_args_on_stack * VMRegImpl::stack_slot_size, StackAlignmentInBytes));
}
for (int i = 0; i < total_args_passed; i++) {
@ -870,7 +871,7 @@ static void gen_c2i_adapter(MacroAssembler *masm,
#ifdef AARCH64
int extraspace = round_to(total_args_passed * Interpreter::stackElementSize, StackAlignmentInBytes);
int extraspace = align_up(total_args_passed * Interpreter::stackElementSize, StackAlignmentInBytes);
if (extraspace) {
__ sub(SP, SP, extraspace);
}
@ -1023,7 +1024,7 @@ static int reg2offset_out(VMReg r) {
static void verify_oop_args(MacroAssembler* masm,
methodHandle method,
const methodHandle& method,
const BasicType* sig_bt,
const VMRegPair* regs) {
Register temp_reg = Rmethod; // not part of any compiled calling seq
@ -1044,7 +1045,7 @@ static void verify_oop_args(MacroAssembler* masm,
}
static void gen_special_dispatch(MacroAssembler* masm,
methodHandle method,
const methodHandle& method,
const BasicType* sig_bt,
const VMRegPair* regs) {
verify_oop_args(masm, method, sig_bt, regs);
@ -1181,7 +1182,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
stack_slots += 2 * VMRegImpl::slots_per_word;
// Calculate the final stack size taking account of alignment
stack_slots = round_to(stack_slots, StackAlignmentInBytes / VMRegImpl::stack_slot_size);
stack_slots = align_up(stack_slots, StackAlignmentInBytes / VMRegImpl::stack_slot_size);
int stack_size = stack_slots * VMRegImpl::stack_slot_size;
int lock_slot_fp_offset = stack_size - 2 * wordSize -
lock_slot_offset * VMRegImpl::stack_slot_size;
@ -1851,7 +1852,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) {
int extra_locals_size = (callee_locals - callee_parameters) * Interpreter::stackElementWords;
#ifdef AARCH64
extra_locals_size = round_to(extra_locals_size, StackAlignmentInBytes/BytesPerWord);
extra_locals_size = align_up(extra_locals_size, StackAlignmentInBytes/BytesPerWord);
#endif // AARCH64
return extra_locals_size;
}

View File

@ -37,6 +37,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "utilities/align.hpp"
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
@ -2876,7 +2877,7 @@ class StubGenerator: public StubCodeGenerator {
BLOCK_COMMENT("PreBarrier");
#ifdef AARCH64
callee_saved_regs = round_to(callee_saved_regs, 2);
callee_saved_regs = align_up(callee_saved_regs, 2);
for (int i = 0; i < callee_saved_regs; i += 2) {
__ raw_push(as_Register(i), as_Register(i+1));
}

View File

@ -45,6 +45,7 @@
#include "runtime/synchronizer.hpp"
#include "runtime/timer.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"
#include "utilities/macros.hpp"
@ -270,12 +271,6 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(const ch
return entry;
}
address TemplateInterpreterGenerator::generate_continuation_for(TosState state) {
// Not used.
STOP("generate_continuation_for");
return NULL;
}
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
address entry = __ pc();
@ -310,6 +305,9 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
__ convert_retval_to_tos(state);
#endif // !AARCH64
__ check_and_handle_popframe();
__ check_and_handle_earlyret();
__ dispatch_next(state, step);
return entry;
@ -678,7 +676,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
// Rstack_top & RextendedSP
__ sub(Rstack_top, SP, 10*wordSize);
if (native_call) {
__ sub(RextendedSP, Rstack_top, round_to(wordSize, StackAlignmentInBytes)); // reserve 1 slot for exception handling
__ sub(RextendedSP, Rstack_top, align_up(wordSize, StackAlignmentInBytes)); // reserve 1 slot for exception handling
} else {
__ sub(RextendedSP, Rstack_top, AsmOperand(RmaxStack, lsl, Interpreter::logStackElementSize));
__ align_reg(RextendedSP, RextendedSP, StackAlignmentInBytes);
@ -1098,7 +1096,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// Allocate more stack space to accomodate all arguments passed on GP and FP registers:
// 8 * wordSize for GPRs
// 8 * wordSize for FPRs
int reg_arguments = round_to(8*wordSize + 8*wordSize, StackAlignmentInBytes);
int reg_arguments = align_up(8*wordSize + 8*wordSize, StackAlignmentInBytes);
#else
// C functions need aligned stack
@ -1111,7 +1109,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// Allocate more stack space to accomodate all GP as well as FP registers:
// 4 * wordSize
// 8 * BytesPerLong
int reg_arguments = round_to((4*wordSize) + (8*BytesPerLong), StackAlignmentInBytes);
int reg_arguments = align_up((4*wordSize) + (8*BytesPerLong), StackAlignmentInBytes);
#else
// Reserve at least 4 words on the stack for loading
// of parameters passed on registers (R0-R3).
@ -1401,7 +1399,13 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
#ifdef AARCH64
// setup RmaxStack
__ ldrh(RmaxStack, Address(RconstMethod, ConstMethod::max_stack_offset()));
__ add(RmaxStack, RmaxStack, MAX2(1, Method::extra_stack_entries())); // reserve slots for exception handler and JSR292 appendix argument
// We have to add extra reserved slots to max_stack. There are 3 users of the extra slots,
// none of which are at the same time, so we just need to make sure there is enough room
// for the biggest user:
// -reserved slot for exception handler
// -reserved slots for JSR292. Method::extra_stack_entries() is the size.
// -3 reserved slots so get_method_counters() can save some registers before call_VM().
__ add(RmaxStack, RmaxStack, MAX2(3, Method::extra_stack_entries()));
#endif // AARCH64
// see if we've got enough room on the stack for locals plus overhead.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, 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
@ -2286,13 +2286,18 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) {
}
__ bind(no_mdo);
// Increment backedge counter in MethodCounters*
__ get_method_counters(Rmethod, Rcounters, dispatch);
// Note Rbumped_taken_count is a callee saved registers for ARM32, but caller saved for ARM64
__ get_method_counters(Rmethod, Rcounters, dispatch, true /*saveRegs*/,
Rdisp, R3_bytecode,
AARCH64_ONLY(Rbumped_taken_count) NOT_AARCH64(noreg));
const Address mask(Rcounters, in_bytes(MethodCounters::backedge_mask_offset()));
__ increment_mask_and_jump(Address(Rcounters, be_offset), increment, mask,
Rcnt, R4_tmp, eq, &backedge_counter_overflow);
} else {
// increment counter
__ get_method_counters(Rmethod, Rcounters, dispatch);
// Increment backedge counter in MethodCounters*
__ get_method_counters(Rmethod, Rcounters, dispatch, true /*saveRegs*/,
Rdisp, R3_bytecode,
AARCH64_ONLY(Rbumped_taken_count) NOT_AARCH64(noreg));
__ ldr_u32(Rtemp, Address(Rcounters, be_offset)); // load backedge counter
__ add(Rtemp, Rtemp, InvocationCounter::count_increment); // increment counter
__ str_32(Rtemp, Address(Rcounters, be_offset)); // store counter
@ -4367,10 +4372,9 @@ void TemplateTable::_new() {
#endif // AARCH64
// get InstanceKlass
__ add(Rklass, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
__ ldr(Rklass, Address(Rklass, sizeof(ConstantPool)));
__ cmp(Rtemp, JVM_CONSTANT_Class);
__ b(slow_case, ne);
__ load_resolved_klass_at_offset(Rcpool, Rindex, Rklass);
// make sure klass is initialized & doesn't have finalizer
// make sure klass is fully initialized
@ -4642,8 +4646,7 @@ void TemplateTable::checkcast() {
// Get superklass in Rsuper and subklass in Rsub
__ bind(quicked);
__ add(Rtemp, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
__ ldr(Rsuper, Address(Rtemp, sizeof(ConstantPool)));
__ load_resolved_klass_at_offset(Rcpool, Rindex, Rsuper);
__ bind(resolved);
__ load_klass(Rsub, Robj);
@ -4716,8 +4719,7 @@ void TemplateTable::instanceof() {
// Get superklass in Rsuper and subklass in Rsub
__ bind(quicked);
__ add(Rtemp, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
__ ldr(Rsuper, Address(Rtemp, sizeof(ConstantPool)));
__ load_resolved_klass_at_offset(Rcpool, Rindex, Rsuper);
__ bind(resolved);
__ load_klass(Rsub, Robj);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, 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
@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvm.h"
#include "runtime/java.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/stubCodeGenerator.hpp"
@ -256,7 +257,9 @@ void VM_Version::initialize() {
}
}
AllocatePrefetchDistance = 128;
if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 128);
}
#ifdef COMPILER2
FLAG_SET_DEFAULT(UseFPUForSpilling, true);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2017, 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
@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvm.h"
#include "runtime/java.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/stubCodeGenerator.hpp"
@ -201,7 +202,9 @@ void VM_Version::initialize() {
}
}
AllocatePrefetchDistance = 128;
if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 128);
}
#ifdef COMPILER2
FLAG_SET_DEFAULT(UseFPUForSpilling, true);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -51,27 +51,6 @@ int AbstractInterpreter::BasicType_as_index(BasicType type) {
return i;
}
// These should never be compiled since the interpreter will prefer
// the compiled version to the intrinsic version.
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
switch (method_kind(m)) {
case Interpreter::java_lang_math_sin : // fall thru
case Interpreter::java_lang_math_cos : // fall thru
case Interpreter::java_lang_math_tan : // fall thru
case Interpreter::java_lang_math_abs : // fall thru
case Interpreter::java_lang_math_log : // fall thru
case Interpreter::java_lang_math_log10 : // fall thru
case Interpreter::java_lang_math_sqrt : // fall thru
case Interpreter::java_lang_math_pow : // fall thru
case Interpreter::java_lang_math_exp : // fall thru
case Interpreter::java_lang_math_fmaD : // fall thru
case Interpreter::java_lang_math_fmaF :
return false;
default:
return true;
}
}
// How much stack a method activation needs in stack slots.
// We must calc this exactly like in generate_fixed_frame.
// Note: This returns the conservative size assuming maximum alignment.

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. 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
@ -376,10 +376,12 @@ class Assembler : public AbstractAssembler {
STWX_OPCODE = (31u << OPCODE_SHIFT | 151u << 1),
STWU_OPCODE = (37u << OPCODE_SHIFT),
STWUX_OPCODE = (31u << OPCODE_SHIFT | 183u << 1),
STWBRX_OPCODE = (31u << OPCODE_SHIFT | 662u << 1),
STH_OPCODE = (44u << OPCODE_SHIFT),
STHX_OPCODE = (31u << OPCODE_SHIFT | 407u << 1),
STHU_OPCODE = (45u << OPCODE_SHIFT),
STHBRX_OPCODE = (31u << OPCODE_SHIFT | 918u << 1),
STB_OPCODE = (38u << OPCODE_SHIFT),
STBX_OPCODE = (31u << OPCODE_SHIFT | 215u << 1),
@ -401,11 +403,13 @@ class Assembler : public AbstractAssembler {
LD_OPCODE = (58u << OPCODE_SHIFT | 0u << XO_30_31_SHIFT), // DS-FORM
LDU_OPCODE = (58u << OPCODE_SHIFT | 1u << XO_30_31_SHIFT), // DS-FORM
LDX_OPCODE = (31u << OPCODE_SHIFT | 21u << XO_21_30_SHIFT), // X-FORM
LDBRX_OPCODE = (31u << OPCODE_SHIFT | 532u << 1), // X-FORM
STD_OPCODE = (62u << OPCODE_SHIFT | 0u << XO_30_31_SHIFT), // DS-FORM
STDU_OPCODE = (62u << OPCODE_SHIFT | 1u << XO_30_31_SHIFT), // DS-FORM
STDUX_OPCODE = (31u << OPCODE_SHIFT | 181u << 1), // X-FORM
STDUX_OPCODE = (31u << OPCODE_SHIFT | 181u << 1), // X-FORM
STDX_OPCODE = (31u << OPCODE_SHIFT | 149u << XO_21_30_SHIFT), // X-FORM
STDBRX_OPCODE = (31u << OPCODE_SHIFT | 660u << 1), // X-FORM
RLDICR_OPCODE = (30u << OPCODE_SHIFT | 1u << XO_27_29_SHIFT), // MD-FORM
RLDICL_OPCODE = (30u << OPCODE_SHIFT | 0u << XO_27_29_SHIFT), // MD-FORM
@ -506,7 +510,13 @@ class Assembler : public AbstractAssembler {
LXVD2X_OPCODE = (31u << OPCODE_SHIFT | 844u << 1),
STXVD2X_OPCODE = (31u << OPCODE_SHIFT | 972u << 1),
MTVSRD_OPCODE = (31u << OPCODE_SHIFT | 179u << 1),
MTVSRWZ_OPCODE = (31u << OPCODE_SHIFT | 243u << 1),
MFVSRD_OPCODE = (31u << OPCODE_SHIFT | 51u << 1),
MTVSRWA_OPCODE = (31u << OPCODE_SHIFT | 211u << 1),
MFVSRWZ_OPCODE = (31u << OPCODE_SHIFT | 115u << 1),
XXPERMDI_OPCODE= (60u << OPCODE_SHIFT | 10u << 3),
XXMRGHW_OPCODE = (60u << OPCODE_SHIFT | 18u << 3),
XXMRGLW_OPCODE = (60u << OPCODE_SHIFT | 50u << 3),
// Vector Permute and Formatting
VPKPX_OPCODE = (4u << OPCODE_SHIFT | 782u ),
@ -556,6 +566,7 @@ class Assembler : public AbstractAssembler {
VADDUBM_OPCODE = (4u << OPCODE_SHIFT | 0u ),
VADDUWM_OPCODE = (4u << OPCODE_SHIFT | 128u ),
VADDUHM_OPCODE = (4u << OPCODE_SHIFT | 64u ),
VADDUDM_OPCODE = (4u << OPCODE_SHIFT | 192u ),
VADDUBS_OPCODE = (4u << OPCODE_SHIFT | 512u ),
VADDUWS_OPCODE = (4u << OPCODE_SHIFT | 640u ),
VADDUHS_OPCODE = (4u << OPCODE_SHIFT | 576u ),
@ -1094,16 +1105,19 @@ class Assembler : public AbstractAssembler {
static int vrs( VectorRegister r) { return vrs(r->encoding());}
static int vrt( VectorRegister r) { return vrt(r->encoding());}
// Only used on SHA sigma instructions (VX-form)
static int vst( int x) { return opp_u_field(x, 16, 16); }
static int vsix( int x) { return opp_u_field(x, 20, 17); }
// Support Vector-Scalar (VSX) instructions.
static int vsra( int x) { return opp_u_field(x, 15, 11); }
static int vsrb( int x) { return opp_u_field(x, 20, 16); }
static int vsrc( int x) { return opp_u_field(x, 25, 21); }
static int vsrs( int x) { return opp_u_field(x, 10, 6); }
static int vsrt( int x) { return opp_u_field(x, 10, 6); }
static int vsra( int x) { return opp_u_field(x & 0x1F, 15, 11) | opp_u_field((x & 0x20) >> 5, 29, 29); }
static int vsrb( int x) { return opp_u_field(x & 0x1F, 20, 16) | opp_u_field((x & 0x20) >> 5, 30, 30); }
static int vsrs( int x) { return opp_u_field(x & 0x1F, 10, 6) | opp_u_field((x & 0x20) >> 5, 31, 31); }
static int vsrt( int x) { return vsrs(x); }
static int vsdm( int x) { return opp_u_field(x, 23, 22); }
static int vsra( VectorSRegister r) { return vsra(r->encoding());}
static int vsrb( VectorSRegister r) { return vsrb(r->encoding());}
static int vsrc( VectorSRegister r) { return vsrc(r->encoding());}
static int vsrs( VectorSRegister r) { return vsrs(r->encoding());}
static int vsrt( VectorSRegister r) { return vsrt(r->encoding());}
@ -1552,6 +1566,9 @@ class Assembler : public AbstractAssembler {
inline void ld( Register d, int si16, Register s1);
inline void ldu( Register d, int si16, Register s1);
// 8 bytes reversed
inline void ldbrx( Register d, Register s1, Register s2);
// For convenience. Load pointer into d from b+s1.
inline void ld_ptr(Register d, int b, Register s1);
DEBUG_ONLY(inline void ld_ptr(Register d, ByteSize b, Register s1);)
@ -1560,10 +1577,12 @@ class Assembler : public AbstractAssembler {
inline void stwx( Register d, Register s1, Register s2);
inline void stw( Register d, int si16, Register s1);
inline void stwu( Register d, int si16, Register s1);
inline void stwbrx( Register d, Register s1, Register s2);
inline void sthx( Register d, Register s1, Register s2);
inline void sth( Register d, int si16, Register s1);
inline void sthu( Register d, int si16, Register s1);
inline void sthbrx( Register d, Register s1, Register s2);
inline void stbx( Register d, Register s1, Register s2);
inline void stb( Register d, int si16, Register s1);
@ -1573,6 +1592,7 @@ class Assembler : public AbstractAssembler {
inline void std( Register d, int si16, Register s1);
inline void stdu( Register d, int si16, Register s1);
inline void stdux(Register s, Register a, Register b);
inline void stdbrx( Register d, Register s1, Register s2);
inline void st_ptr(Register d, int si16, Register s1);
DEBUG_ONLY(inline void st_ptr(Register d, ByteSize b, Register s1);)
@ -2016,7 +2036,7 @@ class Assembler : public AbstractAssembler {
inline void vperm( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c);
inline void vsel( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c);
inline void vsl( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vsldoi( VectorRegister d, VectorRegister a, VectorRegister b, int si4);
inline void vsldoi( VectorRegister d, VectorRegister a, VectorRegister b, int ui4);
inline void vslo( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vsr( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vsro( VectorRegister d, VectorRegister a, VectorRegister b);
@ -2027,6 +2047,7 @@ class Assembler : public AbstractAssembler {
inline void vaddubm( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vadduwm( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vadduhm( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vaddudm( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vaddubs( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vadduws( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vadduhs( VectorRegister d, VectorRegister a, VectorRegister b);
@ -2102,6 +2123,7 @@ class Assembler : public AbstractAssembler {
inline void vandc( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vnor( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vor( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vmr( VectorRegister d, VectorRegister a);
inline void vxor( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vrld( VectorRegister d, VectorRegister a, VectorRegister b);
inline void vrlb( VectorRegister d, VectorRegister a, VectorRegister b);
@ -2125,8 +2147,24 @@ class Assembler : public AbstractAssembler {
inline void lxvd2x( VectorSRegister d, Register a, Register b);
inline void stxvd2x( VectorSRegister d, Register a);
inline void stxvd2x( VectorSRegister d, Register a, Register b);
inline void mtvrwz( VectorRegister d, Register a);
inline void mfvrwz( Register a, VectorRegister d);
inline void mtvrd( VectorRegister d, Register a);
inline void mfvrd( Register a, VectorRegister d);
inline void xxpermdi( VectorSRegister d, VectorSRegister a, VectorSRegister b, int dm);
inline void xxmrghw( VectorSRegister d, VectorSRegister a, VectorSRegister b);
inline void xxmrglw( VectorSRegister d, VectorSRegister a, VectorSRegister b);
// VSX Extended Mnemonics
inline void xxspltd( VectorSRegister d, VectorSRegister a, int x);
inline void xxmrghd( VectorSRegister d, VectorSRegister a, VectorSRegister b);
inline void xxmrgld( VectorSRegister d, VectorSRegister a, VectorSRegister b);
inline void xxswapd( VectorSRegister d, VectorSRegister a);
// Vector-Scalar (VSX) instructions.
inline void mtfprd( FloatRegister d, Register a);
inline void mtfprwa( FloatRegister d, Register a);
inline void mffprd( Register a, FloatRegister d);
// AES (introduced with Power 8)
inline void vcipher( VectorRegister d, VectorRegister a, VectorRegister b);
@ -2182,14 +2220,18 @@ class Assembler : public AbstractAssembler {
inline void lbz( Register d, int si16);
inline void ldx( Register d, Register s2);
inline void ld( Register d, int si16);
inline void ldbrx(Register d, Register s2);
inline void stwx( Register d, Register s2);
inline void stw( Register d, int si16);
inline void stwbrx( Register d, Register s2);
inline void sthx( Register d, Register s2);
inline void sth( Register d, int si16);
inline void sthbrx( Register d, Register s2);
inline void stbx( Register d, Register s2);
inline void stb( Register d, int si16);
inline void stdx( Register d, Register s2);
inline void std( Register d, int si16);
inline void stdbrx( Register d, Register s2);
// PPC 2, section 3.2.1 Instruction Cache Instructions
inline void icbi( Register s2);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. 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
@ -327,6 +327,7 @@ inline void Assembler::lbzu( Register d, int si16, Register s1) { assert(d !=
inline void Assembler::ld( Register d, int si16, Register s1) { emit_int32(LD_OPCODE | rt(d) | ds(si16) | ra0mem(s1));}
inline void Assembler::ldx( Register d, Register s1, Register s2) { emit_int32(LDX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::ldu( Register d, int si16, Register s1) { assert(d != s1, "according to ibm manual"); emit_int32(LDU_OPCODE | rt(d) | ds(si16) | rta0mem(s1));}
inline void Assembler::ldbrx( Register d, Register s1, Register s2) { emit_int32(LDBRX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::ld_ptr(Register d, int b, Register s1) { ld(d, b, s1); }
DEBUG_ONLY(inline void Assembler::ld_ptr(Register d, ByteSize b, Register s1) { ld(d, in_bytes(b), s1); })
@ -335,10 +336,12 @@ DEBUG_ONLY(inline void Assembler::ld_ptr(Register d, ByteSize b, Register s1) {
inline void Assembler::stwx( Register d, Register s1, Register s2) { emit_int32(STWX_OPCODE | rs(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::stw( Register d, int si16, Register s1) { emit_int32(STW_OPCODE | rs(d) | d1(si16) | ra0mem(s1));}
inline void Assembler::stwu( Register d, int si16, Register s1) { emit_int32(STWU_OPCODE | rs(d) | d1(si16) | rta0mem(s1));}
inline void Assembler::stwbrx( Register d, Register s1, Register s2) { emit_int32(STWBRX_OPCODE | rs(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::sthx( Register d, Register s1, Register s2) { emit_int32(STHX_OPCODE | rs(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::sth( Register d, int si16, Register s1) { emit_int32(STH_OPCODE | rs(d) | d1(si16) | ra0mem(s1));}
inline void Assembler::sthu( Register d, int si16, Register s1) { emit_int32(STHU_OPCODE | rs(d) | d1(si16) | rta0mem(s1));}
inline void Assembler::sthbrx( Register d, Register s1, Register s2) { emit_int32(STHBRX_OPCODE | rs(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::stbx( Register d, Register s1, Register s2) { emit_int32(STBX_OPCODE | rs(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::stb( Register d, int si16, Register s1) { emit_int32(STB_OPCODE | rs(d) | d1(si16) | ra0mem(s1));}
@ -348,6 +351,7 @@ inline void Assembler::std( Register d, int si16, Register s1) { emit_int32(
inline void Assembler::stdx( Register d, Register s1, Register s2) { emit_int32(STDX_OPCODE | rs(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::stdu( Register d, int si16, Register s1) { emit_int32(STDU_OPCODE | rs(d) | ds(si16) | rta0mem(s1));}
inline void Assembler::stdux(Register s, Register a, Register b) { emit_int32(STDUX_OPCODE| rs(s) | rta0mem(a) | rb(b));}
inline void Assembler::stdbrx( Register d, Register s1, Register s2) { emit_int32(STDBRX_OPCODE | rs(d) | ra0mem(s1) | rb(s2));}
inline void Assembler::st_ptr(Register d, int b, Register s1) { std(d, b, s1); }
DEBUG_ONLY(inline void Assembler::st_ptr(Register d, ByteSize b, Register s1) { std(d, in_bytes(b), s1); })
@ -754,12 +758,28 @@ inline void Assembler::lvsl( VectorRegister d, Register s1, Register s2) { emit
inline void Assembler::lvsr( VectorRegister d, Register s1, Register s2) { emit_int32( LVSR_OPCODE | vrt(d) | ra0mem(s1) | rb(s2)); }
// Vector-Scalar (VSX) instructions.
inline void Assembler::lxvd2x (VectorSRegister d, Register s1) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra(0) | rb(s1)); }
inline void Assembler::lxvd2x (VectorSRegister d, Register s1, Register s2) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra0mem(s1) | rb(s2)); }
inline void Assembler::stxvd2x(VectorSRegister d, Register s1) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra(0) | rb(s1)); }
inline void Assembler::stxvd2x(VectorSRegister d, Register s1, Register s2) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra0mem(s1) | rb(s2)); }
inline void Assembler::mtvrd( VectorRegister d, Register a) { emit_int32( MTVSRD_OPCODE | vrt(d) | ra(a) | 1u); } // 1u: d is treated as Vector (VMX/Altivec).
inline void Assembler::mfvrd( Register a, VectorRegister d) { emit_int32( MFVSRD_OPCODE | vrt(d) | ra(a) | 1u); } // 1u: d is treated as Vector (VMX/Altivec).
inline void Assembler::lxvd2x( VectorSRegister d, Register s1) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra(0) | rb(s1)); }
inline void Assembler::lxvd2x( VectorSRegister d, Register s1, Register s2) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra0mem(s1) | rb(s2)); }
inline void Assembler::stxvd2x( VectorSRegister d, Register s1) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra(0) | rb(s1)); }
inline void Assembler::stxvd2x( VectorSRegister d, Register s1, Register s2) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra0mem(s1) | rb(s2)); }
inline void Assembler::mtvrd( VectorRegister d, Register a) { emit_int32( MTVSRD_OPCODE | vsrt(d->to_vsr()) | ra(a)); }
inline void Assembler::mfvrd( Register a, VectorRegister d) { emit_int32( MFVSRD_OPCODE | vsrt(d->to_vsr()) | ra(a)); }
inline void Assembler::mtvrwz( VectorRegister d, Register a) { emit_int32( MTVSRWZ_OPCODE | vsrt(d->to_vsr()) | ra(a)); }
inline void Assembler::mfvrwz( Register a, VectorRegister d) { emit_int32( MFVSRWZ_OPCODE | vsrt(d->to_vsr()) | ra(a)); }
inline void Assembler::xxpermdi(VectorSRegister d, VectorSRegister a, VectorSRegister b, int dm) { emit_int32( XXPERMDI_OPCODE | vsrt(d) | vsra(a) | vsrb(b) | vsdm(dm)); }
inline void Assembler::xxmrghw( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XXMRGHW_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
inline void Assembler::xxmrglw( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XXMRGHW_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
// VSX Extended Mnemonics
inline void Assembler::xxspltd( VectorSRegister d, VectorSRegister a, int x) { xxpermdi(d, a, a, x ? 3 : 0); }
inline void Assembler::xxmrghd( VectorSRegister d, VectorSRegister a, VectorSRegister b) { xxpermdi(d, a, b, 0); }
inline void Assembler::xxmrgld( VectorSRegister d, VectorSRegister a, VectorSRegister b) { xxpermdi(d, a, b, 3); }
inline void Assembler::xxswapd( VectorSRegister d, VectorSRegister a) { xxpermdi(d, a, a, 2); }
// Vector-Scalar (VSX) instructions.
inline void Assembler::mtfprd( FloatRegister d, Register a) { emit_int32( MTVSRD_OPCODE | frt(d) | ra(a)); }
inline void Assembler::mtfprwa( FloatRegister d, Register a) { emit_int32( MTVSRWA_OPCODE | frt(d) | ra(a)); }
inline void Assembler::mffprd( Register a, FloatRegister d) { emit_int32( MFVSRD_OPCODE | frt(d) | ra(a)); }
inline void Assembler::vpkpx( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPKPX_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vpkshss( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPKSHSS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
@ -791,7 +811,7 @@ inline void Assembler::vspltisw(VectorRegister d, int si5)
inline void Assembler::vperm( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c){ emit_int32( VPERM_OPCODE | vrt(d) | vra(a) | vrb(b) | vrc(c)); }
inline void Assembler::vsel( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c){ emit_int32( VSEL_OPCODE | vrt(d) | vra(a) | vrb(b) | vrc(c)); }
inline void Assembler::vsl( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSL_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vsldoi( VectorRegister d, VectorRegister a, VectorRegister b, int si4) { emit_int32( VSLDOI_OPCODE| vrt(d) | vra(a) | vrb(b) | vsldoi_shb(simm(si4,4))); }
inline void Assembler::vsldoi( VectorRegister d, VectorRegister a, VectorRegister b, int ui4) { emit_int32( VSLDOI_OPCODE| vrt(d) | vra(a) | vrb(b) | vsldoi_shb(uimm(ui4,4))); }
inline void Assembler::vslo( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSLO_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vsr( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSR_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vsro( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSRO_OPCODE | vrt(d) | vra(a) | vrb(b)); }
@ -802,6 +822,7 @@ inline void Assembler::vaddsws( VectorRegister d, VectorRegister a, VectorRegist
inline void Assembler::vaddubm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUBM_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vadduwm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUWM_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vadduhm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUHM_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vaddudm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUDM_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vaddubs( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUBS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vadduws( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUWS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vadduhs( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUHS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
@ -878,6 +899,7 @@ inline void Assembler::vand( VectorRegister d, VectorRegister a, VectorRegist
inline void Assembler::vandc( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VANDC_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vnor( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VNOR_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vor( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VOR_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vmr( VectorRegister d, VectorRegister a) { emit_int32( VOR_OPCODE | vrt(d) | vra(a) | vrb(a)); }
inline void Assembler::vxor( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VXOR_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vrld( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VRLD_OPCODE | vrt(d) | vra(a) | vrb(b)); }
inline void Assembler::vrlb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VRLB_OPCODE | vrt(d) | vra(a) | vrb(b)); }
@ -944,14 +966,18 @@ inline void Assembler::lbzx( Register d, Register s2) { emit_int32( LBZX_OPCODE
inline void Assembler::lbz( Register d, int si16 ) { emit_int32( LBZ_OPCODE | rt(d) | d1(si16));}
inline void Assembler::ld( Register d, int si16 ) { emit_int32( LD_OPCODE | rt(d) | ds(si16));}
inline void Assembler::ldx( Register d, Register s2) { emit_int32( LDX_OPCODE | rt(d) | rb(s2));}
inline void Assembler::ldbrx(Register d, Register s2) { emit_int32( LDBRX_OPCODE| rt(d) | rb(s2));}
inline void Assembler::stwx( Register d, Register s2) { emit_int32( STWX_OPCODE | rs(d) | rb(s2));}
inline void Assembler::stw( Register d, int si16 ) { emit_int32( STW_OPCODE | rs(d) | d1(si16));}
inline void Assembler::stwbrx(Register d, Register s2){ emit_int32(STWBRX_OPCODE| rs(d) | rb(s2));}
inline void Assembler::sthx( Register d, Register s2) { emit_int32( STHX_OPCODE | rs(d) | rb(s2));}
inline void Assembler::sth( Register d, int si16 ) { emit_int32( STH_OPCODE | rs(d) | d1(si16));}
inline void Assembler::sthbrx(Register d, Register s2){ emit_int32(STHBRX_OPCODE| rs(d) | rb(s2));}
inline void Assembler::stbx( Register d, Register s2) { emit_int32( STBX_OPCODE | rs(d) | rb(s2));}
inline void Assembler::stb( Register d, int si16 ) { emit_int32( STB_OPCODE | rs(d) | d1(si16));}
inline void Assembler::std( Register d, int si16 ) { emit_int32( STD_OPCODE | rs(d) | ds(si16));}
inline void Assembler::stdx( Register d, Register s2) { emit_int32( STDX_OPCODE | rs(d) | rb(s2));}
inline void Assembler::stdbrx(Register d, Register s2){ emit_int32(STDBRX_OPCODE| rs(d) | rb(s2));}
// ra0 version
inline void Assembler::icbi( Register s2) { emit_int32( ICBI_OPCODE | rb(s2) ); }

View File

@ -37,10 +37,6 @@ class Bytes: AllStatic {
#if defined(VM_LITTLE_ENDIAN)
// Returns true, if the byte ordering used by Java is different from the native byte ordering
// of the underlying machine. For example, true for Intel x86, False, for Solaris on Sparc.
static inline bool is_Java_byte_ordering_different() { return true; }
// Forward declarations of the compiler-dependent implementation
static inline u2 swap_u2(u2 x);
static inline u4 swap_u4(u4 x);
@ -155,10 +151,6 @@ class Bytes: AllStatic {
#else // !defined(VM_LITTLE_ENDIAN)
// Returns true, if the byte ordering used by Java is different from the nativ byte ordering
// of the underlying machine. For example, true for Intel x86, False, for Solaris on Sparc.
static inline bool is_Java_byte_ordering_different() { return false; }
// Thus, a swap between native and Java ordering is always a no-op:
static inline u2 swap_u2(u2 x) { return x; }
static inline u4 swap_u4(u4 x) { return x; }

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017, SAP SE. 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
@ -514,25 +514,48 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) {
}
case Bytecodes::_i2d:
case Bytecodes::_l2d: {
__ fcfid(dst->as_double_reg(), src->as_double_reg()); // via mem
bool src_in_memory = !VM_Version::has_mtfprd();
FloatRegister rdst = dst->as_double_reg();
FloatRegister rsrc;
if (src_in_memory) {
rsrc = src->as_double_reg(); // via mem
} else {
// move src to dst register
if (code == Bytecodes::_i2d) {
__ mtfprwa(rdst, src->as_register());
} else {
__ mtfprd(rdst, src->as_register_lo());
}
rsrc = rdst;
}
__ fcfid(rdst, rsrc);
break;
}
case Bytecodes::_i2f: {
case Bytecodes::_i2f:
case Bytecodes::_l2f: {
bool src_in_memory = !VM_Version::has_mtfprd();
FloatRegister rdst = dst->as_float_reg();
FloatRegister rsrc = src->as_double_reg(); // via mem
FloatRegister rsrc;
if (src_in_memory) {
rsrc = src->as_double_reg(); // via mem
} else {
// move src to dst register
if (code == Bytecodes::_i2f) {
__ mtfprwa(rdst, src->as_register());
} else {
__ mtfprd(rdst, src->as_register_lo());
}
rsrc = rdst;
}
if (VM_Version::has_fcfids()) {
__ fcfids(rdst, rsrc);
} else {
assert(code == Bytecodes::_i2f, "fcfid+frsp needs fixup code to avoid rounding incompatibility");
__ fcfid(rdst, rsrc);
__ frsp(rdst, rdst);
}
break;
}
case Bytecodes::_l2f: { // >= Power7
assert(VM_Version::has_fcfids(), "fcfid+frsp needs fixup code to avoid rounding incompatibility");
__ fcfids(dst->as_float_reg(), src->as_double_reg()); // via mem
break;
}
case Bytecodes::_f2d: {
__ fmr_if_needed(dst->as_double_reg(), src->as_float_reg());
break;
@ -543,31 +566,49 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) {
}
case Bytecodes::_d2i:
case Bytecodes::_f2i: {
bool dst_in_memory = !VM_Version::has_mtfprd();
FloatRegister rsrc = (code == Bytecodes::_d2i) ? src->as_double_reg() : src->as_float_reg();
Address addr = frame_map()->address_for_slot(dst->double_stack_ix());
Address addr = dst_in_memory ? frame_map()->address_for_slot(dst->double_stack_ix()) : NULL;
Label L;
// Result must be 0 if value is NaN; test by comparing value to itself.
__ fcmpu(CCR0, rsrc, rsrc);
__ li(R0, 0); // 0 in case of NAN
__ std(R0, addr.disp(), addr.base());
if (dst_in_memory) {
__ li(R0, 0); // 0 in case of NAN
__ std(R0, addr.disp(), addr.base());
} else {
__ li(dst->as_register(), 0);
}
__ bso(CCR0, L);
__ fctiwz(rsrc, rsrc); // USE_KILL
__ stfd(rsrc, addr.disp(), addr.base());
if (dst_in_memory) {
__ stfd(rsrc, addr.disp(), addr.base());
} else {
__ mffprd(dst->as_register(), rsrc);
}
__ bind(L);
break;
}
case Bytecodes::_d2l:
case Bytecodes::_f2l: {
bool dst_in_memory = !VM_Version::has_mtfprd();
FloatRegister rsrc = (code == Bytecodes::_d2l) ? src->as_double_reg() : src->as_float_reg();
Address addr = frame_map()->address_for_slot(dst->double_stack_ix());
Address addr = dst_in_memory ? frame_map()->address_for_slot(dst->double_stack_ix()) : NULL;
Label L;
// Result must be 0 if value is NaN; test by comparing value to itself.
__ fcmpu(CCR0, rsrc, rsrc);
__ li(R0, 0); // 0 in case of NAN
__ std(R0, addr.disp(), addr.base());
if (dst_in_memory) {
__ li(R0, 0); // 0 in case of NAN
__ std(R0, addr.disp(), addr.base());
} else {
__ li(dst->as_register_lo(), 0);
}
__ bso(CCR0, L);
__ fctidz(rsrc, rsrc); // USE_KILL
__ stfd(rsrc, addr.disp(), addr.base());
if (dst_in_memory) {
__ stfd(rsrc, addr.disp(), addr.base());
} else {
__ mffprd(dst->as_register_lo(), rsrc);
}
__ bind(L);
break;
}
@ -3177,9 +3218,8 @@ void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) {
assert_different_registers(val, crc, res);
__ load_const_optimized(res, StubRoutines::crc_table_addr(), R0);
__ nand(crc, crc, crc); // ~crc
__ update_byte_crc32(crc, val, res);
__ nand(res, crc, crc); // ~crc
__ kernel_crc32_singleByteReg(crc, val, res, true);
__ mr(res, crc);
}
#undef __

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017, SAP SE. 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
@ -63,18 +63,6 @@ void LIRItem::load_nonconstant() {
}
inline void load_int_as_long(LIR_List *ll, LIRItem &li, LIR_Opr dst) {
LIR_Opr r = li.value()->operand();
if (r->is_register()) {
LIR_Opr dst_l = FrameMap::as_long_opr(dst->as_register());
ll->convert(Bytecodes::_i2l, li.result(), dst_l); // Convert.
} else {
// Constants or memory get loaded with sign extend on this platform.
ll->move(li.result(), dst);
}
}
//--------------------------------------------------------------
// LIRGenerator
//--------------------------------------------------------------
@ -883,81 +871,91 @@ void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f
// _i2b, _i2c, _i2s
void LIRGenerator::do_Convert(Convert* x) {
switch (x->op()) {
if (!VM_Version::has_mtfprd()) {
switch (x->op()) {
// int -> float: force spill
case Bytecodes::_l2f: {
if (!VM_Version::has_fcfids()) { // fcfids is >= Power7 only
// fcfid+frsp needs fixup code to avoid rounding incompatibility.
address entry = CAST_FROM_FN_PTR(address, SharedRuntime::l2f);
LIR_Opr result = call_runtime(x->value(), entry, x->type(), NULL);
set_result(x, result);
// int -> float: force spill
case Bytecodes::_l2f: {
if (!VM_Version::has_fcfids()) { // fcfids is >= Power7 only
// fcfid+frsp needs fixup code to avoid rounding incompatibility.
address entry = CAST_FROM_FN_PTR(address, SharedRuntime::l2f);
LIR_Opr result = call_runtime(x->value(), entry, x->type(), NULL);
set_result(x, result);
return;
} // else fallthru
}
case Bytecodes::_l2d: {
LIRItem value(x->value(), this);
LIR_Opr reg = rlock_result(x);
value.load_item();
LIR_Opr tmp = force_to_spill(value.result(), T_DOUBLE);
__ convert(x->op(), tmp, reg);
return;
}
case Bytecodes::_i2f:
case Bytecodes::_i2d: {
LIRItem value(x->value(), this);
LIR_Opr reg = rlock_result(x);
value.load_item();
// Convert i2l first.
LIR_Opr tmp1 = new_register(T_LONG);
__ convert(Bytecodes::_i2l, value.result(), tmp1);
LIR_Opr tmp2 = force_to_spill(tmp1, T_DOUBLE);
__ convert(x->op(), tmp2, reg);
return;
}
// float -> int: result will be stored
case Bytecodes::_f2l:
case Bytecodes::_d2l: {
LIRItem value(x->value(), this);
LIR_Opr reg = rlock_result(x);
value.set_destroys_register(); // USE_KILL
value.load_item();
set_vreg_flag(reg, must_start_in_memory);
__ convert(x->op(), value.result(), reg);
return;
}
case Bytecodes::_f2i:
case Bytecodes::_d2i: {
LIRItem value(x->value(), this);
LIR_Opr reg = rlock_result(x);
value.set_destroys_register(); // USE_KILL
value.load_item();
// Convert l2i afterwards.
LIR_Opr tmp1 = new_register(T_LONG);
set_vreg_flag(tmp1, must_start_in_memory);
__ convert(x->op(), value.result(), tmp1);
__ convert(Bytecodes::_l2i, tmp1, reg);
return;
}
// Within same category: just register conversions.
case Bytecodes::_i2b:
case Bytecodes::_i2c:
case Bytecodes::_i2s:
case Bytecodes::_i2l:
case Bytecodes::_l2i:
case Bytecodes::_f2d:
case Bytecodes::_d2f:
break;
} // else fallthru
}
case Bytecodes::_l2d: {
LIRItem value(x->value(), this);
LIR_Opr reg = rlock_result(x);
value.load_item();
LIR_Opr tmp = force_to_spill(value.result(), T_DOUBLE);
__ convert(x->op(), tmp, reg);
break;
}
case Bytecodes::_i2f:
case Bytecodes::_i2d: {
LIRItem value(x->value(), this);
LIR_Opr reg = rlock_result(x);
value.load_item();
// Convert i2l first.
LIR_Opr tmp1 = new_register(T_LONG);
__ convert(Bytecodes::_i2l, value.result(), tmp1);
LIR_Opr tmp2 = force_to_spill(tmp1, T_DOUBLE);
__ convert(x->op(), tmp2, reg);
break;
}
// float -> int: result will be stored
case Bytecodes::_f2l:
case Bytecodes::_d2l: {
LIRItem value(x->value(), this);
LIR_Opr reg = rlock_result(x);
value.set_destroys_register(); // USE_KILL
value.load_item();
set_vreg_flag(reg, must_start_in_memory);
__ convert(x->op(), value.result(), reg);
break;
default: ShouldNotReachHere();
}
case Bytecodes::_f2i:
case Bytecodes::_d2i: {
LIRItem value(x->value(), this);
LIR_Opr reg = rlock_result(x);
value.set_destroys_register(); // USE_KILL
value.load_item();
// Convert l2i afterwards.
LIR_Opr tmp1 = new_register(T_LONG);
set_vreg_flag(tmp1, must_start_in_memory);
__ convert(x->op(), value.result(), tmp1);
__ convert(Bytecodes::_l2i, tmp1, reg);
break;
}
// Within same category: just register conversions.
case Bytecodes::_i2b:
case Bytecodes::_i2c:
case Bytecodes::_i2s:
case Bytecodes::_i2l:
case Bytecodes::_l2i:
case Bytecodes::_f2d:
case Bytecodes::_d2f: {
LIRItem value(x->value(), this);
LIR_Opr reg = rlock_result(x);
value.load_item();
__ convert(x->op(), value.result(), reg);
break;
}
default: ShouldNotReachHere();
}
// Register conversion.
LIRItem value(x->value(), this);
LIR_Opr reg = rlock_result(x);
value.load_item();
switch (x->op()) {
case Bytecodes::_f2l:
case Bytecodes::_d2l:
case Bytecodes::_f2i:
case Bytecodes::_d2i: value.set_destroys_register(); break; // USE_KILL
default: break;
}
__ convert(x->op(), value.result(), reg);
}
@ -1426,10 +1424,9 @@ void LIRGenerator::do_update_CRC32(Intrinsic* x) {
arg2 = cc->at(1),
arg3 = cc->at(2);
// CCallingConventionRequiresIntsAsLongs
crc.load_item_force(arg1); // We skip int->long conversion here, because CRC32 stub doesn't care about high bits.
__ leal(LIR_OprFact::address(a), arg2);
load_int_as_long(gen()->lir(), len, arg3);
len.load_item_force(arg3); // We skip int->long conversion here, , because CRC32 stub expects int.
__ call_runtime_leaf(StubRoutines::updateBytesCRC32(), LIR_OprFact::illegalOpr, result_reg, cc->args());
__ move(result_reg, result);
@ -1441,6 +1438,76 @@ void LIRGenerator::do_update_CRC32(Intrinsic* x) {
}
}
void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
assert(UseCRC32CIntrinsics, "or should not be here");
LIR_Opr result = rlock_result(x);
switch (x->id()) {
case vmIntrinsics::_updateBytesCRC32C:
case vmIntrinsics::_updateDirectByteBufferCRC32C: {
bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32C);
LIRItem crc(x->argument_at(0), this);
LIRItem buf(x->argument_at(1), this);
LIRItem off(x->argument_at(2), this);
LIRItem end(x->argument_at(3), this);
buf.load_item();
off.load_nonconstant();
end.load_nonconstant();
// len = end - off
LIR_Opr len = end.result();
LIR_Opr tmpA = new_register(T_INT);
LIR_Opr tmpB = new_register(T_INT);
__ move(end.result(), tmpA);
__ move(off.result(), tmpB);
__ sub(tmpA, tmpB, tmpA);
len = tmpA;
LIR_Opr index = off.result();
int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0;
if (off.result()->is_constant()) {
index = LIR_OprFact::illegalOpr;
offset += off.result()->as_jint();
}
LIR_Opr base_op = buf.result();
LIR_Address* a = NULL;
if (index->is_valid()) {
LIR_Opr tmp = new_register(T_LONG);
__ convert(Bytecodes::_i2l, index, tmp);
index = tmp;
__ add(index, LIR_OprFact::intptrConst(offset), index);
a = new LIR_Address(base_op, index, T_BYTE);
} else {
a = new LIR_Address(base_op, offset, T_BYTE);
}
BasicTypeList signature(3);
signature.append(T_INT);
signature.append(T_ADDRESS);
signature.append(T_INT);
CallingConvention* cc = frame_map()->c_calling_convention(&signature);
const LIR_Opr result_reg = result_register_for(x->type());
LIR_Opr arg1 = cc->at(0),
arg2 = cc->at(1),
arg3 = cc->at(2);
crc.load_item_force(arg1); // We skip int->long conversion here, because CRC32C stub doesn't care about high bits.
__ leal(LIR_OprFact::address(a), arg2);
__ move(len, cc->at(2)); // We skip int->long conversion here, because CRC32C stub expects int.
__ call_runtime_leaf(StubRoutines::updateBytesCRC32C(), LIR_OprFact::illegalOpr, result_reg, cc->args());
__ move(result_reg, result);
break;
}
default: {
ShouldNotReachHere();
}
}
}
void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
assert(x->number_of_arguments() == 3, "wrong type");
assert(UseFMA, "Needs FMA instructions support.");
@ -1467,7 +1534,3 @@ void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
fatal("vectorizedMismatch intrinsic is not implemented on this platform");
}
void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
Unimplemented();
}

View File

@ -36,6 +36,7 @@
#include "runtime/os.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/align.hpp"
void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
@ -340,7 +341,7 @@ void C1_MacroAssembler::allocate_array(
// Check for negative or excessive length.
size_t max_length = max_array_allocation_length >> log2_elt_size;
if (UseTLAB) {
size_t max_tlab = align_size_up(ThreadLocalAllocBuffer::max_size() >> log2_elt_size, 64*K);
size_t max_tlab = align_up(ThreadLocalAllocBuffer::max_size() >> log2_elt_size, 64*K);
if (max_tlab < max_length) { max_length = max_tlab; }
}
load_const_optimized(t1, max_length);

View File

@ -36,6 +36,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/signature.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
#include "utilities/macros.hpp"
#include "vmreg_ppc.inline.hpp"
#if INCLUDE_ALL_GCS
@ -251,7 +252,7 @@ void Runtime1::initialize_pd() {
fpu_reg_save_offsets[i] = sp_offset;
sp_offset += BytesPerWord;
}
frame_size_in_bytes = align_size_up(sp_offset, frame::alignment_in_bytes);
frame_size_in_bytes = align_up(sp_offset, frame::alignment_in_bytes);
}
@ -275,7 +276,7 @@ OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address targe
static OopMapSet* generate_exception_throw_with_stack_parms(StubAssembler* sasm, address target,
int stack_parms) {
// Make a frame and preserve the caller's caller-save registers.
const int parm_size_in_bytes = align_size_up(stack_parms << LogBytesPerWord, frame::alignment_in_bytes);
const int parm_size_in_bytes = align_up(stack_parms << LogBytesPerWord, frame::alignment_in_bytes);
const int padding = parm_size_in_bytes - (stack_parms << LogBytesPerWord);
OopMap* oop_map = save_live_registers(sasm, true, noreg, parm_size_in_bytes);
@ -287,6 +288,7 @@ static OopMapSet* generate_exception_throw_with_stack_parms(StubAssembler* sasm,
__ ld(R5_ARG3, frame_size_in_bytes + padding + 8, R1_SP);
case 1:
__ ld(R4_ARG2, frame_size_in_bytes + padding + 0, R1_SP);
case 0:
call_offset = __ call_RT(noreg, noreg, target);
break;
default: Unimplemented(); break;
@ -325,7 +327,7 @@ OopMapSet* Runtime1::generate_stub_call(StubAssembler* sasm, Register result, ad
static OopMapSet* stub_call_with_stack_parms(StubAssembler* sasm, Register result, address target,
int stack_parms, bool do_return = true) {
// Make a frame and preserve the caller's caller-save registers.
const int parm_size_in_bytes = align_size_up(stack_parms << LogBytesPerWord, frame::alignment_in_bytes);
const int parm_size_in_bytes = align_up(stack_parms << LogBytesPerWord, frame::alignment_in_bytes);
const int padding = parm_size_in_bytes - (stack_parms << LogBytesPerWord);
OopMap* oop_map = save_live_registers(sasm, true, noreg, parm_size_in_bytes);
@ -337,6 +339,7 @@ static OopMapSet* stub_call_with_stack_parms(StubAssembler* sasm, Register resul
__ ld(R5_ARG3, frame_size_in_bytes + padding + 8, R1_SP);
case 1:
__ ld(R4_ARG2, frame_size_in_bytes + padding + 0, R1_SP);
case 0:
call_offset = __ call_RT(result, noreg, target);
break;
default: Unimplemented(); break;

View File

@ -244,4 +244,6 @@ intptr_t *frame::initial_deoptimization_info() {
frame::frame(void* sp, void* fp, void* pc) : _sp((intptr_t*)sp), _unextended_sp((intptr_t*)sp) {
find_codeblob_and_set_pc_and_deopt_state((address)pc); // also sets _fp and adjusts _unextended_sp
}
void frame::pd_ps() {}
#endif

View File

@ -82,13 +82,7 @@
public:
// C frame layout
enum {
// stack alignment
alignment_in_bytes = 16,
// log_2(16*8 bits) = 7.
log_2_of_alignment_in_bits = 7
};
static const int alignment_in_bytes = 16;
// ABI_MINFRAME:
struct abi_minframe {

View File

@ -28,6 +28,7 @@
#include "code/codeCache.hpp"
#include "code/vmreg.inline.hpp"
#include "utilities/align.hpp"
// Inline functions for ppc64 frames:
@ -193,7 +194,7 @@ inline intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
inline int frame::interpreter_frame_monitor_size() {
// Number of stack slots for a monitor.
return round_to(BasicObjectLock::size(), // number of stack slots
return align_up(BasicObjectLock::size(), // number of stack slots
WordsPerLong); // number of stack slots for a Java long
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. 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
@ -164,7 +164,7 @@ define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong);
product(bool, ZapMemory, false, "Write 0x0101... to empty memory." \
" Use this to ease debugging.") \
\
/* Use Restricted Transactional Memory for lock eliding */ \
/* Use Restricted Transactional Memory for lock elision */ \
product(bool, UseRTMLocking, false, \
"Enable RTM lock eliding for inflated locks in compiled code") \
\
@ -174,24 +174,31 @@ define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong);
product(bool, UseRTMDeopt, false, \
"Perform deopt and recompilation based on RTM abort ratio") \
\
product(uintx, RTMRetryCount, 5, \
product(int, RTMRetryCount, 5, \
"Number of RTM retries on lock abort or busy") \
range(0, max_jint) \
\
experimental(intx, RTMSpinLoopCount, 100, \
experimental(int, RTMSpinLoopCount, 100, \
"Spin count for lock to become free before RTM retry") \
range(0, 32767) /* immediate operand limit on ppc */ \
\
experimental(intx, RTMAbortThreshold, 1000, \
experimental(int, RTMAbortThreshold, 1000, \
"Calculate abort ratio after this number of aborts") \
range(0, max_jint) \
\
experimental(intx, RTMLockingThreshold, 10000, \
experimental(int, RTMLockingThreshold, 10000, \
"Lock count at which to do RTM lock eliding without " \
"abort ratio calculation") \
range(0, max_jint) \
\
experimental(intx, RTMAbortRatio, 50, \
experimental(int, RTMAbortRatio, 50, \
"Lock abort ratio at which to stop use RTM lock eliding") \
range(0, 100) /* natural range */ \
\
experimental(intx, RTMTotalCountIncrRate, 64, \
experimental(int, RTMTotalCountIncrRate, 64, \
"Increment total RTM attempted lock count once every n times") \
range(1, 32767) /* immediate operand limit on ppc */ \
constraint(RTMTotalCountIncrRateConstraintFunc,AfterErgo) \
\
experimental(intx, RTMLockingCalculationDelay, 0, \
"Number of milliseconds to wait before start calculating aborts " \

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. 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
@ -45,8 +45,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
#define thread_(field_name) in_bytes(JavaThread::field_name ## _offset()), R16_thread
#define method_(field_name) in_bytes(Method::field_name ## _offset()), R19_method
virtual void check_and_handle_popframe(Register java_thread);
virtual void check_and_handle_earlyret(Register java_thread);
virtual void check_and_handle_popframe(Register scratch_reg);
virtual void check_and_handle_earlyret(Register scratch_reg);
// Base routine for all dispatches.
void dispatch_base(TosState state, address* table);
@ -79,6 +79,9 @@ class InterpreterMacroAssembler: public MacroAssembler {
// Load object from cpool->resolved_references(index).
void load_resolved_reference_at_index(Register result, Register index, Label *is_null = NULL);
// load cpool->resolved_klass_at(index)
void load_resolved_klass_at_offset(Register Rcpool, Register Roffset, Register Rklass);
void load_receiver(Register Rparam_count, Register Rrecv_dst);
// helpers for expression stack
@ -96,8 +99,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
void push_2ptrs(Register first, Register second);
void push_l_pop_d(Register l = R17_tos, FloatRegister d = F15_ftos);
void push_d_pop_l(FloatRegister d = F15_ftos, Register l = R17_tos);
void move_l_to_d(Register l = R17_tos, FloatRegister d = F15_ftos);
void move_d_to_l(FloatRegister d = F15_ftos, Register l = R17_tos);
void pop (TosState state); // transition vtos -> state
void push(TosState state); // transition state -> vtos

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. 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
@ -284,14 +284,22 @@ void InterpreterMacroAssembler::push_2ptrs(Register first, Register second) {
addi(R15_esp, R15_esp, - 2 * Interpreter::stackElementSize );
}
void InterpreterMacroAssembler::push_l_pop_d(Register l, FloatRegister d) {
std(l, 0, R15_esp);
lfd(d, 0, R15_esp);
void InterpreterMacroAssembler::move_l_to_d(Register l, FloatRegister d) {
if (VM_Version::has_mtfprd()) {
mtfprd(d, l);
} else {
std(l, 0, R15_esp);
lfd(d, 0, R15_esp);
}
}
void InterpreterMacroAssembler::push_d_pop_l(FloatRegister d, Register l) {
stfd(d, 0, R15_esp);
ld(l, 0, R15_esp);
void InterpreterMacroAssembler::move_d_to_l(FloatRegister d, Register l) {
if (VM_Version::has_mtfprd()) {
mffprd(l, d);
} else {
stfd(d, 0, R15_esp);
ld(l, 0, R15_esp);
}
}
void InterpreterMacroAssembler::push(TosState state) {
@ -454,7 +462,8 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result
Register tmp = index; // reuse
sldi(tmp, index, LogBytesPerHeapOop);
// Load pointer for resolved_references[] objArray.
ld(result, ConstantPool::resolved_references_offset_in_bytes(), result);
ld(result, ConstantPool::cache_offset_in_bytes(), result);
ld(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
// JNIHandles::resolve(result)
ld(result, 0, result);
#ifdef ASSERT
@ -471,6 +480,25 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result
load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result, is_null);
}
// load cpool->resolved_klass_at(index)
void InterpreterMacroAssembler::load_resolved_klass_at_offset(Register Rcpool, Register Roffset, Register Rklass) {
// int value = *(Rcpool->int_at_addr(which));
// int resolved_klass_index = extract_low_short_from_int(value);
add(Roffset, Rcpool, Roffset);
#if defined(VM_LITTLE_ENDIAN)
lhz(Roffset, sizeof(ConstantPool), Roffset); // Roffset = resolved_klass_index
#else
lhz(Roffset, sizeof(ConstantPool) + 2, Roffset); // Roffset = resolved_klass_index
#endif
ld(Rklass, ConstantPool::resolved_klasses_offset_in_bytes(), Rcpool); // Rklass = Rcpool->_resolved_klasses
sldi(Roffset, Roffset, LogBytesPerWord);
addi(Roffset, Roffset, Array<Klass*>::base_offset_in_bytes());
isync(); // Order load of instance Klass wrt. tags.
ldx(Rklass, Rklass, Roffset);
}
// Generate a subtype check: branch to ok_is_subtype if sub_klass is
// a subtype of super_klass. Blows registers Rsub_klass, tmp1, tmp2.
void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, Register Rsuper_klass, Register Rtmp1,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -45,7 +45,7 @@ class SignatureHandlerGenerator: public NativeSignatureIterator {
public:
// Creation
SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
_masm = new MacroAssembler(buffer);
_num_used_fp_arg_regs = 0;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. All rights reserved.
* Copyright (c) 2012, 2017, SAP SE. 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
@ -2498,14 +2498,20 @@ void MacroAssembler::rtm_abort_ratio_calculation(Register rtm_counters_Reg,
// All transactions = total_count * RTMTotalCountIncrRate
// Set no_rtm bit if (Aborted transactions >= All transactions * RTMAbortRatio)
ld(R0, RTMLockingCounters::abort_count_offset(), rtm_counters_Reg);
cmpdi(CCR0, R0, RTMAbortThreshold);
blt(CCR0, L_check_always_rtm2);
if (is_simm(RTMAbortThreshold, 16)) { // cmpdi can handle 16bit immediate only.
cmpdi(CCR0, R0, RTMAbortThreshold);
blt(CCR0, L_check_always_rtm2); // reload of rtm_counters_Reg not necessary
} else {
load_const_optimized(rtm_counters_Reg, RTMAbortThreshold);
cmpd(CCR0, R0, rtm_counters_Reg);
blt(CCR0, L_check_always_rtm1); // reload of rtm_counters_Reg required
}
mulli(R0, R0, 100);
const Register tmpReg = rtm_counters_Reg;
ld(tmpReg, RTMLockingCounters::total_count_offset(), rtm_counters_Reg);
mulli(tmpReg, tmpReg, RTMTotalCountIncrRate);
mulli(tmpReg, tmpReg, RTMAbortRatio);
mulli(tmpReg, tmpReg, RTMTotalCountIncrRate); // allowable range: int16
mulli(tmpReg, tmpReg, RTMAbortRatio); // allowable range: int16
cmpd(CCR0, R0, tmpReg);
blt(CCR0, L_check_always_rtm1); // jump to reload
if (method_data != NULL) {
@ -2521,7 +2527,13 @@ void MacroAssembler::rtm_abort_ratio_calculation(Register rtm_counters_Reg,
load_const_optimized(rtm_counters_Reg, (address)rtm_counters, R0); // reload
bind(L_check_always_rtm2);
ld(tmpReg, RTMLockingCounters::total_count_offset(), rtm_counters_Reg);
cmpdi(CCR0, tmpReg, RTMLockingThreshold / RTMTotalCountIncrRate);
int64_t thresholdValue = RTMLockingThreshold / RTMTotalCountIncrRate;
if (is_simm(thresholdValue, 16)) { // cmpdi can handle 16bit immediate only.
cmpdi(CCR0, tmpReg, thresholdValue);
} else {
load_const_optimized(R0, thresholdValue);
cmpd(CCR0, tmpReg, R0);
}
blt(CCR0, L_done);
if (method_data != NULL) {
// Set rtm_state to "always rtm" in MDO.
@ -2620,7 +2632,7 @@ void MacroAssembler::rtm_stack_locking(ConditionRegister flag,
if (PrintPreciseRTMLockingStatistics || profile_rtm) {
Label L_noincrement;
if (RTMTotalCountIncrRate > 1) {
branch_on_random_using_tb(tmp, (int)RTMTotalCountIncrRate, L_noincrement);
branch_on_random_using_tb(tmp, RTMTotalCountIncrRate, L_noincrement);
}
assert(stack_rtm_counters != NULL, "should not be NULL when profiling RTM");
load_const_optimized(tmp, (address)stack_rtm_counters->total_count_addr(), R0);
@ -2687,7 +2699,7 @@ void MacroAssembler::rtm_inflated_locking(ConditionRegister flag,
if (PrintPreciseRTMLockingStatistics || profile_rtm) {
Label L_noincrement;
if (RTMTotalCountIncrRate > 1) {
branch_on_random_using_tb(R0, (int)RTMTotalCountIncrRate, L_noincrement);
branch_on_random_using_tb(R0, RTMTotalCountIncrRate, L_noincrement);
}
assert(rtm_counters != NULL, "should not be NULL when profiling RTM");
load_const(R0, (address)rtm_counters->total_count_addr(), tmpReg);
@ -4120,7 +4132,7 @@ void MacroAssembler::update_byte_crc32(Register crc, Register val, Register tabl
* @param table register pointing to CRC table
*/
void MacroAssembler::update_byteLoop_crc32(Register crc, Register buf, Register len, Register table,
Register data, bool loopAlignment, bool invertCRC) {
Register data, bool loopAlignment) {
assert_different_registers(crc, buf, len, table, data);
Label L_mainLoop, L_done;
@ -4131,10 +4143,6 @@ void MacroAssembler::update_byteLoop_crc32(Register crc, Register buf, Register
clrldi_(len, len, 32); // Enforce 32 bit. Anything to do?
beq(CCR0, L_done);
if (invertCRC) {
nand(crc, crc, crc); // ~c
}
mtctr(len);
align(mainLoop_alignment);
BIND(L_mainLoop);
@ -4143,10 +4151,6 @@ void MacroAssembler::update_byteLoop_crc32(Register crc, Register buf, Register
update_byte_crc32(crc, data, table);
bdnz(L_mainLoop); // Iterate.
if (invertCRC) {
nand(crc, crc, crc); // ~c
}
bind(L_done);
}
@ -4203,7 +4207,8 @@ void MacroAssembler::update_1word_crc32(Register crc, Register buf, Register tab
*/
void MacroAssembler::kernel_crc32_2word(Register crc, Register buf, Register len, Register table,
Register t0, Register t1, Register t2, Register t3,
Register tc0, Register tc1, Register tc2, Register tc3) {
Register tc0, Register tc1, Register tc2, Register tc3,
bool invertCRC) {
assert_different_registers(crc, buf, len, table);
Label L_mainLoop, L_tail;
@ -4217,14 +4222,16 @@ void MacroAssembler::kernel_crc32_2word(Register crc, Register buf, Register len
const int complexThreshold = 2*mainLoop_stepping;
// Don't test for len <= 0 here. This pathological case should not occur anyway.
// Optimizing for it by adding a test and a branch seems to be a waste of CPU cycles.
// The situation itself is detected and handled correctly by the conditional branches
// following aghi(len, -stepping) and aghi(len, +stepping).
// Optimizing for it by adding a test and a branch seems to be a waste of CPU cycles
// for all well-behaved cases. The situation itself is detected and handled correctly
// within update_byteLoop_crc32.
assert(tailLoop_stepping == 1, "check tailLoop_stepping!");
BLOCK_COMMENT("kernel_crc32_2word {");
nand(crc, crc, crc); // ~c
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
// Check for short (<mainLoop_stepping) buffer.
cmpdi(CCR0, len, complexThreshold);
@ -4245,7 +4252,7 @@ void MacroAssembler::kernel_crc32_2word(Register crc, Register buf, Register len
blt(CCR0, L_tail); // For less than one mainloop_stepping left, do only tail processing
mr(len, tmp); // remaining bytes for main loop (>=mainLoop_stepping is guaranteed).
}
update_byteLoop_crc32(crc, buf, tmp2, table, data, false, false);
update_byteLoop_crc32(crc, buf, tmp2, table, data, false);
}
srdi(tmp2, len, log_stepping); // #iterations for mainLoop
@ -4281,9 +4288,11 @@ void MacroAssembler::kernel_crc32_2word(Register crc, Register buf, Register len
// Process last few (<complexThreshold) bytes of buffer.
BIND(L_tail);
update_byteLoop_crc32(crc, buf, len, table, data, false, false);
update_byteLoop_crc32(crc, buf, len, table, data, false);
nand(crc, crc, crc); // ~c
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
BLOCK_COMMENT("} kernel_crc32_2word");
}
@ -4297,7 +4306,8 @@ void MacroAssembler::kernel_crc32_2word(Register crc, Register buf, Register len
*/
void MacroAssembler::kernel_crc32_1word(Register crc, Register buf, Register len, Register table,
Register t0, Register t1, Register t2, Register t3,
Register tc0, Register tc1, Register tc2, Register tc3) {
Register tc0, Register tc1, Register tc2, Register tc3,
bool invertCRC) {
assert_different_registers(crc, buf, len, table);
Label L_mainLoop, L_tail;
@ -4311,14 +4321,16 @@ void MacroAssembler::kernel_crc32_1word(Register crc, Register buf, Register len
const int complexThreshold = 2*mainLoop_stepping;
// Don't test for len <= 0 here. This pathological case should not occur anyway.
// Optimizing for it by adding a test and a branch seems to be a waste of CPU cycles.
// The situation itself is detected and handled correctly by the conditional branches
// following aghi(len, -stepping) and aghi(len, +stepping).
// Optimizing for it by adding a test and a branch seems to be a waste of CPU cycles
// for all well-behaved cases. The situation itself is detected and handled correctly
// within update_byteLoop_crc32.
assert(tailLoop_stepping == 1, "check tailLoop_stepping!");
BLOCK_COMMENT("kernel_crc32_1word {");
nand(crc, crc, crc); // ~c
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
// Check for short (<mainLoop_stepping) buffer.
cmpdi(CCR0, len, complexThreshold);
@ -4339,7 +4351,7 @@ void MacroAssembler::kernel_crc32_1word(Register crc, Register buf, Register len
blt(CCR0, L_tail); // For less than one mainloop_stepping left, do only tail processing
mr(len, tmp); // remaining bytes for main loop (>=mainLoop_stepping is guaranteed).
}
update_byteLoop_crc32(crc, buf, tmp2, table, data, false, false);
update_byteLoop_crc32(crc, buf, tmp2, table, data, false);
}
srdi(tmp2, len, log_stepping); // #iterations for mainLoop
@ -4374,9 +4386,11 @@ void MacroAssembler::kernel_crc32_1word(Register crc, Register buf, Register len
// Process last few (<complexThreshold) bytes of buffer.
BIND(L_tail);
update_byteLoop_crc32(crc, buf, len, table, data, false, false);
update_byteLoop_crc32(crc, buf, len, table, data, false);
nand(crc, crc, crc); // ~c
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
BLOCK_COMMENT("} kernel_crc32_1word");
}
@ -4389,16 +4403,24 @@ void MacroAssembler::kernel_crc32_1word(Register crc, Register buf, Register len
* Uses R7_ARG5, R8_ARG6 as work registers.
*/
void MacroAssembler::kernel_crc32_1byte(Register crc, Register buf, Register len, Register table,
Register t0, Register t1, Register t2, Register t3) {
Register t0, Register t1, Register t2, Register t3,
bool invertCRC) {
assert_different_registers(crc, buf, len, table);
Register data = t0; // Holds the current byte to be folded into crc.
BLOCK_COMMENT("kernel_crc32_1byte {");
// Process all bytes in a single-byte loop.
update_byteLoop_crc32(crc, buf, len, table, data, true, true);
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
// Process all bytes in a single-byte loop.
update_byteLoop_crc32(crc, buf, len, table, data, true);
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
BLOCK_COMMENT("} kernel_crc32_1byte");
}
@ -4416,7 +4438,8 @@ void MacroAssembler::kernel_crc32_1byte(Register crc, Register buf, Register len
*/
void MacroAssembler::kernel_crc32_1word_vpmsumd(Register crc, Register buf, Register len, Register table,
Register constants, Register barretConstants,
Register t0, Register t1, Register t2, Register t3, Register t4) {
Register t0, Register t1, Register t2, Register t3, Register t4,
bool invertCRC) {
assert_different_registers(crc, buf, len, table);
Label L_alignedHead, L_tail, L_alignTail, L_start, L_end;
@ -4434,13 +4457,15 @@ void MacroAssembler::kernel_crc32_1word_vpmsumd(Register crc, Register buf, Regi
Register tc0 = t4;
Register tc1 = constants;
Register tc2 = barretConstants;
kernel_crc32_1word(crc, buf, len, table,t0, t1, t2, t3, tc0, tc1, tc2, table);
kernel_crc32_1word(crc, buf, len, table,t0, t1, t2, t3, tc0, tc1, tc2, table, invertCRC);
b(L_end);
BIND(L_start);
// 2. ~c
nand(crc, crc, crc);
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
// 3. calculate from 0 to first 128bit-aligned address
clrldi_(prealign, buf, 57);
@ -4449,7 +4474,7 @@ void MacroAssembler::kernel_crc32_1word_vpmsumd(Register crc, Register buf, Regi
subfic(prealign, prealign, 128);
subf(len, prealign, len);
update_byteLoop_crc32(crc, buf, prealign, table, t2, false, false);
update_byteLoop_crc32(crc, buf, prealign, table, t2, false);
// 4. calculate from first 128bit-aligned address to last 128bit-aligned address
BIND(L_alignedHead);
@ -4464,12 +4489,14 @@ void MacroAssembler::kernel_crc32_1word_vpmsumd(Register crc, Register buf, Regi
cmpdi(CCR0, postalign, 0);
beq(CCR0, L_tail);
update_byteLoop_crc32(crc, buf, postalign, table, t2, false, false);
update_byteLoop_crc32(crc, buf, postalign, table, t2, false);
BIND(L_tail);
// 6. ~c
nand(crc, crc, crc);
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
BIND(L_end);
@ -4549,12 +4576,12 @@ void MacroAssembler::kernel_crc32_1word_aligned(Register crc, Register buf, Regi
vspltisw(VR0, -1);
vsldoi(mask_32bit, zeroes, VR0, 4);
vsldoi(mask_64bit, zeroes, VR0, -8);
vsldoi(mask_64bit, zeroes, VR0, 8);
// Get the initial value into v8
vxor(VR8, VR8, VR8);
mtvrd(VR8, crc);
vsldoi(VR8, zeroes, VR8, -8); // shift into bottom 32 bits
vsldoi(VR8, zeroes, VR8, 8); // shift into bottom 32 bits
li (rLoaded, 0);
@ -4903,7 +4930,7 @@ void MacroAssembler::kernel_crc32_1word_aligned(Register crc, Register buf, Regi
addi(barretConstants, barretConstants, 16);
lvx(const2, barretConstants);
vsldoi(VR1, VR0, VR0, -8);
vsldoi(VR1, VR0, VR0, 8);
vxor(VR0, VR0, VR1); // xor two 64 bit results together
// shift left one bit
@ -4961,16 +4988,35 @@ void MacroAssembler::kernel_crc32_1word_aligned(Register crc, Register buf, Regi
offsetInt -= 8; ld(R31, offsetInt, R1_SP);
}
void MacroAssembler::kernel_crc32_singleByte(Register crc, Register buf, Register len, Register table, Register tmp) {
void MacroAssembler::kernel_crc32_singleByte(Register crc, Register buf, Register len, Register table, Register tmp, bool invertCRC) {
assert_different_registers(crc, buf, /* len, not used!! */ table, tmp);
BLOCK_COMMENT("kernel_crc32_singleByte:");
nand(crc, crc, crc); // ~c
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
lbz(tmp, 0, buf); // Byte from buffer, zero-extended.
lbz(tmp, 0, buf); // Byte from buffer, zero-extended.
update_byte_crc32(crc, tmp, table);
nand(crc, crc, crc); // ~c
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
}
void MacroAssembler::kernel_crc32_singleByteReg(Register crc, Register val, Register table, bool invertCRC) {
assert_different_registers(crc, val, table);
BLOCK_COMMENT("kernel_crc32_singleByteReg:");
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
update_byte_crc32(crc, val, table);
if (invertCRC) {
nand(crc, crc, crc); // 1s complement of crc
}
}
// dest_lo += src1 + src2

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. All rights reserved.
* Copyright (c) 2012, 2017, SAP SE. 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
@ -819,33 +819,47 @@ class MacroAssembler: public Assembler {
Register tmp6, Register tmp7, Register tmp8, Register tmp9, Register tmp10,
Register tmp11, Register tmp12, Register tmp13);
// CRC32 Intrinsics.
// Emitters for CRC32 calculation.
// A note on invertCRC:
// Unfortunately, internal representation of crc differs between CRC32 and CRC32C.
// CRC32 holds it's current crc value in the externally visible representation.
// CRC32C holds it's current crc value in internal format, ready for updating.
// Thus, the crc value must be bit-flipped before updating it in the CRC32 case.
// In the CRC32C case, it must be bit-flipped when it is given to the outside world (getValue()).
// The bool invertCRC parameter indicates whether bit-flipping is required before updates.
void load_reverse_32(Register dst, Register src);
int crc32_table_columns(Register table, Register tc0, Register tc1, Register tc2, Register tc3);
void fold_byte_crc32(Register crc, Register val, Register table, Register tmp);
void fold_8bit_crc32(Register crc, Register table, Register tmp);
void update_byte_crc32(Register crc, Register val, Register table);
void update_byteLoop_crc32(Register crc, Register buf, Register len, Register table,
Register data, bool loopAlignment, bool invertCRC);
Register data, bool loopAlignment);
void update_1word_crc32(Register crc, Register buf, Register table, int bufDisp, int bufInc,
Register t0, Register t1, Register t2, Register t3,
Register tc0, Register tc1, Register tc2, Register tc3);
void kernel_crc32_2word(Register crc, Register buf, Register len, Register table,
Register t0, Register t1, Register t2, Register t3,
Register tc0, Register tc1, Register tc2, Register tc3);
Register tc0, Register tc1, Register tc2, Register tc3,
bool invertCRC);
void kernel_crc32_1word(Register crc, Register buf, Register len, Register table,
Register t0, Register t1, Register t2, Register t3,
Register tc0, Register tc1, Register tc2, Register tc3);
Register tc0, Register tc1, Register tc2, Register tc3,
bool invertCRC);
void kernel_crc32_1byte(Register crc, Register buf, Register len, Register table,
Register t0, Register t1, Register t2, Register t3);
Register t0, Register t1, Register t2, Register t3,
bool invertCRC);
void kernel_crc32_1word_vpmsumd(Register crc, Register buf, Register len, Register table,
Register constants, Register barretConstants,
Register t0, Register t1, Register t2, Register t3, Register t4);
Register t0, Register t1, Register t2, Register t3, Register t4,
bool invertCRC);
void kernel_crc32_1word_aligned(Register crc, Register buf, Register len,
Register constants, Register barretConstants,
Register t0, Register t1, Register t2);
void kernel_crc32_singleByte(Register crc, Register buf, Register len, Register table, Register tmp);
void kernel_crc32_singleByte(Register crc, Register buf, Register len, Register table, Register tmp,
bool invertCRC);
void kernel_crc32_singleByteReg(Register crc, Register val, Register table,
bool invertCRC);
//
// Debugging

View File

@ -1,78 +0,0 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013 SAP SE. 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.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "asm/codeBuffer.hpp"
#include "memory/metaspaceShared.hpp"
// Generate the self-patching vtable method:
//
// This method will be called (as any other Klass virtual method) with
// the Klass itself as the first argument. Example:
//
// oop obj;
// int size = obj->klass()->klass_part()->oop_size(this);
//
// for which the virtual method call is Klass::oop_size();
//
// The dummy method is called with the Klass object as the first
// operand, and an object as the second argument.
//
//=====================================================================
// All of the dummy methods in the vtable are essentially identical,
// differing only by an ordinal constant, and they bear no releationship
// to the original method which the caller intended. Also, there needs
// to be 'vtbl_list_size' instances of the vtable in order to
// differentiate between the 'vtable_list_size' original Klass objects.
#define __ masm->
void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
void** vtable,
char** md_top,
char* md_end,
char** mc_top,
char* mc_end) {
intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
*(intptr_t *)(*md_top) = vtable_bytes;
*md_top += sizeof(intptr_t);
void** dummy_vtable = (void**)*md_top;
*vtable = dummy_vtable;
*md_top += vtable_bytes;
// Get ready to generate dummy methods.
CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
MacroAssembler* masm = new MacroAssembler(&cb);
// There are more general problems with CDS on ppc, so I can not
// really test this. But having this instead of Unimplementd() allows
// us to pass TestOptionsWithRanges.java.
__ unimplemented();
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. 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
@ -29,6 +29,7 @@
#include "interpreter/interpreter.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvm.h"
#include "prims/methodHandles.hpp"
#define __ _masm->
@ -71,7 +72,7 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,
Register temp_reg, Register temp2_reg,
const char* error_message) {
InstanceKlass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
Klass* klass = SystemDictionary::well_known_klass(klass_id);
Label L_ok, L_bad;
BLOCK_COMMENT("verify_klass {");
__ verify_oop(obj_reg);
@ -174,8 +175,9 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
__ verify_oop(method_temp);
__ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()), method_temp, temp2);
__ verify_oop(method_temp);
// The following assumes that a Method* is normally compressed in the vmtarget field:
__ ld(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()), method_temp);
__ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), method_temp);
__ verify_oop(method_temp);
__ ld(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()), method_temp);
if (VerifyMethodHandles && !for_compiler_entry) {
// Make sure recv is already on stack.
@ -361,14 +363,16 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp2);
}
__ ld(R19_method, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()), member_reg);
__ load_heap_oop(R19_method, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), member_reg);
__ ld(R19_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()), R19_method);
break;
case vmIntrinsics::_linkToStatic:
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp2);
}
__ ld(R19_method, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()), member_reg);
__ load_heap_oop(R19_method, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), member_reg);
__ ld(R19_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()), R19_method);
break;
case vmIntrinsics::_linkToVirtual:

View File

@ -1,6 +1,6 @@
//
// Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2012, 2016 SAP SE. All rights reserved.
// Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2012, 2017 SAP SE. 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
@ -2053,12 +2053,12 @@ const int Matcher::vector_width_in_bytes(BasicType bt) {
}
// Vector ideal reg.
const int Matcher::vector_ideal_reg(int size) {
const uint Matcher::vector_ideal_reg(int size) {
assert(MaxVectorSize == 8 && size == 8, "");
return Op_RegL;
}
const int Matcher::vector_shift_count_ideal_reg(int size) {
const uint Matcher::vector_shift_count_ideal_reg(int size) {
fatal("vector shift is not supported");
return Node::NotAMachineReg;
}
@ -3079,6 +3079,17 @@ encode %{
__ bind(done);
%}
enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
// TODO: PPC port $archOpcode(ppc64Opcode_cmove);
MacroAssembler _masm(&cbuf);
Label done;
__ bso($crx$$CondRegister, done);
__ mffprd($dst$$Register, $src$$FloatRegister);
// TODO PPC port __ endgroup_if_needed(_size == 12);
__ bind(done);
%}
enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
// TODO: PPC port $archOpcode(ppc64Opcode_bc);
@ -5842,6 +5853,16 @@ instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
ins_pipe(pipe_class_default);
%}
instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{
effect(DEF dst, USE src, USE shift, USE mask_begin);
size(4);
ins_encode %{
__ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant);
%}
ins_pipe(pipe_class_default);
%}
// Needed to postalloc expand loadConN: ConN is loaded as ConI
// leaving the upper 32 bits with sign-extension bits.
// This clears these bits: dst = src & 0xFFFFFFFF.
@ -9306,6 +9327,44 @@ instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
ins_pipe(pipe_class_default);
%}
// Bitfield Extract: URShiftI + AndI
instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{
match(Set dst (AndI (URShiftI src1 src2) src3));
format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
size(4);
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
int rshift = ($src2$$constant) & 0x1f;
int length = log2_long(((jlong) $src3$$constant) + 1);
if (rshift + length > 32) {
// if necessary, adjust mask to omit rotated bits.
length = 32 - rshift;
}
__ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
%}
ins_pipe(pipe_class_default);
%}
// Bitfield Extract: URShiftL + AndL
instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{
match(Set dst (AndL (URShiftL src1 src2) src3));
format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
size(4);
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
int rshift = ($src2$$constant) & 0x3f;
int length = log2_long(((jlong) $src3$$constant) + 1);
if (rshift + length > 64) {
// if necessary, adjust mask to omit rotated bits.
length = 64 - rshift;
}
__ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length));
%}
ins_pipe(pipe_class_default);
%}
instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
match(Set dst (ConvL2I (ConvI2L src)));
@ -10078,9 +10137,36 @@ instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
// float intBitsToFloat(int bits)
//
// Notes on the implementation on ppc64:
// We only provide rules which move between a register and a stack-location,
// because we always have to go through memory when moving between a float
// register and an integer register.
// For Power7 and earlier, the rules are limited to those which move between a
// register and a stack-location, because we always have to go through memory
// when moving between a float register and an integer register.
// This restriction is removed in Power8 with the introduction of the mtfprd
// and mffprd instructions.
instruct moveL2D_reg(regD dst, iRegLsrc src) %{
match(Set dst (MoveL2D src));
predicate(VM_Version::has_mtfprd());
format %{ "MTFPRD $dst, $src" %}
size(4);
ins_encode %{
__ mtfprd($dst$$FloatRegister, $src$$Register);
%}
ins_pipe(pipe_class_default);
%}
instruct moveI2D_reg(regD dst, iRegIsrc src) %{
// no match-rule, false predicate
effect(DEF dst, USE src);
predicate(false);
format %{ "MTFPRWA $dst, $src" %}
size(4);
ins_encode %{
__ mtfprwa($dst$$FloatRegister, $src$$Register);
%}
ins_pipe(pipe_class_default);
%}
//---------- Chain stack slots between similar types --------
@ -10519,6 +10605,16 @@ instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
ins_pipe(pipe_class_default);
%}
instruct extsh(iRegIdst dst, iRegIsrc src) %{
effect(DEF dst, USE src);
size(4);
ins_encode %{
__ extsh($dst$$Register, $src$$Register);
%}
ins_pipe(pipe_class_default);
%}
// LShiftI 16 + RShiftI 16 converts short to int.
instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
match(Set dst (RShiftI (LShiftI src amount) amount));
@ -10583,6 +10679,20 @@ instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
ins_pipe(pipe_class_default);
%}
instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{
// no match-rule, false predicate
effect(DEF dst, USE crx, USE src);
predicate(false);
ins_variable_size_depending_on_alignment(true);
format %{ "cmovI $crx, $dst, $src" %}
// Worst case is branch + move + stop, no stop without scheduler.
size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
ins_encode( enc_cmove_bso_reg(dst, crx, src) );
ins_pipe(pipe_class_default);
%}
instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{
// no match-rule, false predicate
effect(DEF dst, USE crx, USE mem);
@ -10637,9 +10747,64 @@ instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stack
%}
%}
instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{
// no match-rule, false predicate
effect(DEF dst, USE crx, USE src);
predicate(false);
format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %}
postalloc_expand %{
//
// replaces
//
// region dst crx src
// \ | | /
// dst=cmovI_bso_reg_conLvalue0
//
// with
//
// region dst
// \ /
// dst=loadConI16(0)
// |
// ^ region dst crx src
// | \ | | /
// dst=cmovI_bso_reg
//
// Create new nodes.
MachNode *m1 = new loadConI16Node();
MachNode *m2 = new cmovI_bso_regNode();
// inputs for new nodes
m1->add_req(n_region);
m2->add_req(n_region, n_crx, n_src);
// precedences for new nodes
m2->add_prec(m1);
// operands for new nodes
m1->_opnds[0] = op_dst;
m1->_opnds[1] = new immI16Oper(0);
m2->_opnds[0] = op_dst;
m2->_opnds[1] = op_crx;
m2->_opnds[2] = op_src;
// registers for new nodes
ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
// Insert new nodes.
nodes->push(m1);
nodes->push(m2);
%}
%}
// Double to Int conversion, NaN is mapped to 0.
instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{
match(Set dst (ConvD2I src));
predicate(!VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
@ -10653,6 +10818,21 @@ instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{
%}
%}
// Double to Int conversion, NaN is mapped to 0. Special version for Power8.
instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
match(Set dst (ConvD2I src));
predicate(VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regD tmpD;
flagsReg crx;
cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
%}
%}
instruct convF2IRaw_regF(regF dst, regF src) %{
// no match-rule, false predicate
effect(DEF dst, USE src);
@ -10670,6 +10850,7 @@ instruct convF2IRaw_regF(regF dst, regF src) %{
// Float to Int conversion, NaN is mapped to 0.
instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{
match(Set dst (ConvF2I src));
predicate(!VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
@ -10683,6 +10864,21 @@ instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{
%}
%}
// Float to Int conversion, NaN is mapped to 0. Special version for Power8.
instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
match(Set dst (ConvF2I src));
predicate(VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regF tmpF;
flagsReg crx;
cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
%}
%}
// Convert to Long
instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
@ -10752,6 +10948,20 @@ instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
ins_pipe(pipe_class_default);
%}
instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
// no match-rule, false predicate
effect(DEF dst, USE crx, USE src);
predicate(false);
ins_variable_size_depending_on_alignment(true);
format %{ "cmovL $crx, $dst, $src" %}
// Worst case is branch + move + stop, no stop without scheduler.
size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
ins_encode( enc_cmove_bso_reg(dst, crx, src) );
ins_pipe(pipe_class_default);
%}
instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{
// no match-rule, false predicate
effect(DEF dst, USE crx, USE mem);
@ -10803,9 +11013,61 @@ instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stack
%}
%}
instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{
// no match-rule, false predicate
effect(DEF dst, USE crx, USE src);
predicate(false);
format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %}
postalloc_expand %{
//
// replaces
//
// region dst crx src
// \ | | /
// dst=cmovL_bso_reg_conLvalue0
//
// with
//
// region dst
// \ /
// dst=loadConL16(0)
// |
// ^ region dst crx src
// | \ | | /
// dst=cmovL_bso_reg
//
// Create new nodes.
MachNode *m1 = new loadConL16Node();
MachNode *m2 = new cmovL_bso_regNode();
// inputs for new nodes
m1->add_req(n_region);
m2->add_req(n_region, n_crx, n_src);
m2->add_prec(m1);
// operands for new nodes
m1->_opnds[0] = op_dst;
m1->_opnds[1] = new immL16Oper(0);
m2->_opnds[0] = op_dst;
m2->_opnds[1] = op_crx;
m2->_opnds[2] = op_src;
// registers for new nodes
ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
// Insert new nodes.
nodes->push(m1);
nodes->push(m2);
%}
%}
// Float to Long conversion, NaN is mapped to 0.
instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{
match(Set dst (ConvF2L src));
predicate(!VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
@ -10819,6 +11081,21 @@ instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{
%}
%}
// Float to Long conversion, NaN is mapped to 0. Special version for Power8.
instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
match(Set dst (ConvF2L src));
predicate(VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regF tmpF;
flagsReg crx;
cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
%}
%}
instruct convD2LRaw_regD(regD dst, regD src) %{
// no match-rule, false predicate
effect(DEF dst, USE src);
@ -10836,6 +11113,7 @@ instruct convD2LRaw_regD(regD dst, regD src) %{
// Double to Long conversion, NaN is mapped to 0.
instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{
match(Set dst (ConvD2L src));
predicate(!VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
@ -10849,6 +11127,21 @@ instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{
%}
%}
// Double to Long conversion, NaN is mapped to 0. Special version for Power8.
instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
match(Set dst (ConvD2L src));
predicate(VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regD tmpD;
flagsReg crx;
cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
%}
%}
// Convert to Float
// Placed here as needed in expand.
@ -10914,7 +11207,7 @@ instruct convL2FRaw_regF(regF dst, regD src) %{
// Integer to Float conversion. Special version for Power7.
instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{
match(Set dst (ConvI2F src));
predicate(VM_Version::has_fcfids());
predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
@ -10928,10 +11221,23 @@ instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{
%}
%}
// Integer to Float conversion. Special version for Power8.
instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
match(Set dst (ConvI2F src));
predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regD tmpD;
moveI2D_reg(tmpD, src);
convL2FRaw_regF(dst, tmpD); // Convert to float.
%}
%}
// L2F to avoid runtime call.
instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{
match(Set dst (ConvL2F src));
predicate(VM_Version::has_fcfids());
predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
@ -10943,6 +11249,19 @@ instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{
%}
%}
// L2F to avoid runtime call. Special version for Power8.
instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
match(Set dst (ConvL2F src));
predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regD tmpD;
moveL2D_reg(tmpD, src);
convL2FRaw_regF(dst, tmpD); // Convert to float.
%}
%}
// Moved up as used in expand.
//instruct convD2F_reg(regF dst, regD src) %{%}
@ -10951,6 +11270,7 @@ instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{
// Integer to Double conversion.
instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{
match(Set dst (ConvI2D src));
predicate(!VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
@ -10964,6 +11284,19 @@ instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{
%}
%}
// Integer to Double conversion. Special version for Power8.
instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
match(Set dst (ConvI2D src));
predicate(VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regD tmpD;
moveI2D_reg(tmpD, src);
convL2DRaw_regD(dst, tmpD); // Convert to double.
%}
%}
// Long to Double conversion
instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{
match(Set dst (ConvL2D src));
@ -10976,6 +11309,19 @@ instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{
%}
%}
// Long to Double conversion. Special version for Power8.
instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
match(Set dst (ConvL2D src));
predicate(VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regD tmpD;
moveL2D_reg(tmpD, src);
convL2DRaw_regD(dst, tmpD); // Convert to double.
%}
%}
instruct convF2D_reg(regD dst, regF src) %{
match(Set dst (ConvF2D src));
format %{ "FMR $dst, $src \t// float->double" %}
@ -12705,8 +13051,7 @@ instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{
// Just slightly faster than java implementation.
instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
match(Set dst (ReverseBytesI src));
predicate(UseCountLeadingZerosInstructionsPPC64);
ins_cost(DEFAULT_COST);
ins_cost(7*DEFAULT_COST);
expand %{
immI16 imm24 %{ (int) 24 %}
@ -12728,6 +13073,172 @@ instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
%}
%}
instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
match(Set dst (ReverseBytesL src));
ins_cost(15*DEFAULT_COST);
expand %{
immI16 imm56 %{ (int) 56 %}
immI16 imm48 %{ (int) 48 %}
immI16 imm40 %{ (int) 40 %}
immI16 imm32 %{ (int) 32 %}
immI16 imm24 %{ (int) 24 %}
immI16 imm16 %{ (int) 16 %}
immI16 imm8 %{ (int) 8 %}
immI16 imm0 %{ (int) 0 %}
iRegLdst tmpL1;
iRegLdst tmpL2;
iRegLdst tmpL3;
iRegLdst tmpL4;
iRegLdst tmpL5;
iRegLdst tmpL6;
// src : |a|b|c|d|e|f|g|h|
rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
%}
%}
instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
match(Set dst (ReverseBytesUS src));
ins_cost(2*DEFAULT_COST);
expand %{
immI16 imm16 %{ (int) 16 %}
immI16 imm8 %{ (int) 8 %}
urShiftI_reg_imm(dst, src, imm8);
insrwi(dst, src, imm16, imm8);
%}
%}
instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
match(Set dst (ReverseBytesS src));
ins_cost(3*DEFAULT_COST);
expand %{
immI16 imm16 %{ (int) 16 %}
immI16 imm8 %{ (int) 8 %}
iRegLdst tmpI1;
urShiftI_reg_imm(tmpI1, src, imm8);
insrwi(tmpI1, src, imm16, imm8);
extsh(dst, tmpI1);
%}
%}
// Load Integer reversed byte order
instruct loadI_reversed(iRegIdst dst, indirect mem) %{
match(Set dst (ReverseBytesI (LoadI mem)));
ins_cost(MEMORY_REF_COST);
size(4);
ins_encode %{
__ lwbrx($dst$$Register, $mem$$Register);
%}
ins_pipe(pipe_class_default);
%}
// Load Long - aligned and reversed
instruct loadL_reversed(iRegLdst dst, indirect mem) %{
match(Set dst (ReverseBytesL (LoadL mem)));
predicate(VM_Version::has_ldbrx());
ins_cost(MEMORY_REF_COST);
size(4);
ins_encode %{
__ ldbrx($dst$$Register, $mem$$Register);
%}
ins_pipe(pipe_class_default);
%}
// Load unsigned short / char reversed byte order
instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
match(Set dst (ReverseBytesUS (LoadUS mem)));
ins_cost(MEMORY_REF_COST);
size(4);
ins_encode %{
__ lhbrx($dst$$Register, $mem$$Register);
%}
ins_pipe(pipe_class_default);
%}
// Load short reversed byte order
instruct loadS_reversed(iRegIdst dst, indirect mem) %{
match(Set dst (ReverseBytesS (LoadS mem)));
ins_cost(MEMORY_REF_COST + DEFAULT_COST);
size(8);
ins_encode %{
__ lhbrx($dst$$Register, $mem$$Register);
__ extsh($dst$$Register, $dst$$Register);
%}
ins_pipe(pipe_class_default);
%}
// Store Integer reversed byte order
instruct storeI_reversed(iRegIsrc src, indirect mem) %{
match(Set mem (StoreI mem (ReverseBytesI src)));
ins_cost(MEMORY_REF_COST);
size(4);
ins_encode %{
__ stwbrx($src$$Register, $mem$$Register);
%}
ins_pipe(pipe_class_default);
%}
// Store Long reversed byte order
instruct storeL_reversed(iRegLsrc src, indirect mem) %{
match(Set mem (StoreL mem (ReverseBytesL src)));
predicate(VM_Version::has_stdbrx());
ins_cost(MEMORY_REF_COST);
size(4);
ins_encode %{
__ stdbrx($src$$Register, $mem$$Register);
%}
ins_pipe(pipe_class_default);
%}
// Store unsigned short / char reversed byte order
instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
match(Set mem (StoreC mem (ReverseBytesUS src)));
ins_cost(MEMORY_REF_COST);
size(4);
ins_encode %{
__ sthbrx($src$$Register, $mem$$Register);
%}
ins_pipe(pipe_class_default);
%}
// Store short reversed byte order
instruct storeS_reversed(iRegIsrc src, indirect mem) %{
match(Set mem (StoreC mem (ReverseBytesS src)));
ins_cost(MEMORY_REF_COST);
size(4);
ins_encode %{
__ sthbrx($src$$Register, $mem$$Register);
%}
ins_pipe(pipe_class_default);
%}
//---------- Replicate Vector Instructions ------------------------------------
// Insrdi does replicate if src == dst.

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013 SAP SE. All rights reserved.
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. 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
@ -81,8 +81,17 @@ const char* VectorSRegisterImpl::name() const {
"VSR0", "VSR1", "VSR2", "VSR3", "VSR4", "VSR5", "VSR6", "VSR7",
"VSR8", "VSR9", "VSR10", "VSR11", "VSR12", "VSR13", "VSR14", "VSR15",
"VSR16", "VSR17", "VSR18", "VSR19", "VSR20", "VSR21", "VSR22", "VSR23",
"VSR24", "VSR25", "VSR26", "VSR27", "VSR28", "VSR29", "VSR30", "VSR31"
"VSR24", "VSR25", "VSR26", "VSR27", "VSR28", "VSR29", "VSR30", "VSR31",
"VSR32", "VSR33", "VSR34", "VSR35", "VSR36", "VSR37", "VSR38", "VSR39",
"VSR40", "VSR41", "VSR42", "VSR43", "VSR44", "VSR45", "VSR46", "VSR47",
"VSR48", "VSR49", "VSR50", "VSR51", "VSR52", "VSR53", "VSR54", "VSR55",
"VSR56", "VSR57", "VSR58", "VSR59", "VSR60", "VSR61", "VSR62", "VSR63"
};
return is_valid() ? names[encoding()] : "vsnoreg";
}
// Method to convert a VectorRegister to a Vector-Scalar Register (VectorSRegister)
VectorSRegister VectorRegisterImpl::to_vsr() const {
if (this == vnoreg) { return vsnoregi; }
return as_VectorSRegister(encoding() + 32);
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. 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
@ -398,6 +398,11 @@ inline VectorRegister as_VectorRegister(int encoding) {
return (VectorRegister)(intptr_t)encoding;
}
// Forward declaration
// Use VectorSRegister as a shortcut.
class VectorSRegisterImpl;
typedef VectorSRegisterImpl* VectorSRegister;
// The implementation of vector registers for the Power architecture
class VectorRegisterImpl: public AbstractRegisterImpl {
public:
@ -415,6 +420,9 @@ class VectorRegisterImpl: public AbstractRegisterImpl {
bool is_valid() const { return 0 <= value() && value() < number_of_registers; }
const char* name() const;
// convert to VSR
VectorSRegister to_vsr() const;
};
// The Vector registers of the Power architecture
@ -491,10 +499,6 @@ CONSTANT_REGISTER_DECLARATION(VectorRegister, VR31, (31));
#endif // DONT_USE_REGISTER_DEFINES
// Use VectorSRegister as a shortcut.
class VectorSRegisterImpl;
typedef VectorSRegisterImpl* VectorSRegister;
inline VectorSRegister as_VectorSRegister(int encoding) {
return (VectorSRegister)(intptr_t)encoding;
}
@ -503,7 +507,7 @@ inline VectorSRegister as_VectorSRegister(int encoding) {
class VectorSRegisterImpl: public AbstractRegisterImpl {
public:
enum {
number_of_registers = 32
number_of_registers = 64
};
// construction
@ -554,6 +558,38 @@ CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR28, (28));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR29, (29));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR30, (30));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR31, (31));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR32, (32));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR33, (33));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR34, (34));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR35, (35));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR36, (36));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR37, (37));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR38, (38));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR39, (39));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR40, (40));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR41, (41));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR42, (42));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR43, (43));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR44, (44));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR45, (45));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR46, (46));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR47, (47));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR48, (48));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR49, (49));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR50, (50));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR51, (51));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR52, (52));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR53, (53));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR54, (54));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR55, (55));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR56, (56));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR57, (57));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR58, (58));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR59, (59));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR60, (60));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR61, (61));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR62, (62));
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR63, (63));
#ifndef DONT_USE_REGISTER_DEFINES
#define vsnoregi ((VectorSRegister)(vsnoreg_VectorSRegisterEnumValue))
@ -589,6 +625,38 @@ CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR31, (31));
#define VSR29 ((VectorSRegister)( VSR29_VectorSRegisterEnumValue))
#define VSR30 ((VectorSRegister)( VSR30_VectorSRegisterEnumValue))
#define VSR31 ((VectorSRegister)( VSR31_VectorSRegisterEnumValue))
#define VSR32 ((VectorSRegister)( VSR32_VectorSRegisterEnumValue))
#define VSR33 ((VectorSRegister)( VSR33_VectorSRegisterEnumValue))
#define VSR34 ((VectorSRegister)( VSR34_VectorSRegisterEnumValue))
#define VSR35 ((VectorSRegister)( VSR35_VectorSRegisterEnumValue))
#define VSR36 ((VectorSRegister)( VSR36_VectorSRegisterEnumValue))
#define VSR37 ((VectorSRegister)( VSR37_VectorSRegisterEnumValue))
#define VSR38 ((VectorSRegister)( VSR38_VectorSRegisterEnumValue))
#define VSR39 ((VectorSRegister)( VSR39_VectorSRegisterEnumValue))
#define VSR40 ((VectorSRegister)( VSR40_VectorSRegisterEnumValue))
#define VSR41 ((VectorSRegister)( VSR41_VectorSRegisterEnumValue))
#define VSR42 ((VectorSRegister)( VSR42_VectorSRegisterEnumValue))
#define VSR43 ((VectorSRegister)( VSR43_VectorSRegisterEnumValue))
#define VSR44 ((VectorSRegister)( VSR44_VectorSRegisterEnumValue))
#define VSR45 ((VectorSRegister)( VSR45_VectorSRegisterEnumValue))
#define VSR46 ((VectorSRegister)( VSR46_VectorSRegisterEnumValue))
#define VSR47 ((VectorSRegister)( VSR47_VectorSRegisterEnumValue))
#define VSR48 ((VectorSRegister)( VSR48_VectorSRegisterEnumValue))
#define VSR49 ((VectorSRegister)( VSR49_VectorSRegisterEnumValue))
#define VSR50 ((VectorSRegister)( VSR50_VectorSRegisterEnumValue))
#define VSR51 ((VectorSRegister)( VSR51_VectorSRegisterEnumValue))
#define VSR52 ((VectorSRegister)( VSR52_VectorSRegisterEnumValue))
#define VSR53 ((VectorSRegister)( VSR53_VectorSRegisterEnumValue))
#define VSR54 ((VectorSRegister)( VSR54_VectorSRegisterEnumValue))
#define VSR55 ((VectorSRegister)( VSR55_VectorSRegisterEnumValue))
#define VSR56 ((VectorSRegister)( VSR56_VectorSRegisterEnumValue))
#define VSR57 ((VectorSRegister)( VSR57_VectorSRegisterEnumValue))
#define VSR58 ((VectorSRegister)( VSR58_VectorSRegisterEnumValue))
#define VSR59 ((VectorSRegister)( VSR59_VectorSRegisterEnumValue))
#define VSR60 ((VectorSRegister)( VSR60_VectorSRegisterEnumValue))
#define VSR61 ((VectorSRegister)( VSR61_VectorSRegisterEnumValue))
#define VSR62 ((VectorSRegister)( VSR62_VectorSRegisterEnumValue))
#define VSR63 ((VectorSRegister)( VSR63_VectorSRegisterEnumValue))
#endif // DONT_USE_REGISTER_DEFINES
// Maximum number of incoming arguments that can be passed in i registers.
@ -609,7 +677,7 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl {
* 2 // register halves
+ ConditionRegisterImpl::number_of_registers // condition code registers
+ SpecialRegisterImpl::number_of_registers // special registers
+ VectorRegisterImpl::number_of_registers // vector registers
+ VectorRegisterImpl::number_of_registers // VSX registers
};
static const int max_gpr;

View File

@ -35,6 +35,7 @@
#include "oops/compiledICHolder.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/align.hpp"
#include "vmreg_ppc.inline.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
@ -221,7 +222,7 @@ OopMap* RegisterSaver::push_frame_reg_args_and_save_live_registers(MacroAssemble
const int regstosave_num = sizeof(RegisterSaver_LiveRegs) /
sizeof(RegisterSaver::LiveRegType);
const int register_save_size = regstosave_num * reg_size;
const int frame_size_in_bytes = round_to(register_save_size, frame::alignment_in_bytes)
const int frame_size_in_bytes = align_up(register_save_size, frame::alignment_in_bytes)
+ frame::abi_reg_args_size;
*out_frame_size_in_bytes = frame_size_in_bytes;
const int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
@ -658,7 +659,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
ShouldNotReachHere();
}
}
return round_to(stk, 2);
return align_up(stk, 2);
}
#if defined(COMPILER1) || defined(COMPILER2)
@ -845,7 +846,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
}
}
return round_to(stk, 2);
return align_up(stk, 2);
}
#endif // COMPILER2
@ -873,7 +874,7 @@ static address gen_c2i_adapter(MacroAssembler *masm,
// Adapter needs TOP_IJAVA_FRAME_ABI.
const int adapter_size = frame::top_ijava_frame_abi_size +
round_to(total_args_passed * wordSize, frame::alignment_in_bytes);
align_up(total_args_passed * wordSize, frame::alignment_in_bytes);
// regular (verified) c2i entry point
c2i_entrypoint = __ pc();
@ -1022,9 +1023,9 @@ void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
// number (all values in registers) or the maximum stack slot accessed.
// Convert 4-byte c2 stack slots to words.
comp_words_on_stack = round_to(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord;
comp_words_on_stack = align_up(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord;
// Round up to miminum stack alignment, in wordSize.
comp_words_on_stack = round_to(comp_words_on_stack, 2);
comp_words_on_stack = align_up(comp_words_on_stack, 2);
__ resize_frame(-comp_words_on_stack * wordSize, R11_scratch1);
}
@ -1609,7 +1610,7 @@ static void unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType
}
static void verify_oop_args(MacroAssembler* masm,
methodHandle method,
const methodHandle& method,
const BasicType* sig_bt,
const VMRegPair* regs) {
Register temp_reg = R19_method; // not part of any compiled calling seq
@ -1631,7 +1632,7 @@ static void verify_oop_args(MacroAssembler* masm,
}
static void gen_special_dispatch(MacroAssembler* masm,
methodHandle method,
const methodHandle& method,
const BasicType* sig_bt,
const VMRegPair* regs) {
verify_oop_args(masm, method, sig_bt, regs);
@ -1918,7 +1919,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
}
}
}
total_save_slots = double_slots * 2 + round_to(single_slots, 2); // round to even
total_save_slots = double_slots * 2 + align_up(single_slots, 2); // round to even
}
int oop_handle_slot_offset = stack_slots;
@ -1945,7 +1946,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
// Now compute actual number of stack words we need.
// Rounding to make stack properly aligned.
stack_slots = round_to(stack_slots, // 7)
stack_slots = align_up(stack_slots, // 7)
frame::alignment_in_bytes / VMRegImpl::stack_slot_size);
int frame_size_in_bytes = stack_slots * VMRegImpl::stack_slot_size;
@ -2203,8 +2204,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
// disallows any pending_exception.
// Save argument registers and leave room for C-compatible ABI_REG_ARGS.
int frame_size = frame::abi_reg_args_size +
round_to(total_c_args * wordSize, frame::alignment_in_bytes);
int frame_size = frame::abi_reg_args_size + align_up(total_c_args * wordSize, frame::alignment_in_bytes);
__ mr(R11_scratch1, R1_SP);
RegisterSaver::push_frame_and_save_argument_registers(masm, R12_scratch2, frame_size, total_c_args, out_regs, out_regs2);
@ -2570,7 +2570,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
// This function returns the adjust size (in number of words) to a c2i adapter
// activation for use during deoptimization.
int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) {
return round_to((callee_locals - callee_parameters) * Interpreter::stackElementWords, frame::alignment_in_bytes);
return align_up((callee_locals - callee_parameters) * Interpreter::stackElementWords, frame::alignment_in_bytes);
}
uint SharedRuntime::out_preserve_stack_slots() {

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017, SAP SE. 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
@ -38,6 +38,7 @@
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
#include "utilities/align.hpp"
#define __ _masm->
@ -626,7 +627,7 @@ class StubGenerator: public StubCodeGenerator {
int spill_slots = 3;
if (preserve1 != noreg) { spill_slots++; }
if (preserve2 != noreg) { spill_slots++; }
const int frame_size = align_size_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
const int frame_size = align_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
Label filtered;
// Is marking active?
@ -687,7 +688,7 @@ class StubGenerator: public StubCodeGenerator {
case BarrierSet::G1SATBCTLogging:
{
int spill_slots = (preserve != noreg) ? 1 : 0;
const int frame_size = align_size_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
const int frame_size = align_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
__ save_LR_CR(R0);
__ push_frame(frame_size, R0);
@ -2728,7 +2729,7 @@ class StubGenerator: public StubCodeGenerator {
__ vspltisb (vTmp2, -16);
__ vrld (keyPerm, keyPerm, vTmp2);
__ vrld (keyPerm, keyPerm, vTmp2);
__ vsldoi (keyPerm, keyPerm, keyPerm, -8);
__ vsldoi (keyPerm, keyPerm, keyPerm, 8);
// load the 1st round key to vKey1
__ li (keypos, 0);
@ -2928,7 +2929,7 @@ class StubGenerator: public StubCodeGenerator {
__ vspltisb (vTmp2, -16);
__ vrld (keyPerm, keyPerm, vTmp2);
__ vrld (keyPerm, keyPerm, vTmp2);
__ vsldoi (keyPerm, keyPerm, keyPerm, -8);
__ vsldoi (keyPerm, keyPerm, keyPerm, 8);
__ cmpwi (CCR0, keylen, 44);
__ beq (CCR0, L_do44);
@ -3276,6 +3277,36 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
// Compute CRC32/CRC32C function.
void generate_CRC_updateBytes(const char* name, Register table, bool invertCRC) {
// arguments to kernel_crc32:
const Register crc = R3_ARG1; // Current checksum, preset by caller or result from previous call.
const Register data = R4_ARG2; // source byte array
const Register dataLen = R5_ARG3; // #bytes to process
const Register t0 = R2;
const Register t1 = R7;
const Register t2 = R8;
const Register t3 = R9;
const Register tc0 = R10;
const Register tc1 = R11;
const Register tc2 = R12;
BLOCK_COMMENT("Stub body {");
assert_different_registers(crc, data, dataLen, table);
__ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, table, invertCRC);
BLOCK_COMMENT("return");
__ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET).
__ blr();
BLOCK_COMMENT("} Stub body");
}
/**
* Arguments:
*
@ -3296,14 +3327,14 @@ class StubGenerator: public StubCodeGenerator {
StubCodeMark mark(this, "StubRoutines", name);
address start = __ function_entry(); // Remember stub start address (is rtn value).
const Register table = R6; // crc table address
#ifdef VM_LITTLE_ENDIAN
// arguments to kernel_crc32:
const Register crc = R3_ARG1; // Current checksum, preset by caller or result from previous call.
const Register data = R4_ARG2; // source byte array
const Register dataLen = R5_ARG3; // #bytes to process
const Register table = R6; // crc table address
#ifdef VM_LITTLE_ENDIAN
if (VM_Version::has_vpmsumb()) {
const Register constants = R2; // constants address
const Register bconstants = R8; // barret table address
@ -3321,7 +3352,7 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::ppc64::generate_load_crc_constants_addr(_masm, constants);
StubRoutines::ppc64::generate_load_crc_barret_constants_addr(_masm, bconstants);
__ kernel_crc32_1word_vpmsumd(crc, data, dataLen, table, constants, bconstants, t0, t1, t2, t3, t4);
__ kernel_crc32_1word_vpmsumd(crc, data, dataLen, table, constants, bconstants, t0, t1, t2, t3, t4, true);
BLOCK_COMMENT("return");
__ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET).
@ -3331,31 +3362,79 @@ class StubGenerator: public StubCodeGenerator {
} else
#endif
{
const Register t0 = R2;
const Register t1 = R7;
const Register t2 = R8;
const Register t3 = R9;
const Register tc0 = R10;
const Register tc1 = R11;
const Register tc2 = R12;
StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table);
generate_CRC_updateBytes(name, table, true);
}
return start;
}
/**
* Arguments:
*
* Inputs:
* R3_ARG1 - int crc
* R4_ARG2 - byte* buf
* R5_ARG3 - int length (of buffer)
*
* scratch:
* R2, R6-R12
*
* Ouput:
* R3_RET - int crc result
*/
// Compute CRC32C function.
address generate_CRC32C_updateBytes(const char* name) {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", name);
address start = __ function_entry(); // Remember stub start address (is rtn value).
const Register table = R6; // crc table address
#if 0 // no vector support yet for CRC32C
#ifdef VM_LITTLE_ENDIAN
// arguments to kernel_crc32:
const Register crc = R3_ARG1; // Current checksum, preset by caller or result from previous call.
const Register data = R4_ARG2; // source byte array
const Register dataLen = R5_ARG3; // #bytes to process
if (VM_Version::has_vpmsumb()) {
const Register constants = R2; // constants address
const Register bconstants = R8; // barret table address
const Register t0 = R9;
const Register t1 = R10;
const Register t2 = R11;
const Register t3 = R12;
const Register t4 = R7;
BLOCK_COMMENT("Stub body {");
assert_different_registers(crc, data, dataLen, table);
StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table);
StubRoutines::ppc64::generate_load_crc32c_table_addr(_masm, table);
StubRoutines::ppc64::generate_load_crc32c_constants_addr(_masm, constants);
StubRoutines::ppc64::generate_load_crc32c_barret_constants_addr(_masm, bconstants);
__ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, table);
__ kernel_crc32_1word_vpmsumd(crc, data, dataLen, table, constants, bconstants, t0, t1, t2, t3, t4, false);
BLOCK_COMMENT("return");
__ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET).
__ blr();
BLOCK_COMMENT("} Stub body");
} else
#endif
#endif
{
StubRoutines::ppc64::generate_load_crc32c_table_addr(_masm, table);
generate_CRC_updateBytes(name, table, false);
}
return start;
}
// Initialization
void generate_initial() {
// Generates all stubs and initializes the entry points
@ -3383,6 +3462,12 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_crc_table_adr = (address)StubRoutines::ppc64::_crc_table;
StubRoutines::_updateBytesCRC32 = generate_CRC32_updateBytes("CRC32_updateBytes");
}
// CRC32C Intrinsics.
if (UseCRC32CIntrinsics) {
StubRoutines::_crc32c_table_addr = (address)StubRoutines::ppc64::_crc32c_table;
StubRoutines::_updateBytesCRC32C = generate_CRC32C_updateBytes("CRC32C_updateBytes");
}
}
void generate_all() {

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017, SAP SE. 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,13 +55,16 @@ class ppc64 {
// CRC32 Intrinsics.
static juint _crc_table[CRC32_TABLES][CRC32_COLUMN_SIZE];
static juint _crc32c_table[CRC32_TABLES][CRC32_COLUMN_SIZE];
static juint* _constants;
static juint* _barret_constants;
public:
// CRC32 Intrinsics.
static void generate_load_table_addr(MacroAssembler* masm, Register table, address table_addr, uint64_t table_contents);
static void generate_load_crc_table_addr(MacroAssembler* masm, Register table);
static void generate_load_crc32c_table_addr(MacroAssembler* masm, Register table);
static void generate_load_crc_constants_addr(MacroAssembler* masm, Register table);
static void generate_load_crc_barret_constants_addr(MacroAssembler* masm, Register table);
static juint* generate_crc_constants();

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017 SAP SE. All rights reserved.
* Copyright (c) 2015, 2017, SAP SE. 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
@ -643,12 +643,6 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(const ch
return entry;
}
address TemplateInterpreterGenerator::generate_continuation_for(TosState state) {
address entry = __ pc();
__ unimplemented("generate_continuation_for");
return entry;
}
// This entry is returned to when a call returns to the interpreter.
// When we arrive here, we expect that the callee stack frame is already popped.
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
@ -692,6 +686,10 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
#endif
__ sldi(size, size, Interpreter::logStackElementSize);
__ add(R15_esp, R15_esp, size);
__ check_and_handle_popframe(R11_scratch1);
__ check_and_handle_earlyret(R11_scratch1);
__ dispatch_next(state, step);
return entry;
}
@ -1894,7 +1892,7 @@ address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
__ lwz(crc, 2*wordSize, argP); // Current crc state, zero extend to 64 bit to have a clean register.
StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table);
__ kernel_crc32_singleByte(crc, data, dataLen, table, tmp);
__ kernel_crc32_singleByte(crc, data, dataLen, table, tmp, true);
// Restore caller sp for c2i case and return.
__ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
@ -1910,7 +1908,7 @@ address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
return NULL;
}
// CRC32 Intrinsics.
/**
* Method entry for static native methods:
* int java.util.zip.CRC32.updateBytes( int crc, byte[] b, int off, int len)
@ -1986,7 +1984,7 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
// Performance measurements show the 1word and 2word variants to be almost equivalent,
// with very light advantages for the 1word variant. We chose the 1word variant for
// code compactness.
__ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, tc3);
__ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, tc3, true);
// Restore caller sp for c2i case and return.
__ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
@ -2002,8 +2000,88 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
return NULL;
}
// Not supported
/**
* Method entry for intrinsic-candidate (non-native) methods:
* int java.util.zip.CRC32C.updateBytes( int crc, byte[] b, int off, int end)
* int java.util.zip.CRC32C.updateDirectByteBuffer(int crc, long* buf, int off, int end)
* Unlike CRC32, CRC32C does not have any methods marked as native
* CRC32C also uses an "end" variable instead of the length variable CRC32 uses
**/
address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
if (UseCRC32CIntrinsics) {
address start = __ pc(); // Remember stub start address (is rtn value).
// We don't generate local frame and don't align stack because
// we not even call stub code (we generate the code inline)
// and there is no safepoint on this path.
// Load parameters.
// Z_esp is callers operand stack pointer, i.e. it points to the parameters.
const Register argP = R15_esp;
const Register crc = R3_ARG1; // crc value
const Register data = R4_ARG2; // address of java byte array
const Register dataLen = R5_ARG3; // source data len
const Register table = R6_ARG4; // address of crc32c table
const Register t0 = R9; // scratch registers for crc calculation
const Register t1 = R10;
const Register t2 = R11;
const Register t3 = R12;
const Register tc0 = R2; // registers to hold pre-calculated column addresses
const Register tc1 = R7;
const Register tc2 = R8;
const Register tc3 = table; // table address is reconstructed at the end of kernel_crc32_* emitters
const Register tmp = t0; // Only used very locally to calculate byte buffer address.
// Arguments are reversed on java expression stack.
// Calculate address of start element.
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) { // Used for "updateDirectByteBuffer".
BLOCK_COMMENT("CRC32C_updateDirectByteBuffer {");
// crc @ (SP + 5W) (32bit)
// buf @ (SP + 3W) (64bit ptr to long array)
// off @ (SP + 2W) (32bit)
// dataLen @ (SP + 1W) (32bit)
// data = buf + off
__ ld( data, 3*wordSize, argP); // start of byte buffer
__ lwa( tmp, 2*wordSize, argP); // byte buffer offset
__ lwa( dataLen, 1*wordSize, argP); // #bytes to process
__ lwz( crc, 5*wordSize, argP); // current crc state
__ add( data, data, tmp); // Add byte buffer offset.
__ sub( dataLen, dataLen, tmp); // (end_index - offset)
} else { // Used for "updateBytes update".
BLOCK_COMMENT("CRC32C_updateBytes {");
// crc @ (SP + 4W) (32bit)
// buf @ (SP + 3W) (64bit ptr to byte array)
// off @ (SP + 2W) (32bit)
// dataLen @ (SP + 1W) (32bit)
// data = buf + off + base_offset
__ ld( data, 3*wordSize, argP); // start of byte buffer
__ lwa( tmp, 2*wordSize, argP); // byte buffer offset
__ lwa( dataLen, 1*wordSize, argP); // #bytes to process
__ add( data, data, tmp); // add byte buffer offset
__ sub( dataLen, dataLen, tmp); // (end_index - offset)
__ lwz( crc, 4*wordSize, argP); // current crc state
__ addi(data, data, arrayOopDesc::base_offset_in_bytes(T_BYTE));
}
StubRoutines::ppc64::generate_load_crc32c_table_addr(_masm, table);
// Performance measurements show the 1word and 2word variants to be almost equivalent,
// with very light advantages for the 1word variant. We chose the 1word variant for
// code compactness.
__ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, tc3, false);
// Restore caller sp for c2i case and return.
__ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
__ blr();
BLOCK_COMMENT("} CRC32C_update{Bytes|DirectByteBuffer}");
return start;
}
return NULL;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2016 SAP SE. All rights reserved.
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2017 SAP SE. 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
@ -1472,13 +1472,13 @@ void TemplateTable::convert() {
case Bytecodes::_i2d:
__ extsw(R17_tos, R17_tos);
case Bytecodes::_l2d:
__ push_l_pop_d();
__ move_l_to_d();
__ fcfid(F15_ftos, F15_ftos);
break;
case Bytecodes::_i2f:
__ extsw(R17_tos, R17_tos);
__ push_l_pop_d();
__ move_l_to_d();
if (VM_Version::has_fcfids()) { // fcfids is >= Power7 only
// Comment: alternatively, load with sign extend could be done by lfiwax.
__ fcfids(F15_ftos, F15_ftos);
@ -1490,7 +1490,7 @@ void TemplateTable::convert() {
case Bytecodes::_l2f:
if (VM_Version::has_fcfids()) { // fcfids is >= Power7 only
__ push_l_pop_d();
__ move_l_to_d();
__ fcfids(F15_ftos, F15_ftos);
} else {
// Avoid rounding problem when result should be 0x3f800001: need fixup code before fcfid+frsp.
@ -1514,7 +1514,7 @@ void TemplateTable::convert() {
__ li(R17_tos, 0); // 0 in case of NAN
__ bso(CCR0, done);
__ fctiwz(F15_ftos, F15_ftos);
__ push_d_pop_l();
__ move_d_to_l();
break;
case Bytecodes::_d2l:
@ -1523,7 +1523,7 @@ void TemplateTable::convert() {
__ li(R17_tos, 0); // 0 in case of NAN
__ bso(CCR0, done);
__ fctidz(F15_ftos, F15_ftos);
__ push_d_pop_l();
__ move_d_to_l();
break;
default: ShouldNotReachHere();
@ -3660,11 +3660,9 @@ void TemplateTable::_new() {
__ cmpdi(CCR0, Rtags, JVM_CONSTANT_Class);
__ bne(CCR0, Lslow_case);
// Get instanceKlass (load from Rcpool + sizeof(ConstantPool) + Rindex*BytesPerWord).
// Get instanceKlass
__ sldi(Roffset, Rindex, LogBytesPerWord);
__ addi(Rscratch, Rcpool, sizeof(ConstantPool));
__ isync(); // Order load of instance Klass wrt. tags.
__ ldx(RinstanceKlass, Roffset, Rscratch);
__ load_resolved_klass_at_offset(Rcpool, Roffset, RinstanceKlass);
// Make sure klass is fully initialized and get instance_size.
__ lbz(Rscratch, in_bytes(InstanceKlass::init_state_offset()), RinstanceKlass);
@ -3722,7 +3720,7 @@ void TemplateTable::_new() {
__ bge(CCR0, Lslow_case);
// Increment waste limit to prevent getting stuck on this slow path.
__ addi(RtlabWasteLimitValue, RtlabWasteLimitValue, (int)ThreadLocalAllocBuffer::refill_waste_limit_increment());
__ add_const_optimized(RtlabWasteLimitValue, RtlabWasteLimitValue, ThreadLocalAllocBuffer::refill_waste_limit_increment());
__ std(RtlabWasteLimitValue, in_bytes(JavaThread::tlab_refill_waste_limit_offset()), R16_thread);
}
// else: No allocation in the shared eden. // fallthru: __ b(Lslow_case);
@ -3875,9 +3873,7 @@ void TemplateTable::checkcast() {
// Extract target class from constant pool.
__ bind(Lquicked);
__ sldi(Roffset, Roffset, LogBytesPerWord);
__ addi(Rcpool, Rcpool, sizeof(ConstantPool));
__ isync(); // Order load of specified Klass wrt. tags.
__ ldx(RspecifiedKlass, Rcpool, Roffset);
__ load_resolved_klass_at_offset(Rcpool, Roffset, RspecifiedKlass);
// Do the checkcast.
__ bind(Lresolved);
@ -3939,9 +3935,7 @@ void TemplateTable::instanceof() {
// Extract target class from constant pool.
__ bind(Lquicked);
__ sldi(Roffset, Roffset, LogBytesPerWord);
__ addi(Rcpool, Rcpool, sizeof(ConstantPool));
__ isync(); // Order load of specified Klass wrt. tags.
__ ldx(RspecifiedKlass, Rcpool, Roffset);
__ load_resolved_klass_at_offset(Rcpool, Roffset, RspecifiedKlass);
// Do the checkcast.
__ bind(Lresolved);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017, SAP SE. 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
@ -28,9 +28,11 @@
#include "asm/macroAssembler.inline.hpp"
#include "compiler/disassembler.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvm.h"
#include "runtime/java.hpp"
#include "runtime/os.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "utilities/align.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/globalDefinitions.hpp"
#include "vm_version_ppc.hpp"
@ -79,7 +81,7 @@ void VM_Version::initialize() {
UINTX_FORMAT " on this machine", PowerArchitecturePPC64);
// Power 8: Configure Data Stream Control Register.
if (has_mfdscr()) {
if (PowerArchitecturePPC64 >= 8 && has_mfdscr()) {
config_dscr();
}
@ -111,7 +113,7 @@ void VM_Version::initialize() {
// Create and print feature-string.
char buf[(num_features+1) * 16]; // Max 16 chars per feature.
jio_snprintf(buf, sizeof(buf),
"ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
"ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
(has_fsqrt() ? " fsqrt" : ""),
(has_isel() ? " isel" : ""),
(has_lxarxeh() ? " lxarxeh" : ""),
@ -126,7 +128,9 @@ void VM_Version::initialize() {
(has_vpmsumb() ? " vpmsumb" : ""),
(has_tcheck() ? " tcheck" : ""),
(has_mfdscr() ? " mfdscr" : ""),
(has_vsx() ? " vsx" : "")
(has_vsx() ? " vsx" : ""),
(has_ldbrx() ? " ldbrx" : ""),
(has_stdbrx() ? " stdbrx" : "")
// Make sure number of %s matches num_features!
);
_features_string = os::strdup(buf);
@ -172,18 +176,27 @@ void VM_Version::initialize() {
assert(AllocatePrefetchStyle >= 0, "AllocatePrefetchStyle should be positive");
// Implementation does not use any of the vector instructions
// available with Power8. Their exploitation is still pending.
// If defined(VM_LITTLE_ENDIAN) and running on Power8 or newer hardware,
// the implementation uses the vector instructions available with Power8.
// In all other cases, the implementation uses only generally available instructions.
if (!UseCRC32Intrinsics) {
if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
FLAG_SET_DEFAULT(UseCRC32Intrinsics, true);
}
}
if (UseCRC32CIntrinsics) {
if (!FLAG_IS_DEFAULT(UseCRC32CIntrinsics))
warning("CRC32C intrinsics are not available on this CPU");
FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
// Implementation does not use any of the vector instructions available with Power8.
// Their exploitation is still pending (aka "work in progress").
if (!UseCRC32CIntrinsics) {
if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
}
}
// TODO: Provide implementation.
if (UseAdler32Intrinsics) {
warning("Adler32Intrinsics not available on this CPU.");
FLAG_SET_DEFAULT(UseAdler32Intrinsics, false);
}
// The AES intrinsic stubs require AES instruction support.
@ -245,11 +258,6 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
}
if (UseAdler32Intrinsics) {
warning("Adler32Intrinsics not available on this CPU.");
FLAG_SET_DEFAULT(UseAdler32Intrinsics, false);
}
if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
UseMultiplyToLenIntrinsic = true;
}
@ -319,18 +327,6 @@ void VM_Version::initialize() {
// high lock contention. For now we do not use it by default.
vm_exit_during_initialization("UseRTMLocking flag should be only set on command line");
}
if (!is_power_of_2(RTMTotalCountIncrRate)) {
warning("RTMTotalCountIncrRate must be a power of 2, resetting it to 64");
FLAG_SET_DEFAULT(RTMTotalCountIncrRate, 64);
}
if (RTMAbortRatio < 0 || RTMAbortRatio > 100) {
warning("RTMAbortRatio must be in the range 0 to 100, resetting it to 50");
FLAG_SET_DEFAULT(RTMAbortRatio, 50);
}
if (RTMSpinLoopCount < 0) {
warning("RTMSpinLoopCount must not be a negative value, resetting it to 0");
FLAG_SET_DEFAULT(RTMSpinLoopCount, 0);
}
#else
// Only C2 does RTM locking optimization.
// Can't continue because UseRTMLocking affects UseBiasedLocking flag
@ -659,6 +655,8 @@ void VM_Version::determine_features() {
a->tcheck(0); // code[12] -> tcheck
a->mfdscr(R0); // code[13] -> mfdscr
a->lxvd2x(VSR0, R3_ARG1); // code[14] -> vsx
a->ldbrx(R7, R3_ARG1, R4_ARG2); // code[15] -> ldbrx
a->stdbrx(R7, R3_ARG1, R4_ARG2); // code[16] -> stdbrx
a->blr();
// Emit function to set one cache line to zero. Emit function descriptor and get pointer to it.
@ -688,7 +686,7 @@ void VM_Version::determine_features() {
// Execute code. Illegal instructions will be replaced by 0 in the signal handler.
VM_Version::_is_determine_features_test_running = true;
// We must align the first argument to 16 bytes because of the lqarx check.
(*test)((address)align_size_up((intptr_t)mid_of_test_area, 16), (uint64_t)0);
(*test)(align_up((address)mid_of_test_area, 16), 0);
VM_Version::_is_determine_features_test_running = false;
// determine which instructions are legal.
@ -708,6 +706,8 @@ void VM_Version::determine_features() {
if (code[feature_cntr++]) features |= tcheck_m;
if (code[feature_cntr++]) features |= mfdscr_m;
if (code[feature_cntr++]) features |= vsx_m;
if (code[feature_cntr++]) features |= ldbrx_m;
if (code[feature_cntr++]) features |= stdbrx_m;
// Print the detection code.
if (PrintAssembly) {

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. 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,6 +47,8 @@ protected:
tcheck,
mfdscr,
vsx,
ldbrx,
stdbrx,
num_features // last entry to count features
};
enum Feature_Flag_Set {
@ -66,6 +68,8 @@ protected:
tcheck_m = (1 << tcheck ),
mfdscr_m = (1 << mfdscr ),
vsx_m = (1 << vsx ),
ldbrx_m = (1 << ldbrx ),
stdbrx_m = (1 << stdbrx ),
all_features_m = (unsigned long)-1
};
@ -100,6 +104,9 @@ public:
static bool has_tcheck() { return (_features & tcheck_m) != 0; }
static bool has_mfdscr() { return (_features & mfdscr_m) != 0; }
static bool has_vsx() { return (_features & vsx_m) != 0; }
static bool has_ldbrx() { return (_features & ldbrx_m) != 0; }
static bool has_stdbrx() { return (_features & stdbrx_m) != 0; }
static bool has_mtfprd() { return has_vpmsumb(); } // alias for P8
// Assembler testing
static void allow_all();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -51,11 +51,6 @@ int AbstractInterpreter::BasicType_as_index(BasicType type) {
return i;
}
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
// No special entry points that preclude compilation.
return true;
}
// How much stack a method top interpreter activation needs in words.
int AbstractInterpreter::size_top_interpreter_activation(Method* method) {

View File

@ -28,8 +28,6 @@
#undef LUCY_DBG
#define NearLabel Label
// Immediate is an abstraction to represent the various immediate
// operands which exist on z/Architecture. Neither this class nor
// instances hereof have an own state. It consists of methods only.

View File

@ -42,12 +42,6 @@ class Bytes: AllStatic {
//
// In short, it makes no sense on z/Architecture to piecemeal get or put unaligned data.
// Returns true if the byte ordering used by Java is different from
// the native byte ordering of the underlying machine.
// z/Arch is big endian, thus, a swap between native and Java ordering
// is always a no-op.
static inline bool is_Java_byte_ordering_different() { return false; }
// Only swap on little endian machines => suffix `_le'.
static inline u2 swap_u2_le(u2 x) { return x; }
static inline u4 swap_u4_le(u4 x) { return x; }

View File

@ -31,6 +31,7 @@
#include "c1/c1_Runtime1.hpp"
#include "nativeInst_s390.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/align.hpp"
#include "utilities/macros.hpp"
#include "vmreg_s390.inline.hpp"
#if INCLUDE_ALL_GCS
@ -284,7 +285,7 @@ void PatchingStub::align_patch_site(MacroAssembler* masm) {
masm->block_comment(bc);
#endif
masm->align(round_to(NativeGeneralJump::instruction_size, wordSize));
masm->align(align_up((int)NativeGeneralJump::instruction_size, wordSize));
}
void PatchingStub::emit_code(LIR_Assembler* ce) {

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, SAP SE. 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
@ -1139,14 +1139,7 @@ void LIR_Assembler::return_op(LIR_Opr result) {
__ load_const_optimized(Z_R1_scratch, pp);
// Pop the frame before the safepoint code.
int retPC_offset = initial_frame_size_in_bytes() + _z_abi16(return_pc);
if (Displacement::is_validDisp(retPC_offset)) {
__ z_lg(Z_R14, retPC_offset, Z_SP);
__ add2reg(Z_SP, initial_frame_size_in_bytes());
} else {
__ add2reg(Z_SP, initial_frame_size_in_bytes());
__ restore_return_pc();
}
__ pop_frame_restore_retPC(initial_frame_size_in_bytes());
if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
__ reserved_stack_check(Z_R14);
@ -3048,9 +3041,8 @@ void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) {
assert_different_registers(val, crc, res);
__ load_const_optimized(res, StubRoutines::crc_table_addr());
__ not_(crc, noreg, false); // ~crc
__ update_byte_crc32(crc, val, res);
__ not_(res, crc, false); // ~crc
__ kernel_crc32_singleByteReg(crc, val, res, true);
__ z_lgfr(res, crc);
}
#undef __

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, SAP SE. 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
@ -61,20 +61,6 @@ void LIRItem::load_nonconstant(int bits) {
}
}
inline void load_int_as_long(LIR_List *ll, LIRItem &li, LIR_Opr dst) {
LIR_Opr r = li.value()->operand();
if (r->is_constant()) {
// Constants get loaded with sign extend on this platform.
ll->move(li.result(), dst);
} else {
if (!r->is_register()) {
li.load_item_force(dst);
}
LIR_Opr dst_l = FrameMap::as_long_opr(dst->as_register());
ll->convert(Bytecodes::_i2l, li.result(), dst_l); // Convert.
}
}
//--------------------------------------------------------------
// LIRGenerator
//--------------------------------------------------------------
@ -1224,10 +1210,9 @@ void LIRGenerator::do_update_CRC32(Intrinsic* x) {
LIR_Opr arg2 = cc->at(1);
LIR_Opr arg3 = cc->at(2);
// CCallingConventionRequiresIntsAsLongs
crc.load_item_force(arg1); // We skip int->long conversion here, because CRC32 stub doesn't care about high bits.
__ leal(LIR_OprFact::address(a), arg2);
load_int_as_long(gen()->lir(), len, arg3);
len.load_item_force(arg3); // We skip int->long conversion here, because CRC32 stub expects int.
__ call_runtime_leaf(StubRoutines::updateBytesCRC32(), LIR_OprFact::illegalOpr, result_reg, cc->args());
__ move(result_reg, result);
@ -1240,7 +1225,70 @@ void LIRGenerator::do_update_CRC32(Intrinsic* x) {
}
void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
Unimplemented();
assert(UseCRC32CIntrinsics, "or should not be here");
LIR_Opr result = rlock_result(x);
switch (x->id()) {
case vmIntrinsics::_updateBytesCRC32C:
case vmIntrinsics::_updateDirectByteBufferCRC32C: {
bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32C);
LIRItem crc(x->argument_at(0), this);
LIRItem buf(x->argument_at(1), this);
LIRItem off(x->argument_at(2), this);
LIRItem end(x->argument_at(3), this);
buf.load_item();
off.load_nonconstant();
end.load_nonconstant();
// len = end - off
LIR_Opr len = end.result();
LIR_Opr tmpA = new_register(T_INT);
LIR_Opr tmpB = new_register(T_INT);
__ move(end.result(), tmpA);
__ move(off.result(), tmpB);
__ sub(tmpA, tmpB, tmpA);
len = tmpA;
LIR_Opr index = off.result();
int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0;
if (off.result()->is_constant()) {
index = LIR_OprFact::illegalOpr;
offset += off.result()->as_jint();
}
LIR_Opr base_op = buf.result();
if (index->is_valid()) {
LIR_Opr tmp = new_register(T_LONG);
__ convert(Bytecodes::_i2l, index, tmp);
index = tmp;
}
LIR_Address* a = new LIR_Address(base_op, index, offset, T_BYTE);
BasicTypeList signature(3);
signature.append(T_INT);
signature.append(T_ADDRESS);
signature.append(T_INT);
CallingConvention* cc = frame_map()->c_calling_convention(&signature);
const LIR_Opr result_reg = result_register_for (x->type());
LIR_Opr arg1 = cc->at(0);
LIR_Opr arg2 = cc->at(1);
LIR_Opr arg3 = cc->at(2);
crc.load_item_force(arg1); // We skip int->long conversion here, because CRC32C stub doesn't care about high bits.
__ leal(LIR_OprFact::address(a), arg2);
__ move(len, cc->at(2)); // We skip int->long conversion here, because CRC32C stub expects int.
__ call_runtime_leaf(StubRoutines::updateBytesCRC32C(), LIR_OprFact::illegalOpr, result_reg, cc->args());
__ move(result_reg, result);
break;
}
default: {
ShouldNotReachHere();
}
}
}
void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
@ -1271,4 +1319,3 @@ void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
fatal("vectorizedMismatch intrinsic is not implemented on this platform");
}

View File

@ -70,7 +70,7 @@ void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_by
assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
generate_stack_overflow_check(bang_size_in_bytes);
save_return_pc();
push_frame(frame_size_in_bytes); // TODO: Must we add z_abi_160?
push_frame(frame_size_in_bytes);
}
void C1_MacroAssembler::unverified_entry(Register receiver, Register ic_klass) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -496,6 +496,8 @@ void frame::describe_pd(FrameValues& values, int frame_no) {
}
}
void frame::pd_ps() {}
#endif // !PRODUCT
intptr_t *frame::initial_deoptimization_info() {

View File

@ -28,6 +28,7 @@
#include "code/codeCache.hpp"
#include "code/vmreg.inline.hpp"
#include "utilities/align.hpp"
// Inline functions for z/Architecture frames:
@ -241,7 +242,7 @@ inline void frame::interpreter_frame_set_monitor_end(BasicObjectLock* monitors)
inline int frame::interpreter_frame_monitor_size() {
// Number of stack slots for a monitor
return round_to(BasicObjectLock::size() /* number of stack slots */,
return align_up(BasicObjectLock::size() /* number of stack slots */,
WordsPerLong /* Number of stack slots for a Java long. */);
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017 SAP SE. 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
@ -107,24 +107,15 @@ void InterpreterMacroAssembler::dispatch_base(TosState state, address* table) {
// TODO: Maybe implement +VerifyActivationFrameSize here.
// verify_thread(); // Too slow. We will just verify on method entry & exit.
verify_oop(Z_tos, state);
#ifdef FAST_DISPATCH
if (table == Interpreter::dispatch_table(state)) {
// Use IdispatchTables.
add(Lbyte_code, Interpreter::distance_from_dispatch_table(state), Lbyte_code);
// Add offset to correct dispatch table.
sll(Lbyte_code, LogBytesPerWord, Lbyte_code); // Multiply by wordSize.
ld_ptr(IdispatchTables, Lbyte_code, G3_scratch); // Get entry addr.
} else
#endif
{
// Dispatch table to use.
load_absolute_address(Z_tmp_1, (address) table); // Z_tmp_1 = table;
// 0 <= Z_bytecode < 256 => Use a 32 bit shift, because it is shorter than sllg.
// Z_bytecode must have been loaded zero-extended for this approach to be correct.
z_sll(Z_bytecode, LogBytesPerWord, Z_R0); // Multiply by wordSize.
z_lg(Z_tmp_1, 0, Z_bytecode, Z_tmp_1); // Get entry addr.
}
// Dispatch table to use.
load_absolute_address(Z_tmp_1, (address) table); // Z_tmp_1 = table;
// 0 <= Z_bytecode < 256 => Use a 32 bit shift, because it is shorter than sllg.
// Z_bytecode must have been loaded zero-extended for this approach to be correct.
z_sll(Z_bytecode, LogBytesPerWord, Z_R0); // Multiply by wordSize.
z_lg(Z_tmp_1, 0, Z_bytecode, Z_tmp_1); // Get entry addr.
z_br(Z_tmp_1);
}
@ -371,7 +362,8 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result
Register tmp = index; // reuse
z_sllg(index, index, LogBytesPerHeapOop); // Offset into resolved references array.
// Load pointer for resolved_references[] objArray.
z_lg(result, ConstantPool::resolved_references_offset_in_bytes(), result);
z_lg(result, ConstantPool::cache_offset_in_bytes(), result);
z_lg(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
// JNIHandles::resolve(result)
z_lg(result, 0, result); // Load resolved references array itself.
#ifdef ASSERT
@ -386,6 +378,16 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result
load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result);
}
// load cpool->resolved_klass_at(index)
void InterpreterMacroAssembler::load_resolved_klass_at_offset(Register cpool, Register offset, Register iklass) {
// int value = *(Rcpool->int_at_addr(which));
// int resolved_klass_index = extract_low_short_from_int(value);
z_llgh(offset, Address(cpool, offset, sizeof(ConstantPool) + 2)); // offset = resolved_klass_index (s390 is big-endian)
z_sllg(offset, offset, LogBytesPerWord); // Convert 'index' to 'offset'
z_lg(iklass, Address(cpool, ConstantPool::resolved_klasses_offset_in_bytes())); // iklass = cpool->_resolved_klasses
z_lg(iklass, Address(iklass, offset, Array<Klass*>::base_offset_in_bytes()));
}
void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
Register tmp,
int bcp_offset,

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017 SAP SE. 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
@ -48,9 +48,6 @@ class InterpreterMacroAssembler: public MacroAssembler {
bool allow_relocation,
bool check_exceptions);
virtual void check_and_handle_popframe(Register java_thread);
virtual void check_and_handle_earlyret(Register java_thread);
// Base routine for all dispatches.
void dispatch_base(TosState state, address* table);
@ -58,6 +55,9 @@ class InterpreterMacroAssembler: public MacroAssembler {
InterpreterMacroAssembler(CodeBuffer* c)
: MacroAssembler(c) {}
virtual void check_and_handle_popframe(Register java_thread);
virtual void check_and_handle_earlyret(Register java_thread);
void jump_to_entry(address entry, Register Rscratch);
virtual void load_earlyret_value(TosState state);
@ -115,6 +115,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
void load_resolved_reference_at_index(Register result, Register index);
// load cpool->resolved_klass_at(index)
void load_resolved_klass_at_offset(Register cpool, Register offset, Register iklass);
// Pop topmost element from stack. It just disappears. Useful if
// consumed previously by access via stackTop().

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