8248238: Implementation: JEP 388: Windows AArch64 Support

Co-authored-by: Monica Beckwith <mbeckwit@openjdk.org>
Co-authored-by: Ludovic Henry <luhenry@openjdk.org>
Co-authored-by: Bernhard Urban-Forster <burban@openjdk.org>
Reviewed-by: dholmes, cjplummer, aph, ihse
This commit is contained in:
Monica Beckwith 2020-10-05 03:21:39 +00:00 committed by David Holmes
parent 1c2754bfe3
commit 9604ee8269
62 changed files with 2440 additions and 358 deletions

View File

@ -117,6 +117,16 @@ AC_DEFUN([BASIC_EVAL_DEVKIT_VARIABLE],
fi
])
###############################################################################
# Evaluates platform specific overrides for build devkit variables.
# $1: Name of variable
AC_DEFUN([BASIC_EVAL_BUILD_DEVKIT_VARIABLE],
[
if test "x[$]$1" = x; then
eval $1="\${$1_${OPENJDK_BUILD_CPU}}"
fi
])
###############################################################################
AC_DEFUN_ONCE([BASIC_SETUP_DEVKIT],
[

View File

@ -666,7 +666,9 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
# toolchain dependend, per-cpu
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
if test "x$FLAGS_CPU" = xx86_64; then
if test "x$FLAGS_CPU" = xaarch64; then
$1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -D_ARM64_ -Darm64"
elif test "x$FLAGS_CPU" = xx86_64; then
$1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -D_AMD64_ -Damd64"
else
$1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -D_X86_ -Dx86"

View File

@ -165,14 +165,13 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_CPU_DEP],
fi
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
if test "x${OPENJDK_$1_CPU_BITS}" = "x32"; then
$1_CPU_EXECUTABLE_LDFLAGS="-stack:327680"
elif test "x${OPENJDK_$1_CPU_BITS}" = "x64"; then
$1_CPU_EXECUTABLE_LDFLAGS="-stack:1048576"
fi
if test "x${OPENJDK_$1_CPU}" = "xx86"; then
$1_CPU_LDFLAGS="-safeseh"
# NOTE: Old build added -machine. Probably not needed.
$1_CPU_LDFLAGS_JVM_ONLY="-machine:I386"
$1_CPU_EXECUTABLE_LDFLAGS="-stack:327680"
else
$1_CPU_LDFLAGS_JVM_ONLY="-machine:AMD64"
$1_CPU_EXECUTABLE_LDFLAGS="-stack:1048576"
fi
fi

View File

@ -237,8 +237,9 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_AOT],
JVM_FEATURES_CHECK_AVAILABILITY(aot, [
AC_MSG_CHECKING([if platform is supported by AOT])
# AOT is only available where JVMCI is available since it requires JVMCI.
if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then
if test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
AC_MSG_RESULT([yes])
elif test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU])
@ -303,8 +304,9 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_GRAAL],
JVM_FEATURES_CHECK_AVAILABILITY(graal, [
AC_MSG_CHECKING([if platform is supported by Graal])
# Graal is only available where JVMCI is available since it requires JVMCI.
if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then
if test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
AC_MSG_RESULT([yes])
elif test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU])
@ -336,8 +338,9 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_JVMCI],
[
JVM_FEATURES_CHECK_AVAILABILITY(jvmci, [
AC_MSG_CHECKING([if platform is supported by JVMCI])
if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then
if test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
AC_MSG_RESULT([yes])
elif test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU])

View File

@ -872,14 +872,18 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS],
. $CONFIGURESUPPORT_OUTPUTDIR/build-devkit.info
# This potentially sets the following:
# A descriptive name of the devkit
BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_NAME])
BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_NAME])
# Corresponds to --with-extra-path
BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_EXTRA_PATH])
BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_EXTRA_PATH])
# Corresponds to --with-toolchain-path
BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_TOOLCHAIN_PATH])
BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_TOOLCHAIN_PATH])
# Corresponds to --with-sysroot
BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_SYSROOT])
# Skip the Window specific parts
BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_SYSROOT])
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_VS_INCLUDE])
BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_VS_LIB])
fi
fi
AC_MSG_CHECKING([for build platform devkit])
@ -889,13 +893,20 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS],
AC_MSG_RESULT([$BUILD_DEVKIT_ROOT])
fi
BUILD_SYSROOT="$BUILD_DEVKIT_SYSROOT"
# Fallback default of just /bin if DEVKIT_PATH is not defined
# Fallback default of just /bin if DEVKIT_PATH is not defined
if test "x$BUILD_DEVKIT_TOOLCHAIN_PATH" = x; then
BUILD_DEVKIT_TOOLCHAIN_PATH="$BUILD_DEVKIT_ROOT/bin"
fi
PATH="$BUILD_DEVKIT_TOOLCHAIN_PATH:$BUILD_DEVKIT_EXTRA_PATH"
BUILD_SYSROOT="$BUILD_DEVKIT_SYSROOT"
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
BUILD_VS_INCLUDE="$BUILD_DEVKIT_VS_INCLUDE"
BUILD_VS_LIB="$BUILD_DEVKIT_VS_LIB"
TOOLCHAIN_SETUP_VISUAL_STUDIO_SYSROOT_FLAGS([BUILD_])
fi
fi
fi
@ -921,9 +932,37 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS],
UTIL_FIXUP_EXECUTABLE(BUILD_STRIP)
# Assume the C compiler is the assembler
BUILD_AS="$BUILD_CC -c"
# Just like for the target compiler, use the compiler as linker
BUILD_LD="$BUILD_CC"
BUILD_LDCXX="$BUILD_CXX"
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
# In the Microsoft toolchain we have a separate LD command "link".
# Make sure we reject /usr/bin/link (as determined in CYGWIN_LINK), which is
# a cygwin program for something completely different.
AC_CHECK_PROG([BUILD_LD], [link$EXE_SUFFIX],[link$EXE_SUFFIX],,, [$CYGWIN_LINK])
UTIL_FIXUP_EXECUTABLE(BUILD_LD)
# Verify that we indeed succeeded with this trick.
AC_MSG_CHECKING([if the found link.exe is actually the Visual Studio linker])
# Reset PATH since it can contain a mix of WSL/linux paths and Windows paths from VS,
# which, in combination with WSLENV, will make the WSL layer complain
old_path="$PATH"
PATH=
"$BUILD_LD" --version > /dev/null
if test $? -eq 0 ; then
AC_MSG_RESULT([no])
AC_MSG_ERROR([This is the Cygwin link tool. Please check your PATH and rerun configure.])
else
AC_MSG_RESULT([yes])
fi
PATH="$old_path"
BUILD_LDCXX="$BUILD_LD"
else
# Just like for the target compiler, use the compiler as linker
BUILD_LD="$BUILD_CC"
BUILD_LDCXX="$BUILD_CXX"
fi
PATH="$OLDPATH"
@ -974,6 +1013,10 @@ AC_DEFUN_ONCE([TOOLCHAIN_MISC_CHECKS],
if test "x$COMPILER_CPU_TEST" != "xx64"; then
AC_MSG_ERROR([Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for "$COMPILER_CPU_TEST"; expected "x64".])
fi
elif test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then
if test "x$COMPILER_CPU_TEST" != "xARM64"; then
AC_MSG_ERROR([Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for "$COMPILER_CPU_TEST"; expected "arm64".])
fi
fi
fi

View File

@ -79,11 +79,15 @@ AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT],
if test -d "$VS_BASE"; then
AC_MSG_NOTICE([Found Visual Studio installation at $VS_BASE using $METHOD])
if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then
if test "x$OPENJDK_TARGET_CPU" = xx86; then
VCVARSFILES="vc/bin/vcvars32.bat vc/auxiliary/build/vcvars32.bat"
else
elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then
VCVARSFILES="vc/bin/amd64/vcvars64.bat vc/bin/x86_amd64/vcvarsx86_amd64.bat \
VC/Auxiliary/Build/vcvarsx86_amd64.bat VC/Auxiliary/Build/vcvars64.bat"
elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then
# for host x86-64, target aarch64
VCVARSFILES="vc/auxiliary/build/vcvarsamd64_arm64.bat \
vc/auxiliary/build/vcvarsx86_arm64.bat"
fi
for VCVARSFILE in $VCVARSFILES; do
@ -123,10 +127,12 @@ AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT],
elif test -f "$WIN_SDK_BASE/Bin/SetEnv.Cmd"; then
AC_MSG_NOTICE([Found Windows SDK installation at $WIN_SDK_BASE using $METHOD])
VS_ENV_CMD="$WIN_SDK_BASE/Bin/SetEnv.Cmd"
if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then
if test "x$OPENJDK_TARGET_CPU" = xx86; then
VS_ENV_ARGS="/x86"
else
elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then
VS_ENV_ARGS="/x64"
elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then
VS_ENV_ARGS="/arm64"
fi
# PLATFORM_TOOLSET is used during the compilation of the freetype sources (see
# 'LIB_BUILD_FREETYPE' in libraries.m4) and must be 'Windows7.1SDK' for Windows7.1SDK
@ -520,41 +526,7 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV],
AC_SUBST(VS_INCLUDE)
AC_SUBST(VS_LIB)
# Convert VS_INCLUDE into SYSROOT_CFLAGS
OLDIFS="$IFS"
IFS=";"
for i in $VS_INCLUDE; do
ipath=$i
# Only process non-empty elements
if test "x$ipath" != x; then
IFS="$OLDIFS"
# Check that directory exists before calling fixup_path
testpath=$ipath
UTIL_REWRITE_AS_UNIX_PATH([testpath])
if test -d "$testpath"; then
UTIL_FIXUP_PATH([ipath])
SYSROOT_CFLAGS="$SYSROOT_CFLAGS -I$ipath"
fi
IFS=";"
fi
done
# Convert VS_LIB into SYSROOT_LDFLAGS
for i in $VS_LIB; do
libpath=$i
# Only process non-empty elements
if test "x$libpath" != x; then
IFS="$OLDIFS"
# Check that directory exists before calling fixup_path
testpath=$libpath
UTIL_REWRITE_AS_UNIX_PATH([testpath])
if test -d "$testpath"; then
UTIL_FIXUP_PATH([libpath])
SYSROOT_LDFLAGS="$SYSROOT_LDFLAGS -libpath:$libpath"
fi
IFS=";"
fi
done
IFS="$OLDIFS"
TOOLCHAIN_SETUP_VISUAL_STUDIO_SYSROOT_FLAGS
AC_SUBST(VS_PATH_WINDOWS)
fi
@ -593,10 +565,15 @@ AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL],
CORRECT_MSVCR_ARCH="PE32+ executable"
fi
else
if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then
if test "x$OPENJDK_TARGET_CPU" = xx86; then
CORRECT_MSVCR_ARCH=386
else
elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then
CORRECT_MSVCR_ARCH=x86-64
elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then
# The cygwin 'file' command only returns "PE32+ executable (DLL) (console), for MS Windows",
# without specifying which architecture it is for specifically. This has been fixed upstream.
# https://github.com/file/file/commit/b849b1af098ddd530094bf779b58431395db2e10#diff-ff2eced09e6860de75057dd731d092aeR142
CORRECT_MSVCR_ARCH="PE32+ executable"
fi
fi
if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then
@ -616,26 +593,26 @@ AC_DEFUN([TOOLCHAIN_SETUP_MSVC_DLL],
DLL_NAME="$1"
MSVC_DLL=
if test "x$OPENJDK_TARGET_CPU" = xx86; then
vs_target_cpu=x86
elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then
vs_target_cpu=x64
elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then
vs_target_cpu=arm64
fi
if test "x$MSVC_DLL" = x; then
if test "x$VCINSTALLDIR" != x; then
CYGWIN_VC_INSTALL_DIR="$VCINSTALLDIR"
UTIL_FIXUP_PATH(CYGWIN_VC_INSTALL_DIR)
if test "$VS_VERSION" -lt 2017; then
# Probe: Using well-known location from Visual Studio 12.0 and older
if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x64/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME"
else
POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x86/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME"
fi
POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/$vs_target_cpu/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME"
else
CYGWIN_VC_TOOLS_REDIST_DIR="$VCToolsRedistDir"
UTIL_FIXUP_PATH(CYGWIN_VC_TOOLS_REDIST_DIR)
# Probe: Using well-known location from VS 2017 and VS 2019
if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
POSSIBLE_MSVC_DLL="`ls $CYGWIN_VC_TOOLS_REDIST_DIR/x64/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME`"
else
POSSIBLE_MSVC_DLL="`ls $CYGWIN_VC_TOOLS_REDIST_DIR/x86/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME`"
fi
POSSIBLE_MSVC_DLL="`ls $CYGWIN_VC_TOOLS_REDIST_DIR/$vs_target_cpu/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME`"
fi
# In case any of the above finds more than one file, loop over them.
for possible_msvc_dll in $POSSIBLE_MSVC_DLL; do
@ -667,13 +644,8 @@ AC_DEFUN([TOOLCHAIN_SETUP_MSVC_DLL],
if test "x$VS100COMNTOOLS" != x; then
CYGWIN_VS_TOOLS_DIR="$VS100COMNTOOLS/.."
UTIL_REWRITE_AS_UNIX_PATH(CYGWIN_VS_TOOLS_DIR)
if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \
| $GREP -i /x64/ | $HEAD --lines 1`
else
POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \
| $GREP -i /x86/ | $HEAD --lines 1`
fi
POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \
| $GREP -i /$vs_target_cpu/ | $HEAD --lines 1`
TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL],
[search of VS100COMNTOOLS])
fi
@ -683,17 +655,17 @@ AC_DEFUN([TOOLCHAIN_SETUP_MSVC_DLL],
# Probe: Search wildly in the VCINSTALLDIR. We've probably lost by now.
# (This was the original behaviour; kept since it might turn something up)
if test "x$CYGWIN_VC_INSTALL_DIR" != x; then
if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
if test "x$OPENJDK_TARGET_CPU" = xx86; then
POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \
| $GREP x64 | $HEAD --lines 1`
else
POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \
| $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $HEAD --lines 1`
| $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $GREP -v arm64 | $HEAD --lines 1`
if test "x$POSSIBLE_MSVC_DLL" = x; then
# We're grasping at straws now...
POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \
| $HEAD --lines 1`
fi
else
POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \
| $GREP $vs_target_cpu | $HEAD --lines 1`
fi
TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL],
@ -757,9 +729,9 @@ AC_DEFUN([TOOLCHAIN_SETUP_VS_RUNTIME_DLLS],
fi
AC_ARG_WITH(vcruntime-1-dll, [AS_HELP_STRING([--with-vcruntime-1-dll],
[path to microsoft C++ runtime dll (vcruntime*_1.dll) (Windows only) @<:@probed@:>@])])
[path to microsoft C++ runtime dll (vcruntime*_1.dll) (Windows 64-bits only) @<:@probed@:>@])])
if test "x$VCRUNTIME_1_NAME" != "x"; then
if test "x$VCRUNTIME_1_NAME" != "x" -a "x$OPENJDK_TARGET_CPU_BITS" = x64; then
if test "x$with_vcruntime_1_dll" != x; then
# If given explicitly by user, do not probe. If not present, fail directly.
TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL($VCRUNTIME_1_NAME, [$with_vcruntime_1_dll],
@ -801,9 +773,12 @@ AC_DEFUN([TOOLCHAIN_SETUP_VS_RUNTIME_DLLS],
else
CYGWIN_WINDOWSSDKDIR="${WINDOWSSDKDIR}"
UTIL_FIXUP_PATH([CYGWIN_WINDOWSSDKDIR])
dll_subdir=$OPENJDK_TARGET_CPU
if test "x$dll_subdir" = "xx86_64"; then
if test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then
dll_subdir="arm64"
elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
dll_subdir="x64"
elif test "x$OPENJDK_TARGET_CPU" = "xx86"; then
dll_subdir="x86"
fi
UCRT_DLL_DIR="$CYGWIN_WINDOWSSDKDIR/Redist/ucrt/DLLs/$dll_subdir"
if test -z "$(ls -d "$UCRT_DLL_DIR/"*.dll 2> /dev/null)"; then
@ -826,3 +801,49 @@ AC_DEFUN([TOOLCHAIN_SETUP_VS_RUNTIME_DLLS],
fi
AC_SUBST(UCRT_DLL_DIR)
])
# Setup the sysroot flags and add them to global CFLAGS and LDFLAGS so
# that configure can use them while detecting compilers.
# TOOLCHAIN_TYPE is available here.
# Param 1 - Optional prefix to all variables. (e.g BUILD_)
AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_SYSROOT_FLAGS],
[
OLDIFS="$IFS"
IFS=";"
# Convert $1VS_INCLUDE into $1SYSROOT_CFLAGS
for i in [$]$1VS_INCLUDE; do
ipath=$i
# Only process non-empty elements
if test "x$ipath" != x; then
IFS="$OLDIFS"
# Check that directory exists before calling fixup_path
testpath=$ipath
UTIL_REWRITE_AS_UNIX_PATH([testpath])
if test -d "$testpath"; then
UTIL_FIXUP_PATH([ipath])
$1SYSROOT_CFLAGS="[$]$1SYSROOT_CFLAGS -I$ipath"
fi
IFS=";"
fi
done
# Convert $1VS_LIB into $1SYSROOT_LDFLAGS
for i in [$]$1VS_LIB; do
libpath=$i
# Only process non-empty elements
if test "x$libpath" != x; then
IFS="$OLDIFS"
# Check that directory exists before calling fixup_path
testpath=$libpath
UTIL_REWRITE_AS_UNIX_PATH([testpath])
if test -d "$testpath"; then
UTIL_FIXUP_PATH([libpath])
$1SYSROOT_LDFLAGS="[$]$1SYSROOT_LDFLAGS -libpath:$libpath"
fi
IFS=";"
fi
done
IFS="$OLDIFS"
AC_SUBST($1SYSROOT_CFLAGS)
AC_SUBST($1SYSROOT_LDFLAGS)
])

View File

@ -113,19 +113,23 @@ REDIST_SUBDIR="VC/Redist/MSVC/$REDIST_VERSION"
echo "Copying VC..."
rm -rf $DEVKIT_ROOT/VC
mkdir -p $DEVKIT_ROOT/VC/bin
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx64/arm64" $DEVKIT_ROOT/VC/bin/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx64/x64" $DEVKIT_ROOT/VC/bin/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx86/x86" $DEVKIT_ROOT/VC/bin/
mkdir -p $DEVKIT_ROOT/VC/lib
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/arm64" $DEVKIT_ROOT/VC/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/x64" $DEVKIT_ROOT/VC/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/x86" $DEVKIT_ROOT/VC/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/include" $DEVKIT_ROOT/VC/
mkdir -p $DEVKIT_ROOT/VC/atlmfc/lib
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/arm64" $DEVKIT_ROOT/VC/atlmfc/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/x64" $DEVKIT_ROOT/VC/atlmfc/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/x86" $DEVKIT_ROOT/VC/atlmfc/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/include" $DEVKIT_ROOT/VC/atlmfc/
mkdir -p $DEVKIT_ROOT/VC/Auxiliary
cp -r "$VS_INSTALL_DIR/VC/Auxiliary/Build" $DEVKIT_ROOT/VC/Auxiliary/
mkdir -p $DEVKIT_ROOT/VC/redist
cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/arm64" $DEVKIT_ROOT/VC/redist/
cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/x64" $DEVKIT_ROOT/VC/redist/
cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/x86" $DEVKIT_ROOT/VC/redist/
@ -134,7 +138,9 @@ cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/x86" $DEVKIT_ROOT/VC/redist/
cp $DEVKIT_ROOT/VC/redist/x86/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/x86
cp $DEVKIT_ROOT/VC/redist/x86/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/x86
cp $DEVKIT_ROOT/VC/redist/x64/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/x64
cp $DEVKIT_ROOT/VC/redist/x64/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/x64
cp $DEVKIT_ROOT/VC/redist/x64/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/x64
cp $DEVKIT_ROOT/VC/redist/arm64/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/arm64
cp $DEVKIT_ROOT/VC/redist/arm64/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/arm64
################################################################################
# Copy SDK files
@ -152,8 +158,10 @@ mkdir -p $DEVKIT_ROOT/$SDK_VERSION/bin
cp -r "$SDK_INSTALL_DIR/bin/$SDK_FULL_VERSION/x64" $DEVKIT_ROOT/$SDK_VERSION/bin/
cp -r "$SDK_INSTALL_DIR/bin/$SDK_FULL_VERSION/x86" $DEVKIT_ROOT/$SDK_VERSION/bin/
mkdir -p $DEVKIT_ROOT/$SDK_VERSION/lib
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/arm64" $DEVKIT_ROOT/$SDK_VERSION/lib/
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/x64" $DEVKIT_ROOT/$SDK_VERSION/lib/
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/x86" $DEVKIT_ROOT/$SDK_VERSION/lib/
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/arm64" $DEVKIT_ROOT/$SDK_VERSION/lib/
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/x64" $DEVKIT_ROOT/$SDK_VERSION/lib/
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/x86" $DEVKIT_ROOT/$SDK_VERSION/lib/
mkdir -p $DEVKIT_ROOT/$SDK_VERSION/Redist
@ -188,6 +196,13 @@ echo-info "DEVKIT_MSVCR_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$MSVCR_DLL\""
echo-info "DEVKIT_MSVCP_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$MSVCP_DLL\""
echo-info "DEVKIT_UCRT_DLL_DIR_x86_64=\"\$DEVKIT_ROOT/10/Redist/ucrt/DLLs/x64\""
echo-info ""
echo-info "DEVKIT_TOOLCHAIN_PATH_aarch64=\"\$DEVKIT_ROOT/VC/bin/arm64:\$DEVKIT_ROOT/$SDK_VERSION/bin/x64:\$DEVKIT_ROOT/$SDK_VERSION/bin/x86\""
echo-info "DEVKIT_VS_INCLUDE_aarch64=\"\$DEVKIT_ROOT/VC/include;\$DEVKIT_ROOT/VC/atlmfc/include;\$DEVKIT_ROOT/$SDK_VERSION/include/shared;\$DEVKIT_ROOT/$SDK_VERSION/include/ucrt;\$DEVKIT_ROOT/$SDK_VERSION/include/um;\$DEVKIT_ROOT/$SDK_VERSION/include/winrt\""
echo-info "DEVKIT_VS_LIB_aarch64=\"\$DEVKIT_ROOT/VC/lib/arm64;\$DEVKIT_ROOT/VC/atlmfc/lib/arm64;\$DEVKIT_ROOT/$SDK_VERSION/lib/arm64\""
echo-info "DEVKIT_MSVCR_DLL_aarch64=\"\$DEVKIT_ROOT/VC/redist/arm64/$MSVCR_DLL\""
echo-info "DEVKIT_MSVCP_DLL_aarch64=\"\$DEVKIT_ROOT/VC/redist/arm64/$MSVCP_DLL\""
echo-info "DEVKIT_UCRT_DLL_DIR_aarch64=\"\$DEVKIT_ROOT/10/Redist/ucrt/DLLs/arm64\""
echo-info ""
echo-info "DEVKIT_TOOLS_VERSION=\"$TOOLS_VERSION\""
echo-info "DEVKIT_REDIST_VERSION=\"$REDIST_VERSION\""
echo-info "DEVKIT_SDK_VERSION=\"$SDK_FULL_VERSION\""

