--- old/make/defs.make 2014-03-03 11:17:51.542823000 -0800 +++ new/make/defs.make 2014-03-03 11:17:51.444824000 -0800 @@ -258,7 +258,11 @@ # Use uname output for SRCARCH, but deal with platform differences. If ARCH # is not explicitly listed below, it is treated as x86. - SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 arm ppc ppc64 zero,$(ARCH))) + ARCH_FLAVOR = $(filter sparc sparc64 ia64 amd64 x86_64 arm ppc ppc64 ppc64le zero,$(ARCH)) + ifeq (,$(ARCH_FLAVOR)) + $(warning Unknown architecture $(ARCH), assuming x86) + endif + SRCARCH = $(ARCH/$(ARCH_FLAVOR)) ARCH/ = x86 ARCH/sparc = sparc ARCH/sparc64= sparc @@ -266,11 +270,12 @@ ARCH/amd64 = x86 ARCH/x86_64 = x86 ARCH/ppc64 = ppc + ARCH/ppc64le= ppc ARCH/ppc = ppc ARCH/arm = arm ARCH/zero = zero - # BUILDARCH is usually the same as SRCARCH, except for sparcv9 + # BUILDARCH is usually the same as SRCARCH, except for 32/64 difference BUILDARCH = $(SRCARCH) ifeq ($(BUILDARCH), x86) ifdef LP64 @@ -286,7 +291,11 @@ endif ifeq ($(BUILDARCH), ppc) ifdef LP64 - BUILDARCH = ppc64 + ifeq ($(ARCH_FLAVOR),ppc64) + BUILDARCH = ppc64 + else + BUILDARCH = ppc64le + endif else BUILDARCH = ppc endif @@ -300,11 +309,12 @@ LIBARCH/sparcv9 = sparcv9 LIBARCH/ia64 = ia64 LIBARCH/ppc64 = ppc64 + LIBARCH/ppc64le = ppc64le LIBARCH/ppc = ppc LIBARCH/arm = arm LIBARCH/zero = $(ZERO_LIBARCH) - LP64_ARCH = sparcv9 amd64 ia64 ppc64 zero + LP64_ARCH = sparcv9 amd64 ia64 ppc64 ppc64le zero endif # Required make macro settings for all platforms --- old/make/linux/makefiles/defs.make 2014-03-03 11:17:52.148828000 -0800 +++ new/make/linux/makefiles/defs.make 2014-03-03 11:17:52.034827000 -0800 @@ -114,6 +114,23 @@ HS_ARCH = ppc endif +# PPC64 +ifeq ($(ARCH), ppc64) + ARCH_DATA_MODEL = 64 + MAKE_ARGS += LP64=1 + PLATFORM = linux-ppc64 + VM_PLATFORM = linux_ppc64 + HS_ARCH = ppc +endif + +ifeq ($(ARCH), ppc64le) + ARCH_DATA_MODEL = 64 + MAKE_ARGS += LP64=1 + PLATFORM = linux-ppc64le + VM_PLATFORM = linux_ppc64le + HS_ARCH = ppc +endif + # On 32 bit linux we build server and client, on 64 bit just server. ifeq ($(JVM_VARIANTS),) ifeq ($(ARCH_DATA_MODEL), 32) @@ -126,15 +143,6 @@ endif endif -# PPC64 -ifeq ($(ARCH), ppc64) - ARCH_DATA_MODEL = 64 - MAKE_ARGS += LP64=1 - PLATFORM = linux-ppc64 - VM_PLATFORM = linux_ppc64 - HS_ARCH = ppc -endif - # determine if HotSpot is being built in JDK6 or earlier version JDK6_OR_EARLIER=0 ifeq "$(shell expr \( '$(JDK_MAJOR_VERSION)' != '' \& '$(JDK_MINOR_VERSION)' != '' \& '$(JDK_MICRO_VERSION)' != '' \))" "1" --- old/make/linux/makefiles/gcc.make 2014-03-03 11:17:52.669832000 -0800 +++ new/make/linux/makefiles/gcc.make 2014-03-03 11:17:52.554832000 -0800 @@ -231,6 +231,7 @@ DEBUG_CFLAGS/arm = -g DEBUG_CFLAGS/ppc = -g DEBUG_CFLAGS/ppc64 = -g + DEBUG_CFLAGS/ppc64le = -g DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH)) ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),) DEBUG_CFLAGS += -gstabs @@ -242,6 +243,7 @@ FASTDEBUG_CFLAGS/arm = -g FASTDEBUG_CFLAGS/ppc = -g FASTDEBUG_CFLAGS/ppc64 = -g + FASTDEBUG_CFLAGS/ppc64le = -g FASTDEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH)) ifeq ($(FASTDEBUG_CFLAGS/$(BUILDARCH)),) FASTDEBUG_CFLAGS += -gstabs @@ -252,6 +254,7 @@ OPT_CFLAGS/arm = -g OPT_CFLAGS/ppc = -g OPT_CFLAGS/ppc64 = -g + OPT_CFLAGS/ppc64le = -g OPT_CFLAGS += $(OPT_CFLAGS/$(BUILDARCH)) ifeq ($(OPT_CFLAGS/$(BUILDARCH)),) OPT_CFLAGS += -gstabs --- old/src/cpu/ppc/vm/assembler_ppc.hpp 2014-03-03 11:17:53.289845000 -0800 +++ new/src/cpu/ppc/vm/assembler_ppc.hpp 2014-03-03 11:17:53.168836000 -0800 @@ -1029,15 +1029,14 @@ } static void set_imm(int* instr, short s) { - short* p = ((short *)instr) + 1; - *p = s; + // imm is always in the lower 16 bits of the instruction, + // so this is endian-neutral. Same for the get_imm below. + uint32_t w = *(uint32_t *)instr; + *instr = (int)((w & ~0x0000FFFF) | (s & 0x0000FFFF)); } static int get_imm(address a, int instruction_number) { - short imm; - short *p =((short *)a)+2*instruction_number+1; - imm = *p; - return (int)imm; + return (short)((int *)a)[instruction_number]; } static inline int hi16_signed( int x) { return (int)(int16_t)(x >> 16); } --- old/src/cpu/ppc/vm/bytes_ppc.hpp 2014-03-03 11:17:53.848852000 -0800 +++ new/src/cpu/ppc/vm/bytes_ppc.hpp 2014-03-03 11:17:53.744862000 -0800 @@ -35,6 +35,128 @@ // Can I count on address always being a pointer to an unsigned char? Yes. +#if defined(VM_LITTLE_ENDIAN) + + // Returns true, if the byte ordering used by Java is different from the native byte ordering + // of the underlying machine. For example, true for Intel x86, False, for Solaris on Sparc. + static inline bool is_Java_byte_ordering_different() { return true; } + + // Forward declarations of the compiler-dependent implementation + static inline u2 swap_u2(u2 x); + static inline u4 swap_u4(u4 x); + static inline u8 swap_u8(u8 x); + + // TODO(asmundak): PowerPC64 supports unaligned reads/writes, investigate whether explicit + // byte manipulation is needed. + static inline u2 get_native_u2(address p) { + return (intptr_t(p) & 1) == 0 + ? *(u2*)p + : ( u2(p[1]) << 8 ) + | ( u2(p[0]) ); + } + + static inline u4 get_native_u4(address p) { + switch (intptr_t(p) & 3) { + case 0: return *(u4*)p; + + case 2: return ( u4( ((u2*)p)[1] ) << 16 ) + | ( u4( ((u2*)p)[0] ) ); + + default: return ( u4(p[3]) << 24 ) + | ( u4(p[2]) << 16 ) + | ( u4(p[1]) << 8 ) + | u4(p[0]); + } + } + + static inline u8 get_native_u8(address p) { + switch (intptr_t(p) & 7) { + case 0: return *(u8*)p; + + case 4: return ( u8( ((u4*)p)[1] ) << 32 ) + | ( u8( ((u4*)p)[0] ) ); + + case 2: return ( u8( ((u2*)p)[3] ) << 48 ) + | ( u8( ((u2*)p)[2] ) << 32 ) + | ( u8( ((u2*)p)[1] ) << 16 ) + | ( u8( ((u2*)p)[0] ) ); + + default: return ( u8(p[7]) << 56 ) + | ( u8(p[6]) << 48 ) + | ( u8(p[5]) << 40 ) + | ( u8(p[4]) << 32 ) + | ( u8(p[3]) << 24 ) + | ( u8(p[2]) << 16 ) + | ( u8(p[1]) << 8 ) + | u8(p[0]); + } + } + + + + static inline void put_native_u2(address p, u2 x) { + if ( (intptr_t(p) & 1) == 0 ) *(u2*)p = x; + else { + p[1] = x >> 8; + p[0] = x; + } + } + + static inline void put_native_u4(address p, u4 x) { + switch ( intptr_t(p) & 3 ) { + case 0: *(u4*)p = x; + break; + + case 2: ((u2*)p)[1] = x >> 16; + ((u2*)p)[0] = x; + break; + + default: ((u1*)p)[3] = x >> 24; + ((u1*)p)[2] = x >> 16; + ((u1*)p)[1] = x >> 8; + ((u1*)p)[0] = x; + break; + } + } + + static inline void put_native_u8(address p, u8 x) { + switch ( intptr_t(p) & 7 ) { + case 0: *(u8*)p = x; + break; + + case 4: ((u4*)p)[1] = x >> 32; + ((u4*)p)[0] = x; + break; + + case 2: ((u2*)p)[3] = x >> 48; + ((u2*)p)[2] = x >> 32; + ((u2*)p)[1] = x >> 16; + ((u2*)p)[0] = x; + break; + + default: ((u1*)p)[7] = x >> 56; + ((u1*)p)[6] = x >> 48; + ((u1*)p)[5] = x >> 40; + ((u1*)p)[4] = x >> 32; + ((u1*)p)[3] = x >> 24; + ((u1*)p)[2] = x >> 16; + ((u1*)p)[1] = x >> 8; + ((u1*)p)[0] = x; + } + } + + // 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 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)); } + +#else // !defined(VM_LITTLE_ENDIAN) + // Returns true, if the byte ordering used by Java is different from the nativ byte ordering // of the underlying machine. For example, true for Intel x86, False, for Solaris on Sparc. static inline bool is_Java_byte_ordering_different() { return false; } @@ -150,6 +272,10 @@ static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, x); } static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, x); } static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, x); } + +#endif // VM_LITTLE_ENDIAN }; +#include "bytes_linux_ppc.inline.hpp" + #endif // CPU_PPC_VM_BYTES_PPC_HPP --- old/src/os/linux/vm/os_linux.cpp 2014-03-03 11:17:54.365855000 -0800 +++ new/src/os/linux/vm/os_linux.cpp 2014-03-03 11:17:54.253872000 -0800 @@ -288,7 +288,11 @@ #elif defined(PPC32) static char cpu_arch[] = "ppc"; #elif defined(PPC64) +#if defined VM_LITTLE_ENDIAN +static char cpu_arch[] = "ppc64le"; +#else static char cpu_arch[] = "ppc64"; +#endif #elif defined(SPARC) # ifdef _LP64 static char cpu_arch[] = "sparcv9"; @@ -1979,6 +1983,14 @@ #define EM_486 6 /* Intel 80486 */ #endif + #if defined(PPC64) + #if defined(VM_LITTLE_ENDIAN) + #define PPC64_ELFDATA2XSB ELFDATA2LSB + #else + #define PPC64_ELFDATA2XSB ELFDATA2MSB + #endif + #endif + static const arch_t arch_array[]={ {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, @@ -1988,7 +2000,7 @@ {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"}, {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"}, - {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}, + {EM_PPC64, EM_PPC64, ELFCLASS64, PPC64_ELFDATA2XSB, (char*)"Power PC 64"}, {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"}, {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"}, {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"}, --- /dev/null 2014-02-20 19:11:28.627924044 -0800 +++ new/make/linux/makefiles/ppc64le.make 2014-03-03 11:17:54.845846000 -0800 @@ -0,0 +1,64 @@ +# +# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright 2012, 2013 SAP AG. 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. +# + +# Obviously, little endian machine. +CFLAGS += -DVM_LITTLE_ENDIAN + +# produce 64 bits object files. +CFLAGS += -m64 + +# make c code know it is on a 64 bit platform. +CFLAGS += -D_LP64=1 + +# fixes `relocation truncated to fit' error for gcc 4.1. +CFLAGS += -mminimal-toc + +# finds use ppc64 instructions, but schedule for power5 +CFLAGS += -mcpu=powerpc64 -mtune=power5 -minsert-sched-nops=regroup_exact -mno-multiple -mno-string + +# PPC uses safefetch stubs. +CFLAGS += -DSAFEFETCH_STUBS + +#PPC64 LE uses ELFv2 ABI +CFLAGS += -DABI_ELFv2 + +# let linker produce 64 bit lib. +LFLAGS_VM += -m64 + +# let linker find external 64 bit libs. +ifndef GOOGLE_CROSSTOOL +LFLAGS_VM += -L/lib64 +endif + +# specify lib format. +LFLAGS_VM += -Wl,-melf64lppc + +# also build launcher as 64 bit executable. +LAUNCHERFLAGS += -m64 +LAUNCHERFLAGS += -D_LP64=1 +AOUT_FLAGS += -m64 +ifndef GOOGLE_CROSSTOOL +AOUT_FLAGS += -L/lib64 +endif +AOUT_FLAGS += -Wl,-melf64lppc --- /dev/null 2014-02-20 19:11:28.627924044 -0800 +++ new/make/linux/platform_ppc64le 2014-03-03 11:17:55.189853000 -0800 @@ -0,0 +1,17 @@ +os_family = linux + +arch = ppc + +arch_model = ppc_64 + +os_arch = linux_ppc + +os_arch_model = linux_ppc_64 + +lib_arch = ppc64 + +compiler = gcc + +gnu_dis_arch = ppc64 + +sysdefs = -DLINUX -D_GNU_SOURCE -DPPC64 --- /dev/null 2014-02-20 19:11:28.627924044 -0800 +++ new/src/os_cpu/linux_ppc/vm/bytes_linux_ppc.inline.hpp 2014-03-03 11:17:55.562899000 -0800 @@ -0,0 +1,14 @@ +#ifndef OS_CPU_LINUX_PPC_VM_BYTES_LINUX_PPC_INLINE_HPP +#define OS_CPU_LINUX_PPCLE_VM_BYTES_LINUX_PPC_INLINE_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_VM_BYTES_LINUX_PPC_INLINE_HPP