Mock Version: 3.5 Mock Version: 3.5 Mock Version: 3.5 ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -bs --noclean --target loongarch64 --nodeps /builddir/build/SPECS/java-17-openjdk-portable.spec'], chrootPath='/var/lib/mock/dist-an8.9-build-413580-72834/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=86400uid=976gid=135user='mockbuild'nspawn_args=[]unshare_net=TrueprintOutput=False) Executing command: ['bash', '--login', '-c', '/usr/bin/rpmbuild -bs --noclean --target loongarch64 --nodeps /builddir/build/SPECS/java-17-openjdk-portable.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'} and shell False Building target platforms: loongarch64 Building for target loongarch64 Wrote: /builddir/build/SRPMS/java-17-openjdk-portable-17.0.14.0.7-1.0.2.an8.src.rpm Child return code was: 0 ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -bb --noclean --target loongarch64 --nodeps /builddir/build/SPECS/java-17-openjdk-portable.spec'], chrootPath='/var/lib/mock/dist-an8.9-build-413580-72834/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=86400uid=976gid=135user='mockbuild'nspawn_args=[]unshare_net=TrueprintOutput=False) Executing command: ['bash', '--login', '-c', '/usr/bin/rpmbuild -bb --noclean --target loongarch64 --nodeps /builddir/build/SPECS/java-17-openjdk-portable.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'} and shell False Building target platforms: loongarch64 Building for target loongarch64 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.wKJi8j + umask 022 + cd /builddir/build/BUILD + echo 'Preparing (Red_Hat-17.0.14.0.7-1)' Preparing (Red_Hat-17.0.14.0.7-1) + echo 'CPU: loongarch64, arch install directory: loongarch64, SystemTap install directory: loongarch64' CPU: loongarch64, arch install directory: loongarch64, SystemTap install directory: loongarch64 + '[' 1 -eq 0 -o 1 -eq 1 ']' + echo 'include_normal_build is 1' include_normal_build is 1 + '[' 1 -eq 0 -o 1 -eq 1 ']' + echo 'include_debug_build is 1' include_debug_build is 1 + '[' 1 -eq 0 -o 1 -eq 1 ']' + echo 'include_fastdebug_build is 1' include_fastdebug_build is 1 + '[' 1 -eq 0 -a 1 -eq 0 -a 1 -eq 0 ']' + export XZ_OPT=-T0 + XZ_OPT=-T0 + cd /builddir/build/BUILD + rm -rf java-17-openjdk-17.0.14.0.7-1.0.2.an8.loongarch64 + /usr/bin/mkdir -p java-17-openjdk-17.0.14.0.7-1.0.2.an8.loongarch64 + cd java-17-openjdk-17.0.14.0.7-1.0.2.an8.loongarch64 + /usr/bin/xz -dc /builddir/build/SOURCES/openjdk-17.0.14+7.tar.xz + /usr/bin/tar -xof - + STATUS=0 + '[' 0 -ne 0 ']' + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . ++ expr length 00000001 ~/build/BUILD/java-17-openjdk-17.0.14.0.7-1.0.2.an8.loongarch64/jdk-17.0.14+7 ~/build/BUILD/java-17-openjdk-17.0.14.0.7-1.0.2.an8.loongarch64 Patch #1 (rh1648242-accessible_toolkit_crash_do_not_break_jvm.patch): + prioritylength=8 + '[' 8 -ne 8 ']' + pushd jdk-17.0.14+7 + echo 'Patch #1 (rh1648242-accessible_toolkit_crash_do_not_break_jvm.patch):' + /usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 patching file src/java.desktop/share/classes/java/awt/Toolkit.java Hunk #1 succeeded at 602 (offset 7 lines). Patch #6 (rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-devel.patch): + echo 'Patch #6 (rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-devel.patch):' + /usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 patching file src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java Hunk #1 succeeded at 46 (offset -2 lines). Patch #1001 (fips-17u-e893be00150.patch): + echo 'Patch #1001 (fips-17u-e893be00150.patch):' + /usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 patching file make/autoconf/build-aux/pkg.m4 patching file make/autoconf/lib-sysconf.m4 patching file make/autoconf/libraries.m4 patching file make/autoconf/spec.gmk.in patching file make/modules/java.base/Gendata.gmk patching file make/modules/java.base/Lib.gmk patching file src/java.base/share/classes/com/sun/crypto/provider/HmacPKCS12PBECore.java patching file src/java.base/share/classes/com/sun/crypto/provider/PBES2Core.java patching file src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java patching file src/java.base/share/classes/java/security/Security.java patching file src/java.base/share/classes/java/security/SystemConfigurator.java patching file src/java.base/share/classes/jdk/internal/access/JavaSecuritySystemConfiguratorAccess.java patching file src/java.base/share/classes/jdk/internal/access/SharedSecrets.java patching file src/java.base/share/classes/module-info.java patching file src/java.base/share/classes/sun/security/provider/SunEntries.java patching file src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java patching file src/java.base/share/classes/sun/security/util/PBEUtil.java patching file src/java.base/share/conf/security/java.security patching file src/java.base/share/conf/security/nss.fips.cfg.in patching file src/java.base/share/lib/security/default.policy patching file src/java.base/share/native/libsystemconf/systemconf.c patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSTokenLoginHandler.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PBECipher.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS2.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java Hunk #5 succeeded at 1713 (offset 36 lines). Hunk #6 succeeded at 1999 (offset 36 lines). patching file src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java patching file src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c Hunk #1 succeeded at 1518 (offset 3 lines). Hunk #2 succeeded at 1665 (offset 3 lines). Hunk #3 succeeded at 1687 (offset 3 lines). Hunk #4 succeeded at 1774 (offset 3 lines). Hunk #5 succeeded at 1842 (offset 3 lines). patching file src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c Hunk #2 succeeded at 544 (offset 11 lines). Hunk #3 succeeded at 585 (offset 11 lines). Hunk #4 succeeded at 631 (offset 11 lines). Hunk #5 succeeded at 672 (offset 11 lines). Hunk #6 succeeded at 713 (offset 11 lines). patching file src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h patching file src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java patching file test/jdk/sun/security/pkcs11/Cipher/PBECipher.java patching file test/jdk/sun/security/pkcs11/KeyStore/ImportKeyToP12.java patching file test/jdk/sun/security/pkcs11/Mac/PBAMac.java patching file test/jdk/sun/security/pkcs11/SecretKeyFactory/TestPBKD.java patching file test/jdk/sun/security/pkcs11/fips/NssdbPin.java patching file test/jdk/sun/security/pkcs11/fips/VerifyMissingAttributes.java Patch #1000 (rh1648249-add_commented_out_nss_cfg_provider_to_java_security.patch): + echo 'Patch #1000 (rh1648249-add_commented_out_nss_cfg_provider_to_java_security.patch):' + /usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 patching file src/java.base/share/conf/security/java.security Hunk #1 succeeded at 81 (offset 3 lines). Patch #600 (rh1750419-redhat_alt_java.patch): + echo 'Patch #600 (rh1750419-redhat_alt_java.patch):' + /usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 patching file make/modules/java.base/Launcher.gmk patching file src/java.base/share/native/launcher/alt_main.h patching file src/java.base/share/native/launcher/main.c Patch #3000 (3000-Add-loongarch64-support.patch): + echo 'Patch #3000 (3000-Add-loongarch64-support.patch):' + /usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 can't find file to patch at input line 38 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |commit 98016d6f75ec4b8b58ad30ae75609a47f93fc54a |Merge: 789ba0f24a3 c5c90ffa45d |Author: aoqi |Date: Sat Feb 8 17:20:42 2025 +0800 | | Merge | | |commit 789ba0f24a3fcaf64609eaa065845861c8de83d8 |Merge: 06f00bc81c7 bdc07d202a9 |Author: aoqi |Date: Sat Feb 8 17:18:33 2025 +0800 | | Merge | | |commit 06f00bc81c7d0dc3e83363fd2b00dd6b03f4d62a |Merge: 15f5afd71be eed263c8077 |Author: aoqi |Date: Thu Oct 17 10:41:06 2024 +0800 | | Merge | | |commit 15f5afd71be34dd61b9044dff02e004eb2bb34b6 |Author: loongson-jvm |Date: Thu Oct 17 10:27:02 2024 +0800 | | Update (2024.10.17) | | 11541: Prevent load reorder of VarHandle::getOpaque | 34943: 8338748: [17u,21u] Test Disconnect.java compile error: cannot find symbol after JDK-8299813 | |diff --git a/src/hotspot/cpu/loongarch/loongarch_64.ad b/src/hotspot/cpu/loongarch/loongarch_64.ad |index 0c6516fc1d5..7e01822e0e9 100644 |--- a/src/hotspot/cpu/loongarch/loongarch_64.ad |+++ b/src/hotspot/cpu/loongarch/loongarch_64.ad -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored patching file src/hotspot/share/adlc/formssel.cpp patching file src/hotspot/share/gc/shared/c2/barrierSetC2.cpp patching file src/hotspot/share/opto/classes.hpp patching file src/hotspot/share/opto/compile.cpp patching file src/hotspot/share/opto/memnode.cpp patching file src/hotspot/share/opto/memnode.hpp patching file src/hotspot/share/runtime/vmStructs.cpp patching file test/jdk/java/nio/channels/DatagramChannel/Disconnect.java Reversed (or previously applied) patch detected! Assume -R? [n] Apply anyway? [n] Skipping patch. 2 out of 2 hunks ignored -- saving rejects to file test/jdk/java/nio/channels/DatagramChannel/Disconnect.java.rej can't find file to patch at input line 296 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit 76487ad345f72808f2dbed45bde1fbe52f91f7b0 |Merge: c6583c8c5cb 33cd4b41b38 |Author: aoqi |Date: Wed Oct 16 18:04:00 2024 +0800 | | Merge | | |commit c6583c8c5cbd49c33df3dc3e65eb9644b8755bfc |Author: loongson-jvm |Date: Wed Oct 16 18:02:45 2024 +0800 | | Update (2024.10.16) | | 34860: [MIPS] build with gtest failed after JDK-8300806 | |diff --git a/src/hotspot/cpu/mips/register_mips.hpp b/src/hotspot/cpu/mips/register_mips.hpp |index 4f74717c24f..c2124538a0f 100644 |--- a/src/hotspot/cpu/mips/register_mips.hpp |+++ b/src/hotspot/cpu/mips/register_mips.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 353 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit 6d0dc6b25f6441f3d37672ea377cc9c75e958693 |Merge: 0389c6ca1b0 03cbfaa733b |Author: aoqi |Date: Wed Oct 16 17:28:09 2024 +0800 | | Merge | | |commit 0389c6ca1b08f91f75c63ed72edbe16abe2210c0 |Merge: 00ca185ba7e 833f65ecb30 |Author: aoqi |Date: Fri Jul 26 14:48:30 2024 +0800 | | Merge | | |commit 00ca185ba7eaf8a3bf9412bad9305fe742c3378c |Merge: 4cc0b3e9764 c1c901179e8 |Author: aoqi |Date: Fri Jul 26 14:47:58 2024 +0800 | | Merge | | |commit 4cc0b3e97643ac46a8e64ea4f3c62510fe49e10a |Author: loongson-jvm |Date: Fri Jul 26 11:32:26 2024 +0800 | | Update (2024.07.26) | | 33980: Fix generate__kernel_rem_pio2 | |diff --git a/src/hotspot/cpu/loongarch/macroAssembler_loongarch_trig.cpp b/src/hotspot/cpu/loongarch/macroAssembler_loongarch_trig.cpp |index 63b5b0da7e7..9c74be2dbd3 100644 |--- a/src/hotspot/cpu/loongarch/macroAssembler_loongarch_trig.cpp |+++ b/src/hotspot/cpu/loongarch/macroAssembler_loongarch_trig.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 3 out of 3 hunks ignored can't find file to patch at input line 399 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit c5070ec1c962df668c876c96554747da28c35520 |Merge: c53840e66c9 c9d83d392f3 |Author: aoqi |Date: Fri Jul 26 09:24:27 2024 +0800 | | Merge | | |commit c53840e66c908f283ba8cf2b167cb3f5d68008fd |Author: loongson-jvm |Date: Fri Apr 26 18:35:30 2024 +0800 | | Update (2024.04.26, 2nd) | | 34058: LA port of 8322122: Enhance generation of addresses | |diff --git a/src/hotspot/cpu/loongarch/c1_LIRGenerator_loongarch_64.cpp b/src/hotspot/cpu/loongarch/c1_LIRGenerator_loongarch_64.cpp |index fedcc547d48..28298dcc375 100644 |--- a/src/hotspot/cpu/loongarch/c1_LIRGenerator_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/c1_LIRGenerator_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 441 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit af76bcbea0b9c4b802af19ba09b062ef510e1d97 |Merge: 38b11e8e016 1c40f899c9c |Author: aoqi |Date: Fri Apr 26 18:25:16 2024 +0800 | | Merge | | |commit 38b11e8e016687f029cad4c183de4aaaf49020d0 |Author: loongson-jvm |Date: Fri Apr 26 18:24:13 2024 +0800 | | Update (2024.04.26) | | 33160: LA port of 8261837: SIGSEGV in ciVirtualCallTypeData::translate_from | |diff --git a/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp b/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp |index 8665c2d8881..cde86e3b3a1 100644 |--- a/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 4 out of 4 hunks ignored can't find file to patch at input line 494 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp b/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp |index 9f1bf88c605..cb8ad8a359c 100644 |--- a/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 3 out of 3 hunks ignored can't find file to patch at input line 656 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit a41749611bd86a21d5021378bc8b0cf6c9caa1f7 |Merge: 202b0ef58d9 39c9e9d2bf8 |Author: aoqi |Date: Fri Apr 26 18:07:56 2024 +0800 | | Merge | |diff --cc src/jdk.hotspot.agent/linux/native/libsaproc/ps_proc.c |index d991f29cbb1,1101b999961..301c9f9f26e |--- a/src/jdk.hotspot.agent/linux/native/libsaproc/ps_proc.c |+++ b/src/jdk.hotspot.agent/linux/native/libsaproc/ps_proc.c |@@@ -144,8 -134,17 +140,17 @@@ static bool process_get_lwp_regs(struc | #define PTRACE_GETREGS_REQ PT_GETREGS | #endif | |- #if defined(PTRACE_GETREGS_REQ) && !defined(loongarch64) |- if (ptrace_getregs(PTRACE_GETREGS_REQ, pid, user, NULL) < 0) { |+ #if defined(PTRACE_GETREGSET) |+ struct iovec iov; |+ iov.iov_base = user; |+ iov.iov_len = sizeof(*user); |+ if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, (void*) &iov) < 0) { |+ print_debug("ptrace(PTRACE_GETREGSET, ...) failed for lwp %d\n", pid); |+ return false; |+ } |+ return true; | -#elif defined(PTRACE_GETREGS_REQ) |++#elif defined(PTRACE_GETREGS_REQ) && !defined(loongarch64) |+ if (ptrace(PTRACE_GETREGS_REQ, pid, NULL, user) < 0) { | print_debug("ptrace(PTRACE_GETREGS, ...) failed for lwp(%d) errno(%d) \"%s\"\n", pid, | errno, strerror(errno)); | return false; |diff --cc test/jdk/sun/security/pkcs11/PKCS11Test.java |index 99295d779c5,9c61ffe47cf..fdcac49a58c |--- a/test/jdk/sun/security/pkcs11/PKCS11Test.java |+++ b/test/jdk/sun/security/pkcs11/PKCS11Test.java |@@@ -689,32 -602,27 +608,30 @@@ public abstract class PKCS11Test | } | | osMap = new HashMap<>(); |- osMap.put("Linux-i386-32", new String[] { |+ osMap.put("Linux-i386-32", new String[]{ | "/usr/lib/i386-linux-gnu/", | "/usr/lib32/", |- "/usr/lib/" }); |- osMap.put("Linux-amd64-64", new String[] { |+ "/usr/lib/"}); |+ osMap.put("Linux-amd64-64", new String[]{ | "/usr/lib/x86_64-linux-gnu/", | "/usr/lib/x86_64-linux-gnu/nss/", |- "/usr/lib64/" }); |- osMap.put("Linux-ppc64-64", new String[] { "/usr/lib64/" }); |- osMap.put("Linux-ppc64le-64", new String[] { "/usr/lib64/" }); |+ "/usr/lib64/"}); |+ osMap.put("Linux-ppc64-64", new String[]{"/usr/lib64/"}); | + osMap.put("Linux-mips64el-64", new String[]{"/usr/lib64/"}); | + osMap.put("Linux-loongarch64-64", new String[]{"/usr/lib/loongarch64-linux-gnu/", | + "/usr/lib64/" }); |- osMap.put("Linux-s390x-64", new String[] { "/usr/lib64/" }); |- osMap.put("Windows-x86-32", new String[] {}); |- osMap.put("Windows-amd64-64", new String[] {}); |- osMap.put("MacOSX-x86_64-64", new String[] {}); |- osMap.put("Linux-arm-32", new String[] { |+ osMap.put("Linux-ppc64le-64", new String[]{"/usr/lib64/"}); |+ osMap.put("Linux-s390x-64", new String[]{"/usr/lib64/"}); |+ osMap.put("Windows-x86-32", new String[]{}); |+ osMap.put("Windows-amd64-64", new String[]{}); |+ osMap.put("MacOSX-x86_64-64", new String[]{}); |+ osMap.put("Linux-arm-32", new String[]{ | "/usr/lib/arm-linux-gnueabi/nss/", |- "/usr/lib/arm-linux-gnueabihf/nss/" }); |- // Exclude linux-aarch64 at the moment until the following bug is fixed: |- // 8296631: NSS tests failing on OL9 linux-aarch64 hosts |- // osMap.put("Linux-aarch64-64", new String[] { |- // "/usr/lib/aarch64-linux-gnu/", |- // "/usr/lib/aarch64-linux-gnu/nss/", |- // "/usr/lib64/" }); |+ "/usr/lib/arm-linux-gnueabihf/nss/"}); |+ osMap.put("Linux-aarch64-64", new String[] { |+ "/usr/lib/aarch64-linux-gnu/", |+ "/usr/lib/aarch64-linux-gnu/nss/", |+ "/usr/lib64/" }); | return osMap; | } | | |commit 202b0ef58d9311f534f9bd10606e0e45accf92b7 |Merge: 5f77562ba03 ca760c86642 |Author: aoqi |Date: Fri Jan 26 16:40:44 2024 +0800 | | Merge | | |commit 5f77562ba03d1713d3615d84f8a3229a39258d41 |Author: loongson-jvm |Date: Fri Jan 26 16:39:46 2024 +0800 | | Update (2024.01.26, 2nd) | | 24527: Fix a typo for invokeinterface in #8604 | |diff --git a/src/hotspot/cpu/loongarch/templateTable_loongarch_64.cpp b/src/hotspot/cpu/loongarch/templateTable_loongarch_64.cpp |index c0d1daea305..2474f90c247 100644 |--- a/src/hotspot/cpu/loongarch/templateTable_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/templateTable_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 689 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit fe193bcbc1cb971738db7fa2d38a9d69456a2c6c |Author: loongson-jvm |Date: Fri Jan 26 16:29:44 2024 +0800 | | Update (2024.01.26) | | 29494: Fix assert(_succ != current) failed: invariant | 30985: Insert acqure membar for load-exclusive with acquire | 26386: Fix atomic ops with memory order relaxed | 28135: Add linux-loongarch64 to CheckedFeatures.notImplemented | 33199: GHA testing failed | |diff --git a/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp b/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp |index 2ddf19a6e5a..8665c2d8881 100644 |--- a/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 712 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/c1_MacroAssembler_loongarch_64.cpp b/src/hotspot/cpu/loongarch/c1_MacroAssembler_loongarch_64.cpp |index 56c6281d415..0221951342a 100644 |--- a/src/hotspot/cpu/loongarch/c1_MacroAssembler_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/c1_MacroAssembler_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 737 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/c2_MacroAssembler_loongarch.cpp b/src/hotspot/cpu/loongarch/c2_MacroAssembler_loongarch.cpp |index ef520a39ff3..0c91c74d63e 100644 |--- a/src/hotspot/cpu/loongarch/c2_MacroAssembler_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/c2_MacroAssembler_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 4 out of 4 hunks ignored can't find file to patch at input line 777 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/gc/shenandoah/shenandoahBarrierSetAssembler_loongarch.cpp b/src/hotspot/cpu/loongarch/gc/shenandoah/shenandoahBarrierSetAssembler_loongarch.cpp |index 7cf552e283a..e90623fe989 100644 |--- a/src/hotspot/cpu/loongarch/gc/shenandoah/shenandoahBarrierSetAssembler_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/gc/shenandoah/shenandoahBarrierSetAssembler_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 805 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/gc/z/z_loongarch_64.ad b/src/hotspot/cpu/loongarch/gc/z/z_loongarch_64.ad |index 59656e75376..262cfd50b65 100644 |--- a/src/hotspot/cpu/loongarch/gc/z/z_loongarch_64.ad |+++ b/src/hotspot/cpu/loongarch/gc/z/z_loongarch_64.ad -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 833 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp b/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp |index fa65d10765c..9f1bf88c605 100644 |--- a/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 862 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/loongarch_64.ad b/src/hotspot/cpu/loongarch/loongarch_64.ad |index f1bb1c2f6cb..0c6516fc1d5 100644 |--- a/src/hotspot/cpu/loongarch/loongarch_64.ad |+++ b/src/hotspot/cpu/loongarch/loongarch_64.ad -------------------------- File to patch: Skip this patch? [y] Skipping patch. 17 out of 17 hunks ignored can't find file to patch at input line 1070 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp |index a7062552f76..06fbc181583 100644 |--- a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 11 out of 11 hunks ignored can't find file to patch at input line 1189 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp |index c24d8a4712a..204ca1a1a07 100644 |--- a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 1211 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp b/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp |index 0b3ea4c42f3..30c06f40493 100644 |--- a/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored patching file src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp Reversed (or previously applied) patch detected! Assume -R? [n] Apply anyway? [n] Skipping patch. 1 out of 1 hunk ignored -- saving rejects to file src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp.rej patching file src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.hpp Reversed (or previously applied) patch detected! Assume -R? [n] Apply anyway? [n] Skipping patch. 1 out of 1 hunk ignored -- saving rejects to file src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.hpp.rej can't find file to patch at input line 1261 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/os_cpu/linux_loongarch/atomic_linux_loongarch.hpp b/src/hotspot/os_cpu/linux_loongarch/atomic_linux_loongarch.hpp |index beb717b67ff..77413aba9f4 100644 |--- a/src/hotspot/os_cpu/linux_loongarch/atomic_linux_loongarch.hpp |+++ b/src/hotspot/os_cpu/linux_loongarch/atomic_linux_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 4 out of 4 hunks ignored patching file src/hotspot/share/c1/c1_LIR.hpp Hunk #1 FAILED at 1619. Hunk #2 FAILED at 1655. Hunk #3 FAILED at 1675. 3 out of 3 hunks FAILED -- saving rejects to file src/hotspot/share/c1/c1_LIR.hpp.rej patching file src/hotspot/share/runtime/objectMonitor.cpp patching file test/hotspot/jtreg/vmTestbase/nsk/share/jdi/ArgumentHandler.java can't find file to patch at input line 1663 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit a6ce2246d45bfb51c72d93e48dcf48cd6ad24917 |Merge: 84bd3bf8f10 b78a848cc7a |Author: aoqi |Date: Fri Jan 26 16:13:03 2024 +0800 | | Merge | | |commit 84bd3bf8f104c294b595be579fa4268c5c83ed82 |Merge: 99147f78245 9c16e89d275 |Author: aoqi |Date: Thu Dec 7 22:42:44 2023 +0800 | | Merge | | |commit 99147f78245703b07fbbf35b7198521eada4cf2c |Author: loongson-jvm |Date: Thu Dec 7 20:59:32 2023 +0800 | | Update (2023.12.07, 2nd) | | 32519: Fix for 31967 set default MaxGCPauseMillis | 31967: [G1GC] Set default MaxGCPauseMillis=150ms | 32564: MIPS port of 8284273: Early crashes in os::print_context on AArch64 | 32563: MIPS port of 8283326: Implement SafeFetch statically | 32186: LA port of 8314020: Print instruction blocks in byte units | 31295: Provide information when hitting a HaltNode | 28314: Misc crash dump improvements | 28096: LA port of 8293851: hs_err should print more stack in hex dump | 26263: LA port of 8284273: Early crashes in os::print_context on AArch64 | 32079: LA port of 8313796: AsyncGetCallTrace crash on unreadable interpreter method pointer | 30410: LA port of 8303154: Investigate and improve instruction cache flushing during compilation | 23671: MIPS/LA port of 8277417: C1 LIR instruction for load-klass | 25388: LA port of 8283326: Implement SafeFetch statically | |diff --git a/src/hotspot/cpu/loongarch/assembler_loongarch.hpp b/src/hotspot/cpu/loongarch/assembler_loongarch.hpp |index af65eb878e4..5eae8b9995c 100644 |--- a/src/hotspot/cpu/loongarch/assembler_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/assembler_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 1684 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp b/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp |index aff47cb97e1..2ddf19a6e5a 100644 |--- a/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 3 out of 3 hunks ignored can't find file to patch at input line 1739 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/frame_loongarch.cpp b/src/hotspot/cpu/loongarch/frame_loongarch.cpp |index 23a63a77d98..1aba8e4dd27 100644 |--- a/src/hotspot/cpu/loongarch/frame_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/frame_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 1752 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/globals_loongarch.hpp b/src/hotspot/cpu/loongarch/globals_loongarch.hpp |index e31a3d02555..2358ca31596 100644 |--- a/src/hotspot/cpu/loongarch/globals_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/globals_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 1767 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/loongarch_64.ad b/src/hotspot/cpu/loongarch/loongarch_64.ad |index 43e32570a0f..f1bb1c2f6cb 100644 |--- a/src/hotspot/cpu/loongarch/loongarch_64.ad |+++ b/src/hotspot/cpu/loongarch/loongarch_64.ad -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 1788 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp |index f1cf308b447..a7062552f76 100644 |--- a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 1820 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp |index 07c33b80151..c24d8a4712a 100644 |--- a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 1834 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/nativeInst_loongarch.cpp b/src/hotspot/cpu/loongarch/nativeInst_loongarch.cpp |index 407f539e8d7..25ef0ecd224 100644 |--- a/src/hotspot/cpu/loongarch/nativeInst_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/nativeInst_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 1849 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/nativeInst_loongarch.hpp b/src/hotspot/cpu/loongarch/nativeInst_loongarch.hpp |index e445ebeb8be..0ec8ebddf09 100644 |--- a/src/hotspot/cpu/loongarch/nativeInst_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/nativeInst_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 1861 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp b/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp |index 930b6240b4b..0b3ea4c42f3 100644 |--- a/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 1873 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp b/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp |index 10242a3df4a..21bfc7d78cb 100644 |--- a/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 1938 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/vm_version_loongarch.cpp b/src/hotspot/cpu/loongarch/vm_version_loongarch.cpp |index c9a19b379b7..1a1ac923117 100644 |--- a/src/hotspot/cpu/loongarch/vm_version_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/vm_version_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 1951 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/mips/stubGenerator_mips_64.cpp b/src/hotspot/cpu/mips/stubGenerator_mips_64.cpp |index ad44d23c531..e894a302b50 100644 |--- a/src/hotspot/cpu/mips/stubGenerator_mips_64.cpp |+++ b/src/hotspot/cpu/mips/stubGenerator_mips_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 3 out of 3 hunks ignored can't find file to patch at input line 2026 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/os_cpu/linux_loongarch/os_linux_loongarch.cpp b/src/hotspot/os_cpu/linux_loongarch/os_linux_loongarch.cpp |index a2e4fea109c..b32ffe9105e 100644 |--- a/src/hotspot/os_cpu/linux_loongarch/os_linux_loongarch.cpp |+++ b/src/hotspot/os_cpu/linux_loongarch/os_linux_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 4 out of 4 hunks ignored patching file src/hotspot/os_cpu/linux_loongarch/safefetch_linux_loongarch64.S can't find file to patch at input line 2169 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/os_cpu/linux_mips/os_linux_mips.cpp b/src/hotspot/os_cpu/linux_mips/os_linux_mips.cpp |index 8344945ff79..ff1af7beb68 100644 |--- a/src/hotspot/os_cpu/linux_mips/os_linux_mips.cpp |+++ b/src/hotspot/os_cpu/linux_mips/os_linux_mips.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored patching file src/hotspot/os_cpu/linux_mips/safefetch_linux_mips64.S can't find file to patch at input line 9256 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit 52397e8a10845dc42966971478c0c50a75330dff |Merge: e7efed5c455 dc00ae47d7a |Author: aoqi |Date: Thu Dec 7 18:25:10 2023 +0800 | | Merge | |diff --cc make/autoconf/jvm-features.m4 |index bfe31396e22,aa99b037b2b..d0c3a85757b |--- a/make/autoconf/jvm-features.m4 |+++ b/make/autoconf/jvm-features.m4 |@@@ -337,7 -312,7 +337,8 @@@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_SHENA | if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86" || \ | test "x$OPENJDK_TARGET_CPU" = "xaarch64" || \ | test "x$OPENJDK_TARGET_CPU" = "xppc64le" || \ | - test "x$OPENJDK_TARGET_CPU" = "xriscv64"; then |++ test "x$OPENJDK_TARGET_CPU" = "xriscv64" || \ | + test "x$OPENJDK_TARGET_CPU" = "xloongarch64"; then | AC_MSG_RESULT([yes]) | else | AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU]) |diff --cc make/autoconf/platform.m4 |index d003aa87436,5752d3bd1a6..d38d650e0fa |--- a/make/autoconf/platform.m4 |+++ b/make/autoconf/platform.m4 |@@@ -582,12 -561,8 +582,14 @@@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HE | HOTSPOT_$1_CPU_DEFINE=PPC64 | elif test "x$OPENJDK_$1_CPU" = xppc64le; then | HOTSPOT_$1_CPU_DEFINE=PPC64 |+ elif test "x$OPENJDK_$1_CPU" = xriscv64; then |+ HOTSPOT_$1_CPU_DEFINE=RISCV64 | + elif test "x$OPENJDK_$1_CPU" = xmips64; then | + HOTSPOT_$1_CPU_DEFINE=MIPS64 | + elif test "x$OPENJDK_$1_CPU" = xmips64el; then | + HOTSPOT_$1_CPU_DEFINE=MIPS64 | + elif test "x$OPENJDK_$1_CPU" = xloongarch64; then | + HOTSPOT_$1_CPU_DEFINE=LOONGARCH64 | | # The cpu defines below are for zero, we don't support them directly. | elif test "x$OPENJDK_$1_CPU" = xsparc; then |diff --cc src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch.hpp |index 486592903ce,00000000000..baadeebb243 |mode 100644,000000..100644 |--- a/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch.hpp |@@@ -1,82 -1,0 +1,84 @@@ | +/* | + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. | + * Copyright (c) 2021, Loongson Technology. 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 CPU_LOONGARCH_C1_LIRASSEMBLER_LOONGARCH_HPP | +#define CPU_LOONGARCH_C1_LIRASSEMBLER_LOONGARCH_HPP | + | +// ArrayCopyStub needs access to bailout | +friend class ArrayCopyStub; | + | + private: | + int array_element_size(BasicType type) const; | + | + void arith_fpu_implementation(LIR_Code code, int left_index, int right_index, | + int dest_index, bool pop_fpu_stack); | + | + // helper functions which checks for overflow and sets bailout if it | + // occurs. Always returns a valid embeddable pointer but in the | + // bailout case the pointer won't be to unique storage. | + address float_constant(float f); | + address double_constant(double d); | + | + address int_constant(jlong n); | + | + bool is_literal_address(LIR_Address* addr); | + | + // Ensure we have a valid Address (base+offset) to a stack-slot. | + Address stack_slot_address(int index, uint shift, int adjust = 0); | + | + // Record the type of the receiver in ReceiverTypeData | + void type_profile_helper(Register mdo, ciMethodData *md, ciProfileData *data, | + Register recv, Label* update_done); | + void add_debug_info_for_branch(address adr, CodeEmitInfo* info); | + | + void casw(Register addr, Register newval, Register cmpval, bool sign); | + void casl(Register addr, Register newval, Register cmpval); | + | + void poll_for_safepoint(relocInfo::relocType rtype, CodeEmitInfo* info = NULL); | + | + static const int max_tableswitches = 20; | + struct tableswitch switches[max_tableswitches]; | + int tableswitch_count; | + | + void init() { tableswitch_count = 0; } | + | + void deoptimize_trap(CodeEmitInfo *info); | + |++ void emit_cmp_branch(LIR_OpBranch* op); |++ | + enum { | + // call stub: CompiledStaticCall::to_interp_stub_size() + | + // CompiledStaticCall::to_trampoline_stub_size() | + _call_stub_size = 13 * NativeInstruction::nop_instruction_size, | + _exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(175), | + _deopt_handler_size = 7 * NativeInstruction::nop_instruction_size | + }; | + | +public: | + void store_parameter(Register r, int offset_from_sp_in_words); | + void store_parameter(jint c, int offset_from_sp_in_words); | + void store_parameter(jobject c, int offset_from_sp_in_words); | + | +#endif // CPU_LOONGARCH_C1_LIRASSEMBLER_LOONGARCH_HPP |diff --cc src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp |index 2e4fbc1ecc0,00000000000..aff47cb97e1 |mode 100644,000000..100644 |--- a/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp |@@@ -1,3382 -1,0 +1,3378 @@@ | +/* | + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. | + * Copyright (c) 2021, Loongson Technology. All rights reserved. | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | + * | + * This code is free software; you can redistribute it and/or modify it | + * under the terms of the GNU General Public License version 2 only, as | + * published by the Free Software Foundation. | + * | + * This code is distributed in the hope that it will be useful, but WITHOUT | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | + * version 2 for more details (a copy is included in the LICENSE file that | + * accompanied this code). | + * | + * You should have received a copy of the GNU General Public License version | + * 2 along with this work; if not, write to the Free Software Foundation, | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | + * | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | + * or visit www.oracle.com if you need additional information or have any | + * questions. | + * | + */ | + | +#include "precompiled.hpp" | +#include "asm/macroAssembler.inline.hpp" | +#include "asm/assembler.hpp" | +#include "c1/c1_CodeStubs.hpp" | +#include "c1/c1_Compilation.hpp" | +#include "c1/c1_LIRAssembler.hpp" | +#include "c1/c1_MacroAssembler.hpp" | +#include "c1/c1_Runtime1.hpp" | +#include "c1/c1_ValueStack.hpp" | +#include "ci/ciArrayKlass.hpp" | +#include "ci/ciInstance.hpp" | +#include "code/compiledIC.hpp" | +#include "gc/shared/collectedHeap.hpp" | +#include "gc/shared/gc_globals.hpp" | +#include "nativeInst_loongarch.hpp" | +#include "oops/objArrayKlass.hpp" | +#include "runtime/frame.inline.hpp" | +#include "runtime/sharedRuntime.hpp" | +#include "runtime/stubRoutines.hpp" | +#include "utilities/powerOfTwo.hpp" | +#include "vmreg_loongarch.inline.hpp" | + | +#define A0 RA0 | +#define A1 RA1 | +#define A2 RA2 | +#define A3 RA3 | +#define A4 RA4 | +#define A5 RA5 | +#define A6 RA6 | +#define A7 RA7 | +#define T0 RT0 | +#define T1 RT1 | +#define T2 RT2 | +#define T3 RT3 | +#define T5 RT5 | +#define T6 RT6 | +#define T7 RT7 | +#define T8 RT8 | + | +#ifndef PRODUCT | +#define COMMENT(x) do { __ block_comment(x); } while (0) | +#else | +#define COMMENT(x) | +#endif | + | +NEEDS_CLEANUP // remove this definitions? | + | +#define __ _masm-> | + | +static void select_different_registers(Register preserve, Register extra, | + Register &tmp1, Register &tmp2) { | + if (tmp1 == preserve) { | + assert_different_registers(tmp1, tmp2, extra); | + tmp1 = extra; | + } else if (tmp2 == preserve) { | + assert_different_registers(tmp1, tmp2, extra); | + tmp2 = extra; | + } | + assert_different_registers(preserve, tmp1, tmp2); | +} | + | +static void select_different_registers(Register preserve, Register extra, | + Register &tmp1, Register &tmp2, | + Register &tmp3) { | + if (tmp1 == preserve) { | + assert_different_registers(tmp1, tmp2, tmp3, extra); | + tmp1 = extra; | + } else if (tmp2 == preserve) { | + assert_different_registers(tmp1, tmp2, tmp3, extra); | + tmp2 = extra; | + } else if (tmp3 == preserve) { | + assert_different_registers(tmp1, tmp2, tmp3, extra); | + tmp3 = extra; | + } | + assert_different_registers(preserve, tmp1, tmp2, tmp3); | +} | + | +bool LIR_Assembler::is_small_constant(LIR_Opr opr) { Unimplemented(); return false; } | + | +LIR_Opr LIR_Assembler::receiverOpr() { | + return FrameMap::receiver_opr; | +} | + | +LIR_Opr LIR_Assembler::osrBufferPointer() { | + return FrameMap::as_pointer_opr(receiverOpr()->as_register()); | +} | + | +//--------------fpu register translations----------------------- | + | +address LIR_Assembler::float_constant(float f) { | + address const_addr = __ float_constant(f); | + if (const_addr == NULL) { | + bailout("const section overflow"); | + return __ code()->consts()->start(); | + } else { | + return const_addr; | + } | +} | + | +address LIR_Assembler::double_constant(double d) { | + address const_addr = __ double_constant(d); | + if (const_addr == NULL) { | + bailout("const section overflow"); | + return __ code()->consts()->start(); | + } else { | + return const_addr; | + } | +} | + | +void LIR_Assembler::breakpoint() { Unimplemented(); } | + | +void LIR_Assembler::push(LIR_Opr opr) { Unimplemented(); } | + | +void LIR_Assembler::pop(LIR_Opr opr) { Unimplemented(); } | + | +bool LIR_Assembler::is_literal_address(LIR_Address* addr) { Unimplemented(); return false; } | + | +static Register as_reg(LIR_Opr op) { | + return op->is_double_cpu() ? op->as_register_lo() : op->as_register(); | +} | + | +static jlong as_long(LIR_Opr data) { | + jlong result; | + switch (data->type()) { | + case T_INT: | + result = (data->as_jint()); | + break; | + case T_LONG: | + result = (data->as_jlong()); | + break; | + default: | + ShouldNotReachHere(); | + result = 0; // unreachable | + } | + return result; | +} | + | +Address LIR_Assembler::as_Address(LIR_Address* addr) { | + Register base = addr->base()->as_pointer_register(); | + LIR_Opr opr = addr->index(); | + if (opr->is_cpu_register()) { | + Register index; | + if (opr->is_single_cpu()) | + index = opr->as_register(); | + else | + index = opr->as_register_lo(); | + assert(addr->disp() == 0, "must be"); | + return Address(base, index, Address::ScaleFactor(addr->scale())); | + } else { | + assert(addr->scale() == 0, "must be"); | + return Address(base, addr->disp()); | + } | + return Address(); | +} | + | +Address LIR_Assembler::as_Address_hi(LIR_Address* addr) { | + ShouldNotReachHere(); | + return Address(); | +} | + | +Address LIR_Assembler::as_Address_lo(LIR_Address* addr) { | + return as_Address(addr); // Ouch | + // FIXME: This needs to be much more clever. See x86. | +} | + | +// Ensure a valid Address (base + offset) to a stack-slot. If stack access is | +// not encodable as a base + (immediate) offset, generate an explicit address | +// calculation to hold the address in a temporary register. | +Address LIR_Assembler::stack_slot_address(int index, uint size, int adjust) { | + precond(size == 4 || size == 8); | + Address addr = frame_map()->address_for_slot(index, adjust); | + precond(addr.index() == noreg); | + precond(addr.base() == SP); | + precond(addr.disp() > 0); | + uint mask = size - 1; | + assert((addr.disp() & mask) == 0, "scaled offsets only"); | + return addr; | +} | + | +void LIR_Assembler::osr_entry() { | + offsets()->set_value(CodeOffsets::OSR_Entry, code_offset()); | + BlockBegin* osr_entry = compilation()->hir()->osr_entry(); | + ValueStack* entry_state = osr_entry->state(); | + int number_of_locks = entry_state->locks_size(); | + | + // we jump here if osr happens with the interpreter | + // state set up to continue at the beginning of the | + // loop that triggered osr - in particular, we have | + // the following registers setup: | + // | + // A2: osr buffer | + // | + | + // build frame | + ciMethod* m = compilation()->method(); | + __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes()); | + | + // OSR buffer is | + // | + // locals[nlocals-1..0] | + // monitors[0..number_of_locks] | + // | + // locals is a direct copy of the interpreter frame so in the osr buffer | + // so first slot in the local array is the last local from the interpreter | + // and last slot is local[0] (receiver) from the interpreter | + // | + // Similarly with locks. The first lock slot in the osr buffer is the nth lock | + // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock | + // in the interpreter frame (the method lock if a sync method) | + | + // Initialize monitors in the compiled activation. | + // A2: pointer to osr buffer | + // | + // All other registers are dead at this point and the locals will be | + // copied into place by code emitted in the IR. | + | + Register OSR_buf = osrBufferPointer()->as_pointer_register(); | + { | + assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below"); | + int monitor_offset = BytesPerWord * method()->max_locals() + (2 * BytesPerWord) * (number_of_locks - 1); | + // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in | + // the OSR buffer using 2 word entries: first the lock and then | + // the oop. | + for (int i = 0; i < number_of_locks; i++) { | + int slot_offset = monitor_offset - ((i * 2) * BytesPerWord); | +#ifdef ASSERT | + // verify the interpreter's monitor has a non-null object | + { | + Label L; | + __ ld_ptr(SCR1, Address(OSR_buf, slot_offset + 1 * BytesPerWord)); | + __ bnez(SCR1, L); | + __ stop("locked object is NULL"); | + __ bind(L); | + } | +#endif | + __ ld_ptr(S0, Address(OSR_buf, slot_offset + 0)); | + __ st_ptr(S0, frame_map()->address_for_monitor_lock(i)); | + __ ld_ptr(S0, Address(OSR_buf, slot_offset + 1*BytesPerWord)); | + __ st_ptr(S0, frame_map()->address_for_monitor_object(i)); | + } | + } | +} | + | +// inline cache check; done before the frame is built. | +int LIR_Assembler::check_icache() { | + Register receiver = FrameMap::receiver_opr->as_register(); | + Register ic_klass = IC_Klass; | + int start_offset = __ offset(); | + Label dont; | + | + __ verify_oop(receiver); | + | + // explicit NULL check not needed since load from [klass_offset] causes a trap | + // check against inline cache | + assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), | + "must add explicit null check"); | + | + __ load_klass(SCR2, receiver); | + __ beq(SCR2, ic_klass, dont); | + | + // if icache check fails, then jump to runtime routine | + // Note: RECEIVER must still contain the receiver! | + __ jmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type); | + | + // We align the verified entry point unless the method body | + // (including its inline cache check) will fit in a single 64-byte | + // icache line. | + if (!method()->is_accessor() || __ offset() - start_offset > 4 * 4) { | + // force alignment after the cache check. | + __ align(CodeEntryAlignment); | + } | + | + __ bind(dont); | + return start_offset; | +} | + | +void LIR_Assembler::clinit_barrier(ciMethod* method) { | + assert(VM_Version::supports_fast_class_init_checks(), "sanity"); | + assert(!method->holder()->is_not_initialized(), "initialization should have been started"); | + Label L_skip_barrier; | + | + __ mov_metadata(SCR2, method->holder()->constant_encoding()); | + __ clinit_barrier(SCR2, SCR1, &L_skip_barrier /*L_fast_path*/); | + __ jmp(SharedRuntime::get_handle_wrong_method_stub(), relocInfo::runtime_call_type); | + __ bind(L_skip_barrier); | +} | + | +void LIR_Assembler::jobject2reg(jobject o, Register reg) { | + if (o == NULL) { | + __ move(reg, R0); | + } else { | + int oop_index = __ oop_recorder()->find_index(o); | + RelocationHolder rspec = oop_Relocation::spec(oop_index); | + __ relocate(rspec); | + __ patchable_li52(reg, (long)o); | + } | +} | + | +void LIR_Assembler::deoptimize_trap(CodeEmitInfo *info) { | + address target = NULL; | + | + switch (patching_id(info)) { | + case PatchingStub::access_field_id: | + target = Runtime1::entry_for(Runtime1::access_field_patching_id); | + break; | + case PatchingStub::load_klass_id: | + target = Runtime1::entry_for(Runtime1::load_klass_patching_id); | + break; | + case PatchingStub::load_mirror_id: | + target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); | + break; | + case PatchingStub::load_appendix_id: | + target = Runtime1::entry_for(Runtime1::load_appendix_patching_id); | + break; | + default: ShouldNotReachHere(); | + } | + | + __ call(target, relocInfo::runtime_call_type); | + add_call_info_here(info); | +} | + | +void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo *info) { | + deoptimize_trap(info); | +} | + | +// This specifies the rsp decrement needed to build the frame | +int LIR_Assembler::initial_frame_size_in_bytes() const { | + // if rounding, must let FrameMap know! | + return in_bytes(frame_map()->framesize_in_bytes()); | +} | + | +int LIR_Assembler::emit_exception_handler() { | + // if the last instruction is a call (typically to do a throw which | + // is coming at the end after block reordering) the return address | + // must still point into the code area in order to avoid assertion | + // failures when searching for the corresponding bci => add a nop | + // (was bug 5/14/1999 - gri) | + __ nop(); | + | + // generate code for exception handler | + address handler_base = __ start_a_stub(exception_handler_size()); | + if (handler_base == NULL) { | + // not enough space left for the handler | + bailout("exception handler overflow"); | + return -1; | + } | + | + int offset = code_offset(); | + | + // the exception oop and pc are in A0, and A1 | + // no other registers need to be preserved, so invalidate them | + __ invalidate_registers(false, true, true, true, true, true); | + | + // check that there is really an exception | + __ verify_not_null_oop(A0); | + | + // search an exception handler (A0: exception oop, A1: throwing pc) | + __ call(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id), relocInfo::runtime_call_type); | + __ should_not_reach_here(); | + guarantee(code_offset() - offset <= exception_handler_size(), "overflow"); | + __ end_a_stub(); | + | + return offset; | +} | + | +// Emit the code to remove the frame from the stack in the exception unwind path. | +int LIR_Assembler::emit_unwind_handler() { | +#ifndef PRODUCT | + if (CommentedAssembly) { | + _masm->block_comment("Unwind handler"); | + } | +#endif | + | + int offset = code_offset(); | + | + // Fetch the exception from TLS and clear out exception related thread state | + __ ld_ptr(A0, Address(TREG, JavaThread::exception_oop_offset())); | + __ st_ptr(R0, Address(TREG, JavaThread::exception_oop_offset())); | + __ st_ptr(R0, Address(TREG, JavaThread::exception_pc_offset())); | + | + __ bind(_unwind_handler_entry); | + __ verify_not_null_oop(V0); | + if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { | + __ move(S0, V0); // Preserve the exception | + } | + | + // Perform needed unlocking | + MonitorExitStub* stub = NULL; | + if (method()->is_synchronized()) { | + monitor_address(0, FrameMap::a0_opr); | + stub = new MonitorExitStub(FrameMap::a0_opr, true, 0); | + __ unlock_object(A5, A4, A0, *stub->entry()); | + __ bind(*stub->continuation()); | + } | + | + if (compilation()->env()->dtrace_method_probes()) { | + __ mov_metadata(A1, method()->constant_encoding()); | + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), TREG, A1); | + } | + | + if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { | + __ move(A0, S0); // Restore the exception | + } | + | + // remove the activation and dispatch to the unwind handler | + __ block_comment("remove_frame and dispatch to the unwind handler"); | + __ remove_frame(initial_frame_size_in_bytes()); | + __ jmp(Runtime1::entry_for(Runtime1::unwind_exception_id), relocInfo::runtime_call_type); | + | + // Emit the slow path assembly | + if (stub != NULL) { | + stub->emit_code(this); | + } | + | + return offset; | +} | + | +int LIR_Assembler::emit_deopt_handler() { | + // if the last instruction is a call (typically to do a throw which | + // is coming at the end after block reordering) the return address | + // must still point into the code area in order to avoid assertion | + // failures when searching for the corresponding bci => add a nop | + // (was bug 5/14/1999 - gri) | + __ nop(); | + | + // generate code for exception handler | + address handler_base = __ start_a_stub(deopt_handler_size()); | + if (handler_base == NULL) { | + // not enough space left for the handler | + bailout("deopt handler overflow"); | + return -1; | + } | + | + int offset = code_offset(); | + | + __ call(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type); | + guarantee(code_offset() - offset <= deopt_handler_size(), "overflow"); | + __ end_a_stub(); | + | + return offset; | +} | + | +void LIR_Assembler::add_debug_info_for_branch(address adr, CodeEmitInfo* info) { | + _masm->code_section()->relocate(adr, relocInfo::poll_type); | + int pc_offset = code_offset(); | + flush_debug_info(pc_offset); | + info->record_debug_info(compilation()->debug_info_recorder(), pc_offset); | + if (info->exception_handlers() != NULL) { | + compilation()->add_exception_handlers_for_pco(pc_offset, info->exception_handlers()); | + } | +} | + | +void LIR_Assembler::return_op(LIR_Opr result, C1SafepointPollStub* code_stub) { | + assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == V0, | + "word returns are in V0,"); | + | + // Pop the stack before the safepoint code | + __ remove_frame(initial_frame_size_in_bytes()); | + | + if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) { | + __ reserved_stack_check(); | + } | + | + code_stub->set_safepoint_offset(__ offset()); | + __ relocate(relocInfo::poll_return_type); | + __ safepoint_poll(*code_stub->entry(), TREG, true /* at_return */, false /* acquire */, true /* in_nmethod */); | + | + __ jr(RA); | +} | + | +int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { | + guarantee(info != NULL, "Shouldn't be NULL"); | + __ ld_ptr(SCR1, Address(TREG, JavaThread::polling_page_offset())); | + add_debug_info_for_branch(info); // This isn't just debug info: it's the oop map | + __ relocate(relocInfo::poll_type); | + __ ld_w(SCR1, SCR1, 0); | + return __ offset(); | +} | + | +void LIR_Assembler::move_regs(Register from_reg, Register to_reg) { | + __ move(to_reg, from_reg); | +} | + | +void LIR_Assembler::swap_reg(Register a, Register b) { Unimplemented(); } | + | +void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) { | + assert(src->is_constant(), "should not call otherwise"); | + assert(dest->is_register(), "should not call otherwise"); | + LIR_Const* c = src->as_constant_ptr(); | + | + switch (c->type()) { | + case T_INT: | + assert(patch_code == lir_patch_none, "no patching handled here"); | + __ li(dest->as_register(), c->as_jint()); | + break; | + case T_ADDRESS: | + assert(patch_code == lir_patch_none, "no patching handled here"); | + __ li(dest->as_register(), c->as_jint()); | + break; | + case T_LONG: | + assert(patch_code == lir_patch_none, "no patching handled here"); | + __ li(dest->as_register_lo(), (intptr_t)c->as_jlong()); | + break; | + case T_OBJECT: | + if (patch_code == lir_patch_none) { | + jobject2reg(c->as_jobject(), dest->as_register()); | + } else { | + jobject2reg_with_patching(dest->as_register(), info); | + } | + break; | + case T_METADATA: | + if (patch_code != lir_patch_none) { | + klass2reg_with_patching(dest->as_register(), info); | + } else { | + __ mov_metadata(dest->as_register(), c->as_metadata()); | + } | + break; | + case T_FLOAT: | + __ lea(SCR1, InternalAddress(float_constant(c->as_jfloat()))); | + __ fld_s(dest->as_float_reg(), SCR1, 0); | + break; | + case T_DOUBLE: | + __ lea(SCR1, InternalAddress(double_constant(c->as_jdouble()))); | + __ fld_d(dest->as_double_reg(), SCR1, 0); | + break; | + default: | + ShouldNotReachHere(); | + } | +} | + | +void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { | + LIR_Const* c = src->as_constant_ptr(); | + switch (c->type()) { | + case T_OBJECT: | + if (!c->as_jobject()) | + __ st_ptr(R0, frame_map()->address_for_slot(dest->single_stack_ix())); | + else { | + const2reg(src, FrameMap::scr1_opr, lir_patch_none, NULL); | + reg2stack(FrameMap::scr1_opr, dest, c->type(), false); | + } | + break; | + case T_ADDRESS: | + const2reg(src, FrameMap::scr1_opr, lir_patch_none, NULL); | + reg2stack(FrameMap::scr1_opr, dest, c->type(), false); | + case T_INT: | + case T_FLOAT: | + if (c->as_jint_bits() == 0) | + __ st_w(R0, frame_map()->address_for_slot(dest->single_stack_ix())); | + else { | + __ li(SCR2, c->as_jint_bits()); | + __ st_w(SCR2, frame_map()->address_for_slot(dest->single_stack_ix())); | + } | + break; | + case T_LONG: | + case T_DOUBLE: | + if (c->as_jlong_bits() == 0) | + __ st_ptr(R0, frame_map()->address_for_slot(dest->double_stack_ix(), | + lo_word_offset_in_bytes)); | + else { | + __ li(SCR2, (intptr_t)c->as_jlong_bits()); | + __ st_ptr(SCR2, frame_map()->address_for_slot(dest->double_stack_ix(), | + lo_word_offset_in_bytes)); | + } | + break; | + default: | + ShouldNotReachHere(); | + } | +} | + | +void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, | + CodeEmitInfo* info, bool wide) { | + assert(src->is_constant(), "should not call otherwise"); | + LIR_Const* c = src->as_constant_ptr(); | + LIR_Address* to_addr = dest->as_address_ptr(); | + | + void (Assembler::* insn)(Register Rt, Address adr); | + | + switch (type) { | + case T_ADDRESS: | + assert(c->as_jint() == 0, "should be"); | + insn = &Assembler::st_d; | + break; | + case T_LONG: | + assert(c->as_jlong() == 0, "should be"); | + insn = &Assembler::st_d; | + break; | + case T_INT: | + assert(c->as_jint() == 0, "should be"); | + insn = &Assembler::st_w; | + break; | + case T_OBJECT: | + case T_ARRAY: | + assert(c->as_jobject() == 0, "should be"); | + if (UseCompressedOops && !wide) { | + insn = &Assembler::st_w; | + } else { | + insn = &Assembler::st_d; | + } | + break; | + case T_CHAR: | + case T_SHORT: | + assert(c->as_jint() == 0, "should be"); | + insn = &Assembler::st_h; | + break; | + case T_BOOLEAN: | + case T_BYTE: | + assert(c->as_jint() == 0, "should be"); | + insn = &Assembler::st_b; | + break; | + default: | + ShouldNotReachHere(); | + insn = &Assembler::st_d; // unreachable | + } | + | + if (info) add_debug_info_for_null_check_here(info); | + (_masm->*insn)(R0, as_Address(to_addr)); | +} | + | +void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) { | + assert(src->is_register(), "should not call otherwise"); | + assert(dest->is_register(), "should not call otherwise"); | + | + // move between cpu-registers | + if (dest->is_single_cpu()) { | + if (src->type() == T_LONG) { | + // Can do LONG -> OBJECT | + move_regs(src->as_register_lo(), dest->as_register()); | + return; | + } | + assert(src->is_single_cpu(), "must match"); | + if (src->type() == T_OBJECT) { | + __ verify_oop(src->as_register()); | + } | + move_regs(src->as_register(), dest->as_register()); | + } else if (dest->is_double_cpu()) { | + if (is_reference_type(src->type())) { | + // Surprising to me but we can see move of a long to t_object | + __ verify_oop(src->as_register()); | + move_regs(src->as_register(), dest->as_register_lo()); | + return; | + } | + assert(src->is_double_cpu(), "must match"); | + Register f_lo = src->as_register_lo(); | + Register f_hi = src->as_register_hi(); | + Register t_lo = dest->as_register_lo(); | + Register t_hi = dest->as_register_hi(); | + assert(f_hi == f_lo, "must be same"); | + assert(t_hi == t_lo, "must be same"); | + move_regs(f_lo, t_lo); | + } else if (dest->is_single_fpu()) { | + __ fmov_s(dest->as_float_reg(), src->as_float_reg()); | + } else if (dest->is_double_fpu()) { | + __ fmov_d(dest->as_double_reg(), src->as_double_reg()); | + } else { | + ShouldNotReachHere(); | + } | +} | + | +void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack) { | + precond(src->is_register() && dest->is_stack()); | + | + uint const c_sz32 = sizeof(uint32_t); | + uint const c_sz64 = sizeof(uint64_t); | + | + if (src->is_single_cpu()) { | + int index = dest->single_stack_ix(); | + if (is_reference_type(type)) { | + __ st_ptr(src->as_register(), stack_slot_address(index, c_sz64)); | + __ verify_oop(src->as_register()); | + } else if (type == T_METADATA || type == T_DOUBLE || type == T_ADDRESS) { | + __ st_ptr(src->as_register(), stack_slot_address(index, c_sz64)); | + } else { | + __ st_w(src->as_register(), stack_slot_address(index, c_sz32)); | + } | + } else if (src->is_double_cpu()) { | + int index = dest->double_stack_ix(); | + Address dest_addr_LO = stack_slot_address(index, c_sz64, lo_word_offset_in_bytes); | + __ st_ptr(src->as_register_lo(), dest_addr_LO); | + } else if (src->is_single_fpu()) { | + int index = dest->single_stack_ix(); | + __ fst_s(src->as_float_reg(), stack_slot_address(index, c_sz32)); | + } else if (src->is_double_fpu()) { | + int index = dest->double_stack_ix(); | + __ fst_d(src->as_double_reg(), stack_slot_address(index, c_sz64)); | + } else { | + ShouldNotReachHere(); | + } | +} | + | +void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, | + CodeEmitInfo* info, bool pop_fpu_stack, bool wide, bool /* unaligned */) { | + LIR_Address* to_addr = dest->as_address_ptr(); | + PatchingStub* patch = NULL; | + Register compressed_src = SCR2; | + | + if (patch_code != lir_patch_none) { | + deoptimize_trap(info); | + return; | + } | + | + if (is_reference_type(type)) { | + __ verify_oop(src->as_register()); | + | + if (UseCompressedOops && !wide) { | + __ encode_heap_oop(compressed_src, src->as_register()); | + } else { | + compressed_src = src->as_register(); | + } | + } | + | + int null_check_here = code_offset(); | + switch (type) { | + case T_FLOAT: | + __ fst_s(src->as_float_reg(), as_Address(to_addr)); | + break; | + case T_DOUBLE: | + __ fst_d(src->as_double_reg(), as_Address(to_addr)); | + break; | + case T_ARRAY: // fall through | + case T_OBJECT: // fall through | + if (UseCompressedOops && !wide) { | + __ st_w(compressed_src, as_Address(to_addr)); | + } else { | + __ st_ptr(compressed_src, as_Address(to_addr)); | + } | + break; | + case T_METADATA: | + // We get here to store a method pointer to the stack to pass to | + // a dtrace runtime call. This can't work on 64 bit with | + // compressed klass ptrs: T_METADATA can be a compressed klass | + // ptr or a 64 bit method pointer. | + ShouldNotReachHere(); | + __ st_ptr(src->as_register(), as_Address(to_addr)); | + break; | + case T_ADDRESS: | + __ st_ptr(src->as_register(), as_Address(to_addr)); | + break; | + case T_INT: | + __ st_w(src->as_register(), as_Address(to_addr)); | + break; | + case T_LONG: | + __ st_ptr(src->as_register_lo(), as_Address_lo(to_addr)); | + break; | + case T_BYTE: // fall through | + case T_BOOLEAN: | + __ st_b(src->as_register(), as_Address(to_addr)); | + break; | + case T_CHAR: // fall through | + case T_SHORT: | + __ st_h(src->as_register(), as_Address(to_addr)); | + break; | + default: | + ShouldNotReachHere(); | + } | + if (info != NULL) { | + add_debug_info_for_null_check(null_check_here, info); | + } | +} | + | +void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { | + precond(src->is_stack() && dest->is_register()); | + | + uint const c_sz32 = sizeof(uint32_t); | + uint const c_sz64 = sizeof(uint64_t); | + | + if (dest->is_single_cpu()) { | + int index = src->single_stack_ix(); | + if (is_reference_type(type)) { | + __ ld_ptr(dest->as_register(), stack_slot_address(index, c_sz64)); | + __ verify_oop(dest->as_register()); | + } else if (type == T_METADATA || type == T_ADDRESS) { | + __ ld_ptr(dest->as_register(), stack_slot_address(index, c_sz64)); | + } else { | + __ ld_w(dest->as_register(), stack_slot_address(index, c_sz32)); | + } | + } else if (dest->is_double_cpu()) { | + int index = src->double_stack_ix(); | + Address src_addr_LO = stack_slot_address(index, c_sz64, lo_word_offset_in_bytes); | + __ ld_ptr(dest->as_register_lo(), src_addr_LO); | + } else if (dest->is_single_fpu()) { | + int index = src->single_stack_ix(); | + __ fld_s(dest->as_float_reg(), stack_slot_address(index, c_sz32)); | + } else if (dest->is_double_fpu()) { | + int index = src->double_stack_ix(); | + __ fld_d(dest->as_double_reg(), stack_slot_address(index, c_sz64)); | + } else { | + ShouldNotReachHere(); | + } | +} | + | +void LIR_Assembler::klass2reg_with_patching(Register reg, CodeEmitInfo* info) { | + address target = NULL; | + | + switch (patching_id(info)) { | + case PatchingStub::access_field_id: | + target = Runtime1::entry_for(Runtime1::access_field_patching_id); | + break; | + case PatchingStub::load_klass_id: | + target = Runtime1::entry_for(Runtime1::load_klass_patching_id); | + break; | + case PatchingStub::load_mirror_id: | + target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); | + break; | + case PatchingStub::load_appendix_id: | + target = Runtime1::entry_for(Runtime1::load_appendix_patching_id); | + break; | + default: ShouldNotReachHere(); | + } | + | + __ call(target, relocInfo::runtime_call_type); | + add_call_info_here(info); | +} | + | +void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) { | + LIR_Opr temp; | + | + if (type == T_LONG || type == T_DOUBLE) | + temp = FrameMap::scr1_long_opr; | + else | + temp = FrameMap::scr1_opr; | + | + stack2reg(src, temp, src->type()); | + reg2stack(temp, dest, dest->type(), false); | +} | + | +void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, | + CodeEmitInfo* info, bool wide, bool /* unaligned */) { | + LIR_Address* addr = src->as_address_ptr(); | + LIR_Address* from_addr = src->as_address_ptr(); | + | + if (addr->base()->type() == T_OBJECT) { | + __ verify_oop(addr->base()->as_pointer_register()); | + } | + | + if (patch_code != lir_patch_none) { | + deoptimize_trap(info); | + return; | + } | + | + if (info != NULL) { | + add_debug_info_for_null_check_here(info); | + } | + int null_check_here = code_offset(); | + switch (type) { | + case T_FLOAT: | + __ fld_s(dest->as_float_reg(), as_Address(from_addr)); | + break; | + case T_DOUBLE: | + __ fld_d(dest->as_double_reg(), as_Address(from_addr)); | + break; | + case T_ARRAY: // fall through | + case T_OBJECT: // fall through | + if (UseCompressedOops && !wide) { | + __ ld_wu(dest->as_register(), as_Address(from_addr)); | + } else { | + __ ld_ptr(dest->as_register(), as_Address(from_addr)); | + } | + break; | + case T_METADATA: | + // We get here to store a method pointer to the stack to pass to | + // a dtrace runtime call. This can't work on 64 bit with | + // compressed klass ptrs: T_METADATA can be a compressed klass | + // ptr or a 64 bit method pointer. | + ShouldNotReachHere(); | + __ ld_ptr(dest->as_register(), as_Address(from_addr)); | + break; | + case T_ADDRESS: | + // FIXME: OMG this is a horrible kludge. Any offset from an | + // address that matches klass_offset_in_bytes() will be loaded | + // as a word, not a long. | + if (UseCompressedClassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) { | + __ ld_wu(dest->as_register(), as_Address(from_addr)); | + } else { | + __ ld_ptr(dest->as_register(), as_Address(from_addr)); | + } | + break; | + case T_INT: | + __ ld_w(dest->as_register(), as_Address(from_addr)); | + break; | + case T_LONG: | + __ ld_ptr(dest->as_register_lo(), as_Address_lo(from_addr)); | + break; | + case T_BYTE: | + __ ld_b(dest->as_register(), as_Address(from_addr)); | + break; | + case T_BOOLEAN: | + __ ld_bu(dest->as_register(), as_Address(from_addr)); | + break; | + case T_CHAR: | + __ ld_hu(dest->as_register(), as_Address(from_addr)); | + break; | + case T_SHORT: | + __ ld_h(dest->as_register(), as_Address(from_addr)); | + break; | + default: | + ShouldNotReachHere(); | + } | + | + if (is_reference_type(type)) { | + if (UseCompressedOops && !wide) { | + __ decode_heap_oop(dest->as_register()); | + } | + | + if (!UseZGC) { | + // Load barrier has not yet been applied, so ZGC can't verify the oop here | + __ verify_oop(dest->as_register()); | + } | + } else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) { | + if (UseCompressedClassPointers) { | + __ decode_klass_not_null(dest->as_register()); | + } | + } | +} | + | +int LIR_Assembler::array_element_size(BasicType type) const { | + int elem_size = type2aelembytes(type); | + return exact_log2(elem_size); | +} | + | +void LIR_Assembler::emit_op3(LIR_Op3* op) { | + switch (op->code()) { | + case lir_idiv: | + case lir_irem: | + arithmetic_idiv(op->code(), op->in_opr1(), op->in_opr2(), op->in_opr3(), | + op->result_opr(), op->info()); | + break; | + case lir_fmad: | + __ fmadd_d(op->result_opr()->as_double_reg(), op->in_opr1()->as_double_reg(), | + op->in_opr2()->as_double_reg(), op->in_opr3()->as_double_reg()); | + break; | + case lir_fmaf: | + __ fmadd_s(op->result_opr()->as_float_reg(), op->in_opr1()->as_float_reg(), | + op->in_opr2()->as_float_reg(), op->in_opr3()->as_float_reg()); | + break; | + default: | + ShouldNotReachHere(); | + break; | + } | +} | + | +void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) { | +#ifdef ASSERT | + assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label"); | + if (op->block() != NULL) _branch_target_blocks.append(op->block()); |- assert(op->cond() == lir_cond_always, "must be"); | +#endif | + |- if (op->info() != NULL) |- add_debug_info_for_branch(op->info()); |++ if (op->cond() == lir_cond_always) { |++ if (op->info() != NULL) |++ add_debug_info_for_branch(op->info()); | + |- __ b_far(*(op->label())); |++ __ b_far(*(op->label())); |++ } else { |++ emit_cmp_branch(op); |++ } | +} | + |- void LIR_Assembler::emit_opCmpBranch(LIR_OpCmpBranch* op) { |++void LIR_Assembler::emit_cmp_branch(LIR_OpBranch* op) { | +#ifdef ASSERT |- assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label"); |- if (op->block() != NULL) _branch_target_blocks.append(op->block()); | + if (op->ublock() != NULL) _branch_target_blocks.append(op->ublock()); | +#endif | + | + if (op->info() != NULL) { | + assert(op->in_opr1()->is_address() || op->in_opr2()->is_address(), | + "shouldn't be codeemitinfo for non-address operands"); | + add_debug_info_for_null_check_here(op->info()); // exception possible | + } | + | + Label& L = *(op->label()); | + Assembler::Condition acond; | + LIR_Opr opr1 = op->in_opr1(); | + LIR_Opr opr2 = op->in_opr2(); | + assert(op->condition() != lir_cond_always, "must be"); | + |- if (op->code() == lir_cmp_float_branch) { |++ if (op->code() == lir_cond_float_branch) { | + bool is_unordered = (op->ublock() == op->block()); | + if (opr1->is_single_fpu()) { | + FloatRegister reg1 = opr1->as_float_reg(); | + assert(opr2->is_single_fpu(), "expect single float register"); | + FloatRegister reg2 = opr2->as_float_reg(); | + switch(op->condition()) { | + case lir_cond_equal: | + if (is_unordered) | + __ fcmp_cueq_s(FCC0, reg1, reg2); | + else | + __ fcmp_ceq_s(FCC0, reg1, reg2); | + break; | + case lir_cond_notEqual: | + if (is_unordered) | + __ fcmp_cune_s(FCC0, reg1, reg2); | + else | + __ fcmp_cne_s(FCC0, reg1, reg2); | + break; | + case lir_cond_less: | + if (is_unordered) | + __ fcmp_cult_s(FCC0, reg1, reg2); | + else | + __ fcmp_clt_s(FCC0, reg1, reg2); | + break; | + case lir_cond_lessEqual: | + if (is_unordered) | + __ fcmp_cule_s(FCC0, reg1, reg2); | + else | + __ fcmp_cle_s(FCC0, reg1, reg2); | + break; | + case lir_cond_greaterEqual: | + if (is_unordered) | + __ fcmp_cule_s(FCC0, reg2, reg1); | + else | + __ fcmp_cle_s(FCC0, reg2, reg1); | + break; | + case lir_cond_greater: | + if (is_unordered) | + __ fcmp_cult_s(FCC0, reg2, reg1); | + else | + __ fcmp_clt_s(FCC0, reg2, reg1); | + break; | + default: | + ShouldNotReachHere(); | + } | + } else if (opr1->is_double_fpu()) { | + FloatRegister reg1 = opr1->as_double_reg(); | + assert(opr2->is_double_fpu(), "expect double float register"); | + FloatRegister reg2 = opr2->as_double_reg(); | + switch(op->condition()) { | + case lir_cond_equal: | + if (is_unordered) | + __ fcmp_cueq_d(FCC0, reg1, reg2); | + else | + __ fcmp_ceq_d(FCC0, reg1, reg2); | + break; | + case lir_cond_notEqual: | + if (is_unordered) | + __ fcmp_cune_d(FCC0, reg1, reg2); | + else | + __ fcmp_cne_d(FCC0, reg1, reg2); | + break; | + case lir_cond_less: | + if (is_unordered) | + __ fcmp_cult_d(FCC0, reg1, reg2); | + else | + __ fcmp_clt_d(FCC0, reg1, reg2); | + break; | + case lir_cond_lessEqual: | + if (is_unordered) | + __ fcmp_cule_d(FCC0, reg1, reg2); | + else | + __ fcmp_cle_d(FCC0, reg1, reg2); | + break; | + case lir_cond_greaterEqual: | + if (is_unordered) | + __ fcmp_cule_d(FCC0, reg2, reg1); | + else | + __ fcmp_cle_d(FCC0, reg2, reg1); | + break; | + case lir_cond_greater: | + if (is_unordered) | + __ fcmp_cult_d(FCC0, reg2, reg1); | + else | + __ fcmp_clt_d(FCC0, reg2, reg1); | + break; | + default: | + ShouldNotReachHere(); | + } | + } else { | + ShouldNotReachHere(); | + } | + __ bcnez(FCC0, L); | + } else { | + if (opr1->is_constant() && opr2->is_single_cpu()) { | + // tableswitch | + Unimplemented(); | + } else if (opr1->is_single_cpu() || opr1->is_double_cpu()) { | + Register reg1 = as_reg(opr1); | + Register reg2 = noreg; | + jlong imm2 = 0; | + if (opr2->is_single_cpu()) { | + // cpu register - cpu register | + reg2 = opr2->as_register(); | + } else if (opr2->is_double_cpu()) { | + // cpu register - cpu register | + reg2 = opr2->as_register_lo(); | + } else if (opr2->is_constant()) { | + switch(opr2->type()) { | + case T_INT: | + case T_ADDRESS: | + imm2 = opr2->as_constant_ptr()->as_jint(); | + break; | + case T_LONG: | + imm2 = opr2->as_constant_ptr()->as_jlong(); | + break; | + case T_METADATA: | + imm2 = (intptr_t)opr2->as_constant_ptr()->as_metadata(); | + break; | + case T_OBJECT: | + case T_ARRAY: | + if (opr2->as_constant_ptr()->as_jobject() != NULL) { | + reg2 = SCR1; | + jobject2reg(opr2->as_constant_ptr()->as_jobject(), reg2); | + } else { | + reg2 = R0; | + } | + break; | + default: | + ShouldNotReachHere(); | + break; | + } | + } else { | + ShouldNotReachHere(); | + } | + if (reg2 == noreg) { | + if (imm2 == 0) { | + reg2 = R0; | + } else { | + reg2 = SCR1; | + __ li(reg2, imm2); | + } | + } | + switch (op->condition()) { | + case lir_cond_equal: | + __ beq_far(reg1, reg2, L); break; | + case lir_cond_notEqual: | + __ bne_far(reg1, reg2, L); break; | + case lir_cond_less: | + __ blt_far(reg1, reg2, L, true); break; | + case lir_cond_lessEqual: | + __ bge_far(reg2, reg1, L, true); break; | + case lir_cond_greaterEqual: | + __ bge_far(reg1, reg2, L, true); break; | + case lir_cond_greater: | + __ blt_far(reg2, reg1, L, true); break; | + case lir_cond_belowEqual: | + __ bge_far(reg2, reg1, L, false); break; | + case lir_cond_aboveEqual: | + __ bge_far(reg1, reg2, L, false); break; | + default: | + ShouldNotReachHere(); | + } | + } | + } | +} | + | +void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { | + LIR_Opr src = op->in_opr(); | + LIR_Opr dest = op->result_opr(); | + LIR_Opr tmp = op->tmp(); | + | + switch (op->bytecode()) { | + case Bytecodes::_i2f: | + __ movgr2fr_w(dest->as_float_reg(), src->as_register()); | + __ ffint_s_w(dest->as_float_reg(), dest->as_float_reg()); | + break; | + case Bytecodes::_i2d: | + __ movgr2fr_w(dest->as_double_reg(), src->as_register()); | + __ ffint_d_w(dest->as_double_reg(), dest->as_double_reg()); | + break; | + case Bytecodes::_l2d: | + __ movgr2fr_d(dest->as_double_reg(), src->as_register_lo()); | + __ ffint_d_l(dest->as_double_reg(), dest->as_double_reg()); | + break; | + case Bytecodes::_l2f: | + __ movgr2fr_d(dest->as_float_reg(), src->as_register_lo()); | + __ ffint_s_l(dest->as_float_reg(), dest->as_float_reg()); | + break; | + case Bytecodes::_f2d: | + __ fcvt_d_s(dest->as_double_reg(), src->as_float_reg()); | + break; | + case Bytecodes::_d2f: | + __ fcvt_s_d(dest->as_float_reg(), src->as_double_reg()); | + break; | + case Bytecodes::_i2c: | + __ bstrpick_w(dest->as_register(), src->as_register(), 15, 0); | + break; | + case Bytecodes::_i2l: | + _masm->block_comment("FIXME: This could be a no-op"); | + __ slli_w(dest->as_register_lo(), src->as_register(), 0); | + break; | + case Bytecodes::_i2s: | + __ ext_w_h(dest->as_register(), src->as_register()); | + break; | + case Bytecodes::_i2b: | + __ ext_w_b(dest->as_register(), src->as_register()); | + break; | + case Bytecodes::_l2i: | + __ slli_w(dest->as_register(), src->as_register_lo(), 0); | + break; | + case Bytecodes::_d2l: | + __ ftintrz_l_d(tmp->as_double_reg(), src->as_double_reg()); | + __ movfr2gr_d(dest->as_register_lo(), tmp->as_double_reg()); | + break; | + case Bytecodes::_f2i: | + __ ftintrz_w_s(tmp->as_float_reg(), src->as_float_reg()); | + __ movfr2gr_s(dest->as_register(), tmp->as_float_reg()); | + break; | + case Bytecodes::_f2l: | + __ ftintrz_l_s(tmp->as_float_reg(), src->as_float_reg()); | + __ movfr2gr_d(dest->as_register_lo(), tmp->as_float_reg()); | + break; | + case Bytecodes::_d2i: | + __ ftintrz_w_d(tmp->as_double_reg(), src->as_double_reg()); | + __ movfr2gr_s(dest->as_register(), tmp->as_double_reg()); | + break; | + default: ShouldNotReachHere(); | + } | +} | + | +void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) { | + if (op->init_check()) { | + __ ld_bu(SCR1, Address(op->klass()->as_register(), InstanceKlass::init_state_offset())); | + __ li(SCR2, InstanceKlass::fully_initialized); | + add_debug_info_for_null_check_here(op->stub()->info()); | + __ bne_far(SCR1, SCR2, *op->stub()->entry()); | + } | + __ allocate_object(op->obj()->as_register(), op->tmp1()->as_register(), | + op->tmp2()->as_register(), op->header_size(), | + op->object_size(), op->klass()->as_register(), | + *op->stub()->entry()); | + __ bind(*op->stub()->continuation()); | +} | + | +void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { | + Register len = op->len()->as_register(); | + if (UseSlowPath || | + (!UseFastNewObjectArray && is_reference_type(op->type())) || | + (!UseFastNewTypeArray && !is_reference_type(op->type()))) { | + __ b(*op->stub()->entry()); | + } else { | + Register tmp1 = op->tmp1()->as_register(); | + Register tmp2 = op->tmp2()->as_register(); | + Register tmp3 = op->tmp3()->as_register(); | + if (len == tmp1) { | + tmp1 = tmp3; | + } else if (len == tmp2) { | + tmp2 = tmp3; | + } else if (len == tmp3) { | + // everything is ok | + } else { | + __ move(tmp3, len); | + } | + __ allocate_array(op->obj()->as_register(), len, tmp1, tmp2, | + arrayOopDesc::header_size(op->type()), | + array_element_size(op->type()), | + op->klass()->as_register(), | + *op->stub()->entry()); | + } | + __ bind(*op->stub()->continuation()); | +} | + | +void LIR_Assembler::type_profile_helper(Register mdo, ciMethodData *md, ciProfileData *data, | + Register recv, Label* update_done) { | + for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) { | + Label next_test; | + // See if the receiver is receiver[n]. | + __ lea(SCR2, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)))); | + __ ld_ptr(SCR1, Address(SCR2)); | + __ bne(recv, SCR1, next_test); | + Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))); | + __ ld_ptr(SCR2, data_addr); | + __ addi_d(SCR2, SCR2, DataLayout::counter_increment); | + __ st_ptr(SCR2, data_addr); | + __ b(*update_done); | + __ bind(next_test); | + } | + | + // Didn't find receiver; find next empty slot and fill it in | + for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) { | + Label next_test; | + __ lea(SCR2, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)))); | + Address recv_addr(SCR2); | + __ ld_ptr(SCR1, recv_addr); | + __ bnez(SCR1, next_test); | + __ st_ptr(recv, recv_addr); | + __ li(SCR1, DataLayout::counter_increment); | + __ lea(SCR2, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)))); | + __ st_ptr(SCR1, Address(SCR2)); | + __ b(*update_done); | + __ bind(next_test); | + } | +} | + | +void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, | + Label* failure, Label* obj_is_null) { | + // we always need a stub for the failure case. | + CodeStub* stub = op->stub(); | + Register obj = op->object()->as_register(); | + Register k_RInfo = op->tmp1()->as_register(); | + Register klass_RInfo = op->tmp2()->as_register(); | + Register dst = op->result_opr()->as_register(); | + ciKlass* k = op->klass(); | + Register Rtmp1 = noreg; | + | + // check if it needs to be profiled | + ciMethodData* md; | + ciProfileData* data; | + | + const bool should_profile = op->should_profile(); | + | + if (should_profile) { | + ciMethod* method = op->profiled_method(); | + assert(method != NULL, "Should have method"); | + int bci = op->profiled_bci(); | + md = method->method_data_or_null(); | + assert(md != NULL, "Sanity"); | + data = md->bci_to_data(bci); | + assert(data != NULL, "need data for type check"); | + assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); | + } | + | + Label profile_cast_success, profile_cast_failure; | + Label *success_target = should_profile ? &profile_cast_success : success; | + Label *failure_target = should_profile ? &profile_cast_failure : failure; | + | + if (obj == k_RInfo) { | + k_RInfo = dst; | + } else if (obj == klass_RInfo) { | + klass_RInfo = dst; | + } | + if (k->is_loaded() && !UseCompressedClassPointers) { | + select_different_registers(obj, dst, k_RInfo, klass_RInfo); | + } else { | + Rtmp1 = op->tmp3()->as_register(); | + select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1); | + } | + | + assert_different_registers(obj, k_RInfo, klass_RInfo); | + | + if (should_profile) { | + Label not_null; | + __ bnez(obj, not_null); | + // Object is null; update MDO and exit | + Register mdo = klass_RInfo; | + __ mov_metadata(mdo, md->constant_encoding()); | + Address data_addr = Address(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset())); | + __ ld_bu(SCR2, data_addr); | + __ ori(SCR2, SCR2, BitData::null_seen_byte_constant()); | + __ st_b(SCR2, data_addr); | + __ b(*obj_is_null); | + __ bind(not_null); | + } else { | + __ beqz(obj, *obj_is_null); | + } | + | + if (!k->is_loaded()) { | + klass2reg_with_patching(k_RInfo, op->info_for_patch()); | + } else { | + __ mov_metadata(k_RInfo, k->constant_encoding()); | + } | + __ verify_oop(obj); | + | + if (op->fast_check()) { | + // get object class | + // not a safepoint as obj null check happens earlier | + __ load_klass(SCR2, obj); | + __ bne_far(SCR2, k_RInfo, *failure_target); | + // successful cast, fall through to profile or jump | + } else { | + // get object class | + // not a safepoint as obj null check happens earlier | + __ load_klass(klass_RInfo, obj); | + if (k->is_loaded()) { | + // See if we get an immediate positive hit | + __ ld_ptr(SCR1, Address(klass_RInfo, int64_t(k->super_check_offset()))); | + if ((juint)in_bytes(Klass::secondary_super_cache_offset()) != k->super_check_offset()) { | + __ bne_far(k_RInfo, SCR1, *failure_target); | + // successful cast, fall through to profile or jump | + } else { | + // See if we get an immediate positive hit | + __ beq_far(k_RInfo, SCR1, *success_target); | + // check for self | + __ beq_far(klass_RInfo, k_RInfo, *success_target); | + | + __ addi_d(SP, SP, -2 * wordSize); | + __ st_ptr(k_RInfo, Address(SP, 0 * wordSize)); | + __ st_ptr(klass_RInfo, Address(SP, 1 * wordSize)); | + __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); | + __ ld_ptr(klass_RInfo, Address(SP, 0 * wordSize)); | + __ addi_d(SP, SP, 2 * wordSize); | + // result is a boolean | + __ beqz(klass_RInfo, *failure_target); | + // successful cast, fall through to profile or jump | + } | + } else { | + // perform the fast part of the checking logic | + __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); | + // call out-of-line instance of __ check_klass_subtype_slow_path(...): | + __ addi_d(SP, SP, -2 * wordSize); | + __ st_ptr(k_RInfo, Address(SP, 0 * wordSize)); | + __ st_ptr(klass_RInfo, Address(SP, 1 * wordSize)); | + __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); | + __ ld_ptr(k_RInfo, Address(SP, 0 * wordSize)); | + __ ld_ptr(klass_RInfo, Address(SP, 1 * wordSize)); | + __ addi_d(SP, SP, 2 * wordSize); | + // result is a boolean | + __ beqz(k_RInfo, *failure_target); | + // successful cast, fall through to profile or jump | + } | + } | + if (should_profile) { | + Register mdo = klass_RInfo, recv = k_RInfo; | + __ bind(profile_cast_success); | + __ mov_metadata(mdo, md->constant_encoding()); | + __ load_klass(recv, obj); | + Label update_done; | + type_profile_helper(mdo, md, data, recv, success); | + __ b(*success); | + | + __ bind(profile_cast_failure); | + __ mov_metadata(mdo, md->constant_encoding()); | + Address counter_addr = Address(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); | + __ ld_ptr(SCR2, counter_addr); | + __ addi_d(SCR2, SCR2, -DataLayout::counter_increment); | + __ st_ptr(SCR2, counter_addr); | + __ b(*failure); | + } | + __ b(*success); | +} | + | +void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { | + const bool should_profile = op->should_profile(); | + | + LIR_Code code = op->code(); | + if (code == lir_store_check) { | + Register value = op->object()->as_register(); | + Register array = op->array()->as_register(); | + Register k_RInfo = op->tmp1()->as_register(); | + Register klass_RInfo = op->tmp2()->as_register(); | + Register Rtmp1 = op->tmp3()->as_register(); | + CodeStub* stub = op->stub(); | + | + // check if it needs to be profiled | + ciMethodData* md; | + ciProfileData* data; | + | + if (should_profile) { | + ciMethod* method = op->profiled_method(); | + assert(method != NULL, "Should have method"); | + int bci = op->profiled_bci(); | + md = method->method_data_or_null(); | + assert(md != NULL, "Sanity"); | + data = md->bci_to_data(bci); | + assert(data != NULL, "need data for type check"); | + assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); | + } | + Label profile_cast_success, profile_cast_failure, done; | + Label *success_target = should_profile ? &profile_cast_success : &done; | + Label *failure_target = should_profile ? &profile_cast_failure : stub->entry(); | + | + if (should_profile) { | + Label not_null; | + __ bnez(value, not_null); | + // Object is null; update MDO and exit | + Register mdo = klass_RInfo; | + __ mov_metadata(mdo, md->constant_encoding()); | + Address data_addr = Address(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset())); | + __ ld_bu(SCR2, data_addr); | + __ ori(SCR2, SCR2, BitData::null_seen_byte_constant()); | + __ st_b(SCR2, data_addr); | + __ b(done); | + __ bind(not_null); | + } else { | + __ beqz(value, done); | + } | + | + add_debug_info_for_null_check_here(op->info_for_exception()); | + __ load_klass(k_RInfo, array); | + __ load_klass(klass_RInfo, value); | + | + // get instance klass (it's already uncompressed) | + __ ld_ptr(k_RInfo, Address(k_RInfo, ObjArrayKlass::element_klass_offset())); | + // perform the fast part of the checking logic | + __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); | + // call out-of-line instance of __ check_klass_subtype_slow_path(...): | + __ addi_d(SP, SP, -2 * wordSize); | + __ st_ptr(k_RInfo, Address(SP, 0 * wordSize)); | + __ st_ptr(klass_RInfo, Address(SP, 1 * wordSize)); | + __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); | + __ ld_ptr(k_RInfo, Address(SP, 0 * wordSize)); | + __ ld_ptr(klass_RInfo, Address(SP, 1 * wordSize)); | + __ addi_d(SP, SP, 2 * wordSize); | + // result is a boolean | + __ beqz(k_RInfo, *failure_target); | + // fall through to the success case | + | + if (should_profile) { | + Register mdo = klass_RInfo, recv = k_RInfo; | + __ bind(profile_cast_success); | + __ mov_metadata(mdo, md->constant_encoding()); | + __ load_klass(recv, value); | + Label update_done; | + type_profile_helper(mdo, md, data, recv, &done); | + __ b(done); | + | + __ bind(profile_cast_failure); | + __ mov_metadata(mdo, md->constant_encoding()); | + Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); | + __ lea(SCR2, counter_addr); | + __ ld_ptr(SCR1, Address(SCR2)); | + __ addi_d(SCR1, SCR1, -DataLayout::counter_increment); | + __ st_ptr(SCR1, Address(SCR2)); | + __ b(*stub->entry()); | + } | + | + __ bind(done); | + } else if (code == lir_checkcast) { | + Register obj = op->object()->as_register(); | + Register dst = op->result_opr()->as_register(); | + Label success; | + emit_typecheck_helper(op, &success, op->stub()->entry(), &success); | + __ bind(success); | + if (dst != obj) { | + __ move(dst, obj); | + } | + } else if (code == lir_instanceof) { | + Register obj = op->object()->as_register(); | + Register dst = op->result_opr()->as_register(); | + Label success, failure, done; | + emit_typecheck_helper(op, &success, &failure, &failure); | + __ bind(failure); | + __ move(dst, R0); | + __ b(done); | + __ bind(success); | + __ li(dst, 1); | + __ bind(done); | + } else { | + ShouldNotReachHere(); | + } | +} | + | +void LIR_Assembler::casw(Register addr, Register newval, Register cmpval, bool sign) { | + __ cmpxchg32(Address(addr, 0), cmpval, newval, SCR1, sign, | + /* retold */ false, /* barrier */ true, /* weak */ false, /* exchage */ false); | +} | + | +void LIR_Assembler::casl(Register addr, Register newval, Register cmpval) { | + __ cmpxchg(Address(addr, 0), cmpval, newval, SCR1, | + /* retold */ false, /* barrier */ true, /* weak */ false, /* exchage */ false); | +} | + | +void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { | + assert(VM_Version::supports_cx8(), "wrong machine"); | + Register addr; | + if (op->addr()->is_register()) { | + addr = as_reg(op->addr()); | + } else { | + assert(op->addr()->is_address(), "what else?"); | + LIR_Address* addr_ptr = op->addr()->as_address_ptr(); | + assert(addr_ptr->disp() == 0, "need 0 disp"); | + assert(addr_ptr->index() == LIR_OprDesc::illegalOpr(), "need 0 index"); | + addr = as_reg(addr_ptr->base()); | + } | + Register newval = as_reg(op->new_value()); | + Register cmpval = as_reg(op->cmp_value()); | + | + if (op->code() == lir_cas_obj) { | + if (UseCompressedOops) { | + Register t1 = op->tmp1()->as_register(); | + assert(op->tmp1()->is_valid(), "must be"); | + __ encode_heap_oop(t1, cmpval); | + cmpval = t1; | + __ encode_heap_oop(SCR2, newval); | + newval = SCR2; | + casw(addr, newval, cmpval, false); | + } else { | + casl(addr, newval, cmpval); | + } | + } else if (op->code() == lir_cas_int) { | + casw(addr, newval, cmpval, true); | + } else { | + casl(addr, newval, cmpval); | + } | +} | + |- void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, |- LIR_Opr result, BasicType type) { |- Unimplemented(); |- } |- |- void LIR_Assembler::cmp_cmove(LIR_Condition condition, LIR_Opr left, LIR_Opr right, |- LIR_Opr src1, LIR_Opr src2, LIR_Opr result, BasicType type) { |++void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr result, BasicType type, |++ LIR_Opr left, LIR_Opr right) { | + assert(result->is_single_cpu() || result->is_double_cpu(), "expect single register for result"); | + assert(left->is_single_cpu() || left->is_double_cpu(), "must be"); | + Register regd = (result->type() == T_LONG) ? result->as_register_lo() : result->as_register(); | + Register regl = as_reg(left); | + Register regr = noreg; | + Register reg1 = noreg; | + Register reg2 = noreg; | + jlong immr = 0; | + | + // comparison operands | + if (right->is_single_cpu()) { | + // cpu register - cpu register | + regr = right->as_register(); | + } else if (right->is_double_cpu()) { | + // cpu register - cpu register | + regr = right->as_register_lo(); | + } else if (right->is_constant()) { | + switch(right->type()) { | + case T_INT: | + case T_ADDRESS: | + immr = right->as_constant_ptr()->as_jint(); | + break; | + case T_LONG: | + immr = right->as_constant_ptr()->as_jlong(); | + break; | + case T_METADATA: | + immr = (intptr_t)right->as_constant_ptr()->as_metadata(); | + break; | + case T_OBJECT: | + case T_ARRAY: | + if (right->as_constant_ptr()->as_jobject() != NULL) { | + regr = SCR1; | + jobject2reg(right->as_constant_ptr()->as_jobject(), regr); | + } else { | + immr = 0; | + } | + break; | + default: | + ShouldNotReachHere(); | + break; | + } | + } else { | + ShouldNotReachHere(); | + } | + | + if (regr == noreg) { | + switch (condition) { | + case lir_cond_equal: | + case lir_cond_notEqual: | + if (!Assembler::is_simm(-immr, 12)) { | + regr = SCR1; | + __ li(regr, immr); | + } | + break; | + default: | + if (!Assembler::is_simm(immr, 12)) { | + regr = SCR1; | + __ li(regr, immr); | + } | + } | + } | + | + // special cases | + if (src1->is_constant() && src2->is_constant()) { | + jlong val1 = 0, val2 = 0; | + if (src1->type() == T_INT && src2->type() == T_INT) { | + val1 = src1->as_jint(); | + val2 = src2->as_jint(); | + } else if (src1->type() == T_LONG && src2->type() == T_LONG) { | + val1 = src1->as_jlong(); | + val2 = src2->as_jlong(); | + } | + if (val1 == 0 && val2 == 1) { | + if (regr == noreg) { | + switch (condition) { | + case lir_cond_equal: | + if (immr == 0) { | + __ sltu(regd, R0, regl); | + } else { | + __ addi_d(SCR1, regl, -immr); | + __ li(regd, 1); | + __ maskeqz(regd, regd, SCR1); | + } | + break; | + case lir_cond_notEqual: | + if (immr == 0) { | + __ sltu(regd, R0, regl); | + __ xori(regd, regd, 1); | + } else { | + __ addi_d(SCR1, regl, -immr); | + __ li(regd, 1); | + __ masknez(regd, regd, SCR1); | + } | + break; | + case lir_cond_less: | + __ slti(regd, regl, immr); | + __ xori(regd, regd, 1); | + break; | + case lir_cond_lessEqual: | + if (immr == 0) { | + __ slt(regd, R0, regl); | + } else { | + __ li(SCR1, immr); | + __ slt(regd, SCR1, regl); | + } | + break; | + case lir_cond_greater: | + if (immr == 0) { | + __ slt(regd, R0, regl); | + } else { | + __ li(SCR1, immr); | + __ slt(regd, SCR1, regl); | + } | + __ xori(regd, regd, 1); | + break; | + case lir_cond_greaterEqual: | + __ slti(regd, regl, immr); | + break; | + case lir_cond_belowEqual: | + if (immr == 0) { | + __ sltu(regd, R0, regl); | + } else { | + __ li(SCR1, immr); | + __ sltu(regd, SCR1, regl); | + } | + break; | + case lir_cond_aboveEqual: | + __ sltui(regd, regl, immr); | + break; | + default: | + ShouldNotReachHere(); | + } | + } else { | + switch (condition) { | + case lir_cond_equal: | + __ sub_d(SCR1, regl, regr); | + __ li(regd, 1); | + __ maskeqz(regd, regd, SCR1); | + break; | + case lir_cond_notEqual: | + __ sub_d(SCR1, regl, regr); | + __ li(regd, 1); | + __ masknez(regd, regd, SCR1); | + break; | + case lir_cond_less: | + __ slt(regd, regl, regr); | + __ xori(regd, regd, 1); | + break; | + case lir_cond_lessEqual: | + __ slt(regd, regr, regl); | + break; | + case lir_cond_greater: | + __ slt(regd, regr, regl); | + __ xori(regd, regd, 1); | + break; | + case lir_cond_greaterEqual: | + __ slt(regd, regl, regr); | + break; | + case lir_cond_belowEqual: | + __ sltu(regd, regr, regl); | + break; | + case lir_cond_aboveEqual: | + __ sltu(regd, regl, regr); | + break; | + default: | + ShouldNotReachHere(); | + } | + } | + return; | + } else if (val1 == 1 && val2 == 0) { | + if (regr == noreg) { | + switch (condition) { | + case lir_cond_equal: | + if (immr == 0) { | + __ sltu(regd, R0, regl); | + __ xori(regd, regd, 1); | + } else { | + __ addi_d(SCR1, regl, -immr); | + __ li(regd, 1); | + __ masknez(regd, regd, SCR1); | + } | + break; | + case lir_cond_notEqual: | + if (immr == 0) { | + __ sltu(regd, R0, regl); | + } else { | + __ addi_d(SCR1, regl, -immr); | + __ li(regd, 1); | + __ maskeqz(regd, regd, SCR1); | + } | + break; | + case lir_cond_less: | + __ slti(regd, regl, immr); | + break; | + case lir_cond_lessEqual: | + if (immr == 0) { | + __ slt(regd, R0, regl); | + } else { | + __ li(SCR1, immr); | + __ slt(regd, SCR1, regl); | + } | + __ xori(regd, regd, 1); | + break; | + case lir_cond_greater: | + if (immr == 0) { | + __ slt(regd, R0, regl); | + } else { | + __ li(SCR1, immr); | + __ slt(regd, SCR1, regl); | + } | + break; | + case lir_cond_greaterEqual: | + __ slti(regd, regl, immr); | + __ xori(regd, regd, 1); | + break; | + case lir_cond_belowEqual: | + if (immr == 0) { | + __ sltu(regd, R0, regl); | + } else { | + __ li(SCR1, immr); | + __ sltu(regd, SCR1, regl); | + } | + __ xori(regd, regd, 1); | + break; | + case lir_cond_aboveEqual: | + __ sltui(regd, regl, immr); | + __ xori(regd, regd, 1); | + break; | + default: | + ShouldNotReachHere(); | + } | + } else { | + switch (condition) { | + case lir_cond_equal: | + __ sub_d(SCR1, regl, regr); | + __ li(regd, 1); | + __ masknez(regd, regd, SCR1); | + break; | + case lir_cond_notEqual: | + __ sub_d(SCR1, regl, regr); | + __ li(regd, 1); | + __ maskeqz(regd, regd, SCR1); | + break; | + case lir_cond_less: | + __ slt(regd, regl, regr); | + break; | + case lir_cond_lessEqual: | + __ slt(regd, regr, regl); | + __ xori(regd, regd, 1); | + break; | + case lir_cond_greater: | + __ slt(regd, regr, regl); | + break; | + case lir_cond_greaterEqual: | + __ slt(regd, regl, regr); | + __ xori(regd, regd, 1); | + break; | + case lir_cond_belowEqual: | + __ sltu(regd, regr, regl); | + __ xori(regd, regd, 1); | + break; | + case lir_cond_aboveEqual: | + __ sltu(regd, regl, regr); | + __ xori(regd, regd, 1); | + break; | + default: | + ShouldNotReachHere(); | + } | + } | + return; | + } | + } | + | + // cmp | + if (regr == noreg) { | + switch (condition) { | + case lir_cond_equal: | + __ addi_d(SCR2, regl, -immr); | + break; | + case lir_cond_notEqual: | + __ addi_d(SCR2, regl, -immr); | + break; | + case lir_cond_less: | + __ slti(SCR2, regl, immr); | + break; | + case lir_cond_lessEqual: | + __ li(SCR1, immr); | + __ slt(SCR2, SCR1, regl); | + break; | + case lir_cond_greater: | + __ li(SCR1, immr); | + __ slt(SCR2, SCR1, regl); | + break; | + case lir_cond_greaterEqual: | + __ slti(SCR2, regl, immr); | + break; | + case lir_cond_belowEqual: | + __ li(SCR1, immr); | + __ sltu(SCR2, SCR1, regl); | + break; | + case lir_cond_aboveEqual: | + __ sltui(SCR2, regl, immr); | + break; | + default: | + ShouldNotReachHere(); | + } | + } else { | + switch (condition) { | + case lir_cond_equal: | + __ sub_d(SCR2, regl, regr); | + break; | + case lir_cond_notEqual: | + __ sub_d(SCR2, regl, regr); | + break; | + case lir_cond_less: | + __ slt(SCR2, regl, regr); | + break; | + case lir_cond_lessEqual: | + __ slt(SCR2, regr, regl); | + break; | + case lir_cond_greater: | + __ slt(SCR2, regr, regl); | + break; | + case lir_cond_greaterEqual: | + __ slt(SCR2, regl, regr); | + break; | + case lir_cond_belowEqual: | + __ sltu(SCR2, regr, regl); | + break; | + case lir_cond_aboveEqual: | + __ sltu(SCR2, regl, regr); | + break; | + default: | + ShouldNotReachHere(); | + } | + } | + | + // value operands | + if (src1->is_stack()) { | + stack2reg(src1, result, result->type()); | + reg1 = regd; | + } else if (src1->is_constant()) { | + const2reg(src1, result, lir_patch_none, NULL); | + reg1 = regd; | + } else { | + reg1 = (src1->type() == T_LONG) ? src1->as_register_lo() : src1->as_register(); | + } | + | + if (src2->is_stack()) { | + stack2reg(src2, FrameMap::scr1_opr, result->type()); | + reg2 = SCR1; | + } else if (src2->is_constant()) { | + LIR_Opr tmp = src2->type() == T_LONG ? FrameMap::scr1_long_opr : FrameMap::scr1_opr; | + const2reg(src2, tmp, lir_patch_none, NULL); | + reg2 = SCR1; | + } else { | + reg2 = (src2->type() == T_LONG) ? src2->as_register_lo() : src2->as_register(); | + } | + | + // cmove | + switch (condition) { | + case lir_cond_equal: | + __ masknez(regd, reg1, SCR2); | + __ maskeqz(SCR2, reg2, SCR2); | + break; | + case lir_cond_notEqual: | + __ maskeqz(regd, reg1, SCR2); | + __ masknez(SCR2, reg2, SCR2); | + break; | + case lir_cond_less: | + __ maskeqz(regd, reg1, SCR2); | + __ masknez(SCR2, reg2, SCR2); | + break; | + case lir_cond_lessEqual: | + __ masknez(regd, reg1, SCR2); | + __ maskeqz(SCR2, reg2, SCR2); | + break; | + case lir_cond_greater: | + __ maskeqz(regd, reg1, SCR2); | + __ masknez(SCR2, reg2, SCR2); | + break; | + case lir_cond_greaterEqual: | + __ masknez(regd, reg1, SCR2); | + __ maskeqz(SCR2, reg2, SCR2); | + break; | + case lir_cond_belowEqual: | + __ masknez(regd, reg1, SCR2); | + __ maskeqz(SCR2, reg2, SCR2); | + break; | + case lir_cond_aboveEqual: | + __ masknez(regd, reg1, SCR2); | + __ maskeqz(SCR2, reg2, SCR2); | + break; | + default: | + ShouldNotReachHere(); | + } | + | + __ OR(regd, regd, SCR2); | +} | + | +void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, | + CodeEmitInfo* info, bool pop_fpu_stack) { | + assert(info == NULL, "should never be used, idiv/irem and ldiv/lrem not handled by this method"); | + | + if (left->is_single_cpu()) { | + Register lreg = left->as_register(); | + Register dreg = as_reg(dest); | + | + if (right->is_single_cpu()) { | + // cpu register - cpu register | + assert(left->type() == T_INT && right->type() == T_INT && dest->type() == T_INT, "should be"); | + Register rreg = right->as_register(); | + switch (code) { | + case lir_add: __ add_w (dest->as_register(), lreg, rreg); break; | + case lir_sub: __ sub_w (dest->as_register(), lreg, rreg); break; | + case lir_mul: __ mul_w (dest->as_register(), lreg, rreg); break; | + default: ShouldNotReachHere(); | + } | + } else if (right->is_double_cpu()) { | + Register rreg = right->as_register_lo(); | + // single_cpu + double_cpu: can happen with obj+long | + assert(code == lir_add || code == lir_sub, "mismatched arithmetic op"); | + switch (code) { | + case lir_add: __ add_d(dreg, lreg, rreg); break; | + case lir_sub: __ sub_d(dreg, lreg, rreg); break; | + default: ShouldNotReachHere(); | + } | + } else if (right->is_constant()) { | + // cpu register - constant | + jlong c; | + | + // FIXME: This is fugly: we really need to factor all this logic. | + switch(right->type()) { | + case T_LONG: | + c = right->as_constant_ptr()->as_jlong(); | + break; | + case T_INT: | + case T_ADDRESS: | + c = right->as_constant_ptr()->as_jint(); | + break; | + default: | + ShouldNotReachHere(); | + c = 0; // unreachable | + break; | + } | + | + assert(code == lir_add || code == lir_sub, "mismatched arithmetic op"); | + if (c == 0 && dreg == lreg) { | + COMMENT("effective nop elided"); | + return; | + } | + | + switch(left->type()) { | + case T_INT: | + switch (code) { | + case lir_add: __ addi_w(dreg, lreg, c); break; | + case lir_sub: __ addi_w(dreg, lreg, -c); break; | + default: ShouldNotReachHere(); | + } | + break; | + case T_OBJECT: | + case T_ADDRESS: | + switch (code) { | + case lir_add: __ addi_d(dreg, lreg, c); break; | + case lir_sub: __ addi_d(dreg, lreg, -c); break; | + default: ShouldNotReachHere(); | + } | + break; | + default: | + ShouldNotReachHere(); | + } | + } else { | + ShouldNotReachHere(); | + } | + } else if (left->is_double_cpu()) { | + Register lreg_lo = left->as_register_lo(); | + | + if (right->is_double_cpu()) { | + // cpu register - cpu register | + Register rreg_lo = right->as_register_lo(); | + switch (code) { | + case lir_add: __ add_d(dest->as_register_lo(), lreg_lo, rreg_lo); break; | + case lir_sub: __ sub_d(dest->as_register_lo(), lreg_lo, rreg_lo); break; | + case lir_mul: __ mul_d(dest->as_register_lo(), lreg_lo, rreg_lo); break; | + case lir_div: __ div_d(dest->as_register_lo(), lreg_lo, rreg_lo); break; | + case lir_rem: __ mod_d(dest->as_register_lo(), lreg_lo, rreg_lo); break; | + default: ShouldNotReachHere(); | + } | + | + } else if (right->is_constant()) { | + jlong c = right->as_constant_ptr()->as_jlong(); | + Register dreg = as_reg(dest); | + switch (code) { | + case lir_add: | + case lir_sub: | + if (c == 0 && dreg == lreg_lo) { | + COMMENT("effective nop elided"); | + return; | + } | + code == lir_add ? __ addi_d(dreg, lreg_lo, c) : __ addi_d(dreg, lreg_lo, -c); | + break; | + case lir_div: | + assert(c > 0 && is_power_of_2(c), "divisor must be power-of-2 constant"); | + if (c == 1) { | + // move lreg_lo to dreg if divisor is 1 | + __ move(dreg, lreg_lo); | + } else { | + unsigned int shift = log2i_exact(c); | + // use scr1 as intermediate result register | + __ srai_d(SCR1, lreg_lo, 63); | + __ srli_d(SCR1, SCR1, 64 - shift); | + __ add_d(SCR1, lreg_lo, SCR1); | + __ srai_d(dreg, SCR1, shift); | + } | + break; | + case lir_rem: | + assert(c > 0 && is_power_of_2(c), "divisor must be power-of-2 constant"); | + if (c == 1) { | + // move 0 to dreg if divisor is 1 | + __ move(dreg, R0); | + } else { | + // use scr1/2 as intermediate result register | + __ sub_d(SCR1, R0, lreg_lo); | + __ slt(SCR2, SCR1, R0); | + __ andi(dreg, lreg_lo, c - 1); | + __ andi(SCR1, SCR1, c - 1); | + __ sub_d(SCR1, R0, SCR1); | + __ maskeqz(dreg, dreg, SCR2); | + __ masknez(SCR1, SCR1, SCR2); | + __ OR(dreg, dreg, SCR1); | + } | + break; | + default: | + ShouldNotReachHere(); | + } | + } else { | + ShouldNotReachHere(); | + } | + } else if (left->is_single_fpu()) { | + assert(right->is_single_fpu(), "right hand side of float arithmetics needs to be float register"); | + switch (code) { | + case lir_add: __ fadd_s (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; | + case lir_sub: __ fsub_s (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; | + case lir_mul: __ fmul_s (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; | + case lir_div: __ fdiv_s (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; | + default: ShouldNotReachHere(); | + } | + } else if (left->is_double_fpu()) { | + if (right->is_double_fpu()) { | + // fpu register - fpu register | + switch (code) { | + case lir_add: __ fadd_d (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; | + case lir_sub: __ fsub_d (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; | + case lir_mul: __ fmul_d (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; | + case lir_div: __ fdiv_d (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; | + default: ShouldNotReachHere(); | + } | + } else { | + if (right->is_constant()) { | + ShouldNotReachHere(); | + } | + ShouldNotReachHere(); | + } | + } else if (left->is_single_stack() || left->is_address()) { | + assert(left == dest, "left and dest must be equal"); | + ShouldNotReachHere(); | + } else { | + ShouldNotReachHere(); | + } | +} | + | +void LIR_Assembler::arith_fpu_implementation(LIR_Code code, int left_index, int right_index, | + int dest_index, bool pop_fpu_stack) { | + Unimplemented(); | +} | + | +void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr unused, LIR_Opr dest, LIR_Op* op) { | + switch(code) { | + case lir_abs : __ fabs_d(dest->as_double_reg(), value->as_double_reg()); break; | + case lir_sqrt: __ fsqrt_d(dest->as_double_reg(), value->as_double_reg()); break; | + default : ShouldNotReachHere(); | + } | +} | + | +void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst) { | + assert(left->is_single_cpu() || left->is_double_cpu(), "expect single or double register"); | + Register Rleft = left->is_single_cpu() ? left->as_register() : left->as_register_lo(); | + | + if (dst->is_single_cpu()) { | + Register Rdst = dst->as_register(); | + if (right->is_constant()) { | + switch (code) { | + case lir_logic_and: | + if (Assembler::is_uimm(right->as_jint(), 12)) { | + __ andi(Rdst, Rleft, right->as_jint()); | + } else { | + __ li(AT, right->as_jint()); | + __ AND(Rdst, Rleft, AT); | + } | + break; | + case lir_logic_or: __ ori(Rdst, Rleft, right->as_jint()); break; | + case lir_logic_xor: __ xori(Rdst, Rleft, right->as_jint()); break; | + default: ShouldNotReachHere(); break; | + } | + } else { | + Register Rright = right->is_single_cpu() ? right->as_register() : right->as_register_lo(); | + switch (code) { | + case lir_logic_and: __ AND(Rdst, Rleft, Rright); break; | + case lir_logic_or: __ OR(Rdst, Rleft, Rright); break; | + case lir_logic_xor: __ XOR(Rdst, Rleft, Rright); break; | + default: ShouldNotReachHere(); break; | + } | + } | + } else { | + Register Rdst = dst->as_register_lo(); | + if (right->is_constant()) { | + switch (code) { | + case lir_logic_and: | + if (Assembler::is_uimm(right->as_jlong(), 12)) { | + __ andi(Rdst, Rleft, right->as_jlong()); | + } else { | + // We can guarantee that transform from HIR LogicOp is in range of | + // uimm(12), but the common code directly generates LIR LogicAnd, | + // and the right-operand is mask with all ones in the high bits. | + __ li(AT, right->as_jlong()); | + __ AND(Rdst, Rleft, AT); | + } | + break; | + case lir_logic_or: __ ori(Rdst, Rleft, right->as_jlong()); break; | + case lir_logic_xor: __ xori(Rdst, Rleft, right->as_jlong()); break; | + default: ShouldNotReachHere(); break; | + } | + } else { | + Register Rright = right->is_single_cpu() ? right->as_register() : right->as_register_lo(); | + switch (code) { | + case lir_logic_and: __ AND(Rdst, Rleft, Rright); break; | + case lir_logic_or: __ OR(Rdst, Rleft, Rright); break; | + case lir_logic_xor: __ XOR(Rdst, Rleft, Rright); break; | + default: ShouldNotReachHere(); break; | + } | + } | + } | +} | + | +void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, | + LIR_Opr illegal, LIR_Opr result, CodeEmitInfo* info) { | + // opcode check | + assert((code == lir_idiv) || (code == lir_irem), "opcode must be idiv or irem"); | + bool is_irem = (code == lir_irem); | + | + // operand check | + assert(left->is_single_cpu(), "left must be register"); | + assert(right->is_single_cpu() || right->is_constant(), "right must be register or constant"); | + assert(result->is_single_cpu(), "result must be register"); | + Register lreg = left->as_register(); | + Register dreg = result->as_register(); | + | + // power-of-2 constant check and codegen | + if (right->is_constant()) { | + int c = right->as_constant_ptr()->as_jint(); | + assert(c > 0 && is_power_of_2(c), "divisor must be power-of-2 constant"); | + if (is_irem) { | + if (c == 1) { | + // move 0 to dreg if divisor is 1 | + __ move(dreg, R0); | + } else { | + // use scr1/2 as intermediate result register | + __ sub_w(SCR1, R0, lreg); | + __ slt(SCR2, SCR1, R0); | + __ andi(dreg, lreg, c - 1); | + __ andi(SCR1, SCR1, c - 1); | + __ sub_w(SCR1, R0, SCR1); | + __ maskeqz(dreg, dreg, SCR2); | + __ masknez(SCR1, SCR1, SCR2); | + __ OR(dreg, dreg, SCR1); | + } | + } else { | + if (c == 1) { | + // move lreg to dreg if divisor is 1 | + __ move(dreg, lreg); | + } else { | + unsigned int shift = exact_log2(c); | + // use scr1 as intermediate result register | + __ srai_w(SCR1, lreg, 31); | + __ srli_w(SCR1, SCR1, 32 - shift); | + __ add_w(SCR1, lreg, SCR1); | + __ srai_w(dreg, SCR1, shift); | + } | + } | + } else { | + Register rreg = right->as_register(); | + if (is_irem) | + __ mod_w(dreg, lreg, rreg); | + else | + __ div_w(dreg, lreg, rreg); | + } | +} | + | +void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Op2* op) { | + Unimplemented(); | +} | + | +void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst, LIR_Op2* op){ | + if (code == lir_cmp_fd2i || code == lir_ucmp_fd2i) { | + bool is_unordered_less = (code == lir_ucmp_fd2i); | + if (left->is_single_fpu()) { | + if (is_unordered_less) { | + __ fcmp_clt_s(FCC0, right->as_float_reg(), left->as_float_reg()); | + __ fcmp_cult_s(FCC1, left->as_float_reg(), right->as_float_reg()); | + } else { | + __ fcmp_cult_s(FCC0, right->as_float_reg(), left->as_float_reg()); | + __ fcmp_clt_s(FCC1, left->as_float_reg(), right->as_float_reg()); | + } | + } else if (left->is_double_fpu()) { | + if (is_unordered_less) { | + __ fcmp_clt_d(FCC0, right->as_double_reg(), left->as_double_reg()); | + __ fcmp_cult_d(FCC1, left->as_double_reg(), right->as_double_reg()); | + } else { | + __ fcmp_cult_d(FCC0, right->as_double_reg(), left->as_double_reg()); | + __ fcmp_clt_d(FCC1, left->as_double_reg(), right->as_double_reg()); | + } | + } else { | + ShouldNotReachHere(); | + } | + __ movcf2gr(dst->as_register(), FCC0); | + __ movcf2gr(SCR1, FCC1); | + __ sub_d(dst->as_register(), dst->as_register(), SCR1); | + } else if (code == lir_cmp_l2i) { | + __ slt(SCR1, left->as_register_lo(), right->as_register_lo()); | + __ slt(dst->as_register(), right->as_register_lo(), left->as_register_lo()); | + __ sub_d(dst->as_register(), dst->as_register(), SCR1); | + } else { | + ShouldNotReachHere(); | + } | +} | + | +void LIR_Assembler::align_call(LIR_Code code) {} | + | +void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) { | + address call = __ trampoline_call(AddressLiteral(op->addr(), rtype)); | + if (call == NULL) { | + bailout("trampoline stub overflow"); | + return; | + } | + add_call_info(code_offset(), op->info()); | +} | + | +void LIR_Assembler::ic_call(LIR_OpJavaCall* op) { | + address call = __ ic_call(op->addr()); | + if (call == NULL) { | + bailout("trampoline stub overflow"); | + return; | + } | + add_call_info(code_offset(), op->info()); | +} | + | +void LIR_Assembler::emit_static_call_stub() { | + address call_pc = __ pc(); | + address stub = __ start_a_stub(call_stub_size()); | + if (stub == NULL) { | + bailout("static call stub overflow"); | + return; | + } | + | + int start = __ offset(); | + | + __ relocate(static_stub_Relocation::spec(call_pc)); | + | + // Code stream for loading method may be changed. | + __ ibar(0); | + | + // Rmethod contains Method*, it should be relocated for GC | + // static stub relocation also tags the Method* in the code-stream. | + __ mov_metadata(Rmethod, NULL); | + // This is recognized as unresolved by relocs/nativeInst/ic code | + __ patchable_jump(__ pc()); | + | + assert(__ offset() - start + CompiledStaticCall::to_trampoline_stub_size() <= call_stub_size(), | + "stub too big"); | + __ end_a_stub(); | +} | + | +void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) { | + assert(exceptionOop->as_register() == A0, "must match"); | + assert(exceptionPC->as_register() == A1, "must match"); | + | + // exception object is not added to oop map by LinearScan | + // (LinearScan assumes that no oops are in fixed registers) | + info->add_register_oop(exceptionOop); | + Runtime1::StubID unwind_id; | + | + // get current pc information | + // pc is only needed if the method has an exception handler, the unwind code does not need it. | + if (compilation()->debug_info_recorder()->last_pc_offset() == __ offset()) { | + // As no instructions have been generated yet for this LIR node it's | + // possible that an oop map already exists for the current offset. | + // In that case insert an dummy NOP here to ensure all oop map PCs | + // are unique. See JDK-8237483. | + __ nop(); | + } | + Label L; | + int pc_for_athrow_offset = __ offset(); | + __ bind(L); | + __ lipc(exceptionPC->as_register(), L); | + add_call_info(pc_for_athrow_offset, info); // for exception handler | + | + __ verify_not_null_oop(A0); | + // search an exception handler (A0: exception oop, A1: throwing pc) | + if (compilation()->has_fpu_code()) { | + unwind_id = Runtime1::handle_exception_id; | + } else { | + unwind_id = Runtime1::handle_exception_nofpu_id; | + } | + __ call(Runtime1::entry_for(unwind_id), relocInfo::runtime_call_type); | + | + // FIXME: enough room for two byte trap ???? | + __ nop(); | +} | + | +void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) { | + assert(exceptionOop->as_register() == A0, "must match"); | + __ b(_unwind_handler_entry); | +} | + | +void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) { | + Register lreg = left->is_single_cpu() ? left->as_register() : left->as_register_lo(); | + Register dreg = dest->is_single_cpu() ? dest->as_register() : dest->as_register_lo(); | + | + switch (left->type()) { | + case T_INT: { | + switch (code) { | + case lir_shl: __ sll_w(dreg, lreg, count->as_register()); break; | + case lir_shr: __ sra_w(dreg, lreg, count->as_register()); break; | + case lir_ushr: __ srl_w(dreg, lreg, count->as_register()); break; | + default: ShouldNotReachHere(); break; | + } | + break; | + case T_LONG: | + case T_ADDRESS: | + case T_OBJECT: | + switch (code) { | + case lir_shl: __ sll_d(dreg, lreg, count->as_register()); break; | + case lir_shr: __ sra_d(dreg, lreg, count->as_register()); break; | + case lir_ushr: __ srl_d(dreg, lreg, count->as_register()); break; | + default: ShouldNotReachHere(); break; | + } | + break; | + default: | + ShouldNotReachHere(); | + break; | + } | + } | +} | + | +void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest) { | + Register dreg = dest->is_single_cpu() ? dest->as_register() : dest->as_register_lo(); | + Register lreg = left->is_single_cpu() ? left->as_register() : left->as_register_lo(); | + | + switch (left->type()) { | + case T_INT: { | + switch (code) { | + case lir_shl: __ slli_w(dreg, lreg, count); break; | + case lir_shr: __ srai_w(dreg, lreg, count); break; | + case lir_ushr: __ srli_w(dreg, lreg, count); break; | + default: ShouldNotReachHere(); break; | + } | + break; | + case T_LONG: | + case T_ADDRESS: | + case T_OBJECT: | + switch (code) { | + case lir_shl: __ slli_d(dreg, lreg, count); break; | + case lir_shr: __ srai_d(dreg, lreg, count); break; | + case lir_ushr: __ srli_d(dreg, lreg, count); break; | + default: ShouldNotReachHere(); break; | + } | + break; | + default: | + ShouldNotReachHere(); | + break; | + } | + } | +} | + | +void LIR_Assembler::store_parameter(Register r, int offset_from_sp_in_words) { | + assert(offset_from_sp_in_words >= 0, "invalid offset from sp"); | + int offset_from_sp_in_bytes = offset_from_sp_in_words * BytesPerWord; | + assert(offset_from_sp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); | + __ st_ptr(r, Address(SP, offset_from_sp_in_bytes)); | +} | + | +void LIR_Assembler::store_parameter(jint c, int offset_from_sp_in_words) { | + assert(offset_from_sp_in_words >= 0, "invalid offset from sp"); | + int offset_from_sp_in_bytes = offset_from_sp_in_words * BytesPerWord; | + assert(offset_from_sp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); | + __ li(SCR2, c); | + __ st_ptr(SCR2, Address(SP, offset_from_sp_in_bytes)); | +} | + | +void LIR_Assembler::store_parameter(jobject o, int offset_from_sp_in_words) { | + ShouldNotReachHere(); | +} | + | +// This code replaces a call to arraycopy; no exception may | +// be thrown in this code, they must be thrown in the System.arraycopy | +// activation frame; we could save some checks if this would not be the case | +void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { | + Register j_rarg0 = T0; | + Register j_rarg1 = A0; | + Register j_rarg2 = A1; | + Register j_rarg3 = A2; | + Register j_rarg4 = A3; | + | + ciArrayKlass* default_type = op->expected_type(); | + Register src = op->src()->as_register(); | + Register dst = op->dst()->as_register(); | + Register src_pos = op->src_pos()->as_register(); | + Register dst_pos = op->dst_pos()->as_register(); | + Register length = op->length()->as_register(); | + Register tmp = op->tmp()->as_register(); | + | + CodeStub* stub = op->stub(); | + int flags = op->flags(); | + BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL; | + if (is_reference_type(basic_type)) | + basic_type = T_OBJECT; | + | + // if we don't know anything, just go through the generic arraycopy | + if (default_type == NULL) { | + Label done; | + assert(src == T0 && src_pos == A0, "mismatch in calling convention"); | + | + // Save the arguments in case the generic arraycopy fails and we | + // have to fall back to the JNI stub | + __ st_ptr(dst, Address(SP, 0 * BytesPerWord)); | + __ st_ptr(dst_pos, Address(SP, 1 * BytesPerWord)); | + __ st_ptr(length, Address(SP, 2 * BytesPerWord)); | + __ st_ptr(src_pos, Address(SP, 3 * BytesPerWord)); | + __ st_ptr(src, Address(SP, 4 * BytesPerWord)); | + | + address copyfunc_addr = StubRoutines::generic_arraycopy(); | + assert(copyfunc_addr != NULL, "generic arraycopy stub required"); | + | + // The arguments are in java calling convention so we shift them | + // to C convention | + assert_different_registers(A4, j_rarg0, j_rarg1, j_rarg2, j_rarg3); | + __ move(A4, j_rarg4); | + assert_different_registers(A3, j_rarg0, j_rarg1, j_rarg2); | + __ move(A3, j_rarg3); | + assert_different_registers(A2, j_rarg0, j_rarg1); | + __ move(A2, j_rarg2); | + assert_different_registers(A1, j_rarg0); | + __ move(A1, j_rarg1); | + __ move(A0, j_rarg0); | +#ifndef PRODUCT | + if (PrintC1Statistics) { | + __ li(SCR2, (address)&Runtime1::_generic_arraycopystub_cnt); | + __ increment(SCR2, 1); | + } | +#endif | + __ call(copyfunc_addr, relocInfo::runtime_call_type); | + | + __ beqz(A0, *stub->continuation()); | + __ move(tmp, A0); | + | + // Reload values from the stack so they are where the stub | + // expects them. | + __ ld_ptr(dst, Address(SP, 0 * BytesPerWord)); | + __ ld_ptr(dst_pos, Address(SP, 1 * BytesPerWord)); | + __ ld_ptr(length, Address(SP, 2 * BytesPerWord)); | + __ ld_ptr(src_pos, Address(SP, 3 * BytesPerWord)); | + __ ld_ptr(src, Address(SP, 4 * BytesPerWord)); | + | + // tmp is -1^K where K == partial copied count | + __ nor(SCR1, tmp, R0); | + // adjust length down and src/end pos up by partial copied count | + __ sub_w(length, length, SCR1); | + __ add_w(src_pos, src_pos, SCR1); | + __ add_w(dst_pos, dst_pos, SCR1); | + __ b(*stub->entry()); | + | + __ bind(*stub->continuation()); | + return; | + } | + | + assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), | + "must be true at this point"); | + | + int elem_size = type2aelembytes(basic_type); | + Address::ScaleFactor scale = Address::times(elem_size); | + | + Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes()); | + Address dst_length_addr = Address(dst, arrayOopDesc::length_offset_in_bytes()); | + Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes()); | + Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes()); | + | + // test for NULL | + if (flags & LIR_OpArrayCopy::src_null_check) { | + __ beqz(src, *stub->entry()); | + } | + if (flags & LIR_OpArrayCopy::dst_null_check) { | + __ beqz(dst, *stub->entry()); | + } | + | + // If the compiler was not able to prove that exact type of the source or the destination | + // of the arraycopy is an array type, check at runtime if the source or the destination is | + // an instance type. | + if (flags & LIR_OpArrayCopy::type_check) { | + if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) { | + __ load_klass(tmp, dst); | + __ ld_w(SCR1, Address(tmp, in_bytes(Klass::layout_helper_offset()))); | + __ li(SCR2, Klass::_lh_neutral_value); | + __ bge_far(SCR1, SCR2, *stub->entry(), true); | + } | + | + if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) { | + __ load_klass(tmp, src); | + __ ld_w(SCR1, Address(tmp, in_bytes(Klass::layout_helper_offset()))); | + __ li(SCR2, Klass::_lh_neutral_value); | + __ bge_far(SCR1, SCR2, *stub->entry(), true); | + } | + } | + | + // check if negative | + if (flags & LIR_OpArrayCopy::src_pos_positive_check) { | + __ blt_far(src_pos, R0, *stub->entry(), true); | + } | + if (flags & LIR_OpArrayCopy::dst_pos_positive_check) { | + __ blt_far(dst_pos, R0, *stub->entry(), true); | + } | + | + if (flags & LIR_OpArrayCopy::length_positive_check) { | + __ blt_far(length, R0, *stub->entry(), true); | + } | + | + if (flags & LIR_OpArrayCopy::src_range_check) { | + __ add_w(tmp, src_pos, length); | + __ ld_wu(SCR1, src_length_addr); | + __ blt_far(SCR1, tmp, *stub->entry(), false); | + } | + if (flags & LIR_OpArrayCopy::dst_range_check) { | + __ add_w(tmp, dst_pos, length); | + __ ld_wu(SCR1, dst_length_addr); | + __ blt_far(SCR1, tmp, *stub->entry(), false); | + } | + | + if (flags & LIR_OpArrayCopy::type_check) { | + // We don't know the array types are compatible | + if (basic_type != T_OBJECT) { | + // Simple test for basic type arrays | + if (UseCompressedClassPointers) { | + __ ld_wu(tmp, src_klass_addr); | + __ ld_wu(SCR1, dst_klass_addr); | + } else { | + __ ld_ptr(tmp, src_klass_addr); | + __ ld_ptr(SCR1, dst_klass_addr); | + } | + __ bne_far(tmp, SCR1, *stub->entry()); | + } else { | + // For object arrays, if src is a sub class of dst then we can | + // safely do the copy. | + Label cont, slow; | + | + __ addi_d(SP, SP, -2 * wordSize); | + __ st_ptr(dst, Address(SP, 0 * wordSize)); | + __ st_ptr(src, Address(SP, 1 * wordSize)); | + | + __ load_klass(src, src); | + __ load_klass(dst, dst); | + | + __ check_klass_subtype_fast_path(src, dst, tmp, &cont, &slow, NULL); | + | + __ addi_d(SP, SP, -2 * wordSize); | + __ st_ptr(dst, Address(SP, 0 * wordSize)); | + __ st_ptr(src, Address(SP, 1 * wordSize)); | + __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); | + __ ld_ptr(dst, Address(SP, 0 * wordSize)); | + __ ld_ptr(src, Address(SP, 1 * wordSize)); | + __ addi_d(SP, SP, 2 * wordSize); | + | + __ bnez(dst, cont); | + | + __ bind(slow); | + __ ld_ptr(dst, Address(SP, 0 * wordSize)); | + __ ld_ptr(src, Address(SP, 1 * wordSize)); | + __ addi_d(SP, SP, 2 * wordSize); | + | + address copyfunc_addr = StubRoutines::checkcast_arraycopy(); | + if (copyfunc_addr != NULL) { // use stub if available | + // src is not a sub class of dst so we have to do a | + // per-element check. | + | + int mask = LIR_OpArrayCopy::src_objarray|LIR_OpArrayCopy::dst_objarray; | + if ((flags & mask) != mask) { | + // Check that at least both of them object arrays. | + assert(flags & mask, "one of the two should be known to be an object array"); | + | + if (!(flags & LIR_OpArrayCopy::src_objarray)) { | + __ load_klass(tmp, src); | + } else if (!(flags & LIR_OpArrayCopy::dst_objarray)) { | + __ load_klass(tmp, dst); | + } | + int lh_offset = in_bytes(Klass::layout_helper_offset()); | + Address klass_lh_addr(tmp, lh_offset); | + jint objArray_lh = Klass::array_layout_helper(T_OBJECT); | + __ ld_w(SCR1, klass_lh_addr); | + __ li(SCR2, objArray_lh); | + __ XOR(SCR1, SCR1, SCR2); | + __ bnez(SCR1, *stub->entry()); | + } | + | + // Spill because stubs can use any register they like and it's | + // easier to restore just those that we care about. | + __ st_ptr(dst, Address(SP, 0 * BytesPerWord)); | + __ st_ptr(dst_pos, Address(SP, 1 * BytesPerWord)); | + __ st_ptr(length, Address(SP, 2 * BytesPerWord)); | + __ st_ptr(src_pos, Address(SP, 3 * BytesPerWord)); | + __ st_ptr(src, Address(SP, 4 * BytesPerWord)); | + | + __ lea(A0, Address(src, src_pos, scale)); | + __ addi_d(A0, A0, arrayOopDesc::base_offset_in_bytes(basic_type)); | + assert_different_registers(A0, dst, dst_pos, length); | + __ load_klass(A4, dst); | + assert_different_registers(A4, dst, dst_pos, length); | + __ lea(A1, Address(dst, dst_pos, scale)); | + __ addi_d(A1, A1, arrayOopDesc::base_offset_in_bytes(basic_type)); | + assert_different_registers(A1, length); | + __ bstrpick_d(A2, length, 31, 0); | + __ ld_ptr(A4, Address(A4, ObjArrayKlass::element_klass_offset())); | + __ ld_w(A3, Address(A4, Klass::super_check_offset_offset())); | + __ call(copyfunc_addr, relocInfo::runtime_call_type); | + | +#ifndef PRODUCT | + if (PrintC1Statistics) { | + Label failed; | + __ bnez(A0, failed); | + __ li(SCR2, (address)&Runtime1::_arraycopy_checkcast_cnt); | + __ increment(SCR2, 1); | + __ bind(failed); | + } | +#endif | + | + __ beqz(A0, *stub->continuation()); | + | +#ifndef PRODUCT | + if (PrintC1Statistics) { | + __ li(SCR2, (address)&Runtime1::_arraycopy_checkcast_attempt_cnt); | + __ increment(SCR2, 1); | + } | +#endif | + assert_different_registers(dst, dst_pos, length, src_pos, src, tmp, SCR1); | + __ move(tmp, A0); | + | + // Restore previously spilled arguments | + __ ld_ptr(dst, Address(SP, 0 * BytesPerWord)); | + __ ld_ptr(dst_pos, Address(SP, 1 * BytesPerWord)); | + __ ld_ptr(length, Address(SP, 2 * BytesPerWord)); | + __ ld_ptr(src_pos, Address(SP, 3 * BytesPerWord)); | + __ ld_ptr(src, Address(SP, 4 * BytesPerWord)); | + | + // return value is -1^K where K is partial copied count | + __ nor(SCR1, tmp, R0); | + // adjust length down and src/end pos up by partial copied count | + __ sub_w(length, length, SCR1); | + __ add_w(src_pos, src_pos, SCR1); | + __ add_w(dst_pos, dst_pos, SCR1); | + } | + | + __ b(*stub->entry()); | + | + __ bind(cont); | + __ ld_ptr(dst, Address(SP, 0 * wordSize)); | + __ ld_ptr(src, Address(SP, 1 * wordSize)); | + __ addi_d(SP, SP, 2 * wordSize); | + } | + } | + | +#ifdef ASSERT | + if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) { | + // Sanity check the known type with the incoming class. For the | + // primitive case the types must match exactly with src.klass and | + // dst.klass each exactly matching the default type. For the | + // object array case, if no type check is needed then either the | + // dst type is exactly the expected type and the src type is a | + // subtype which we can't check or src is the same array as dst | + // but not necessarily exactly of type default_type. | + Label known_ok, halt; | + __ mov_metadata(tmp, default_type->constant_encoding()); | + if (UseCompressedClassPointers) { | + __ encode_klass_not_null(tmp); | + } | + | + if (basic_type != T_OBJECT) { | + | + if (UseCompressedClassPointers) { | + __ ld_wu(SCR1, dst_klass_addr); | + } else { | + __ ld_ptr(SCR1, dst_klass_addr); | + } | + __ bne(tmp, SCR1, halt); | + if (UseCompressedClassPointers) { | + __ ld_wu(SCR1, src_klass_addr); | + } else { | + __ ld_ptr(SCR1, src_klass_addr); | + } | + __ beq(tmp, SCR1, known_ok); | + } else { | + if (UseCompressedClassPointers) { | + __ ld_wu(SCR1, dst_klass_addr); | + } else { | + __ ld_ptr(SCR1, dst_klass_addr); | + } | + __ beq(tmp, SCR1, known_ok); | + __ beq(src, dst, known_ok); | + } | + __ bind(halt); | + __ stop("incorrect type information in arraycopy"); | + __ bind(known_ok); | + } | +#endif | + | +#ifndef PRODUCT | + if (PrintC1Statistics) { | + __ li(SCR2, Runtime1::arraycopy_count_address(basic_type)); | + __ increment(SCR2, 1); | + } | +#endif | + | + __ lea(A0, Address(src, src_pos, scale)); | + __ addi_d(A0, A0, arrayOopDesc::base_offset_in_bytes(basic_type)); | + assert_different_registers(A0, dst, dst_pos, length); | + __ lea(A1, Address(dst, dst_pos, scale)); | + __ addi_d(A1, A1, arrayOopDesc::base_offset_in_bytes(basic_type)); | + assert_different_registers(A1, length); | + __ bstrpick_d(A2, length, 31, 0); | + | + bool disjoint = (flags & LIR_OpArrayCopy::overlapping) == 0; | + bool aligned = (flags & LIR_OpArrayCopy::unaligned) == 0; | + const char *name; | + address entry = StubRoutines::select_arraycopy_function(basic_type, aligned, disjoint, name, false); | + | + CodeBlob *cb = CodeCache::find_blob(entry); | + if (cb) { | + __ call(entry, relocInfo::runtime_call_type); | + } else { | + __ call_VM_leaf(entry, 3); | + } | + | + __ bind(*stub->continuation()); | +} | + | +void LIR_Assembler::emit_lock(LIR_OpLock* op) { | + Register obj = op->obj_opr()->as_register(); // may not be an oop | + Register hdr = op->hdr_opr()->as_register(); | + Register lock = op->lock_opr()->as_register(); | + if (!UseFastLocking) { | + __ b(*op->stub()->entry()); | + } else if (op->code() == lir_lock) { | + Register scratch = noreg; | + if (UseBiasedLocking) { | + scratch = op->scratch_opr()->as_register(); | + } | + assert(BasicLock::displaced_header_offset_in_bytes() == 0, | + "lock_reg must point to the displaced header"); | + // add debug info for NullPointerException only if one is possible | + int null_check_offset = __ lock_object(hdr, obj, lock, scratch, *op->stub()->entry()); | + if (op->info() != NULL) { | + add_debug_info_for_null_check(null_check_offset, op->info()); | + } | + // done | + } else if (op->code() == lir_unlock) { | + assert(BasicLock::displaced_header_offset_in_bytes() == 0, | + "lock_reg must point to the displaced header"); | + __ unlock_object(hdr, obj, lock, *op->stub()->entry()); | + } else { | + Unimplemented(); | + } | + __ bind(*op->stub()->continuation()); | +} | + | +void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { | + ciMethod* method = op->profiled_method(); | + ciMethod* callee = op->profiled_callee(); | + int bci = op->profiled_bci(); | + | + // Update counter for all call types | + ciMethodData* md = method->method_data_or_null(); | + assert(md != NULL, "Sanity"); | + ciProfileData* data = md->bci_to_data(bci); | + assert(data != NULL && data->is_CounterData(), "need CounterData for calls"); | + assert(op->mdo()->is_single_cpu(), "mdo must be allocated"); | + Register mdo = op->mdo()->as_register(); | + __ mov_metadata(mdo, md->constant_encoding()); | + Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); | + // Perform additional virtual call profiling for invokevirtual and | + // invokeinterface bytecodes | + if (op->should_profile_receiver_type()) { | + assert(op->recv()->is_single_cpu(), "recv must be allocated"); | + Register recv = op->recv()->as_register(); | + assert_different_registers(mdo, recv); | + assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls"); | + ciKlass* known_klass = op->known_holder(); | + if (C1OptimizeVirtualCallProfiling && known_klass != NULL) { | + // We know the type that will be seen at this call site; we can | + // statically update the MethodData* rather than needing to do | + // dynamic tests on the receiver type | + | + // NOTE: we should probably put a lock around this search to | + // avoid collisions by concurrent compilations | + ciVirtualCallData* vc_data = (ciVirtualCallData*) data; | + uint i; | + for (i = 0; i < VirtualCallData::row_limit(); i++) { | + ciKlass* receiver = vc_data->receiver(i); | + if (known_klass->equals(receiver)) { | + Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); | + __ ld_ptr(SCR2, data_addr); | + __ addi_d(SCR2, SCR2, DataLayout::counter_increment); | + __ st_ptr(SCR2, data_addr); | + return; | + } | + } | + | + // Receiver type not found in profile data; select an empty slot | + | + // Note that this is less efficient than it should be because it | + // always does a write to the receiver part of the | + // VirtualCallData rather than just the first time | + for (i = 0; i < VirtualCallData::row_limit(); i++) { | + ciKlass* receiver = vc_data->receiver(i); | + if (receiver == NULL) { | + Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); | + __ mov_metadata(SCR2, known_klass->constant_encoding()); | + __ lea(SCR1, recv_addr); | + __ st_ptr(SCR2, SCR1, 0); | + Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); | + __ ld_ptr(SCR2, data_addr); | + __ addi_d(SCR2, SCR1, DataLayout::counter_increment); | + __ st_ptr(SCR2, data_addr); | + return; | + } | + } | + } else { | + __ load_klass(recv, recv); | + Label update_done; | + type_profile_helper(mdo, md, data, recv, &update_done); | + // Receiver did not match any saved receiver and there is no empty row for it. | + // Increment total counter to indicate polymorphic case. | + __ ld_ptr(SCR2, counter_addr); | + __ addi_d(SCR2, SCR2, DataLayout::counter_increment); | + __ st_ptr(SCR2, counter_addr); | + | + __ bind(update_done); | + } | + } else { | + // Static call | + __ ld_ptr(SCR2, counter_addr); | + __ addi_d(SCR2, SCR2, DataLayout::counter_increment); | + __ st_ptr(SCR2, counter_addr); | + } | +} | + | +void LIR_Assembler::emit_delay(LIR_OpDelay*) { | + Unimplemented(); | +} | + | +void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) { | + __ lea(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no)); | +} | + | +void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) { | + assert(op->crc()->is_single_cpu(), "crc must be register"); | + assert(op->val()->is_single_cpu(), "byte value must be register"); | + assert(op->result_opr()->is_single_cpu(), "result must be register"); | + Register crc = op->crc()->as_register(); | + Register val = op->val()->as_register(); | + Register res = op->result_opr()->as_register(); | + | + assert_different_registers(val, crc, res); | + __ li(res, StubRoutines::crc_table_addr()); | + __ nor(crc, crc, R0); // ~crc | + __ update_byte_crc32(crc, val, res); | + __ nor(res, crc, R0); // ~crc | +} | + | +void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { | + COMMENT("emit_profile_type {"); | + Register obj = op->obj()->as_register(); | + Register tmp = op->tmp()->as_pointer_register(); | + Address mdo_addr = as_Address(op->mdp()->as_address_ptr()); | + ciKlass* exact_klass = op->exact_klass(); | + intptr_t current_klass = op->current_klass(); | + bool not_null = op->not_null(); | + bool no_conflict = op->no_conflict(); | + | + Label update, next, none; | + | + bool do_null = !not_null; | + bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass; | + bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set; | + | + assert(do_null || do_update, "why are we here?"); | + assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?"); | + assert(mdo_addr.base() != SCR1, "wrong register"); | + | + __ verify_oop(obj); | + | + if (tmp != obj) { | + __ move(tmp, obj); | + } | + if (do_null) { | + __ bnez(tmp, update); | + if (!TypeEntries::was_null_seen(current_klass)) { | + __ ld_ptr(SCR2, mdo_addr); | + __ ori(SCR2, SCR2, TypeEntries::null_seen); | + __ st_ptr(SCR2, mdo_addr); | + } | + if (do_update) { | +#ifndef ASSERT | + __ b(next); | + } | +#else | + __ b(next); | + } | + } else { | + __ bnez(tmp, update); | + __ stop("unexpected null obj"); | +#endif | + } | + | + __ bind(update); | + | + if (do_update) { | +#ifdef ASSERT | + if (exact_klass != NULL) { | + Label ok; | + __ load_klass(tmp, tmp); | + __ mov_metadata(SCR1, exact_klass->constant_encoding()); | + __ XOR(SCR1, tmp, SCR1); | + __ beqz(SCR1, ok); | + __ stop("exact klass and actual klass differ"); | + __ bind(ok); | + } | +#endif | + if (!no_conflict) { | + if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) { | + if (exact_klass != NULL) { | + __ mov_metadata(tmp, exact_klass->constant_encoding()); | + } else { | + __ load_klass(tmp, tmp); | + } | + | + __ ld_ptr(SCR2, mdo_addr); | + __ XOR(tmp, tmp, SCR2); | + assert(TypeEntries::type_klass_mask == -4, "must be"); | + __ bstrpick_d(SCR1, tmp, 63, 2); | + // klass seen before, nothing to do. The unknown bit may have been | + // set already but no need to check. | + __ beqz(SCR1, next); | + | + __ andi(SCR1, tmp, TypeEntries::type_unknown); | + __ bnez(SCR1, next); // already unknown. Nothing to do anymore. | + | + if (TypeEntries::is_type_none(current_klass)) { | + __ beqz(SCR2, none); | + __ li(SCR1, (u1)TypeEntries::null_seen); | + __ beq(SCR2, SCR1, none); | + // There is a chance that the checks above (re-reading profiling | + // data from memory) fail if another thread has just set the | + // profiling to this obj's klass | + membar_acquire(); | + __ ld_ptr(SCR2, mdo_addr); | + __ XOR(tmp, tmp, SCR2); | + assert(TypeEntries::type_klass_mask == -4, "must be"); | + __ bstrpick_d(SCR1, tmp, 63, 2); | + __ beqz(SCR1, next); | + } | + } else { | + assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && | + ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only"); | + | + __ ld_ptr(tmp, mdo_addr); | + __ andi(SCR2, tmp, TypeEntries::type_unknown); | + __ bnez(SCR2, next); // already unknown. Nothing to do anymore. | + } | + | + // different than before. Cannot keep accurate profile. | + __ ld_ptr(SCR2, mdo_addr); | + __ ori(SCR2, SCR2, TypeEntries::type_unknown); | + __ st_ptr(SCR2, mdo_addr); | + | + if (TypeEntries::is_type_none(current_klass)) { | + __ b(next); | + | + __ bind(none); | + // first time here. Set profile type. | + __ st_ptr(tmp, mdo_addr); | + } | + } else { | + // There's a single possible klass at this profile point | + assert(exact_klass != NULL, "should be"); | + if (TypeEntries::is_type_none(current_klass)) { | + __ mov_metadata(tmp, exact_klass->constant_encoding()); | + __ ld_ptr(SCR2, mdo_addr); | + __ XOR(tmp, tmp, SCR2); | + assert(TypeEntries::type_klass_mask == -4, "must be"); | + __ bstrpick_d(SCR1, tmp, 63, 2); | + __ beqz(SCR1, next); | +#ifdef ASSERT | + { | + Label ok; | + __ ld_ptr(SCR1, mdo_addr); | + __ beqz(SCR1, ok); | + __ li(SCR2, (u1)TypeEntries::null_seen); | + __ beq(SCR1, SCR2, ok); | + // may have been set by another thread | + membar_acquire(); | + __ mov_metadata(SCR1, exact_klass->constant_encoding()); | + __ ld_ptr(SCR2, mdo_addr); | + __ XOR(SCR2, SCR1, SCR2); | + assert(TypeEntries::type_mask == -2, "must be"); | + __ bstrpick_d(SCR2, SCR2, 63, 1); | + __ beqz(SCR2, ok); | + | + __ stop("unexpected profiling mismatch"); | + __ bind(ok); | + } | +#endif | + // first time here. Set profile type. | + __ st_ptr(tmp, mdo_addr); | + } else { | + assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && | + ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent"); | + | + __ ld_ptr(tmp, mdo_addr); | + __ andi(SCR1, tmp, TypeEntries::type_unknown); | + __ bnez(SCR1, next); // already unknown. Nothing to do anymore. | + | + __ ori(tmp, tmp, TypeEntries::type_unknown); | + __ st_ptr(tmp, mdo_addr); | + // FIXME: Write barrier needed here? | + } | + } | + | + __ bind(next); | + } | + COMMENT("} emit_profile_type"); | +} | + | +void LIR_Assembler::align_backward_branch_target() {} | + | +void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest, LIR_Opr tmp) { | + // tmp must be unused | + assert(tmp->is_illegal(), "wasting a register if tmp is allocated"); | + | + if (left->is_single_cpu()) { | + assert(dest->is_single_cpu(), "expect single result reg"); | + __ sub_w(dest->as_register(), R0, left->as_register()); | + } else if (left->is_double_cpu()) { | + assert(dest->is_double_cpu(), "expect double result reg"); | + __ sub_d(dest->as_register_lo(), R0, left->as_register_lo()); | + } else if (left->is_single_fpu()) { | + assert(dest->is_single_fpu(), "expect single float result reg"); | + __ fneg_s(dest->as_float_reg(), left->as_float_reg()); | + } else { | + assert(left->is_double_fpu(), "expect double float operand reg"); | + assert(dest->is_double_fpu(), "expect double float result reg"); | + __ fneg_d(dest->as_double_reg(), left->as_double_reg()); | + } | +} | + | +void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest, LIR_PatchCode patch_code, | + CodeEmitInfo* info) { | + if (patch_code != lir_patch_none) { | + deoptimize_trap(info); | + return; | + } | + | + __ lea(dest->as_register_lo(), as_Address(addr->as_address_ptr())); | +} | + | +void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, | + LIR_Opr tmp, CodeEmitInfo* info) { | + assert(!tmp->is_valid(), "don't need temporary"); | + __ call(dest, relocInfo::runtime_call_type); | + if (info != NULL) { | + add_call_info_here(info); | + } | +} | + | +void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, | + CodeEmitInfo* info) { | + if (dest->is_address() || src->is_address()) { | + move_op(src, dest, type, lir_patch_none, info, | + /*pop_fpu_stack*/false, /*unaligned*/false, /*wide*/false); | + } else { | + ShouldNotReachHere(); | + } | +} | + | +#ifdef ASSERT | +// emit run-time assertion | +void LIR_Assembler::emit_assert(LIR_OpAssert* op) { | + assert(op->code() == lir_assert, "must be"); | + Label ok; | + | + if (op->in_opr1()->is_valid()) { | + assert(op->in_opr2()->is_valid(), "both operands must be valid"); | + assert(op->in_opr1()->is_cpu_register() || op->in_opr2()->is_cpu_register(), "must be"); | + Register reg1 = as_reg(op->in_opr1()); | + Register reg2 = as_reg(op->in_opr2()); | + switch (op->condition()) { | + case lir_cond_equal: __ beq(reg1, reg2, ok); break; | + case lir_cond_notEqual: __ bne(reg1, reg2, ok); break; | + case lir_cond_less: __ blt(reg1, reg2, ok); break; | + case lir_cond_lessEqual: __ bge(reg2, reg1, ok); break; | + case lir_cond_greaterEqual: __ bge(reg1, reg2, ok); break; | + case lir_cond_greater: __ blt(reg2, reg1, ok); break; | + case lir_cond_belowEqual: __ bgeu(reg2, reg1, ok); break; | + case lir_cond_aboveEqual: __ bgeu(reg1, reg2, ok); break; | + default: ShouldNotReachHere(); | + } | + } else { | + assert(op->in_opr2()->is_illegal(), "both operands must be illegal"); | + assert(op->condition() == lir_cond_always, "no other conditions allowed"); | + } | + if (op->halt()) { | + const char* str = __ code_string(op->msg()); | + __ stop(str); | + } else { | + breakpoint(); | + } | + __ bind(ok); | +} | +#endif | + | +#ifndef PRODUCT | +#define COMMENT(x) do { __ block_comment(x); } while (0) | +#else | +#define COMMENT(x) | +#endif | + | +void LIR_Assembler::membar() { | + COMMENT("membar"); | + __ membar(Assembler::AnyAny); | +} | + | +void LIR_Assembler::membar_acquire() { | + __ membar(Assembler::Membar_mask_bits(Assembler::LoadLoad | Assembler::LoadStore)); | +} | + | +void LIR_Assembler::membar_release() { | + __ membar(Assembler::Membar_mask_bits(Assembler::LoadStore|Assembler::StoreStore)); | +} | + | +void LIR_Assembler::membar_loadload() { | + __ membar(Assembler::LoadLoad); | +} | + | +void LIR_Assembler::membar_storestore() { | + __ membar(MacroAssembler::StoreStore); | +} | + | +void LIR_Assembler::membar_loadstore() { | + __ membar(MacroAssembler::LoadStore); | +} | + | +void LIR_Assembler::membar_storeload() { | + __ membar(MacroAssembler::StoreLoad); | +} | + | +void LIR_Assembler::on_spin_wait() { | + Unimplemented(); | +} | + | +void LIR_Assembler::get_thread(LIR_Opr result_reg) { | + __ move(result_reg->as_register(), TREG); | +} | + | +void LIR_Assembler::peephole(LIR_List *lir) { | +} | + | +void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, | + LIR_Opr dest, LIR_Opr tmp_op) { | + Address addr = as_Address(src->as_address_ptr()); | + BasicType type = src->type(); | + Register dst = as_reg(dest); | + Register tmp = as_reg(tmp_op); | + bool is_oop = is_reference_type(type); | + | + if (Assembler::is_simm(addr.disp(), 12)) { | + __ addi_d(tmp, addr.base(), addr.disp()); | + } else { | + __ li(tmp, addr.disp()); | + __ add_d(tmp, addr.base(), tmp); | + } | + if (addr.index() != noreg) { | + if (addr.scale() != Address::no_scale) | + __ alsl_d(tmp, addr.index(), tmp, addr.scale() - 1); | + else | + __ add_d(tmp, tmp, addr.index()); | + } | + | + switch(type) { | + case T_INT: | + break; | + case T_LONG: | + break; | + case T_OBJECT: | + case T_ARRAY: | + if (UseCompressedOops) { | + // unsigned int | + } else { | + // long | + } | + break; | + default: | + ShouldNotReachHere(); | + } | + | + if (code == lir_xadd) { | + Register inc = noreg; | + if (data->is_constant()) { | + inc = SCR1; | + __ li(inc, as_long(data)); | + } else { | + inc = as_reg(data); | + } | + switch(type) { | + case T_INT: | + __ amadd_db_w(dst, inc, tmp); | + break; | + case T_LONG: | + __ amadd_db_d(dst, inc, tmp); | + break; | + case T_OBJECT: | + case T_ARRAY: | + if (UseCompressedOops) { | + __ amadd_db_w(dst, inc, tmp); | + __ lu32i_d(dst, 0); | + } else { | + __ amadd_db_d(dst, inc, tmp); | + } | + break; | + default: | + ShouldNotReachHere(); | + } | + } else if (code == lir_xchg) { | + Register obj = as_reg(data); | + if (is_oop && UseCompressedOops) { | + __ encode_heap_oop(SCR2, obj); | + obj = SCR2; | + } | + switch(type) { | + case T_INT: | + __ amswap_db_w(dst, obj, tmp); | + break; | + case T_LONG: | + __ amswap_db_d(dst, obj, tmp); | + break; | + case T_OBJECT: | + case T_ARRAY: | + if (UseCompressedOops) { | + __ amswap_db_w(dst, obj, tmp); | + __ lu32i_d(dst, 0); | + } else { | + __ amswap_db_d(dst, obj, tmp); | + } | + break; | + default: | + ShouldNotReachHere(); | + } | + if (is_oop && UseCompressedOops) { | + __ decode_heap_oop(dst); | + } | + } else { | + ShouldNotReachHere(); | + } | +} | + | +#undef __ |diff --cc src/hotspot/cpu/loongarch/c1_LIRGenerator_loongarch_64.cpp |index a346700ed36,00000000000..fedcc547d48 |mode 100644,000000..100644 |--- a/src/hotspot/cpu/loongarch/c1_LIRGenerator_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/c1_LIRGenerator_loongarch_64.cpp |@@@ -1,1397 -1,0 +1,1384 @@@ | +/* | + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. | + * Copyright (c) 2021, 2022, Loongson Technology. All rights reserved. | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | + * | + * This code is free software; you can redistribute it and/or modify it | + * under the terms of the GNU General Public License version 2 only, as | + * published by the Free Software Foundation. | + * | + * This code is distributed in the hope that it will be useful, but WITHOUT | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | + * version 2 for more details (a copy is included in the LICENSE file that | + * accompanied this code). | + * | + * You should have received a copy of the GNU General Public License version | + * 2 along with this work; if not, write to the Free Software Foundation, | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | + * | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | + * or visit www.oracle.com if you need additional information or have any | + * questions. | + * | + */ | + | +#include "precompiled.hpp" | +#include "asm/macroAssembler.inline.hpp" | +#include "c1/c1_Compilation.hpp" | +#include "c1/c1_FrameMap.hpp" | +#include "c1/c1_Instruction.hpp" | +#include "c1/c1_LIRAssembler.hpp" | +#include "c1/c1_LIRGenerator.hpp" | +#include "c1/c1_Runtime1.hpp" | +#include "c1/c1_ValueStack.hpp" | +#include "ci/ciArray.hpp" | +#include "ci/ciObjArrayKlass.hpp" | +#include "ci/ciTypeArrayKlass.hpp" | +#include "runtime/sharedRuntime.hpp" | +#include "runtime/stubRoutines.hpp" | +#include "utilities/powerOfTwo.hpp" | +#include "vmreg_loongarch.inline.hpp" | + | +#ifdef ASSERT | +#define __ gen()->lir(__FILE__, __LINE__)-> | +#else | +#define __ gen()->lir()-> | +#endif | + | +// Item will be loaded into a byte register; Intel only | +void LIRItem::load_byte_item() { | + load_item(); | +} | + | +void LIRItem::load_nonconstant() { | + LIR_Opr r = value()->operand(); | + if (r->is_constant()) { | + _result = r; | + } else { | + load_item(); | + } | +} | + | +//-------------------------------------------------------------- | +// LIRGenerator | +//-------------------------------------------------------------- | + | +LIR_Opr LIRGenerator::exceptionOopOpr() { return FrameMap::a0_oop_opr; } | +LIR_Opr LIRGenerator::exceptionPcOpr() { return FrameMap::a1_opr; } | +LIR_Opr LIRGenerator::divInOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; } | +LIR_Opr LIRGenerator::divOutOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; } | +LIR_Opr LIRGenerator::remOutOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; } | +LIR_Opr LIRGenerator::shiftCountOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; } | +LIR_Opr LIRGenerator::syncLockOpr() { return new_register(T_INT); } | +LIR_Opr LIRGenerator::syncTempOpr() { return FrameMap::a0_opr; } | +LIR_Opr LIRGenerator::getThreadTemp() { return LIR_OprFact::illegalOpr; } | + | +LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) { | + LIR_Opr opr; | + switch (type->tag()) { | + case intTag: opr = FrameMap::a0_opr; break; | + case objectTag: opr = FrameMap::a0_oop_opr; break; | + case longTag: opr = FrameMap::long0_opr; break; | + case floatTag: opr = FrameMap::fpu0_float_opr; break; | + case doubleTag: opr = FrameMap::fpu0_double_opr; break; | + case addressTag: | + default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; | + } | + | + assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch"); | + return opr; | +} | + | +LIR_Opr LIRGenerator::rlock_byte(BasicType type) { | + LIR_Opr reg = new_register(T_INT); | + set_vreg_flag(reg, LIRGenerator::byte_reg); | + return reg; | +} | + | +//--------- loading items into registers -------------------------------- | + | +bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const { | + if (v->type()->as_IntConstant() != NULL) { | + return v->type()->as_IntConstant()->value() == 0L; | + } else if (v->type()->as_LongConstant() != NULL) { | + return v->type()->as_LongConstant()->value() == 0L; | + } else if (v->type()->as_ObjectConstant() != NULL) { | + return v->type()->as_ObjectConstant()->value()->is_null_object(); | + } else { | + return false; | + } | +} | + | +bool LIRGenerator::can_inline_as_constant(Value v) const { | + // FIXME: Just a guess | + if (v->type()->as_IntConstant() != NULL) { | + return Assembler::is_simm(v->type()->as_IntConstant()->value(), 12); | + } else if (v->type()->as_LongConstant() != NULL) { | + return v->type()->as_LongConstant()->value() == 0L; | + } else if (v->type()->as_ObjectConstant() != NULL) { | + return v->type()->as_ObjectConstant()->value()->is_null_object(); | + } else { | + return false; | + } | +} | + | +bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const { return false; } | + | +LIR_Opr LIRGenerator::safepoint_poll_register() { | + return LIR_OprFact::illegalOpr; | +} | + | +LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, | + int shift, int disp, BasicType type) { | + assert(base->is_register(), "must be"); | + intx large_disp = disp; | + | + // accumulate fixed displacements | + if (index->is_constant()) { | + LIR_Const *constant = index->as_constant_ptr(); | + if (constant->type() == T_INT) { | + large_disp += index->as_jint() << shift; | + } else { | + assert(constant->type() == T_LONG, "should be"); | + jlong c = index->as_jlong() << shift; | + if ((jlong)((jint)c) == c) { | + large_disp += c; | + index = LIR_OprFact::illegalOpr; | + } else { | + LIR_Opr tmp = new_register(T_LONG); | + __ move(index, tmp); | + index = tmp; | + // apply shift and displacement below | + } | + } | + } | + | + if (index->is_register()) { | + // apply the shift and accumulate the displacement | + if (shift > 0) { | + LIR_Opr tmp = new_pointer_register(); | + __ shift_left(index, shift, tmp); | + index = tmp; | + } | + if (large_disp != 0) { | + LIR_Opr tmp = new_pointer_register(); | + if (Assembler::is_simm(large_disp, 12)) { | + __ add(index, LIR_OprFact::intptrConst(large_disp), tmp); | + index = tmp; | + } else { | + __ move(LIR_OprFact::intptrConst(large_disp), tmp); | + __ add(tmp, index, tmp); | + index = tmp; | + } | + large_disp = 0; | + } | + } else if (large_disp != 0 && !Assembler::is_simm(large_disp, 12)) { | + // index is illegal so replace it with the displacement loaded into a register | + index = new_pointer_register(); | + __ move(LIR_OprFact::intptrConst(large_disp), index); | + large_disp = 0; | + } | + | + // at this point we either have base + index or base + displacement | + if (large_disp == 0 && index->is_register()) { | + return new LIR_Address(base, index, type); | + } else { | + assert(Assembler::is_simm(large_disp, 12), "must be"); | + return new LIR_Address(base, large_disp, type); | + } | +} | + | +LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, BasicType type) { | + int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type); | + int elem_size = type2aelembytes(type); | + int shift = exact_log2(elem_size); | + | + LIR_Address* addr; | + if (index_opr->is_constant()) { | + addr = new LIR_Address(array_opr, offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type); | + } else { | + if (offset_in_bytes) { | + LIR_Opr tmp = new_pointer_register(); | + __ add(array_opr, LIR_OprFact::intConst(offset_in_bytes), tmp); | + array_opr = tmp; | + offset_in_bytes = 0; | + } | + addr = new LIR_Address(array_opr, index_opr, LIR_Address::scale(type), offset_in_bytes, type); | + } | + return addr; | +} | + | +LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) { | + LIR_Opr r; | + if (type == T_LONG) { | + r = LIR_OprFact::longConst(x); | + if (!Assembler::is_simm(x, 12)) { | + LIR_Opr tmp = new_register(type); | + __ move(r, tmp); | + return tmp; | + } | + } else if (type == T_INT) { | + r = LIR_OprFact::intConst(x); | + if (!Assembler::is_simm(x, 12)) { | + // This is all rather nasty. We don't know whether our constant | + // is required for a logical or an arithmetic operation, wo we | + // don't know what the range of valid values is!! | + LIR_Opr tmp = new_register(type); | + __ move(r, tmp); | + return tmp; | + } | + } else { | + ShouldNotReachHere(); | + r = NULL; // unreachable | + } | + return r; | +} | + | +void LIRGenerator::increment_counter(address counter, BasicType type, int step) { | + LIR_Opr pointer = new_pointer_register(); | + __ move(LIR_OprFact::intptrConst(counter), pointer); | + LIR_Address* addr = new LIR_Address(pointer, type); | + increment_counter(addr, step); | +} | + | +void LIRGenerator::increment_counter(LIR_Address* addr, int step) { | + LIR_Opr imm = NULL; | + switch(addr->type()) { | + case T_INT: | + imm = LIR_OprFact::intConst(step); | + break; | + case T_LONG: | + imm = LIR_OprFact::longConst(step); | + break; | + default: | + ShouldNotReachHere(); | + } | + LIR_Opr reg = new_register(addr->type()); | + __ load(addr, reg); | + __ add(reg, imm, reg); | + __ store(reg, addr); | +} | + |- template |- void LIRGenerator::cmp_mem_int_branch(LIR_Condition condition, LIR_Opr base, |- int disp, int c, T tgt, CodeEmitInfo* info) { |++void LIRGenerator::cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info) { | + LIR_Opr reg = new_register(T_INT); | + __ load(generate_address(base, disp, T_INT), reg, info); |- __ cmp_branch(condition, reg, LIR_OprFact::intConst(c), tgt); |++ __ cmp(condition, reg, LIR_OprFact::intConst(c)); | +} | + |- // Explicit instantiation for all supported types. |- template void LIRGenerator::cmp_mem_int_branch(LIR_Condition, LIR_Opr, int, int, Label*, CodeEmitInfo*); |- template void LIRGenerator::cmp_mem_int_branch(LIR_Condition, LIR_Opr, int, int, BlockBegin*, CodeEmitInfo*); |- template void LIRGenerator::cmp_mem_int_branch(LIR_Condition, LIR_Opr, int, int, CodeStub*, CodeEmitInfo*); |- |- template |- void LIRGenerator::cmp_reg_mem_branch(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, |- int disp, BasicType type, T tgt, CodeEmitInfo* info) { |++void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info) { | + LIR_Opr reg1 = new_register(T_INT); | + __ load(generate_address(base, disp, type), reg1, info); |- __ cmp_branch(condition, reg, reg1, tgt); |++ __ cmp(condition, reg, reg1); | +} | + |- // Explicit instantiation for all supported types. |- template void LIRGenerator::cmp_reg_mem_branch(LIR_Condition, LIR_Opr, LIR_Opr, int, BasicType, Label*, CodeEmitInfo*); |- template void LIRGenerator::cmp_reg_mem_branch(LIR_Condition, LIR_Opr, LIR_Opr, int, BasicType, BlockBegin*, CodeEmitInfo*); |- template void LIRGenerator::cmp_reg_mem_branch(LIR_Condition, LIR_Opr, LIR_Opr, int, BasicType, CodeStub*, CodeEmitInfo*); |- | +bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, jint c, LIR_Opr result, LIR_Opr tmp) { | + if (is_power_of_2(c - 1)) { | + __ shift_left(left, exact_log2(c - 1), tmp); | + __ add(tmp, left, result); | + return true; | + } else if (is_power_of_2(c + 1)) { | + __ shift_left(left, exact_log2(c + 1), tmp); | + __ sub(tmp, left, result); | + return true; | + } else { | + return false; | + } | +} | + | +void LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) { | + BasicType type = item->type(); | + __ store(item, new LIR_Address(FrameMap::sp_opr, in_bytes(offset_from_sp), type)); | +} | + | +void LIRGenerator::array_store_check(LIR_Opr value, LIR_Opr array, CodeEmitInfo* store_check_info, | + ciMethod* profiled_method, int profiled_bci) { | + LIR_Opr tmp1 = new_register(objectType); | + LIR_Opr tmp2 = new_register(objectType); | + LIR_Opr tmp3 = new_register(objectType); | + __ store_check(value, array, tmp1, tmp2, tmp3, store_check_info, profiled_method, profiled_bci); | +} | + | +//---------------------------------------------------------------------- | +// visitor functions | +//---------------------------------------------------------------------- | + | +void LIRGenerator::do_MonitorEnter(MonitorEnter* x) { | + assert(x->is_pinned(),""); | + LIRItem obj(x->obj(), this); | + obj.load_item(); | + | + set_no_result(x); | + | + // "lock" stores the address of the monitor stack slot, so this is not an oop | + LIR_Opr lock = new_register(T_INT); | + // Need a scratch register for biased locking | + LIR_Opr scratch = LIR_OprFact::illegalOpr; | + if (UseBiasedLocking) { | + scratch = new_register(T_INT); | + } | + | + CodeEmitInfo* info_for_exception = NULL; | + if (x->needs_null_check()) { | + info_for_exception = state_for(x); | + } | + // this CodeEmitInfo must not have the xhandlers because here the | + // object is already locked (xhandlers expect object to be unlocked) | + CodeEmitInfo* info = state_for(x, x->state(), true); | + monitor_enter(obj.result(), lock, syncTempOpr(), scratch, | + x->monitor_no(), info_for_exception, info); | +} | + | +void LIRGenerator::do_MonitorExit(MonitorExit* x) { | + assert(x->is_pinned(),""); | + | + LIRItem obj(x->obj(), this); | + obj.dont_load_item(); | + | + LIR_Opr lock = new_register(T_INT); | + LIR_Opr obj_temp = new_register(T_INT); | + set_no_result(x); | + monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no()); | +} | + | +void LIRGenerator::do_NegateOp(NegateOp* x) { | + LIRItem from(x->x(), this); | + from.load_item(); | + LIR_Opr result = rlock_result(x); | + __ negate (from.result(), result); | +} | + | +// for _fadd, _fmul, _fsub, _fdiv, _frem | +// _dadd, _dmul, _dsub, _ddiv, _drem | +void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) { | + if (x->op() == Bytecodes::_frem || x->op() == Bytecodes::_drem) { | + // float remainder is implemented as a direct call into the runtime | + LIRItem right(x->x(), this); | + LIRItem left(x->y(), this); | + | + BasicTypeList signature(2); | + if (x->op() == Bytecodes::_frem) { | + signature.append(T_FLOAT); | + signature.append(T_FLOAT); | + } else { | + signature.append(T_DOUBLE); | + signature.append(T_DOUBLE); | + } | + CallingConvention* cc = frame_map()->c_calling_convention(&signature); | + | + const LIR_Opr result_reg = result_register_for(x->type()); | + left.load_item_force(cc->at(1)); | + right.load_item(); | + | + __ move(right.result(), cc->at(0)); | + | + address entry; | + if (x->op() == Bytecodes::_frem) { | + entry = CAST_FROM_FN_PTR(address, SharedRuntime::frem); | + } else { | + entry = CAST_FROM_FN_PTR(address, SharedRuntime::drem); | + } | + | + LIR_Opr result = rlock_result(x); | + __ call_runtime_leaf(entry, getThreadTemp(), result_reg, cc->args()); | + __ move(result_reg, result); | + return; | + } | + | + LIRItem left(x->x(), this); | + LIRItem right(x->y(), this); | + LIRItem* left_arg = &left; | + LIRItem* right_arg = &right; | + | + // Always load right hand side. | + right.load_item(); | + | + if (!left.is_register()) | + left.load_item(); | + | + LIR_Opr reg = rlock(x); | + | + arithmetic_op_fpu(x->op(), reg, left.result(), right.result()); | + | + set_result(x, round_item(reg)); | +} | + | +// for _ladd, _lmul, _lsub, _ldiv, _lrem | +void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) { | + // missing test if instr is commutative and if we should swap | + LIRItem left(x->x(), this); | + LIRItem right(x->y(), this); | + | + if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem) { | + left.load_item(); | + bool need_zero_check = true; | + if (right.is_constant()) { | + jlong c = right.get_jlong_constant(); | + // no need to do div-by-zero check if the divisor is a non-zero constant | + if (c != 0) need_zero_check = false; | + // do not load right if the divisor is a power-of-2 constant | + if (c > 0 && is_power_of_2(c) && Assembler::is_uimm(c - 1, 12)) { | + right.dont_load_item(); | + } else { | + right.load_item(); | + } | + } else { | + right.load_item(); | + } | + if (need_zero_check) { | + CodeEmitInfo* info = state_for(x); |- CodeStub* stub = new DivByZeroStub(info); |- __ cmp_branch(lir_cond_equal, right.result(), LIR_OprFact::longConst(0), stub); |++ __ cmp(lir_cond_equal, right.result(), LIR_OprFact::longConst(0)); |++ __ branch(lir_cond_equal, new DivByZeroStub(info)); | + } | + | + rlock_result(x); | + switch (x->op()) { | + case Bytecodes::_lrem: | + __ rem (left.result(), right.result(), x->operand()); | + break; | + case Bytecodes::_ldiv: | + __ div (left.result(), right.result(), x->operand()); | + break; | + default: | + ShouldNotReachHere(); | + break; | + } | + } else { | + assert(x->op() == Bytecodes::_lmul || x->op() == Bytecodes::_ladd || x->op() == Bytecodes::_lsub, | + "expect lmul, ladd or lsub"); | + // add, sub, mul | + left.load_item(); | + if (!right.is_register()) { | + if (x->op() == Bytecodes::_lmul || !right.is_constant() || | + (x->op() == Bytecodes::_ladd && !Assembler::is_simm(right.get_jlong_constant(), 12)) || | + (x->op() == Bytecodes::_lsub && !Assembler::is_simm(-right.get_jlong_constant(), 12))) { | + right.load_item(); | + } else { // add, sub | + assert(x->op() == Bytecodes::_ladd || x->op() == Bytecodes::_lsub, "expect ladd or lsub"); | + // don't load constants to save register | + right.load_nonconstant(); | + } | + } | + rlock_result(x); | + arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL); | + } | +} | + | +// for: _iadd, _imul, _isub, _idiv, _irem | +void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) { | + // Test if instr is commutative and if we should swap | + LIRItem left(x->x(), this); | + LIRItem right(x->y(), this); | + LIRItem* left_arg = &left; | + LIRItem* right_arg = &right; | + if (x->is_commutative() && left.is_stack() && right.is_register()) { | + // swap them if left is real stack (or cached) and right is real register(not cached) | + left_arg = &right; | + right_arg = &left; | + } | + | + left_arg->load_item(); | + | + // do not need to load right, as we can handle stack and constants | + if (x->op() == Bytecodes::_idiv || x->op() == Bytecodes::_irem) { | + rlock_result(x); | + bool need_zero_check = true; | + if (right.is_constant()) { | + jint c = right.get_jint_constant(); | + // no need to do div-by-zero check if the divisor is a non-zero constant | + if (c != 0) need_zero_check = false; | + // do not load right if the divisor is a power-of-2 constant | + if (c > 0 && is_power_of_2(c) && Assembler::is_uimm(c - 1, 12)) { | + right_arg->dont_load_item(); | + } else { | + right_arg->load_item(); | + } | + } else { | + right_arg->load_item(); | + } | + if (need_zero_check) { | + CodeEmitInfo* info = state_for(x); |- CodeStub* stub = new DivByZeroStub(info); |- __ cmp_branch(lir_cond_equal, right_arg->result(), LIR_OprFact::longConst(0), stub); |++ __ cmp(lir_cond_equal, right_arg->result(), LIR_OprFact::longConst(0)); |++ __ branch(lir_cond_equal, new DivByZeroStub(info)); | + } | + | + LIR_Opr ill = LIR_OprFact::illegalOpr; | + if (x->op() == Bytecodes::_irem) { | + __ irem(left_arg->result(), right_arg->result(), x->operand(), ill, NULL); | + } else if (x->op() == Bytecodes::_idiv) { | + __ idiv(left_arg->result(), right_arg->result(), x->operand(), ill, NULL); | + } | + } else if (x->op() == Bytecodes::_iadd || x->op() == Bytecodes::_isub) { | + if (right.is_constant() && | + ((x->op() == Bytecodes::_iadd && Assembler::is_simm(right.get_jint_constant(), 12)) || | + (x->op() == Bytecodes::_isub && Assembler::is_simm(-right.get_jint_constant(), 12)))) { | + right.load_nonconstant(); | + } else { | + right.load_item(); | + } | + rlock_result(x); | + arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), LIR_OprFact::illegalOpr); | + } else { | + assert (x->op() == Bytecodes::_imul, "expect imul"); | + if (right.is_constant()) { | + jint c = right.get_jint_constant(); | + if (c > 0 && c < max_jint && (is_power_of_2(c) || is_power_of_2(c - 1) || is_power_of_2(c + 1))) { | + right_arg->dont_load_item(); | + } else { | + // Cannot use constant op. | + right_arg->load_item(); | + } | + } else { | + right.load_item(); | + } | + rlock_result(x); | + arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), new_register(T_INT)); | + } | +} | + | +void LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) { | + // when an operand with use count 1 is the left operand, then it is | + // likely that no move for 2-operand-LIR-form is necessary | + if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) { | + x->swap_operands(); | + } | + | + ValueTag tag = x->type()->tag(); | + assert(x->x()->type()->tag() == tag && x->y()->type()->tag() == tag, "wrong parameters"); | + switch (tag) { | + case floatTag: | + case doubleTag: do_ArithmeticOp_FPU(x); return; | + case longTag: do_ArithmeticOp_Long(x); return; | + case intTag: do_ArithmeticOp_Int(x); return; | + default: ShouldNotReachHere(); return; | + } | +} | + | +// _ishl, _lshl, _ishr, _lshr, _iushr, _lushr | +void LIRGenerator::do_ShiftOp(ShiftOp* x) { | + LIRItem left(x->x(), this); | + LIRItem right(x->y(), this); | + | + left.load_item(); | + | + rlock_result(x); | + if (right.is_constant()) { | + right.dont_load_item(); | + int c; | + switch (x->op()) { | + case Bytecodes::_ishl: | + c = right.get_jint_constant() & 0x1f; | + __ shift_left(left.result(), c, x->operand()); | + break; | + case Bytecodes::_ishr: | + c = right.get_jint_constant() & 0x1f; | + __ shift_right(left.result(), c, x->operand()); | + break; | + case Bytecodes::_iushr: | + c = right.get_jint_constant() & 0x1f; | + __ unsigned_shift_right(left.result(), c, x->operand()); | + break; | + case Bytecodes::_lshl: | + c = right.get_jint_constant() & 0x3f; | + __ shift_left(left.result(), c, x->operand()); | + break; | + case Bytecodes::_lshr: | + c = right.get_jint_constant() & 0x3f; | + __ shift_right(left.result(), c, x->operand()); | + break; | + case Bytecodes::_lushr: | + c = right.get_jint_constant() & 0x3f; | + __ unsigned_shift_right(left.result(), c, x->operand()); | + break; | + default: | + ShouldNotReachHere(); | + } | + } else { | + right.load_item(); | + LIR_Opr tmp = new_register(T_INT); | + switch (x->op()) { | + case Bytecodes::_ishl: | + __ logical_and(right.result(), LIR_OprFact::intConst(0x1f), tmp); | + __ shift_left(left.result(), tmp, x->operand(), tmp); | + break; | + case Bytecodes::_ishr: | + __ logical_and(right.result(), LIR_OprFact::intConst(0x1f), tmp); | + __ shift_right(left.result(), tmp, x->operand(), tmp); | + break; | + case Bytecodes::_iushr: | + __ logical_and(right.result(), LIR_OprFact::intConst(0x1f), tmp); | + __ unsigned_shift_right(left.result(), tmp, x->operand(), tmp); | + break; | + case Bytecodes::_lshl: | + __ logical_and(right.result(), LIR_OprFact::intConst(0x3f), tmp); | + __ shift_left(left.result(), tmp, x->operand(), tmp); | + break; | + case Bytecodes::_lshr: | + __ logical_and(right.result(), LIR_OprFact::intConst(0x3f), tmp); | + __ shift_right(left.result(), tmp, x->operand(), tmp); | + break; | + case Bytecodes::_lushr: | + __ logical_and(right.result(), LIR_OprFact::intConst(0x3f), tmp); | + __ unsigned_shift_right(left.result(), tmp, x->operand(), tmp); | + break; | + default: | + ShouldNotReachHere(); | + } | + } | +} | + | +// _iand, _land, _ior, _lor, _ixor, _lxor | +void LIRGenerator::do_LogicOp(LogicOp* x) { | + LIRItem left(x->x(), this); | + LIRItem right(x->y(), this); | + | + left.load_item(); | + | + rlock_result(x); | + if (right.is_constant() | + && ((right.type()->tag() == intTag | + && Assembler::is_uimm(right.get_jint_constant(), 12)) | + || (right.type()->tag() == longTag | + && Assembler::is_uimm(right.get_jlong_constant(), 12)))) { | + right.dont_load_item(); | + } else { | + right.load_item(); | + } | + switch (x->op()) { | + case Bytecodes::_iand: | + case Bytecodes::_land: | + __ logical_and(left.result(), right.result(), x->operand()); break; | + case Bytecodes::_ior: | + case Bytecodes::_lor: | + __ logical_or (left.result(), right.result(), x->operand()); break; | + case Bytecodes::_ixor: | + case Bytecodes::_lxor: | + __ logical_xor(left.result(), right.result(), x->operand()); break; | + default: Unimplemented(); | + } | +} | + | +// _lcmp, _fcmpl, _fcmpg, _dcmpl, _dcmpg | +void LIRGenerator::do_CompareOp(CompareOp* x) { | + LIRItem left(x->x(), this); | + LIRItem right(x->y(), this); | + ValueTag tag = x->x()->type()->tag(); | + if (tag == longTag) { | + left.set_destroys_register(); | + } | + left.load_item(); | + right.load_item(); | + LIR_Opr reg = rlock_result(x); | + | + if (x->x()->type()->is_float_kind()) { | + Bytecodes::Code code = x->op(); | + __ fcmp2int(left.result(), right.result(), reg, | + (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl)); | + } else if (x->x()->type()->tag() == longTag) { | + __ lcmp2int(left.result(), right.result(), reg); | + } else { | + Unimplemented(); | + } | +} | + | +LIR_Opr LIRGenerator::atomic_cmpxchg(BasicType type, LIR_Opr addr, | + LIRItem& cmp_value, LIRItem& new_value) { | + LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience | + new_value.load_item(); | + cmp_value.load_item(); | + LIR_Opr result = new_register(T_INT); | + if (is_reference_type(type)) { | + __ cas_obj(addr, cmp_value.result(), new_value.result(), | + new_register(T_INT), new_register(T_INT), result); | + } else if (type == T_INT) { | + __ cas_int(addr->as_address_ptr()->base(), cmp_value.result(), | + new_value.result(), ill, ill); | + } else if (type == T_LONG) { | + __ cas_long(addr->as_address_ptr()->base(), cmp_value.result(), | + new_value.result(), ill, ill); | + } else { | + ShouldNotReachHere(); | + Unimplemented(); | + } | + __ move(FrameMap::scr1_opr, result); | + return result; | +} | + | +LIR_Opr LIRGenerator::atomic_xchg(BasicType type, LIR_Opr addr, LIRItem& value) { | + bool is_oop = is_reference_type(type); | + LIR_Opr result = new_register(type); | + value.load_item(); | + assert(type == T_INT || is_oop || type == T_LONG, "unexpected type"); | + LIR_Opr tmp = new_register(T_INT); | + __ xchg(addr, value.result(), result, tmp); | + return result; | +} | + | +LIR_Opr LIRGenerator::atomic_add(BasicType type, LIR_Opr addr, LIRItem& value) { | + LIR_Opr result = new_register(type); | + value.load_item(); | + assert(type == T_INT || type == T_LONG, "unexpected type"); | + LIR_Opr tmp = new_register(T_INT); | + __ xadd(addr, value.result(), result, tmp); | + return result; | +} | + | +void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { | + assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), | + "wrong type"); | + if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog || | + x->id() == vmIntrinsics::_dpow || x->id() == vmIntrinsics::_dcos || | + x->id() == vmIntrinsics::_dsin || x->id() == vmIntrinsics::_dtan || | + x->id() == vmIntrinsics::_dlog10) { | + do_LibmIntrinsic(x); | + return; | + } | + switch (x->id()) { | + case vmIntrinsics::_dabs: | + case vmIntrinsics::_dsqrt: { | + assert(x->number_of_arguments() == 1, "wrong type"); | + LIRItem value(x->argument_at(0), this); | + value.load_item(); | + LIR_Opr dst = rlock_result(x); | + | + switch (x->id()) { | + case vmIntrinsics::_dsqrt: | + __ sqrt(value.result(), dst, LIR_OprFact::illegalOpr); | + break; | + case vmIntrinsics::_dabs: | + __ abs(value.result(), dst, LIR_OprFact::illegalOpr); | + break; | + default: | + ShouldNotReachHere(); | + } | + break; | + } | + default: | + ShouldNotReachHere(); | + } | +} | + | +void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) { | + LIRItem value(x->argument_at(0), this); | + value.set_destroys_register(); | + | + LIR_Opr calc_result = rlock_result(x); | + LIR_Opr result_reg = result_register_for(x->type()); | + | + CallingConvention* cc = NULL; | + | + if (x->id() == vmIntrinsics::_dpow) { | + LIRItem value1(x->argument_at(1), this); | + | + value1.set_destroys_register(); | + | + BasicTypeList signature(2); | + signature.append(T_DOUBLE); | + signature.append(T_DOUBLE); | + cc = frame_map()->c_calling_convention(&signature); | + value.load_item_force(cc->at(0)); | + value1.load_item_force(cc->at(1)); | + } else { | + BasicTypeList signature(1); | + signature.append(T_DOUBLE); | + cc = frame_map()->c_calling_convention(&signature); | + value.load_item_force(cc->at(0)); | + } | + | + switch (x->id()) { | + case vmIntrinsics::_dexp: | + if (StubRoutines::dexp() != NULL) { | + __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); | + } else { | + __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args()); | + } | + break; | + case vmIntrinsics::_dlog: | + if (StubRoutines::dlog() != NULL) { | + __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); | + } else { | + __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args()); | + } | + break; | + case vmIntrinsics::_dlog10: | + if (StubRoutines::dlog10() != NULL) { | + __ call_runtime_leaf(StubRoutines::dlog10(), getThreadTemp(), result_reg, cc->args()); | + } else { | + __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10), getThreadTemp(), result_reg, cc->args()); | + } | + break; | + case vmIntrinsics::_dpow: | + if (StubRoutines::dpow() != NULL) { | + __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args()); | + } else { | + __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args()); | + } | + break; | + case vmIntrinsics::_dsin: | + if (StubRoutines::dsin() != NULL) { | + __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args()); | + } else { | + __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args()); | + } | + break; | + case vmIntrinsics::_dcos: | + if (StubRoutines::dcos() != NULL) { | + __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args()); | + } else { | + __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args()); | + } | + break; | + case vmIntrinsics::_dtan: | + if (StubRoutines::dtan() != NULL) { | + __ call_runtime_leaf(StubRoutines::dtan(), getThreadTemp(), result_reg, cc->args()); | + } else { | + __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), getThreadTemp(), result_reg, cc->args()); | + } | + break; | + default: ShouldNotReachHere(); | + } | + __ move(result_reg, calc_result); | +} | + | +void LIRGenerator::do_ArrayCopy(Intrinsic* x) { | + Register j_rarg0 = RT0; | + Register j_rarg1 = RA0; | + Register j_rarg2 = RA1; | + Register j_rarg3 = RA2; | + Register j_rarg4 = RA3; | + Register j_rarg5 = RA4; | + | + assert(x->number_of_arguments() == 5, "wrong type"); | + | + // Make all state_for calls early since they can emit code | + CodeEmitInfo* info = state_for(x, x->state()); | + | + LIRItem src(x->argument_at(0), this); | + LIRItem src_pos(x->argument_at(1), this); | + LIRItem dst(x->argument_at(2), this); | + LIRItem dst_pos(x->argument_at(3), this); | + LIRItem length(x->argument_at(4), this); | + | + // operands for arraycopy must use fixed registers, otherwise | + // LinearScan will fail allocation (because arraycopy always needs a | + // call) | + | + // The java calling convention will give us enough registers | + // so that on the stub side the args will be perfect already. | + // On the other slow/special case side we call C and the arg | + // positions are not similar enough to pick one as the best. | + // Also because the java calling convention is a "shifted" version | + // of the C convention we can process the java args trivially into C | + // args without worry of overwriting during the xfer | + | + src.load_item_force (FrameMap::as_oop_opr(j_rarg0)); | + src_pos.load_item_force (FrameMap::as_opr(j_rarg1)); | + dst.load_item_force (FrameMap::as_oop_opr(j_rarg2)); | + dst_pos.load_item_force (FrameMap::as_opr(j_rarg3)); | + length.load_item_force (FrameMap::as_opr(j_rarg4)); | + | + LIR_Opr tmp = FrameMap::as_opr(j_rarg5); | + | + set_no_result(x); | + | + int flags; | + ciArrayKlass* expected_type; | + arraycopy_helper(x, &flags, &expected_type); | + | + __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), | + length.result(), tmp, expected_type, flags, info); // does add_safepoint | +} | + | +void LIRGenerator::do_update_CRC32(Intrinsic* x) { | + assert(UseCRC32Intrinsics, "why are we here?"); | + // Make all state_for calls early since they can emit code | + LIR_Opr result = rlock_result(x); | + int flags = 0; | + switch (x->id()) { | + case vmIntrinsics::_updateCRC32: { | + LIRItem crc(x->argument_at(0), this); | + LIRItem val(x->argument_at(1), this); | + // val is destroyed by update_crc32 | + val.set_destroys_register(); | + crc.load_item(); | + val.load_item(); | + __ update_crc32(crc.result(), val.result(), result); | + break; | + } | + case vmIntrinsics::_updateBytesCRC32: | + case vmIntrinsics::_updateByteBufferCRC32: { | + bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32); | + | + LIRItem crc(x->argument_at(0), this); | + LIRItem buf(x->argument_at(1), this); | + LIRItem off(x->argument_at(2), this); | + LIRItem len(x->argument_at(3), this); | + buf.load_item(); | + off.load_nonconstant(); | + | + LIR_Opr index = off.result(); | + int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0; | + if(off.result()->is_constant()) { | + index = LIR_OprFact::illegalOpr; | + offset += off.result()->as_jint(); | + } | + LIR_Opr base_op = buf.result(); | + | + if (index->is_valid()) { | + LIR_Opr tmp = new_register(T_LONG); | + __ convert(Bytecodes::_i2l, index, tmp); | + index = tmp; | + } | + | + if (offset) { | + LIR_Opr tmp = new_pointer_register(); | + __ add(base_op, LIR_OprFact::intConst(offset), tmp); | + base_op = tmp; | + offset = 0; | + } | + | + LIR_Address* a = new LIR_Address(base_op, index, offset, T_BYTE); | + BasicTypeList signature(3); | + signature.append(T_INT); | + signature.append(T_ADDRESS); | + signature.append(T_INT); | + CallingConvention* cc = frame_map()->c_calling_convention(&signature); | + const LIR_Opr result_reg = result_register_for(x->type()); | + | + LIR_Opr addr = new_pointer_register(); | + __ leal(LIR_OprFact::address(a), addr); | + | + crc.load_item_force(cc->at(0)); | + __ move(addr, cc->at(1)); | + len.load_item_force(cc->at(2)); | + | + __ call_runtime_leaf(StubRoutines::updateBytesCRC32(), getThreadTemp(), result_reg, cc->args()); | + __ move(result_reg, result); | + | + break; | + } | + default: { | + ShouldNotReachHere(); | + } | + } | +} | + | +void LIRGenerator::do_update_CRC32C(Intrinsic* x) { | + assert(UseCRC32CIntrinsics, "why are we here?"); | + // Make all state_for calls early since they can emit code | + LIR_Opr result = rlock_result(x); | + int flags = 0; | + switch (x->id()) { | + case vmIntrinsics::_updateBytesCRC32C: | + case vmIntrinsics::_updateDirectByteBufferCRC32C: { | + bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32C); | + int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0; | + | + LIRItem crc(x->argument_at(0), this); | + LIRItem buf(x->argument_at(1), this); | + LIRItem off(x->argument_at(2), this); | + LIRItem end(x->argument_at(3), this); | + | + buf.load_item(); | + off.load_nonconstant(); | + end.load_nonconstant(); | + | + // len = end - off | + LIR_Opr len = end.result(); | + LIR_Opr tmpA = new_register(T_INT); | + LIR_Opr tmpB = new_register(T_INT); | + __ move(end.result(), tmpA); | + __ move(off.result(), tmpB); | + __ sub(tmpA, tmpB, tmpA); | + len = tmpA; | + | + LIR_Opr index = off.result(); | + if(off.result()->is_constant()) { | + index = LIR_OprFact::illegalOpr; | + offset += off.result()->as_jint(); | + } | + LIR_Opr base_op = buf.result(); | + | + if (index->is_valid()) { | + LIR_Opr tmp = new_register(T_LONG); | + __ convert(Bytecodes::_i2l, index, tmp); | + index = tmp; | + } | + | + if (offset) { | + LIR_Opr tmp = new_pointer_register(); | + __ add(base_op, LIR_OprFact::intConst(offset), tmp); | + base_op = tmp; | + offset = 0; | + } | + | + LIR_Address* a = new LIR_Address(base_op, index, offset, T_BYTE); | + BasicTypeList signature(3); | + signature.append(T_INT); | + signature.append(T_ADDRESS); | + signature.append(T_INT); | + CallingConvention* cc = frame_map()->c_calling_convention(&signature); | + const LIR_Opr result_reg = result_register_for(x->type()); | + | + LIR_Opr addr = new_pointer_register(); | + __ leal(LIR_OprFact::address(a), addr); | + | + crc.load_item_force(cc->at(0)); | + __ move(addr, cc->at(1)); | + __ move(len, cc->at(2)); | + | + __ call_runtime_leaf(StubRoutines::updateBytesCRC32C(), getThreadTemp(), result_reg, cc->args()); | + __ move(result_reg, result); | + | + break; | + } | + default: { | + ShouldNotReachHere(); | + } | + } | +} | + | +void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) { | + assert(x->number_of_arguments() == 3, "wrong type"); | + assert(UseFMA, "Needs FMA instructions support."); | + LIRItem value(x->argument_at(0), this); | + LIRItem value1(x->argument_at(1), this); | + LIRItem value2(x->argument_at(2), this); | + | + value.load_item(); | + value1.load_item(); | + value2.load_item(); | + | + LIR_Opr calc_input = value.result(); | + LIR_Opr calc_input1 = value1.result(); | + LIR_Opr calc_input2 = value2.result(); | + LIR_Opr calc_result = rlock_result(x); | + | + switch (x->id()) { | + case vmIntrinsics::_fmaD: | + __ fmad(calc_input, calc_input1, calc_input2, calc_result); | + break; | + case vmIntrinsics::_fmaF: | + __ fmaf(calc_input, calc_input1, calc_input2, calc_result); | + break; | + default: | + ShouldNotReachHere(); | + } | +} | + | +void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) { | + fatal("vectorizedMismatch intrinsic is not implemented on this platform"); | +} | + | +// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f | +// _i2b, _i2c, _i2s | +void LIRGenerator::do_Convert(Convert* x) { | + LIRItem value(x->value(), this); | + value.load_item(); | + LIR_Opr input = value.result(); | + LIR_Opr result = rlock(x); | + | + // arguments of lir_convert | + LIR_Opr conv_input = input; | + LIR_Opr conv_result = result; | + | + switch (x->op()) { | + case Bytecodes::_f2i: | + case Bytecodes::_f2l: | + __ convert(x->op(), conv_input, conv_result, NULL, new_register(T_FLOAT)); | + break; | + case Bytecodes::_d2i: | + case Bytecodes::_d2l: | + __ convert(x->op(), conv_input, conv_result, NULL, new_register(T_DOUBLE)); | + break; | + default: | + __ convert(x->op(), conv_input, conv_result); | + break; | + } | + | + assert(result->is_virtual(), "result must be virtual register"); | + set_result(x, result); | +} | + | +void LIRGenerator::do_NewInstance(NewInstance* x) { | +#ifndef PRODUCT | + if (PrintNotLoaded && !x->klass()->is_loaded()) { | + tty->print_cr(" ###class not loaded at new bci %d", x->printable_bci()); | + } | +#endif | + CodeEmitInfo* info = state_for(x, x->state()); | + LIR_Opr reg = result_register_for(x->type()); | + new_instance(reg, x->klass(), x->is_unresolved(), | + FrameMap::t0_oop_opr, | + FrameMap::t1_oop_opr, | + FrameMap::a4_oop_opr, | + LIR_OprFact::illegalOpr, | + FrameMap::a3_metadata_opr, info); | + LIR_Opr result = rlock_result(x); | + __ move(reg, result); | +} | + | +void LIRGenerator::do_NewTypeArray(NewTypeArray* x) { | + CodeEmitInfo* info = state_for(x, x->state()); | + | + LIRItem length(x->length(), this); | + length.load_item_force(FrameMap::s0_opr); | + | + LIR_Opr reg = result_register_for(x->type()); | + LIR_Opr tmp1 = FrameMap::t0_oop_opr; | + LIR_Opr tmp2 = FrameMap::t1_oop_opr; | + LIR_Opr tmp3 = FrameMap::a5_oop_opr; | + LIR_Opr tmp4 = reg; | + LIR_Opr klass_reg = FrameMap::a3_metadata_opr; | + LIR_Opr len = length.result(); | + BasicType elem_type = x->elt_type(); | + | + __ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg); | + | + CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info); | + __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path); | + | + LIR_Opr result = rlock_result(x); | + __ move(reg, result); | +} | + | +void LIRGenerator::do_NewObjectArray(NewObjectArray* x) { | + LIRItem length(x->length(), this); | + // in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction | + // and therefore provide the state before the parameters have been consumed | + CodeEmitInfo* patching_info = NULL; | + if (!x->klass()->is_loaded() || PatchALot) { | + patching_info = state_for(x, x->state_before()); | + } | + | + CodeEmitInfo* info = state_for(x, x->state()); | + | + LIR_Opr reg = result_register_for(x->type()); | + LIR_Opr tmp1 = FrameMap::t0_oop_opr; | + LIR_Opr tmp2 = FrameMap::t1_oop_opr; | + LIR_Opr tmp3 = FrameMap::a5_oop_opr; | + LIR_Opr tmp4 = reg; | + LIR_Opr klass_reg = FrameMap::a3_metadata_opr; | + | + length.load_item_force(FrameMap::s0_opr); | + LIR_Opr len = length.result(); | + | + CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info); | + ciKlass* obj = (ciKlass*) ciObjArrayKlass::make(x->klass()); | + if (obj == ciEnv::unloaded_ciobjarrayklass()) { | + BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error"); | + } | + klass2reg_with_patching(klass_reg, obj, patching_info); | + __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path); | + | + LIR_Opr result = rlock_result(x); | + __ move(reg, result); | +} | + | +void LIRGenerator::do_NewMultiArray(NewMultiArray* x) { | + Values* dims = x->dims(); | + int i = dims->length(); | + LIRItemList* items = new LIRItemList(i, i, NULL); | + while (i-- > 0) { | + LIRItem* size = new LIRItem(dims->at(i), this); | + items->at_put(i, size); | + } | + | + // Evaluate state_for early since it may emit code. | + CodeEmitInfo* patching_info = NULL; | + if (!x->klass()->is_loaded() || PatchALot) { | + patching_info = state_for(x, x->state_before()); | + | + // Cannot re-use same xhandlers for multiple CodeEmitInfos, so | + // clone all handlers (NOTE: Usually this is handled transparently | + // by the CodeEmitInfo cloning logic in CodeStub constructors but | + // is done explicitly here because a stub isn't being used). | + x->set_exception_handlers(new XHandlers(x->exception_handlers())); | + } | + CodeEmitInfo* info = state_for(x, x->state()); | + | + i = dims->length(); | + while (i-- > 0) { | + LIRItem* size = items->at(i); | + size->load_item(); | + | + store_stack_parameter(size->result(), in_ByteSize(i*4)); | + } | + | + LIR_Opr klass_reg = FrameMap::a0_metadata_opr; | + klass2reg_with_patching(klass_reg, x->klass(), patching_info); | + | + LIR_Opr rank = FrameMap::s0_opr; | + __ move(LIR_OprFact::intConst(x->rank()), rank); | + LIR_Opr varargs = FrameMap::a2_opr; | + __ move(FrameMap::sp_opr, varargs); | + LIR_OprList* args = new LIR_OprList(3); | + args->append(klass_reg); | + args->append(rank); | + args->append(varargs); | + LIR_Opr reg = result_register_for(x->type()); | + __ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id), | + LIR_OprFact::illegalOpr, | + reg, args, info); | + | + LIR_Opr result = rlock_result(x); | + __ move(reg, result); | +} | + | +void LIRGenerator::do_BlockBegin(BlockBegin* x) { | + // nothing to do for now | +} | + | +void LIRGenerator::do_CheckCast(CheckCast* x) { | + LIRItem obj(x->obj(), this); | + | + CodeEmitInfo* patching_info = NULL; | + if (!x->klass()->is_loaded() || | + (PatchALot && !x->is_incompatible_class_change_check() && | + !x->is_invokespecial_receiver_check())) { | + // must do this before locking the destination register as an oop register, | + // and before the obj is loaded (the latter is for deoptimization) | + patching_info = state_for(x, x->state_before()); | + } | + obj.load_item(); | + | + // info for exceptions | + CodeEmitInfo* info_for_exception = | + (x->needs_exception_state() ? state_for(x) : | + state_for(x, x->state_before(), true /*ignore_xhandler*/)); | + | + CodeStub* stub; | + if (x->is_incompatible_class_change_check()) { | + assert(patching_info == NULL, "can't patch this"); | + stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, | + LIR_OprFact::illegalOpr, info_for_exception); | + } else if (x->is_invokespecial_receiver_check()) { | + assert(patching_info == NULL, "can't patch this"); | + stub = new DeoptimizeStub(info_for_exception, | + Deoptimization::Reason_class_check, | + Deoptimization::Action_none); | + } else { | + stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, | + obj.result(), info_for_exception); | + } | + LIR_Opr reg = rlock_result(x); | + LIR_Opr tmp3 = LIR_OprFact::illegalOpr; | + if (!x->klass()->is_loaded() || UseCompressedClassPointers) { | + tmp3 = new_register(objectType); | + } | + __ checkcast(reg, obj.result(), x->klass(), | + new_register(objectType), new_register(objectType), tmp3, | + x->direct_compare(), info_for_exception, patching_info, stub, | + x->profiled_method(), x->profiled_bci()); | +} | + | +void LIRGenerator::do_InstanceOf(InstanceOf* x) { | + LIRItem obj(x->obj(), this); | + | + // result and test object may not be in same register | + LIR_Opr reg = rlock_result(x); | + CodeEmitInfo* patching_info = NULL; | + if ((!x->klass()->is_loaded() || PatchALot)) { | + // must do this before locking the destination register as an oop register | + patching_info = state_for(x, x->state_before()); | + } | + obj.load_item(); | + LIR_Opr tmp3 = LIR_OprFact::illegalOpr; | + if (!x->klass()->is_loaded() || UseCompressedClassPointers) { | + tmp3 = new_register(objectType); | + } | + __ instanceof(reg, obj.result(), x->klass(), | + new_register(objectType), new_register(objectType), tmp3, | + x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci()); | +} | + | +void LIRGenerator::do_If(If* x) { | + assert(x->number_of_sux() == 2, "inconsistency"); | + ValueTag tag = x->x()->type()->tag(); | + bool is_safepoint = x->is_safepoint(); | + | + If::Condition cond = x->cond(); | + | + LIRItem xitem(x->x(), this); | + LIRItem yitem(x->y(), this); | + LIRItem* xin = &xitem; | + LIRItem* yin = &yitem; | + | + if (tag == longTag) { | + // for longs, only conditions "eql", "neq", "lss", "geq" are valid; | + // mirror for other conditions | + if (cond == If::gtr || cond == If::leq) { | + cond = Instruction::mirror(cond); | + xin = &yitem; | + yin = &xitem; | + } | + xin->set_destroys_register(); | + } | + xin->load_item(); | + | + if (tag == longTag) { | + if (yin->is_constant() && yin->get_jlong_constant() == 0) { | + yin->dont_load_item(); | + } else { | + yin->load_item(); | + } | + } else if (tag == intTag) { | + if (yin->is_constant() && yin->get_jint_constant() == 0) { | + yin->dont_load_item(); | + } else { | + yin->load_item(); | + } | + } else { | + yin->load_item(); | + } | + | + set_no_result(x); | + | + LIR_Opr left = xin->result(); | + LIR_Opr right = yin->result(); | + | + // add safepoint before generating condition code so it can be recomputed | + if (x->is_safepoint()) { | + // increment backedge counter if needed | + increment_backedge_counter_conditionally(lir_cond(cond), left, right, state_for(x, x->state_before()), | + x->tsux()->bci(), x->fsux()->bci(), x->profiled_bci()); | + __ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before())); | + } | + |++ __ cmp(lir_cond(cond), left, right); | + // Generate branch profiling. Profiling code doesn't kill flags. |- profile_branch(x, cond, left, right); |++ profile_branch(x, cond); | + move_to_phi(x->state()); | + if (x->x()->type()->is_float_kind()) { |- __ cmp_branch(lir_cond(cond), left, right, x->tsux(), x->usux()); |++ __ branch(lir_cond(cond), x->tsux(), x->usux()); | + } else { |- __ cmp_branch(lir_cond(cond), left, right, x->tsux()); |++ __ branch(lir_cond(cond), x->tsux()); | + } | + assert(x->default_sux() == x->fsux(), "wrong destination above"); | + __ jump(x->default_sux()); | +} | + | +LIR_Opr LIRGenerator::getThreadPointer() { | + return FrameMap::as_pointer_opr(TREG); | +} | + | +void LIRGenerator::trace_block_entry(BlockBegin* block) { Unimplemented(); } | + | +void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address, | + CodeEmitInfo* info) { | + __ volatile_store_mem_reg(value, address, info); | +} | + | +void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result, | + CodeEmitInfo* info) { | + // 8179954: We need to make sure that the code generated for | + // volatile accesses forms a sequentially-consistent set of | + // operations when combined with STLR and LDAR. Without a leading | + // membar it's possible for a simple Dekker test to fail if loads | + // use LD;DMB but stores use STLR. This can happen if C2 compiles | + // the stores in one method and C1 compiles the loads in another. | + if (!CompilerConfig::is_c1_only_no_jvmci()) { | + __ membar(); | + } | + __ volatile_load_mem_reg(address, result, info); | +} |diff --cc src/hotspot/cpu/loongarch/c1_LIR_loongarch_64.cpp |index 127be89865e,00000000000..01e8c9f270e |mode 100644,000000..100644 |--- a/src/hotspot/cpu/loongarch/c1_LIR_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/c1_LIR_loongarch_64.cpp |@@@ -1,75 -1,0 +1,57 @@@ | +/* | + * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. | + * Copyright (c) 2021, Loongson Technology. All rights reserved. | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | + * | + * This code is free software; you can redistribute it and/or modify it | + * under the terms of the GNU General Public License version 2 only, as | + * published by the Free Software Foundation. | + * | + * This code is distributed in the hope that it will be useful, but WITHOUT | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | + * version 2 for more details (a copy is included in the LICENSE file that | + * accompanied this code). | + * | + * You should have received a copy of the GNU General Public License version | + * 2 along with this work; if not, write to the Free Software Foundation, | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | + * | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | + * or visit www.oracle.com if you need additional information or have any | + * questions. | + * | + */ | + | +#include "precompiled.hpp" | +#include "asm/register.hpp" | +#include "c1/c1_LIR.hpp" | + | +FloatRegister LIR_OprDesc::as_float_reg() const { | + return as_FloatRegister(fpu_regnr()); | +} | + | +FloatRegister LIR_OprDesc::as_double_reg() const { | + return as_FloatRegister(fpu_regnrLo()); | +} | + | +// Reg2 unused. | +LIR_Opr LIR_OprFact::double_fpu(int reg1, int reg2) { | + assert(as_FloatRegister(reg2) == fnoreg, "Not used on this platform"); | + return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) | | + (reg1 << LIR_OprDesc::reg2_shift) | | + LIR_OprDesc::double_type | | + LIR_OprDesc::fpu_register | | + LIR_OprDesc::double_size); | +} | + | +#ifndef PRODUCT | +void LIR_Address::verify() const { | + assert(base()->is_cpu_register(), "wrong base operand"); | + assert(index()->is_illegal() || index()->is_double_cpu() || | + index()->is_single_cpu(), "wrong index operand"); | + assert(base()->type() == T_ADDRESS || base()->type() == T_OBJECT || | + base()->type() == T_LONG || base()->type() == T_METADATA, | + "wrong type for addresses"); | +} | +#endif // PRODUCT |- |- template |- void LIR_List::cmp_branch(LIR_Condition condition, LIR_Opr left, LIR_Opr right, T tgt, CodeEmitInfo* info) { |- append(new LIR_OpCmpBranch(condition, left, right, tgt, info)); |- } |- |- // Explicit instantiation for all supported types. |- template void LIR_List::cmp_branch(LIR_Condition, LIR_Opr, LIR_Opr, Label*, CodeEmitInfo*); |- template void LIR_List::cmp_branch(LIR_Condition, LIR_Opr, LIR_Opr, BlockBegin*, CodeEmitInfo*); |- template void LIR_List::cmp_branch(LIR_Condition, LIR_Opr, LIR_Opr, CodeStub*, CodeEmitInfo*); |- |- void LIR_List::cmp_branch(LIR_Condition condition, LIR_Opr left, LIR_Opr right, BlockBegin* block, BlockBegin* unordered) { |- append(new LIR_OpCmpBranch(condition, left, right, block, unordered)); |- } |- |- void LIR_List::cmp_cmove(LIR_Condition condition, LIR_Opr left, LIR_Opr right, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst, BasicType type) { |- append(new LIR_Op4(lir_cmp_cmove, condition, left, right, src1, src2, dst, type)); |- } |diff --cc src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.cpp |index 3ef43daa725,00000000000..372d80cf11b |mode 100644,000000..100644 |--- a/src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.cpp |@@@ -1,466 -1,0 +1,462 @@@ | +/* | + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. | + * Copyright (c) 2021, 2022, Loongson Technology. All rights reserved. | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | + * | + * This code is free software; you can redistribute it and/or modify it | + * under the terms of the GNU General Public License version 2 only, as | + * published by the Free Software Foundation. | + * | + * This code is distributed in the hope that it will be useful, but WITHOUT | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | + * version 2 for more details (a copy is included in the LICENSE file that | + * accompanied this code). | + * | + * You should have received a copy of the GNU General Public License version | + * 2 along with this work; if not, write to the Free Software Foundation, | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | + * | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | + * or visit www.oracle.com if you need additional information or have any | + * questions. | + */ | + | +#include "precompiled.hpp" | +#include "asm/macroAssembler.inline.hpp" | +#include "code/codeBlob.hpp" | +#include "code/vmreg.inline.hpp" | +#include "gc/z/zBarrier.inline.hpp" | +#include "gc/z/zBarrierSet.hpp" | +#include "gc/z/zBarrierSetAssembler.hpp" | +#include "gc/z/zBarrierSetRuntime.hpp" | +#include "gc/z/zThreadLocalData.hpp" | +#include "memory/resourceArea.hpp" | +#include "runtime/sharedRuntime.hpp" | +#include "utilities/macros.hpp" | +#ifdef COMPILER1 | +#include "c1/c1_LIRAssembler.hpp" | +#include "c1/c1_MacroAssembler.hpp" | +#include "gc/z/c1/zBarrierSetC1.hpp" | +#endif // COMPILER1 | +#ifdef COMPILER2 | +#include "gc/z/c2/zBarrierSetC2.hpp" | +#endif // COMPILER2 | + | +#ifdef PRODUCT | +#define BLOCK_COMMENT(str) /* nothing */ | +#else | +#define BLOCK_COMMENT(str) __ block_comment(str) | +#endif | + | +#undef __ | +#define __ masm-> | + | +#define A0 RA0 | +#define A1 RA1 | +#define T4 RT4 | + | +void ZBarrierSetAssembler::load_at(MacroAssembler* masm, | + DecoratorSet decorators, | + BasicType type, | + Register dst, | + Address src, | + Register tmp1, | + Register tmp_thread) { | + if (!ZBarrierSet::barrier_needed(decorators, type)) { | + // Barrier not needed | + BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); | + return; | + } | + | + // Allocate scratch register | + Register scratch = tmp1; | + | + assert_different_registers(dst, scratch, SCR1); | + | + Label done; | + | + // | + // Fast Path | + // | + | + // Load address | + __ lea(scratch, src); | + | + // Load oop at address | + __ ld_ptr(dst, scratch, 0); | + | + // Test address bad mask | + __ ld_ptr(SCR1, address_bad_mask_from_thread(TREG)); | + __ andr(SCR1, dst, SCR1); | + __ beqz(SCR1, done); | + | + // | + // Slow path | + // | + __ enter(); | + | + if (dst != V0) { | + __ push(V0); | + } | + __ push_call_clobbered_registers_except(RegSet::of(V0)); | + | + if (dst != A0) { | + __ move(A0, dst); | + } | + __ move(A1, scratch); | + __ MacroAssembler::call_VM_leaf_base(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2); | + | + __ pop_call_clobbered_registers_except(RegSet::of(V0)); | + | + // Make sure dst has the return value. | + if (dst != V0) { | + __ move(dst, V0); | + __ pop(V0); | + } | + __ leave(); | + | + __ bind(done); | +} | + | +#ifdef ASSERT | + | +void ZBarrierSetAssembler::store_at(MacroAssembler* masm, | + DecoratorSet decorators, | + BasicType type, | + Address dst, | + Register val, | + Register tmp1, | + Register tmp2) { | + // Verify value | + if (is_reference_type(type)) { | + // Note that src could be noreg, which means we | + // are storing null and can skip verification. | + if (val != noreg) { | + Label done; | + | + // tmp1 and tmp2 are often set to noreg. | + | + __ ld_ptr(AT, address_bad_mask_from_thread(TREG)); | + __ andr(AT, val, AT); | + __ beqz(AT, done); | + __ stop("Verify oop store failed"); | + __ should_not_reach_here(); | + __ bind(done); | + } | + } | + | + // Store value | + BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2); | +} | + | +#endif // ASSERT | + | +void ZBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, | + DecoratorSet decorators, | + bool is_oop, | + Register src, | + Register dst, | + Register count, | + RegSet saved_regs) { | + if (!is_oop) { | + // Barrier not needed | + return; | + } | + | + BLOCK_COMMENT("ZBarrierSetAssembler::arraycopy_prologue {"); | + | + __ push(saved_regs); | + | + if (count == A0) { | + if (src == A1) { | + // exactly backwards!! | + __ move(AT, A0); | + __ move(A0, A1); | + __ move(A1, AT); | + } else { | + __ move(A1, count); | + __ move(A0, src); | + } | + } else { | + __ move(A0, src); | + __ move(A1, count); | + } | + | + __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_array_addr(), 2); | + | + __ pop(saved_regs); | + | + BLOCK_COMMENT("} ZBarrierSetAssembler::arraycopy_prologue"); | +} | + | +void ZBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, | + Register jni_env, | + Register robj, | + Register tmp, | + Label& slowpath) { | + BLOCK_COMMENT("ZBarrierSetAssembler::try_resolve_jobject_in_native {"); | + | + assert_different_registers(jni_env, robj, tmp); | + | + // Resolve jobject | + BarrierSetAssembler::try_resolve_jobject_in_native(masm, jni_env, robj, tmp, slowpath); | + | + // The Address offset is too large to direct load - -784. Our range is +127, -128. | + __ li(tmp, (int64_t)(in_bytes(ZThreadLocalData::address_bad_mask_offset()) - | + in_bytes(JavaThread::jni_environment_offset()))); | + | + // Load address bad mask | + __ ldx_d(tmp, jni_env, tmp); | + | + // Check address bad mask | + __ andr(AT, robj, tmp); | + __ bnez(AT, slowpath); | + | + BLOCK_COMMENT("} ZBarrierSetAssembler::try_resolve_jobject_in_native"); | +} | + | +#ifdef COMPILER1 | + | +#undef __ | +#define __ ce->masm()-> | + | +void ZBarrierSetAssembler::generate_c1_load_barrier_test(LIR_Assembler* ce, |- LIR_Opr ref, |- LIR_Opr res) const { |- Register rscratch1 = AT; |- Register rthread = TREG; |- assert_different_registers(rscratch1, rthread, ref->as_register()); |- |- __ ld_d(rscratch1, address_bad_mask_from_thread(rthread)); |- __ andr(res->as_register(), ref->as_register(), rscratch1); |++ LIR_Opr ref) const { |++ assert_different_registers(SCR1, TREG, ref->as_register()); |++ __ ld_d(SCR1, address_bad_mask_from_thread(TREG)); |++ __ andr(SCR1, SCR1, ref->as_register()); | +} | + | +void ZBarrierSetAssembler::generate_c1_load_barrier_stub(LIR_Assembler* ce, | + ZLoadBarrierStubC1* stub) const { | + // Stub entry | + __ bind(*stub->entry()); | + | + Register ref = stub->ref()->as_register(); | + Register ref_addr = noreg; | + Register tmp = noreg; | + | + if (stub->tmp()->is_valid()) { | + // Load address into tmp register | + ce->leal(stub->ref_addr(), stub->tmp()); | + ref_addr = tmp = stub->tmp()->as_pointer_register(); | + } else { | + // Address already in register | + ref_addr = stub->ref_addr()->as_address_ptr()->base()->as_pointer_register(); | + } | + | + assert_different_registers(ref, ref_addr, noreg); | + | + // Save V0 unless it is the result or tmp register | + // Set up SP to accomodate parameters and maybe V0. | + if (ref != V0 && tmp != V0) { | + __ addi_d(SP, SP, -32); | + __ st_d(V0, SP, 16); | + } else { | + __ addi_d(SP, SP, -16); | + } | + | + // Setup arguments and call runtime stub | + ce->store_parameter(ref_addr, 1); | + ce->store_parameter(ref, 0); | + | + __ call(stub->runtime_stub(), relocInfo::runtime_call_type); | + | + // Verify result | + __ verify_oop(V0, "Bad oop"); | + | + // Move result into place | + if (ref != V0) { | + __ move(ref, V0); | + } | + | + // Restore V0 unless it is the result or tmp register | + if (ref != V0 && tmp != V0) { | + __ ld_d(V0, SP, 16); | + __ addi_d(SP, SP, 32); | + } else { | + __ addi_d(SP, SP, 16); | + } | + | + // Stub exit | + __ b(*stub->continuation()); | +} | + | +#undef __ | +#define __ sasm-> | + | +void ZBarrierSetAssembler::generate_c1_load_barrier_runtime_stub(StubAssembler* sasm, | + DecoratorSet decorators) const { | + __ prologue("zgc_load_barrier stub", false); | + | + __ push_call_clobbered_registers_except(RegSet::of(V0)); | + | + // Setup arguments | + __ load_parameter(0, A0); | + __ load_parameter(1, A1); | + | + __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2); | + | + __ pop_call_clobbered_registers_except(RegSet::of(V0)); | + | + __ epilogue(); | +} | +#endif // COMPILER1 | + | +#ifdef COMPILER2 | + | +OptoReg::Name ZBarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) { | + if (!OptoReg::is_reg(opto_reg)) { | + return OptoReg::Bad; | + } | + | + const VMReg vm_reg = OptoReg::as_VMReg(opto_reg); | + if (vm_reg->is_FloatRegister()) { | + return opto_reg & ~1; | + } | + | + return opto_reg; | +} | + | +#undef __ | +#define __ _masm-> | + | +class ZSaveLiveRegisters { | +private: | + MacroAssembler* const _masm; | + RegSet _gp_regs; | + FloatRegSet _fp_regs; | + FloatRegSet _lsx_vp_regs; | + FloatRegSet _lasx_vp_regs; | + | +public: | + void initialize(ZLoadBarrierStubC2* stub) { | + // Record registers that needs to be saved/restored | + RegMaskIterator rmi(stub->live()); | + while (rmi.has_next()) { | + const OptoReg::Name opto_reg = rmi.next(); | + if (OptoReg::is_reg(opto_reg)) { | + const VMReg vm_reg = OptoReg::as_VMReg(opto_reg); | + if (vm_reg->is_Register()) { | + _gp_regs += RegSet::of(vm_reg->as_Register()); | + } else if (vm_reg->is_FloatRegister()) { | + if (UseLASX && vm_reg->next(7)) | + _lasx_vp_regs += FloatRegSet::of(vm_reg->as_FloatRegister()); | + else if (UseLSX && vm_reg->next(3)) | + _lsx_vp_regs += FloatRegSet::of(vm_reg->as_FloatRegister()); | + else | + _fp_regs += FloatRegSet::of(vm_reg->as_FloatRegister()); | + } else { | + fatal("Unknown register type"); | + } | + } | + } | + | + // Remove C-ABI SOE registers, scratch regs and _ref register that will be updated | + _gp_regs -= RegSet::range(S0, S7) + RegSet::of(SP, SCR1, SCR2, stub->ref()); | + } | + | + ZSaveLiveRegisters(MacroAssembler* masm, ZLoadBarrierStubC2* stub) : | + _masm(masm), | + _gp_regs(), | + _fp_regs(), | + _lsx_vp_regs(), | + _lasx_vp_regs() { | + | + // Figure out what registers to save/restore | + initialize(stub); | + | + // Save registers | + __ push(_gp_regs); | + __ push_fpu(_fp_regs); | + __ push_vp(_lsx_vp_regs /* UseLSX */); | + __ push_vp(_lasx_vp_regs /* UseLASX */); | + } | + | + ~ZSaveLiveRegisters() { | + // Restore registers | + __ pop_vp(_lasx_vp_regs /* UseLASX */); | + __ pop_vp(_lsx_vp_regs /* UseLSX */); | + __ pop_fpu(_fp_regs); | + __ pop(_gp_regs); | + } | +}; | + | +#undef __ | +#define __ _masm-> | + | +class ZSetupArguments { | +private: | + MacroAssembler* const _masm; | + const Register _ref; | + const Address _ref_addr; | + | +public: | + ZSetupArguments(MacroAssembler* masm, ZLoadBarrierStubC2* stub) : | + _masm(masm), | + _ref(stub->ref()), | + _ref_addr(stub->ref_addr()) { | + | + // Setup arguments | + if (_ref_addr.base() == noreg) { | + // No self healing | + if (_ref != A0) { | + __ move(A0, _ref); | + } | + __ move(A1, 0); | + } else { | + // Self healing | + if (_ref == A0) { | + // _ref is already at correct place | + __ lea(A1, _ref_addr); | + } else if (_ref != A1) { | + // _ref is in wrong place, but not in A1, so fix it first | + __ lea(A1, _ref_addr); | + __ move(A0, _ref); | + } else if (_ref_addr.base() != A0 && _ref_addr.index() != A0) { | + assert(_ref == A1, "Mov ref first, vacating A0"); | + __ move(A0, _ref); | + __ lea(A1, _ref_addr); | + } else { | + assert(_ref == A1, "Need to vacate A1 and _ref_addr is using A0"); | + if (_ref_addr.base() == A0 || _ref_addr.index() == A0) { | + __ move(T4, A1); | + __ lea(A1, _ref_addr); | + __ move(A0, T4); | + } else { | + ShouldNotReachHere(); | + } | + } | + } | + } | + | + ~ZSetupArguments() { | + // Transfer result | + if (_ref != V0) { | + __ move(_ref, V0); | + } | + } | +}; | + | +#undef __ | +#define __ masm-> | + | +void ZBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, ZLoadBarrierStubC2* stub) const { | + BLOCK_COMMENT("ZLoadBarrierStubC2"); | + | + // Stub entry | + __ bind(*stub->entry()); | + | + { | + ZSaveLiveRegisters save_live_registers(masm, stub); | + ZSetupArguments setup_arguments(masm, stub); | + __ call_VM_leaf(stub->slow_path(), 2); | + } | + // Stub exit | + __ b(*stub->continuation()); | +} | + | +#undef __ | + | +#endif // COMPILER2 |diff --cc src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.hpp |index 8d032c34995,00000000000..6a96d6fdd60 |mode 100644,000000..100644 |--- a/src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.hpp |@@@ -1,102 -1,0 +1,101 @@@ | +/* | + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. | + * Copyright (c) 2021, Loongson Technology. 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 CPU_LOONGARCH_GC_Z_ZBARRIERSETASSEMBLER_LOONGARCH_HPP | +#define CPU_LOONGARCH_GC_Z_ZBARRIERSETASSEMBLER_LOONGARCH_HPP | + | +#include "code/vmreg.hpp" | +#include "oops/accessDecorators.hpp" | +#ifdef COMPILER2 | +#include "opto/optoreg.hpp" | +#endif // COMPILER2 | + | +#ifdef COMPILER1 | +class LIR_Assembler; | +class LIR_OprDesc; | +typedef LIR_OprDesc* LIR_Opr; | +class StubAssembler; | +class ZLoadBarrierStubC1; | +#endif // COMPILER1 | + | +#ifdef COMPILER2 | +class Node; | +class ZLoadBarrierStubC2; | +#endif // COMPILER2 | + | +class ZBarrierSetAssembler : public ZBarrierSetAssemblerBase { | +public: | + virtual void load_at(MacroAssembler* masm, | + DecoratorSet decorators, | + BasicType type, | + Register dst, | + Address src, | + Register tmp1, | + Register tmp_thread); | + | +#ifdef ASSERT | + virtual void store_at(MacroAssembler* masm, | + DecoratorSet decorators, | + BasicType type, | + Address dst, | + Register val, | + Register tmp1, | + Register tmp2); | +#endif // ASSERT | + | + virtual void arraycopy_prologue(MacroAssembler* masm, | + DecoratorSet decorators, | + bool is_oop, | + Register src, | + Register dst, | + Register count, | + RegSet saved_regs); | + | + virtual void try_resolve_jobject_in_native(MacroAssembler* masm, | + Register jni_env, | + Register robj, | + Register tmp, | + Label& slowpath); | + | +#ifdef COMPILER1 | + void generate_c1_load_barrier_test(LIR_Assembler* ce, |- LIR_Opr ref, |- LIR_Opr res) const; |++ LIR_Opr ref) const; | + | + void generate_c1_load_barrier_stub(LIR_Assembler* ce, | + ZLoadBarrierStubC1* stub) const; | + | + void generate_c1_load_barrier_runtime_stub(StubAssembler* sasm, | + DecoratorSet decorators) const; | +#endif // COMPILER1 | + | +#ifdef COMPILER2 | + OptoReg::Name refine_register(const Node* node, | + OptoReg::Name opto_reg); | + | + void generate_c2_load_barrier_stub(MacroAssembler* masm, | + ZLoadBarrierStubC2* stub) const; | +#endif // COMPILER2 | +}; | + | +#endif // CPU_LOONGARCH_GC_Z_ZBARRIERSETASSEMBLER_LOONGARCH_HPP |diff --cc src/hotspot/cpu/loongarch/gc/z/zGlobals_loongarch.hpp |index 7d20899d949,00000000000..542fd267434 |mode 100644,000000..100644 |--- a/src/hotspot/cpu/loongarch/gc/z/zGlobals_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/gc/z/zGlobals_loongarch.hpp |@@@ -1,37 -1,0 +1,35 @@@ | +/* | + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. | + * Copyright (c) 2021, Loongson Technology. 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 CPU_LOONGARCH_GC_Z_ZGLOBALS_LOONGARCH_HPP | +#define CPU_LOONGARCH_GC_Z_ZGLOBALS_LOONGARCH_HPP | + | +const size_t ZPlatformGranuleSizeShift = 21; // 2MB | +const size_t ZPlatformHeapViews = 3; | +const size_t ZPlatformCacheLineSize = 64; | + |- const bool ZPlatformLoadBarrierTestResultInRegister = true; |- | +size_t ZPlatformAddressOffsetBits(); | +size_t ZPlatformAddressMetadataShift(); | + | +#endif // CPU_LOONGARCH_GC_Z_ZGLOBALS_LOONGARCH_HPP |diff --cc src/hotspot/share/c1/c1_LIR.cpp |index f1af08d5df0,308f3a09c15..53a68cdb2fd |--- a/src/hotspot/share/c1/c1_LIR.cpp |+++ b/src/hotspot/share/c1/c1_LIR.cpp |@@@ -22,6 -22,6 +22,12 @@@ | * | */ | |++/* |++ * This file has been modified by Loongson Technology in 2023, These |++ * modifications are Copyright (c) 2022, 2023, Loongson Technology, and are made |++ * available on the same license terms set forth above. |++ */ |++ | #include "precompiled.hpp" | #include "c1/c1_CodeStubs.hpp" | #include "c1/c1_InstructionPrinter.hpp" |@@@ -188,6 -188,9 +194,11 @@@ void LIR_Op2::verify() const | #ifdef ASSERT | switch (code()) { | case lir_cmove: |+ #ifdef RISCV |+ assert(false, "lir_cmove is LIR_Op4 on RISCV"); |++#elif defined(LOONGARCH) |++ assert(false, "lir_cmove is LIR_Op4 on LoongArch"); |+ #endif | case lir_xchg: | break; | |@@@ -236,22 -239,14 +247,14 @@@ | #endif | } | |- void LIR_Op4::verify() const { |- #ifdef ASSERT |- switch (code()) { |- case lir_cmp_cmove: |- break; |- |- default: |- assert(!result_opr()->is_register() || !result_opr()->is_oop_register(), |- "can't produce oops from arith"); |- } |- #endif |- } | | LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, BlockBegin* block) | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ : LIR_Op2(lir_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) |+ #else | : LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) | , _cond(cond) |+ #endif | , _label(block->label()) | , _block(block) | , _ublock(NULL) |@@@ -259,8 -254,12 +262,12 @@@ | } | | LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, CodeStub* stub) : | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ LIR_Op2(lir_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) |+ #else | LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) | , _cond(cond) |+ #endif | , _label(stub->entry()) | , _block(NULL) | , _ublock(NULL) |@@@ -268,8 -267,12 +275,12 @@@ | } | | LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, BlockBegin* block, BlockBegin* ublock) | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ : LIR_Op2(lir_cond_float_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) |+ #else | : LIR_Op(lir_cond_float_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL) | , _cond(cond) |+ #endif | , _label(block->label()) | , _block(block) | , _ublock(ublock) |@@@ -559,7 -512,10 +520,11 @@@ void LIR_OpVisitState::visit(LIR_Op* op | assert(opConvert->_info == NULL, "must be"); | if (opConvert->_opr->is_valid()) do_input(opConvert->_opr); | if (opConvert->_result->is_valid()) do_output(opConvert->_result); | + if (opConvert->_tmp->is_valid()) do_temp(opConvert->_tmp); |+ #ifdef PPC32 |+ if (opConvert->_tmp1->is_valid()) do_temp(opConvert->_tmp1); |+ if (opConvert->_tmp2->is_valid()) do_temp(opConvert->_tmp2); |+ #endif | do_stub(opConvert->_stub); | | break; |@@@ -572,6 -528,15 +537,15 @@@ | assert(op->as_OpBranch() != NULL, "must be"); | LIR_OpBranch* opBranch = (LIR_OpBranch*)op; | | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ assert(opBranch->_tmp1->is_illegal() && opBranch->_tmp2->is_illegal() && |+ opBranch->_tmp3->is_illegal() && opBranch->_tmp4->is_illegal() && |+ opBranch->_tmp5->is_illegal(), "not used"); |+ |+ if (opBranch->_opr1->is_valid()) do_input(opBranch->_opr1); |+ if (opBranch->_opr2->is_valid()) do_input(opBranch->_opr2); |+ #endif |+ | if (opBranch->_info != NULL) do_info(opBranch->_info); | assert(opBranch->_result->is_illegal(), "not used"); | if (opBranch->_stub != NULL) opBranch->stub()->visit(this); |@@@ -679,6 -625,21 +634,21 @@@ | // to the result operand, otherwise the backend fails | case lir_cmove: | { | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ assert(op->as_Op4() != NULL, "must be"); |+ LIR_Op4* op4 = (LIR_Op4*)op; |+ |+ assert(op4->_info == NULL && op4->_tmp1->is_illegal() && op4->_tmp2->is_illegal() && |+ op4->_tmp3->is_illegal() && op4->_tmp4->is_illegal() && op4->_tmp5->is_illegal(), "not used"); |+ assert(op4->_opr1->is_valid() && op4->_opr2->is_valid() && op4->_result->is_valid(), "used"); |+ |+ do_input(op4->_opr1); |+ do_input(op4->_opr2); |+ if (op4->_opr3->is_valid()) do_input(op4->_opr3); |+ if (op4->_opr4->is_valid()) do_input(op4->_opr4); |+ do_temp(op4->_opr2); |+ do_output(op4->_result); |+ #else | assert(op->as_Op2() != NULL, "must be"); | LIR_Op2* op2 = (LIR_Op2*)op; | |@@@ -1150,6 -1095,7 +1104,7 @@@ void LIR_Op3::emit_code(LIR_Assembler* | masm->emit_op3(this); | } | | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) | void LIR_Op4::emit_code(LIR_Assembler* masm) { | masm->emit_op4(this); | } |@@@ -1190,6 -1141,10 +1150,10 @@@ LIR_List::LIR_List(Compilation* compila | , _file(NULL) | , _line(0) | #endif | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ , _cmp_opr1(LIR_OprFact::illegalOpr) |+ , _cmp_opr2(LIR_OprFact::illegalOpr) |+ #endif | { } | | |@@@ -1207,6 -1162,38 +1171,38 @@@ void LIR_List::set_file_and_line(const | } | #endif | | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ void LIR_List::set_cmp_oprs(LIR_Op* op) { |+ switch (op->code()) { |+ case lir_cmp: |+ _cmp_opr1 = op->as_Op2()->in_opr1(); |+ _cmp_opr2 = op->as_Op2()->in_opr2(); |+ break; |+ case lir_branch: // fall through |+ case lir_cond_float_branch: |+ assert(op->as_OpBranch()->cond() == lir_cond_always || |+ (_cmp_opr1 != LIR_OprFact::illegalOpr && _cmp_opr2 != LIR_OprFact::illegalOpr), |+ "conditional branches must have legal operands"); |+ if (op->as_OpBranch()->cond() != lir_cond_always) { |+ op->as_Op2()->set_in_opr1(_cmp_opr1); |+ op->as_Op2()->set_in_opr2(_cmp_opr2); |+ } |+ break; |+ case lir_cmove: |+ op->as_Op4()->set_in_opr3(_cmp_opr1); |+ op->as_Op4()->set_in_opr4(_cmp_opr2); |+ break; |+ #if INCLUDE_ZGC |+ case lir_zloadbarrier_test: | - _cmp_opr1 = FrameMap::as_opr(t1); |++ _cmp_opr1 = FrameMap::as_opr(RISCV_ONLY(t1) LOONGARCH64_ONLY(SCR1)); |+ _cmp_opr2 = LIR_OprFact::intConst(0); |+ break; |+ #endif |+ default: |+ break; |+ } |+ } |+ #endif | | void LIR_List::append(LIR_InsertionBuffer* buffer) { | assert(this == buffer->lir_list(), "wrong lir list"); |@@@ -1940,26 -1924,10 +1933,10 @@@ void LIR_Op1::print_patch_code(outputSt | // LIR_OpBranch | void LIR_OpBranch::print_instr(outputStream* out) const { | print_condition(out, cond()); out->print(" "); |- if (block() != NULL) { |- out->print("[B%d] ", block()->block_id()); |- } else if (stub() != NULL) { |- out->print("["); |- stub()->print_name(out); |- out->print(": " INTPTR_FORMAT "]", p2i(stub())); |- if (stub()->info() != NULL) out->print(" [bci:%d]", stub()->info()->stack()->bci()); |- } else { |- out->print("[label:" INTPTR_FORMAT "] ", p2i(label())); |- } |- if (ublock() != NULL) { |- out->print("unordered: [B%d] ", ublock()->block_id()); |- } |- } |- |- // LIR_OpCmpBranch |- void LIR_OpCmpBranch::print_instr(outputStream* out) const { |- print_condition(out, condition()); out->print(" "); |- in_opr1()->print(out); out->print(" "); |- in_opr2()->print(out); out->print(" "); | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ in_opr1()->print(out); out->print(" "); |+ in_opr2()->print(out); out->print(" "); |+ #endif | if (block() != NULL) { | out->print("[B%d] ", block()->block_id()); | } else if (stub() != NULL) { |@@@ -1995,9 -1963,12 +1972,15 @@@ void LIR_OpConvert::print_instr(outputS | print_bytecode(out, bytecode()); | in_opr()->print(out); out->print(" "); | result_opr()->print(out); out->print(" "); | + if(tmp()->is_valid()) { | + tmp()->print(out); out->print(" "); | + } |+ #ifdef PPC32 |+ if(tmp1()->is_valid()) { |+ tmp1()->print(out); out->print(" "); |+ tmp2()->print(out); out->print(" "); |+ } |+ #endif | } | | void LIR_OpConvert::print_bytecode(outputStream* out, Bytecodes::Code code) { |@@@ -2043,7 -2014,11 +2026,11 @@@ void LIR_OpRoundFP::print_instr(outputS | | // LIR_Op2 | void LIR_Op2::print_instr(outputStream* out) const { | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ if (code() == lir_cmp || code() == lir_branch || code() == lir_cond_float_branch) { |+ #else | if (code() == lir_cmove || code() == lir_cmp) { |+ #endif | print_condition(out, condition()); out->print(" "); | } | in_opr1()->print(out); out->print(" "); |@@@ -2094,19 -2069,17 +2081,17 @@@ void LIR_Op3::print_instr(outputStream | result_opr()->print(out); | } | |- | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) | // LIR_Op4 | void LIR_Op4::print_instr(outputStream* out) const { |- if (code() == lir_cmp_cmove) { |- print_condition(out, condition()); out->print(" "); |- } |- in_opr1()->print(out); out->print(" "); |- in_opr2()->print(out); out->print(" "); |- in_opr3()->print(out); out->print(" "); |- in_opr4()->print(out); out->print(" "); |+ print_condition(out, condition()); out->print(" "); |+ in_opr1()->print(out); out->print(" "); |+ in_opr2()->print(out); out->print(" "); |+ in_opr3()->print(out); out->print(" "); |+ in_opr4()->print(out); out->print(" "); | result_opr()->print(out); | } |- |+ #endif | | void LIR_OpLock::print_instr(outputStream* out) const { | hdr_opr()->print(out); out->print(" "); |diff --cc src/hotspot/share/c1/c1_LIR.hpp |index 00c3f938e11,717404e9726..0fffd4aabfc |--- a/src/hotspot/share/c1/c1_LIR.hpp |+++ b/src/hotspot/share/c1/c1_LIR.hpp |@@@ -22,6 -22,6 +22,12 @@@ | * | */ | |++/* |++ * This file has been modified by Loongson Technology in 2023, These |++ * modifications are Copyright (c) 2022, 2023, Loongson Technology, and are made |++ * available on the same license terms set forth above. |++ */ |++ | #ifndef SHARE_C1_C1_LIR_HPP | #define SHARE_C1_C1_LIR_HPP | |@@@ -869,8 -869,9 +875,9 @@@ class LIR_Op2 | class LIR_OpDelay; | class LIR_Op3; | class LIR_OpAllocArray; | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) | class LIR_Op4; |+ #endif | class LIR_OpCall; | class LIR_OpJavaCall; | class LIR_OpRTCall; |@@@ -915,8 -917,10 +923,10 @@@ enum LIR_Code | , lir_null_check | , lir_return | , lir_leal | -#ifndef RISCV |++#if !defined(RISCV) && !defined(LOONGARCH) | , lir_branch | , lir_cond_float_branch |+ #endif | , lir_move | , lir_convert | , lir_alloc_object |@@@ -924,15 -928,20 +934,20 @@@ | , lir_roundfp | , lir_safepoint | , lir_unwind |+ , lir_load_klass | , end_op1 | , begin_op2 | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ , lir_branch |+ , lir_cond_float_branch |+ #endif | , lir_cmp | , lir_cmp_l2i | , lir_ucmp_fd2i | , lir_cmp_fd2i |- , lir_cmp_branch |- , lir_cmp_float_branch | -#ifndef RISCV |++#if !defined(RISCV) && !defined(LOONGARCH) | , lir_cmove |+ #endif | , lir_add | , lir_sub | , lir_mul |@@@ -960,9 -969,11 +975,11 @@@ | , lir_fmad | , lir_fmaf | , end_op3 | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) | , begin_op4 |- , lir_cmp_cmove |+ , lir_cmove | , end_op4 |+ #endif | , begin_opJavaCall | , lir_static_call | , lir_optvirtual_call |@@@ -999,6 -1010,11 +1016,11 @@@ | , begin_opAssert | , lir_assert | , end_opAssert | -#if defined(RISCV) && defined(INCLUDE_ZGC) |++#if (defined(RISCV) || defined(LOONGARCH)) && defined(INCLUDE_ZGC) |+ , begin_opZLoadBarrierTest |+ , lir_zloadbarrier_test |+ , end_opZLoadBarrierTest |+ #endif | }; | | |@@@ -1136,7 -1151,9 +1157,9 @@@ class LIR_Op: public CompilationResourc | virtual LIR_Op1* as_Op1() { return NULL; } | virtual LIR_Op2* as_Op2() { return NULL; } | virtual LIR_Op3* as_Op3() { return NULL; } | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) | virtual LIR_Op4* as_Op4() { return NULL; } |+ #endif | virtual LIR_OpArrayCopy* as_OpArrayCopy() { return NULL; } | virtual LIR_OpUpdateCRC32* as_OpUpdateCRC32() { return NULL; } | virtual LIR_OpTypeCheck* as_OpTypeCheck() { return NULL; } |@@@ -1636,7 -1610,7 +1619,11 @@@ class LIR_Op2: public LIR_Op | , _tmp4(LIR_OprFact::illegalOpr) | , _tmp5(LIR_OprFact::illegalOpr) | , _condition(condition) { |- assert(code == lir_cmp || code == lir_cmp_branch || code == lir_cmp_float_branch || code == lir_assert, "code check"); | - assert(code == lir_cmp || code == lir_assert RISCV_ONLY(|| code == lir_branch || code == lir_cond_float_branch), "code check"); |++ assert(code == lir_cmp || code == lir_assert |++#if defined(RISCV) || defined(LOONGARCH) |++ || code == lir_branch || code == lir_cond_float_branch |++#endif |++ , "code check"); | } | | LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) |@@@ -1668,7 -1642,7 +1655,11 @@@ | , _tmp4(LIR_OprFact::illegalOpr) | , _tmp5(LIR_OprFact::illegalOpr) | , _condition(lir_cond_unknown) { |- assert((code != lir_cmp && code != lir_cmp_branch && code != lir_cmp_float_branch) && is_in_range(code, begin_op2, end_op2), "code check"); | - assert(code != lir_cmp && RISCV_ONLY(code != lir_branch && code != lir_cond_float_branch &&) is_in_range(code, begin_op2, end_op2), "code check"); |++ assert(code != lir_cmp && |++#if defined(RISCV) || defined(LOONGARCH) |++ code != lir_branch && code != lir_cond_float_branch && |++#endif |++ is_in_range(code, begin_op2, end_op2), "code check"); | } | | LIR_Op2(LIR_Code code, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, LIR_Opr tmp1, LIR_Opr tmp2 = LIR_OprFact::illegalOpr, |@@@ -1684,7 -1658,7 +1675,11 @@@ | , _tmp4(tmp4) | , _tmp5(tmp5) | , _condition(lir_cond_unknown) { |- assert((code != lir_cmp && code != lir_cmp_branch && code != lir_cmp_float_branch) && is_in_range(code, begin_op2, end_op2), "code check"); | - assert(code != lir_cmp && RISCV_ONLY(code != lir_branch && code != lir_cond_float_branch &&) is_in_range(code, begin_op2, end_op2), "code check"); |++ assert(code != lir_cmp && |++#if defined(RISCV) || defined(LOONGARCH) |++ code != lir_branch && code != lir_cond_float_branch && |++#endif |++ is_in_range(code, begin_op2, end_op2), "code check"); | } | | LIR_Opr in_opr1() const { return _opr1; } |@@@ -1696,12 -1670,18 +1691,18 @@@ | LIR_Opr tmp4_opr() const { return _tmp4; } | LIR_Opr tmp5_opr() const { return _tmp5; } | LIR_Condition condition() const { |- assert(code() == lir_cmp || code() == lir_cmp_branch || code() == lir_cmp_float_branch || code() == lir_cmove || code() == lir_assert, "only valid for cmp and cmove and assert"); |- return _condition; | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ assert(code() == lir_cmp || code() == lir_branch || code() == lir_cond_float_branch || code() == lir_assert, "only valid for branch and assert"); return _condition; |+ #else |+ assert(code() == lir_cmp || code() == lir_cmove || code() == lir_assert, "only valid for cmp and cmove and assert"); return _condition; |+ #endif | } | void set_condition(LIR_Condition condition) { |- assert(code() == lir_cmp || code() == lir_cmp_branch || code() == lir_cmp_float_branch || code() == lir_cmove, "only valid for cmp and cmove"); |- _condition = condition; | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ assert(code() == lir_cmp || code() == lir_branch || code() == lir_cond_float_branch, "only valid for branch"); _condition = condition; |+ #else |+ assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove"); _condition = condition; |+ #endif | } | | void set_fpu_stack_size(int size) { _fpu_stack_size = size; } |@@@ -1715,33 -1695,52 +1716,52 @@@ | virtual void print_instr(outputStream* out) const PRODUCT_RETURN; | }; | |- class LIR_OpCmpBranch: public LIR_Op2 { | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ class LIR_OpBranch: public LIR_Op2 { |+ #else |+ class LIR_OpBranch: public LIR_Op { |+ #endif | friend class LIR_OpVisitState; | | private: | -#ifndef RISCV |++#if !defined(RISCV) && !defined(LOONGARCH) |+ LIR_Condition _cond; |+ #endif | Label* _label; | BlockBegin* _block; // if this is a branch to a block, this is the block |- BlockBegin* _ublock; // if this is a float-branch, this is the unorderd block |+ BlockBegin* _ublock; // if this is a float-branch, this is the unordered block | CodeStub* _stub; // if this is a branch to a stub, this is the stub | | public: |- LIR_OpCmpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, Label* lbl, CodeEmitInfo* info = NULL) |- : LIR_Op2(lir_cmp_branch, cond, left, right, info) |+ LIR_OpBranch(LIR_Condition cond, Label* lbl) | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ : LIR_Op2(lir_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*) NULL) |+ #else |+ : LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*) NULL) |+ , _cond(cond) |+ #endif | , _label(lbl) | , _block(NULL) | , _ublock(NULL) | , _stub(NULL) { } | |- LIR_OpCmpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, CodeStub* stub, CodeEmitInfo* info = NULL); |- LIR_OpCmpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BlockBegin* block, CodeEmitInfo* info = NULL); |+ LIR_OpBranch(LIR_Condition cond, BlockBegin* block); |+ LIR_OpBranch(LIR_Condition cond, CodeStub* stub); | | // for unordered comparisons |- LIR_OpCmpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BlockBegin* block, BlockBegin* ublock, CodeEmitInfo* info = NULL); |+ LIR_OpBranch(LIR_Condition cond, BlockBegin* block, BlockBegin* ublock); | |- Label* label() const { return _label; } |- BlockBegin* block() const { return _block; } |- BlockBegin* ublock() const { return _ublock; } |- CodeStub* stub() const { return _stub; } | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ LIR_Condition cond() const { return condition(); } |+ void set_cond(LIR_Condition cond) { set_condition(cond); } |+ #else |+ LIR_Condition cond() const { return _cond; } |+ void set_cond(LIR_Condition cond) { _cond = cond; } |+ #endif |+ Label* label() const { return _label; } |+ BlockBegin* block() const { return _block; } |+ BlockBegin* ublock() const { return _ublock; } |+ CodeStub* stub() const { return _stub; } | | void change_block(BlockBegin* b); | void change_ublock(BlockBegin* b); |@@@ -1815,22 -1814,25 +1835,25 @@@ class LIR_Op3: public LIR_Op | virtual void print_instr(outputStream* out) const PRODUCT_RETURN; | }; | |- | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) | class LIR_Op4: public LIR_Op { |- friend class LIR_OpVisitState; |- |- private: |- LIR_Opr _opr1; |- LIR_Opr _opr2; |- LIR_Opr _opr3; |- LIR_Opr _opr4; |+ friend class LIR_OpVisitState; |+ protected: |+ LIR_Opr _opr1; |+ LIR_Opr _opr2; |+ LIR_Opr _opr3; |+ LIR_Opr _opr4; | BasicType _type; |+ LIR_Opr _tmp1; |+ LIR_Opr _tmp2; |+ LIR_Opr _tmp3; |+ LIR_Opr _tmp4; |+ LIR_Opr _tmp5; | LIR_Condition _condition; | |- void verify() const; |- | public: |- LIR_Op4(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr opr3, LIR_Opr opr4, LIR_Opr result, BasicType type) |+ LIR_Op4(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr opr3, LIR_Opr opr4, |+ LIR_Opr result, BasicType type) | : LIR_Op(code, result, NULL) | , _opr1(opr1) | , _opr2(opr2) |@@@ -2079,6 -2112,10 +2133,10 @@@ class LIR_List: public CompilationResou | const char * _file; | int _line; | #endif | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ LIR_Opr _cmp_opr1; |+ LIR_Opr _cmp_opr2; |+ #endif | | public: | void append(LIR_Op* op) { |@@@ -2091,6 -2128,12 +2149,12 @@@ | } | #endif // PRODUCT | | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ set_cmp_oprs(op); |+ // lir_cmp set cmp oprs only on riscv |+ if (op->code() == lir_cmp) return; |+ #endif |+ | _operations.append(op); | | #ifdef ASSERT |@@@ -2107,6 -2150,10 +2171,10 @@@ | void set_file_and_line(const char * file, int line); | #endif | | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ void set_cmp_oprs(LIR_Op* op); |+ #endif |+ | //---------- accessors --------------- | LIR_OpList* instructions_list() { return &_operations; } | int length() const { return _operations.length(); } |@@@ -2228,15 -2273,12 +2296,12 @@@ | void cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info); | void cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Address* addr, CodeEmitInfo* info); | | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ void cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst, BasicType type, |+ LIR_Opr cmp_opr1 = LIR_OprFact::illegalOpr, LIR_Opr cmp_opr2 = LIR_OprFact::illegalOpr) { |+ append(new LIR_Op4(lir_cmove, condition, src1, src2, cmp_opr1, cmp_opr2, dst, type)); |+ } |+ #else | void cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst, BasicType type) { | append(new LIR_Op2(lir_cmove, condition, src1, src2, dst, type)); | } |diff --cc src/hotspot/share/c1/c1_LIRAssembler.cpp |index 09053d94b51,989a6f8ad25..e288de2ab8e |--- a/src/hotspot/share/c1/c1_LIRAssembler.cpp |+++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp |@@@ -22,6 -22,6 +22,12 @@@ | * | */ | |++/* |++ * This file has been modified by Loongson Technology in 2023, These |++ * modifications are Copyright (c) 2022, 2023, Loongson Technology, and are made |++ * available on the same license terms set forth above. |++ */ |++ | #include "precompiled.hpp" | #include "asm/assembler.inline.hpp" | #include "c1/c1_Compilation.hpp" |@@@ -691,6 -691,7 +697,7 @@@ void LIR_Assembler::emit_op2(LIR_Op2* o | comp_fl2i(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op); | break; | | -#ifndef RISCV |++#if !defined(RISCV) && !defined(LOONGARCH) | case lir_cmove: | cmove(op->condition(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->type()); | break; |@@@ -756,11 -758,11 +764,11 @@@ | } | } | |- | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) | void LIR_Assembler::emit_op4(LIR_Op4* op) { |- switch (op->code()) { |- case lir_cmp_cmove: |- cmp_cmove(op->condition(), op->in_opr1(), op->in_opr2(), op->in_opr3(), op->in_opr4(), op->result_opr(), op->type()); |+ switch(op->code()) { |+ case lir_cmove: |+ cmove(op->condition(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->type(), op->in_opr3(), op->in_opr4()); | break; | | default: |diff --cc src/hotspot/share/c1/c1_LIRAssembler.hpp |index d0cceefdda1,c82baa15fe7..84c34db4985 |--- a/src/hotspot/share/c1/c1_LIRAssembler.hpp |+++ b/src/hotspot/share/c1/c1_LIRAssembler.hpp |@@@ -22,6 -22,6 +22,12 @@@ | * | */ | |++/* |++ * This file has been modified by Loongson Technology in 2023, These |++ * modifications are Copyright (c) 2022, 2023, Loongson Technology, and are made |++ * available on the same license terms set forth above. |++ */ |++ | #ifndef SHARE_C1_C1_LIRASSEMBLER_HPP | #define SHARE_C1_C1_LIRASSEMBLER_HPP | |@@@ -186,9 -186,10 +192,10 @@@ class LIR_Assembler: public Compilation | void emit_op1(LIR_Op1* op); | void emit_op2(LIR_Op2* op); | void emit_op3(LIR_Op3* op); | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) | void emit_op4(LIR_Op4* op); |+ #endif | void emit_opBranch(LIR_OpBranch* op); |- void emit_opCmpBranch(LIR_OpCmpBranch* op); | void emit_opLabel(LIR_OpLabel* op); | void emit_arraycopy(LIR_OpArrayCopy* op); | void emit_updatecrc32(LIR_OpUpdateCRC32* op); |@@@ -220,9 -222,12 +228,12 @@@ | void volatile_move_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info); | void comp_mem_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info); // info set for null exceptions | void comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr result, LIR_Op2* op); | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ void cmove(LIR_Condition code, LIR_Opr left, LIR_Opr right, LIR_Opr result, BasicType type, |+ LIR_Opr cmp_opr1 = LIR_OprFact::illegalOpr, LIR_Opr cmp_opr2 = LIR_OprFact::illegalOpr); |+ #else | void cmove(LIR_Condition code, LIR_Opr left, LIR_Opr right, LIR_Opr result, BasicType type); |- void cmp_cmove(LIR_Condition code, LIR_Opr left, LIR_Opr right, LIR_Opr src1, LIR_Opr src2, LIR_Opr result, BasicType type); |- |+ #endif | void call( LIR_OpJavaCall* op, relocInfo::relocType rtype); | void ic_call( LIR_OpJavaCall* op); | void vtable_call( LIR_OpJavaCall* op); |diff --cc src/hotspot/share/c1/c1_LinearScan.cpp |index f81a440d237,d3d38d11a90..6947406b2e7 |--- a/src/hotspot/share/c1/c1_LinearScan.cpp |+++ b/src/hotspot/share/c1/c1_LinearScan.cpp |@@@ -35,12 -35,6 +35,12 @@@ | #include "runtime/timerTrace.hpp" | #include "utilities/bitMap.inline.hpp" | | +/* |- * This file has been modified by Loongson Technology in 2022, These |- * modifications are Copyright (c) 2022, Loongson Technology, and are made |++ * This file has been modified by Loongson Technology in 2023, These |++ * modifications are Copyright (c) 2022, 2023, Loongson Technology, and are made | + * available on the same license terms set forth above. | + */ | + | #ifndef PRODUCT | | static LinearScanStatistic _stat_before_alloc; |@@@ -1246,8 -1240,13 +1246,13 @@@ void LinearScan::add_register_hints(LIR | break; | } | case lir_cmove: { | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ assert(op->as_Op4() != NULL, "lir_cmove must be LIR_Op4"); |+ LIR_Op4* cmove = (LIR_Op4*)op; |+ #else | assert(op->as_Op2() != NULL, "lir_cmove must be LIR_Op2"); | LIR_Op2* cmove = (LIR_Op2*)op; |+ #endif | | LIR_Opr move_from = cmove->in_opr1(); | LIR_Opr move_to = cmove->result_opr(); |@@@ -3161,6 -3151,9 +3157,9 @@@ void LinearScan::do_linear_scan() | } | } | | -#ifndef RISCV |++#if !defined(RISCV) && !defined(LOONGARCH) |+ // Disable these optimizations on riscv temporarily, because it does not |+ // work when the comparison operands are bound to branches or cmoves. | { TIME_LINEAR_SCAN(timer_optimize_lir); | | EdgeMoveOptimizer::optimize(ir()->code()); |@@@ -6403,14 -6385,23 +6391,23 @@@ void ControlFlowOptimizer::delete_unnec | // There might be a cmove inserted for profiling which depends on the same | // compare. If we change the condition of the respective compare, we have | // to take care of this cmove as well. | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ LIR_Op4* prev_cmove = NULL; |+ #else | LIR_Op2* prev_cmove = NULL; |+ #endif | | for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) { | prev_op = instructions->at(j); | // check for the cmove | if (prev_op->code() == lir_cmove) { | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ assert(prev_op->as_Op4() != NULL, "cmove must be of type LIR_Op4"); |+ prev_cmove = (LIR_Op4*)prev_op; |+ #else | assert(prev_op->as_Op2() != NULL, "cmove must be of type LIR_Op2"); | prev_cmove = (LIR_Op2*)prev_op; |+ #endif | assert(prev_branch->cond() == prev_cmove->condition(), "should be the same"); | } | if (prev_op->code() == lir_cmp) { |diff --cc src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp |index c6717bb76af,7d31ff02e1a..07dac06aecf |--- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp |+++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp |@@@ -41,7 -35,7 +41,7 @@@ | #include "utilities/defaultStream.hpp" | | void ShenandoahArguments::initialize() { |- #if !(defined AARCH64 || defined AMD64 || defined IA32 || defined PPC64 || defined LOONGARCH64) | -#if !(defined AARCH64 || defined AMD64 || defined IA32 || defined PPC64 || defined RISCV64) |++#if !(defined AARCH64 || defined AMD64 || defined IA32 || defined PPC64 || defined RISCV64 || defined LOONGARCH64) | vm_exit_during_initialization("Shenandoah GC is not supported on this platform."); | #endif | |diff --cc src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp |index b145a63363a,0e99bf107c1..d5541cf8966 |--- a/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp |+++ b/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp |@@@ -21,6 -21,6 +21,12 @@@ | * questions. | */ | |++/* |++ * This file has been modified by Loongson Technology in 2023, These |++ * modifications are Copyright (c) 2022, 2023, Loongson Technology, and are made |++ * available on the same license terms set forth above. |++ */ |++ | #include "precompiled.hpp" | #include "c1/c1_LIR.hpp" | #include "c1/c1_LIRGenerator.hpp" |@@@ -94,7 -94,11 +100,11 @@@ private | | public: | LIR_OpZLoadBarrierTest(LIR_Opr opr) : | -#ifdef RISCV |++#if defined(RISCV) || defined(LOONGARCH) |+ LIR_Op(lir_zloadbarrier_test, LIR_OprFact::illegalOpr, NULL), |+ #else | LIR_Op(), |+ #endif | _opr(opr) {} | | virtual void visit(LIR_OpVisitState* state) { |diff --cc src/hotspot/share/jfr/utilities/jfrBigEndian.hpp |index c381aa11475,597ddb3800f..427a9503eaf |--- a/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp |+++ b/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp |@@@ -108,7 -102,7 +108,7 @@@ inline T JfrBigEndian::read_unaligned(c | inline bool JfrBigEndian::platform_supports_unaligned_reads(void) { | #if defined(IA32) || defined(AMD64) || defined(PPC) || defined(S390) | return true; |- #elif defined(ARM) || defined(AARCH64) || defined(MIPS) || defined(LOONGARCH) | -#elif defined(ARM) || defined(AARCH64) || defined(RISCV) |++#elif defined(ARM) || defined(AARCH64) || defined(RISCV) || defined(MIPS) || defined(LOONGARCH) | return false; | #else | #warning "Unconfigured platform" |diff --cc src/hotspot/share/opto/output.cpp |index 79c2b223588,8a1ed0d3160..596829c07ca |--- a/src/hotspot/share/opto/output.cpp |+++ b/src/hotspot/share/opto/output.cpp |@@@ -1016,28 -1010,7 +1016,28 @@@ void PhaseOutput::Process_OopMap_Node(M | | // Add the safepoint in the DebugInfoRecorder | if( !mach->is_MachCall() ) { |- mcall = NULL; |+ mcall = nullptr; | +#if defined(MIPS) || defined(LOONGARCH) | + // safepoint_pc_offset should point to tha last instruction in safePoint. | + // In X86 and sparc, their safePoints only contain one instruction. | + // However, we should add current_offset with the size of safePoint in MIPS. | + // 0x2d6ff22c: lw s2, 0x14(s2) | + // last_pd->pc_offset()=308, pc_offset=304, bci=64 | + // last_pd->pc_offset()=312, pc_offset=312, bci=64 | + // src/hotspot/share/code/debugInfoRec.cpp:295, assert(last_pd->pc_offset() == pc_offset, "must be last pc") | + // | + // ;; Safepoint: | + // ---> pc_offset=304 | + // 0x2d6ff230: lui at, 0x2b7a ; OopMap{s2=Oop s5=Oop t4=Oop off=308} | + // ;*goto | + // ; - java.util.Hashtable::get@64 (line 353) | + // ---> last_pd(308) | + // 0x2d6ff234: lw at, 0xffffc100(at) ;*goto | + // ; - java.util.Hashtable::get@64 (line 353) | + // ; {poll} | + // 0x2d6ff238: addiu s0, zero, 0x0 | + safepoint_pc_offset += sfn->size(C->regalloc()) - 4; | +#endif | C->debug_info()->add_safepoint(safepoint_pc_offset, sfn->_oop_map); | } else { | mcall = mach->as_MachCall(); |diff --cc src/hotspot/share/runtime/thread.inline.hpp |index 9b72ada86b6,d86fce3c8ac..71bfd4dfa19 |--- a/src/hotspot/share/runtime/thread.inline.hpp |+++ b/src/hotspot/share/runtime/thread.inline.hpp |@@@ -138,7 -132,7 +138,7 @@@ inline void JavaThread::set_pending_asy | } | | inline JavaThreadState JavaThread::thread_state() const { |- #if defined(PPC64) || defined (AARCH64) || defined(LOONGARCH64) | -#if defined(PPC64) || defined (AARCH64) || defined(RISCV64) |++#if defined(PPC64) || defined (AARCH64) || defined(RISCV64) || defined(LOONGARCH64) | // Use membars when accessing volatile _thread_state. See | // Threads::create_vm() for size checks. | return (JavaThreadState) Atomic::load_acquire((volatile jint*)&_thread_state); |@@@ -150,7 -144,7 +150,7 @@@ | inline void JavaThread::set_thread_state(JavaThreadState s) { | assert(current_or_null() == NULL || current_or_null() == this, | "state change should only be called by the current thread"); |- #if defined(PPC64) || defined (AARCH64) || defined(LOONGARCH64) | -#if defined(PPC64) || defined (AARCH64) || defined(RISCV64) |++#if defined(PPC64) || defined (AARCH64) || defined(RISCV64) || defined(LOONGARCH64) | // Use membars when accessing volatile _thread_state. See | // Threads::create_vm() for size checks. | Atomic::release_store((volatile jint*)&_thread_state, (jint)s); |diff --cc src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.cpp |index c2a144f49b8,9accba375a2..200bb1e82f3 |--- a/src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.cpp |+++ b/src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.cpp |@@@ -67,10 -60,10 +67,14 @@@ | #include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h" | #endif | |+ #ifdef riscv64 |+ #include "sun_jvm_hotspot_debugger_riscv64_RISCV64ThreadContext.h" |+ #endif |+ | +#ifdef loongarch64 | +#include "sun_jvm_hotspot_debugger_loongarch64_LOONGARCH64ThreadContext.h" | +#endif | + | class AutoJavaString { | JNIEnv* m_env; | jstring m_str; |@@@ -419,7 -412,7 +423,7 @@@ JNIEXPORT jbyteArray JNICALL Java_sun_j | return (err == PS_OK)? array : 0; | } | |- #if defined(i586) || defined(amd64) || defined(ppc64) || defined(ppc64le) || defined(aarch64) || defined(loongarch64) | -#if defined(i586) || defined(amd64) || defined(ppc64) || defined(ppc64le) || defined(aarch64) || defined(riscv64) |++#if defined(i586) || defined(amd64) || defined(ppc64) || defined(ppc64le) || defined(aarch64) || defined(riscv64) || defined(loongarch64) | extern "C" | JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0 | (JNIEnv *env, jobject this_obj, jint lwp_id) { |@@@ -451,9 -444,9 +455,12 @@@ | #ifdef aarch64 | #define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG | #endif |+ #ifdef riscv64 |+ #define NPRGREG sun_jvm_hotspot_debugger_riscv64_RISCV64ThreadContext_NPRGREG |+ #endif | +#ifdef loongarch64 | +#define NPRGREG sun_jvm_hotspot_debugger_loongarch64_LOONGARCH64ThreadContext_NPRGREG | +#endif | #if defined(ppc64) || defined(ppc64le) | #define NPRGREG sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_NPRGREG | #endif |@@@ -530,18 -523,44 +537,56 @@@ | } | #endif /* aarch64 */ | |+ #if defined(riscv64) |+ #define REG_INDEX(reg) sun_jvm_hotspot_debugger_riscv64_RISCV64ThreadContext_##reg |+ |+ regs[REG_INDEX(PC)] = gregs.pc; |+ regs[REG_INDEX(LR)] = gregs.ra; |+ regs[REG_INDEX(SP)] = gregs.sp; |+ regs[REG_INDEX(R3)] = gregs.gp; |+ regs[REG_INDEX(R4)] = gregs.tp; |+ regs[REG_INDEX(R5)] = gregs.t0; |+ regs[REG_INDEX(R6)] = gregs.t1; |+ regs[REG_INDEX(R7)] = gregs.t2; |+ regs[REG_INDEX(R8)] = gregs.s0; |+ regs[REG_INDEX(R9)] = gregs.s1; |+ regs[REG_INDEX(R10)] = gregs.a0; |+ regs[REG_INDEX(R11)] = gregs.a1; |+ regs[REG_INDEX(R12)] = gregs.a2; |+ regs[REG_INDEX(R13)] = gregs.a3; |+ regs[REG_INDEX(R14)] = gregs.a4; |+ regs[REG_INDEX(R15)] = gregs.a5; |+ regs[REG_INDEX(R16)] = gregs.a6; |+ regs[REG_INDEX(R17)] = gregs.a7; |+ regs[REG_INDEX(R18)] = gregs.s2; |+ regs[REG_INDEX(R19)] = gregs.s3; |+ regs[REG_INDEX(R20)] = gregs.s4; |+ regs[REG_INDEX(R21)] = gregs.s5; |+ regs[REG_INDEX(R22)] = gregs.s6; |+ regs[REG_INDEX(R23)] = gregs.s7; |+ regs[REG_INDEX(R24)] = gregs.s8; |+ regs[REG_INDEX(R25)] = gregs.s9; |+ regs[REG_INDEX(R26)] = gregs.s10; |+ regs[REG_INDEX(R27)] = gregs.s11; |+ regs[REG_INDEX(R28)] = gregs.t3; |+ regs[REG_INDEX(R29)] = gregs.t4; |+ regs[REG_INDEX(R30)] = gregs.t5; |+ regs[REG_INDEX(R31)] = gregs.t6; |+ |+ #endif /* riscv64 */ |+ | +#if defined(loongarch64) | + | +#define REG_INDEX(reg) sun_jvm_hotspot_debugger_loongarch64_LOONGARCH64ThreadContext_##reg | + | + { | + int i; | + for (i = 0; i < 31; i++) | + regs[i] = gregs.regs[i]; | + regs[REG_INDEX(PC)] = gregs.csr_era; | + } | +#endif /* loongarch64 */ | + | #if defined(ppc64) || defined(ppc64le) | #define REG_INDEX(reg) sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_##reg | |diff --cc src/jdk.hotspot.agent/linux/native/libsaproc/libproc.h |index 17920fafec9,a69496e77a4..64312b4705d |--- a/src/jdk.hotspot.agent/linux/native/libsaproc/libproc.h |+++ b/src/jdk.hotspot.agent/linux/native/libsaproc/libproc.h |@@@ -50,11 -43,9 +50,13 @@@ | #elif defined(arm) | #include | #define user_regs_struct pt_regs |+ #elif defined(riscv64) |+ #include | #endif | +#if defined(mips) || defined(mipsel) || defined(mips64) || defined(mips64el) | +#include | +#define user_regs_struct pt_regs | +#endif | | // This C bool type must be int for compatibility with Linux calls and | // it would be a mistake to equivalence it to C++ bool on many platforms |diff --cc src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java |index 021ba6f2820,e0e9b4b6727..9af1218ed46 |--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java |+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java |@@@ -42,9 -36,8 +42,10 @@@ import sun.jvm.hotspot.debugger.Machine | import sun.jvm.hotspot.debugger.MachineDescriptionAMD64; | import sun.jvm.hotspot.debugger.MachineDescriptionPPC64; | import sun.jvm.hotspot.debugger.MachineDescriptionAArch64; |+ import sun.jvm.hotspot.debugger.MachineDescriptionRISCV64; | import sun.jvm.hotspot.debugger.MachineDescriptionIntelX86; | +import sun.jvm.hotspot.debugger.MachineDescriptionMIPS64; | +import sun.jvm.hotspot.debugger.MachineDescriptionLOONGARCH64; | import sun.jvm.hotspot.debugger.NoSuchSymbolException; | import sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal; | import sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal; |@@@ -577,10 -570,8 +578,12 @@@ public class HotSpotAgent | machDesc = new MachineDescriptionPPC64(); | } else if (cpu.equals("aarch64")) { | machDesc = new MachineDescriptionAArch64(); |+ } else if (cpu.equals("riscv64")) { |+ machDesc = new MachineDescriptionRISCV64(); | + } else if (cpu.equals("mips64")) { | + machDesc = new MachineDescriptionMIPS64(); | + } else if (cpu.equals("loongarch64")) { | + machDesc = new MachineDescriptionLOONGARCH64(); | } else { | try { | machDesc = (MachineDescription) |diff --cc src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java |index db3b1cc20ee,469bb6e0665..ea3a118de2a |--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java |+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java |@@@ -39,15 -33,13 +39,17 @@@ import sun.jvm.hotspot.debugger.cdbg.* | import sun.jvm.hotspot.debugger.x86.*; | import sun.jvm.hotspot.debugger.amd64.*; | import sun.jvm.hotspot.debugger.aarch64.*; |+ import sun.jvm.hotspot.debugger.riscv64.*; | +import sun.jvm.hotspot.debugger.mips64.*; | +import sun.jvm.hotspot.debugger.loongarch64.*; | import sun.jvm.hotspot.debugger.ppc64.*; | import sun.jvm.hotspot.debugger.linux.x86.*; | import sun.jvm.hotspot.debugger.linux.amd64.*; | import sun.jvm.hotspot.debugger.linux.ppc64.*; | import sun.jvm.hotspot.debugger.linux.aarch64.*; |+ import sun.jvm.hotspot.debugger.linux.riscv64.*; | +import sun.jvm.hotspot.debugger.linux.mips64.*; | +import sun.jvm.hotspot.debugger.linux.loongarch64.*; | import sun.jvm.hotspot.utilities.*; | | class LinuxCDebugger implements CDebugger { |diff --cc src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java |index 59e4a3aca46,d16ac8aae51..de1e70a7290 |--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java |+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java |@@@ -40,9 -34,8 +40,10 @@@ import sun.jvm.hotspot.runtime.win32_aa | import sun.jvm.hotspot.runtime.linux_x86.LinuxX86JavaThreadPDAccess; | import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess; | import sun.jvm.hotspot.runtime.linux_aarch64.LinuxAARCH64JavaThreadPDAccess; |+ import sun.jvm.hotspot.runtime.linux_riscv64.LinuxRISCV64JavaThreadPDAccess; | import sun.jvm.hotspot.runtime.linux_ppc64.LinuxPPC64JavaThreadPDAccess; | +import sun.jvm.hotspot.runtime.linux_mips64.LinuxMIPS64JavaThreadPDAccess; | +import sun.jvm.hotspot.runtime.linux_loongarch64.LinuxLOONGARCH64JavaThreadPDAccess; | import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess; | import sun.jvm.hotspot.runtime.bsd_amd64.BsdAMD64JavaThreadPDAccess; | import sun.jvm.hotspot.runtime.bsd_aarch64.BsdAARCH64JavaThreadPDAccess; |@@@ -121,10 -114,8 +122,12 @@@ public class Threads | access = new LinuxPPC64JavaThreadPDAccess(); | } else if (cpu.equals("aarch64")) { | access = new LinuxAARCH64JavaThreadPDAccess(); |+ } else if (cpu.equals("riscv64")) { |+ access = new LinuxRISCV64JavaThreadPDAccess(); | + } else if (cpu.equals("mips64")) { | + access = new LinuxMIPS64JavaThreadPDAccess(); | + } else if (cpu.equals("loongarch64")) { | + access = new LinuxLOONGARCH64JavaThreadPDAccess(); | } else { | try { | access = (JavaThreadPDAccess) |diff --cc src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java |index f894792f912,f4cd4873207..6901946e58a |--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java |+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java |@@@ -57,7 -50,7 +57,7 @@@ public class PlatformInfo | | public static boolean knownCPU(String cpu) { | final String[] KNOWN = |- new String[] {"i386", "x86", "x86_64", "amd64", "ppc64", "ppc64le", "aarch64", "mips64", "mips64el", "loongarch64"}; | - new String[] {"i386", "x86", "x86_64", "amd64", "ppc64", "ppc64le", "aarch64", "riscv64"}; |++ new String[] {"i386", "x86", "x86_64", "amd64", "ppc64", "ppc64le", "aarch64", "riscv64", "mips64", "mips64el", "loongarch64"}; | | for(String s : KNOWN) { | if(s.equals(cpu)) |diff --cc test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java |index 3c81fc96949,4c56daebfb8..92836130408 |--- a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java |+++ b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java |@@@ -32,9 -26,9 +32,9 @@@ | * @library /test/lib / | * @modules java.base/jdk.internal.misc | * java.management | - * @requires vm.cpu.features ~= ".*aes.*" & !vm.graal.enabled | + * @requires (vm.cpu.features ~= ".*aes.*" | os.arch == "loongarch64") & !vm.graal.enabled |- * @build sun.hotspot.WhiteBox |- * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox |+ * @build jdk.test.whitebox.WhiteBox |+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox | * @run main/othervm/timeout=600 -Xbootclasspath/a:. | * -XX:+UnlockDiagnosticVMOptions | * -XX:+WhiteBoxAPI -Xbatch |diff --cc test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java |index 460a3dafe38,03016ea3dd6..62ce6c1a7a5 |--- a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java |+++ b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java |@@@ -33,10 -27,10 +33,10 @@@ | * @modules java.base/jdk.internal.misc | * java.management | * |- * @build sun.hotspot.WhiteBox |+ * @build jdk.test.whitebox.WhiteBox | - * @requires !(vm.cpu.features ~= ".*aes.*") | + * @requires !(vm.cpu.features ~= ".*aes.*" | os.arch == "loongarch64") | * @requires vm.compiler1.enabled | !vm.graal.enabled |- * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox |+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox | * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions | * -XX:+WhiteBoxAPI -Xbatch | * compiler.cpuflags.TestAESIntrinsicsOnUnsupportedConfig |diff --cc test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java |index 0209ea644ef,468cd83d7a2..40d2b03e301 |--- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java |+++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java |@@@ -38,7 -32,7 +38,7 @@@ import jdk.test.lib.cli.predicate.OrPre | | /** | * Generic test case for SHA-related options targeted to any CPU except |- * AArch64, PPC, S390x, LoongArch64, and X86. | - * AArch64, RISCV64, PPC, S390x, and X86. |++ * AArch64, RISCV64, PPC, S390x, LoongArch64, and X86. | */ | public class GenericTestCaseForOtherCPU extends | DigestOptionsBase.TestCase { |@@@ -50,14 -44,14 +50,15 @@@ | } | | public GenericTestCaseForOtherCPU(String optionName, boolean checkUseSHA) { |- // Execute the test case on any CPU except AArch64, PPC, S390x, LoongArch64, and X86. | - // Execute the test case on any CPU except AArch64, RISCV64, PPC, S390x, and X86. |++ // Execute the test case on any CPU except AArch64, RISCV64, PPC, S390x, LoongArch64, and X86. | super(optionName, new NotPredicate( | new OrPredicate(Platform::isAArch64, |+ new OrPredicate(Platform::isRISCV64, | new OrPredicate(Platform::isS390x, | new OrPredicate(Platform::isPPC, | + new OrPredicate(Platform::isLoongArch64, | new OrPredicate(Platform::isX64, |-- Platform::isX86))))))); |++ Platform::isX86)))))))); | | this.checkUseSHA = checkUseSHA; | } |diff --cc test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java |index 93ffcadf8bc,2f2395b77c6..58482edb32e |--- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java |+++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java |@@@ -59,13 -53,13 +59,13 @@@ public class IRNode | private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; | private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; | |- public static final String ALLOC = "(.*precise klass .*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END; |- public static final String ALLOC_OF = COMPOSITE_PREFIX + "(.*precise klass .*" + IS_REPLACED + ":.*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END; |- public static final String ALLOC_ARRAY = "(.*precise klass \\[L.*\\R((.*(?i:mov|xor|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END; |- public static final String ALLOC_ARRAY_OF = COMPOSITE_PREFIX + "(.*precise klass \\[L.*" + IS_REPLACED + ";:.*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END; |+ public static final String ALLOC = "(.*precise klass .*\\R((.*(?i:mov|mv|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END; |+ public static final String ALLOC_OF = COMPOSITE_PREFIX + "(.*precise klass .*" + IS_REPLACED + ":.*\\R((.*(?i:mov|mv|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END; |+ public static final String ALLOC_ARRAY = "(.*precise klass \\[L.*\\R((.*(?i:mov|mv|xor|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END; |+ public static final String ALLOC_ARRAY_OF = COMPOSITE_PREFIX + "(.*precise klass \\[L.*" + IS_REPLACED + ";:.*\\R((.*(?i:mov|mv|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END; | |- public static final String CHECKCAST_ARRAY = "(((?i:cmp|CLFI|CLR).*precise klass \\[.*;:|.*(?i:mov|or|li).*precise klass \\[.*;:.*\\R.*(cmp|CMP|CLR))" + END; |- public static final String CHECKCAST_ARRAY_OF = COMPOSITE_PREFIX + "(((?i:cmp|CLFI|CLR).*precise klass \\[.*" + IS_REPLACED + ";:|.*(?i:mov|or|li).*precise klass \\[.*" + IS_REPLACED + ";:.*\\R.*(cmp|CMP|CLR))" + END; | - public static final String CHECKCAST_ARRAY = "(((?i:cmp|CLFI|CLR).*precise klass \\[.*;:|.*(?i:mov|mv|or).*precise klass \\[.*;:.*\\R.*(cmp|CMP|CLR))" + END; | - public static final String CHECKCAST_ARRAY_OF = COMPOSITE_PREFIX + "(((?i:cmp|CLFI|CLR).*precise klass \\[.*" + IS_REPLACED + ";:|.*(?i:mov|mv|or).*precise klass \\[.*" + IS_REPLACED + ";:.*\\R.*(cmp|CMP|CLR))" + END; |++ public static final String CHECKCAST_ARRAY = "(((?i:cmp|CLFI|CLR).*precise klass \\[.*;:|.*(?i:mov|mv|or|li).*precise klass \\[.*;:.*\\R.*(cmp|CMP|CLR))" + END; |++ public static final String CHECKCAST_ARRAY_OF = COMPOSITE_PREFIX + "(((?i:cmp|CLFI|CLR).*precise klass \\[.*" + IS_REPLACED + ";:|.*(?i:mov|mv|or|li).*precise klass \\[.*" + IS_REPLACED + ";:.*\\R.*(cmp|CMP|CLR))" + END; | // Does not work on s390 (a rule containing this regex will be skipped on s390). | public static final String CHECKCAST_ARRAYCOPY = "(.*((?i:call_leaf_nofp,runtime)|CALL,\\s?runtime leaf nofp|BCTRL.*.leaf call).*checkcast_arraycopy.*" + END; | |diff --cc test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java |index eb9db789f91,85fd3fa938d..0655f2b0bd1 |--- a/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java |+++ b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java |@@@ -136,7 -130,7 +136,7 @@@ public abstract class TestConstantsInEr | results.shouldMatch("Test_C1/.*::test \\(3 bytes\\)$") | .shouldMatch("Test_C2/.*::test \\(3 bytes\\)$"); | |- if (isC1 && (Platform.isAArch64() || Platform.isLoongArch64())) { // no code patching | - if (isC1 && (Platform.isAArch64() || Platform.isRISCV64())) { // no code patching |++ if (isC1 && (Platform.isAArch64() || Platform.isRISCV64() || Platform.isLoongArch64())) { // no code patching | results.shouldMatch("Test_C1/.*::test \\(3 bytes\\) made not entrant") | .shouldMatch("Test_C2/.*::test \\(3 bytes\\) made not entrant"); | } else { |@@@ -174,7 -168,7 +174,7 @@@ | .shouldMatch("Test_MH3/.*::test \\(3 bytes\\)$") | .shouldMatch("Test_MH4/.*::test \\(3 bytes\\)$"); | |- if (isC1 && (Platform.isAArch64() || Platform.isLoongArch64())) { // no code patching | - if (isC1 && (Platform.isAArch64() || Platform.isRISCV64())) { // no code patching |++ if (isC1 && (Platform.isAArch64() || Platform.isRISCV64() || Platform.isLoongArch64())) { // no code patching | results.shouldMatch("Test_MH1/.*::test \\(3 bytes\\) made not entrant") | .shouldMatch("Test_MH2/.*::test \\(3 bytes\\) made not entrant") | .shouldMatch("Test_MH3/.*::test \\(3 bytes\\) made not entrant") |@@@ -197,7 -191,7 +197,7 @@@ | results.shouldMatch("Test_MT1/.*::test \\(3 bytes\\)$") | .shouldMatch("Test_MT2/.*::test \\(3 bytes\\)$"); | |- if (isC1 && (Platform.isAArch64() || Platform.isLoongArch64())) { // no code patching | - if (isC1 && (Platform.isAArch64() || Platform.isRISCV64())) { // no code patching |++ if (isC1 && (Platform.isAArch64() || Platform.isRISCV64() || Platform.isLoongArch64())) { // no code patching | results.shouldMatch("Test_MT1/.*::test \\(3 bytes\\) made not entrant") | .shouldMatch("Test_MT2/.*::test \\(3 bytes\\) made not entrant"); | } else { |diff --cc test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java |index 119acb520da,10d87d51f0f..dbea76741d6 |--- a/test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java |+++ b/test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java |@@@ -30,8 -24,7 +30,8 @@@ | | /* @test | * @bug 8167409 |- * @requires (os.arch != "aarch64") & (os.arch != "arm") & (vm.flavor != "zero") |+ * @requires (os.arch != "aarch64") & (os.arch != "arm") & (os.arch != "riscv64") & (vm.flavor != "zero") | + * @requires (os.arch != "mips64el") & (os.arch != "loongarch64") & (vm.flavor != "zero") | * @run main/othervm/native -Xcomp -XX:+CriticalJNINatives compiler.runtime.criticalnatives.argumentcorruption.CheckLongArgs | */ | package compiler.runtime.criticalnatives.argumentcorruption; |diff --cc test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup/LookUp.java |index d3e73158a25,23c1e6e6acb..2f402d567d9 |--- a/test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup/LookUp.java |+++ b/test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup/LookUp.java |@@@ -30,8 -24,7 +30,8 @@@ | | /* @test | * @bug 8167408 |- * @requires (os.arch != "aarch64") & (os.arch != "arm") & (vm.flavor != "zero") |+ * @requires (os.arch != "aarch64") & (os.arch != "arm") & (os.arch != "riscv64") & (vm.flavor != "zero") | + * @requires (os.arch != "mips64el") & (os.arch != "loongarch64") & (vm.flavor != "zero") | * @run main/othervm/native -Xcomp -XX:+CriticalJNINatives compiler.runtime.criticalnatives.lookup.LookUp | */ | package compiler.runtime.criticalnatives.lookup; |diff --cc test/hotspot/jtreg/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java |index 8b859a92d8a,689c7c8cc2f..f734c1baa3f |--- a/test/hotspot/jtreg/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java |+++ b/test/hotspot/jtreg/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java |@@@ -75,13 -68,12 +75,14 @@@ public class IntrinsicPredicates | | public static final BooleanSupplier SHA1_INSTRUCTION_AVAILABLE | = new OrPredicate(new CPUSpecificPredicate("aarch64.*", new String[] { "sha1" }, null), |+ new OrPredicate(new CPUSpecificPredicate("riscv64.*", new String[] { "sha1" }, null), | new OrPredicate(new CPUSpecificPredicate("s390.*", new String[] { "sha1" }, null), | + // Basic instructions are used to implement SHA1 Intrinsics on LA, so "sha1" feature is not needed. | + new OrPredicate(new CPUSpecificPredicate("loongarch64.*", null, null), | // x86 variants | new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "sha" }, null), | new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { "sha" }, null), |-- new CPUSpecificPredicate("x86.*", new String[] { "sha" }, null)))))); |++ new CPUSpecificPredicate("x86.*", new String[] { "sha" }, null))))))); | | public static final BooleanSupplier SHA256_INSTRUCTION_AVAILABLE | = new OrPredicate(new CPUSpecificPredicate("aarch64.*", new String[] { "sha256" }, null), |@@@ -95,7 -86,7 +97,7 @@@ | new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { "sha" }, null), | new OrPredicate(new CPUSpecificPredicate("x86.*", new String[] { "sha" }, null), | new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "avx2", "bmi2" }, null), |-- new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null)))))))))); |++ new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null))))))))))); | | public static final BooleanSupplier SHA512_INSTRUCTION_AVAILABLE | = new OrPredicate(new CPUSpecificPredicate("aarch64.*", new String[] { "sha512" }, null), |diff --cc test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java |index bf933f04957,36f74d01b54..035b91b9d8e |--- a/test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java |+++ b/test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java |@@@ -246,7 -240,7 +246,8 @@@ public class ReservedStackTest | return Platform.isAix() || | (Platform.isLinux() && | (Platform.isPPC() || Platform.isS390x() || Platform.isX64() || |- Platform.isX86() || Platform.isAArch64() || Platform.isMIPS() || Platform.isLoongArch64())) || | - Platform.isX86() || Platform.isAArch64() || Platform.isRISCV64())) || |++ Platform.isX86() || Platform.isAArch64() || Platform.isRISCV64() || |++ Platform.isMIPS() || Platform.isLoongArch64())) || | Platform.isOSX(); | } | |diff --cc test/jdk/jdk/jfr/event/os/TestCPUInformation.java |index ae739a92f28,c5166580010..913136a1fd1 |--- a/test/jdk/jdk/jfr/event/os/TestCPUInformation.java |+++ b/test/jdk/jdk/jfr/event/os/TestCPUInformation.java |@@@ -58,8 -52,8 +58,8 @@@ public class TestCPUInformation | Events.assertField(event, "hwThreads").atLeast(1); | Events.assertField(event, "cores").atLeast(1); | Events.assertField(event, "sockets").atLeast(1); |- Events.assertField(event, "cpu").containsAny("Intel", "AMD", "Unknown x86", "ARM", "PPC", "PowerPC", "AArch64", "s390", "MIPS", "LoongArch"); |- Events.assertField(event, "description").containsAny("Intel", "AMD", "Unknown x86", "ARM", "PPC", "PowerPC", "AArch64", "s390", "MIPS", "LoongArch"); | - Events.assertField(event, "cpu").containsAny("Intel", "AMD", "Unknown x86", "ARM", "PPC", "PowerPC", "AArch64", "RISCV64", "s390"); | - Events.assertField(event, "description").containsAny("Intel", "AMD", "Unknown x86", "ARM", "PPC", "PowerPC", "AArch64", "RISCV64", "s390"); |++ Events.assertField(event, "cpu").containsAny("Intel", "AMD", "Unknown x86", "ARM", "PPC", "PowerPC", "AArch64", "RISCV64", "s390", "MIPS", "LoongArch"); |++ Events.assertField(event, "description").containsAny("Intel", "AMD", "Unknown x86", "ARM", "PPC", "PowerPC", "AArch64", "RISCV64", "s390", "MIPS", "LoongArch"); | } | } | } |diff --cc test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java |index 9084076f433,c71a6034748..427ebda770f |--- a/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java |+++ b/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java |@@@ -51,7 -45,7 +51,7 @@@ import java.util.Set | */ | public class TestMutuallyExclusivePlatformPredicates { | private static enum MethodGroup { |- ARCH("isAArch64", "isARM", "isPPC", "isS390x", "isX64", "isX86", "isMIPS", "isLoongArch64"), | - ARCH("isAArch64", "isARM", "isRISCV64", "isPPC", "isS390x", "isX64", "isX86"), |++ ARCH("isAArch64", "isARM", "isRISCV64", "isPPC", "isS390x", "isX64", "isX86", "isMIPS", "isLoongArch64"), | BITNESS("is32bit", "is64bit"), | OS("isAix", "isLinux", "isOSX", "isWindows"), | VM_TYPE("isClient", "isServer", "isMinimal", "isZero", "isEmbedded"), | |commit e7efed5c455e2af269d45f1761fb8a22a0834b78 |Author: loongson-jvm |Date: Thu Dec 7 18:05:56 2023 +0800 | | Update (2023.12.07) | | 30457: Use membars when accessing volatile _thread_state | 32163: The size of is_wide_vector should be greater than 8 bytes | |diff --git a/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp b/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp |index 44af7805b8a..930b6240b4b 100644 |--- a/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored patching file src/hotspot/share/runtime/thread.inline.hpp Hunk #2 FAILED at 138. Hunk #3 FAILED at 150. 2 out of 3 hunks FAILED -- saving rejects to file src/hotspot/share/runtime/thread.inline.hpp.rej can't find file to patch at input line 9391 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit 983f139f47a778dcb225d3a514f5ca5f9f949e06 |Merge: 0ca05554a06 3197a9b0299 |Author: aoqi |Date: Mon Aug 14 19:28:14 2023 +0800 | | Merge | |diff --cc src/hotspot/share/memory/metaspace.cpp |index 2bfb3d71634,3f29a72a86d..0b3d26df59c |--- a/src/hotspot/share/memory/metaspace.cpp |+++ b/src/hotspot/share/memory/metaspace.cpp |@@@ -593,15 -587,12 +593,15 @@@ bool Metaspace::class_space_is_initiali | // On error, returns an unreserved space. | ReservedSpace Metaspace::reserve_address_space_for_compressed_classes(size_t size) { | | -#if defined(AARCH64) || defined(PPC64) | +#if defined(AARCH64) || defined(PPC64) || defined(MIPS64) || defined(LOONGARCH64) | const size_t alignment = Metaspace::reserve_alignment(); | |- // AArch64: Try to align metaspace so that we can decode a compressed |- // klass with a single MOVK instruction. We can do this iff the |+ // AArch64: Try to align metaspace class space so that we can decode a |+ // compressed klass with a single MOVK instruction. We can do this iff the | // compressed class base is a multiple of 4G. | + | + // MIPS: Cannot mmap for 1G space at 4G position, and prepare for future optimization. | + | // Additionally, above 32G, ensure the lower LogKlassAlignmentInBytes bits | // of the upper 32-bits of the address are zero so we can handle a shift | // when decoding. |@@@ -627,18 -622,34 +631,34 @@@ | address a = search_ranges[i].from; | assert(CompressedKlassPointers::is_valid_base(a), "Sanity"); | while (a < search_ranges[i].to) { |- ReservedSpace rs(size, Metaspace::reserve_alignment(), |- os::vm_page_size(), (char*)a); |- if (rs.is_reserved()) { |- assert(a == (address)rs.base(), "Sanity"); |- return rs; |- } |+ list.append(a); | a += search_ranges[i].increment; | } |+ } |+ |+ int len = list.length(); |+ int r = 0; |+ if (!DumpSharedSpaces) { |+ // Starting from a random position in the list. If the address cannot be reserved |+ // (the OS already assigned it for something else), go to the next position, wrapping |+ // around if necessary, until we exhaust all the items. |+ os::init_random((int)os::javaTimeNanos()); |+ r = os::random(); |+ log_info(metaspace)("Randomizing compressed class space: start from %d out of %d locations", |+ r % len, len); |+ } |+ for (int i = 0; i < len; i++) { |+ address a = list.at((i + r) % len); |+ ReservedSpace rs(size, Metaspace::reserve_alignment(), |+ os::vm_page_size(), (char*)a); |+ if (rs.is_reserved()) { |+ assert(a == (address)rs.base(), "Sanity"); |+ return rs; |+ } | } | -#endif // defined(AARCH64) || defined(PPC64) | +#endif // defined(AARCH64) || defined(PPC64) || defined(MIPS64) || defined(LOONGARCH64) | | -#ifdef AARCH64 | +#if defined(AARCH64) || defined(MIPS64) || defined(LOONGARCH64) | // Note: on AARCH64, if the code above does not find any good placement, we | // have no recourse. We return an empty space and the VM will exit. | return ReservedSpace(); | |commit 0ca05554a0681d353bc743c741cec776f2e9bf5e |Author: loongson-jvm |Date: Mon Aug 14 19:24:05 2023 +0800 | | Update (2023.08.14, 2nd) | | 30943: LA port of 8303588: [JVMCI] make JVMCI source directories conform with standard layout | 22702: MIPS/LA port of 8252990: Intrinsify Unsafe.storeStoreFence | |diff --git a/src/hotspot/cpu/loongarch/loongarch_64.ad b/src/hotspot/cpu/loongarch/loongarch_64.ad |index daa1db594ce..43e32570a0f 100644 |--- a/src/hotspot/cpu/loongarch/loongarch_64.ad |+++ b/src/hotspot/cpu/loongarch/loongarch_64.ad -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 9403 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/mips/mips_64.ad b/src/hotspot/cpu/mips/mips_64.ad |index ec85f64244c..882878f739a 100644 |--- a/src/hotspot/cpu/mips/mips_64.ad |+++ b/src/hotspot/cpu/mips/mips_64.ad -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored Cannot rename file without two valid file names 1 out of 1 hunk ignored Cannot rename file without two valid file names 1 out of 1 hunk ignored Cannot rename file without two valid file names 1 out of 1 hunk ignored Cannot rename file without two valid file names 1 out of 1 hunk ignored Cannot rename file without two valid file names 1 out of 1 hunk ignored Cannot rename file without two valid file names 1 out of 1 hunk ignored Cannot rename file without two valid file names 1 out of 1 hunk ignored patching file test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInstallationTest.java Hunk #1 FAILED at 22. 1 out of 1 hunk FAILED -- saving rejects to file test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInstallationTest.java.rej can't find file to patch at input line 9593 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit 1f64aa86dc7214e3587472b98886550f777c890f |Merge: d833eebe238 0f531dacb87 |Author: aoqi |Date: Mon Aug 14 17:52:34 2023 +0800 | | Merge | |diff --cc test/lib/jdk/test/lib/Platform.java |index ef98ee74a48,886f54be165..d15decbfa79 |--- a/test/lib/jdk/test/lib/Platform.java |+++ b/test/lib/jdk/test/lib/Platform.java |@@@ -21,16 -21,12 +21,18 @@@ | * questions. | */ | | +/* | + * This file has been modified by Loongson Technology in 2021, These | + * modifications are Copyright (c) 2019, 2021, Loongson Technology, and are made | + * available on the same license terms set forth above. | + */ | + | package jdk.test.lib; | |+ import java.io.BufferedReader; | import java.io.FileNotFoundException; | import java.io.IOException; |+ import java.io.InputStreamReader; | import java.nio.file.Files; | import java.nio.file.Path; | import java.nio.file.Paths; | |commit d833eebe238495b3493dc760d56a5da4490118b7 |Author: loongson-jvm |Date: Mon Aug 14 17:49:18 2023 +0800 | | Update (2023.08.14) | | 30285: ArrayCopy: Align destination address | 27957: Mark stub code without alignment padding | |diff --git a/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp b/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp |index fbdc96f10f5..10242a3df4a 100644 |--- a/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 33 out of 33 hunks ignored can't find file to patch at input line 10126 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit cece1917fcfc054ec2d8e7db859536b2d19b208d |Author: loongson-jvm |Date: Mon Jul 3 21:07:28 2023 +0800 | | Update (2023.07.03) | | 31006: Fix VectorInsert | 30358: Add support for ordering memory barriers | 9854: Implement cross modify fence | |diff --git a/src/hotspot/cpu/loongarch/assembler_loongarch.hpp b/src/hotspot/cpu/loongarch/assembler_loongarch.hpp |index 40a3aea36f8..af65eb878e4 100644 |--- a/src/hotspot/cpu/loongarch/assembler_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/assembler_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 10179 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/c2_MacroAssembler_loongarch.cpp b/src/hotspot/cpu/loongarch/c2_MacroAssembler_loongarch.cpp |index e3a01f1f25d..ef520a39ff3 100644 |--- a/src/hotspot/cpu/loongarch/c2_MacroAssembler_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/c2_MacroAssembler_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 10200 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/loongarch_64.ad b/src/hotspot/cpu/loongarch/loongarch_64.ad |index 703aeafc855..daa1db594ce 100644 |--- a/src/hotspot/cpu/loongarch/loongarch_64.ad |+++ b/src/hotspot/cpu/loongarch/loongarch_64.ad -------------------------- File to patch: Skip this patch? [y] Skipping patch. 3 out of 3 hunks ignored can't find file to patch at input line 10259 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp |index 882c43bf592..f1cf308b447 100644 |--- a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 5 out of 5 hunks ignored can't find file to patch at input line 10315 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/nativeInst_loongarch.hpp b/src/hotspot/cpu/loongarch/nativeInst_loongarch.hpp |index 2f126991338..e445ebeb8be 100644 |--- a/src/hotspot/cpu/loongarch/nativeInst_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/nativeInst_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 10331 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp b/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp |index 0fe2f8f0d36..44af7805b8a 100644 |--- a/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 4 out of 4 hunks ignored can't find file to patch at input line 10376 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/templateInterpreterGenerator_loongarch.cpp b/src/hotspot/cpu/loongarch/templateInterpreterGenerator_loongarch.cpp |index 88b938103bc..02af7c8ffa7 100644 |--- a/src/hotspot/cpu/loongarch/templateInterpreterGenerator_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/templateInterpreterGenerator_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 4 out of 4 hunks ignored can't find file to patch at input line 10421 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/templateTable_loongarch_64.cpp b/src/hotspot/cpu/loongarch/templateTable_loongarch_64.cpp |index 138bf701bf8..c0d1daea305 100644 |--- a/src/hotspot/cpu/loongarch/templateTable_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/templateTable_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 11 out of 11 hunks ignored can't find file to patch at input line 10554 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/os_cpu/linux_loongarch/atomic_linux_loongarch.hpp b/src/hotspot/os_cpu/linux_loongarch/atomic_linux_loongarch.hpp |index 4fab36f92b4..beb717b67ff 100644 |--- a/src/hotspot/os_cpu/linux_loongarch/atomic_linux_loongarch.hpp |+++ b/src/hotspot/os_cpu/linux_loongarch/atomic_linux_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 3 out of 3 hunks ignored can't find file to patch at input line 10584 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/os_cpu/linux_loongarch/orderAccess_linux_loongarch.hpp b/src/hotspot/os_cpu/linux_loongarch/orderAccess_linux_loongarch.hpp |index 23a9d27b0f4..6236e741d05 100644 |--- a/src/hotspot/os_cpu/linux_loongarch/orderAccess_linux_loongarch.hpp |+++ b/src/hotspot/os_cpu/linux_loongarch/orderAccess_linux_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 10623 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/os_cpu/linux_mips/orderAccess_linux_mips.hpp b/src/hotspot/os_cpu/linux_mips/orderAccess_linux_mips.hpp |index 460d118c869..a92bf43bdbb 100644 |--- a/src/hotspot/os_cpu/linux_mips/orderAccess_linux_mips.hpp |+++ b/src/hotspot/os_cpu/linux_mips/orderAccess_linux_mips.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 10683 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- | |commit 2eceaca5eb843f2c040de99e82cd17a24b7167c1 |Merge: f3b0a23f659 22cdf79dce8 |Author: aoqi |Date: Wed May 17 14:31:52 2023 +0800 | | Merge | |diff --cc test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java |index ecac04f43b6,bbbec26406d..5989d3fd6c2 |--- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java |+++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java |@@@ -21,15 -21,9 +21,15 @@@ | * questions. | */ | | +/* | + * This file has been modified by Loongson Technology in 2022, These | + * modifications are Copyright (c) 2022, Loongson Technology, and are made | + * available on the same license terms set forth above. | + */ | + | package compiler.lib.ir_framework; | |- import compiler.lib.ir_framework.driver.IRMatcher; |+ import compiler.lib.ir_framework.driver.irmatching.IRMatcher; | import compiler.lib.ir_framework.shared.*; | import jdk.test.lib.Platform; | import sun.hotspot.WhiteBox; | |commit f3b0a23f659eef01237010d69ea71d0aee9bf1a1 |Author: loongson-jvm |Date: Wed May 17 14:29:44 2023 +0800 | | Update (2023.05.17) | | 29453: Some cpu features use hwcap detect | |diff --git a/src/hotspot/cpu/loongarch/vm_version_loongarch.cpp b/src/hotspot/cpu/loongarch/vm_version_loongarch.cpp |index 4cc21e7dd08..c9a19b379b7 100644 |--- a/src/hotspot/cpu/loongarch/vm_version_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/vm_version_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 10727 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/vm_version_loongarch.hpp b/src/hotspot/cpu/loongarch/vm_version_loongarch.hpp |index 16c12a30ee4..cae9f863c30 100644 |--- a/src/hotspot/cpu/loongarch/vm_version_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/vm_version_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 3 out of 3 hunks ignored patching file src/hotspot/os_cpu/linux_loongarch/vm_version_linux_loongarch.cpp patching file make/conf/github-actions.conf Hunk #1 FAILED at 26. 1 out of 1 hunk FAILED -- saving rejects to file make/conf/github-actions.conf.rej can't find file to patch at input line 10923 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/gc/g1/g1BarrierSetAssembler_loongarch.cpp b/src/hotspot/cpu/loongarch/gc/g1/g1BarrierSetAssembler_loongarch.cpp |index 0afc25e6e95..e129264506b 100644 |--- a/src/hotspot/cpu/loongarch/gc/g1/g1BarrierSetAssembler_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/gc/g1/g1BarrierSetAssembler_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 10952 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/gc/shenandoah/shenandoahBarrierSetAssembler_loongarch.cpp b/src/hotspot/cpu/loongarch/gc/shenandoah/shenandoahBarrierSetAssembler_loongarch.cpp |index 37124c99615..7cf552e283a 100644 |--- a/src/hotspot/cpu/loongarch/gc/shenandoah/shenandoahBarrierSetAssembler_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/gc/shenandoah/shenandoahBarrierSetAssembler_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 8 out of 8 hunks ignored can't find file to patch at input line 11035 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.cpp b/src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.cpp |index f345008bb92..3ef43daa725 100644 |--- a/src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 4 out of 4 hunks ignored can't find file to patch at input line 11075 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp |index be66c6c5e92..882c43bf592 100644 |--- a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 6 out of 6 hunks ignored can't find file to patch at input line 11219 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp |index 8e36a23afc1..07c33b80151 100644 |--- a/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp |+++ b/src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 11249 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp b/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp |index 0ca8968136b..0fe2f8f0d36 100644 |--- a/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 11271 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp b/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp |index 667f6aa92fc..fbdc96f10f5 100644 |--- a/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp |+++ b/src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored can't find file to patch at input line 11293 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/cpu/loongarch/templateInterpreterGenerator_loongarch.cpp b/src/hotspot/cpu/loongarch/templateInterpreterGenerator_loongarch.cpp |index 18e19e87b2e..88b938103bc 100644 |--- a/src/hotspot/cpu/loongarch/templateInterpreterGenerator_loongarch.cpp |+++ b/src/hotspot/cpu/loongarch/templateInterpreterGenerator_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored patching file src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp patching file src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.hpp patching file src/hotspot/cpu/ppc/gc/z/zGlobals_ppc.hpp can't find file to patch at input line 11354 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/os_cpu/linux_loongarch/os_linux_loongarch.cpp b/src/hotspot/os_cpu/linux_loongarch/os_linux_loongarch.cpp |index 84519a31f56..a2e4fea109c 100644 |--- a/src/hotspot/os_cpu/linux_loongarch/os_linux_loongarch.cpp |+++ b/src/hotspot/os_cpu/linux_loongarch/os_linux_loongarch.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored can't find file to patch at input line 11367 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff --git a/src/hotspot/os_cpu/linux_mips/os_linux_mips.cpp b/src/hotspot/os_cpu/linux_mips/os_linux_mips.cpp |index df17c3f8853..8344945ff79 100644 |--- a/src/hotspot/os_cpu/linux_mips/os_linux_mips.cpp |+++ b/src/hotspot/os_cpu/linux_mips/os_linux_mips.cpp -------------------------- File to patch: Skip this patch? [y] Skipping patch. 2 out of 2 hunks ignored patching file src/hotspot/share/asm/codeBuffer.cpp Hunk #2 FAILED at 336. 1 out of 2 hunks FAILED -- saving rejects to file src/hotspot/share/asm/codeBuffer.cpp.rej patching file make/autoconf/jvm-features.m4 Hunk #3 succeeded at 318 (offset 3 lines). Hunk #4 FAILED at 333. Hunk #5 succeeded at 395 (offset 5 lines). Hunk #6 succeeded at 436 (offset 5 lines). 1 out of 6 hunks FAILED -- saving rejects to file make/autoconf/jvm-features.m4.rej patching file make/autoconf/platform.m4 Hunk #3 FAILED at 582. 1 out of 3 hunks FAILED -- saving rejects to file make/autoconf/platform.m4.rej patching file src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Hunk #1 succeeded at 1109 (offset -12 lines). Hunk #2 succeeded at 1650 (offset -12 lines). patching file src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp Hunk #1 succeeded at 263 (offset -15 lines). patching file src/hotspot/cpu/aarch64/c1_LIR_aarch64.cpp patching file src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp patching file src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.hpp patching file src/hotspot/cpu/aarch64/gc/z/zGlobals_aarch64.hpp patching file src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp Hunk #1 succeeded at 895 (offset -4 lines). Hunk #2 succeeded at 1497 (offset -1 lines). patching file src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp patching file src/hotspot/cpu/arm/c1_LIR_arm.cpp patching file src/hotspot/cpu/loongarch/abstractInterpreter_loongarch.cpp patching file src/hotspot/cpu/loongarch/assembler_loongarch.cpp patching file src/hotspot/cpu/loongarch/assembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/assembler_loongarch.inline.hpp patching file src/hotspot/cpu/loongarch/bytes_loongarch.hpp patching file src/hotspot/cpu/loongarch/c1_CodeStubs_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/c1_Defs_loongarch.hpp patching file src/hotspot/cpu/loongarch/c1_FpuStackSim_loongarch.hpp patching file src/hotspot/cpu/loongarch/c1_FpuStackSim_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/c1_FrameMap_loongarch.hpp patching file src/hotspot/cpu/loongarch/c1_FrameMap_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/c1_LIRGenerator_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/c1_LIR_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/c1_LinearScan_loongarch.hpp patching file src/hotspot/cpu/loongarch/c1_LinearScan_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/c1_MacroAssembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/c1_MacroAssembler_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/c1_Runtime1_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/c1_globals_loongarch.hpp patching file src/hotspot/cpu/loongarch/c2_MacroAssembler_loongarch.cpp patching file src/hotspot/cpu/loongarch/c2_MacroAssembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/c2_globals_loongarch.hpp patching file src/hotspot/cpu/loongarch/c2_init_loongarch.cpp patching file src/hotspot/cpu/loongarch/c2_safepointPollStubTable_loongarch.cpp patching file src/hotspot/cpu/loongarch/codeBuffer_loongarch.hpp patching file src/hotspot/cpu/loongarch/compiledIC_loongarch.cpp patching file src/hotspot/cpu/loongarch/copy_loongarch.hpp patching file src/hotspot/cpu/loongarch/disassembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/foreign_globals_loongarch.cpp patching file src/hotspot/cpu/loongarch/foreign_globals_loongarch.hpp patching file src/hotspot/cpu/loongarch/frame_loongarch.cpp patching file src/hotspot/cpu/loongarch/frame_loongarch.hpp patching file src/hotspot/cpu/loongarch/frame_loongarch.inline.hpp patching file src/hotspot/cpu/loongarch/gc/g1/g1BarrierSetAssembler_loongarch.cpp patching file src/hotspot/cpu/loongarch/gc/g1/g1BarrierSetAssembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/gc/g1/g1Globals_loongarch.hpp patching file src/hotspot/cpu/loongarch/gc/shared/barrierSetAssembler_loongarch.cpp patching file src/hotspot/cpu/loongarch/gc/shared/barrierSetAssembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/gc/shared/barrierSetNMethod_loongarch.cpp patching file src/hotspot/cpu/loongarch/gc/shared/cardTableBarrierSetAssembler_loongarch.cpp patching file src/hotspot/cpu/loongarch/gc/shared/cardTableBarrierSetAssembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/gc/shared/modRefBarrierSetAssembler_loongarch.cpp patching file src/hotspot/cpu/loongarch/gc/shared/modRefBarrierSetAssembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/gc/shenandoah/c1/shenandoahBarrierSetC1_loongarch.cpp patching file src/hotspot/cpu/loongarch/gc/shenandoah/shenandoahBarrierSetAssembler_loongarch.cpp patching file src/hotspot/cpu/loongarch/gc/shenandoah/shenandoahBarrierSetAssembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/gc/shenandoah/shenandoah_loongarch_64.ad patching file src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.cpp patching file src/hotspot/cpu/loongarch/gc/z/zBarrierSetAssembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/gc/z/zGlobals_loongarch.cpp patching file src/hotspot/cpu/loongarch/gc/z/zGlobals_loongarch.hpp patching file src/hotspot/cpu/loongarch/gc/z/z_loongarch_64.ad patching file src/hotspot/cpu/loongarch/globalDefinitions_loongarch.hpp patching file src/hotspot/cpu/loongarch/globals_loongarch.hpp patching file src/hotspot/cpu/loongarch/icBuffer_loongarch.cpp patching file src/hotspot/cpu/loongarch/icache_loongarch.cpp patching file src/hotspot/cpu/loongarch/icache_loongarch.hpp patching file src/hotspot/cpu/loongarch/interp_masm_loongarch.hpp patching file src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/interpreterRT_loongarch.hpp patching file src/hotspot/cpu/loongarch/interpreterRT_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/javaFrameAnchor_loongarch.hpp patching file src/hotspot/cpu/loongarch/jniFastGetField_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/jniTypes_loongarch.hpp patching file src/hotspot/cpu/loongarch/jvmciCodeInstaller_loongarch.cpp patching file src/hotspot/cpu/loongarch/loongarch.ad patching file src/hotspot/cpu/loongarch/loongarch_64.ad patching file src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp patching file src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp patching file src/hotspot/cpu/loongarch/macroAssembler_loongarch.inline.hpp patching file src/hotspot/cpu/loongarch/macroAssembler_loongarch_trig.cpp patching file src/hotspot/cpu/loongarch/matcher_loongarch.hpp patching file src/hotspot/cpu/loongarch/methodHandles_loongarch.cpp patching file src/hotspot/cpu/loongarch/methodHandles_loongarch.hpp patching file src/hotspot/cpu/loongarch/nativeInst_loongarch.cpp patching file src/hotspot/cpu/loongarch/nativeInst_loongarch.hpp patching file src/hotspot/cpu/loongarch/registerMap_loongarch.hpp patching file src/hotspot/cpu/loongarch/register_definitions_loongarch.cpp patching file src/hotspot/cpu/loongarch/register_loongarch.cpp patching file src/hotspot/cpu/loongarch/register_loongarch.hpp patching file src/hotspot/cpu/loongarch/relocInfo_loongarch.cpp patching file src/hotspot/cpu/loongarch/relocInfo_loongarch.hpp patching file src/hotspot/cpu/loongarch/runtime_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/sharedRuntime_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/stubRoutines_loongarch.hpp patching file src/hotspot/cpu/loongarch/stubRoutines_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/templateInterpreterGenerator_loongarch.cpp patching file src/hotspot/cpu/loongarch/templateTable_loongarch.hpp patching file src/hotspot/cpu/loongarch/templateTable_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/universalNativeInvoker_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/universalUpcallHandler_loongarch_64.cpp patching file src/hotspot/cpu/loongarch/vmStructs_loongarch.hpp patching file src/hotspot/cpu/loongarch/vm_version_ext_loongarch.cpp patching file src/hotspot/cpu/loongarch/vm_version_ext_loongarch.hpp patching file src/hotspot/cpu/loongarch/vm_version_loongarch.cpp patching file src/hotspot/cpu/loongarch/vm_version_loongarch.hpp patching file src/hotspot/cpu/loongarch/vmreg_loongarch.cpp patching file src/hotspot/cpu/loongarch/vmreg_loongarch.hpp patching file src/hotspot/cpu/loongarch/vmreg_loongarch.inline.hpp patching file src/hotspot/cpu/loongarch/vtableStubs_loongarch_64.cpp patching file src/hotspot/cpu/mips/abstractInterpreter_mips.cpp patching file src/hotspot/cpu/mips/assembler_mips.cpp patching file src/hotspot/cpu/mips/assembler_mips.hpp patching file src/hotspot/cpu/mips/assembler_mips.inline.hpp patching file src/hotspot/cpu/mips/bytes_mips.hpp patching file src/hotspot/cpu/mips/c2_MacroAssembler_mips.cpp patching file src/hotspot/cpu/mips/c2_MacroAssembler_mips.hpp patching file src/hotspot/cpu/mips/c2_globals_mips.hpp patching file src/hotspot/cpu/mips/c2_init_mips.cpp patching file src/hotspot/cpu/mips/codeBuffer_mips.hpp patching file src/hotspot/cpu/mips/compiledIC_mips.cpp patching file src/hotspot/cpu/mips/copy_mips.hpp patching file src/hotspot/cpu/mips/depChecker_mips.cpp patching file src/hotspot/cpu/mips/depChecker_mips.hpp patching file src/hotspot/cpu/mips/disassembler_mips.hpp patching file src/hotspot/cpu/mips/foreign_globals_mips.cpp patching file src/hotspot/cpu/mips/foreign_globals_mips.hpp patching file src/hotspot/cpu/mips/frame_mips.cpp patching file src/hotspot/cpu/mips/frame_mips.hpp patching file src/hotspot/cpu/mips/frame_mips.inline.hpp patching file src/hotspot/cpu/mips/gc/g1/g1BarrierSetAssembler_mips.cpp patching file src/hotspot/cpu/mips/gc/g1/g1BarrierSetAssembler_mips.hpp patching file src/hotspot/cpu/mips/gc/g1/g1Globals_mips.hpp patching file src/hotspot/cpu/mips/gc/shared/barrierSetAssembler_mips.cpp patching file src/hotspot/cpu/mips/gc/shared/barrierSetAssembler_mips.hpp patching file src/hotspot/cpu/mips/gc/shared/barrierSetNMethod_mips.cpp patching file src/hotspot/cpu/mips/gc/shared/cardTableBarrierSetAssembler_mips.cpp patching file src/hotspot/cpu/mips/gc/shared/cardTableBarrierSetAssembler_mips.hpp patching file src/hotspot/cpu/mips/gc/shared/modRefBarrierSetAssembler_mips.cpp patching file src/hotspot/cpu/mips/gc/shared/modRefBarrierSetAssembler_mips.hpp patching file src/hotspot/cpu/mips/globalDefinitions_mips.hpp patching file src/hotspot/cpu/mips/globals_mips.hpp patching file src/hotspot/cpu/mips/icBuffer_mips.cpp patching file src/hotspot/cpu/mips/icache_mips.cpp patching file src/hotspot/cpu/mips/icache_mips.hpp patching file src/hotspot/cpu/mips/interp_masm_mips.hpp patching file src/hotspot/cpu/mips/interp_masm_mips_64.cpp patching file src/hotspot/cpu/mips/interpreterRT_mips.hpp patching file src/hotspot/cpu/mips/interpreterRT_mips_64.cpp patching file src/hotspot/cpu/mips/javaFrameAnchor_mips.hpp patching file src/hotspot/cpu/mips/jniFastGetField_mips_64.cpp patching file src/hotspot/cpu/mips/jniTypes_mips.hpp patching file src/hotspot/cpu/mips/macroAssembler_mips.cpp patching file src/hotspot/cpu/mips/macroAssembler_mips.hpp patching file src/hotspot/cpu/mips/macroAssembler_mips.inline.hpp patching file src/hotspot/cpu/mips/matcher_mips.hpp patching file src/hotspot/cpu/mips/methodHandles_mips.cpp patching file src/hotspot/cpu/mips/methodHandles_mips.hpp patching file src/hotspot/cpu/mips/mips.ad patching file src/hotspot/cpu/mips/mips_64.ad patching file src/hotspot/cpu/mips/nativeInst_mips.cpp patching file src/hotspot/cpu/mips/nativeInst_mips.hpp patching file src/hotspot/cpu/mips/registerMap_mips.hpp patching file src/hotspot/cpu/mips/register_definitions_mips.cpp patching file src/hotspot/cpu/mips/register_mips.cpp patching file src/hotspot/cpu/mips/register_mips.hpp patching file src/hotspot/cpu/mips/relocInfo_mips.cpp patching file src/hotspot/cpu/mips/relocInfo_mips.hpp patching file src/hotspot/cpu/mips/runtime_mips_64.cpp patching file src/hotspot/cpu/mips/sharedRuntime_mips_64.cpp patching file src/hotspot/cpu/mips/stubGenerator_mips_64.cpp patching file src/hotspot/cpu/mips/stubRoutines_mips.hpp patching file src/hotspot/cpu/mips/stubRoutines_mips_64.cpp patching file src/hotspot/cpu/mips/templateInterpreterGenerator_mips.cpp patching file src/hotspot/cpu/mips/templateTable_mips.hpp patching file src/hotspot/cpu/mips/templateTable_mips_64.cpp patching file src/hotspot/cpu/mips/universalNativeInvoker_mips_64.cpp patching file src/hotspot/cpu/mips/universalUpcallHandler_mips_64.cpp patching file src/hotspot/cpu/mips/vmStructs_mips.hpp patching file src/hotspot/cpu/mips/vm_version_ext_mips.cpp patching file src/hotspot/cpu/mips/vm_version_ext_mips.hpp patching file src/hotspot/cpu/mips/vm_version_mips.cpp patching file src/hotspot/cpu/mips/vm_version_mips.hpp patching file src/hotspot/cpu/mips/vmreg_mips.cpp patching file src/hotspot/cpu/mips/vmreg_mips.hpp patching file src/hotspot/cpu/mips/vmreg_mips.inline.hpp patching file src/hotspot/cpu/mips/vtableStubs_mips_64.cpp patching file src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Hunk #1 succeeded at 522 (offset 16 lines). Hunk #2 succeeded at 1621 (offset 9 lines). patching file src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp Hunk #1 succeeded at 277 (offset 2 lines). patching file src/hotspot/cpu/ppc/c1_LIR_ppc.cpp patching file src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Hunk #1 succeeded at 409 (offset 14 lines). Hunk #2 succeeded at 1513 (offset 9 lines). patching file src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp Hunk #1 succeeded at 216 (offset 2 lines). patching file src/hotspot/cpu/s390/c1_LIR_s390.cpp patching file src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Hunk #1 succeeded at 1448 (offset -11 lines). Hunk #2 succeeded at 2070 (offset -11 lines). patching file src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp patching file src/hotspot/cpu/x86/c1_LIR_x86.cpp patching file src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp patching file src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.hpp patching file src/hotspot/cpu/x86/gc/z/zGlobals_x86.hpp patching file src/hotspot/os/linux/os_linux.cpp Hunk #2 succeeded at 2463 (offset 41 lines). Hunk #3 succeeded at 2553 (offset 41 lines). patching file src/hotspot/os_cpu/linux_loongarch/assembler_linux_loongarch.cpp patching file src/hotspot/os_cpu/linux_loongarch/atomic_linux_loongarch.hpp patching file src/hotspot/os_cpu/linux_loongarch/bytes_linux_loongarch.inline.hpp patching file src/hotspot/os_cpu/linux_loongarch/copy_linux_loongarch.inline.hpp patching file src/hotspot/os_cpu/linux_loongarch/gc/z/zSyscall_linux_loongarch.hpp patching file src/hotspot/os_cpu/linux_loongarch/globals_linux_loongarch.hpp patching file src/hotspot/os_cpu/linux_loongarch/linux_loongarch.s patching file src/hotspot/os_cpu/linux_loongarch/orderAccess_linux_loongarch.hpp patching file src/hotspot/os_cpu/linux_loongarch/os_linux_loongarch.cpp patching file src/hotspot/os_cpu/linux_loongarch/os_linux_loongarch.hpp patching file src/hotspot/os_cpu/linux_loongarch/prefetch_linux_loongarch.inline.hpp patching file src/hotspot/os_cpu/linux_loongarch/thread_linux_loongarch.cpp patching file src/hotspot/os_cpu/linux_loongarch/thread_linux_loongarch.hpp patching file src/hotspot/os_cpu/linux_loongarch/vmStructs_linux_loongarch.hpp patching file src/hotspot/os_cpu/linux_mips/assembler_linux_mips.cpp patching file src/hotspot/os_cpu/linux_mips/atomic_linux_mips.hpp patching file src/hotspot/os_cpu/linux_mips/bytes_linux_mips.inline.hpp patching file src/hotspot/os_cpu/linux_mips/copy_linux_mips.inline.hpp patching file src/hotspot/os_cpu/linux_mips/globals_linux_mips.hpp patching file src/hotspot/os_cpu/linux_mips/linux_mips.s patching file src/hotspot/os_cpu/linux_mips/orderAccess_linux_mips.hpp patching file src/hotspot/os_cpu/linux_mips/os_linux_mips.cpp patching file src/hotspot/os_cpu/linux_mips/os_linux_mips.hpp patching file src/hotspot/os_cpu/linux_mips/prefetch_linux_mips.inline.hpp patching file src/hotspot/os_cpu/linux_mips/thread_linux_mips.cpp patching file src/hotspot/os_cpu/linux_mips/thread_linux_mips.hpp patching file src/hotspot/os_cpu/linux_mips/vmStructs_linux_mips.hpp patching file src/hotspot/os_cpu/linux_mips/vm_version_linux_mips.cpp patching file src/hotspot/share/asm/codeBuffer.cpp Hunk #1 succeeded at 336 (offset 6 lines). patching file src/hotspot/share/c1/c1_Compiler.cpp Hunk #2 succeeded at 218 (offset 1 line). patching file src/hotspot/share/c1/c1_LIR.cpp Hunk #1 FAILED at 236. Hunk #2 succeeded at 306 (offset 15 lines). Hunk #3 succeeded at 562 (offset 15 lines). Hunk #4 succeeded at 668 (offset 24 lines). Hunk #5 succeeded at 803 (offset 40 lines). Hunk #6 succeeded at 1164 (offset 53 lines). Hunk #7 FAILED at 1138. Hunk #8 succeeded at 1613 (offset 99 lines). Hunk #9 succeeded at 1861 (offset 99 lines). Hunk #10 succeeded at 1886 (offset 99 lines). Hunk #11 succeeded at 2042 (offset 103 lines). Hunk #12 succeeded at 2082 (offset 103 lines). Hunk #13 FAILED at 2079. 3 out of 13 hunks FAILED -- saving rejects to file src/hotspot/share/c1/c1_LIR.cpp.rej patching file src/hotspot/share/c1/c1_LIR.hpp Hunk #1 FAILED at 866. Hunk #2 FAILED at 928. Hunk #3 FAILED at 956. Hunk #4 succeeded at 1144 (offset 23 lines). Hunk #5 FAILED at 1129. Hunk #6 succeeded at 1448 (offset -14 lines). Hunk #7 FAILED at 1628. Hunk #8 FAILED at 1660. Hunk #9 FAILED at 1676. Hunk #10 FAILED at 1688. Hunk #11 succeeded at 1755 (offset 50 lines). Hunk #12 FAILED at 1806. Hunk #13 succeeded at 2287 (offset 140 lines). Hunk #14 succeeded at 2313 (offset 140 lines). Hunk #15 FAILED at 2189. 10 out of 15 hunks FAILED -- saving rejects to file src/hotspot/share/c1/c1_LIR.hpp.rej patching file src/hotspot/share/c1/c1_LIRAssembler.cpp Hunk #1 FAILED at 757. 1 out of 1 hunk FAILED -- saving rejects to file src/hotspot/share/c1/c1_LIRAssembler.cpp.rej patching file src/hotspot/share/c1/c1_LIRAssembler.hpp Hunk #1 FAILED at 186. Hunk #2 FAILED at 219. 2 out of 2 hunks FAILED -- saving rejects to file src/hotspot/share/c1/c1_LIRAssembler.hpp.rej patching file src/hotspot/share/c1/c1_LIRGenerator.cpp Hunk #1 succeeded at 476 (offset 1 line). Hunk #2 succeeded at 488 (offset 1 line). Hunk #3 succeeded at 918 (offset 1 line). Hunk #4 succeeded at 939 (offset 1 line). Hunk #5 succeeded at 1303 (offset 5 lines). Hunk #6 succeeded at 1336 (offset 5 lines). Hunk #7 succeeded at 1369 (offset 5 lines). Hunk #8 succeeded at 1422 (offset 5 lines). Hunk #9 succeeded at 1721 (offset 5 lines). Hunk #10 succeeded at 1900 (offset 5 lines). Hunk #11 succeeded at 1982 (offset 5 lines). Hunk #12 succeeded at 2358 (offset 5 lines). Hunk #13 succeeded at 2465 (offset 5 lines). Hunk #14 succeeded at 2483 (offset 5 lines). Hunk #15 succeeded at 2521 (offset 5 lines). Hunk #16 succeeded at 2540 (offset 5 lines). Hunk #17 succeeded at 3035 (offset 5 lines). Hunk #18 succeeded at 3053 (offset 5 lines). Hunk #19 succeeded at 3364 (offset 8 lines). Hunk #20 succeeded at 3420 (offset 8 lines). Hunk #21 succeeded at 3466 (offset 8 lines). Hunk #22 succeeded at 3474 (offset 8 lines). Hunk #23 succeeded at 3591 (offset 8 lines). Hunk #24 succeeded at 3745 (offset 8 lines). patching file src/hotspot/share/c1/c1_LIRGenerator.hpp Hunk #1 succeeded at 367 (offset 2 lines). Hunk #2 succeeded at 397 (offset 2 lines). patching file src/hotspot/share/c1/c1_LinearScan.cpp Hunk #2 succeeded at 1267 (offset 5 lines). Hunk #3 succeeded at 3426 (offset 17 lines). Hunk #4 succeeded at 6318 (offset 17 lines). Hunk #5 succeeded at 6465 (offset 26 lines). Hunk #6 succeeded at 6554 (offset 26 lines). Hunk #7 succeeded at 6804 (offset 26 lines). patching file src/hotspot/share/code/nmethod.cpp Hunk #2 succeeded at 2547 (offset 61 lines). Hunk #3 succeeded at 3113 (offset 64 lines). patching file src/hotspot/share/code/relocInfo.cpp patching file src/hotspot/share/code/relocInfo.hpp patching file src/hotspot/share/code/vtableStubs.cpp patching file src/hotspot/share/gc/g1/c1/g1BarrierSetC1.cpp patching file src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp patching file src/hotspot/share/gc/shared/c1/barrierSetC1.cpp patching file src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp patching file src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp patching file src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp Hunk #2 FAILED at 41. 1 out of 2 hunks FAILED -- saving rejects to file src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp.rej patching file src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp Hunk #1 succeeded at 103 (offset 4 lines). Hunk #2 succeeded at 152 (offset 4 lines). patching file src/hotspot/share/interpreter/interpreterRuntime.cpp patching file src/hotspot/share/interpreter/interpreterRuntime.hpp patching file src/hotspot/share/interpreter/templateInterpreterGenerator.hpp patching file src/hotspot/share/jfr/utilities/jfrBigEndian.hpp Hunk #2 FAILED at 108. 1 out of 2 hunks FAILED -- saving rejects to file src/hotspot/share/jfr/utilities/jfrBigEndian.hpp.rej patching file src/hotspot/share/jvmci/vmStructs_jvmci.cpp patching file src/hotspot/share/memory/metaspace.cpp Hunk #2 FAILED at 593. Hunk #3 FAILED at 633. 2 out of 3 hunks FAILED -- saving rejects to file src/hotspot/share/memory/metaspace.cpp.rej patching file src/hotspot/share/opto/output.cpp Hunk #2 FAILED at 1017. Hunk #3 succeeded at 1697 (offset 5 lines). 1 out of 3 hunks FAILED -- saving rejects to file src/hotspot/share/opto/output.cpp.rej patching file src/hotspot/share/opto/type.cpp patching file src/hotspot/share/runtime/os.cpp Hunk #2 succeeded at 1246 (offset -72 lines). patching file src/hotspot/share/runtime/sharedRuntime.cpp Hunk #2 succeeded at 3060 (offset 13 lines). patching file src/hotspot/share/runtime/sharedRuntimeTrig.cpp patching file src/hotspot/share/utilities/macros.hpp Hunk #3 succeeded at 643 (offset 26 lines). patching file src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.cpp Hunk #2 FAILED at 67. Hunk #3 FAILED at 415. Hunk #4 FAILED at 447. Hunk #5 FAILED at 523. 4 out of 5 hunks FAILED -- saving rejects to file src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.cpp.rej patching file src/jdk.hotspot.agent/linux/native/libsaproc/libproc.h Hunk #2 FAILED at 44. 1 out of 2 hunks FAILED -- saving rejects to file src/jdk.hotspot.agent/linux/native/libsaproc/libproc.h.rej patching file src/jdk.hotspot.agent/linux/native/libsaproc/ps_proc.c Hunk #2 FAILED at 144. 1 out of 2 hunks FAILED -- saving rejects to file src/jdk.hotspot.agent/linux/native/libsaproc/ps_proc.c.rej patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java Hunk #2 FAILED at 43. Hunk #3 FAILED at 575. 2 out of 3 hunks FAILED -- saving rejects to file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java.rej patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionLOONGARCH64.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionMIPS64.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java Hunk #2 FAILED at 39. Hunk #3 succeeded at 99 (offset 2 lines). 1 out of 3 hunks FAILED -- saving rejects to file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java.rej patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/loongarch64/LinuxLOONGARCH64CFrame.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/loongarch64/LinuxLOONGARCH64ThreadContext.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/mips64/LinuxMIPS64CFrame.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/mips64/LinuxMIPS64ThreadContext.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/loongarch64/LOONGARCH64ThreadContext.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/mips64/MIPS64ThreadContext.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFHeader.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/proc/loongarch64/ProcLOONGARCH64Thread.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/proc/loongarch64/ProcLOONGARCH64ThreadContext.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/proc/loongarch64/ProcLOONGARCH64ThreadFactory.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/proc/mips64/ProcMIPS64Thread.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/proc/mips64/ProcMIPS64ThreadContext.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/proc/mips64/ProcMIPS64ThreadFactory.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/remote/loongarch64/RemoteLOONGARCH64Thread.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/remote/loongarch64/RemoteLOONGARCH64ThreadContext.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/remote/loongarch64/RemoteLOONGARCH64ThreadFactory.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/remote/mips64/RemoteMIPS64Thread.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/remote/mips64/RemoteMIPS64ThreadContext.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/remote/mips64/RemoteMIPS64ThreadFactory.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java Hunk #2 FAILED at 41. Hunk #3 FAILED at 119. 2 out of 3 hunks FAILED -- saving rejects to file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java.rej patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/linux_loongarch64/LinuxLOONGARCH64JavaThreadPDAccess.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/linux_mips64/LinuxMIPS64JavaThreadPDAccess.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/loongarch64/LOONGARCH64CurrentFrameGuess.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/loongarch64/LOONGARCH64Frame.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/loongarch64/LOONGARCH64JavaCallWrapper.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/loongarch64/LOONGARCH64RegisterMap.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/mips64/MIPS64CurrentFrameGuess.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/mips64/MIPS64Frame.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/mips64/MIPS64JavaCallWrapper.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/mips64/MIPS64RegisterMap.java patching file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java Hunk #2 FAILED at 57. 1 out of 3 hunks FAILED -- saving rejects to file src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java.rej patching file src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.loongarch64/src/jdk/vm/ci/hotspot/loongarch64/LoongArch64HotSpotJVMCIBackendFactory.java patching file src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.loongarch64/src/jdk/vm/ci/hotspot/loongarch64/LoongArch64HotSpotRegisterConfig.java patching file src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.loongarch64/src/jdk/vm/ci/hotspot/loongarch64/LoongArch64HotSpotVMConfig.java patching file src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.loongarch64/src/jdk/vm/ci/hotspot/loongarch64/package-info.java patching file src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.loongarch64/src/jdk/vm/ci/loongarch64/LoongArch64.java patching file src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.loongarch64/src/jdk/vm/ci/loongarch64/LoongArch64Kind.java patching file src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.loongarch64/src/jdk/vm/ci/loongarch64/package-info.java patching file src/jdk.internal.vm.ci/share/classes/module-info.java patching file src/utils/hsdis/Makefile patching file test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java Hunk #1 FAILED at 21. 1 out of 1 hunk FAILED -- saving rejects to file test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java.rej patching file test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java Hunk #2 FAILED at 34. 1 out of 2 hunks FAILED -- saving rejects to file test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java.rej patching file test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java Hunk #2 FAILED at 38. Hunk #3 FAILED at 50. 2 out of 3 hunks FAILED -- saving rejects to file test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java.rej patching file test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInstallationTest.java patching file test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java patching file test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java patching file test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java patching file test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java patching file test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java patching file test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java patching file test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java patching file test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/loongarch64/LoongArch64TestAssembler.java patching file test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java Hunk #1 FAILED at 21. Hunk #2 FAILED at 58. 2 out of 2 hunks FAILED -- saving rejects to file test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java.rej patching file test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java Hunk #2 FAILED at 136. Hunk #3 FAILED at 174. Hunk #4 FAILED at 197. 3 out of 4 hunks FAILED -- saving rejects to file test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java.rej patching file test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java Hunk #1 FAILED at 21. 1 out of 1 hunk FAILED -- saving rejects to file test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java.rej patching file test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup/LookUp.java Hunk #1 FAILED at 21. 1 out of 1 hunk FAILED -- saving rejects to file test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup/LookUp.java.rej patching file test/hotspot/jtreg/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java Hunk #2 FAILED at 67. 1 out of 2 hunks FAILED -- saving rejects to file test/hotspot/jtreg/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java.rej patching file test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java Hunk #2 FAILED at 246. 1 out of 2 hunks FAILED -- saving rejects to file test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java.rej patching file test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java Hunk #2 succeeded at 221 (offset 8 lines). patching file test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java Reversed (or previously applied) patch detected! Assume -R? [n] Apply anyway? [n] Skipping patch. 3 out of 3 hunks ignored -- saving rejects to file test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java.rej patching file test/jdk/java/security/cert/pkix/policyChanges/TestPolicy.java Reversed (or previously applied) patch detected! Assume -R? [n] Apply anyway? [n] Skipping patch. 3 out of 3 hunks ignored -- saving rejects to file test/jdk/java/security/cert/pkix/policyChanges/TestPolicy.java.rej patching file test/jdk/jdk/jfr/event/os/TestCPUInformation.java Hunk #2 FAILED at 58. 1 out of 2 hunks FAILED -- saving rejects to file test/jdk/jdk/jfr/event/os/TestCPUInformation.java.rej patching file test/jdk/sun/security/pkcs11/PKCS11Test.java Hunk #2 FAILED at 699. 1 out of 2 hunks FAILED -- saving rejects to file test/jdk/sun/security/pkcs11/PKCS11Test.java.rej patching file test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFxMode.java Reversed (or previously applied) patch detected! Assume -R? [n] Apply anyway? [n] Skipping patch. 2 out of 2 hunks ignored -- saving rejects to file test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFxMode.java.rej patching file test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java Hunk #2 FAILED at 51. 1 out of 2 hunks FAILED -- saving rejects to file test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java.rej patching file test/lib/jdk/test/lib/Platform.java Hunk #1 FAILED at 21. Hunk #2 succeeded at 234 (offset 20 lines). 1 out of 2 hunks FAILED -- saving rejects to file test/lib/jdk/test/lib/Platform.java.rej RPM build errors: error: Bad exit status from /var/tmp/rpm-tmp.wKJi8j (%prep) Bad exit status from /var/tmp/rpm-tmp.wKJi8j (%prep) Child return code was: 1 EXCEPTION: [Error('Command failed: \n # bash --login -c /usr/bin/rpmbuild -bb --noclean --target loongarch64 --nodeps /builddir/build/SPECS/java-17-openjdk-portable.spec\n', 1)] Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/mockbuild/trace_decorator.py", line 93, in trace result = func(*args, **kw) File "/usr/lib/python3.6/site-packages/mockbuild/util.py", line 598, in do_with_status raise exception.Error("Command failed: \n # %s\n%s" % (command, output), child.returncode) mockbuild.exception.Error: Command failed: # bash --login -c /usr/bin/rpmbuild -bb --noclean --target loongarch64 --nodeps /builddir/build/SPECS/java-17-openjdk-portable.spec