diff --git a/src/hotspot/cpu/aarch64/bytes_aarch64.hpp b/src/hotspot/cpu/aarch64/bytes_aarch64.hpp index 672f03b93a9..6d4a18d00b5 100644 --- a/src/hotspot/cpu/aarch64/bytes_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/bytes_aarch64.hpp @@ -27,6 +27,7 @@ #define CPU_AARCH64_BYTES_AARCH64_HPP #include "memory/allStatic.hpp" +#include "utilities/byteswap.hpp" class Bytes: AllStatic { public: @@ -44,23 +45,13 @@ class Bytes: AllStatic { // Efficient reading and writing of unaligned unsigned data in Java // byte ordering (i.e. big-endian ordering). Byte-order reversal is // needed since x86 CPUs use little-endian format. - static inline u2 get_Java_u2(address p) { return swap_u2(get_native_u2(p)); } - static inline u4 get_Java_u4(address p) { return swap_u4(get_native_u4(p)); } - static inline u8 get_Java_u8(address p) { return swap_u8(get_native_u8(p)); } + static inline u2 get_Java_u2(address p) { return byteswap(get_native_u2(p)); } + static inline u4 get_Java_u4(address p) { return byteswap(get_native_u4(p)); } + static inline u8 get_Java_u8(address p) { return byteswap(get_native_u8(p)); } - static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, swap_u2(x)); } - static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, swap_u4(x)); } - static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, swap_u8(x)); } - - - // Efficient swapping of byte ordering - static inline u2 swap_u2(u2 x); // compiler-dependent implementation - static inline u4 swap_u4(u4 x); // compiler-dependent implementation - static inline u8 swap_u8(u8 x); + static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, byteswap(x)); } + static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, byteswap(x)); } + static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, byteswap(x)); } }; - -// The following header contains the implementations of swap_u2, swap_u4, and swap_u8[_base] -#include OS_CPU_HEADER(bytes) - #endif // CPU_AARCH64_BYTES_AARCH64_HPP diff --git a/src/hotspot/cpu/arm/bytes_arm.hpp b/src/hotspot/cpu/arm/bytes_arm.hpp index 34af43edcac..6ebf5a61e4f 100644 --- a/src/hotspot/cpu/arm/bytes_arm.hpp +++ b/src/hotspot/cpu/arm/bytes_arm.hpp @@ -175,15 +175,6 @@ class Bytes: AllStatic { static inline void put_native_u8(address p, u8 x) { put_Java_u8(p, x); } #endif // VM_LITTLE_ENDIAN - - // Efficient swapping of byte ordering - static inline u2 swap_u2(u2 x); - static inline u4 swap_u4(u4 x); - static inline u8 swap_u8(u8 x); }; - -// The following header contains the implementations of swap_u2, swap_u4, and swap_u8 -#include OS_CPU_HEADER(bytes) - #endif // CPU_ARM_BYTES_ARM_HPP diff --git a/src/hotspot/cpu/ppc/bytes_ppc.hpp b/src/hotspot/cpu/ppc/bytes_ppc.hpp index a4d061e9b73..d6076a9c5b2 100644 --- a/src/hotspot/cpu/ppc/bytes_ppc.hpp +++ b/src/hotspot/cpu/ppc/bytes_ppc.hpp @@ -27,6 +27,7 @@ #define CPU_PPC_BYTES_PPC_HPP #include "memory/allStatic.hpp" +#include "utilities/byteswap.hpp" class Bytes: AllStatic { public: @@ -37,11 +38,6 @@ class Bytes: AllStatic { #if defined(VM_LITTLE_ENDIAN) - // Forward declarations of the compiler-dependent implementation - static inline u2 swap_u2(u2 x); - static inline u4 swap_u4(u4 x); - static inline u8 swap_u8(u8 x); - static inline u2 get_native_u2(address p) { return (intptr_t(p) & 1) == 0 ? *(u2*)p @@ -141,21 +137,16 @@ class Bytes: AllStatic { // Efficient reading and writing of unaligned unsigned data in Java byte ordering (i.e. big-endian ordering) // (no byte-order reversal is needed since Power CPUs are big-endian oriented). - static inline u2 get_Java_u2(address p) { return swap_u2(get_native_u2(p)); } - static inline u4 get_Java_u4(address p) { return swap_u4(get_native_u4(p)); } - static inline u8 get_Java_u8(address p) { return swap_u8(get_native_u8(p)); } + static inline u2 get_Java_u2(address p) { return byteswap(get_native_u2(p)); } + static inline u4 get_Java_u4(address p) { return byteswap(get_native_u4(p)); } + static inline u8 get_Java_u8(address p) { return byteswap(get_native_u8(p)); } - static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, swap_u2(x)); } - static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, swap_u4(x)); } - static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, swap_u8(x)); } + static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, byteswap(x)); } + static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, byteswap(x)); } + static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, byteswap(x)); } #else // !defined(VM_LITTLE_ENDIAN) - // Thus, a swap between native and Java ordering is always a no-op: - static inline u2 swap_u2(u2 x) { return x; } - static inline u4 swap_u4(u4 x) { return x; } - static inline u8 swap_u8(u8 x) { return x; } - static inline u2 get_native_u2(address p) { return (intptr_t(p) & 1) == 0 ? *(u2*)p @@ -266,6 +257,4 @@ class Bytes: AllStatic { #endif // VM_LITTLE_ENDIAN }; -#include OS_CPU_HEADER(bytes) - #endif // CPU_PPC_BYTES_PPC_HPP diff --git a/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp b/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp index c196e033838..c49a4ede6a4 100644 --- a/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp @@ -28,6 +28,7 @@ #include "runtime/os.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/vm_version.hpp" +#include "utilities/byteswap.hpp" // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. @@ -74,12 +75,6 @@ static julong compute_inverse_poly(julong long_poly) { return div; } -#ifndef VM_LITTLE_ENDIAN -static void reverse_bytes(juint &w) { - w = ((w >> 24) & 0xFF) | (((w >> 16) & 0xFF) << 8) | (((w >> 8) & 0xFF) << 16) | ((w & 0xFF) << 24); -} -#endif - // Constants to fold n words as needed by macroAssembler. address StubRoutines::ppc::generate_crc_constants(juint reverse_poly) { // Layout of constant table: @@ -112,10 +107,10 @@ address StubRoutines::ppc::generate_crc_constants(juint reverse_poly) { c = fold_byte(b, reverse_poly), d = fold_byte(c, reverse_poly); #ifndef VM_LITTLE_ENDIAN - reverse_bytes(a); - reverse_bytes(b); - reverse_bytes(c); - reverse_bytes(d); + a = byteswap(a); + b = byteswap(b); + c = byteswap(c); + d = byteswap(d); #endif ptr[i ] = a; ptr[i + 256] = b; diff --git a/src/hotspot/cpu/riscv/bytes_riscv.hpp b/src/hotspot/cpu/riscv/bytes_riscv.hpp index 34143c265bf..9495703a03f 100644 --- a/src/hotspot/cpu/riscv/bytes_riscv.hpp +++ b/src/hotspot/cpu/riscv/bytes_riscv.hpp @@ -28,17 +28,13 @@ #define CPU_RISCV_BYTES_RISCV_HPP #include "memory/allStatic.hpp" +#include "utilities/byteswap.hpp" class Bytes: AllStatic { public: // Efficient reading and writing of unaligned unsigned data in platform-specific byte ordering // RISCV needs to check for alignment. - // Forward declarations of the compiler-dependent implementation - static inline u2 swap_u2(u2 x); - static inline u4 swap_u4(u4 x); - static inline u8 swap_u8(u8 x); - static inline u2 get_native_u2(address p) { if ((intptr_t(p) & 1) == 0) { return *(u2*)p; @@ -154,16 +150,18 @@ class Bytes: AllStatic { } } - // Efficient reading and writing of unaligned unsigned data in Java byte ordering (i.e. big-endian ordering) - static inline u2 get_Java_u2(address p) { return swap_u2(get_native_u2(p)); } - static inline u4 get_Java_u4(address p) { return swap_u4(get_native_u4(p)); } - static inline u8 get_Java_u8(address p) { return swap_u8(get_native_u8(p)); } +#ifndef VM_LITTLE_ENDIAN +#error RISC-V is little endian, the preprocessor macro VM_LITTLE_ENDIAN should be defined. +#endif - static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, swap_u2(x)); } - static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, swap_u4(x)); } - static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, swap_u8(x)); } + // Efficient reading and writing of unaligned unsigned data in Java byte ordering (i.e. big-endian ordering) + static inline u2 get_Java_u2(address p) { return byteswap(get_native_u2(p)); } + static inline u4 get_Java_u4(address p) { return byteswap(get_native_u4(p)); } + static inline u8 get_Java_u8(address p) { return byteswap(get_native_u8(p)); } + + static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, byteswap(x)); } + static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, byteswap(x)); } + static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, byteswap(x)); } }; -#include OS_CPU_HEADER(bytes) - #endif // CPU_RISCV_BYTES_RISCV_HPP diff --git a/src/hotspot/cpu/s390/bytes_s390.hpp b/src/hotspot/cpu/s390/bytes_s390.hpp index 9b4d7b04221..ed6418bd451 100644 --- a/src/hotspot/cpu/s390/bytes_s390.hpp +++ b/src/hotspot/cpu/s390/bytes_s390.hpp @@ -50,9 +50,6 @@ class Bytes: AllStatic { static inline void put_native_u4(address p, u4 x) { *(u4*)p = x; } static inline void put_native_u8(address p, u8 x) { *(u8*)p = x; } - // The following header contains the implementations of swap_u2, swap_u4, and swap_u8. -#include OS_CPU_HEADER(bytes) - // Efficient reading and writing of unaligned unsigned data in Java byte ordering (i.e. big-endian ordering) static inline u2 get_Java_u2(address p) { return get_native_u2(p); } static inline u4 get_Java_u4(address p) { return get_native_u4(p); } diff --git a/src/hotspot/cpu/x86/bytes_x86.hpp b/src/hotspot/cpu/x86/bytes_x86.hpp index cb5987d2c82..326edd3fd98 100644 --- a/src/hotspot/cpu/x86/bytes_x86.hpp +++ b/src/hotspot/cpu/x86/bytes_x86.hpp @@ -27,15 +27,10 @@ #include "memory/allStatic.hpp" #include "utilities/align.hpp" +#include "utilities/byteswap.hpp" #include "utilities/macros.hpp" class Bytes: AllStatic { - private: -#ifndef AMD64 - // Helper function for swap_u8 - static inline u8 swap_u8_base(u4 x, u4 y); // compiler-dependent implementation -#endif // AMD64 - public: // Efficient reading and writing of unaligned unsigned data in platform-specific byte ordering template @@ -79,7 +74,7 @@ class Bytes: AllStatic { T x = get_native(p); if (Endian::is_Java_byte_ordering_different()) { - x = swap(x); + x = byteswap(x); } return x; @@ -88,7 +83,7 @@ class Bytes: AllStatic { template static inline void put_Java(address p, T x) { if (Endian::is_Java_byte_ordering_different()) { - x = swap(x); + x = byteswap(x); } put_native(p, x); @@ -101,27 +96,6 @@ class Bytes: AllStatic { static inline void put_Java_u2(address p, u2 x) { put_Java(p, x); } static inline void put_Java_u4(address p, u4 x) { put_Java(p, x); } static inline void put_Java_u8(address p, u8 x) { put_Java(p, x); } - - // Efficient swapping of byte ordering - template - static T swap(T x) { - switch (sizeof(T)) { - case sizeof(u1): return x; - case sizeof(u2): return swap_u2(x); - case sizeof(u4): return swap_u4(x); - case sizeof(u8): return swap_u8(x); - default: - guarantee(false, "invalid size: " SIZE_FORMAT "\n", sizeof(T)); - return 0; - } - } - - static inline u2 swap_u2(u2 x); // compiler-dependent implementation - static inline u4 swap_u4(u4 x); // compiler-dependent implementation - static inline u8 swap_u8(u8 x); }; -// The following header contains the implementations of swap_u2, swap_u4, and swap_u8[_base] -#include OS_CPU_HEADER(bytes) - #endif // CPU_X86_BYTES_X86_HPP diff --git a/src/hotspot/cpu/zero/bytes_zero.hpp b/src/hotspot/cpu/zero/bytes_zero.hpp index 93d49b8a28d..15d0fc32650 100644 --- a/src/hotspot/cpu/zero/bytes_zero.hpp +++ b/src/hotspot/cpu/zero/bytes_zero.hpp @@ -118,11 +118,6 @@ class Bytes: AllStatic { p[6] = lo >> 8; p[7] = lo; } - - // Efficient swapping of byte ordering - static inline u2 swap_u2(u2 x); - static inline u4 swap_u4(u4 x); - static inline u8 swap_u8(u8 x); #else // No byte-order reversal is needed static inline u2 get_Java_u2(address p) { @@ -144,20 +139,7 @@ class Bytes: AllStatic { static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, x); } - - // No byte-order reversal is needed - static inline u2 swap_u2(u2 x) { return x; } - static inline u4 swap_u4(u4 x) { return x; } - static inline u8 swap_u8(u8 x) { return x; } #endif // VM_LITTLE_ENDIAN }; -#ifdef VM_LITTLE_ENDIAN -// The following header contains the implementations of swap_u2, -// swap_u4, and swap_u8 - -#include OS_CPU_HEADER(bytes) - -#endif // VM_LITTLE_ENDIAN - #endif // CPU_ZERO_BYTES_ZERO_HPP diff --git a/src/hotspot/os_cpu/aix_ppc/bytes_aix_ppc.hpp b/src/hotspot/os_cpu/aix_ppc/bytes_aix_ppc.hpp deleted file mode 100644 index 036cde01337..00000000000 --- a/src/hotspot/os_cpu/aix_ppc/bytes_aix_ppc.hpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_AIX_PPC_BYTES_AIX_PPC_HPP -#define OS_CPU_AIX_PPC_BYTES_AIX_PPC_HPP - -#if defined(VM_LITTLE_ENDIAN) -// Aix is not little endian. -#endif // VM_LITTLE_ENDIAN - -#endif // OS_CPU_AIX_PPC_BYTES_AIX_PPC_HPP diff --git a/src/hotspot/os_cpu/bsd_aarch64/bytes_bsd_aarch64.hpp b/src/hotspot/os_cpu/bsd_aarch64/bytes_bsd_aarch64.hpp deleted file mode 100644 index 382d2ea8b95..00000000000 --- a/src/hotspot/os_cpu/bsd_aarch64/bytes_bsd_aarch64.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_BSD_AARCH64_BYTES_BSD_AARCH64_HPP -#define OS_CPU_BSD_AARCH64_BYTES_BSD_AARCH64_HPP - -#ifdef __APPLE__ -#include -#endif - -#if defined(__APPLE__) -# define bswap_16(x) OSSwapInt16(x) -# define bswap_32(x) OSSwapInt32(x) -# define bswap_64(x) OSSwapInt64(x) -#else -# error "Unimplemented" -#endif - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. -inline u2 Bytes::swap_u2(u2 x) { - return bswap_16(x); -} - -inline u4 Bytes::swap_u4(u4 x) { - return bswap_32(x); -} - -inline u8 Bytes::swap_u8(u8 x) { - return bswap_64(x); -} - -#endif // OS_CPU_BSD_AARCH64_BYTES_BSD_AARCH64_HPP diff --git a/src/hotspot/os_cpu/bsd_x86/bytes_bsd_x86.hpp b/src/hotspot/os_cpu/bsd_x86/bytes_bsd_x86.hpp deleted file mode 100644 index f496c125a68..00000000000 --- a/src/hotspot/os_cpu/bsd_x86/bytes_bsd_x86.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_BSD_X86_BYTES_BSD_X86_HPP -#define OS_CPU_BSD_X86_BYTES_BSD_X86_HPP - -#ifdef __APPLE__ -#include -#endif - -#if defined(AMD64) -# if defined(__APPLE__) -# define bswap_16(x) OSSwapInt16(x) -# define bswap_32(x) OSSwapInt32(x) -# define bswap_64(x) OSSwapInt64(x) -# elif defined(__OpenBSD__) -# define bswap_16(x) swap16(x) -# define bswap_32(x) swap32(x) -# define bswap_64(x) swap64(x) -# elif defined(__NetBSD__) -# define bswap_16(x) bswap16(x) -# define bswap_32(x) bswap32(x) -# define bswap_64(x) bswap64(x) -# else -# define bswap_16(x) __bswap16(x) -# define bswap_32(x) __bswap32(x) -# define bswap_64(x) __bswap64(x) -# endif -#endif - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. -inline u2 Bytes::swap_u2(u2 x) { -#ifdef AMD64 - return bswap_16(x); -#else - u2 ret; - __asm__ __volatile__ ( - "movw %0, %%ax;" - "xchg %%al, %%ah;" - "movw %%ax, %0" - :"=r" (ret) // output : register 0 => ret - :"0" (x) // input : x => register 0 - :"ax", "0" // clobbered registers - ); - return ret; -#endif // AMD64 -} - -inline u4 Bytes::swap_u4(u4 x) { -#ifdef AMD64 - return bswap_32(x); -#else - u4 ret; - __asm__ __volatile__ ( - "bswap %0" - :"=r" (ret) // output : register 0 => ret - :"0" (x) // input : x => register 0 - :"0" // clobbered register - ); - return ret; -#endif // AMD64 -} - -#ifdef AMD64 -inline u8 Bytes::swap_u8(u8 x) { - return bswap_64(x); -} -#else -// Helper function for swap_u8 -inline u8 Bytes::swap_u8_base(u4 x, u4 y) { - return (((u8)swap_u4(x))<<32) | swap_u4(y); -} - -inline u8 Bytes::swap_u8(u8 x) { - return swap_u8_base(*(u4*)&x, *(((u4*)&x)+1)); -} -#endif // !AMD64 - -#endif // OS_CPU_BSD_X86_BYTES_BSD_X86_HPP diff --git a/src/hotspot/os_cpu/bsd_zero/bytes_bsd_zero.hpp b/src/hotspot/os_cpu/bsd_zero/bytes_bsd_zero.hpp deleted file mode 100644 index 0da7ecc7892..00000000000 --- a/src/hotspot/os_cpu/bsd_zero/bytes_bsd_zero.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_BSD_ZERO_BYTES_BSD_ZERO_HPP -#define OS_CPU_BSD_ZERO_BYTES_BSD_ZERO_HPP - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. - -#ifdef __APPLE__ -# include -#else -# include -#endif - -#if defined(__APPLE__) -# define bswap_16(x) OSSwapInt16(x) -# define bswap_32(x) OSSwapInt32(x) -# define bswap_64(x) OSSwapInt64(x) -#elif defined(__OpenBSD__) -# define bswap_16(x) swap16(x) -# define bswap_32(x) swap32(x) -# define bswap_64(x) swap64(x) -#elif defined(__NetBSD__) -# define bswap_16(x) bswap16(x) -# define bswap_32(x) bswap32(x) -# define bswap_64(x) bswap64(x) -#else -# define bswap_16(x) __bswap16(x) -# define bswap_32(x) __bswap32(x) -# define bswap_64(x) __bswap64(x) -#endif - -inline u2 Bytes::swap_u2(u2 x) { - return bswap_16(x); -} - -inline u4 Bytes::swap_u4(u4 x) { - return bswap_32(x); -} - -inline u8 Bytes::swap_u8(u8 x) { - return bswap_64(x); -} - -#endif // OS_CPU_BSD_ZERO_BYTES_BSD_ZERO_HPP diff --git a/src/hotspot/os_cpu/linux_aarch64/bytes_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/bytes_linux_aarch64.hpp deleted file mode 100644 index 4dedb16c3e6..00000000000 --- a/src/hotspot/os_cpu/linux_aarch64/bytes_linux_aarch64.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_AARCH64_BYTES_LINUX_AARCH64_HPP -#define OS_CPU_LINUX_AARCH64_BYTES_LINUX_AARCH64_HPP - -#include - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. -inline u2 Bytes::swap_u2(u2 x) { - return bswap_16(x); -} - -inline u4 Bytes::swap_u4(u4 x) { - return bswap_32(x); -} - -inline u8 Bytes::swap_u8(u8 x) { - return bswap_64(x); -} - -#endif // OS_CPU_LINUX_AARCH64_BYTES_LINUX_AARCH64_HPP diff --git a/src/hotspot/os_cpu/linux_arm/bytes_linux_arm.hpp b/src/hotspot/os_cpu/linux_arm/bytes_linux_arm.hpp deleted file mode 100644 index 0acf393de60..00000000000 --- a/src/hotspot/os_cpu/linux_arm/bytes_linux_arm.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_ARM_BYTES_LINUX_ARM_HPP -#define OS_CPU_LINUX_ARM_BYTES_LINUX_ARM_HPP - -#include - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. -inline u2 Bytes::swap_u2(u2 x) { - // TODO: ARM - optimize - return bswap_16(x); -} - -inline u4 Bytes::swap_u4(u4 x) { - // TODO: ARM - optimize - return bswap_32(x); -} - -inline u8 Bytes::swap_u8(u8 x) { - // TODO: ARM - optimize - return bswap_64(x); -} - -#endif // OS_CPU_LINUX_ARM_BYTES_LINUX_ARM_HPP diff --git a/src/hotspot/os_cpu/linux_ppc/bytes_linux_ppc.hpp b/src/hotspot/os_cpu/linux_ppc/bytes_linux_ppc.hpp deleted file mode 100644 index 8ba324f55df..00000000000 --- a/src/hotspot/os_cpu/linux_ppc/bytes_linux_ppc.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright 2014 Google Inc. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_PPC_BYTES_LINUX_PPC_HPP -#define OS_CPU_LINUX_PPC_BYTES_LINUX_PPC_HPP - -#if defined(VM_LITTLE_ENDIAN) -#include - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. -inline u2 Bytes::swap_u2(u2 x) { return bswap_16(x); } -inline u4 Bytes::swap_u4(u4 x) { return bswap_32(x); } -inline u8 Bytes::swap_u8(u8 x) { return bswap_64(x); } -#endif // VM_LITTLE_ENDIAN - -#endif // OS_CPU_LINUX_PPC_BYTES_LINUX_PPC_HPP diff --git a/src/hotspot/os_cpu/linux_riscv/bytes_linux_riscv.hpp b/src/hotspot/os_cpu/linux_riscv/bytes_linux_riscv.hpp deleted file mode 100644 index 28868c76406..00000000000 --- a/src/hotspot/os_cpu/linux_riscv/bytes_linux_riscv.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_RISCV_BYTES_LINUX_RISCV_HPP -#define OS_CPU_LINUX_RISCV_BYTES_LINUX_RISCV_HPP - -#include - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. -inline u2 Bytes::swap_u2(u2 x) { - return bswap_16(x); -} - -inline u4 Bytes::swap_u4(u4 x) { - return bswap_32(x); -} - -inline u8 Bytes::swap_u8(u8 x) { - return bswap_64(x); -} - -#endif // OS_CPU_LINUX_RISCV_BYTES_LINUX_RISCV_HPP diff --git a/src/hotspot/os_cpu/linux_s390/bytes_linux_s390.hpp b/src/hotspot/os_cpu/linux_s390/bytes_linux_s390.hpp deleted file mode 100644 index 5309d7a7742..00000000000 --- a/src/hotspot/os_cpu/linux_s390/bytes_linux_s390.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016 SAP SE. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_S390_BYTES_LINUX_S390_HPP -#define OS_CPU_LINUX_S390_BYTES_LINUX_S390_HPP - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. - -#include - -inline u2 swap_u2(u2 x) { - return bswap_16(x); -} - -inline u4 swap_u4(u4 x) { - return bswap_32(x); -} - -inline u8 swap_u8(u8 x) { - return bswap_64(x); -} - -#endif // OS_CPU_LINUX_S390_BYTES_LINUX_S390_HPP diff --git a/src/hotspot/os_cpu/linux_x86/bytes_linux_x86.hpp b/src/hotspot/os_cpu/linux_x86/bytes_linux_x86.hpp deleted file mode 100644 index e448537267d..00000000000 --- a/src/hotspot/os_cpu/linux_x86/bytes_linux_x86.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_X86_BYTES_LINUX_X86_HPP -#define OS_CPU_LINUX_X86_BYTES_LINUX_X86_HPP - -#include - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. -inline u2 Bytes::swap_u2(u2 x) { -#ifdef AMD64 - return bswap_16(x); -#else - u2 ret; - __asm__ __volatile__ ( - "movw %0, %%ax;" - "xchg %%al, %%ah;" - "movw %%ax, %0" - :"=r" (ret) // output : register 0 => ret - :"0" (x) // input : x => register 0 - :"ax", "0" // clobbered registers - ); - return ret; -#endif // AMD64 -} - -inline u4 Bytes::swap_u4(u4 x) { -#ifdef AMD64 - return bswap_32(x); -#else - u4 ret; - __asm__ __volatile__ ( - "bswap %0" - :"=r" (ret) // output : register 0 => ret - :"0" (x) // input : x => register 0 - :"0" // clobbered register - ); - return ret; -#endif // AMD64 -} - -#ifdef AMD64 -inline u8 Bytes::swap_u8(u8 x) { - return bswap_64(x); -} -#else -// Helper function for swap_u8 -inline u8 Bytes::swap_u8_base(u4 x, u4 y) { - return (((u8)swap_u4(x))<<32) | swap_u4(y); -} - -inline u8 Bytes::swap_u8(u8 x) { - return swap_u8_base(*(u4*)&x, *(((u4*)&x)+1)); -} -#endif // !AMD64 - -#endif // OS_CPU_LINUX_X86_BYTES_LINUX_X86_HPP diff --git a/src/hotspot/os_cpu/linux_zero/bytes_linux_zero.hpp b/src/hotspot/os_cpu/linux_zero/bytes_linux_zero.hpp deleted file mode 100644 index 2489071028f..00000000000 --- a/src/hotspot/os_cpu/linux_zero/bytes_linux_zero.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_ZERO_BYTES_LINUX_ZERO_HPP -#define OS_CPU_LINUX_ZERO_BYTES_LINUX_ZERO_HPP - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. - -#include - -inline u2 Bytes::swap_u2(u2 x) { - return bswap_16(x); -} - -inline u4 Bytes::swap_u4(u4 x) { - return bswap_32(x); -} - -inline u8 Bytes::swap_u8(u8 x) { - return bswap_64(x); -} - -#endif // OS_CPU_LINUX_ZERO_BYTES_LINUX_ZERO_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.hpp deleted file mode 100644 index e6c62fb7ad7..00000000000 --- a/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2020, Microsoft Corporation. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_HPP -#define OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_HPP - -#include - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. -inline u2 Bytes::swap_u2(u2 x) { - return _byteswap_ushort(x); -} - -inline u4 Bytes::swap_u4(u4 x) { - return _byteswap_ulong(x); -} - -inline u8 Bytes::swap_u8(u8 x) { - return _byteswap_uint64(x); -} - -#pragma warning(default: 4035) // Enable warning 4035: no return value - -#endif // OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_HPP diff --git a/src/hotspot/os_cpu/windows_x86/bytes_windows_x86.hpp b/src/hotspot/os_cpu/windows_x86/bytes_windows_x86.hpp deleted file mode 100644 index 0c3574dabc5..00000000000 --- a/src/hotspot/os_cpu/windows_x86/bytes_windows_x86.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_WINDOWS_X86_BYTES_WINDOWS_X86_HPP -#define OS_CPU_WINDOWS_X86_BYTES_WINDOWS_X86_HPP - -#include - -// Efficient swapping of data bytes from Java byte -// ordering to native byte ordering and vice versa. -inline u2 Bytes::swap_u2(u2 x) { - return (u2) _byteswap_ushort((unsigned short) x); -} - -inline u4 Bytes::swap_u4(u4 x) { - return (u4) _byteswap_ulong((unsigned long) x); -} - -inline u8 Bytes::swap_u8(u8 x) { - return (u8) _byteswap_uint64((unsigned __int64) x); -} - -#endif // OS_CPU_WINDOWS_X86_BYTES_WINDOWS_X86_HPP diff --git a/src/hotspot/share/code/compressedStream.cpp b/src/hotspot/share/code/compressedStream.cpp index a26b78e47e5..6a4174fb6ce 100644 --- a/src/hotspot/share/code/compressedStream.cpp +++ b/src/hotspot/share/code/compressedStream.cpp @@ -25,7 +25,7 @@ #include "precompiled.hpp" #include "code/compressedStream.hpp" #include "utilities/ostream.hpp" -#include "utilities/moveBits.hpp" +#include "utilities/reverse_bits.hpp" jint CompressedReadStream::read_signed_int() { return UNSIGNED5::decode_sign(read_int()); diff --git a/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp b/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp index 15ae3046721..34db48f90cc 100644 --- a/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp +++ b/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp @@ -26,7 +26,8 @@ #define SHARE_JFR_UTILITIES_JFRBIGENDIAN_HPP #include "memory/allStatic.hpp" -#include "utilities/bytes.hpp" +#include "utilities/byteswap.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" #ifndef VM_LITTLE_ENDIAN @@ -34,9 +35,9 @@ # define bigendian_32(x) (x) # define bigendian_64(x) (x) #else -# define bigendian_16(x) Bytes::swap_u2(x) -# define bigendian_32(x) Bytes::swap_u4(x) -# define bigendian_64(x) Bytes::swap_u8(x) +# define bigendian_16(x) byteswap(x) +# define bigendian_32(x) byteswap(x) +# define bigendian_64(x) byteswap(x) #endif class JfrBigEndian : AllStatic { diff --git a/src/hotspot/share/opto/subnode.cpp b/src/hotspot/share/opto/subnode.cpp index 9b94a28fce4..285cd388aec 100644 --- a/src/hotspot/share/opto/subnode.cpp +++ b/src/hotspot/share/opto/subnode.cpp @@ -39,7 +39,7 @@ #include "opto/phaseX.hpp" #include "opto/subnode.hpp" #include "runtime/sharedRuntime.hpp" -#include "utilities/moveBits.hpp" +#include "utilities/reverse_bits.hpp" // Portions of code courtesy of Clifford Click diff --git a/src/hotspot/share/utilities/byteswap.hpp b/src/hotspot/share/utilities/byteswap.hpp new file mode 100644 index 00000000000..d5ece7e00cd --- /dev/null +++ b/src/hotspot/share/utilities/byteswap.hpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2023, Google and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_UTILITIES_BYTESWAP_HPP +#define SHARE_UTILITIES_BYTESWAP_HPP + +#include "metaprogramming/enableIf.hpp" +#include "utilities/globalDefinitions.hpp" + +#include +#include +#include + +template +struct ByteswapImpl; + +// T byteswap(T) +// +// Reverses the bytes for the value of the integer type T. Partially compatible with std::byteswap +// introduced in C++23. +template ::value)> +inline T byteswap(T x) { + using U = std::make_unsigned_t; + return static_cast(ByteswapImpl{}(static_cast(x))); +} + +// We support 8-bit integer types to be compatible with C++23's std::byteswap. +template +struct ByteswapImpl { + inline constexpr T operator()(T x) const { + return x; + } +}; + +/***************************************************************************** + * Fallback + *****************************************************************************/ + +template +struct ByteswapFallbackImpl; + +template +struct ByteswapFallbackImpl { + inline constexpr uint16_t operator()(uint16_t x) const { + return (((x & UINT16_C(0x00ff)) << 8) | ((x & UINT16_C(0xff00)) >> 8)); + } +}; + +template +struct ByteswapFallbackImpl { + inline constexpr uint32_t operator()(uint32_t x) const { + return (((x & UINT32_C(0x000000ff)) << 24) | ((x & UINT32_C(0x0000ff00)) << 8) | + ((x & UINT32_C(0x00ff0000)) >> 8) | ((x & UINT32_C(0xff000000)) >> 24)); + } +}; + +template +struct ByteswapFallbackImpl { + inline constexpr uint64_t operator()(uint64_t x) const { + return (((x & UINT64_C(0x00000000000000ff)) << 56) | ((x & UINT64_C(0x000000000000ff00)) << 40) | + ((x & UINT64_C(0x0000000000ff0000)) << 24) | ((x & UINT64_C(0x00000000ff000000)) << 8) | + ((x & UINT64_C(0x000000ff00000000)) >> 8) | ((x & UINT64_C(0x0000ff0000000000)) >> 24) | + ((x & UINT64_C(0x00ff000000000000)) >> 40) | ((x & UINT64_C(0xff00000000000000)) >> 56)); + } +}; + +/***************************************************************************** + * GCC and compatible (including Clang) + *****************************************************************************/ +#if defined(TARGET_COMPILER_gcc) || defined(TARGET_COMPILER_xlc) + +#if defined(__clang__) || defined(ASSERT) + +// Unlike GCC, Clang is willing to inline the generic implementation of __builtin_bswap when +// architecture support is unavailable in -O2. This ensures we avoid the function call to libgcc. +// Clang is able to recognize the fallback implementation as byteswapping, but not on every +// architecture unlike GCC. This suggests the optimization pass for GCC that recognizes byteswapping +// is architecture agnostic, while for Clang it is not. + +template +struct ByteswapImpl { + inline constexpr uint16_t operator()(uint16_t x) const { + return __builtin_bswap16(x); + } +}; + +template +struct ByteswapImpl { + inline constexpr uint32_t operator()(uint32_t x) const { + return __builtin_bswap32(x); + } +}; + +template +struct ByteswapImpl { + inline constexpr uint64_t operator()(uint64_t x) const { + return __builtin_bswap64(x); + } +}; + +#else + +// We do not use __builtin_bswap and friends for GCC in release builds. Unfortunately on +// architectures that do not have a byteswap instruction (i.e. RISC-V), GCC emits a function call to +// libgcc regardless of optimization options, even when the generic implementation is, for example, +// less than 20 instructions. GCC is however able to recognize the fallback as byteswapping +// regardless of architecture and appropriately replaces the code in -O2 with the appropriate +// architecture-specific byteswap instruction, if available. If it is not available, GCC emits the +// exact same implementation that underpins its __builtin_bswap in libgcc as there is really only +// one way to implement it, as we have in fallback. + +template +struct ByteswapImpl : public ByteswapFallbackImpl {}; + +#endif + +/***************************************************************************** + * Microsoft Visual Studio + *****************************************************************************/ +#elif defined(TARGET_COMPILER_visCPP) + +#include + +#pragma intrinsic(_byteswap_ushort) +#pragma intrinsic(_byteswap_ulong) +#pragma intrinsic(_byteswap_uint64) + +template +struct ByteswapImpl { + inline unsigned short operator()(unsigned short x) const { + return _byteswap_ushort(x); + } +}; + +template +struct ByteswapImpl { + inline unsigned long operator()(unsigned long x) const { + return _byteswap_ulong(x); + } +}; + +template +struct ByteswapImpl { + inline unsigned __int64 operator()(unsigned __int64 x) const { + return _byteswap_uint64(x); + } +}; + +/***************************************************************************** + * Unknown toolchain + *****************************************************************************/ +#else + +#error Unknown toolchain. + +#endif + +#endif // SHARE_UTILITIES_BYTESWAP_HPP diff --git a/src/hotspot/share/utilities/copy.cpp b/src/hotspot/share/utilities/copy.cpp index 6ac703ed49a..cc6e8189449 100644 --- a/src/hotspot/share/utilities/copy.cpp +++ b/src/hotspot/share/utilities/copy.cpp @@ -26,6 +26,7 @@ #include "utilities/copy.hpp" #include "runtime/sharedRuntime.hpp" #include "utilities/align.hpp" +#include "utilities/byteswap.hpp" #include "utilities/copy.hpp" @@ -84,33 +85,6 @@ public: } private: - /** - * Byte swap a 16-bit value - */ - static uint16_t byte_swap(uint16_t x) { - return (x << 8) | (x >> 8); - } - - /** - * Byte swap a 32-bit value - */ - static uint32_t byte_swap(uint32_t x) { - uint16_t lo = (uint16_t)x; - uint16_t hi = (uint16_t)(x >> 16); - - return ((uint32_t)byte_swap(lo) << 16) | (uint32_t)byte_swap(hi); - } - - /** - * Byte swap a 64-bit value - */ - static uint64_t byte_swap(uint64_t x) { - uint32_t lo = (uint32_t)x; - uint32_t hi = (uint32_t)(x >> 32); - - return ((uint64_t)byte_swap(lo) << 32) | (uint64_t)byte_swap(hi); - } - enum CopyDirection { RIGHT, // lower -> higher address LEFT // higher -> lower address @@ -154,7 +128,7 @@ private: } if (swap) { - tmp = byte_swap(tmp); + tmp = byteswap(tmp); } if (is_dst_aligned) { diff --git a/src/hotspot/share/utilities/moveBits.hpp b/src/hotspot/share/utilities/moveBits.hpp deleted file mode 100644 index f972d93d704..00000000000 --- a/src/hotspot/share/utilities/moveBits.hpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_UTILITIES_MOVEBITS_HPP -#define SHARE_UTILITIES_MOVEBITS_HPP - -#include "metaprogramming/enableIf.hpp" -#include "utilities/globalDefinitions.hpp" - -#include - -template -class ReverseBitsImpl { - static const size_t NB = sizeof(T) * BitsPerByte; - - static_assert((NB == 8) || (NB == 16) || (NB == 32) || (NB == 64), - "unsupported size"); - - // The unsigned integral type for calculations. - using I = std::conditional_t; - - static const I rep_5555 = static_cast(UCONST64(0x5555555555555555)); - static const I rep_3333 = static_cast(UCONST64(0x3333333333333333)); - static const I rep_0F0F = static_cast(UCONST64(0x0F0F0F0F0F0F0F0F)); - static const I rep_00FF = static_cast(UCONST64(0x00FF00FF00FF00FF)); - static const I rep_FFFF = static_cast(UCONST64(0x0000FFFF0000FFFF)); - -public: - - static constexpr T reverse_bits_in_bytes(T v) { - // Based on Hacker's Delight Section 7-1 - auto x = static_cast(v); - x = ((x & rep_5555) << 1) | ((x >> 1) & rep_5555); - x = ((x & rep_3333) << 2) | ((x >> 2) & rep_3333); - x = ((x & rep_0F0F) << 4) | ((x >> 4) & rep_0F0F); - return static_cast(x); - } - - static constexpr T reverse_bytes(T v) { - // Based on Hacker's Delight Section 7-1 - // NB: Compilers are good at recognizing byte-swap code and transforming - // it into platform-specific instructions like x86 bswap. - auto x = static_cast(v); - switch (NB) { - case 64: - // The use of NB/2 rather than 32 avoids a warning in dead code when - // I is uint32_t, because shifting a 32bit type by 32 is UB. - x = (x << (NB/2)) | (x >> (NB/2)); - case 32: // fallthrough - x = ((x & rep_FFFF) << 16) | ((x >> 16) & rep_FFFF); - case 16: // fallthrough - x = ((x & rep_00FF) << 8) | ((x >> 8) & rep_00FF); - default: // fallthrough - return static_cast(x); - } - } -}; - -// Performs byte reversal of an integral type up to 64 bits. -template ::value)> -constexpr T reverse_bytes(T x) { - return ReverseBitsImpl::reverse_bytes(x); -} - -// Performs bytewise bit reversal of each byte of an integral -// type up to 64 bits. -template ::value)> -constexpr T reverse_bits_in_bytes(T x) { - return ReverseBitsImpl::reverse_bits_in_bytes(x); -} - -// Performs full bit reversal an integral type up to 64 bits. -template ::value)> -constexpr T reverse_bits(T x) { - return reverse_bytes(reverse_bits_in_bytes(x)); -} - -#endif // SHARE_UTILITIES_MOVEBITS_HPP diff --git a/src/hotspot/share/utilities/reverse_bits.hpp b/src/hotspot/share/utilities/reverse_bits.hpp new file mode 100644 index 00000000000..fd08b6f7358 --- /dev/null +++ b/src/hotspot/share/utilities/reverse_bits.hpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, Google and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_UTILITIES_REVERSE_BITS_HPP +#define SHARE_UTILITIES_REVERSE_BITS_HPP + +#include "metaprogramming/enableIf.hpp" +#include "utilities/byteswap.hpp" +#include "utilities/globalDefinitions.hpp" + +#include +#include +#include + +template +struct ReverseBitsImpl; + +// T reverse_bits(T) +// +// Reverses the bits in the integral value of type T. +template ::value)> +inline T reverse_bits(T x) { + using U = std::make_unsigned_t; + return static_cast(ReverseBitsImpl{}(static_cast(x))); +} + +/***************************************************************************** + * Fallback + *****************************************************************************/ + +template +struct ReverseBitsFallbackImpl { + private: + // The unsigned integral type for calculations. + using U = std::conditional_t; + + static constexpr U rep_5555 = static_cast(UINT64_C(0x5555555555555555)); + static constexpr U rep_3333 = static_cast(UINT64_C(0x3333333333333333)); + static constexpr U rep_0F0F = static_cast(UINT64_C(0x0F0F0F0F0F0F0F0F)); + + public: + inline T operator()(T v) const { + // Based on Hacker's Delight Section 7-1 + U x = static_cast(v); + x = ((x & rep_5555) << 1) | ((x >> 1) & rep_5555); + x = ((x & rep_3333) << 2) | ((x >> 2) & rep_3333); + x = ((x & rep_0F0F) << 4) | ((x >> 4) & rep_0F0F); + return byteswap(static_cast(x)); + } +}; + + +/***************************************************************************** + * GCC and compatible (including Clang) + *****************************************************************************/ +#if defined(TARGET_COMPILER_gcc) || defined(TARGET_COMPILER_xlc) + +// Default implementation for GCC-like compilers is the fallback. At the time of writing GCC does +// not have intrinsics for bit reversal while Clang does. + +template +struct ReverseBitsImpl : public ReverseBitsFallbackImpl {}; + +#ifdef __has_builtin + +#if __has_builtin(__builtin_bitreverse8) + +template +struct ReverseBitsImpl { + inline uint8_t operator()(uint8_t x) const { + return __builtin_bitreverse8(x); + } +}; + +#endif // __has_builtin(__builtin_bitreverse8) + +#if __has_builtin(__builtin_bitreverse16) + +template +struct ReverseBitsImpl { + inline uint16_t operator()(uint16_t x) const { + return __builtin_bitreverse16(x); + } +}; + +#endif // __has_builtin(__builtin_bitreverse16) + +#if __has_builtin(__builtin_bitreverse32) + +template +struct ReverseBitsImpl { + inline uint32_t operator()(uint32_t x) const { + return __builtin_bitreverse32(x); + } +}; + +#endif // __has_builtin(__builtin_bitreverse32) + +#if __has_builtin(__builtin_bitreverse64) + +template +struct ReverseBitsImpl { + inline uint64_t operator()(uint64_t x) const { + return __builtin_bitreverse64(x); + } +}; + +#endif // __has_builtin(__builtin_bitreverse64) + +#endif // __has_builtin + +/***************************************************************************** + * Microsoft Visual Studio + *****************************************************************************/ +#elif defined(TARGET_COMPILER_visCPP) + +template +struct ReverseBitsImpl : public ReverseBitsFallbackImpl {}; + +/***************************************************************************** + * Unknown toolchain + *****************************************************************************/ +#else + +#error Unknown toolchain. + +#endif + +#endif // SHARE_UTILITIES_REVERSE_BITS_HPP diff --git a/test/hotspot/gtest/utilities/test_byteswap.cpp b/test/hotspot/gtest/utilities/test_byteswap.cpp new file mode 100644 index 00000000000..3284d35765c --- /dev/null +++ b/test/hotspot/gtest/utilities/test_byteswap.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "utilities/byteswap.hpp" +#include "utilities/globalDefinitions.hpp" +#include "unittest.hpp" + +template +static inline void test_byteswap() { + const int NBIT = sizeof(T) * 8; + const bool IS_U = (T)-1 > 0; + const int XOR_REV_BITS = (NBIT - 1); + const int XOR_REV_BITS_IN_BYTES = 7; // only flip position in byte + const int XOR_REV_BYTES = XOR_REV_BITS ^ XOR_REV_BITS_IN_BYTES; + ASSERT_EQ(byteswap((T)0), (T)0); + ASSERT_EQ(byteswap((T)-1), (T)-1); + for (int i1 = 0; i1 < NBIT; i1++) { + T mask1 = (T)1 << i1; + T rbym1 = (T)1 << (i1 ^ XOR_REV_BYTES); + for (int i2 = 0; i2 <= i1; i2++) { + T mask2 = (T)1 << i2; + T rbym2 = (T)1 << (i2 ^ XOR_REV_BYTES); + T mask = mask1|mask2; +#define STUFF (IS_U?"u":"s") << NBIT << "@" << i1 << "," << i2 + ASSERT_EQ(byteswap(mask), rbym1|rbym2) << STUFF; + ASSERT_EQ((T)~byteswap((T)~mask), rbym1|rbym2) << STUFF; + } + } +} + +TEST_VM(utilities, byteswap) { + test_byteswap(); + test_byteswap(); + test_byteswap(); + test_byteswap(); + test_byteswap(); + test_byteswap(); + test_byteswap(); + test_byteswap(); +} + +// Here is some object code to look at if we want to do a manual +// study. One could find the build file named test_byteswap.o.cmdline +// and hand-edit the command line to produce assembly code in +// test_byteswap.s. +// +// Or, given the two empty "fence functions", one could do a +// quick scan like this: +// +// $ objdump -D $(find build/*release -name test_byteswap.o) \ +// | sed -n '/start_code_quality/,$p;/end_code_quality/q' \ +// | egrep -B10 bswap # or grep -B20 cfi_endproc + +void start_code_quality_byteswap() { } + +int32_t code_quality_reverse_bytes_32(int32_t x) { + return byteswap(x); +} + +int64_t code_quality_reverse_bytes_64(int64_t x) { + return byteswap(x); +} diff --git a/test/hotspot/gtest/opto/test_moveBits.cpp b/test/hotspot/gtest/utilities/test_reverse_bits.cpp similarity index 55% rename from test/hotspot/gtest/opto/test_moveBits.cpp rename to test/hotspot/gtest/utilities/test_reverse_bits.cpp index d25f18ddb68..63176fa3519 100644 --- a/test/hotspot/gtest/opto/test_moveBits.cpp +++ b/test/hotspot/gtest/utilities/test_reverse_bits.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,90 +24,59 @@ #include "precompiled.hpp" #include "utilities/globalDefinitions.hpp" -#include "utilities/moveBits.hpp" +#include "utilities/reverse_bits.hpp" #include "unittest.hpp" template -inline void test_moveBits() { +static inline void test_reverse_bits() { const int NBIT = sizeof(T) * 8; const bool IS_U = (T)-1 > 0; const int XOR_REV_BITS = (NBIT - 1); - const int XOR_REV_BITS_IN_BYTES = 7; // only flip position in byte - const int XOR_REV_BYTES = XOR_REV_BITS ^ XOR_REV_BITS_IN_BYTES; - printf("testing %sint%d_t...\n", IS_U ? "u" : "", NBIT); ASSERT_EQ(reverse_bits((T)0), (T)0); ASSERT_EQ(reverse_bits((T)-1), (T)-1); - ASSERT_EQ(reverse_bytes((T)0), (T)0); - ASSERT_EQ(reverse_bytes((T)-1), (T)-1); - ASSERT_EQ(reverse_bits_in_bytes((T)0), (T)0); - ASSERT_EQ(reverse_bits_in_bytes((T)-1), (T)-1); for (int i1 = 0; i1 < NBIT; i1++) { T mask1 = (T)1 << i1; T revm1 = (T)1 << (i1 ^ XOR_REV_BITS); - T rbym1 = (T)1 << (i1 ^ XOR_REV_BYTES); - T ribm1 = (T)1 << (i1 ^ XOR_REV_BITS_IN_BYTES); for (int i2 = 0; i2 <= i1; i2++) { T mask2 = (T)1 << i2; T revm2 = (T)1 << (i2 ^ XOR_REV_BITS); - T rbym2 = (T)1 << (i2 ^ XOR_REV_BYTES); - T ribm2 = (T)1 << (i2 ^ XOR_REV_BITS_IN_BYTES); T mask = mask1|mask2; #define STUFF (IS_U?"u":"s") << NBIT << "@" << i1 << "," << i2 ASSERT_EQ(reverse_bits(mask), revm1|revm2) << STUFF; ASSERT_EQ((T)~reverse_bits((T)~mask), revm1|revm2) << STUFF; - ASSERT_EQ(reverse_bytes(mask), rbym1|rbym2) << STUFF; - ASSERT_EQ((T)~reverse_bytes((T)~mask), rbym1|rbym2) << STUFF; - ASSERT_EQ(reverse_bits_in_bytes(mask), ribm1|ribm2) << STUFF; - ASSERT_EQ((T)~reverse_bits_in_bytes((T)~mask), ribm1|ribm2) << STUFF; } } } -TEST_VM(opto, moveBits) { - test_moveBits(); - test_moveBits(); - test_moveBits(); - test_moveBits(); - test_moveBits(); - test_moveBits(); - test_moveBits(); - test_moveBits(); +TEST_VM(utilities, reverse_bits) { + test_reverse_bits(); + test_reverse_bits(); + test_reverse_bits(); + test_reverse_bits(); + test_reverse_bits(); + test_reverse_bits(); + test_reverse_bits(); + test_reverse_bits(); } // Here is some object code to look at if we want to do a manual -// study. One could find the build file named test_moveBits.o.cmdline +// study. One could find the build file named test_reverse_bits.o.cmdline // and hand-edit the command line to produce assembly code in -// test_moveBits.s. +// test_reverse_bits.s. // // Or, given the two empty "fence functions", one could do a // quick scan like this: // -// $ objdump -D $(find build/*release -name test_moveBits.o) \ +// $ objdump -D $(find build/*release -name test_reverse_bits.o) \ // | sed -n '/start_code_quality/,$p;/end_code_quality/q' \ // | egrep -B10 bswap # or grep -B20 cfi_endproc -void start_code_quality_moveBits() { } +void start_code_quality_reverse_bits() { } int32_t code_quality_reverse_bits_32(int32_t x) { return reverse_bits(x); } -int32_t code_quality_reverse_bytes_32(int32_t x) { - return reverse_bytes(x); -} - -int32_t code_quality_reverse_bits_in_bytes_32(int32_t x) { - return reverse_bits_in_bytes(x); -} - int64_t code_quality_reverse_bits_64(int64_t x) { return reverse_bits(x); } - -int64_t code_quality_reverse_bytes_64(int64_t x) { - return reverse_bytes(x); -} - -int64_t code_quality_reverse_bits_in_bytes_64(int64_t x) { - return reverse_bits_in_bytes(x); -}