View File

@ -117,19 +117,23 @@ REDIST_SUBDIR="VC/Redist/MSVC/$REDIST_VERSION"
echo "Copying VC..."
rm -rf $DEVKIT_ROOT/VC
mkdir -p $DEVKIT_ROOT/VC/bin
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx64/arm64" $DEVKIT_ROOT/VC/bin/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx64/x64" $DEVKIT_ROOT/VC/bin/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx86/x86" $DEVKIT_ROOT/VC/bin/
mkdir -p $DEVKIT_ROOT/VC/lib
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/arm64" $DEVKIT_ROOT/VC/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/x64" $DEVKIT_ROOT/VC/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/x86" $DEVKIT_ROOT/VC/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/include" $DEVKIT_ROOT/VC/
mkdir -p $DEVKIT_ROOT/VC/atlmfc/lib
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/arm64" $DEVKIT_ROOT/VC/atlmfc/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/x64" $DEVKIT_ROOT/VC/atlmfc/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/x86" $DEVKIT_ROOT/VC/atlmfc/lib/
cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/include" $DEVKIT_ROOT/VC/atlmfc/
mkdir -p $DEVKIT_ROOT/VC/Auxiliary
cp -r "$VS_INSTALL_DIR/VC/Auxiliary/Build" $DEVKIT_ROOT/VC/Auxiliary/
mkdir -p $DEVKIT_ROOT/VC/redist
cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/arm64" $DEVKIT_ROOT/VC/redist/
cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/x64" $DEVKIT_ROOT/VC/redist/
cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/x86" $DEVKIT_ROOT/VC/redist/
@ -139,6 +143,8 @@ cp $DEVKIT_ROOT/VC/redist/x86/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/x86
cp $DEVKIT_ROOT/VC/redist/x86/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/x86
cp $DEVKIT_ROOT/VC/redist/x64/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/x64
cp $DEVKIT_ROOT/VC/redist/x64/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/x64
cp $DEVKIT_ROOT/VC/redist/arm64/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/arm64
cp $DEVKIT_ROOT/VC/redist/arm64/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/arm64
################################################################################
# Copy SDK files
@ -156,8 +162,10 @@ mkdir -p $DEVKIT_ROOT/$SDK_VERSION/bin
cp -r "$SDK_INSTALL_DIR/bin/$SDK_FULL_VERSION/x64" $DEVKIT_ROOT/$SDK_VERSION/bin/
cp -r "$SDK_INSTALL_DIR/bin/$SDK_FULL_VERSION/x86" $DEVKIT_ROOT/$SDK_VERSION/bin/
mkdir -p $DEVKIT_ROOT/$SDK_VERSION/lib
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/arm64" $DEVKIT_ROOT/$SDK_VERSION/lib/
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/x64" $DEVKIT_ROOT/$SDK_VERSION/lib/
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/x86" $DEVKIT_ROOT/$SDK_VERSION/lib/
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/arm64" $DEVKIT_ROOT/$SDK_VERSION/lib/
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/x64" $DEVKIT_ROOT/$SDK_VERSION/lib/
cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/x86" $DEVKIT_ROOT/$SDK_VERSION/lib/
mkdir -p $DEVKIT_ROOT/$SDK_VERSION/Redist
@ -193,6 +201,14 @@ echo-info "DEVKIT_VCRUNTIME_1_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$VCRUNTIM
echo-info "DEVKIT_MSVCP_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$MSVCP_DLL\""
echo-info "DEVKIT_UCRT_DLL_DIR_x86_64=\"\$DEVKIT_ROOT/10/Redist/ucrt/DLLs/x64\""
echo-info ""
echo-info "DEVKIT_TOOLCHAIN_PATH_aarch64=\"\$DEVKIT_ROOT/VC/bin/arm64:\$DEVKIT_ROOT/$SDK_VERSION/bin/x64:\$DEVKIT_ROOT/$SDK_VERSION/bin/x86\""
echo-info "DEVKIT_VS_INCLUDE_aarch64=\"\$DEVKIT_ROOT/VC/include;\$DEVKIT_ROOT/VC/atlmfc/include;\$DEVKIT_ROOT/$SDK_VERSION/include/shared;\$DEVKIT_ROOT/$SDK_VERSION/include/ucrt;\$DEVKIT_ROOT/$SDK_VERSION/include/um;\$DEVKIT_ROOT/$SDK_VERSION/include/winrt\""
echo-info "DEVKIT_VS_LIB_aarch64=\"\$DEVKIT_ROOT/VC/lib/arm64;\$DEVKIT_ROOT/VC/atlmfc/lib/arm64;\$DEVKIT_ROOT/$SDK_VERSION/lib/arm64\""
echo-info "DEVKIT_MSVCR_DLL_aarch64=\"\$DEVKIT_ROOT/VC/redist/arm64/$MSVCR_DLL\""
echo-info "DEVKIT_VCRUNTIME_1_DLL_aarch64=\"\$DEVKIT_ROOT/VC/redist/arm64/$VCRUNTIME_1_DLL\""
echo-info "DEVKIT_MSVCP_DLL_aarch64=\"\$DEVKIT_ROOT/VC/redist/arm64/$MSVCP_DLL\""
echo-info "DEVKIT_UCRT_DLL_DIR_aarch64=\"\$DEVKIT_ROOT/10/Redist/ucrt/DLLs/arm64\""
echo-info ""
echo-info "DEVKIT_TOOLS_VERSION=\"$TOOLS_VERSION\""
echo-info "DEVKIT_REDIST_VERSION=\"$REDIST_VERSION\""
echo-info "DEVKIT_SDK_VERSION=\"$SDK_FULL_VERSION\""

View File

@ -88,6 +88,13 @@ ifeq ($(call check-jvm-feature, compiler2), true)
ADLCFLAGS += -DAIX=1
else ifeq ($(call isTargetOs, macosx), true)
ADLCFLAGS += -D_ALLBSD_SOURCE=1 -D_GNU_SOURCE=1
else ifeq ($(call isTargetOs, windows), true)
ifeq ($(call isTargetCpuBits, 64), true)
ADLCFLAGS += -D_WIN64=1
endif
ifeq ($(HOTSPOT_TARGET_CPU_ARCH), aarch64)
ADLCFLAGS += -DR18_RESERVED
endif
endif
ifeq ($(call isTargetOs, windows), false)

View File

@ -60,6 +60,12 @@ ifneq ($(filter $(TOOLCHAIN_TYPE), gcc clang), )
CPP_FLAGS += -x c
else ifeq ($(TOOLCHAIN_TYPE), microsoft)
CPP_FLAGS += -nologo
ifeq ($(OPENJDK_TARGET_CPU),aarch64)
# cl.exe does only recognize few file extensions as valid (ex: .c, .h, .cpp), so
# make sure *.java.template files are recognized as valid input files
CPP_FILEPREFIX = -Tc
endif
endif
# Generate a java source file from a template through the C preprocessor for the
@ -73,7 +79,7 @@ define generate-preproc-src
$(call MakeDir, $(@D))
$(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/gensrc/java.base/_$(@F), \
( $(NAWK) '/@@END_COPYRIGHT@@/{exit}1' $< && \
$(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $(CFLAGS_JDKLIB) $< \
$(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $(CFLAGS_JDKLIB) $(CPP_FILEPREFIX) $< \
2> >($(GREP) -v '^$(<F)$$' >&2) \
| $(NAWK) '/@@START_HERE@@/,0' \
| $(SED) -e 's/@@START_HERE@@/\/\/ AUTOMATICALLY GENERATED FILE - DO NOT EDIT/' \

View File

@ -13,6 +13,8 @@ class Register(Operand):
def generate(self):
self.number = random.randint(0, 30)
if self.number == 18:
self.number = 17
return self
def astr(self, prefix):
@ -37,6 +39,8 @@ class GeneralRegisterOrZr(Register):
def generate(self):
self.number = random.randint(0, 31)
if self.number == 18:
self.number = 16
return self
def astr(self, prefix = ""):
@ -54,6 +58,8 @@ class GeneralRegisterOrZr(Register):
class GeneralRegisterOrSp(Register):
def generate(self):
self.number = random.randint(0, 31)
if self.number == 18:
self.number = 15
return self
def astr(self, prefix = ""):
@ -1331,7 +1337,7 @@ generate(SpecialCases, [["ccmn", "__ ccmn(zr, zr, 3u, Assembler::LE);",
["st1w", "__ sve_st1w(z0, __ S, p1, Address(r0, 7));", "st1w\t{z0.s}, p1, [x0, #7, MUL VL]"],
["st1b", "__ sve_st1b(z0, __ B, p2, Address(sp, r1));", "st1b\t{z0.b}, p2, [sp, x1]"],
["st1h", "__ sve_st1h(z0, __ H, p3, Address(sp, r8));", "st1h\t{z0.h}, p3, [sp, x8, LSL #1]"],
["st1d", "__ sve_st1d(z0, __ D, p4, Address(r0, r18));", "st1d\t{z0.d}, p4, [x0, x18, LSL #3]"],
["st1d", "__ sve_st1d(z0, __ D, p4, Address(r0, r17));", "st1d\t{z0.d}, p4, [x0, x17, LSL #3]"],
["ldr", "__ sve_ldr(z0, Address(sp));", "ldr\tz0, [sp]"],
["ldr", "__ sve_ldr(z31, Address(sp, -256));", "ldr\tz31, [sp, #-256, MUL VL]"],
["str", "__ sve_str(z8, Address(r8, 255));", "str\tz8, [x8, #255, MUL VL]"],

View File

@ -114,8 +114,8 @@ reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() );
reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next());
reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() );
reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next());
reg_def R18 ( SOC, SOC, Op_RegI, 18, r18->as_VMReg() );
reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next());
reg_def R18 ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg() );
reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg()->next());
reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() );
reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next());
reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp
@ -716,6 +716,10 @@ reg_class any_reg %{
// Class for non-allocatable 32 bit registers
reg_class non_allocatable_reg32(
#ifdef R18_RESERVED
// See comment in register_aarch64.hpp
R18, // tls on Windows
#endif
R28, // thread
R30, // lr
R31 // sp
@ -723,6 +727,10 @@ reg_class non_allocatable_reg32(
// Class for non-allocatable 64 bit registers
reg_class non_allocatable_reg(
#ifdef R18_RESERVED
// See comment in register_aarch64.hpp
R18, R18_H, // tls on Windows, platform register on macOS
#endif
R28, R28_H, // thread
R30, R30_H, // lr
R31, R31_H // sp
@ -6286,7 +6294,7 @@ pipeline %{
attributes %{
// ARM instructions are of fixed length
fixed_size_instructions; // Fixed size instructions TODO does
max_instructions_per_bundle = 2; // A53 = 2, A57 = 4
max_instructions_per_bundle = 4; // A53 = 2, A57 = 4
// ARM instructions come in 32-bit word units
instruction_unit_size = 4; // An instruction is 4 bytes long
instruction_fetch_unit_size = 64; // The processor fetches one line

View File

@ -101,7 +101,7 @@ void entry(CodeBuffer *cb) {
__ adds(r28, r15, r8, Assembler::ASR, 39); // adds x28, x15, x8, ASR #39
__ subs(r7, r28, r30, Assembler::ASR, 57); // subs x7, x28, x30, ASR #57
__ addw(r9, r22, r27, Assembler::ASR, 15); // add w9, w22, w27, ASR #15
__ subw(r3, r13, r18, Assembler::ASR, 30); // sub w3, w13, w18, ASR #30
__ subw(r3, r13, r17, Assembler::ASR, 30); // sub w3, w13, w17, ASR #30
__ addsw(r14, r26, r8, Assembler::ASR, 17); // adds w14, w26, w8, ASR #17
__ subsw(r0, r22, r12, Assembler::ASR, 21); // subs w0, w22, w12, ASR #21
__ andr(r0, r15, r26, Assembler::LSL, 20); // and x0, x15, x26, LSL #20
@ -109,8 +109,8 @@ void entry(CodeBuffer *cb) {
__ eor(r24, r13, r2, Assembler::LSL, 32); // eor x24, x13, x2, LSL #32
__ ands(r28, r3, r17, Assembler::ASR, 35); // ands x28, x3, x17, ASR #35
__ andw(r25, r16, r29, Assembler::LSR, 18); // and w25, w16, w29, LSR #18
__ orrw(r13, r18, r11, Assembler::LSR, 9); // orr w13, w18, w11, LSR #9
__ eorw(r5, r5, r18, Assembler::LSR, 15); // eor w5, w5, w18, LSR #15
__ orrw(r13, r17, r11, Assembler::LSR, 9); // orr w13, w17, w11, LSR #9
__ eorw(r5, r5, r17, Assembler::LSR, 15); // eor w5, w5, w17, LSR #15
__ andsw(r2, r23, r27, Assembler::ASR, 26); // ands w2, w23, w27, ASR #26
__ bic(r27, r28, r16, Assembler::LSR, 45); // bic x27, x28, x16, LSR #45
__ orn(r8, r25, r26, Assembler::ASR, 37); // orn x8, x25, x26, ASR #37
@ -135,7 +135,7 @@ void entry(CodeBuffer *cb) {
__ andw(r6, r11, 4294049777ull); // and w6, w11, #0xfff1fff1
__ orrw(r28, r5, 4294966791ull); // orr w28, w5, #0xfffffe07
__ eorw(r1, r20, 134217216ull); // eor w1, w20, #0x7fffe00
__ andsw(r7, r18, 1048576ull); // ands w7, w18, #0x100000
__ andsw(r7, r17, 1048576ull); // ands w7, w17, #0x100000
__ andr(r14, r12, 9223372036854775808ull); // and x14, x12, #0x8000000000000000
__ orr(r9, r11, 562675075514368ull); // orr x9, x11, #0x1ffc000000000
__ eor(r17, r0, 18014398509481728ull); // eor x17, x0, #0x3fffffffffff00
@ -283,7 +283,7 @@ void entry(CodeBuffer *cb) {
// LoadStoreExclusiveOp
__ stxrw(r22, r27, r19); // stxr w22, w27, [x19]
__ stlxrw(r11, r16, r6); // stlxr w11, w16, [x6]
__ ldxrw(r18, r0); // ldxr w18, [x0]
__ ldxrw(r17, r0); // ldxr w17, [x0]
__ ldaxrw(r4, r10); // ldaxr w4, [x10]
__ stlrw(r24, r22); // stlr w24, [x22]
__ ldarw(r10, r19); // ldar w10, [x19]
@ -311,7 +311,7 @@ void entry(CodeBuffer *cb) {
__ stlxp(r12, r16, r13, r15); // stlxp w12, x16, x13, [x15]
// LoadStoreExclusiveOp
__ ldxpw(r18, r21, r13); // ldxp w18, w21, [x13]
__ ldxpw(r17, r21, r13); // ldxp w17, w21, [x13]
__ ldaxpw(r11, r30, r8); // ldaxp w11, w30, [x8]
__ stxpw(r24, r13, r11, r1); // stxp w24, w13, w11, [x1]
__ stlxpw(r26, r21, r27, r13); // stlxp w26, w21, w27, [x13]
@ -324,7 +324,7 @@ void entry(CodeBuffer *cb) {
__ strh(r2, Address(r25, -50)); // strh w2, [x25, -50]
__ ldr(r4, Address(r2, -241)); // ldr x4, [x2, -241]
__ ldrw(r30, Address(r20, -31)); // ldr w30, [x20, -31]
__ ldrb(r18, Address(r23, -23)); // ldrb w18, [x23, -23]
__ ldrb(r17, Address(r23, -23)); // ldrb w17, [x23, -23]
__ ldrh(r29, Address(r26, -1)); // ldrh w29, [x26, -1]
__ ldrsb(r1, Address(r9, 6)); // ldrsb x1, [x9, 6]
__ ldrsh(r11, Address(r12, 19)); // ldrsh x11, [x12, 19]
@ -375,14 +375,14 @@ void entry(CodeBuffer *cb) {
// base_plus_reg
// LoadStoreOp
__ str(r10, Address(r18, r21, Address::sxtw(3))); // str x10, [x18, w21, sxtw #3]
__ str(r10, Address(r17, r21, Address::sxtw(3))); // str x10, [x17, w21, sxtw #3]
__ strw(r4, Address(r13, r22, Address::sxtw(2))); // str w4, [x13, w22, sxtw #2]
__ strb(r13, Address(r0, r19, Address::uxtw(0))); // strb w13, [x0, w19, uxtw #0]
__ strh(r12, Address(r27, r6, Address::sxtw(0))); // strh w12, [x27, w6, sxtw #0]
__ ldr(r0, Address(r8, r16, Address::lsl(0))); // ldr x0, [x8, x16, lsl #0]
__ ldrw(r0, Address(r4, r26, Address::sxtx(0))); // ldr w0, [x4, x26, sxtx #0]
__ ldrb(r14, Address(r25, r5, Address::sxtw(0))); // ldrb w14, [x25, w5, sxtw #0]
__ ldrh(r9, Address(r4, r18, Address::uxtw(0))); // ldrh w9, [x4, w18, uxtw #0]
__ ldrh(r9, Address(r4, r17, Address::uxtw(0))); // ldrh w9, [x4, w17, uxtw #0]
__ ldrsb(r27, Address(r4, r7, Address::lsl(0))); // ldrsb x27, [x4, x7, lsl #0]
__ ldrsh(r15, Address(r17, r30, Address::sxtw(0))); // ldrsh x15, [x17, w30, sxtw #0]
__ ldrshw(r16, Address(r0, r22, Address::sxtw(0))); // ldrsh w16, [x0, w22, sxtw #0]
@ -439,7 +439,7 @@ void entry(CodeBuffer *cb) {
__ sbcs(r1, r24, r3); // sbcs x1, x24, x3
// AddSubExtendedOp
__ addw(r18, r24, r20, ext::uxtb, 2); // add w18, w24, w20, uxtb #2
__ addw(r17, r24, r20, ext::uxtb, 2); // add w17, w24, w20, uxtb #2
__ addsw(r13, r28, r10, ext::uxth, 1); // adds w13, w28, w10, uxth #1
__ sub(r15, r16, r2, ext::sxth, 2); // sub x15, x16, x2, sxth #2
__ subsw(r29, r13, r13, ext::uxth, 2); // subs w29, w13, w13, uxth #2
@ -450,8 +450,8 @@ void entry(CodeBuffer *cb) {
// ConditionalCompareOp
__ ccmnw(r0, r13, 14u, Assembler::MI); // ccmn w0, w13, #14, MI
__ ccmpw(r22, r18, 6u, Assembler::CC); // ccmp w22, w18, #6, CC
__ ccmn(r18, r30, 14u, Assembler::VS); // ccmn x18, x30, #14, VS
__ ccmpw(r22, r17, 6u, Assembler::CC); // ccmp w22, w17, #6, CC
__ ccmn(r17, r30, 14u, Assembler::VS); // ccmn x17, x30, #14, VS
__ ccmp(r10, r19, 12u, Assembler::HI); // ccmp x10, x19, #12, HI
// ConditionalCompareImmedOp
@ -476,7 +476,7 @@ void entry(CodeBuffer *cb) {
__ revw(r29, r30); // rev w29, w30
__ clzw(r25, r21); // clz w25, w21
__ clsw(r4, r0); // cls w4, w0
__ rbit(r18, r21); // rbit x18, x21
__ rbit(r17, r21); // rbit x17, x21
__ rev16(r29, r16); // rev16 x29, x16
__ rev32(r21, r20); // rev32 x21, x20
__ rev(r6, r19); // rev x6, x19
@ -486,16 +486,16 @@ void entry(CodeBuffer *cb) {
// ThreeRegOp
__ udivw(r11, r24, r0); // udiv w11, w24, w0
__ sdivw(r27, r25, r14); // sdiv w27, w25, w14
__ lslvw(r3, r14, r18); // lslv w3, w14, w18
__ lslvw(r3, r14, r17); // lslv w3, w14, w17
__ lsrvw(r7, r15, r24); // lsrv w7, w15, w24
__ asrvw(r28, r17, r25); // asrv w28, w17, w25
__ rorvw(r2, r26, r28); // rorv w2, w26, w28
__ udiv(r5, r25, r26); // udiv x5, x25, x26
__ sdiv(r27, r16, r18); // sdiv x27, x16, x18
__ sdiv(r27, r16, r17); // sdiv x27, x16, x17
__ lslv(r6, r21, r12); // lslv x6, x21, x12
__ lsrv(r0, r4, r12); // lsrv x0, x4, x12
__ asrv(r27, r17, r28); // asrv x27, x17, x28
__ rorv(r28, r2, r18); // rorv x28, x2, x18
__ rorv(r28, r2, r17); // rorv x28, x2, x17
__ umulh(r10, r15, r14); // umulh x10, x15, x14
__ smulh(r14, r3, r25); // smulh x14, x3, x25
@ -540,7 +540,7 @@ void entry(CodeBuffer *cb) {
__ fmovd(v24, v11); // fmov d24, d11
__ fabsd(v7, v1); // fabs d7, d1
__ fnegd(v11, v0); // fneg d11, d0
__ fsqrtd(v3, v18); // fsqrt d3, d18
__ fsqrtd(v3, v17); // fsqrt d3, d17
__ fcvtd(v28, v6); // fcvt s28, d6
// FloatConvertOp
@ -552,9 +552,9 @@ void entry(CodeBuffer *cb) {
__ scvtfs(v25, r13); // scvtf s25, x13
__ scvtfwd(v11, r23); // scvtf d11, w23
__ scvtfd(v19, r8); // scvtf d19, x8
__ fmovs(r18, v21); // fmov w18, s21
__ fmovs(r17, v21); // fmov w17, s21
__ fmovd(r25, v20); // fmov x25, d20
__ fmovs(v19, r18); // fmov s19, w18
__ fmovs(v19, r17); // fmov s19, w17
__ fmovd(v2, r29); // fmov d2, x29
// TwoRegFloatOp
@ -598,11 +598,11 @@ void entry(CodeBuffer *cb) {
__ ld1r(v29, __ T8B, Address(r17)); // ld1r {v29.8B}, [x17]
__ ld1r(v24, __ T4S, Address(__ post(r23, 4))); // ld1r {v24.4S}, [x23], 4
__ ld1r(v10, __ T1D, Address(__ post(r5, r25))); // ld1r {v10.1D}, [x5], x25
__ ld2(v18, v19, __ T2D, Address(r10)); // ld2 {v18.2D, v19.2D}, [x10]
__ ld2(v17, v18, __ T2D, Address(r10)); // ld2 {v17.2D, v18.2D}, [x10]
__ ld2(v12, v13, __ T4H, Address(__ post(r15, 16))); // ld2 {v12.4H, v13.4H}, [x15], 16
__ ld2r(v25, v26, __ T16B, Address(r18)); // ld2r {v25.16B, v26.16B}, [x18]
__ ld2r(v25, v26, __ T16B, Address(r17)); // ld2r {v25.16B, v26.16B}, [x17]
__ ld2r(v1, v2, __ T2S, Address(__ post(r30, 8))); // ld2r {v1.2S, v2.2S}, [x30], 8
__ ld2r(v16, v17, __ T2D, Address(__ post(r18, r9))); // ld2r {v16.2D, v17.2D}, [x18], x9
__ ld2r(v16, v17, __ T2D, Address(__ post(r17, r9))); // ld2r {v16.2D, v17.2D}, [x17], x9
__ ld3(v25, v26, v27, __ T4S, Address(__ post(r12, r2))); // ld3 {v25.4S, v26.4S, v27.4S}, [x12], x2
__ ld3(v26, v27, v28, __ T2S, Address(r19)); // ld3 {v26.2S, v27.2S, v28.2S}, [x19]
__ ld3r(v15, v16, v17, __ T8H, Address(r21)); // ld3r {v15.8H, v16.8H, v17.8H}, [x21]
@ -610,7 +610,7 @@ void entry(CodeBuffer *cb) {
__ ld3r(v14, v15, v16, __ T1D, Address(__ post(r28, r29))); // ld3r {v14.1D, v15.1D, v16.1D}, [x28], x29
__ ld4(v17, v18, v19, v20, __ T8H, Address(__ post(r29, 64))); // ld4 {v17.8H, v18.8H, v19.8H, v20.8H}, [x29], 64
__ ld4(v27, v28, v29, v30, __ T8B, Address(__ post(r7, r0))); // ld4 {v27.8B, v28.8B, v29.8B, v30.8B}, [x7], x0
__ ld4r(v24, v25, v26, v27, __ T8B, Address(r18)); // ld4r {v24.8B, v25.8B, v26.8B, v27.8B}, [x18]
__ ld4r(v24, v25, v26, v27, __ T8B, Address(r17)); // ld4r {v24.8B, v25.8B, v26.8B, v27.8B}, [x17]
__ ld4r(v0, v1, v2, v3, __ T4H, Address(__ post(r26, 8))); // ld4r {v0.4H, v1.4H, v2.4H, v3.4H}, [x26], 8
__ ld4r(v12, v13, v14, v15, __ T2S, Address(__ post(r25, r2))); // ld4r {v12.2S, v13.2S, v14.2S, v15.2S}, [x25], x2
@ -665,7 +665,7 @@ void entry(CodeBuffer *cb) {
__ sve_st1w(z0, __ S, p1, Address(r0, 7)); // st1w {z0.s}, p1, [x0, #7, MUL VL]
__ sve_st1b(z0, __ B, p2, Address(sp, r1)); // st1b {z0.b}, p2, [sp, x1]
__ sve_st1h(z0, __ H, p3, Address(sp, r8)); // st1h {z0.h}, p3, [sp, x8, LSL #1]
__ sve_st1d(z0, __ D, p4, Address(r0, r18)); // st1d {z0.d}, p4, [x0, x18, LSL #3]
__ sve_st1d(z0, __ D, p4, Address(r0, r17)); // st1d {z0.d}, p4, [x0, x17, LSL #3]
__ sve_ldr(z0, Address(sp)); // ldr z0, [sp]
__ sve_ldr(z31, Address(sp, -256)); // ldr z31, [sp, #-256, MUL VL]
__ sve_str(z8, Address(r8, 255)); // str z8, [x8, #255, MUL VL]
@ -716,7 +716,7 @@ void entry(CodeBuffer *cb) {
__ ldumax(Assembler::xword, r11, r20, r12); // ldumax x11, x20, [x12]
// LSEOp
__ swpa(Assembler::xword, r18, r22, r16); // swpa x18, x22, [x16]
__ swpa(Assembler::xword, r16, r22, r16); // swpa x16, x22, [x16]
__ ldadda(Assembler::xword, r21, r24, r26); // ldadda x21, x24, [x26]
__ ldbica(Assembler::xword, r6, r6, r16); // ldclra x6, x6, [x16]
__ ldeora(Assembler::xword, r16, r25, r16); // ldeora x16, x25, [x16]
@ -734,14 +734,14 @@ void entry(CodeBuffer *cb) {
__ ldorral(Assembler::xword, zr, r0, r19); // ldsetal xzr, x0, [x19]
__ ldsminal(Assembler::xword, r29, r26, r9); // ldsminal x29, x26, [x9]
__ ldsmaxal(Assembler::xword, r26, r12, r15); // ldsmaxal x26, x12, [x15]
__ lduminal(Assembler::xword, r11, r11, r18); // lduminal x11, x11, [x18]
__ lduminal(Assembler::xword, r11, r11, r15); // lduminal x11, x11, [x15]
__ ldumaxal(Assembler::xword, r25, r22, r24); // ldumaxal x25, x22, [x24]
// LSEOp
__ swpl(Assembler::xword, r0, r17, r11); // swpl x0, x17, [x11]
__ ldaddl(Assembler::xword, r6, r29, r6); // ldaddl x6, x29, [x6]
__ ldbicl(Assembler::xword, r5, r5, r21); // ldclrl x5, x5, [x21]
__ ldeorl(Assembler::xword, r19, r16, r18); // ldeorl x19, x16, [x18]
__ ldeorl(Assembler::xword, r19, r16, r15); // ldeorl x19, x16, [x15]
__ ldorrl(Assembler::xword, r30, r27, r28); // ldsetl x30, x27, [x28]
__ ldsminl(Assembler::xword, r1, r28, r1); // ldsminl x1, x28, [x1]
__ ldsmaxl(Assembler::xword, r20, r29, r16); // ldsmaxl x20, x29, [x16]
@ -767,7 +767,7 @@ void entry(CodeBuffer *cb) {
__ ldorra(Assembler::word, r24, r4, r3); // ldseta w24, w4, [x3]
__ ldsmina(Assembler::word, r12, zr, r28); // ldsmina w12, wzr, [x28]
__ ldsmaxa(Assembler::word, r10, r26, r2); // ldsmaxa w10, w26, [x2]
__ ldumina(Assembler::word, r12, r18, sp); // ldumina w12, w18, [sp]
__ ldumina(Assembler::word, r12, r16, sp); // ldumina w12, w16, [sp]
__ ldumaxa(Assembler::word, r1, r13, r29); // ldumaxa w1, w13, [x29]
// LSEOp
@ -777,7 +777,7 @@ void entry(CodeBuffer *cb) {
__ ldeoral(Assembler::word, r1, r26, r28); // ldeoral w1, w26, [x28]
__ ldorral(Assembler::word, r4, r30, r4); // ldsetal w4, w30, [x4]
__ ldsminal(Assembler::word, r6, r30, r26); // ldsminal w6, w30, [x26]
__ ldsmaxal(Assembler::word, r18, r9, r8); // ldsmaxal w18, w9, [x8]
__ ldsmaxal(Assembler::word, r16, r9, r8); // ldsmaxal w16, w9, [x8]
__ lduminal(Assembler::word, r12, r0, r20); // lduminal w12, w0, [x20]
__ ldumaxal(Assembler::word, r1, r24, r2); // ldumaxal w1, w24, [x2]
@ -785,7 +785,7 @@ void entry(CodeBuffer *cb) {
__ swpl(Assembler::word, r0, r9, r24); // swpl w0, w9, [x24]
__ ldaddl(Assembler::word, r26, r16, r30); // ldaddl w26, w16, [x30]
__ ldbicl(Assembler::word, r3, r10, r23); // ldclrl w3, w10, [x23]
__ ldeorl(Assembler::word, r10, r4, r18); // ldeorl w10, w4, [x18]
__ ldeorl(Assembler::word, r10, r4, r15); // ldeorl w10, w4, [x15]
__ ldorrl(Assembler::word, r2, r11, r8); // ldsetl w2, w11, [x8]
__ ldsminl(Assembler::word, r10, r15, r17); // ldsminl w10, w15, [x17]
__ ldsmaxl(Assembler::word, r2, r10, r12); // ldsmaxl w2, w10, [x12]
@ -817,19 +817,19 @@ void entry(CodeBuffer *cb) {
__ sve_fmin(z19, __ D, p2, z4); // fmin z19.d, p2/m, z19.d, z4.d
__ sve_fmul(z17, __ S, p4, z22); // fmul z17.s, p4/m, z17.s, z22.s
__ sve_fneg(z28, __ D, p3, z21); // fneg z28.d, p3/m, z21.d
__ sve_frintm(z18, __ S, p5, z2); // frintm z18.s, p5/m, z2.s
__ sve_frintm(z17, __ S, p5, z2); // frintm z17.s, p5/m, z2.s
__ sve_frintn(z6, __ S, p3, z15); // frintn z6.s, p3/m, z15.s
__ sve_frintp(z12, __ D, p5, z1); // frintp z12.d, p5/m, z1.d
__ sve_fsqrt(z18, __ S, p1, z17); // fsqrt z18.s, p1/m, z17.s
__ sve_fsqrt(z17, __ S, p1, z17); // fsqrt z17.s, p1/m, z17.s
__ sve_fsub(z15, __ S, p5, z13); // fsub z15.s, p5/m, z15.s, z13.s
__ sve_fmla(z20, __ D, p7, z27, z11); // fmla z20.d, p7/m, z27.d, z11.d
__ sve_fmls(z3, __ D, p0, z30, z23); // fmls z3.d, p0/m, z30.d, z23.d
__ sve_fnmla(z17, __ S, p2, z27, z26); // fnmla z17.s, p2/m, z27.s, z26.s
__ sve_fnmls(z6, __ D, p5, z22, z30); // fnmls z6.d, p5/m, z22.d, z30.d
__ sve_mla(z2, __ H, p7, z26, z18); // mla z2.h, p7/m, z26.h, z18.h
__ sve_mla(z2, __ H, p7, z26, z17); // mla z2.h, p7/m, z26.h, z17.h
__ sve_mls(z22, __ B, p4, z2, z17); // mls z22.b, p4/m, z2.b, z17.b
__ sve_and(z24, z25, z22); // and z24.d, z25.d, z22.d
__ sve_eor(z18, z12, z3); // eor z18.d, z12.d, z3.d
__ sve_eor(z17, z12, z3); // eor z17.d, z12.d, z3.d
__ sve_orr(z29, z28, z16); // orr z29.d, z28.d, z16.d
// SVEReductionOp
@ -857,7 +857,7 @@ Disassembly of section .text:
8: ab889dfc adds x28, x15, x8, asr #39
c: eb9ee787 subs x7, x28, x30, asr #57
10: 0b9b3ec9 add w9, w22, w27, asr #15
14: 4b9279a3 sub w3, w13, w18, asr #30
14: 4b9179a3 sub w3, w13, w17, asr #30
18: 2b88474e adds w14, w26, w8, asr #17
1c: 6b8c56c0 subs w0, w22, w12, asr #21
20: 8a1a51e0 and x0, x15, x26, lsl #20
@ -865,8 +865,8 @@ Disassembly of section .text:
28: ca0281b8 eor x24, x13, x2, lsl #32
2c: ea918c7c ands x28, x3, x17, asr #35
30: 0a5d4a19 and w25, w16, w29, lsr #18
34: 2a4b264d orr w13, w18, w11, lsr #9
38: 4a523ca5 eor w5, w5, w18, lsr #15
34: 2a4b262d orr w13, w17, w11, lsr #9
38: 4a513ca5 eor w5, w5, w17, lsr #15
3c: 6a9b6ae2 ands w2, w23, w27, asr #26
40: 8a70b79b bic x27, x28, x16, lsr #45
44: aaba9728 orn x8, x25, x26, asr #37
@ -887,7 +887,7 @@ Disassembly of section .text:
80: 120cb166 and w6, w11, #0xfff1fff1
84: 321764bc orr w28, w5, #0xfffffe07
88: 52174681 eor w1, w20, #0x7fffe00
8c: 720c0247 ands w7, w18, #0x100000
8c: 720c0227 ands w7, w17, #0x100000
90: 9241018e and x14, x12, #0x8000000000000000
94: b25a2969 orr x9, x11, #0x1ffc000000000
98: d278b411 eor x17, x0, #0x3fffffffffff00
@ -1009,7 +1009,7 @@ Disassembly of section .text:
268: c8dffe95 ldar x21, [x20]
26c: 88167e7b stxr w22, w27, [x19]
270: 880bfcd0 stlxr w11, w16, [x6]
274: 885f7c12 ldxr w18, [x0]
274: 885f7c11 ldxr w17, [x0]
278: 885ffd44 ldaxr w4, [x10]
27c: 889ffed8 stlr w24, [x22]
280: 88dffe6a ldar w10, [x19]
@ -1029,7 +1029,7 @@ Disassembly of section .text:
2b8: c87fcc5e ldaxp x30, x19, [x2]
2bc: c8220417 stxp w2, x23, x1, [x0]
2c0: c82cb5f0 stlxp w12, x16, x13, [x15]
2c4: 887f55b2 ldxp w18, w21, [x13]
2c4: 887f55b1 ldxp w17, w21, [x13]
2c8: 887ff90b ldaxp w11, w30, [x8]
2cc: 88382c2d stxp w24, w13, w11, [x1]
2d0: 883aedb5 stlxp w26, w21, w27, [x13]
@ -1039,7 +1039,7 @@ Disassembly of section .text:
2e0: 781ce322 sturh w2, [x25, #-50]
2e4: f850f044 ldur x4, [x2, #-241]
2e8: b85e129e ldur w30, [x20, #-31]
2ec: 385e92f2 ldurb w18, [x23, #-23]
2ec: 385e92f1 ldurb w17, [x23, #-23]
2f0: 785ff35d ldurh w29, [x26, #-1]
2f4: 39801921 ldrsb x1, [x9, #6]
2f8: 7881318b ldursh x11, [x12, #19]
@ -1081,14 +1081,14 @@ Disassembly of section .text:
388: bc4155f9 ldr s25, [x15], #21
38c: fc05a6ee str d14, [x23], #90
390: bc1df408 str s8, [x0], #-33
394: f835da4a str x10, [x18, w21, sxtw #3]
394: f835da2a str x10, [x17, w21, sxtw #3]
398: b836d9a4 str w4, [x13, w22, sxtw #2]
39c: 3833580d strb w13, [x0, w19, uxtw #0]
3a0: 7826cb6c strh w12, [x27, w6, sxtw]
3a4: f8706900 ldr x0, [x8, x16]
3a8: b87ae880 ldr w0, [x4, x26, sxtx]
3ac: 3865db2e ldrb w14, [x25, w5, sxtw #0]
3b0: 78724889 ldrh w9, [x4, w18, uxtw]
3b0: 78714889 ldrh w9, [x4, w17, uxtw]
3b4: 38a7789b ldrsb x27, [x4, x7, lsl #0]
3b8: 78beca2f ldrsh x15, [x17, w30, sxtw]
3bc: 78f6c810 ldrsh w16, [x0, w22, sxtw]
@ -1127,7 +1127,7 @@ Disassembly of section .text:
440: ba1e030c adcs x12, x24, x30
444: da0f0320 sbc x0, x25, x15
448: fa030301 sbcs x1, x24, x3
44c: 0b340b12 add w18, w24, w20, uxtb #2
44c: 0b340b11 add w17, w24, w20, uxtb #2
450: 2b2a278d adds w13, w28, w10, uxth #1
454: cb22aa0f sub x15, x16, w2, sxth #2
458: 6b2d29bd subs w29, w13, w13, uxth #2
@ -1136,8 +1136,8 @@ Disassembly of section .text:
464: cb21c8ee sub x14, x7, w1, sxtw #2
468: eb3ba47d subs x29, x3, w27, sxth #1
46c: 3a4d400e ccmn w0, w13, #0xe, mi // mi = first
470: 7a5232c6 ccmp w22, w18, #0x6, cc // cc = lo, ul, last
474: ba5e624e ccmn x18, x30, #0xe, vs
470: 7a5132c6 ccmp w22, w17, #0x6, cc // cc = lo, ul, last
474: ba5e622e ccmn x17, x30, #0xe, vs
478: fa53814c ccmp x10, x19, #0xc, hi // hi = pmore
47c: 3a52d8c2 ccmn w6, #0x12, #0x2, le
480: 7a4d8924 ccmp w9, #0xd, #0x4, hi // hi = pmore
@ -1156,7 +1156,7 @@ Disassembly of section .text:
4b4: 5ac00bdd rev w29, w30
4b8: 5ac012b9 clz w25, w21
4bc: 5ac01404 cls w4, w0
4c0: dac002b2 rbit x18, x21
4c0: dac002b1 rbit x17, x21
4c4: dac0061d rev16 x29, x16
4c8: dac00a95 rev32 x21, x20
4cc: dac00e66 rev x6, x19
@ -1164,16 +1164,16 @@ Disassembly of section .text:
4d4: dac01675 cls x21, x19
4d8: 1ac00b0b udiv w11, w24, w0
4dc: 1ace0f3b sdiv w27, w25, w14
4e0: 1ad221c3 lsl w3, w14, w18
4e0: 1ad121c3 lsl w3, w14, w17
4e4: 1ad825e7 lsr w7, w15, w24
4e8: 1ad92a3c asr w28, w17, w25
4ec: 1adc2f42 ror w2, w26, w28
4f0: 9ada0b25 udiv x5, x25, x26
4f4: 9ad20e1b sdiv x27, x16, x18
4f4: 9ad10e1b sdiv x27, x16, x17
4f8: 9acc22a6 lsl x6, x21, x12
4fc: 9acc2480 lsr x0, x4, x12
500: 9adc2a3b asr x27, x17, x28
504: 9ad22c5c ror x28, x2, x18
504: 9ad12c5c ror x28, x2, x17
508: 9bce7dea umulh x10, x15, x14
50c: 9b597c6e smulh x14, x3, x25
510: 1b0e166f madd w15, w19, w14, w5
@ -1210,7 +1210,7 @@ Disassembly of section .text:
58c: 1e604178 fmov d24, d11
590: 1e60c027 fabs d7, d1
594: 1e61400b fneg d11, d0
598: 1e61c243 fsqrt d3, d18
598: 1e61c223 fsqrt d3, d17
59c: 1e6240dc fcvt s28, d6
5a0: 1e3800d6 fcvtzs w22, s6
5a4: 9e380360 fcvtzs x0, s27
@ -1220,9 +1220,9 @@ Disassembly of section .text:
5b4: 9e2201b9 scvtf s25, x13
5b8: 1e6202eb scvtf d11, w23
5bc: 9e620113 scvtf d19, x8
5c0: 1e2602b2 fmov w18, s21
5c0: 1e2602b1 fmov w17, s21
5c4: 9e660299 fmov x25, d20
5c8: 1e270253 fmov s19, w18
5c8: 1e270233 fmov s19, w17
5cc: 9e6703a2 fmov d2, x29
5d0: 1e2822c0 fcmp s22, s8
5d4: 1e7322a0 fcmp d21, d19
@ -1254,11 +1254,11 @@ Disassembly of section .text:
63c: 0d40c23d ld1r {v29.8b}, [x17]
640: 4ddfcaf8 ld1r {v24.4s}, [x23], #4
644: 0dd9ccaa ld1r {v10.1d}, [x5], x25
648: 4c408d52 ld2 {v18.2d, v19.2d}, [x10]
648: 4c408d51 ld2 {v17.2d, v18.2d}, [x10]
64c: 0cdf85ec ld2 {v12.4h, v13.4h}, [x15], #16
650: 4d60c259 ld2r {v25.16b, v26.16b}, [x18]
650: 4d60c239 ld2r {v25.16b, v26.16b}, [x17]
654: 0dffcbc1 ld2r {v1.2s, v2.2s}, [x30], #8
658: 4de9ce50 ld2r {v16.2d, v17.2d}, [x18], x9
658: 4de9ce30 ld2r {v16.2d, v17.2d}, [x17], x9
65c: 4cc24999 ld3 {v25.4s-v27.4s}, [x12], x2
660: 0c404a7a ld3 {v26.2s-v28.2s}, [x19]
664: 4d40e6af ld3r {v15.8h-v17.8h}, [x21]
@ -1266,7 +1266,7 @@ Disassembly of section .text:
66c: 0dddef8e ld3r {v14.1d-v16.1d}, [x28], x29
670: 4cdf07b1 ld4 {v17.8h-v20.8h}, [x29], #64
674: 0cc000fb ld4 {v27.8b-v30.8b}, [x7], x0
678: 0d60e258 ld4r {v24.8b-v27.8b}, [x18]
678: 0d60e238 ld4r {v24.8b-v27.8b}, [x17]
67c: 0dffe740 ld4r {v0.4h-v3.4h}, [x26], #8
680: 0de2eb2c ld4r {v12.2s-v15.2s}, [x25], x2
684: ce648376 sha512h q22, q27, v4.2d
@ -1317,7 +1317,7 @@ Disassembly of section .text:
738: e547e400 st1w {z0.s}, p1, [x0, #7, mul vl]
73c: e4014be0 st1b {z0.b}, p2, [sp, x1]
740: e4a84fe0 st1h {z0.h}, p3, [sp, x8, lsl #1]
744: e5f25000 st1d {z0.d}, p4, [x0, x18, lsl #3]
744: e5f15000 st1d {z0.d}, p4, [x0, x17, lsl #3]
748: 858043e0 ldr z0, [sp]
74c: 85a043ff ldr z31, [sp, #-256, mul vl]
750: e59f5d08 str z8, [x8, #255, mul vl]
@ -1362,7 +1362,7 @@ Disassembly of section .text:
7ec: f82f41ee ldsmax x15, x14, [x15]
7f0: f82973b9 ldumin x9, x25, [x29]
7f4: f82b6194 ldumax x11, x20, [x12]
7f8: f8b28216 swpa x18, x22, [x16]
7f8: f8b08216 swpa x16, x22, [x16]
7fc: f8b50358 ldadda x21, x24, [x26]
800: f8a61206 ldclra x6, x6, [x16]
804: f8b02219 ldeora x16, x25, [x16]
@ -1378,12 +1378,12 @@ Disassembly of section .text:
82c: f8ff3260 ldsetal xzr, x0, [x19]
830: f8fd513a ldsminal x29, x26, [x9]
834: f8fa41ec ldsmaxal x26, x12, [x15]
838: f8eb724b lduminal x11, x11, [x18]
838: f8eb71eb lduminal x11, x11, [x15]
83c: f8f96316 ldumaxal x25, x22, [x24]
840: f8608171 swpl x0, x17, [x11]
844: f86600dd ldaddl x6, x29, [x6]
848: f86512a5 ldclrl x5, x5, [x21]
84c: f8732250 ldeorl x19, x16, [x18]
84c: f87321f0 ldeorl x19, x16, [x15]
850: f87e339b ldsetl x30, x27, [x28]
854: f861503c ldsminl x1, x28, [x1]
858: f874421d ldsmaxl x20, x29, [x16]
@ -1405,7 +1405,7 @@ Disassembly of section .text:
898: b8b83064 ldseta w24, w4, [x3]
89c: b8ac539f ldsmina w12, wzr, [x28]
8a0: b8aa405a ldsmaxa w10, w26, [x2]
8a4: b8ac73f2 ldumina w12, w18, [sp]
8a4: b8ac73f0 ldumina w12, w16, [sp]
8a8: b8a163ad ldumaxa w1, w13, [x29]
8ac: b8e08193 swpal w0, w19, [x12]
8b0: b8f101b6 ldaddal w17, w22, [x13]
@ -1413,13 +1413,13 @@ Disassembly of section .text:
8b8: b8e1239a ldeoral w1, w26, [x28]
8bc: b8e4309e ldsetal w4, w30, [x4]
8c0: b8e6535e ldsminal w6, w30, [x26]
8c4: b8f24109 ldsmaxal w18, w9, [x8]
8c4: b8f04109 ldsmaxal w16, w9, [x8]
8c8: b8ec7280 lduminal w12, w0, [x20]
8cc: b8e16058 ldumaxal w1, w24, [x2]
8d0: b8608309 swpl w0, w9, [x24]
8d4: b87a03d0 ldaddl w26, w16, [x30]
8d8: b86312ea ldclrl w3, w10, [x23]
8dc: b86a2244 ldeorl w10, w4, [x18]
8dc: b86a21e4 ldeorl w10, w4, [x15]
8e0: b862310b ldsetl w2, w11, [x8]
8e4: b86a522f ldsminl w10, w15, [x17]
8e8: b862418a ldsmaxl w2, w10, [x12]
@ -1449,19 +1449,19 @@ Disassembly of section .text:
948: 65c78893 fmin z19.d, p2/m, z19.d, z4.d
94c: 658292d1 fmul z17.s, p4/m, z17.s, z22.s
950: 04ddaebc fneg z28.d, p3/m, z21.d
954: 6582b452 frintm z18.s, p5/m, z2.s
954: 6582b451 frintm z17.s, p5/m, z2.s
958: 6580ade6 frintn z6.s, p3/m, z15.s
95c: 65c1b42c frintp z12.d, p5/m, z1.d
960: 658da632 fsqrt z18.s, p1/m, z17.s
960: 658da631 fsqrt z17.s, p1/m, z17.s
964: 658195af fsub z15.s, p5/m, z15.s, z13.s
968: 65eb1f74 fmla z20.d, p7/m, z27.d, z11.d
96c: 65f723c3 fmls z3.d, p0/m, z30.d, z23.d
970: 65ba4b71 fnmla z17.s, p2/m, z27.s, z26.s
974: 65fe76c6 fnmls z6.d, p5/m, z22.d, z30.d
978: 04525f42 mla z2.h, p7/m, z26.h, z18.h
978: 04515f42 mla z2.h, p7/m, z26.h, z17.h
97c: 04117056 mls z22.b, p4/m, z2.b, z17.b
980: 04363338 and z24.d, z25.d, z22.d
984: 04a33192 eor z18.d, z12.d, z3.d
984: 04a33191 eor z17.d, z12.d, z3.d
988: 0470339d orr z29.d, z28.d, z16.d
98c: 049a2b86 andv s6, p2, z28.s
990: 045824e7 orv h7, p1, z7.h
@ -1477,14 +1477,14 @@ Disassembly of section .text:
static const unsigned int insns[] =
{
0x8b0d82fa, 0xcb49970c, 0xab889dfc, 0xeb9ee787,
0x0b9b3ec9, 0x4b9279a3, 0x2b88474e, 0x6b8c56c0,
0x0b9b3ec9, 0x4b9179a3, 0x2b88474e, 0x6b8c56c0,
0x8a1a51e0, 0xaa11f4ba, 0xca0281b8, 0xea918c7c,
0x0a5d4a19, 0x2a4b264d, 0x4a523ca5, 0x6a9b6ae2,
0x0a5d4a19, 0x2a4b262d, 0x4a513ca5, 0x6a9b6ae2,
0x8a70b79b, 0xaaba9728, 0xca6dfe3d, 0xea627f1c,
0x0aa70f53, 0x2aaa0f06, 0x4a6176a4, 0x6a604eb0,
0x1105ed91, 0x3100583e, 0x5101f8bd, 0x710f0306,
0x9101a1a0, 0xb10a5cc8, 0xd10810aa, 0xf10fd061,
0x120cb166, 0x321764bc, 0x52174681, 0x720c0247,
0x120cb166, 0x321764bc, 0x52174681, 0x720c0227,
0x9241018e, 0xb25a2969, 0xd278b411, 0xf26aad01,
0x14000000, 0x17ffffd7, 0x14000242, 0x94000000,
0x97ffffd4, 0x9400023f, 0x3400000a, 0x34fffa2a,
@ -1515,14 +1515,14 @@ Disassembly of section .text:
0xd5033fdf, 0xd5033e9f, 0xd50332bf, 0xd61f0200,
0xd63f0280, 0xc80a7d1b, 0xc800fea1, 0xc85f7fb1,
0xc85fff9d, 0xc89ffee1, 0xc8dffe95, 0x88167e7b,
0x880bfcd0, 0x885f7c12, 0x885ffd44, 0x889ffed8,
0x880bfcd0, 0x885f7c11, 0x885ffd44, 0x889ffed8,
0x88dffe6a, 0x48017fc5, 0x4808fe2c, 0x485f7dc9,
0x485ffc27, 0x489ffe05, 0x48dffd82, 0x080a7c6c,
0x081cff4e, 0x085f7d5e, 0x085ffeae, 0x089ffd2d,
0x08dfff76, 0xc87f4d7c, 0xc87fcc5e, 0xc8220417,
0xc82cb5f0, 0x887f55b2, 0x887ff90b, 0x88382c2d,
0xc82cb5f0, 0x887f55b1, 0x887ff90b, 0x88382c2d,
0x883aedb5, 0xf819928b, 0xb803e21c, 0x381f713b,
0x781ce322, 0xf850f044, 0xb85e129e, 0x385e92f2,
0x781ce322, 0xf850f044, 0xb85e129e, 0x385e92f1,
0x785ff35d, 0x39801921, 0x7881318b, 0x78dce02b,
0xb8829313, 0xfc45f318, 0xbc5d50af, 0xfc001375,
0xbc1951b7, 0xf8008c0b, 0xb801dc03, 0x38009dcb,
@ -1533,9 +1533,9 @@ Disassembly of section .text:
0x7801b506, 0xf853654e, 0xb85d74b0, 0x384095c2,
0x785ec5bc, 0x389e15a9, 0x789dc703, 0x78c06474,
0xb89ff667, 0xfc57e51e, 0xbc4155f9, 0xfc05a6ee,
0xbc1df408, 0xf835da4a, 0xb836d9a4, 0x3833580d,
0xbc1df408, 0xf835da2a, 0xb836d9a4, 0x3833580d,
0x7826cb6c, 0xf8706900, 0xb87ae880, 0x3865db2e,
0x78724889, 0x38a7789b, 0x78beca2f, 0x78f6c810,
0x78714889, 0x38a7789b, 0x78beca2f, 0x78f6c810,
0xb8bef956, 0xfc6afabd, 0xbc734963, 0xfc3d5b8d,
0xbc25fbb7, 0xf9189d05, 0xb91ecb1d, 0x39187a33,
0x791f226d, 0xf95aa2f3, 0xb9587bb7, 0x395f7176,
@ -1544,19 +1544,19 @@ Disassembly of section .text:
0xbd1b1869, 0x58002cfb, 0x1800000b, 0xf8945060,
0xd8000000, 0xf8ae6ba0, 0xf99a0080, 0x1a070035,
0x3a0700a8, 0x5a0e0367, 0x7a11009b, 0x9a000380,
0xba1e030c, 0xda0f0320, 0xfa030301, 0x0b340b12,
0xba1e030c, 0xda0f0320, 0xfa030301, 0x0b340b11,
0x2b2a278d, 0xcb22aa0f, 0x6b2d29bd, 0x8b2cce8c,
0xab2b877e, 0xcb21c8ee, 0xeb3ba47d, 0x3a4d400e,
0x7a5232c6, 0xba5e624e, 0xfa53814c, 0x3a52d8c2,
0x7a5132c6, 0xba5e622e, 0xfa53814c, 0x3a52d8c2,
0x7a4d8924, 0xba4b3aab, 0xfa4d7882, 0x1a96804c,
0x1a912618, 0x5a90b0e6, 0x5a96976b, 0x9a9db06a,
0x9a9b374c, 0xda95c14f, 0xda89c6fe, 0x5ac0015e,
0x5ac005fd, 0x5ac00bdd, 0x5ac012b9, 0x5ac01404,
0xdac002b2, 0xdac0061d, 0xdac00a95, 0xdac00e66,
0xdac002b1, 0xdac0061d, 0xdac00a95, 0xdac00e66,
0xdac0107e, 0xdac01675, 0x1ac00b0b, 0x1ace0f3b,
0x1ad221c3, 0x1ad825e7, 0x1ad92a3c, 0x1adc2f42,
0x9ada0b25, 0x9ad20e1b, 0x9acc22a6, 0x9acc2480,
0x9adc2a3b, 0x9ad22c5c, 0x9bce7dea, 0x9b597c6e,
0x1ad121c3, 0x1ad825e7, 0x1ad92a3c, 0x1adc2f42,
0x9ada0b25, 0x9ad10e1b, 0x9acc22a6, 0x9acc2480,
0x9adc2a3b, 0x9ad12c5c, 0x9bce7dea, 0x9b597c6e,
0x1b0e166f, 0x1b1ae490, 0x9b023044, 0x9b089e3d,
0x9b391083, 0x9b24c73a, 0x9bb15f40, 0x9bbcc6af,
0x1e23095b, 0x1e3918e0, 0x1e2f28c9, 0x1e2a39fd,
@ -1565,10 +1565,10 @@ Disassembly of section .text:
0x1f2935da, 0x1f2574ea, 0x1f4b306f, 0x1f5ec7cf,
0x1f6f3e93, 0x1f6226a9, 0x1e2040fb, 0x1e20c3dd,
0x1e214031, 0x1e21c0c2, 0x1e22c06a, 0x1e604178,
0x1e60c027, 0x1e61400b, 0x1e61c243, 0x1e6240dc,
0x1e60c027, 0x1e61400b, 0x1e61c223, 0x1e6240dc,
0x1e3800d6, 0x9e380360, 0x1e78005a, 0x9e7800e5,
0x1e22017c, 0x9e2201b9, 0x1e6202eb, 0x9e620113,
0x1e2602b2, 0x9e660299, 0x1e270253, 0x9e6703a2,
0x1e2602b1, 0x9e660299, 0x1e270233, 0x9e6703a2,
0x1e2822c0, 0x1e7322a0, 0x1e202288, 0x1e602168,
0x293c19f4, 0x2966387b, 0x69762971, 0xa9041dc7,
0xa9475c0c, 0x29b61ccd, 0x29ee405e, 0x69ee0744,
@ -1576,10 +1576,10 @@ Disassembly of section .text:
0x68f61831, 0xa8b352ad, 0xa8c56d5e, 0x28024565,
0x2874134e, 0xa8027597, 0xa87b1aa0, 0x0c40734f,
0x4cdfa177, 0x0cc76ee8, 0x4cdf2733, 0x0d40c23d,
0x4ddfcaf8, 0x0dd9ccaa, 0x4c408d52, 0x0cdf85ec,
0x4d60c259, 0x0dffcbc1, 0x4de9ce50, 0x4cc24999,
0x4ddfcaf8, 0x0dd9ccaa, 0x4c408d51, 0x0cdf85ec,
0x4d60c239, 0x0dffcbc1, 0x4de9ce30, 0x4cc24999,
0x0c404a7a, 0x4d40e6af, 0x4ddfe9b9, 0x0dddef8e,
0x4cdf07b1, 0x0cc000fb, 0x0d60e258, 0x0dffe740,
0x4cdf07b1, 0x0cc000fb, 0x0d60e238, 0x0dffe740,
0x0de2eb2c, 0xce648376, 0xce6184c7, 0xcec081fa,
0xce6d89a2, 0xba5fd3e3, 0x3a5f03e5, 0xfa411be4,
0x7a42cbe2, 0x93df03ff, 0xc820ffff, 0x8822fc7f,
@ -1592,7 +1592,7 @@ Disassembly of section .text:
0x25b8efe2, 0x25f8f007, 0xa400a3e0, 0xa4a8a7ea,
0xa547a814, 0xa4084ffe, 0xa55c53e0, 0xa5e1540b,
0xe400fbf6, 0xe408ffff, 0xe547e400, 0xe4014be0,
0xe4a84fe0, 0xe5f25000, 0x858043e0, 0x85a043ff,
0xe4a84fe0, 0xe5f15000, 0x858043e0, 0x85a043ff,
0xe59f5d08, 0x1e601000, 0x1e603000, 0x1e621000,
0x1e623000, 0x1e641000, 0x1e643000, 0x1e661000,
0x1e663000, 0x1e681000, 0x1e683000, 0x1e6a1000,
@ -1603,21 +1603,21 @@ Disassembly of section .text:
0x1e7a3000, 0x1e7c1000, 0x1e7c3000, 0x1e7e1000,
0x1e7e3000, 0xf8388098, 0xf8340010, 0xf8241175,
0xf83e22d0, 0xf82432ef, 0xf83a5186, 0xf82f41ee,
0xf82973b9, 0xf82b6194, 0xf8b28216, 0xf8b50358,
0xf82973b9, 0xf82b6194, 0xf8b08216, 0xf8b50358,
0xf8a61206, 0xf8b02219, 0xf8bc3218, 0xf8ba514f,
0xf8ad428e, 0xf8a173d7, 0xf8ae60c2, 0xf8e38328,
0xf8e003db, 0xf8e513c5, 0xf8eb2019, 0xf8ff3260,
0xf8fd513a, 0xf8fa41ec, 0xf8eb724b, 0xf8f96316,
0xf8608171, 0xf86600dd, 0xf86512a5, 0xf8732250,
0xf8fd513a, 0xf8fa41ec, 0xf8eb71eb, 0xf8f96316,
0xf8608171, 0xf86600dd, 0xf86512a5, 0xf87321f0,
0xf87e339b, 0xf861503c, 0xf874421d, 0xf86d73aa,
0xf87d62d3, 0xb82a83e4, 0xb83503e8, 0xb833138a,
0xb82220b9, 0xb82332c8, 0xb83350ad, 0xb83d42b8,
0xb83a7078, 0xb83862fa, 0xb8af8075, 0xb8b80328,
0xb8b41230, 0xb8a22001, 0xb8b83064, 0xb8ac539f,
0xb8aa405a, 0xb8ac73f2, 0xb8a163ad, 0xb8e08193,
0xb8aa405a, 0xb8ac73f0, 0xb8a163ad, 0xb8e08193,
0xb8f101b6, 0xb8fc13fe, 0xb8e1239a, 0xb8e4309e,
0xb8e6535e, 0xb8f24109, 0xb8ec7280, 0xb8e16058,
0xb8608309, 0xb87a03d0, 0xb86312ea, 0xb86a2244,
0xb8e6535e, 0xb8f04109, 0xb8ec7280, 0xb8e16058,
0xb8608309, 0xb87a03d0, 0xb86312ea, 0xb86a21e4,
0xb862310b, 0xb86a522f, 0xb862418a, 0xb86c71af,
0xb8626287, 0x042401f9, 0x04b10564, 0x65ca0230,
0x65d90996, 0x65ca05dc, 0x0456afc1, 0x0400044f,
@ -1625,10 +1625,10 @@ Disassembly of section .text:
0x04901774, 0x0417b89a, 0x041eb3d6, 0x04480b6b,
0x048a17dc, 0x048105be, 0x04dcb35e, 0x65808d6f,
0x65cd9e06, 0x65869cfb, 0x65c78893, 0x658292d1,
0x04ddaebc, 0x6582b452, 0x6580ade6, 0x65c1b42c,
0x658da632, 0x658195af, 0x65eb1f74, 0x65f723c3,
0x65ba4b71, 0x65fe76c6, 0x04525f42, 0x04117056,
0x04363338, 0x04a33192, 0x0470339d, 0x049a2b86,
0x04ddaebc, 0x6582b451, 0x6580ade6, 0x65c1b42c,
0x658da631, 0x658195af, 0x65eb1f74, 0x65f723c3,
0x65ba4b71, 0x65fe76c6, 0x04515f42, 0x04117056,
0x04363338, 0x04a33191, 0x0470339d, 0x049a2b86,
0x045824e7, 0x04193509, 0x040837db, 0x044a221a,
0x65c73903, 0x65c63b55, 0x65982096, 0x04412071,
@ -1979,3 +1979,7 @@ static float unpack(unsigned value) {
ival = fp_immediate_for_encoding(value, 0);
return val;
}
address Assembler::locate_next_instruction(address inst) {
return inst + Assembler::instruction_size;
}

View File

@ -28,6 +28,19 @@
#include "asm/register.hpp"
#ifdef __GNUC__
// __nop needs volatile so that compiler doesn't optimize it away
#define NOP() asm volatile ("nop");
#elif defined(_MSC_VER)
// Use MSVC instrinsic: https://docs.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=vs-2019#I
#define NOP() __nop();
#endif
// definitions of various symbolic names for machine registers
// First intercalls between C and Java which use 8 general registers
@ -640,7 +653,7 @@ class Assembler : public AbstractAssembler {
void emit_long(jint x) {
if ((uintptr_t)pc() == asm_bp)
asm volatile ("nop");
NOP();
AbstractAssembler::emit_int32(x);
}
#else
@ -680,6 +693,8 @@ public:
return Address(Post(base, idx));
}
static address locate_next_instruction(address inst);
Instruction_aarch64* current;
void set_current(Instruction_aarch64* i) { current = i; }
@ -1555,6 +1570,11 @@ public:
#undef INSN
#ifdef _WIN64
// In MSVC, `mvn` is defined as a macro and it affects compilation
#undef mvn
#endif
// Aliases for short forms of orn
void mvn(Register Rd, Register Rm,
enum shift_kind kind = LSL, unsigned shift = 0) {

View File

@ -44,13 +44,13 @@ enum {
pd_nof_cpu_regs_frame_map = RegisterImpl::number_of_registers, // number of registers used during code emission
pd_nof_fpu_regs_frame_map = FloatRegisterImpl::number_of_registers, // number of registers used during code emission
pd_nof_caller_save_cpu_regs_frame_map = 19 - 2, // number of registers killed by calls
pd_nof_caller_save_cpu_regs_frame_map = 19 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), // number of registers killed by calls
pd_nof_caller_save_fpu_regs_frame_map = 32, // number of registers killed by calls
pd_first_callee_saved_reg = 19 - 2,
pd_last_callee_saved_reg = 26 - 2,
pd_first_callee_saved_reg = 19 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1),
pd_last_callee_saved_reg = 26 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1),
pd_last_allocatable_cpu_reg = 16,
pd_last_allocatable_cpu_reg = 16 R18_RESERVED_ONLY(- 1),
pd_nof_cpu_regs_reg_alloc
= pd_last_allocatable_cpu_reg + 1, // number of registers that are visible to register allocator
@ -60,9 +60,9 @@ enum {
pd_nof_fpu_regs_linearscan = pd_nof_fpu_regs_frame_map, // number of registers visible to linear scan
pd_nof_xmm_regs_linearscan = 0, // don't have vector registers
pd_first_cpu_reg = 0,
pd_last_cpu_reg = 16,
pd_last_cpu_reg = 16 R18_RESERVED_ONLY(- 1),
pd_first_byte_reg = 0,
pd_last_byte_reg = 16,
pd_last_byte_reg = 16 R18_RESERVED_ONLY(- 1),
pd_first_fpu_reg = pd_nof_cpu_regs_frame_map,
pd_last_fpu_reg = pd_first_fpu_reg + 31,

View File

@ -28,3 +28,4 @@
//--------------------------------------------------------
// No FPU stack on AARCH64
#include "precompiled.hpp"

View File

@ -181,7 +181,10 @@ void FrameMap::initialize() {
map_register(i, r15); r15_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r16); r16_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r17); r17_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r18); r18_opr = LIR_OprFact::single_cpu(i); i++;
#ifndef R18_RESERVED
// See comment in register_aarch64.hpp
map_register(i, r18_tls); r18_opr = LIR_OprFact::single_cpu(i); i++;
#endif
map_register(i, r19); r19_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r20); r20_opr = LIR_OprFact::single_cpu(i); i++;
map_register(i, r21); r21_opr = LIR_OprFact::single_cpu(i); i++;
@ -199,6 +202,11 @@ void FrameMap::initialize() {
map_register(i, r8); r8_opr = LIR_OprFact::single_cpu(i); i++; // rscratch1
map_register(i, r9); r9_opr = LIR_OprFact::single_cpu(i); i++; // rscratch2
#ifdef R18_RESERVED
// See comment in register_aarch64.hpp
map_register(i, r18_tls); r18_opr = LIR_OprFact::single_cpu(i); i++;
#endif
rscratch1_opr = r8_opr;
rscratch2_opr = r9_opr;
rscratch1_long_opr = LIR_OprFact::double_cpu(r8_opr->cpu_regnr(), r8_opr->cpu_regnr());
@ -227,7 +235,10 @@ void FrameMap::initialize() {
_caller_save_cpu_regs[13] = r15_opr;
_caller_save_cpu_regs[14] = r16_opr;
_caller_save_cpu_regs[15] = r17_opr;
#ifndef R18_RESERVED
// See comment in register_aarch64.hpp
_caller_save_cpu_regs[16] = r18_opr;
#endif
for (int i = 0; i < 8; i++) {
_caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);
@ -253,7 +264,7 @@ void FrameMap::initialize() {
r15_oop_opr = as_oop_opr(r15);
r16_oop_opr = as_oop_opr(r16);
r17_oop_opr = as_oop_opr(r17);
r18_oop_opr = as_oop_opr(r18);
r18_oop_opr = as_oop_opr(r18_tls);
r19_oop_opr = as_oop_opr(r19);
r20_oop_opr = as_oop_opr(r20);
r21_oop_opr = as_oop_opr(r21);

View File

@ -543,7 +543,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2,
Register cnt1, Register cnt2, Register result, Register tmp1, Register tmp2,
FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3, int ae) {
Label DONE, SHORT_LOOP, SHORT_STRING, SHORT_LAST, TAIL, STUB,
DIFFERENCE, NEXT_WORD, SHORT_LOOP_TAIL, SHORT_LAST2, SHORT_LAST_INIT,
DIFF, NEXT_WORD, SHORT_LOOP_TAIL, SHORT_LAST2, SHORT_LAST_INIT,
SHORT_LOOP_START, TAIL_CHECK;
bool isLL = ae == StrIntrinsicNode::LL;
@ -634,7 +634,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2,
adds(cnt2, cnt2, isUL ? 4 : 8);
br(GE, TAIL);
eor(rscratch2, tmp1, tmp2);
cbnz(rscratch2, DIFFERENCE);
cbnz(rscratch2, DIFF);
// main loop
bind(NEXT_WORD);
if (str1_isL == str2_isL) {
@ -660,10 +660,10 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2,
eor(rscratch2, tmp1, tmp2);
cbz(rscratch2, NEXT_WORD);
b(DIFFERENCE);
b(DIFF);
bind(TAIL);
eor(rscratch2, tmp1, tmp2);
cbnz(rscratch2, DIFFERENCE);
cbnz(rscratch2, DIFF);
// Last longword. In the case where length == 4 we compare the
// same longword twice, but that's still faster than another
// conditional branch.
@ -687,7 +687,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2,
// Find the first different characters in the longwords and
// compute their difference.
bind(DIFFERENCE);
bind(DIFF);
rev(rscratch2, rscratch2);
clz(rscratch2, rscratch2);
andr(rscratch2, rscratch2, isLL ? -8 : -16);

View File

@ -23,6 +23,7 @@
//
source_hpp %{
#include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
%}

View File

@ -58,4 +58,13 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
#define COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS false
#if defined(_WIN64)
#define R18_RESERVED
#define R18_RESERVED_ONLY(code) code
#define NOT_R18_RESERVED(code)
#else
#define R18_RESERVED_ONLY(code)
#define NOT_R18_RESERVED(code) code
#endif
#endif // CPU_AARCH64_GLOBALDEFINITIONS_AARCH64_HPP

View File

@ -26,19 +26,6 @@
#ifndef CPU_AARCH64_ICACHE_AARCH64_HPP
#define CPU_AARCH64_ICACHE_AARCH64_HPP
// Interface for updating the instruction cache. Whenever the VM
// modifies code, part of the processor instruction cache potentially
// has to be flushed.
class ICache : public AbstractICache {
public:
static void initialize();
static void invalidate_word(address addr) {
__builtin___clear_cache((char *)addr, (char *)(addr + 3));
}
static void invalidate_range(address start, int nbytes) {
__builtin___clear_cache((char *)start, (char *)(start + nbytes));
}
};
#include OS_CPU_HEADER(icache)
#endif // CPU_AARCH64_ICACHE_AARCH64_HPP

View File

@ -24,6 +24,9 @@
#include <stdlib.h>
#include <stdint.h>
#include "precompiled.hpp"
#include "utilities/globalDefinitions.hpp"
#include "immediate_aarch64.hpp"
// there are at most 2^13 possible logical immediate encodings
@ -244,7 +247,10 @@ int expandLogicalImmediate(uint32_t immN, uint32_t immr,
// constructor to initialise the lookup tables
static void initLITables() __attribute__ ((constructor));
static void initLITables();
// Use an empty struct with a construtor as MSVC doesn't support `__attribute__ ((constructor))`
// See https://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
static struct initLITables_t { initLITables_t(void) { initLITables(); } } _initLITables;
static void initLITables()
{
li_table_entry_count = 0;

View File

@ -2651,9 +2651,17 @@ void MacroAssembler::debug64(char* msg, int64_t pc, int64_t regs[])
fatal("DEBUG MESSAGE: %s", msg);
}
RegSet MacroAssembler::call_clobbered_registers() {
RegSet regs = RegSet::range(r0, r17) - RegSet::of(rscratch1, rscratch2);
#ifndef R18_RESERVED
regs += r18_tls;
#endif
return regs;
}
void MacroAssembler::push_call_clobbered_registers_except(RegSet exclude) {
int step = 4 * wordSize;
push(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2) - exclude, sp);
push(call_clobbered_registers() - exclude, sp);
sub(sp, sp, step);
mov(rscratch1, -step);
// Push v0-v7, v16-v31.
@ -2673,7 +2681,7 @@ void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) {
as_FloatRegister(i+3), T1D, Address(post(sp, 4 * wordSize)));
}
pop(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2) - exclude, sp);
pop(call_clobbered_registers() - exclude, sp);
}
void MacroAssembler::push_CPU_state(bool save_vectors, bool use_sve,

View File

@ -188,7 +188,15 @@ class MacroAssembler: public Assembler {
mov(rscratch2, call_site);
}
// Microsoft's MSVC team thinks that the __FUNCSIG__ is approximately (sympathy for calling conventions) equivalent to __PRETTY_FUNCTION__
// Also, from Clang patch: "It is very similar to GCC's PRETTY_FUNCTION, except it prints the calling convention."
// https://reviews.llvm.org/D3311
#ifdef _WIN64
#define call_Unimplemented() _call_Unimplemented((address)__FUNCSIG__)
#else
#define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__)
#endif
// aliases defined in AARCH64 spec
@ -196,7 +204,7 @@ class MacroAssembler: public Assembler {
inline void cmpw(Register Rd, T imm) { subsw(zr, Rd, imm); }
inline void cmp(Register Rd, unsigned char imm8) { subs(zr, Rd, imm8); }
inline void cmp(Register Rd, unsigned imm) __attribute__ ((deprecated));
inline void cmp(Register Rd, unsigned imm) = delete;
inline void cmnw(Register Rd, unsigned imm) { addsw(zr, Rd, imm); }
inline void cmn(Register Rd, unsigned imm) { adds(zr, Rd, imm); }
@ -470,6 +478,8 @@ public:
void push_fp(RegSet regs, Register stack) { if (regs.bits()) push_fp(regs.bits(), stack); }
void pop_fp(RegSet regs, Register stack) { if (regs.bits()) pop_fp(regs.bits(), stack); }
static RegSet call_clobbered_registers();
// Push and pop everything that might be clobbered by a native
// runtime call except rscratch1 and rscratch2. (They are always
// scratch, so we don't have to protect them.) Only save the lower
@ -522,10 +532,10 @@ public:
// Generalized Test Bit And Branch, including a "far" variety which
// spans more than 32KiB.
void tbr(Condition cond, Register Rt, int bitpos, Label &dest, bool far = false) {
void tbr(Condition cond, Register Rt, int bitpos, Label &dest, bool isfar = false) {
assert(cond == EQ || cond == NE, "must be");
if (far)
if (isfar)
cond = ~cond;
void (Assembler::* branch)(Register Rt, int bitpos, Label &L);
@ -534,7 +544,7 @@ public:
else
branch = &Assembler::tbnz;
if (far) {
if (isfar) {
Label L;
(this->*branch)(Rt, bitpos, L);
b(dest);

View File

@ -689,7 +689,7 @@ void MacroAssembler::generate__kernel_rem_pio2(address two_over_pi, address pio2
RECOMP_FOR1_CHECK;
Register tmp2 = r1, n = r2, jv = r4, tmp5 = r5, jx = r6,
tmp3 = r7, iqBase = r10, ih = r11, tmp4 = r12, tmp1 = r13,
jz = r14, j = r15, twoOverPiBase = r16, i = r17, qBase = r18;
jz = r14, j = r15, twoOverPiBase = r16, i = r17, qBase = r19;
// jp = jk == init_jk[prec] = init_jk[2] == {2,3,4,6}[2] == 4
// jx = nx - 1
lea(twoOverPiBase, ExternalAddress(two_over_pi));
@ -1421,6 +1421,12 @@ void MacroAssembler::generate_dsin_dcos(bool isCos, address npio2_hw,
Label DONE, ARG_REDUCTION, TINY_X, RETURN_SIN, EARLY_CASE;
Register X = r0, absX = r1, n = r2, ix = r3;
FloatRegister y0 = v4, y1 = v5;
enter();
// r19 is used in TemplateInterpreterGenerator::generate_math_entry
RegSet saved_regs = RegSet::of(r19);
push (saved_regs, sp);
block_comment("check |x| ~< pi/4, NaN, Inf and |x| < 2**-27 cases"); {
fmovd(X, v0);
mov(rscratch2, 0x3e400000);
@ -1438,14 +1444,14 @@ void MacroAssembler::generate_dsin_dcos(bool isCos, address npio2_hw,
// Set last bit unconditionally to make it NaN
orr(r10, r10, 1);
fmovd(v0, r10);
ret(lr);
b(DONE);
}
block_comment("kernel_sin/kernel_cos: if(ix<0x3e400000) {<fast return>}"); {
bind(TINY_X);
if (isCos) {
fmovd(v0, 1.0);
}
ret(lr);
b(DONE);
}
bind(ARG_REDUCTION); /* argument reduction needed */
block_comment("n = __ieee754_rem_pio2(x,y);"); {
@ -1465,7 +1471,7 @@ void MacroAssembler::generate_dsin_dcos(bool isCos, address npio2_hw,
tbz(n, 1, DONE);
}
fnegd(v0, v0);
ret(lr);
b(DONE);
bind(RETURN_SIN);
generate_kernel_sin(y0, true, dsin_coef);
if (isCos) {
@ -1474,7 +1480,7 @@ void MacroAssembler::generate_dsin_dcos(bool isCos, address npio2_hw,
tbz(n, 1, DONE);
}
fnegd(v0, v0);
ret(lr);
b(DONE);
}
bind(EARLY_CASE);
eor(y1, T8B, y1, y1);
@ -1484,5 +1490,7 @@ void MacroAssembler::generate_dsin_dcos(bool isCos, address npio2_hw,
generate_kernel_sin(v0, false, dsin_coef);
}
bind(DONE);
pop(saved_regs, sp);
leave();
ret(lr);
}

View File

@ -41,7 +41,7 @@ const char* RegisterImpl::name() const {
"c_rarg0", "c_rarg1", "c_rarg2", "c_rarg3", "c_rarg4", "c_rarg5", "c_rarg6", "c_rarg7",
"rscratch1", "rscratch2",
"r10", "r11", "r12", "r13", "r14", "r15", "r16",
"r17", "r18", "r19",
"r17", "r18_tls", "r19",
"resp", "rdispatch", "rbcp", "r23", "rlocals", "rmonitors", "rcpool", "rheapbase",
"rthread", "rfp", "lr", "sp"
};

View File

@ -27,6 +27,7 @@
#define CPU_AARCH64_REGISTER_AARCH64_HPP
#include "asm/register.hpp"
#include "utilities/powerOfTwo.hpp"
class VMRegImpl;
typedef VMRegImpl* VMReg;
@ -91,7 +92,18 @@ CONSTANT_REGISTER_DECLARATION(Register, r14, (14));
CONSTANT_REGISTER_DECLARATION(Register, r15, (15));
CONSTANT_REGISTER_DECLARATION(Register, r16, (16));
CONSTANT_REGISTER_DECLARATION(Register, r17, (17));
CONSTANT_REGISTER_DECLARATION(Register, r18, (18));
// In the ABI for Windows+AArch64 the register r18 is used to store the pointer
// to the current thread's TEB (where TLS variables are stored). We could
// carefully save and restore r18 at key places, however Win32 Structured
// Exception Handling (SEH) is using TLS to unwind the stack. If r18 is used
// for any other purpose at the time of an exception happening, SEH would not
// be able to unwind the stack properly and most likely crash.
//
// It's easier to avoid allocating r18 altogether.
//
// See https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=vs-2019#integer-registers
CONSTANT_REGISTER_DECLARATION(Register, r18_tls, (18));
CONSTANT_REGISTER_DECLARATION(Register, r19, (19));
CONSTANT_REGISTER_DECLARATION(Register, r20, (20));
CONSTANT_REGISTER_DECLARATION(Register, r21, (21));
@ -292,6 +304,8 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl {
static const int max_pr;
};
class RegSetIterator;
// A set of registers
class RegSet {
uint32_t _bitset;
@ -350,6 +364,49 @@ public:
}
uint32_t bits() const { return _bitset; }
private:
Register first() {
uint32_t first = _bitset & -_bitset;
return first ? as_Register(exact_log2(first)) : noreg;
}
public:
friend class RegSetIterator;
RegSetIterator begin();
};
class RegSetIterator {
RegSet _regs;
public:
RegSetIterator(RegSet x): _regs(x) {}
RegSetIterator(const RegSetIterator& mit) : _regs(mit._regs) {}
RegSetIterator& operator++() {
Register r = _regs.first();
if (r != noreg)
_regs -= r;
return *this;
}
bool operator==(const RegSetIterator& rhs) const {
return _regs.bits() == rhs._regs.bits();
}
bool operator!=(const RegSetIterator& rhs) const {
return ! (rhs == *this);
}
Register operator*() {
return _regs.first();
}
};
inline RegSetIterator RegSet::begin() {
return RegSetIterator(*this);
}
#endif // CPU_AARCH64_REGISTER_AARCH64_HPP

View File

@ -50,7 +50,7 @@ REGISTER_DEFINITION(Register, r14);
REGISTER_DEFINITION(Register, r15);
REGISTER_DEFINITION(Register, r16);
REGISTER_DEFINITION(Register, r17);
REGISTER_DEFINITION(Register, r18);
REGISTER_DEFINITION(Register, r18_tls); // see comment in register_aarch64.hpp
REGISTER_DEFINITION(Register, r19);
REGISTER_DEFINITION(Register, r20);
REGISTER_DEFINITION(Register, r21);

View File

@ -1092,7 +1092,7 @@ class StubGenerator: public StubCodeGenerator {
Label copy4, copy8, copy16, copy32, copy80, copy_big, finish;
const Register t2 = r5, t3 = r6, t4 = r7, t5 = r8;
const Register t6 = r9, t7 = r10, t8 = r11, t9 = r12;
const Register send = r17, dend = r18;
const Register send = r17, dend = r16;
if (PrefetchCopyIntervalInBytes > 0)
__ prfm(Address(s, 0), PLDL1KEEP);
@ -1282,11 +1282,15 @@ class StubGenerator: public StubCodeGenerator {
void clobber_registers() {
#ifdef ASSERT
RegSet clobbered
= MacroAssembler::call_clobbered_registers() - rscratch1;
__ mov(rscratch1, (uint64_t)0xdeadbeef);
__ orr(rscratch1, rscratch1, rscratch1, Assembler::LSL, 32);
for (Register r = r3; r <= r18; r++)
if (r != rscratch1) __ mov(r, rscratch1);
for (RegSetIterator it = clobbered.begin(); *it != noreg; ++it) {
__ mov(*it, rscratch1);
}
#endif
}
// Scan over array at a for count oops, verifying each one.
@ -1719,10 +1723,10 @@ class StubGenerator: public StubCodeGenerator {
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)
// Registers used as temps (r19, r20, r21, r22 are save-on-entry)
const Register copied_oop = r22; // actual oop copied
const Register count_save = r21; // orig elementscount
const Register start_to = r20; // destination array start address
const Register copied_oop = r18; // actual oop copied
const Register r19_klass = r19; // oop._klass
//---------------------------------------------------------------
@ -1759,8 +1763,7 @@ class StubGenerator: public StubCodeGenerator {
// Empty array: Nothing to do.
__ cbz(count, L_done);
__ push(RegSet::of(r18, r19, r20, r21), sp);
__ push(RegSet::of(r19, r20, r21, r22), sp);
#ifdef ASSERT
BLOCK_COMMENT("assert consistent ckoff/ckval");
@ -1829,7 +1832,7 @@ class StubGenerator: public StubCodeGenerator {
bs->arraycopy_epilogue(_masm, decorators, is_oop, start_to, count_save, rscratch1, wb_post_saved_regs);
__ bind(L_done_pop);
__ pop(RegSet::of(r18, r19, r20, r21), sp);
__ pop(RegSet::of(r19, r20, r21, r22), sp);
inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr);
__ bind(L_done);
@ -2006,7 +2009,7 @@ class StubGenerator: public StubCodeGenerator {
// registers used as temp
const Register scratch_length = r16; // elements count to copy
const Register scratch_src_klass = r17; // array klass
const Register lh = r18; // layout helper
const Register lh = r15; // layout helper
// if (length < 0) return -1;
__ movw(scratch_length, length); // length (elements count, 32-bits value)
@ -2077,7 +2080,7 @@ class StubGenerator: public StubCodeGenerator {
//
const Register rscratch1_offset = rscratch1; // array offset
const Register r18_elsize = lh; // element size
const Register r15_elsize = lh; // element size
__ ubfx(rscratch1_offset, lh, Klass::_lh_header_size_shift,
exact_log2(Klass::_lh_header_size_mask+1)); // array_offset
@ -2098,8 +2101,8 @@ class StubGenerator: public StubCodeGenerator {
// The possible values of elsize are 0-3, i.e. exact_log2(element
// size in bytes). We do a simple bitwise binary search.
__ BIND(L_copy_bytes);
__ tbnz(r18_elsize, 1, L_copy_ints);
__ tbnz(r18_elsize, 0, L_copy_shorts);
__ tbnz(r15_elsize, 1, L_copy_ints);
__ tbnz(r15_elsize, 0, L_copy_shorts);
__ lea(from, Address(src, src_pos));// src_addr
__ lea(to, Address(dst, dst_pos));// dst_addr
__ movw(count, scratch_length); // length
@ -2112,7 +2115,7 @@ class StubGenerator: public StubCodeGenerator {
__ b(RuntimeAddress(short_copy_entry));
__ BIND(L_copy_ints);
__ tbnz(r18_elsize, 0, L_copy_longs);
__ tbnz(r15_elsize, 0, L_copy_longs);
__ lea(from, Address(src, src_pos, Address::lsl(2)));// src_addr
__ lea(to, Address(dst, dst_pos, Address::lsl(2)));// dst_addr
__ movw(count, scratch_length); // length
@ -2123,8 +2126,8 @@ class StubGenerator: public StubCodeGenerator {
{
BLOCK_COMMENT("assert long copy {");
Label L;
__ andw(lh, lh, Klass::_lh_log2_element_size_mask); // lh -> r18_elsize
__ cmpw(r18_elsize, LogBytesPerLong);
__ andw(lh, lh, Klass::_lh_log2_element_size_mask); // lh -> r15_elsize
__ cmpw(r15_elsize, LogBytesPerLong);
__ br(Assembler::EQ, L);
__ stop("must be long copy, but elsize is wrong");
__ bind(L);
@ -2142,8 +2145,8 @@ class StubGenerator: public StubCodeGenerator {
Label L_plain_copy, L_checkcast_copy;
// test array classes for subtyping
__ load_klass(r18, dst);
__ cmp(scratch_src_klass, r18); // usual case is exact equality
__ load_klass(r15, dst);
__ cmp(scratch_src_klass, r15); // usual case is exact equality
__ br(Assembler::NE, L_checkcast_copy);
// Identically typed arrays can be copied without element-wise checks.
@ -2159,17 +2162,17 @@ class StubGenerator: public StubCodeGenerator {
__ b(RuntimeAddress(oop_copy_entry));
__ BIND(L_checkcast_copy);
// live at this point: scratch_src_klass, scratch_length, r18 (dst_klass)
// live at this point: scratch_src_klass, scratch_length, r15 (dst_klass)
{
// Before looking at dst.length, make sure dst is also an objArray.
__ ldrw(rscratch1, Address(r18, lh_offset));
__ ldrw(rscratch1, Address(r15, lh_offset));
__ movw(rscratch2, objArray_lh);
__ eorw(rscratch1, rscratch1, rscratch2);
__ cbnzw(rscratch1, L_failed);
// It is safe to examine both src.length and dst.length.
arraycopy_range_checks(src, src_pos, dst, dst_pos, scratch_length,
r18, L_failed);
r15, L_failed);
__ load_klass(dst_klass, dst); // reload
@ -5066,42 +5069,42 @@ class StubGenerator: public StubCodeGenerator {
// Register allocation
Register reg = c_rarg0;
Pa_base = reg; // Argument registers
RegSetIterator regs = (RegSet::range(r0, r26) - r18_tls).begin();
Pa_base = *regs; // Argument registers
if (squaring)
Pb_base = Pa_base;
else
Pb_base = ++reg;
Pn_base = ++reg;
Rlen= ++reg;
inv = ++reg;
Pm_base = ++reg;
Pb_base = *++regs;
Pn_base = *++regs;
Rlen= *++regs;
inv = *++regs;
Pm_base = *++regs;
// Working registers:
Ra = ++reg; // The current digit of a, b, n, and m.
Rb = ++reg;
Rm = ++reg;
Rn = ++reg;
Ra = *++regs; // The current digit of a, b, n, and m.
Rb = *++regs;
Rm = *++regs;
Rn = *++regs;
Pa = ++reg; // Pointers to the current/next digit of a, b, n, and m.
Pb = ++reg;
Pm = ++reg;
Pn = ++reg;
Pa = *++regs; // Pointers to the current/next digit of a, b, n, and m.
Pb = *++regs;
Pm = *++regs;
Pn = *++regs;
t0 = ++reg; // Three registers which form a
t1 = ++reg; // triple-precision accumuator.
t2 = ++reg;
t0 = *++regs; // Three registers which form a
t1 = *++regs; // triple-precision accumuator.
t2 = *++regs;
Ri = ++reg; // Inner and outer loop indexes.
Rj = ++reg;
Ri = *++regs; // Inner and outer loop indexes.
Rj = *++regs;
Rhi_ab = ++reg; // Product registers: low and high parts
Rlo_ab = ++reg; // of a*b and m*n.
Rhi_mn = ++reg;
Rlo_mn = ++reg;
Rhi_ab = *++regs; // Product registers: low and high parts
Rlo_ab = *++regs; // of a*b and m*n.
Rhi_mn = *++regs;
Rlo_mn = *++regs;
// r19 and up are callee-saved.
_toSave = RegSet::range(r19, reg) + Pm_base;
_toSave = RegSet::range(r19, *regs) + Pm_base;
}
private:

View File

@ -22,6 +22,7 @@
*
*/
#include "precompiled.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
#include "runtime/os.inline.hpp"

View File

@ -32,6 +32,7 @@
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/icBuffer.hpp"
#include "code/nativeInst.hpp"
#include "code/vtableStubs.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/disassembler.hpp"
@ -119,13 +120,18 @@ static FILETIME process_exit_time;
static FILETIME process_user_time;
static FILETIME process_kernel_time;
#ifdef _M_AMD64
#if defined(_M_ARM64)
#define __CPU__ aarch64
#elif defined(_M_AMD64)
#define __CPU__ amd64
#else
#define __CPU__ i486
#endif
#if INCLUDE_AOT
#if defined(USE_VECTORED_EXCEPTION_HANDLING)
PVOID topLevelVectoredExceptionHandler = NULL;
LPTOP_LEVEL_EXCEPTION_FILTER previousUnhandledExceptionFilter = NULL;
#elif INCLUDE_AOT
PVOID topLevelVectoredExceptionHandler = NULL;
LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
#endif
@ -148,7 +154,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
if (ForceTimeHighResolution) {
timeEndPeriod(1L);
}
#if INCLUDE_AOT
#if defined(USE_VECTORED_EXCEPTION_HANDLING) || INCLUDE_AOT
if (topLevelVectoredExceptionHandler != NULL) {
RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler);
topLevelVectoredExceptionHandler = NULL;
@ -457,6 +463,12 @@ static unsigned __stdcall thread_native_entry(Thread* thread) {
log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id());
#ifdef USE_VECTORED_EXCEPTION_HANDLING
// Any exception is caught by the Vectored Exception Handler, so VM can
// generate error dump when an exception occurred in non-Java thread
// (e.g. VM thread).
thread->call_run();
#else
// Install a win32 structured exception handler around every thread created
// by VM, so VM can generate error dump when an exception occurred in non-
// Java thread (e.g. VM thread).
@ -466,6 +478,7 @@ static unsigned __stdcall thread_native_entry(Thread* thread) {
(_EXCEPTION_POINTERS*)_exception_info())) {
// Nothing to do.
}
#endif
// Note: at this point the thread object may already have deleted itself.
// Do not dereference it from here on out.
@ -1428,15 +1441,18 @@ void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
static const arch_t arch_array[] = {
{IMAGE_FILE_MACHINE_I386, (char*)"IA 32"},
{IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"}
{IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"},
{IMAGE_FILE_MACHINE_ARM64, (char*)"ARM 64"}
};
#if (defined _M_AMD64)
#if (defined _M_ARM64)
static const uint16_t running_arch = IMAGE_FILE_MACHINE_ARM64;
#elif (defined _M_AMD64)
static const uint16_t running_arch = IMAGE_FILE_MACHINE_AMD64;
#elif (defined _M_IX86)
static const uint16_t running_arch = IMAGE_FILE_MACHINE_I386;
#else
#error Method os::dll_load requires that one of following \
is defined :_M_AMD64 or _M_IX86
is defined :_M_AMD64 or _M_IX86 or _M_ARM64
#endif
@ -1731,7 +1747,8 @@ void os::win32::print_windows_version(outputStream* st) {
SYSTEM_INFO si;
ZeroMemory(&si, sizeof(SYSTEM_INFO));
GetNativeSystemInfo(&si);
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
if ((si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ||
(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)) {
st->print(" , 64 bit");
}
@ -2139,7 +2156,14 @@ LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo,
address handler) {
Thread* thread = Thread::current_or_null();
// Save pc in thread
#ifdef _M_AMD64
#if defined(_M_ARM64)
// Do not blow up if no thread info available.
if (thread) {
thread->as_Java_thread()->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Pc);
}
// Set pc to handler
exceptionInfo->ContextRecord->Pc = (DWORD64)handler;
#elif defined(_M_AMD64)
// Do not blow up if no thread info available.
if (thread != NULL) {
thread->as_Java_thread()->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
@ -2237,7 +2261,17 @@ const char* os::exception_name(int exception_code, char *buf, size_t size) {
LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
// handle exception caused by idiv; should only happen for -MinInt/-1
// (division by zero is handled explicitly)
#ifdef _M_AMD64
#if defined(_M_ARM64)
PCONTEXT ctx = exceptionInfo->ContextRecord;
address pc = (address)ctx->Sp;
assert(pc[0] == 0x83, "not an sdiv opcode"); //Fixme did i get the right opcode?
assert(ctx->X4 == min_jint, "unexpected idiv exception");
// set correct result values and continue after idiv instruction
ctx->Pc = (uint64_t)pc + 4; // idiv reg, reg, reg is 4 bytes
ctx->X4 = (uint64_t)min_jint; // result
ctx->X5 = (uint64_t)0; // remainder
// Continue the execution
#elif defined(_M_AMD64)
PCONTEXT ctx = exceptionInfo->ContextRecord;
address pc = (address)ctx->Rip;
assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode");
@ -2268,6 +2302,7 @@ LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
return EXCEPTION_CONTINUE_EXECUTION;
}
#if defined(_M_AMD64) || defined(_M_IX86)
//-----------------------------------------------------------------------------
LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
PCONTEXT ctx = exceptionInfo->ContextRecord;
@ -2313,6 +2348,7 @@ LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
static inline void report_error(Thread* t, DWORD exception_code,
address addr, void* siginfo, void* context) {
@ -2322,66 +2358,14 @@ static inline void report_error(Thread* t, DWORD exception_code,
// somewhere where we can find it in the minidump.
}
bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) {
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
address addr = (address) exceptionRecord->ExceptionInformation[1];
if (Interpreter::contains(pc)) {
*fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
if (!fr->is_first_java_frame()) {
// get_frame_at_stack_banging_point() is only called when we
// have well defined stacks so java_sender() calls do not need
// to assert safe_for_sender() first.
*fr = fr->java_sender();
}
} else {
// more complex code with compiled code
assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
CodeBlob* cb = CodeCache::find_blob(pc);
if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
// Not sure where the pc points to, fallback to default
// stack overflow handling
return false;
} else {
*fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
// in compiled code, the stack banging is performed just after the return pc
// has been pushed on the stack
*fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp()));
if (!fr->is_java_frame()) {
// See java_sender() comment above.
*fr = fr->java_sender();
}
}
}
assert(fr->is_java_frame(), "Safety check");
return true;
}
#if INCLUDE_AOT
LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
address addr = (address) exceptionRecord->ExceptionInformation[1];
address pc = (address) exceptionInfo->ContextRecord->Rip;
// Handle the case where we get an implicit exception in AOT generated
// code. AOT DLL's loaded are not registered for structured exceptions.
// If the exception occurred in the codeCache or AOT code, pass control
// to our normal exception handler.
CodeBlob* cb = CodeCache::find_blob(pc);
if (cb != NULL) {
return topLevelExceptionFilter(exceptionInfo);
}
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
//-----------------------------------------------------------------------------
LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
PEXCEPTION_RECORD exception_record = exceptionInfo->ExceptionRecord;
DWORD exception_code = exception_record->ExceptionCode;
#ifdef _M_AMD64
#if defined(_M_ARM64)
address pc = (address) exceptionInfo->ContextRecord->Pc;
#elif defined(_M_AMD64)
address pc = (address) exceptionInfo->ContextRecord->Rip;
#else
address pc = (address) exceptionInfo->ContextRecord->Eip;
@ -2464,18 +2448,22 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
// Last unguard failed or not unguarding
tty->print_raw_cr("Execution protection violation");
#if !defined(USE_VECTORED_EXCEPTION_HANDLING)
report_error(t, exception_code, addr, exception_record,
exceptionInfo->ContextRecord);
#endif
return EXCEPTION_CONTINUE_SEARCH;
}
}
#endif // _WIN64
#if defined(_M_AMD64) || defined(_M_IX86)
if ((exception_code == EXCEPTION_ACCESS_VIOLATION) &&
VM_Version::is_cpuinfo_segv_addr(pc)) {
// Verify that OS save/restore AVX registers.
return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr());
}
#endif
if (t != NULL && t->is_Java_thread()) {
JavaThread* thread = t->as_Java_thread();
@ -2506,8 +2494,10 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
// Fatal red zone violation.
thread->disable_stack_red_zone();
tty->print_raw_cr("An unrecoverable stack overflow has occurred.");
#if !defined(USE_VECTORED_EXCEPTION_HANDLING)
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
#endif
return EXCEPTION_CONTINUE_SEARCH;
}
} else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
@ -2563,8 +2553,10 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
#endif
// Stack overflow or null pointer exception in native code.
#if !defined(USE_VECTORED_EXCEPTION_HANDLING)
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
#endif
return EXCEPTION_CONTINUE_SEARCH;
} // /EXCEPTION_ACCESS_VIOLATION
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -2587,6 +2579,19 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
}
}
#ifdef _M_ARM64
if (in_java &&
(exception_code == EXCEPTION_ILLEGAL_INSTRUCTION ||
exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) {
if (nativeInstruction_at(pc)->is_sigill_zombie_not_entrant()) {
if (TraceTraps) {
tty->print_cr("trap: zombie_not_entrant");
}
return Handle_Exception(exceptionInfo, SharedRuntime::get_handle_wrong_method_stub());
}
}
#endif
if (in_java) {
switch (exception_code) {
case EXCEPTION_INT_DIVIDE_BY_ZERO:
@ -2597,19 +2602,75 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
} // switch
}
#if defined(_M_AMD64) || defined(_M_IX86)
if ((in_java || in_native) && exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) {
LONG result=Handle_FLT_Exception(exceptionInfo);
if (result==EXCEPTION_CONTINUE_EXECUTION) return result;
}
#endif
}
#if !defined(USE_VECTORED_EXCEPTION_HANDLING)
if (exception_code != EXCEPTION_BREAKPOINT) {
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
}
#endif
return EXCEPTION_CONTINUE_SEARCH;
}
#if defined(USE_VECTORED_EXCEPTION_HANDLING) || INCLUDE_AOT
LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
#if defined(_M_ARM64)
address pc = (address) exceptionInfo->ContextRecord->Pc;
#elif defined(_M_AMD64)
address pc = (address) exceptionInfo->ContextRecord->Rip;
#else
address pc = (address) exceptionInfo->ContextRecord->Eip;
#endif
// Fast path for code part of the code cache
if (CodeCache::low_bound() <= pc && pc < CodeCache::high_bound()) {
return topLevelExceptionFilter(exceptionInfo);
}
// Handle the case where we get an implicit exception in AOT generated
// code. AOT DLL's loaded are not registered for structured exceptions.
// If the exception occurred in the codeCache or AOT code, pass control
// to our normal exception handler.
CodeBlob* cb = CodeCache::find_blob(pc);
if (cb != NULL) {
return topLevelExceptionFilter(exceptionInfo);
}
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
#if defined(USE_VECTORED_EXCEPTION_HANDLING)
LONG WINAPI topLevelUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
if (InterceptOSException) goto exit;
DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
#if defined(_M_ARM64)
address pc = (address)exceptionInfo->ContextRecord->Pc;
#elif defined(_M_AMD64)
address pc = (address) exceptionInfo->ContextRecord->Rip;
#else
address pc = (address) exceptionInfo->ContextRecord->Eip;
#endif
Thread* t = Thread::current_or_null_safe();
if (exception_code != EXCEPTION_BREAKPOINT) {
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
}
exit:
return previousUnhandledExceptionFilter ? previousUnhandledExceptionFilter(exceptionInfo) : EXCEPTION_CONTINUE_SEARCH;
}
#endif
#ifndef _WIN64
// Special care for fast JNI accessors.
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and
@ -3455,7 +3516,12 @@ char* os::non_memory_address_word() {
// Must never look like an address returned by reserve_memory,
// even in its subfields (as defined by the CPU immediate fields,
// if the CPU splits constants across multiple instructions).
#ifdef _M_ARM64
// AArch64 has a maximum addressable space of 48-bits
return (char*)((1ull << 48) - 1);
#else
return (char*)-1;
#endif
}
#define MAX_ERROR_COUNT 100
@ -3979,7 +4045,10 @@ jint os::init_2(void) {
// Setup Windows Exceptions
#if INCLUDE_AOT
#if defined(USE_VECTORED_EXCEPTION_HANDLING)
topLevelVectoredExceptionHandler = AddVectoredExceptionHandler(1, topLevelVectoredExceptionFilter);
previousUnhandledExceptionFilter = SetUnhandledExceptionFilter(topLevelUnhandledExceptionFilter);
#elif INCLUDE_AOT
// If AOT is enabled we need to install a vectored exception handler
// in order to forward implicit exceptions from code in AOT
// generated DLLs. This is necessary since these DLLs are not
@ -5446,7 +5515,7 @@ int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
// WINDOWS CONTEXT Flags for THREAD_SAMPLING
#if defined(IA32)
#define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
#elif defined (AMD64)
#elif defined(AMD64) || defined(_M_ARM64)
#define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
#endif

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 1999, 2020, 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.
*
*/
#ifndef OS_CPU_LINUX_AARCH64_ICACHE_AARCH64_HPP
#define OS_CPU_LINUX_AARCH64_ICACHE_AARCH64_HPP
// Interface for updating the instruction cache. Whenever the VM
// modifies code, part of the processor instruction cache potentially
// has to be flushed.
class ICache : public AbstractICache {
public:
static void initialize();
static void invalidate_word(address addr) {
__builtin___clear_cache((char *)addr, (char *)(addr + 4));
}
static void invalidate_range(address start, int nbytes) {
__builtin___clear_cache((char *)start, (char *)(start + nbytes));
}
};
#endif // OS_CPU_LINUX_AARCH64_ICACHE_AARCH64_HPP

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
// nothing required here
#include "precompiled.hpp"

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_ATOMIC_WINDOWS_AARCH64_HPP
#define OS_CPU_WINDOWS_AARCH64_ATOMIC_WINDOWS_AARCH64_HPP
#include <intrin.h>
#include "runtime/os.hpp"
#include "runtime/vm_version.hpp"
// As per atomic.hpp all read-modify-write operations have to provide two-way
// barriers semantics. The memory_order parameter is ignored - we always provide
// the strongest/most-conservative ordering
//
// For AARCH64 we add explicit barriers in the stubs.
template<size_t byte_size>
struct Atomic::PlatformAdd {
template<typename D, typename I>
D add_and_fetch(D volatile* dest, I add_value, atomic_memory_order order) const;
template<typename D, typename I>
D fetch_and_add(D volatile* dest, I add_value, atomic_memory_order order) const {
return add_and_fetch(dest, add_value, order) - add_value;
}
};
// The Interlocked* APIs only take long and will not accept __int32. That is
// acceptable on Windows, since long is a 32-bits integer type.
#define DEFINE_INTRINSIC_ADD(IntrinsicName, IntrinsicType) \
template<> \
template<typename D, typename I> \
inline D Atomic::PlatformAdd<sizeof(IntrinsicType)>::add_and_fetch(D volatile* dest, \
I add_value, \
atomic_memory_order order) const { \
STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(D)); \
return PrimitiveConversions::cast<D>( \
IntrinsicName(reinterpret_cast<IntrinsicType volatile *>(dest), \
PrimitiveConversions::cast<IntrinsicType>(add_value))); \
}
DEFINE_INTRINSIC_ADD(InterlockedAdd, long)
DEFINE_INTRINSIC_ADD(InterlockedAdd64, __int64)
#undef DEFINE_INTRINSIC_ADD
#define DEFINE_INTRINSIC_XCHG(IntrinsicName, IntrinsicType) \
template<> \
template<typename T> \
inline T Atomic::PlatformXchg<sizeof(IntrinsicType)>::operator()(T volatile* dest, \
T exchange_value, \
atomic_memory_order order) const { \
STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \
return PrimitiveConversions::cast<T>( \
IntrinsicName(reinterpret_cast<IntrinsicType volatile *>(dest), \
PrimitiveConversions::cast<IntrinsicType>(exchange_value))); \
}
DEFINE_INTRINSIC_XCHG(InterlockedExchange, long)
DEFINE_INTRINSIC_XCHG(InterlockedExchange64, __int64)
#undef DEFINE_INTRINSIC_XCHG
// Note: the order of the parameters is different between
// Atomic::PlatformCmpxchg<*>::operator() and the
// InterlockedCompareExchange* API.
#define DEFINE_INTRINSIC_CMPXCHG(IntrinsicName, IntrinsicType) \
template<> \
template<typename T> \
inline T Atomic::PlatformCmpxchg<sizeof(IntrinsicType)>::operator()(T volatile* dest, \
T compare_value, \
T exchange_value, \
atomic_memory_order order) const { \
STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \
return PrimitiveConversions::cast<T>( \
IntrinsicName(reinterpret_cast<IntrinsicType volatile *>(dest), \
PrimitiveConversions::cast<IntrinsicType>(exchange_value), \
PrimitiveConversions::cast<IntrinsicType>(compare_value))); \
}
DEFINE_INTRINSIC_CMPXCHG(_InterlockedCompareExchange8, char) // Use the intrinsic as InterlockedCompareExchange8 does not exist
DEFINE_INTRINSIC_CMPXCHG(InterlockedCompareExchange, long)
DEFINE_INTRINSIC_CMPXCHG(InterlockedCompareExchange64, __int64)
#undef DEFINE_INTRINSIC_CMPXCHG
#endif // OS_CPU_WINDOWS_AARCH64_ATOMIC_WINDOWS_AARCH64_HPP

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_INLINE_HPP
#define OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_INLINE_HPP
#include <stdlib.h>
// Efficient swapping of data bytes from Java byte
// ordering to native byte ordering and vice versa.
inline u2 Bytes::swap_u2(u2 x) {
return _byteswap_ushort(x);
}
inline u4 Bytes::swap_u4(u4 x) {
return _byteswap_ulong(x);
}
inline u8 Bytes::swap_u8(u8 x) {
return _byteswap_uint64(x);
}
#pragma warning(default: 4035) // Enable warning 4035: no return value
#endif // OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_INLINE_HPP

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_COPY_WINDOWS_AARCH64_INLINE_HPP
#define OS_CPU_WINDOWS_AARCH64_COPY_WINDOWS_AARCH64_INLINE_HPP
#include <string.h>
static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
(void)memmove(to, from, count * HeapWordSize);
}
static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
switch (count) {
case 8: to[7] = from[7];
case 7: to[6] = from[6];
case 6: to[5] = from[5];
case 5: to[4] = from[4];
case 4: to[3] = from[3];
case 3: to[2] = from[2];
case 2: to[1] = from[1];
case 1: to[0] = from[0];
case 0: break;
default:
(void)memcpy(to, from, count * HeapWordSize);
break;
}
}
static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
switch (count) {
case 8: to[7] = from[7];
case 7: to[6] = from[6];
case 6: to[5] = from[5];
case 5: to[4] = from[4];
case 4: to[3] = from[3];
case 3: to[2] = from[2];
case 2: to[1] = from[1];
case 1: to[0] = from[0];
case 0: break;
default: while (count-- > 0) {
*to++ = *from++;
}
break;
}
}
static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
// pd_conjoint_words(from, to, count);
(void)memmove(to, from, count * HeapWordSize);
}
static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_disjoint_words(from, to, count);
}
static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
(void)memmove(to, from, count);
}
static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
pd_conjoint_bytes(from, to, count);
}
static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
if (from > to) {
while (count-- > 0) {
// Copy forwards
*to++ = *from++;
}
} else {
from += count - 1;
to += count - 1;
while (count-- > 0) {
// Copy backwards
*to-- = *from--;
}
}
}
static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
if (from > to) {
while (count-- > 0) {
// Copy forwards
*to++ = *from++;
}
} else {
from += count - 1;
to += count - 1;
while (count-- > 0) {
// Copy backwards
*to-- = *from--;
}
}
}
static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
}
static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
if (from > to) {
while (count-- > 0) {
// Copy forwards
*to++ = *from++;
}
} else {
from += count - 1;
to += count - 1;
while (count-- > 0) {
// Copy backwards
*to-- = *from--;
}
}
}
static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_bytes_atomic(from, to, count);
}
static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_jshorts_atomic((const jshort*)from, (jshort*)to, count);
}
static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
}
static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
}
static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
}
#endif // OS_CPU_WINDOWS_AARCH64_COPY_WINDOWS_AARCH64_INLINE_HPP

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_GLOBALS_WINDOWS_AARCH64_HPP
#define OS_CPU_WINDOWS_AARCH64_GLOBALS_WINDOWS_AARCH64_HPP
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
define_pd_global(bool, DontYieldALot, false);
// Default stack size on Windows is determined by the executable (java.exe
// has a default value of 320K/1MB [32bit/64bit]). Depending on Windows version, changing
// ThreadStackSize to non-zero may have significant impact on memory usage.
// See comments in os_windows.cpp.
define_pd_global(intx, ThreadStackSize, 0); // 0 => use system default
define_pd_global(intx, VMThreadStackSize, 0);
#ifdef ASSERT
define_pd_global(intx, CompilerThreadStackSize, 1024);
#else
define_pd_global(intx, CompilerThreadStackSize, 0);
#endif
define_pd_global(uintx,JVMInvokeMethodSlack, 8192);
// Used on 64 bit platforms for UseCompressedOops base address
define_pd_global(uintx,HeapBaseMinAddress, 2*G);
#endif // OS_CPU_WINDOWS_AARCH64_GLOBALS_WINDOWS_AARCH64_HPP

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 1997, 2020, 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_ICACHE_AARCH64_HPP
#define OS_CPU_WINDOWS_AARCH64_ICACHE_AARCH64_HPP
// Interface for updating the instruction cache. Whenever the VM
// modifies code, part of the processor instruction cache potentially
// has to be flushed.
class ICache : public AbstractICache {
public:
static void initialize();
static void invalidate_word(address addr) {
invalidate_range(addr, 4);
}
static void invalidate_range(address start, int nbytes) {
FlushInstructionCache((HANDLE)GetCurrentProcess(), start, (SIZE_T)(nbytes));
}
};
#endif // OS_CPU_WINDOWS_AARCH64_ICACHE_AARCH64_HPP

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_ORDERACCESS_WINDOWS_AARCH64_HPP
#define OS_CPU_WINDOWS_AARCH64_ORDERACCESS_WINDOWS_AARCH64_HPP
// Included in orderAccess.hpp header file.
#include <atomic>
using std::atomic_thread_fence;
#include <intrin.h>
#include "vm_version_aarch64.hpp"
#include "runtime/vm_version.hpp"
// Implementation of class OrderAccess.
inline void OrderAccess::loadload() { acquire(); }
inline void OrderAccess::storestore() { release(); }
inline void OrderAccess::loadstore() { acquire(); }
inline void OrderAccess::storeload() { fence(); }
#define READ_MEM_BARRIER atomic_thread_fence(std::memory_order_acquire);
#define WRITE_MEM_BARRIER atomic_thread_fence(std::memory_order_release);
#define FULL_MEM_BARRIER atomic_thread_fence(std::memory_order_seq_cst);
inline void OrderAccess::acquire() {
READ_MEM_BARRIER;
}
inline void OrderAccess::release() {
WRITE_MEM_BARRIER;
}
inline void OrderAccess::fence() {
FULL_MEM_BARRIER;
}
inline void OrderAccess::cross_modify_fence() { }
#endif // OS_CPU_WINDOWS_AARCH64_ORDERACCESS_WINDOWS_AARCH64_HPP

View File

@ -0,0 +1,311 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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 "jvm.h"
#include "asm/macroAssembler.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
#include "code/nativeInst.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/allocation.inline.hpp"
#include "prims/jniFastGetField.hpp"
#include "prims/jvm_misc.hpp"
#include "runtime/arguments.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/osThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
#include "unwind_windows_aarch64.hpp"
#include "utilities/debug.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
// put OS-includes here
# include <sys/types.h>
# include <signal.h>
# include <errno.h>
# include <stdlib.h>
# include <stdio.h>
# include <intrin.h>
void os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method, JavaCallArguments* args, Thread* thread) {
f(value, method, args, thread);
}
PRAGMA_DISABLE_MSVC_WARNING(4172)
// Returns an estimate of the current stack pointer. Result must be guaranteed
// to point into the calling threads stack, and be no lower than the current
// stack pointer.
address os::current_stack_pointer() {
int dummy;
address sp = (address)&dummy;
return sp;
}
address os::fetch_frame_from_context(const void* ucVoid,
intptr_t** ret_sp, intptr_t** ret_fp) {
address epc;
CONTEXT* uc = (CONTEXT*)ucVoid;
if (uc != NULL) {
epc = (address)uc->Pc;
if (ret_sp) *ret_sp = (intptr_t*)uc->Sp;
if (ret_fp) *ret_fp = (intptr_t*)uc->Fp;
} else {
// construct empty ExtendedPC for return value checking
epc = NULL;
if (ret_sp) *ret_sp = (intptr_t *)NULL;
if (ret_fp) *ret_fp = (intptr_t *)NULL;
}
return epc;
}
frame os::fetch_frame_from_context(const void* ucVoid) {
intptr_t* sp;
intptr_t* fp;
address epc = fetch_frame_from_context(ucVoid, &sp, &fp);
return frame(sp, fp, epc);
}
bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) {
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
address addr = (address) exceptionRecord->ExceptionInformation[1];
if (Interpreter::contains(pc)) {
// interpreter performs stack banging after the fixed frame header has
// been generated while the compilers perform it before. To maintain
// semantic consistency between interpreted and compiled frames, the
// method returns the Java sender of the current frame.
*fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
if (!fr->is_first_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
*fr = fr->java_sender();
}
} else {
// more complex code with compiled code
assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
CodeBlob* cb = CodeCache::find_blob(pc);
if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
// Not sure where the pc points to, fallback to default
// stack overflow handling
return false;
} else {
// In compiled code, the stack banging is performed before LR
// has been saved in the frame. LR is live, and SP and FP
// belong to the caller.
intptr_t* fp = (intptr_t*)exceptionInfo->ContextRecord->Fp;
intptr_t* sp = (intptr_t*)exceptionInfo->ContextRecord->Sp;
address pc = (address)(exceptionInfo->ContextRecord->Lr
- NativeInstruction::instruction_size);
*fr = frame(sp, fp, pc);
if (!fr->is_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
assert(!fr->is_first_frame(), "Safety check");
*fr = fr->java_sender();
}
}
}
assert(fr->is_java_frame(), "Safety check");
return true;
}
// By default, gcc always saves frame pointer rfp on this stack. This
// may get turned off by -fomit-frame-pointer.
frame os::get_sender_for_C_frame(frame* fr) {
return frame(fr->link(), fr->link(), fr->sender_pc());
}
frame os::current_frame() {
typedef intptr_t* get_fp_func ();
get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*,
StubRoutines::aarch64::get_previous_fp_entry());
if (func == NULL) return frame();
intptr_t* fp = (*func)();
if (fp == NULL) {
return frame();
}
frame myframe((intptr_t*)os::current_stack_pointer(),
(intptr_t*)fp,
CAST_FROM_FN_PTR(address, os::current_frame));
if (os::is_first_C_frame(&myframe)) {
// stack is not walkable
return frame();
} else {
return os::get_sender_for_C_frame(&myframe);
}
}
////////////////////////////////////////////////////////////////////////////////
// thread stack
// Minimum usable stack sizes required to get to user code. Space for
// HotSpot guard pages is added later.
/////////////////////////////////////////////////////////////////////////////
// helper functions for fatal error handler
void os::print_context(outputStream *st, const void *context) {
if (context == NULL) return;
const CONTEXT* uc = (const CONTEXT*)context;
st->print_cr("Registers:");
st->print( "X0 =" INTPTR_FORMAT, uc->X0);
st->print(", X1 =" INTPTR_FORMAT, uc->X1);
st->print(", X2 =" INTPTR_FORMAT, uc->X2);
st->print(", X3 =" INTPTR_FORMAT, uc->X3);
st->cr();
st->print( "X4 =" INTPTR_FORMAT, uc->X4);
st->print(", X5 =" INTPTR_FORMAT, uc->X5);
st->print(", X6 =" INTPTR_FORMAT, uc->X6);
st->print(", X7 =" INTPTR_FORMAT, uc->X7);
st->cr();
st->print( "X8 =" INTPTR_FORMAT, uc->X8);
st->print(", X9 =" INTPTR_FORMAT, uc->X9);
st->print(", X10=" INTPTR_FORMAT, uc->X10);
st->print(", X11=" INTPTR_FORMAT, uc->X11);
st->cr();
st->print( "X12=" INTPTR_FORMAT, uc->X12);
st->print(", X13=" INTPTR_FORMAT, uc->X13);
st->print(", X14=" INTPTR_FORMAT, uc->X14);
st->print(", X15=" INTPTR_FORMAT, uc->X15);
st->cr();
st->print( "X16=" INTPTR_FORMAT, uc->X16);
st->print(", X17=" INTPTR_FORMAT, uc->X17);
st->print(", X18=" INTPTR_FORMAT, uc->X18);
st->print(", X19=" INTPTR_FORMAT, uc->X19);
st->cr();
st->print(", X20=" INTPTR_FORMAT, uc->X20);
st->print(", X21=" INTPTR_FORMAT, uc->X21);
st->print(", X22=" INTPTR_FORMAT, uc->X22);
st->print(", X23=" INTPTR_FORMAT, uc->X23);
st->cr();
st->print(", X24=" INTPTR_FORMAT, uc->X24);
st->print(", X25=" INTPTR_FORMAT, uc->X25);
st->print(", X26=" INTPTR_FORMAT, uc->X26);
st->print(", X27=" INTPTR_FORMAT, uc->X27);
st->print(", X28=" INTPTR_FORMAT, uc->X28);
st->cr();
st->cr();
intptr_t *sp = (intptr_t *)uc->Sp;
st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t));
st->cr();
// Note: it may be unsafe to inspect memory near pc. For example, pc may
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = (address)uc->Pc;
st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
st->cr();
}
void os::print_register_info(outputStream *st, const void *context) {
if (context == NULL) return;
const CONTEXT* uc = (const CONTEXT*)context;
st->print_cr("Register to memory mapping:");
st->cr();
// this is only for the "general purpose" registers
st->print(" X0="); print_location(st, uc->X0);
st->print(" X1="); print_location(st, uc->X1);
st->print(" X2="); print_location(st, uc->X2);
st->print(" X3="); print_location(st, uc->X3);
st->cr();
st->print(" X4="); print_location(st, uc->X4);
st->print(" X5="); print_location(st, uc->X5);
st->print(" X6="); print_location(st, uc->X6);
st->print(" X7="); print_location(st, uc->X7);
st->cr();
st->print(" X8="); print_location(st, uc->X8);
st->print(" X9="); print_location(st, uc->X9);
st->print("X10="); print_location(st, uc->X10);
st->print("X11="); print_location(st, uc->X11);
st->cr();
st->print("X12="); print_location(st, uc->X12);
st->print("X13="); print_location(st, uc->X13);
st->print("X14="); print_location(st, uc->X14);
st->print("X15="); print_location(st, uc->X15);
st->cr();
st->print("X16="); print_location(st, uc->X16);
st->print("X17="); print_location(st, uc->X17);
st->print("X18="); print_location(st, uc->X18);
st->print("X19="); print_location(st, uc->X19);
st->cr();
st->print("X20="); print_location(st, uc->X20);
st->print("X21="); print_location(st, uc->X21);
st->print("X22="); print_location(st, uc->X22);
st->print("X23="); print_location(st, uc->X23);
st->cr();
st->print("X24="); print_location(st, uc->X24);
st->print("X25="); print_location(st, uc->X25);
st->print("X26="); print_location(st, uc->X26);
st->print("X27="); print_location(st, uc->X27);
st->print("X28="); print_location(st, uc->X28);
st->cr();
}
void os::setup_fpu() {
}
bool os::supports_sse() {
return true;
}
#ifndef PRODUCT
void os::verify_stack_alignment() {
assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
}
#endif
int os::extra_bang_size_in_bytes() {
// AArch64 does not require the additional stack bang.
return 0;
}
extern "C" {
int SpinPause() {
return 0;
}
};

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP
#define OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP
static void setup_fpu();
static bool supports_sse();
static bool register_code_area(char *low, char *high) {
// Using Vectored Exception Handling
return true;
}
#endif // OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_INLINE_HPP
#define OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_INLINE_HPP
#include "runtime/os.hpp"
#endif // OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_INLINE_HPP

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_PREFETCH_WINDOWS_AARCH64_INLINE_HPP
#define OS_CPU_WINDOWS_AARCH64_PREFETCH_WINDOWS_AARCH64_INLINE_HPP
#include "runtime/prefetch.hpp"
inline void Prefetch::read (void *loc, intx interval) {
}
inline void Prefetch::write(void *loc, intx interval) {
}
#endif // OS_CPU_WINDOWS_AARCH64_PREFETCH_WINDOWS_AARCH64_INLINE_HPP

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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 "memory/metaspaceShared.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
frame JavaThread::pd_last_frame() {
assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
}
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
void* ucontext, bool isInJava) {
assert(Thread::current() == this, "caller must be current thread");
return pd_get_top_frame(fr_addr, ucontext, isInJava);
}
bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
return pd_get_top_frame(fr_addr, ucontext, isInJava);
}
bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
assert(this->is_Java_thread(), "must be JavaThread");
JavaThread* jt = (JavaThread *)this;
// If we have a last_Java_frame, then we should use it even if
// isInJava == true. It should be more reliable than CONTEXT info.
if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
*fr_addr = jt->pd_last_frame();
return true;
}
// At this point, we don't have a last_Java_frame, so
// we try to glean some information out of the CONTEXT
// if we were running Java code when SIGPROF came in.
if (isInJava) {
frame ret_frame = os::fetch_frame_from_context(ucontext);
if (ret_frame.pc() == NULL || ret_frame.sp() == NULL ) {
// CONTEXT wasn't useful
return false;
}
if (MetaspaceShared::is_in_trampoline_frame(ret_frame.pc())) {
// In the middle of a trampoline call. Bail out for safety.
// This happens rarely so shouldn't affect profiling.
return false;
}
if (!ret_frame.safe_for_sender(jt)) {
#if COMPILER2_OR_JVMCI
// C2 and JVMCI use ebp as a general register see if NULL fp helps
frame ret_frame2(ret_frame.sp(), NULL, ret_frame.pc());
if (!ret_frame2.safe_for_sender(jt)) {
// nothing else to try if the frame isn't good
return false;
}
ret_frame = ret_frame2;
#else
// nothing else to try if the frame isn't good
return false;
#endif // COMPILER2_OR_JVMCI
}
*fr_addr = ret_frame;
return true;
}
// nothing else to try
return false;
}
void JavaThread::cache_global_variables() { }

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_THREAD_WINDOWS_AARCH64_HPP
#define OS_CPU_WINDOWS_AARCH64_THREAD_WINDOWS_AARCH64_HPP
private:
#ifdef ASSERT
// spill stack holds N callee-save registers at each Java call and
// grows downwards towards limit
// we need limit to check we have space for a spill and base so we
// can identify all live spill frames at GC (eventually)
address _spill_stack;
address _spill_stack_base;
address _spill_stack_limit;
#endif // ASSERT
void pd_initialize() {
_anchor.clear();
}
frame pd_last_frame();
public:
static ByteSize last_Java_fp_offset() {
return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_fp_offset();
}
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
bool isInJava);
bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
private:
bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
public:
static Thread *aarch64_get_thread_helper() {
return Thread::current();
}
#endif // OS_CPU_WINDOWS_AARCH64_THREAD_WINDOWS_AARCH64_HPP

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_UNWIND_WINDOWS_AARCH64_HPP
#define OS_CPU_WINDOWS_AARCH64_UNWIND_WINDOWS_AARCH64_HPP
typedef unsigned char UBYTE;
#if _MSC_VER < 1700
/* Not needed for VS2012 compiler, comes from winnt.h. */
#define UNW_FLAG_EHANDLER 0x01
#define UNW_FLAG_UHANDLER 0x02
#define UNW_FLAG_CHAININFO 0x04
#endif
// See https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling#xdata-records
typedef struct _UNWIND_INFO_EH_ONLY {
DWORD FunctionLength : 18;
DWORD Version : 2;
DWORD X : 1; // = 1
DWORD E : 1; // = 1
DWORD EpilogCount : 5; // = 0
DWORD CodeWords : 5; // = 1
DWORD UnwindCode0 : 8;
DWORD UnwindCode1 : 8;
DWORD UnwindCode2 : 8;
DWORD UnwindCode3 : 8;
DWORD ExceptionHandler;
} UNWIND_INFO_EH_ONLY, *PUNWIND_INFO_EH_ONLY;
/*
typedef struct _RUNTIME_FUNCTION {
DWORD BeginAddress;
union {
DWORD UnwindData;
struct {
DWORD Flag : 2;
DWORD FunctionLength : 11;
DWORD RegF : 3;
DWORD RegI : 4;
DWORD H : 1;
DWORD CR : 2;
DWORD FrameSize : 9;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
*/
#if _MSC_VER < 1700
/* Not needed for VS2012 compiler, comes from winnt.h. */
typedef struct _DISPATCHER_CONTEXT {
ULONG64 ControlPc;
ULONG64 ImageBase;
PRUNTIME_FUNCTION FunctionEntry;
ULONG64 EstablisherFrame;
ULONG64 TargetIp;
PCONTEXT ContextRecord;
// PEXCEPTION_ROUTINE LanguageHandler;
char * LanguageHandler; // double dependency problem
PVOID HandlerData;
} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
#endif
#if _MSC_VER < 1500
/* Not needed for VS2008 compiler, comes from winnt.h. */
typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
IN PEXCEPTION_RECORD ExceptionRecord,
IN ULONG64 EstablisherFrame,
IN OUT PCONTEXT ContextRecord,
IN OUT PDISPATCHER_CONTEXT DispatcherContext
);
#endif
#endif // OS_CPU_WINDOWS_AARCH64_UNWIND_WINDOWS_AARCH64_HPP

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
#ifndef OS_CPU_WINDOWS_AARCH64_VMSTRUCTS_WINDOWS_AARCH64_HPP
#define OS_CPU_WINDOWS_AARCH64_VMSTRUCTS_WINDOWS_AARCH64_HPP
// These are the OS and CPU-specific fields, types and integer
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
\
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
declare_unsigned_integer_type(OSThread::thread_id_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_WINDOWS_AARCH64_VMSTRUCTS_WINDOWS_AARCH64_HPP

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2020, Microsoft Corporation. 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 "runtime/os.hpp"
#include "runtime/vm_version.hpp"
int VM_Version::get_current_sve_vector_length() {
assert(_features & CPU_SVE, "should not call this");
ShouldNotReachHere();
return 0;
}
int VM_Version::set_and_get_current_sve_vector_lenght(int length) {
assert(_features & CPU_SVE, "should not call this");
ShouldNotReachHere();
return 0;
}
void VM_Version::get_os_cpu_info() {
if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) _features |= CPU_CRC32;
if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) _features |= CPU_AES | CPU_SHA1 | CPU_SHA2;
if (IsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE)) _features |= CPU_ASIMD;
// No check for CPU_PMULL, CPU_SVE, CPU_SVE2
__int64 dczid_el0 = _ReadStatusReg(0x5807 /* ARM64_DCZID_EL0 */);
if (!(dczid_el0 & 0x10)) {
_zva_length = 4 << (dczid_el0 & 0xf);
}
{
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
DWORD returnLength = 0;
// See https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation
GetLogicalProcessorInformation(NULL, &returnLength);
assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected return from GetLogicalProcessorInformation");
buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)os::malloc(returnLength, mtInternal);
BOOL rc = GetLogicalProcessorInformation(buffer, &returnLength);
assert(rc, "Unexpected return from GetLogicalProcessorInformation");
_icache_line_size = _dcache_line_size = -1;
for (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer; ptr < buffer + returnLength / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ptr++) {
switch (ptr->Relationship) {
case RelationCache:
// Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache.
PCACHE_DESCRIPTOR Cache = &ptr->Cache;
if (Cache->Level == 1) {
_icache_line_size = _dcache_line_size = Cache->LineSize;
}
break;
}
}
os::free(buffer);
}
{
char* buf = ::getenv("PROCESSOR_IDENTIFIER");
if (buf && strstr(buf, "Ampere(TM)") != NULL) {
_cpu = CPU_AMCC;
} else if (buf && strstr(buf, "Cavium Inc.") != NULL) {
_cpu = CPU_CAVIUM;
} else {
log_info(os)("VM_Version: unknown CPU model");
}
if (_cpu) {
SYSTEM_INFO si;
GetSystemInfo(&si);
_model = si.wProcessorLevel;
_variant = si.wProcessorRevision / 0xFF;
_revision = si.wProcessorRevision & 0xFF;
}
}
}

View File

@ -354,6 +354,41 @@ address os::current_stack_pointer() {
}
#endif
bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) {
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
address addr = (address) exceptionRecord->ExceptionInformation[1];
if (Interpreter::contains(pc)) {
*fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
if (!fr->is_first_java_frame()) {
// get_frame_at_stack_banging_point() is only called when we
// have well defined stacks so java_sender() calls do not need
// to assert safe_for_sender() first.
*fr = fr->java_sender();
}
} else {
// more complex code with compiled code
assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
CodeBlob* cb = CodeCache::find_blob(pc);
if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
// Not sure where the pc points to, fallback to default
// stack overflow handling
return false;
} else {
// in compiled code, the stack banging is performed just after the return pc
// has been pushed on the stack
intptr_t* fp = (intptr_t*)exceptionInfo->ContextRecord->REG_FP;
intptr_t* sp = (intptr_t*)exceptionInfo->ContextRecord->REG_SP;
*fr = frame(sp + 1, fp, (address)*sp);
if (!fr->is_java_frame()) {
// See java_sender() comment above.
*fr = fr->java_sender();
}
}
}
assert(fr->is_java_frame(), "Safety check");
return true;
}
#ifndef AMD64
intptr_t* _get_previous_fp() {

View File

@ -32,7 +32,13 @@
// lookups for that information all over the place.
struct G1HeapRegionAttr {
public:
#if defined(_M_ARM64)&& defined(_MSC_VER) && _MSC_VER <= 1927
// workaround for MSCV ARM64 bug
// https://developercommunity.visualstudio.com/content/problem/1079221/arm64-bad-code-generation-around-signed-char-arith.html
typedef int32_t region_type_t;
#else
typedef int8_t region_type_t;
#endif
typedef uint8_t needs_remset_update_t;
private:

View File

@ -93,7 +93,7 @@
static jint CurrentVersion = JNI_VERSION_10;
#ifdef _WIN32
#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
#endif
@ -3841,11 +3841,11 @@ static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
jint result = JNI_ERR;
// On Windows, let CreateJavaVM run with SEH protection
#ifdef _WIN32
#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
__try {
#endif
result = JNI_CreateJavaVM_inner(vm, penv, args);
#ifdef _WIN32
#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
} __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
// Nothing to do.
}
@ -3913,11 +3913,11 @@ static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) {
jint JNICALL jni_DestroyJavaVM(JavaVM *vm) {
jint result = JNI_ERR;
// On Windows, we need SEH protection
#ifdef _WIN32
#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
__try {
#endif
result = jni_DestroyJavaVM_inner(vm);
#ifdef _WIN32
#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
} __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
// Nothing to do.
}

View File

@ -136,4 +136,8 @@ inline int g_isfinite(jdouble f) { return _finite(f); }
// Alignment
#define ATTRIBUTE_ALIGNED(x) __declspec(align(x))
#ifdef _M_ARM64
#define USE_VECTORED_EXCEPTION_HANDLING
#endif
#endif // SHARE_UTILITIES_GLOBALDEFINITIONS_VISCPP_HPP

View File

@ -569,6 +569,8 @@ GetJavaProperties(JNIEnv* env)
sprops.os_arch = "amd64";
#elif defined(_X86_)
sprops.os_arch = "x86";
#elif defined(_M_ARM64)
sprops.os_arch = "aarch64";
#else
sprops.os_arch = "unknown";
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2020, 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
@ -43,7 +43,7 @@ public class AttachProviderImpl extends HotSpotAttachProvider {
"This provider is not supported on this version of Windows");
}
String arch = System.getProperty("os.arch");
if (!arch.equals("x86") && !arch.equals("amd64")) {
if (!arch.equals("x86") && !arch.equals("amd64") && !arch.equals("aarch64")) {
throw new RuntimeException(
"This provider is not supported on this processor architecture");
}

View File

@ -530,8 +530,10 @@ public class HotSpotAgent {
machDesc = new MachineDescriptionIntelX86();
} else if (cpu.equals("amd64")) {
machDesc = new MachineDescriptionAMD64();
} else if (cpu.equals("aarch64")) {
machDesc = new MachineDescriptionAArch64();
} else {
throw new DebuggerException("Win32 supported under x86 and amd64 only");
throw new DebuggerException("Win32 supported under x86, amd64 and aarch64 only");
}
// Note we do not use a cache for the local debugger in server

View File

@ -28,8 +28,10 @@ import java.io.*;
import java.net.*;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.debugger.amd64.*;
import sun.jvm.hotspot.debugger.x86.*;
import sun.jvm.hotspot.debugger.windbg.aarch64.*;
import sun.jvm.hotspot.debugger.windbg.amd64.*;
import sun.jvm.hotspot.debugger.windbg.x86.*;
import sun.jvm.hotspot.debugger.win32.coff.*;
@ -113,6 +115,8 @@ public class WindbgDebuggerLocal extends DebuggerBase implements WindbgDebugger
threadFactory = new WindbgX86ThreadFactory(this);
} else if (cpu.equals("amd64")) {
threadFactory = new WindbgAMD64ThreadFactory(this);
} else if (cpu.equals("aarch64")) {
threadFactory = new WindbgAARCH64ThreadFactory(this);
}
if (useCache) {

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
package sun.jvm.hotspot.debugger.windbg.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.debugger.windbg.*;
class WindbgAARCH64Thread implements ThreadProxy {
private WindbgDebugger debugger;
private long sysId;
private boolean gotID;
private long id;
// The address argument must be the address of the OSThread::_thread_id
WindbgAARCH64Thread(WindbgDebugger debugger, Address addr) {
this.debugger = debugger;
this.sysId = (long)addr.getCIntegerAt(0, 4, true);
gotID = false;
}
WindbgAARCH64Thread(WindbgDebugger debugger, long sysId) {
this.debugger = debugger;
this.sysId = sysId;
gotID = false;
}
public ThreadContext getContext() throws IllegalThreadStateException {
long[] data = debugger.getThreadIntegerRegisterSet(getThreadID());
WindbgAARCH64ThreadContext context = new WindbgAARCH64ThreadContext(debugger);
for (int i = 0; i < data.length; i++) {
context.setRegister(i, data[i]);
}
return context;
}
public boolean canSetContext() throws DebuggerException {
return false;
}
public void setContext(ThreadContext thrCtx)
throws IllegalThreadStateException, DebuggerException {
throw new DebuggerException("Unimplemented");
}
public boolean equals(Object obj) {
if ((obj == null) || !(obj instanceof WindbgAARCH64Thread)) {
return false;
}
return (((WindbgAARCH64Thread) obj).getThreadID() == getThreadID());
}
public int hashCode() {
return (int) getThreadID();
}
public String toString() {
return Long.toString(getThreadID());
}
/** Retrieves the thread ID of this thread by examining the Thread
Information Block. */
private long getThreadID() {
if (!gotID) {
id = debugger.getThreadIdFromSysId(sysId);
}
return id;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
package sun.jvm.hotspot.debugger.windbg.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.debugger.windbg.*;
class WindbgAARCH64ThreadContext extends AARCH64ThreadContext {
private WindbgDebugger debugger;
public WindbgAARCH64ThreadContext(WindbgDebugger debugger) {
super();
this.debugger = debugger;
}
public void setRegisterAsAddress(int index, Address value) {
setRegister(index, debugger.getAddressValue(value));
}
public Address getRegisterAsAddress(int index) {
return debugger.newAddress(getRegister(index));
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
package sun.jvm.hotspot.debugger.windbg.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.windbg.*;
public class WindbgAARCH64ThreadFactory implements WindbgThreadFactory {
private WindbgDebugger debugger;
public WindbgAARCH64ThreadFactory(WindbgDebugger debugger) {
this.debugger = debugger;
}
public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) {
return new WindbgAARCH64Thread(debugger, threadIdentifierAddr);
}
public ThreadProxy createThreadWrapper(long id) {
return new WindbgAARCH64Thread(debugger, id);
}
}

View File

@ -28,8 +28,9 @@ import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.runtime.win32_amd64.Win32AMD64JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.win32_x86.Win32X86JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.win32_amd64.Win32AMD64JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.win32_aarch64.Win32AARCH64JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.linux_x86.LinuxX86JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.linux_aarch64.LinuxAARCH64JavaThreadPDAccess;
@ -99,6 +100,8 @@ public class Threads {
access = new Win32X86JavaThreadPDAccess();
} else if (cpu.equals("amd64")) {
access = new Win32AMD64JavaThreadPDAccess();
} else if (cpu.equals("aarch64")) {
access = new Win32AARCH64JavaThreadPDAccess();
}
} else if (os.equals("linux")) {
if (cpu.equals("x86")) {

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, Microsoft Corporation. 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.
*
*/
package sun.jvm.hotspot.runtime.win32_aarch64;
import java.io.*;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.runtime.aarch64.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.utilities.Observable;
import sun.jvm.hotspot.utilities.Observer;
/** This class is only public to allow using the VMObjectFactory to
instantiate these.
*/
public class Win32AARCH64JavaThreadPDAccess implements JavaThreadPDAccess {
private static AddressField lastJavaFPField;
private static AddressField osThreadField;
// Field from OSThread
private static Field osThreadThreadIDField;
// This is currently unneeded but is being kept in case we change
// the currentFrameGuess algorithm
private static final long GUESS_SCAN_RANGE = 128 * 1024;
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("JavaThread");
osThreadField = type.getAddressField("_osthread");
Type anchorType = db.lookupType("JavaFrameAnchor");
lastJavaFPField = anchorType.getAddressField("_last_Java_fp");
Type osThreadType = db.lookupType("OSThread");
osThreadThreadIDField = osThreadType.getField("_thread_id");
}
public Address getLastJavaFP(Address addr) {
return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset()));
}
public Address getLastJavaPC(Address addr) {
return null;
}
public Address getBaseOfStackPointer(Address addr) {
return null;
}
public Frame getLastFramePD(JavaThread thread, Address addr) {
Address fp = thread.getLastJavaFP();
if (fp == null) {
return null; // no information
}
Address pc = thread.getLastJavaPC();
if ( pc != null ) {
return new AARCH64Frame(thread.getLastJavaSP(), fp, pc);
} else {
return new AARCH64Frame(thread.getLastJavaSP(), fp);
}
}
public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
return new AARCH64RegisterMap(thread, updateMap);
}
public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
ThreadProxy t = getThreadProxy(addr);
AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext();
AARCH64CurrentFrameGuess guesser = new AARCH64CurrentFrameGuess(context, thread);
if (!guesser.run(GUESS_SCAN_RANGE)) {
return null;
}
if (guesser.getPC() == null) {
return new AARCH64Frame(guesser.getSP(), guesser.getFP());
} else {
return new AARCH64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
}
}
public void printThreadIDOn(Address addr, PrintStream tty) {
tty.print(getThreadProxy(addr));
}
public void printInfoOn(Address threadAddr, PrintStream tty) {
}
public Address getLastSP(Address addr) {
ThreadProxy t = getThreadProxy(addr);
AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext();
return context.getRegisterAsAddress(AARCH64ThreadContext.SP);
}
public ThreadProxy getThreadProxy(Address addr) {
// Addr is the address of the JavaThread.
// Fetch the OSThread (for now and for simplicity, not making a
// separate "OSThread" class in this package)
Address osThreadAddr = osThreadField.getValue(addr);
// Get the address of the thread_id within the OSThread
Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset());
JVMDebugger debugger = VM.getVM().getDebugger();
return debugger.getThreadForIdentifierAddress(threadIdAddr);
}
}

View File

@ -36,6 +36,9 @@
#elif _M_AMD64
#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
#elif _M_ARM64
#include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h"
#define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG
#else
#error "SA windbg back-end is not supported for your cpu!"
#endif