Mercurial > hg > release > icedtea6-1.4.1
changeset 343:9dcd398427b7
2007-11-12 Gary Benson <gbenson@redhat.com>
* ports/hotspot/build/linux/platform_ppc: New file.
* ports/hotspot/build/linux/platform_ppc64: Likewise.
* ports/hotspot/build/linux/makefiles/ppc.make: Likewise.
* ports/hotspot/build/linux/makefiles/ppc64.make: Likewise.
* ports/hotspot/src/cpu/ppc/vm/assembler_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/bytecodeInterpreter_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/bytecodeInterpreter_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/bytecodeInterpreter_ppc.inline.hpp:
Likewise.
* ports/hotspot/src/cpu/ppc/vm/bytecodes_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/bytecodes_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/bytes_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/codeBuffer_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/copy_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/cppInterpreterGenerator_ppc.hpp:
Likewise.
* ports/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/debug_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/depChecker_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/depChecker_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/disassembler_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/disassembler_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/dump_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/frame_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/frame_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/globals_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/icBuffer_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/icache_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/icache_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/interp_masm_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/interp_masm_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/interpreterGenerator_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/interpreterRT_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/interpreterRT_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/interpreter_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/javaFrameAnchor_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/jniFastGetField_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/jniTypes_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/jni_ppc.h: Likewise.
* ports/hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/nativeInst_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/registerMap_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/register_definitions_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/register_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/register_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/relocInfo_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/relocInfo_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/stubRoutines_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/stubRoutines_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.hpp:
Likewise.
* ports/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/templateTable_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/templateTable_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/vmStructs_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/vm_version_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/vmreg_ppc.cpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/vmreg_ppc.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/vmreg_ppc.inline.hpp: Likewise.
* ports/hotspot/src/cpu/ppc/vm/vtableStubs_ppc.cpp: Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/linux_ppc.s: Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/linux_ppc64.s: Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/assembler_linux_ppc.cpp:
Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp:
Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/bytes_linux_ppc.inline.hpp:
Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp:
Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/orderAccess_linux_ppc.inline.hpp:
Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp: Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.hpp: Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/prefetch_linux_ppc.inline.hpp:
Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.cpp:
Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.hpp:
Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/thread_linux_ppc.cpp: Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/thread_linux_ppc.hpp: Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/vmStructs_linux_ppc.hpp:
Likewise.
* ports/hotspot/src/os_cpu/linux_ppc/vm/vm_version_linux_ppc.cpp:
Likewise.
* ports/j2se/src/solaris/bin/ppc/jvm.cfg: Likewise.
* ports/j2se/src/solaris/bin/ppc64/jvm.cfg: Likewise.
* ports/j2se/src/solaris/bin/ergo_ppc.c: Likewise.
* Makefile.am: Link the above into the build trees before building.
* Makefile.in: Regenerated.
line wrap: on
line diff
--- a/ChangeLog Mon Nov 12 06:27:08 2007 -0500 +++ b/ChangeLog Mon Nov 12 06:37:43 2007 -0500 @@ -1,3 +1,107 @@ +2007-11-12 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/build/linux/platform_ppc: New file. + * ports/hotspot/build/linux/platform_ppc64: Likewise. + * ports/hotspot/build/linux/makefiles/ppc.make: Likewise. + * ports/hotspot/build/linux/makefiles/ppc64.make: Likewise. + * ports/hotspot/src/cpu/ppc/vm/assembler_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/bytecodeInterpreter_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/bytecodeInterpreter_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/bytecodeInterpreter_ppc.inline.hpp: + Likewise. + * ports/hotspot/src/cpu/ppc/vm/bytecodes_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/bytecodes_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/bytes_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/codeBuffer_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/copy_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/cppInterpreterGenerator_ppc.hpp: + Likewise. + * ports/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/debug_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/depChecker_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/depChecker_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/disassembler_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/disassembler_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/dump_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/frame_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/frame_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/globals_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/icBuffer_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/icache_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/icache_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/interp_masm_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/interp_masm_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/interpreterGenerator_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/interpreterRT_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/interpreterRT_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/interpreter_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/javaFrameAnchor_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/jniFastGetField_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/jniTypes_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/jni_ppc.h: Likewise. + * ports/hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/nativeInst_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/registerMap_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/register_definitions_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/register_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/register_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/relocInfo_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/relocInfo_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/stubRoutines_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/stubRoutines_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.hpp: + Likewise. + * ports/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/templateTable_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/templateTable_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/vmStructs_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/vm_version_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/vmreg_ppc.cpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/vmreg_ppc.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/vmreg_ppc.inline.hpp: Likewise. + * ports/hotspot/src/cpu/ppc/vm/vtableStubs_ppc.cpp: Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/linux_ppc.s: Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/linux_ppc64.s: Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/assembler_linux_ppc.cpp: + Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp: + Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/bytes_linux_ppc.inline.hpp: + Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp: + Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/orderAccess_linux_ppc.inline.hpp: + Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp: Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.hpp: Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/prefetch_linux_ppc.inline.hpp: + Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.cpp: + Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.hpp: + Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/thread_linux_ppc.cpp: Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/thread_linux_ppc.hpp: Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/vmStructs_linux_ppc.hpp: + Likewise. + * ports/hotspot/src/os_cpu/linux_ppc/vm/vm_version_linux_ppc.cpp: + Likewise. + * ports/j2se/src/solaris/bin/ppc/jvm.cfg: Likewise. + * ports/j2se/src/solaris/bin/ppc64/jvm.cfg: Likewise. + * ports/j2se/src/solaris/bin/ergo_ppc.c: Likewise. + * Makefile.am: Link the above into the build trees before building. + * Makefile.in: Regenerated. + 2007-11-12 Gary Benson <gbenson@redhat.com> * patches/icedtea-ports.patch: Remake for setarch and ppc64.
--- a/Makefile.am Mon Nov 12 06:27:08 2007 -0500 +++ b/Makefile.am Mon Nov 12 06:37:43 2007 -0500 @@ -150,6 +150,18 @@ rm -f stamps/extract.stamp rm -rf openjdk +# Link ports sources into tree +stamps/ports.stamp: stamps/extract.stamp + for target in ports/hotspot/build/*/platform_* \ + ports/hotspot/build/*/makefiles/* \ + ports/hotspot/src/*/* \ + ports/j2se/src/*/bin/*; do \ + link=$$(dirname $$target | sed 's/^ports/openjdk/'); \ + ln -sf $$PWD/$$target $$link; \ + done + mkdir -p stamps + touch stamps/ports.stamp + # Patch OpenJDK sources for plug replacements. if FAST_BUILD FAST_BUILD_PATCH = patches/icedtea-speed.patch @@ -241,6 +253,18 @@ rm -f stamps/extract-ecj.stamp rm -rf openjdk-ecj +# Link ports sources into tree +stamps/ports-ecj.stamp: stamps/extract.stamp + for target in ports/hotspot/build/*/platform_* \ + ports/hotspot/build/*/makefiles/* \ + ports/hotspot/src/*/* \ + ports/j2se/src/*/bin/*; do \ + link=$$(dirname $$target | sed 's/^ports/openjdk-ecj/'); \ + ln -sf $$PWD/$$target $$link; \ + done + mkdir -p stamps + touch stamps/ports-ecj.stamp + # Patch OpenJDK for plug replacements and ecj. ICEDTEA_ECJ_PATCH = patches/icedtea-ecj.patch @@ -372,7 +396,7 @@ # If you change anything here in the icedtea target, please make sure # you change it in the icedtea-debug target as well. icedtea: stamps/tools.stamp stamps/plugs.stamp stamps/extract.stamp \ - stamps/patch.stamp gcjwebplugin.so + stamps/ports.stamp stamps/patch.stamp gcjwebplugin.so $(MAKE) \ $(ICEDTEA_ENV) \ -C openjdk/control/make @@ -384,7 +408,7 @@ icedtea-debug: stamps/bootstrap-directory-symlink.stamp \ stamps/tools.stamp stamps/plugs.stamp stamps/extract.stamp \ - stamps/patch.stamp gcjwebplugin.so + stamps/ports.stamp stamps/patch.stamp gcjwebplugin.so $(MAKE) \ $(ICEDTEA_ENV) \ -C openjdk/control/make \ @@ -409,7 +433,7 @@ # =================== stamps/icedtea-ecj.stamp: stamps/tools.stamp stamps/plugs.stamp \ - stamps/extract-ecj.stamp stamps/patch-ecj.stamp + stamps/extract-ecj.stamp stamps/ports-ecj.stamp stamps/patch-ecj.stamp $(MAKE) \ $(ICEDTEA_ENV_ECJ) \ -C openjdk-ecj/control/make
--- a/Makefile.in Mon Nov 12 06:27:08 2007 -0500 +++ b/Makefile.in Mon Nov 12 06:37:43 2007 -0500 @@ -699,6 +699,18 @@ rm -f stamps/extract.stamp rm -rf openjdk +# Link ports sources into tree +stamps/ports.stamp: stamps/extract.stamp + for target in ports/hotspot/build/*/platform_* \ + ports/hotspot/build/*/makefiles/* \ + ports/hotspot/src/*/* \ + ports/j2se/src/*/bin/*; do \ + link=$$(dirname $$target | sed 's/^ports/openjdk/'); \ + ln -sf $$PWD/$$target $$link; \ + done + mkdir -p stamps + touch stamps/ports.stamp + stamps/patch.stamp: stamps/extract.stamp for p in $(ICEDTEA_PATCHES) ; \ do \ @@ -745,6 +757,18 @@ rm -f stamps/extract-ecj.stamp rm -rf openjdk-ecj +# Link ports sources into tree +stamps/ports-ecj.stamp: stamps/extract.stamp + for target in ports/hotspot/build/*/platform_* \ + ports/hotspot/build/*/makefiles/* \ + ports/hotspot/src/*/* \ + ports/j2se/src/*/bin/*; do \ + link=$$(dirname $$target | sed 's/^ports/openjdk-ecj/'); \ + ln -sf $$PWD/$$target $$link; \ + done + mkdir -p stamps + touch stamps/ports-ecj.stamp + stamps/patch-ecj.stamp: stamps/extract-ecj.stamp for p in $(ICEDTEA_PATCHES) ; \ do \ @@ -855,7 +879,7 @@ # If you change anything here in the icedtea target, please make sure # you change it in the icedtea-debug target as well. icedtea: stamps/tools.stamp stamps/plugs.stamp stamps/extract.stamp \ - stamps/patch.stamp gcjwebplugin.so + stamps/ports.stamp stamps/patch.stamp gcjwebplugin.so $(MAKE) \ $(ICEDTEA_ENV) \ -C openjdk/control/make @@ -867,7 +891,7 @@ icedtea-debug: stamps/bootstrap-directory-symlink.stamp \ stamps/tools.stamp stamps/plugs.stamp stamps/extract.stamp \ - stamps/patch.stamp gcjwebplugin.so + stamps/ports.stamp stamps/patch.stamp gcjwebplugin.so $(MAKE) \ $(ICEDTEA_ENV) \ -C openjdk/control/make \ @@ -892,7 +916,7 @@ # =================== stamps/icedtea-ecj.stamp: stamps/tools.stamp stamps/plugs.stamp \ - stamps/extract-ecj.stamp stamps/patch-ecj.stamp + stamps/extract-ecj.stamp stamps/ports-ecj.stamp stamps/patch-ecj.stamp $(MAKE) \ $(ICEDTEA_ENV_ECJ) \ -C openjdk-ecj/control/make
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/build/linux/makefiles/ppc.make Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,34 @@ +# +# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007 Red Hat, Inc. +# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# +# + +# Not included in includeDB because it has no dependencies +Obj_Files += linux_ppc.o + +# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized +OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT) +# The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized +OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT) + +OPT_CFLAGS/compactingPermGenGen.o = -O1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/build/linux/makefiles/ppc64.make Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,37 @@ +# +# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007 Red Hat, Inc. +# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# +# + +# Not included in includeDB because it has no dependencies +Obj_Files += linux_ppc64.o + +# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized +OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT) +# The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized +OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT) + +# Specify that the CPU is 64 bit +CFLAGS += -D_LP64=1 + +OPT_CFLAGS/compactingPermGenGen.o = -O1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/build/linux/platform_ppc Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,17 @@ +os_family = linux + +arch = ppc + +arch_model = ppc + +os_arch = linux_ppc + +os_arch_model = linux_ppc + +lib_arch = ppc + +compiler = gcc + +gnu_dis_arch = ppc + +sysdefs = -DLINUX -D_GNU_SOURCE -DPPC -DPPC32 -DCC_INTERP -DXXX_EVIL_EVIL_EVIL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/build/linux/platform_ppc64 Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,17 @@ +os_family = linux + +arch = ppc + +arch_model = ppc + +os_arch = linux_ppc + +os_arch_model = linux_ppc + +lib_arch = ppc + +compiler = gcc + +gnu_dis_arch = ppc + +sysdefs = -DLINUX -D_GNU_SOURCE -DPPC -DPPC64 -DCC_INTERP -DXXX_EVIL_EVIL_EVIL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/assembler_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,1371 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_assembler_ppc.cpp.incl" + + +// Fill empty space with zeros. +// (0x00000000 is an illegal instruction on ppc) + +int AbstractAssembler::code_fill_byte() +{ + return 0x00; +} + +// Instruction emitters for the various forms. +// Every instruction should ultimately come through one of these. + +void Assembler::emit_instruction(int opcode, int li, bool aa, bool lk) +{ + // I-form + assert(!(opcode & ~0x3f), "invalid opcode"); + assert(!(li & ~0xffffff), "invalid operand"); + emit_long(opcode << 26 | li << 2 | aa << 1 | lk); +} +void Assembler::emit_instruction(int opcode, int bo, int bi, int bd, + bool aa, bool lk) { + // B-form (includes SC-form) + assert(!(opcode & ~0x3f), "invalid opcode"); + assert(!(bo & ~0x1f), "invalid operand"); + assert(!(bi & ~0x1f), "invalid operand"); + assert(!(bd & ~0x3fff), "invalid operand"); + emit_long(opcode << 26 | bo << 21 | bi << 16 | bd << 2 | aa << 1 | lk); +} +void Assembler::emit_instruction(int opcode, int a, int b, int c) +{ + // D-form + assert(!(opcode & ~0x3f), "invalid opcode"); + assert(!(a & ~0x1f), "invalid operand"); + assert(!(b & ~0x1f), "invalid operand"); + if (c < 0) { + assert((c & ~0xffff) == ~0xffff, "invalid operand"); + c &= 0xffff; + } + else + assert(!(c & ~0xffff), "invalid operand"); + emit_long(opcode << 26 | a << 21 | b << 16 | c); +} +void Assembler::emit_instruction(int opcode, int a, int b, int c, int d) +{ + // DS-form + assert(!(opcode & ~0x3f), "invalid opcode"); + assert(!(a & ~0x1f), "invalid operand"); + assert(!(b & ~0x1f), "invalid operand"); + if (c < 0) { + assert((c & ~0x3fff) == ~0x3fff, "invalid operand"); + c &= 0x3fff; + } + else + assert(!(c & ~0x3fff), "invalid operand"); + assert(!(d & ~0x3), "invalid operand"); + emit_long(opcode << 26 | a << 21 | b << 16 | c << 2 | d); +} +void Assembler::emit_instruction(int opcode, int a, int b, int c, int xo, + bool rc) { + // X-form + assert(!(opcode & ~0x3f), "invalid opcode"); + assert(!(a & ~0x1f), "invalid operand"); + assert(!(b & ~0x1f), "invalid operand"); + assert(!(c & ~0x1f), "invalid operand"); + assert(!(xo & ~0x3ff), "invalid operand"); + emit_long(opcode << 26 | a << 21 | b << 16 | c << 11 | xo << 1 | rc); +} +void Assembler::emit_instruction(int opcode, int a, int b, int c, int d, + int e, bool rc) { + switch (opcode) { + case 21: + // M-form + assert(!(a & ~0x1f), "invalid operand"); + assert(!(b & ~0x1f), "invalid operand"); + assert(!(c & ~0x1f), "invalid operand"); + assert(!(d & ~0x1f), "invalid operand"); + assert(!(e & ~0x1f), "invalid operand"); + break; + + case 30: + // MD-form + assert(!(a & ~0x1f), "invalid operand"); + assert(!(b & ~0x1f), "invalid operand"); + assert(!(c & ~0x3f), "invalid operand"); + assert(!(d & ~0x3f), "invalid operand"); + assert(!(e & ~0x07), "invalid operand"); + { + int C = c & 0x1f; + int D = d & 0x1f; + int E = (d & 0x20) >> 1 | e << 1 | (c & 0x20) >> 5; + + c = C; d = D; e = E; + } + break; + + default: + ShouldNotReachHere(); + } + emit_long(opcode << 26 | a << 21 | b << 16 | c << 11 | d << 6 | e << 1 | rc); +} + +// Wrappers for the instruction emitters. +// These handle casting and stuff. + +void Assembler::emit_instruction(int opcode, Register a, Register b, int c) +{ + emit_instruction(opcode, a->encoding(), b->encoding(), c); +} +void Assembler::emit_instruction(int opcode, Register a, Register b, int c, + int d) { + emit_instruction(opcode, a->encoding(), b->encoding(), c, d); +} +void Assembler::emit_instruction(int opcode, FloatRegister a, Register b, + int c) { + emit_instruction(opcode, a->encoding(), b->encoding(), c); +} +void Assembler::emit_instruction(int opcode, Register a, const Address& b) +{ + emit_instruction(opcode, a, b.base(), b.displacement()); +} +void Assembler::emit_instruction(int opcode, Register a, const Address& b, + int c) { + emit_instruction(opcode, a, b.base(), b.displacement() >> 2, c); +} +void Assembler::emit_instruction(int opcode, FloatRegister a, const Address& b) +{ + emit_instruction(opcode, a, b.base(), b.displacement()); +} +void Assembler::emit_instruction(int opcode, Register a, int b, int c, + int xo, bool rc) { + emit_instruction(opcode, a->encoding(), b, c, xo, rc); +} +void Assembler::emit_instruction(int opcode, Register a, Register b, + Register c, int xo, bool rc) { + emit_instruction(opcode, a->encoding(), b->encoding(), c->encoding(), + xo, rc); +} +void Assembler::emit_instruction(int opcode, Register a, + SpecialPurposeRegister b, int c, int xo, + bool rc) { + emit_instruction(opcode, a->encoding(), b->encoding(), c, xo, rc); +} +void Assembler::emit_instruction(int opcode, SpecialPurposeRegister a, + Register b, int c, int xo, bool rc) { + emit_instruction(opcode, a->encoding(), b->encoding(), c, xo, rc); +} +void Assembler::emit_instruction(int opcode, Register a, Register b, + int c, int d, int e, bool rc) { + emit_instruction(opcode, a->encoding(), b->encoding(), c, d, e, rc); +} +void Assembler::emit_instruction(int opcode, int a, Register b, Register c, + int d, bool rc) { + emit_instruction(opcode, a, b->encoding(), c->encoding(), d, rc); +} +void Assembler::emit_instruction(int opcode, ConditionRegister a, bool l, + Register b, Register c, int d, bool rc) { + emit_instruction(opcode, a->encoding() << 2 | l, b, c, d, rc); +} +void Assembler::emit_instruction(int opcode, ConditionRegister a, bool l, + Register b, int c) { + emit_instruction(opcode, a->encoding() << 2 | l, b->encoding(), c); +} +void Assembler::emit_instruction(int opcode, FloatRegister a, int b, + FloatRegister c, int xo, bool rc) { + emit_instruction(opcode, a->encoding(), b, c->encoding(), xo, rc); +} + +// Helpers for computing branch targets + +intptr_t Assembler::branch_target(address branch, address target, int bits) +{ + assert(!((intptr_t) branch & 3), "invalid address"); + assert(!((intptr_t) target & 3), "invalid address"); + + intptr_t disp = ((intptr_t) target - (intptr_t) branch) >> 2; + + intptr_t mask = (1 << bits) - 1; + intptr_t msb = 1 << (bits - 1); + + if (disp & msb) { + assert((disp & ~mask) == ~mask, "invalid displacement"); + disp &= mask; + } + else { + assert(!(disp & ~mask), "invalid displacement"); + } + return disp; +} + +// Instructions common to 32- and 64-bit implementations + +void Assembler::add(Register dst, Register a, Register b) +{ + emit_instruction(31, dst, a, b, 266, false); +} +void Assembler::addi(Register dst, Register a, int b) +{ + emit_instruction(14, dst, a, b); +} +void Assembler::addis(Register dst, Register a, int b) +{ + emit_instruction(15, dst, a, b); +} +void Assembler::andi_(Register dst, Register a, int b) +{ + emit_instruction(28, a, dst, b); +} +void Assembler::b(address a) +{ + emit_instruction(18, branch_target(pc(), a, 24), false, false); +} +void Assembler::bc(int bo, int bi, address a) +{ + emit_instruction(16, bo, bi, branch_target(pc(), a, 14), false, false); +} +void Assembler::bclr(int bo, int bi) +{ + emit_instruction(19, bo, bi, 0, 16, false); +} +void Assembler::bclrl(int bo, int bi) +{ + emit_instruction(19, bo, bi, 0, 16, true); +} +void Assembler::bl(address a) +{ + emit_instruction(18, branch_target(pc(), a, 24), false, true); +} +void Assembler::cmp(ConditionRegister dst, bool l, Register a, Register b) +{ + emit_instruction(31, dst, l, a, b, 0, false); +} +void Assembler::cmpi(ConditionRegister dst, bool l, Register a, int b) +{ + emit_instruction(11, dst, l, a, b); +} +void Assembler::dcbf(Register a, Register b) +{ + emit_instruction(31, 0, a, b, 86, false); +} +void Assembler::extsb(Register dst, Register src) +{ + emit_instruction(31, src, dst, 0, 954, false); +} +void Assembler::extsh(Register dst, Register src) +{ + emit_instruction(31, src, dst, 0, 922, false); +} +void Assembler::fmr(FloatRegister dst, FloatRegister src) +{ + emit_instruction(63, dst, 0, src, 72, false); +} +void Assembler::icbi(Register a, Register b) +{ + emit_instruction(31, 0, a, b, 982, false); +} +void Assembler::isync() +{ + emit_instruction(19, 0, 0, 0, 150, false); +} +void Assembler::lbzx(Register dst, Register a, Register b) +{ + emit_instruction(31, dst, a, b, 87, false); +} +void Assembler::lfd(FloatRegister dst, const Address& src) +{ + emit_instruction(50, dst, src); +} +void Assembler::lfs(FloatRegister dst, const Address& src) +{ + emit_instruction(48, dst, src); +} +void Assembler::lhz(Register dst, const Address& src) +{ + emit_instruction(40, dst, src); +} +void Assembler::lhzx(Register dst, Register a, Register b) +{ + emit_instruction(31, dst, a, b, 279, false); +} +void Assembler::lwarx(Register dst, Register a, Register b) +{ + emit_instruction(31, dst, a, b, 20, false); +} +void Assembler::lwz(Register dst, const Address& src) +{ + emit_instruction(32, dst, src); +} +void Assembler::lwzx(Register dst, Register a, Register b) +{ + emit_instruction(31, dst, a, b, 23, false); +} +void Assembler::mfcr(Register dst) +{ + emit_instruction(31, dst, 0, 0, 19, false); +} +void Assembler::mfspr(Register dst, SpecialPurposeRegister src) +{ + emit_instruction(31, dst, src, 0, 339, false); +} +void Assembler::mtcrf(int mask, Register src) +{ + emit_instruction(31, src, (mask & 0xf0) >> 4, (mask & 0xf) << 1, 144, false); +} +void Assembler::mtspr(SpecialPurposeRegister dst, Register src) +{ + emit_instruction(31, src, dst, 0, 467, false); +} +void Assembler::neg(Register dst, Register src) +{ + emit_instruction(31, dst, src, 0, 104, false); +} +void Assembler::OR(Register dst, Register a, Register b) +{ + emit_instruction(31, a, dst, b, 444, false); +} +void Assembler::ori(Register dst, Register a, int b) +{ + emit_instruction(24, a, dst, b); +} +void Assembler::oris(Register dst, Register a, int b) +{ + emit_instruction(25, a, dst, b); +} +void Assembler::rlwinm(Register dst, Register a, int b, int mb, int me) +{ + emit_instruction(21, a, dst, b, mb, me, false); +} +void Assembler::stfd(FloatRegister src, const Address& dst) +{ + emit_instruction(54, src, dst); +} +void Assembler::stfs(FloatRegister src, const Address& dst) +{ + emit_instruction(52, src, dst); +} +void Assembler::stw(Register src, const Address& dst) +{ + emit_instruction(36, src, dst); +} +void Assembler::stwcx_(Register src, Register a, Register b) +{ + emit_instruction(31, src, a, b, 150, true); +} +void Assembler::stwu(Register src, const Address& dst) +{ + emit_instruction(37, src, dst); +} +void Assembler::stwux(Register src, Register a, Register b) +{ + emit_instruction(31, src, a, b, 183, false); +} +void Assembler::stwx(Register src, Register a, Register b) +{ + emit_instruction(31, src, a, b, 151, false); +} +void Assembler::subf(Register dst, Register a, Register b) +{ + emit_instruction(31, dst, a, b, 40, false); +} +void Assembler::subfic(Register dst, Register a, int b) +{ + emit_instruction(8, dst, a, b); +} +void Assembler::sync() +{ + emit_instruction(31, 0, 0, 0, 598, false); +} + +// Instructions for 64-bit implementations only +#ifdef PPC64 +void Assembler::extsw(Register dst, Register src) +{ + emit_instruction(31, src, dst, 0, 986, false); +} +void Assembler::ld(Register dst, const Address& src) +{ + emit_instruction(58, dst, src, 0); +} +void Assembler::ldarx(Register dst, Register a, Register b) +{ + emit_instruction(31, dst, a, b, 84, false); +} +void Assembler::ldx(Register dst, Register a, Register b) +{ + emit_instruction(31, dst, a, b, 21, false); +} +void Assembler::rldicl(Register dst, Register a, int sh, int mb) +{ + emit_instruction(30, a, dst, sh, mb, 0, false); +} +void Assembler::rldicr(Register dst, Register a, int sh, int me) +{ + emit_instruction(30, a, dst, sh, me, 1, false); +} +void Assembler::std(Register src, const Address& dst) +{ + emit_instruction(62, src, dst, 0); +} +void Assembler::stdcx_(Register src, Register a, Register b) +{ + emit_instruction(31, src, a, b, 214, true); +} +void Assembler::stdu(Register src, const Address& dst) +{ + emit_instruction(62, src, dst, 1); +} +void Assembler::stdux(Register src, Register a, Register b) +{ + emit_instruction(31, src, a, b, 181, false); +} +void Assembler::stdx(Register src, Register a, Register b) +{ + emit_instruction(31, src, a, b, 149, false); +} +#endif // PPC64 + +// Standard mnemonics common to 32- and 64-bit implementations + +void Assembler::bdnz(Label& l) +{ + bc(16, 0, l); +} +void Assembler::beq(Label& l) +{ + bc(12, 2, l); +} +void Assembler::beqlr() +{ + bclr(12, 2); +} +void Assembler::bge(Label& l) +{ + bc(4, 0, l); +} +void Assembler::bgt(Label& l) +{ + bc(12, 1, l); +} +void Assembler::ble(Label& l) +{ + bc(4, 1, l); +} +void Assembler::blelr() +{ + bclr(4, 1); +} +void Assembler::blr() +{ + bclr(20, 0); +} +void Assembler::blrl() +{ + bclrl(20, 0); +} +void Assembler::blt(Label& l) +{ + bc(12, 0, l); +} +void Assembler::bne(Label& l) +{ + bne(cr0, l); +} +void Assembler::bne(ConditionRegister r, Label& l) +{ + bc(4, (r->encoding() << 2) | 2, l); +} +void Assembler::cmpw(ConditionRegister dst, Register a, Register b) +{ + cmp(dst, false, a, b); +} +void Assembler::cmpwi(ConditionRegister dst, Register a, int b) +{ + cmpi(dst, false, a, b); +} +void Assembler::la(Register dst, Address value) +{ + addi(dst, value.base(), value.displacement()); +} +void Assembler::li(Register dst, int value) +{ + addi(dst, 0, value); +} +void Assembler::lis(Register dst, int value) +{ + addis(dst, 0, value); +} +void Assembler::mr(Register dst, Register src) +{ + OR(dst, src, src); +} +void Assembler::mfctr(Register dst) +{ + mfspr(dst, ctr); +} +void Assembler::mflr(Register dst) +{ + mfspr(dst, lr); +} +void Assembler::mtcr(Register src) +{ + mtcrf(0xff, src); +} +void Assembler::mtctr(Register src) +{ + mtspr(ctr, src); +} +void Assembler::mtlr(Register src) +{ + mtspr(lr, src); +} +void Assembler::nop() +{ + ori(r0, r0, 0); +} +void Assembler::slwi(Register dst, Register a, int b) +{ + rlwinm(dst, a, b, 0, 31 - b); +} +void Assembler::srwi(Register dst, Register a, int b) +{ + rlwinm(dst, a, 32 - b, b, 31); +} +void Assembler::sub(Register dst, Register a, Register b) +{ + subf(dst, b, a); +} +void Assembler::subi(Register dst, Register a, int b) +{ + addi(dst, a, -b); +} + +// Standard mnemonics for 64-bit implementations only +#ifdef PPC64 +void Assembler::cmpd(ConditionRegister dst, Register a, Register b) +{ + cmp(dst, true, a, b); +} +void Assembler::cmpdi(ConditionRegister dst, Register a, int b) +{ + cmpi(dst, true, a, b); +} +void Assembler::sldi(Register dst, Register a, int b) +{ + rldicr(dst, a, b, 63 - b); +} +void Assembler::srdi(Register dst, Register a, int b) +{ + rldicl(dst, a, 64 - b, b); +} +#endif // PPC64 + +// Wrappers for branch instructions + +void Assembler::b(Label &l) +{ + if (l.is_bound()) { + b(target(l)); + } + else { + l.add_patch_at(code(), locator()); + b(pc()); + } +} +void Assembler::bc(int bo, int bi, Label& l) +{ + if (l.is_bound()) { + bc(bo, bi, target(l)); + } + else { + l.add_patch_at(code(), locator()); + bc(bo, bi, pc()); + } +} +void Assembler::bl(Label &l) +{ + if (l.is_bound()) { + bl(target(l)); + } + else { + l.add_patch_at(code(), locator()); + bl(pc()); + } +} + +// Function to fix up forward branches + +void Assembler::pd_patch_instruction(address branch, address target) +{ + unsigned int instruction = *(unsigned int *) branch; + unsigned int opcode = instruction >> 26; + assert (!(instruction & 2), "must use relocations for absolute branches"); + + switch (opcode) { + case 16: + // conditional branch, 14-bit displacement + assert(!(instruction & 0xfffc), "should be zeroed"); + (*(unsigned int *) branch) |= branch_target(branch, target, 14) << 2; + break; + + case 18: + // unconditional branch, 24-bit displacement + assert(!(instruction & 0x3fffffc), "should be zeroed"); + (*(unsigned int *) branch) |= branch_target(branch, target, 24) << 2; + break; + + default: + Unimplemented(); + } +} + +#ifndef PRODUCT + +void Assembler::pd_print_patched_instruction(address branch) +{ + Unimplemented(); +} + +void Assembler::disassemble(const char *what, address start, address end) +{ + const char *fmt = "/tmp/aztec-%d.%c"; + char c_file[BUFSIZ], o_file[BUFSIZ]; + sprintf(c_file, fmt, getpid(), 'c'); + sprintf(o_file, fmt, getpid(), 'o'); + + FILE *fp = fopen(c_file, "w"); + if (fp == NULL) + fatal2("%s:%d: can't write file", __FILE__, __LINE__); + + fputs("unsigned char start[] = {", fp); + for (address a = start; a < end; a++) { + if (a != start) + fputc(',', fp); + fprintf(fp, "0x%02x", *a); + } + fputs("};\n", fp); + fclose(fp); + + char cmd[BUFSIZ]; + sprintf(cmd, "gcc -m%d -c %s -o %s", wordSize * 8, c_file, o_file); + if (system(cmd) != 0) + fatal2("%s:%d: can't compile file", __FILE__, __LINE__); + + printf("%s: %p-%p:\n", what, start, end); + fflush(stdout); + sprintf(cmd, "objdump -D -j .data %s | grep '^....:'", o_file); + if (system(cmd) != 0) + fatal2("%s:%d: can't disassemble file", __FILE__, __LINE__); + putchar('\n'); + fflush(stdout); + + unlink(c_file); + unlink(o_file); +} + +#endif // PRODUCT + +// 32-bit ABI: +// +// | ... | +// +----------------------+ +// | LR save word | +// +-> | Back chain | +// | +----------------------+ --------------------------------------- +// | | FPR save area f31 | high addresses +// | | ... | 2 * _fprs words +// | | f14 | +// | +----------------------+ +// | | GPR save area r31 | +// | | ... | _gprs words +// | | r14 | +// | +----------------------+ +// | | CR save area | 1 word +// | +----------------------+ +// | | Local variable space | _locals words (+ padding if required) +// | +----------------------+ +// | | Parameter list space | _params words +// | +----------------------+ +// | | LR save word | 1 word +// +---+ Back chain | 1 word low addresses +// +----------------------+ --------------------------------------- + +// 64-bit ABI: +// +// | ... | +// | LR save word | +// | CR save word | +// +-> | Back chain | +// | +----------------------+ --------------------------------------- +// | | FPR save area f31 | high addresses +// | | ... | _fprs words +// | | f14 | +// | +----------------------+ +// | | GPR save area r31 | +// | | ... | _gprs words +// | | r14 | +// | +----------------------+ +// | | Local variable space | _locals words (+ padding if required) +// | +----------------------+ +// | | Parameter list space | _params words (minimum 8) +// | +----------------------+ +// | | TOC save word | 1 word +// | | Reserved | 2 words +// | | LR save word | 1 word +// | | CR save word | 1 word +// +---+ Back chain | 1 word low addresses +// +----------------------+ --------------------------------------- + +const Address StackFrame::get_parameter() +{ + assert(_state == done_nothing, "can't change layout after prolog written"); + assert(_locals == 0, "get all parameters before allocating locals"); + return Address(r1, (link_area_words + _params++) * wordSize); +} +const Address StackFrame::get_local_variable() +{ + assert(_state == done_nothing, "can't change layout after prolog written"); + if (_params < min_params) + _params = min_params; + return Address(r1, (link_area_words + _params + _locals++) * wordSize); +} +const ConditionRegister StackFrame::get_cr_field() +{ + assert(_state == done_nothing, "can't change layout after prolog written"); + assert(_crfs < max_crfs, "no more fields!"); + return as_ConditionRegister(4 - _crfs++); +} +const Register StackFrame::get_register() +{ + assert(_state == done_nothing, "can't change layout after prolog written"); + assert(_gprs < max_gprs, "no more registers!"); + return as_Register(31 - _gprs++); +} +const FloatRegister StackFrame::get_float_register() +{ + assert(_state == done_nothing, "can't change layout after prolog written"); + assert(_fprs < max_fprs, "no more registers!"); + return as_FloatRegister(31 - _fprs++); +} +void StackFrame::set_save_volatiles(bool value) +{ + assert(_state == done_nothing, "can't change layout after prolog written"); + _save_volatiles = value; +} + +int StackFrame::unaligned_size() +{ +#ifdef PPC32 + int crfs = _crfs ? 1 : 0; +#else + int crfs = 0; +#endif // PPC32 + + int params = _params; + if (params < min_params) + params = min_params; + + int vgprs = _save_volatiles ? num_vgprs : 0; + int vsprs = _save_volatiles ? num_vsprs : 0; + int vfprs = _save_volatiles ? num_vfprs * words_per_fpr : 0; + + return (link_area_words + + params + + _locals + + vgprs + + vsprs + + vfprs + + crfs + + _gprs + + _fprs * words_per_fpr) * wordSize; +} + +int StackFrame::start_of_locals() +{ + int params = _params; + if (params < min_params) + params = min_params; + + return (link_area_words + params) * wordSize; +} + +#define __ masm-> +void StackFrame::generate_prolog(MacroAssembler *masm) +{ + assert(_state == done_nothing, "invalid state"); + + // Calculate the aligned frame size + while (true) { + _frame_size = unaligned_size(); + if (_frame_size % 16 == 0) + break; + _locals++; + } + int offset = start_of_locals() / wordSize + _locals; + const Address r0_save = Address(r1, offset++ * wordSize); + + // Save the link register and create the new frame + if (_save_volatiles) { + __ store_update (r1, Address(r1, -_frame_size)); + __ store (r0, r0_save); + __ mflr (r0); + __ store (r0, Address(r1, _frame_size + lr_save_offset * wordSize)); + } + else { + __ mflr (r0); + __ store (r0, Address(r1, lr_save_offset * wordSize)); + __ store_update (r1, Address(r1, -_frame_size)); + } + + // Store the remaining volatile registers + if (_save_volatiles) { + for (int i = 3; i < 13; i++) { + __ store (as_Register(i), Address(r1, offset++ * wordSize)); + } + __ mfctr (r0); + __ store (r0, Address(r1, offset++ * wordSize)); + for (int i = 0; i < num_vfprs; i++) { + __ stfd (as_FloatRegister(i), Address(r1, offset * wordSize)); + offset += words_per_fpr; + } + } + + // Store the non-volatile registers + if (_crfs) { + __ mfcr (r0); +#ifdef PPC32 + __ store (r0, Address(r1, offset++ * wordSize)); +#else + __ store (r0, Address(r1, cr_save_offset * wordSize)); +#endif // PPC32 + } + for (int i = 32 - _gprs; i < 32; i++) { + __ store (as_Register(i), Address(r1, offset++ * wordSize)); + } + for (int i = 32 - _fprs; i < 32; i++) { + __ stfd (as_FloatRegister(i), Address(r1, offset * wordSize)); + offset += words_per_fpr; + } + + // Restore r0 before continuing + if (_save_volatiles) + __ load (r0, r0_save); + + _state = done_prolog; +} +void StackFrame::generate_epilog(MacroAssembler *masm) +{ + assert(_state != done_nothing, "invalid state"); + + int offset = start_of_locals() / wordSize + _locals; + const Address r0_save = Address(r1, offset++ * wordSize); + + // Restore the volatile registers except r0 + if (_save_volatiles) { + for (int i = 3; i < 13; i++) { + __ load (as_Register(i), Address(r1, offset++ * wordSize)); + } + __ load (r0, Address(r1, offset++ * wordSize)); + __ mtctr (r0); + for (int i = 0; i < num_vfprs; i++) { + __ lfd (as_FloatRegister(i), Address(r1, offset * wordSize)); + offset += words_per_fpr; + } + } + + // Restore the non-volatile registers + if (_crfs) { +#ifdef PPC32 + __ load (r0, Address(r1, offset++ * wordSize)); +#else + __ load (r0, Address(r1, cr_save_offset * wordSize)); +#endif // PPC32 + __ mtcr (r0); + } + for (int i = 32 - _gprs; i < 32; i++) { + __ load (as_Register(i), Address(r1, offset++ * wordSize)); + } + for (int i = 32 - _fprs; i < 32; i++) { + __ lfd (as_FloatRegister(i), Address(r1, offset * wordSize)); + offset += words_per_fpr; + } + + // Remove the frame and restore the link register + if (_save_volatiles) { + __ load (r0, Address(r1, _frame_size + lr_save_offset * wordSize)); + __ mtlr (r0); + __ load (r0, r0_save); + __ addi (r1, r1, _frame_size); + } + else { + __ addi (r1, r1, _frame_size); + __ load (r0, Address(r1, lr_save_offset * wordSize)); + __ mtlr (r0); + } + + _state = done_epilog; +} +#undef __ + +void MacroAssembler::align(int modulus) +{ + assert(!((offset() % modulus) & 3), "invalid alignment"); + while (offset() % modulus != 0) + nop(); +} + +// Non-standard mnemonics +void MacroAssembler::lbax(Register dst, Register a, Register b) +{ + lbzx(dst, a, b); + extsb(dst, dst); +} +void MacroAssembler::lhax(Register dst, Register a, Register b) +{ + // NB there actually is an actual lhax instruction but the + // manual mentions higher latency and gcc for one does not + // use it. + lhzx(dst, a, b); + extsh(dst, dst); +} +void MacroAssembler::lwa(Register dst, const Address& src) +{ + lwz(dst, src); +#ifdef PPC64 + extsw(dst, dst); +#endif +} +void MacroAssembler::lwax(Register dst, Register a, Register b) +{ + lwzx(dst, a, b); +#ifdef PPC64 + extsw(dst, dst); +#endif +} + +// Operations which are different on PPC32/64 + +void MacroAssembler::call(address func) +{ + assert(((intptr_t) func & 3) == 0, "invalid address"); + +#ifdef PPC32 + const Register reg = r0; +#else + const Register reg = r12; +#endif // PPC32 + + load(reg, (intptr_t) func); + call(reg); +} + +void MacroAssembler::call(Register func) +{ +#ifdef PPC64 + std(r2, Address(r1, 40)); + ld(r2, Address(func, 8)); + ld(r0, Address(func, 0)); + func = r0; +#endif // PPC64 + + mtlr(func); + blrl(); + +#ifdef PPC64 + ld (r2, Address(r1, 40)); +#endif // PPC64 +} + +void MacroAssembler::compare(Register a, int b) +{ + compare(cr0, a, b); +} + +void MacroAssembler::compare(Register a, Register b) +{ + compare(cr0, a, b); +} + +void MacroAssembler::compare(ConditionRegister dst, Register a, int b) +{ +#ifdef PPC32 + cmpwi(dst, a, b); +#else + cmpdi(dst, a, b); +#endif // PPC32 +} + +void MacroAssembler::compare(ConditionRegister dst, Register a, Register b) +{ +#ifdef PPC32 + cmpw(dst, a, b); +#else + cmpd(dst, a, b); +#endif // PPC32 +} + +address MacroAssembler::enter() +{ + address start = pc(); +#ifdef PPC64 + // Sneak in a function descriptor + // NB this is not relocatable! + emit_address(start + 16); + emit_address(NULL); +#endif // PPC64 + return start; +} + +void MacroAssembler::load(Register dst, long value) +{ +#ifdef PPC32 + int a = value >> 16; + int b = value & 0xffff; + + if (a) { + lis(dst, a); + if (b) + ori(dst, dst, b); + } + else { + li(dst, b); + } +#else + int a = (int)(value >> 48); + int b = (int)(value >> 32) & 0xffff; + int c = (int)(value >> 16) & 0xffff; + int d = (int) value & 0xffff; + + if (a) { + lis (dst, a); + if (b) + ori (dst, dst, b); + } + else if (b) { + li (dst, b); + } + if (a || b) + sldi (dst, dst, 32); + + if (c) { + if (a || b) + oris (dst, dst, c); + else + lis (dst, c); + if (d) + ori (dst, dst, d); + } + else if (d || !(a || b)) { + if (a || b) + ori (dst, dst, d); + else + li (dst, d); + } +#endif // PPC32 +} + +void MacroAssembler::load(Register dst, const Address& src) +{ +#ifdef PPC32 + lwz(dst, src); +#else + ld(dst, src); +#endif // PPC32 +} + +void MacroAssembler::load_and_reserve_indexed(Register dst, Register a, + Register b) { +#ifdef PPC32 + lwarx(dst, a, b); +#else + ldarx(dst, a, b); +#endif // PPC32 +} + +void MacroAssembler::load_indexed(Register dst, Register a, Register b) +{ +#ifdef PPC32 + lwzx(dst, a, b); +#else + ldx(dst, a, b); +#endif // PPC32 +} + +void MacroAssembler::shift_left(Register dst, Register a, int b) +{ +#ifdef PPC32 + slwi(dst, a, b); +#else + sldi(dst, a, b); +#endif // PPC32 +} + +void MacroAssembler::shift_right(Register dst, Register a, int b) +{ +#ifdef PPC32 + srwi(dst, a, b); +#else + srdi(dst, a, b); +#endif // PPC32 +} + +void MacroAssembler::store(Register src, const Address& dst) +{ +#ifdef PPC32 + stw(src, dst); +#else + std(src, dst); +#endif // PPC32 +} + +void MacroAssembler::store_conditional_indexed(Register src, Register a, + Register b) { +#ifdef PPC32 + stwcx_(src, a, b); +#else + stdcx_(src, a, b); +#endif // PPC32 +} + +void MacroAssembler::store_indexed(Register src, Register a, Register b) +{ +#ifdef PPC32 + stwx(src, a, b); +#else + stdx(src, a, b); +#endif // PPC32 +} + +void MacroAssembler::store_update(Register src, const Address& dst) +{ +#ifdef PPC32 + stwu(src, dst); +#else + stdu(src, dst); +#endif // PPC32 +} + +void MacroAssembler::store_update_indexed(Register src, Register a, Register b) +{ +#ifdef PPC32 + stwux(src, a, b); +#else + stdux(src, a, b); +#endif // PPC32 +} + +// Atomic compare and exchange +// +// if (*dst == comp) +// *dst = exchange +// +// Returns: +// cr0 is set to reflect whether the store was performed + +void MacroAssembler::cmpxchg_(Register exchange, Register dst, Register comp) +{ + assert_different_registers(exchange, dst, comp, r0); + + Label loop, done; + + sync(); + bind(loop); + load_and_reserve_indexed(r0, 0, dst); + compare(r0, comp); + bne(done); + store_conditional_indexed(exchange, 0, dst); + bne(loop); + isync(); + bind(done); +} + +void MacroAssembler::set_last_Java_frame() +{ + Label label; + + bl(label); + bind(label); + mflr(r0); + store(r0, Address(Rthread, JavaThread::last_Java_pc_offset())); + store(r1, Address(Rthread, JavaThread::last_Java_sp_offset())); +} + +void MacroAssembler::reset_last_Java_frame() +{ + load(r0, 0); + store(r0, Address(Rthread, JavaThread::last_Java_sp_offset())); +} + +// Write serialization page so VM thread can do a pseudo remote membar. +void MacroAssembler::serialize_memory(Register tmp1, Register tmp2) +{ + // We use the current thread pointer to calculate a thread specific + // offset to write to within the page. This minimizes bus traffic + // due to cache line collision. + shift_right(tmp1, Rthread, os::get_serialize_page_shift_count()); + andi_(tmp1, tmp1, os::vm_page_size() - sizeof(int)); + load(tmp2, (intptr_t) os::get_memory_serialize_page()); + stwx(tmp1, tmp2, tmp1); +} + +void MacroAssembler::calc_padding_for_alignment( + Register dst, Register src, int align) { +#ifdef ASSERT + { + int tmp = align; + while (!(tmp & 1)) + tmp >>= 1; + assert (tmp == 1, "alignment must be a power of two"); + } +#endif // ASSERT + andi_(dst, src, align - 1); + subfic(dst, dst, align); + andi_(dst, dst, align - 1); +} + +void MacroAssembler::maybe_extend_frame( + Register required_bytes, Register available_bytes) +{ + Label done; + + // Check whether we have enough space already + compare(required_bytes, available_bytes); + ble(done); + + // Calculate how many extra bytes we need to allocate + const Register extra_bytes = required_bytes; + const Register padding = available_bytes; + + sub(extra_bytes, required_bytes, available_bytes); + calc_padding_for_alignment(padding, extra_bytes, 16); + add(extra_bytes, extra_bytes, padding); + + // Extend the frame + const Register saved_r1 = padding; + const Register scratch = extra_bytes; + + mr(saved_r1, r1); + neg(scratch, extra_bytes); + store_update_indexed(r1, r1, scratch); + load(scratch, Address(saved_r1, StackFrame::back_chain_offset * wordSize)); + store(scratch, Address(r1, StackFrame::back_chain_offset * wordSize)); +#ifdef PPC64 + load(scratch, Address(saved_r1, StackFrame::cr_save_offset * wordSize)); + store(scratch, Address(r1, StackFrame::cr_save_offset * wordSize)); +#endif + + bind (done); +} + +void MacroAssembler::get_mirror_handle(Register dst) +{ + load(dst, Address(Rmethod, methodOopDesc::constants_offset())); + load(dst, Address(dst, constantPoolOopDesc::pool_holder_offset_in_bytes())); + load(dst, Address(dst, klassOopDesc::klass_part_offset_in_bytes() + + Klass::java_mirror_offset_in_bytes())); +} + +void MacroAssembler::report_and_die(address function, + const char* file, int line, + const char* message) { + load(r3, (intptr_t) file); + load(r4, line); + if (message) + load(r5, (intptr_t) message); + call(function); +} + +void MacroAssembler::should_not_reach_here(const char* file, int line) +{ + report_and_die( + CAST_FROM_FN_PTR(address, report_should_not_reach_here), file, line); +} +void MacroAssembler::unimplemented(const char* file, int line) +{ + report_and_die( + CAST_FROM_FN_PTR(address, report_unimplemented), file, line); +} +void MacroAssembler::untested(const char* file, int line, const char* message) +{ + report_and_die( + CAST_FROM_FN_PTR(address, report_untested), file, line, message); +} + + +address MacroAssembler::generate_unimplemented_stub(const char* file, int line) +{ + address start = enter(); + StackFrame frame; + prolog(frame); + unimplemented(file, line); + epilog(frame); + blr(); + return start; +} +address MacroAssembler::generate_unimplemented_entry(const char* file,int line) +{ + address start = pc(); + StackFrame frame; + prolog(frame); + unimplemented(file, line); + epilog(frame); + blr(); + return start; +} + +#ifndef PRODUCT +static void dump_int_helper(const char* prefix, long src) +{ + ttyLocker ttyl; + ResourceMark rm; + + if (abs(src) < 1000000) +#ifdef PPC64 + tty->print_cr("%s = %ld", prefix, src); +#else + tty->print_cr("%s = %d", prefix, src); +#endif // PPC64 + else + tty->print_cr("%s = %p", prefix, src); +} + +void MacroAssembler::dump_int(Register src) +{ + dump_int(src->name(), src); +} + +void MacroAssembler::dump_int(const char* prefix, Register src) +{ + StackFrame frame; + frame.set_save_volatiles(true); + prolog(frame); + if (src == r1) { + int framesize = frame.unaligned_size(); + framesize += (16 - (framesize & 15)) & 15; + addi(r4, r1, framesize); + } + else if (src != r4) { + mr(r4, src); + } + load(r3, (intptr_t) prefix); + call(CAST_FROM_FN_PTR(address, dump_int_helper)); + epilog(frame); +} +#endif // PRODUCT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,398 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// The definitions needed for ppc assembly code generation. + +// Non-volatile registers used by the interpreter + +REGISTER_DECLARATION(Register, Rmethod, r31); +REGISTER_DECLARATION(Register, Rlocals, r30); +REGISTER_DECLARATION(Register, Rthread, r29); +#ifdef CC_INTERP +REGISTER_DECLARATION(Register, Rstate, r28); +#endif // CC_INTERP + + +// Address is an abstraction used to represent a memory location + +class Address { + private: + const Register _base; + const int16_t _displacement; + + public: + Address(const Register base, int16_t displacement) + : _base(base), + _displacement(displacement) + { + assert(base != r0, "can't use r0 for addressing"); + } + +#ifdef ASSERT + Address(Register base, ByteSize displacement) + : _base(base), + _displacement(in_bytes(displacement)) {} +#endif // ASSERT + + const Register base() const { return _base; } + int displacement() const { return (int) _displacement & 0xffff; } +}; + + +// The ppc Assembler: Pure assembler doing NO optimizations on +// the instruction level; i.e., what you write is what you get. +// The Assembler is generating code into a CodeBuffer. + +class Assembler : public AbstractAssembler { + public: + Assembler(CodeBuffer* code) : AbstractAssembler(code) {} + + private: + // Instruction emitters for the various forms. + // Every instruction should ultimately come through one of these. + void emit_instruction(int opcode, int li, bool aa, bool lk); + void emit_instruction(int opcode, int bo, int bi, int bd, bool aa, bool lk); + void emit_instruction(int opcode, int a, int b, int c); + void emit_instruction(int opcode, int a, int b, int c, int d); + void emit_instruction(int opcode, int a, int b, int c, int xo, bool rc); + void emit_instruction(int opcode, int a, int b, int c, int d, int e,bool rc); + + // Wrappers for the instruction emitters. + // These handle casting and stuff. + void emit_instruction(int opcode, Register a, Register b, int c); + void emit_instruction(int opcode, Register a, Register b, int c, int d); + void emit_instruction(int opcode, FloatRegister a, Register b, int c); + void emit_instruction(int opcode, Register a, const Address& b); + void emit_instruction(int opcode, Register a, const Address& b, int c); + void emit_instruction(int opcode, FloatRegister a, const Address& b); + void emit_instruction(int opcode, Register a, int b, int c, int xo, + bool rc); + void emit_instruction(int opcode, Register a, Register b, Register c, + int xo, bool rc); + void emit_instruction(int opcode, Register a, SpecialPurposeRegister b, + int c, int xo, bool rc); + void emit_instruction(int opcode, SpecialPurposeRegister a, Register b, + int c, int xo, bool rc); + void emit_instruction(int opcode, Register a, Register b, int c, int d, + int e, bool rc); + void emit_instruction(int opcode, int a, Register b, Register c, int d, + bool rc); + void emit_instruction(int opcode, ConditionRegister a, bool l, + Register b, Register c, int d, bool rc); + void emit_instruction(int opcode, ConditionRegister a, bool l, + Register b, int c); + void emit_instruction(int opcode, FloatRegister a, int b, + FloatRegister c, int xo, bool rc); + + // Helper for computing branch targets + intptr_t branch_target(address branch, address target, int bits); + + public: + // Instructions common to 32- and 64-bit implementations + void add(Register dst, Register a, Register b); + void addi(Register dst, Register a, int b); + void addis(Register dst, Register a, int b); + void andi_(Register dst, Register a, int b); + void b(address a); + void bc(int bo, int bi, address a); + void bclr(int bo, int bi); + void bclrl(int bo, int bi); + void bl(address a); + void cmp(ConditionRegister dst, bool l, Register a, Register b); + void cmpi(ConditionRegister dst, bool l, Register a, int b); + void dcbf(Register a, Register b); + void extsb(Register dst, Register src); + void extsh(Register dst, Register src); + void fmr(FloatRegister dst, FloatRegister src); + void icbi(Register a, Register b); + void isync(); + void lbzx(Register dst, Register a, Register b); + void lfd(FloatRegister dst, const Address& src); + void lfs(FloatRegister dst, const Address& src); + void lhz(Register dst, const Address& src); + void lhzx(Register dst, Register a, Register b); + void lwarx(Register dst, Register a, Register b); + void lwz(Register dst, const Address& src); + void lwzx(Register dst, Register a, Register b); + void mfcr(Register dst); + void mfspr(Register dst, SpecialPurposeRegister src); + void mtcrf(int mask, Register src); + void mtspr(SpecialPurposeRegister dst, Register src); + void neg(Register dst, Register src); + void OR(Register dst, Register a, Register b); + void ori(Register dst, Register a, int b); + void oris(Register dst, Register a, int b); + void rlwinm(Register dst, Register a, int b, int mb, int me); + void stfd(FloatRegister src, const Address& dst); + void stfs(FloatRegister src, const Address& dst); + void stw(Register src, const Address& dst); + void stwcx_(Register src, Register a, Register b); + void stwu(Register src, const Address& dst); + void stwux(Register src, Register a, Register b); + void stwx(Register src, Register a, Register b); + void subf(Register dst, Register a, Register b); + void subfic(Register dst, Register a, int b); + void sync(); + + // Instructions for 64-bit implementations only +#ifdef PPC64 + void extsw(Register dst, Register src); + void ld(Register dst, const Address& src); + void ldarx(Register dst, Register a, Register b); + void ldx(Register dst, Register a, Register b); + void std(Register src, const Address& dst); + void stdcx_(Register src, Register a, Register b); + void stdu(Register src, const Address& dst); + void stdux(Register src, Register a, Register b); + void stdx(Register src, Register a, Register b); + void rldicl(Register dst, Register a, int sh, int mb); + void rldicr(Register dst, Register a, int sh, int me); +#endif // PPC64 + + // Standard mnemonics common to 32- and 64-bit implementations + void bdnz(Label& l); + void beq(Label& l); + void beqlr(); + void bge(Label& l); + void bgt(Label& l); + void ble(Label& l); + void blelr(); + void blr(); + void blrl(); + void blt(Label& l); + void bne(Label& l); + void bne(ConditionRegister r, Label& l); + void cmpw(ConditionRegister dst, Register a, Register b); + void cmpwi(ConditionRegister dst, Register a, int b); + void la(Register dst, Address value); + void li(Register dst, int value); + void lis(Register dst, int value); + void mr(Register dst, Register src); + void mfctr(Register dst); + void mflr(Register dst); + void mtcr(Register src); + void mtctr(Register src); + void mtlr(Register src); + void nop(); + void slwi(Register dst, Register a, int b); + void srwi(Register dst, Register a, int b); + void sub(Register dst, Register a, Register b); + void subi(Register dst, Register a, int b); + + // Standard mnemonics for 64-bit implementations only +#ifdef PPC64 + void cmpd(ConditionRegister dst, Register a, Register b); + void cmpdi(ConditionRegister dst, Register a, int b); + void sldi(Register dst, Register a, int b); + void srdi(Register dst, Register a, int b); +#endif // PPC64 + + // Wrappers for branch instructions + void b(Label& l); + void bc(int bo, int bi, Label& l); + void bl(Label& l); + + // Function to fix up forward branches + void pd_patch_instruction(address branch, address target); +#ifndef PRODUCT + static void pd_print_patched_instruction(address branch); +#endif // PRODUCT + + // Disassemble a region of memory to stdout +#ifndef PRODUCT + static void disassemble(const char *what, address start, address end); +#endif // PRODUCT +}; + + +// StackFrame is used to generate prologs and epilogs + +class StackFrame { + private: + int _params; + int _locals; + int _crfs; + int _gprs; + int _fprs; + + enum State { + done_nothing, + done_prolog, + done_epilog + }; + State _state; + + int _frame_size; + + bool _save_volatiles; + + public: + enum LinkArea { + back_chain_offset, +#ifdef PPC64 + cr_save_offset, +#endif // PPC64 + lr_save_offset, +#ifdef PPC64 + reserved_1, + reserved_2, + saved_toc_offset, +#endif // PPC64 + link_area_words + }; + + enum Constants { +#ifdef PPC32 + min_params = 0, +#else + min_params = 8, +#endif // PPC32 + max_gprs = 18, // r14-r31 + max_fprs = 18, // f14-f31 + max_crfs = 3, // cr2-cr4 + num_vgprs = 11, // r0 and r3-r12 + num_vsprs = 1, // ctr + num_vfprs = 14, // f0-f13 + + words_per_fpr = 8 / wordSize + }; + + public: + StackFrame() + : _params(0), + _locals(0), + _crfs(0), + _gprs(0), + _fprs(0), + _state(done_nothing), + _save_volatiles(false) {} + +#ifdef ASSERT + ~StackFrame() { assert(_state != done_prolog, "stack not restored"); } +#endif // ASSERT + + const Address get_parameter(); + const Address get_local_variable(); + const ConditionRegister get_cr_field(); + const Register get_register(); + const FloatRegister get_float_register(); + + protected: + void generate_prolog(MacroAssembler *masm); + void generate_epilog(MacroAssembler *masm); + + void set_save_volatiles(bool value); + + friend class MacroAssembler; + + public: + int unaligned_size(); + int start_of_locals(); +}; + + +// MacroAssembler extends Assembler by frequently used macros. +// +// Instructions for which a 'better' code sequence exists depending +// on arguments should also go in here. + +class MacroAssembler : public Assembler { + public: + MacroAssembler(CodeBuffer* code) : Assembler(code) {} + + void align(int modulus); + + void prolog(StackFrame& frame) { frame.generate_prolog(this); } + void epilog(StackFrame& frame) { frame.generate_epilog(this); } + + // Non-standard mnemonics + void lbax(Register dst, Register a, Register b); + void lhax(Register dst, Register a, Register b); + void lwa(Register dst, const Address& src); + void lwax(Register dst, Register a, Register b); + + // Operations which are different on PPC32/64 + void call(address addr); + void call(Register addr); + void compare(Register a, int b); + void compare(Register a, Register b); + void compare(ConditionRegister dst, Register a, int b); + void compare(ConditionRegister dst, Register a, Register b); + address enter(); + void load(Register dst, long value); + void load(Register dst, const Address& src); + void load_and_reserve_indexed(Register dst, Register a, Register b); + void load_indexed(Register dst, Register a, Register b); + void shift_left(Register dst, Register a, int b); + void shift_right(Register dst, Register a, int b); + void store(Register src, const Address& dst); + void store_conditional_indexed(Register dst, Register a, Register b); + void store_indexed(Register src, Register a, Register b); + void store_update(Register src, const Address& dst); + void store_update_indexed(Register src, Register a, Register b); + + void cmpxchg_(Register exchange, Register dst, Register compare); + + void set_last_Java_frame(); + void reset_last_Java_frame(); + + void serialize_memory(Register tmp1, Register tmp2); + + void calc_padding_for_alignment(Register dst, Register src, int align); + void maybe_extend_frame(Register required_bytes, Register available_bytes); + void get_mirror_handle(Register dst); + + private: + void report_and_die(address function, + const char* file, int line, + const char* message = NULL); + + public: + void should_not_reach_here(const char* file, int line); + void unimplemented(const char* file, int line); + void untested(const char* file, int line, const char* message); + + address generate_unimplemented_stub(const char* file, int line); + address generate_unimplemented_entry(const char* file, int line); + +#ifndef PRODUCT + void dump_int(Register src); + void dump_int(const char* prefix, Register src); +#endif // PRODUCT + + void bang_stack_with_offset(int offset) + { + Unimplemented(); + } +}; + +#ifdef ASSERT +inline bool AbstractAssembler::pd_check_instruction_mark() { Unimplemented(); } +#endif + +#define UnimplementedStub() \ + (__ generate_unimplemented_stub(__FILE__, __LINE__)) +#define UnimplementedEntry() \ + (__ generate_unimplemented_entry(__FILE__, __LINE__))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/bytecodeInterpreter_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,98 @@ +/* + * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Platform specific for C++ based Interpreter +#define LOTS_OF_REGS // Use plenty of registers + + private: + interpreterState _self_link; + + public: + static ByteSize stack_limit_offset() + { + return byte_offset_of(BytecodeInterpreter, _stack_limit); + } + +// The frame manager handles this +#define SET_LAST_JAVA_FRAME() +#define RESET_LAST_JAVA_FRAME() + +/* + * Macros for accessing the stack. + */ +#undef STACK_INT +#undef STACK_FLOAT +#undef STACK_ADDR +#undef STACK_OBJECT +#undef STACK_DOUBLE +#undef STACK_LONG + +// JavaStack Implementation + +#define GET_STACK_SLOT(offset) (*((intptr_t*) &topOfStack[-(offset)])) +#define STACK_SLOT(offset) ((address) &topOfStack[-(offset)]) +#define STACK_ADDR(offset) (*((address *) &topOfStack[-(offset)])) +#define STACK_INT(offset) (*((jint*) &topOfStack[-(offset)])) +#define STACK_FLOAT(offset) (*((jfloat *) &topOfStack[-(offset)])) +#define STACK_OBJECT(offset) (*((oop *) &topOfStack [-(offset)])) +#define STACK_DOUBLE(offset) (((VMJavaVal64*) &topOfStack[-(offset)])->d) +#define STACK_LONG(offset) (((VMJavaVal64 *) &topOfStack[-(offset)])->l) + +#define SET_STACK_SLOT(value, offset) (*(intptr_t*)&topOfStack[-(offset)] = *(intptr_t*)(value)) +#define SET_STACK_ADDR(value, offset) (*((address *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_INT(value, offset) (*((jint *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_FLOAT(value, offset) (*((jfloat *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_OBJECT(value, offset) (*((oop *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_DOUBLE(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = (value)) +#define SET_STACK_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = \ + ((VMJavaVal64*)(addr))->d) +#define SET_STACK_LONG(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = (value)) +#define SET_STACK_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = \ + ((VMJavaVal64*)(addr))->l) +// JavaLocals implementation + +#define LOCALS_SLOT(offset) ((intptr_t*)&locals[-(offset)]) +#define LOCALS_ADDR(offset) ((address)locals[-(offset)]) +#define LOCALS_INT(offset) (*((jint*)&locals[-(offset)])) +#define LOCALS_FLOAT(offset) (*((jfloat*)&locals[-(offset)])) +#define LOCALS_OBJECT(offset) ((oop)locals[-(offset)]) +#define LOCALS_DOUBLE(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->d) +#define LOCALS_LONG(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->l) +#define LOCALS_LONG_AT(offset) (((address)&locals[-((offset) + 1)])) +#define LOCALS_DOUBLE_AT(offset) (((address)&locals[-((offset) + 1)])) + +#define SET_LOCALS_SLOT(value, offset) (*(intptr_t*)&locals[-(offset)] = *(intptr_t *)(value)) +#define SET_LOCALS_ADDR(value, offset) (*((address *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_INT(value, offset) (*((jint *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_FLOAT(value, offset) (*((jfloat *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_OBJECT(value, offset) (*((oop *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_DOUBLE(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = (value)) +#define SET_LOCALS_LONG(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = (value)) +#define SET_LOCALS_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = \ + ((VMJavaVal64*)(addr))->d) +#define SET_LOCALS_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = \ + ((VMJavaVal64*)(addr))->l) + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/bytecodeInterpreter_ppc.inline.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,281 @@ +/* + * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Inline interpreter functions for ppc + +inline jfloat BytecodeInterpreter::VMfloatAdd(jfloat op1, jfloat op2) { return op1 + op2; } +inline jfloat BytecodeInterpreter::VMfloatSub(jfloat op1, jfloat op2) { return op1 - op2; } +inline jfloat BytecodeInterpreter::VMfloatMul(jfloat op1, jfloat op2) { return op1 * op2; } +inline jfloat BytecodeInterpreter::VMfloatDiv(jfloat op1, jfloat op2) { return op1 / op2; } +inline jfloat BytecodeInterpreter::VMfloatRem(jfloat op1, jfloat op2) { return fmod(op1, op2); } + +inline jfloat BytecodeInterpreter::VMfloatNeg(jfloat op) { return -op; } + +inline int32_t BytecodeInterpreter::VMfloatCompare(jfloat op1, jfloat op2, int32_t direction) { + return ( op1 < op2 ? -1 : + op1 > op2 ? 1 : + op1 == op2 ? 0 : + (direction == -1 || direction == 1) ? direction : 0); + +} + +inline void BytecodeInterpreter::VMmemCopy64(uint32_t to[2], const uint32_t from[2]) { + // x86 can do unaligned copies but not 64bits at a time + to[0] = from[0]; to[1] = from[1]; +} + +// The long operations depend on compiler support for "long long" on x86 + +inline jlong BytecodeInterpreter::VMlongAdd(jlong op1, jlong op2) { + return op1 + op2; +} + +inline jlong BytecodeInterpreter::VMlongAnd(jlong op1, jlong op2) { + return op1 & op2; +} + +inline jlong BytecodeInterpreter::VMlongDiv(jlong op1, jlong op2) { + // QQQ what about check and throw... + return op1 / op2; +} + +inline jlong BytecodeInterpreter::VMlongMul(jlong op1, jlong op2) { + return op1 * op2; +} + +inline jlong BytecodeInterpreter::VMlongOr(jlong op1, jlong op2) { + return op1 | op2; +} + +inline jlong BytecodeInterpreter::VMlongSub(jlong op1, jlong op2) { + return op1 - op2; +} + +inline jlong BytecodeInterpreter::VMlongXor(jlong op1, jlong op2) { + return op1 ^ op2; +} + +inline jlong BytecodeInterpreter::VMlongRem(jlong op1, jlong op2) { + return op1 % op2; +} + +inline jlong BytecodeInterpreter::VMlongUshr(jlong op1, jint op2) { + // CVM did this 0x3f mask, is the really needed??? QQQ + return ((unsigned long long) op1) >> (op2 & 0x3F); +} + +inline jlong BytecodeInterpreter::VMlongShr(jlong op1, jint op2) { + return op1 >> (op2 & 0x3F); +} + +inline jlong BytecodeInterpreter::VMlongShl(jlong op1, jint op2) { + return op1 << (op2 & 0x3F); +} + +inline jlong BytecodeInterpreter::VMlongNeg(jlong op) { + return -op; +} + +inline jlong BytecodeInterpreter::VMlongNot(jlong op) { + return ~op; +} + +inline int32_t BytecodeInterpreter::VMlongLtz(jlong op) { + return (op <= 0); +} + +inline int32_t BytecodeInterpreter::VMlongGez(jlong op) { + return (op >= 0); +} + +inline int32_t BytecodeInterpreter::VMlongEqz(jlong op) { + return (op == 0); +} + +inline int32_t BytecodeInterpreter::VMlongEq(jlong op1, jlong op2) { + return (op1 == op2); +} + +inline int32_t BytecodeInterpreter::VMlongNe(jlong op1, jlong op2) { + return (op1 != op2); +} + +inline int32_t BytecodeInterpreter::VMlongGe(jlong op1, jlong op2) { + return (op1 >= op2); +} + +inline int32_t BytecodeInterpreter::VMlongLe(jlong op1, jlong op2) { + return (op1 <= op2); +} + +inline int32_t BytecodeInterpreter::VMlongLt(jlong op1, jlong op2) { + return (op1 < op2); +} + +inline int32_t BytecodeInterpreter::VMlongGt(jlong op1, jlong op2) { + return (op1 > op2); +} + +inline int32_t BytecodeInterpreter::VMlongCompare(jlong op1, jlong op2) { + return (VMlongLt(op1, op2) ? -1 : VMlongGt(op1, op2) ? 1 : 0); +} + +// Long conversions + +inline jdouble BytecodeInterpreter::VMlong2Double(jlong val) { + return (jdouble) val; +} + +inline jfloat BytecodeInterpreter::VMlong2Float(jlong val) { + return (jfloat) val; +} + +inline jint BytecodeInterpreter::VMlong2Int(jlong val) { + return (jint) val; +} + +// Double Arithmetic + +inline jdouble BytecodeInterpreter::VMdoubleAdd(jdouble op1, jdouble op2) { + return op1 + op2; +} + +inline jdouble BytecodeInterpreter::VMdoubleDiv(jdouble op1, jdouble op2) { + // Divide by zero... QQQ + return op1 / op2; +} + +inline jdouble BytecodeInterpreter::VMdoubleMul(jdouble op1, jdouble op2) { + return op1 * op2; +} + +inline jdouble BytecodeInterpreter::VMdoubleNeg(jdouble op) { + return -op; +} + +inline jdouble BytecodeInterpreter::VMdoubleRem(jdouble op1, jdouble op2) { + return fmod(op1, op2); +} + +inline jdouble BytecodeInterpreter::VMdoubleSub(jdouble op1, jdouble op2) { + return op1 - op2; +} + +inline int32_t BytecodeInterpreter::VMdoubleCompare(jdouble op1, jdouble op2, int32_t direction) { + return ( op1 < op2 ? -1 : + op1 > op2 ? 1 : + op1 == op2 ? 0 : + (direction == -1 || direction == 1) ? direction : 0); +} + +// Double Conversions + +inline jfloat BytecodeInterpreter::VMdouble2Float(jdouble val) { + return (jfloat) val; +} + +// Float Conversions + +inline jdouble BytecodeInterpreter::VMfloat2Double(jfloat op) { + return (jdouble) op; +} + +// Integer Arithmetic + +inline jint BytecodeInterpreter::VMintAdd(jint op1, jint op2) { + return op1 + op2; +} + +inline jint BytecodeInterpreter::VMintAnd(jint op1, jint op2) { + return op1 & op2; +} + +inline jint BytecodeInterpreter::VMintDiv(jint op1, jint op2) { + /* it's possible we could catch this special case implicitly */ + if (op1 == (jint) 0x80000000 && op2 == -1) return op1; + else return op1 / op2; +} + +inline jint BytecodeInterpreter::VMintMul(jint op1, jint op2) { + return op1 * op2; +} + +inline jint BytecodeInterpreter::VMintNeg(jint op) { + return -op; +} + +inline jint BytecodeInterpreter::VMintOr(jint op1, jint op2) { + return op1 | op2; +} + +inline jint BytecodeInterpreter::VMintRem(jint op1, jint op2) { + /* it's possible we could catch this special case implicitly */ + if (op1 == (jint) 0x80000000 && op2 == -1) return 0; + else return op1 % op2; +} + +inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) { + return op1 << op2; +} + +inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) { + return op1 >> op2; // QQ op2 & 0x1f?? +} + +inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) { + return op1 - op2; +} + +inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) { + return ((juint) op1) >> op2; // QQ op2 & 0x1f?? +} + +inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) { + return op1 ^ op2; +} + +inline jdouble BytecodeInterpreter::VMint2Double(jint val) { + return (jdouble) val; +} + +inline jfloat BytecodeInterpreter::VMint2Float(jint val) { + return (jfloat) val; +} + +inline jlong BytecodeInterpreter::VMint2Long(jint val) { + return (jlong) val; +} + +inline jchar BytecodeInterpreter::VMint2Char(jint val) { + return (jchar) val; +} + +inline jshort BytecodeInterpreter::VMint2Short(jint val) { + return (jshort) val; +} + +inline jbyte BytecodeInterpreter::VMint2Byte(jint val) { + return (jbyte) val; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/bytecodes_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,32 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_bytecodes_ppc.cpp.incl" + +void Bytecodes::pd_initialize() +{ + // No ppc specific initialization +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/bytecodes_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,25 @@ +/* + * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// No ppc specific bytecodes
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/bytes_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,168 @@ +/* + * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class Bytes: AllStatic { + public: + // Returns true if the byte ordering used by Java is different from + // the native byte ordering of the underlying machine. For example, + // this is true for Intel x86, but false for Solaris on Sparc. + static inline bool is_Java_byte_ordering_different() + { + return false; + } + + // Efficient reading and writing of unaligned unsigned data in + // platform-specific byte ordering. + static inline u2 get_native_u2(address p){ + return (intptr_t(p) & 1) == 0 + ? *(u2*)p + : ( u2(p[0]) << 8 ) + | ( u2(p[1]) ); + } + + static inline u4 get_native_u4(address p) { + switch (intptr_t(p) & 3) { + case 0: return *(u4*)p; + + case 2: return ( u4( ((u2*)p)[0] ) << 16 ) + | ( u4( ((u2*)p)[1] ) ); + + default: return ( u4(p[0]) << 24 ) + | ( u4(p[1]) << 16 ) + | ( u4(p[2]) << 8 ) + | u4(p[3]); + } + } + + static inline u8 get_native_u8(address p) { + switch (intptr_t(p) & 7) { + case 0: return *(u8*)p; + + case 4: return ( u8( ((u4*)p)[0] ) << 32 ) + | ( u8( ((u4*)p)[1] ) ); + + case 2: return ( u8( ((u2*)p)[0] ) << 48 ) + | ( u8( ((u2*)p)[1] ) << 32 ) + | ( u8( ((u2*)p)[2] ) << 16 ) + | ( u8( ((u2*)p)[3] ) ); + + default: return ( u8(p[0]) << 56 ) + | ( u8(p[1]) << 48 ) + | ( u8(p[2]) << 40 ) + | ( u8(p[3]) << 32 ) + | ( u8(p[4]) << 24 ) + | ( u8(p[5]) << 16 ) + | ( u8(p[6]) << 8 ) + | u8(p[7]); + } + } + + static inline void put_native_u2(address p, u2 x) { + if ( (intptr_t(p) & 1) == 0 ) *(u2*)p = x; + else { + p[0] = x >> 8; + p[1] = 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)[0] = x >> 16; + ((u2*)p)[1] = x; + break; + + default: ((u1*)p)[0] = x >> 24; + ((u1*)p)[1] = x >> 16; + ((u1*)p)[2] = x >> 8; + ((u1*)p)[3] = 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)[0] = x >> 32; + ((u4*)p)[1] = x; + break; + + case 2: ((u2*)p)[0] = x >> 48; + ((u2*)p)[1] = x >> 32; + ((u2*)p)[2] = x >> 16; + ((u2*)p)[3] = x; + break; + + default: ((u1*)p)[0] = x >> 56; + ((u1*)p)[1] = x >> 48; + ((u1*)p)[2] = x >> 40; + ((u1*)p)[3] = x >> 32; + ((u1*)p)[4] = x >> 24; + ((u1*)p)[5] = x >> 16; + ((u1*)p)[6] = x >> 8; + ((u1*)p)[7] = 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 ppc CPUs use big-endian format. + 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); + } + static inline u8 get_Java_u8(address p) + { + return get_native_u8(p); + } + + 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); + } + + // 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; } +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/codeBuffer_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,27 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +private: + void pd_initialize() {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/copy_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,166 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Inline functions for memory copy and fill. + +static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) { + (void)memmove(to, from, count * HeapWordSize); +} + +static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) { + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: + (void)memcpy(to, from, count * HeapWordSize); + break; + } +} + +static void pd_disjoint_words_atomic(HeapWord* from, + HeapWord* to, + size_t count) { + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: + while (count-- > 0) { + *to++ = *from++; + } + break; + } +} + +static void pd_aligned_conjoint_words(HeapWord* from, + HeapWord* to, + size_t count) { + (void)memmove(to, from, count * HeapWordSize); +} + +static void pd_aligned_disjoint_words(HeapWord* from, + HeapWord* to, + size_t count) { + pd_disjoint_words(from, to, count); +} + +static void pd_conjoint_bytes(void* from, void* to, size_t count) { + (void)memmove(to, from, count); +} + +static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) { + (void)memmove(to, from, count); +} + +static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) { + _Copy_conjoint_jshorts_atomic(from, to, count); +} + +static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) { + _Copy_conjoint_jints_atomic(from, to, count); +} + +static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) { + _Copy_conjoint_jlongs_atomic(from, to, count); +} + +static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) { +#ifdef PPC64 + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count); +#else + assert(BytesPerInt == BytesPerOop, "jints and oops must be the same size"); + _Copy_conjoint_jints_atomic((jint*)from, (jint*)to, count); +#endif // PPC64 +} + +static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_bytes(from, to, count); +} + +static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jshorts(from, to, count); +} + +static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jints(from, to, count); +} + +static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jlongs(from, to, count); +} + +static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) { +#ifdef PPC64 + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_arrayof_conjoint_jlongs(from, to, count); +#else + assert(BytesPerInt == BytesPerOop, "jints and oops must be the same size"); + _Copy_arrayof_conjoint_jints(from, to, count); +#endif // PPC64 +} + +static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) { +#ifdef PPC64 + julong* to = (julong*) tohw; + julong v = ((julong) value << 32) | value; +#else + juint* to = (juint*) tohw; + juint v = value; +#endif // PPC64 + + while (count-- > 0) { + *to++ = v; + } +} + +static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) { + pd_fill_to_words(tohw, count, value); +} + +static void pd_fill_to_bytes(void* to, size_t count, jubyte value) { + (void)memset(to, value, count); +} + +static void pd_zero_to_words(HeapWord* tohw, size_t count) { + pd_fill_to_words(tohw, count, 0); +} + +static void pd_zero_to_bytes(void* to, size_t count) { + (void)memset(to, 0, count); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/cppInterpreterGenerator_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + void generate_adjust_callers_stack(); + void generate_compute_interpreter_state(bool native); + void generate_more_monitors(); + void generate_convert_result(address* converter_array); + void generate_unwind_interpreter_state();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,1380 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_cppInterpreter_ppc.cpp.incl" + +#ifdef CC_INTERP + +// The address of this function is stored in the LR save area +// while we are recursed in the frame manager/C++ interpreter. +// We could use an address in the frame manager but having it +// this way makes things look nicer in the debugger and catches +// us if we attempt to "return" from a re-dispatched frame. +extern "C" void RecursiveInterpreterActivation(interpreterState istate) +{ + ShouldNotReachHere(); +} + +#define __ _masm-> +#define STATE(field_name) \ + (Address(Rstate, byte_offset_of(BytecodeInterpreter, field_name))) + +// Non-volatile registers we use +const Register Rmonitor = r27; +const ConditionRegister CRsync = cr2; +const ConditionRegister CRstatic = cr3; + +// slop_factor is two extra slots on the expression stack so +// that we always have room to store a result when returning +// from a call without parameters that returns a result. +// This is the "static long no_params() method" issue. It +// may not be needed for native calls -- it may not be needed +// at all -- but if it is needed then it's going to start +// writing all over the link area on PPC32 at least so better +// safe than sorry for now. +const int slop_factor = 2 * wordSize; + +// Stuff for inter-entry jumping +static Label fast_accessor_slow_entry_path; + +// Stuff for caching identical entries +static address normal_entry = NULL; +static address native_entry = NULL; + +int AbstractInterpreter::BasicType_as_index(BasicType type) +{ + int i = 0; + switch (type) { + case T_BOOLEAN: i = 0; break; + case T_CHAR : i = 1; break; + case T_BYTE : i = 2; break; + case T_SHORT : i = 3; break; + case T_INT : i = 4; break; + case T_LONG : i = 5; break; + case T_VOID : i = 6; break; + case T_FLOAT : i = 7; break; + case T_DOUBLE : i = 8; break; + case T_OBJECT : i = 9; break; + case T_ARRAY : i = 9; break; + default : ShouldNotReachHere(); + } + assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, + "index out of bounds"); + return i; +} + +// Is this pc anywhere within code owned by the interpreter? +// This only works for code that we have generated. It clearly +// misses all of the actual C++ interpreter implementation. + +bool CppInterpreter::contains(address pc) +{ + return pc == CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation) + || _code->contains(pc); +} + +// A result is the register or registers defined in the native ABI +// for that type, unless it is an OOP in which case it will have +// been unboxed and saved in the frame. Preprocess it. + +address CppInterpreterGenerator::generate_result_handler_for(BasicType type) +{ + address start = __ pc(); + + switch (type) { + case T_VOID: + break; + + case T_BOOLEAN: + { + Label zero; + + __ compare (r3, 0); + __ beq (zero); + __ load (r3, 1); + __ bind (zero); + } + break; + + case T_CHAR: + __ andi_ (r3, r3, 0xffff); + break; + + case T_BYTE: + __ extsb (r3, r3); + break; + + case T_SHORT: + __ extsh (r3, r3); + break; + + case T_INT: +#ifdef PPC64 + __ extsw (r3, r3); +#endif + break; + + case T_LONG: + case T_FLOAT: + case T_DOUBLE: + break; + + case T_OBJECT: + __ load (r3, STATE(_oop_temp)); + break; + + default: + ShouldNotReachHere(); + } + __ blr (); + + return start; +} + +// A result is the register or registers defined in the native ABI +// for that type. Push it from there onto the top of the caller's +// expression stack. +// +// Arguments: +// Rlocals: the top of the caller's expression stack +// +// Returns: +// Rlocals: the adjusted top of the caller's expression stack + +address CppInterpreterGenerator::generate_tosca_to_stack_converter( + BasicType type) +{ + address start = __ pc(); + + switch (type) { + case T_VOID: + break; + + case T_BOOLEAN: + case T_CHAR: + case T_BYTE: + case T_SHORT: + case T_INT: + __ stw (r3, Address(Rlocals, 0)); + __ subi (Rlocals, Rlocals, wordSize); + break; + + case T_LONG: + __ store (r3, Address(Rlocals, -wordSize)); +#ifdef PPC32 + __ store (r4, Address(Rlocals, 0)); +#endif + __ subi (Rlocals, Rlocals, wordSize * 2); + break; + + case T_FLOAT: + __ stfs (f1, Address(Rlocals, 0)); + __ subi (Rlocals, Rlocals, wordSize); + break; + + case T_DOUBLE: + __ stfd (f1, Address(Rlocals, -wordSize)); + __ subi (Rlocals, Rlocals, wordSize * 2); + break; + + case T_OBJECT: + __ store (r3, Address(Rlocals, 0)); + __ subi (Rlocals, Rlocals, wordSize); + break; + + default: + ShouldNotReachHere(); + } + __ blr (); + + return start; +} + +// A result is at the top of the Java expression stack of the method +// that has just returned. Push it from there onto the top of the +// caller's expression stack. +// +// Arguments: +// Rstate: the interpreter state of the method that has just returned +// Rlocals: the top of the caller's expression stack +// +// Returns: +// Rlocals: the adjusted top of the caller's expression stack + +address CppInterpreterGenerator::generate_stack_to_stack_converter( + BasicType type) +{ + const Register stack = r3; + + address start = __ pc(); + + switch (type) { + case T_VOID: + break; + + case T_BOOLEAN: + case T_CHAR: + case T_BYTE: + case T_SHORT: + case T_INT: + case T_FLOAT: + __ load (stack, STATE(_stack)); + __ lwz (r0, Address(stack, wordSize)); + __ stw (r0, Address(Rlocals, 0)); + __ subi (Rlocals, Rlocals, wordSize); + break; + + case T_LONG: + case T_DOUBLE: + __ load (stack, STATE(_stack)); + __ load (r0, Address(stack, wordSize)); + __ store (r0, Address(Rlocals, -wordSize)); +#ifdef PPC32 + __ load (r0, Address(stack, wordSize * 2)); + __ store (r0, Address(Rlocals, 0)); +#endif + __ subi (Rlocals, Rlocals, wordSize * 2); + break; + + case T_OBJECT: + __ load (stack, STATE(_stack)); + __ load (r0, Address(stack, wordSize)); + __ store (r0, Address(Rlocals, 0)); + __ subi (Rlocals, Rlocals, wordSize); + break; + + default: + ShouldNotReachHere(); + } + __ blr (); + + return start; +} + +// A result is at the top of the Java expression stack of the method +// that has just returned. Copy it from there into the register or +// registers defined in the native ABI for that type. +// +// Arguments: +// Rstate: the interpreter state of the method that has just returned + +address CppInterpreterGenerator::generate_stack_to_native_abi_converter( + BasicType type) +{ + const Register stack = r5; + + address start = __ pc(); + + switch (type) { + case T_VOID: + break; + + case T_BOOLEAN: + case T_CHAR: + case T_BYTE: + case T_SHORT: + case T_INT: + __ load (stack, STATE(_stack)); + __ lwa (r3, Address(stack, wordSize)); + break; + + case T_LONG: + __ load (stack, STATE(_stack)); + __ load (r3, Address(stack, wordSize)); +#ifdef PPC32 + __ load (r4, Address(stack, wordSize * 2)); +#endif + break; + + case T_FLOAT: + __ load (stack, STATE(_stack)); + __ lfs (f1, Address(stack, wordSize)); + break; + + case T_DOUBLE: + __ load (stack, STATE(_stack)); + __ lfd (f1, Address(stack, wordSize)); + break; + + case T_OBJECT: + __ load (stack, STATE(_stack)); + __ load (r3, Address(stack, wordSize)); + break; + + default: + ShouldNotReachHere(); + } + __ blr (); + + return start; +} + +// C++ Interpreter stub for empty methods. + +address InterpreterGenerator::generate_empty_entry() +{ + if (!UseFastEmptyMethods) + return NULL; + + Label& slow_path = fast_accessor_slow_entry_path; + + address start = __ pc(); + + // Drop into the slow path if we need a safepoint check. + __ load (r3, (intptr_t) SafepointSynchronize::address_of_state()); + __ load (r0, Address(r3, 0)); + __ compare (r0, SafepointSynchronize::_not_synchronized); + __ bne (slow_path); + + // Ok, we're done :) + __ blr (); + + return start; +} + +// C++ Interpreter stub for "calling" an accessor method. + +address InterpreterGenerator::generate_accessor_entry() +{ + if (!UseFastAccessorMethods) + return NULL; + + Label& slow_path = fast_accessor_slow_entry_path; + + address start = __ pc(); + + // Drop into the slow path if we need a safepoint check. + __ load (r3, (intptr_t) SafepointSynchronize::address_of_state()); + __ load (r0, Address(r3, 0)); + __ compare (r0, SafepointSynchronize::_not_synchronized); + __ bne (slow_path); + + // Load the object pointer and drop into the slow path + // if we have a NullPointerException. + const Register object = r4; + + __ load (object, Address(Rlocals, 0)); + __ compare (object, 0); + __ beq (slow_path); + + // Read the field index from the bytecode, which looks like this: + // 0: 0x2a: aload_0 + // 1: 0xb4: getfield + // 2: index (high byte) + // 3: index (low byte) + // 4: 0xac/b0: ireturn/areturn + const Register index = r5; + + __ load (index, Address(Rmethod, methodOopDesc::const_offset())); + __ lwz (index, Address(index, constMethodOopDesc::codes_offset())); +#ifdef ASSERT + { + Label ok; + __ shift_right (r0, index, 16); + __ compare (r0, (Bytecodes::_aload_0 << 8) | Bytecodes::_getfield); + __ beq (ok); + __ should_not_reach_here (__FILE__, __LINE__); + __ bind (ok); + } +#endif + __ andi_ (index, index, 0xffff); + + // Locate the entry in the constant pool cache + const Register entry = r6; + + __ load (entry, Address(Rmethod, methodOopDesc::constants_offset())); + __ load (entry, Address(entry,constantPoolOopDesc::cache_offset_in_bytes())); + __ la (entry, Address(entry, constantPoolCacheOopDesc::base_offset())); + __ shift_left(r0, index, + exact_log2(in_words(ConstantPoolCacheEntry::size())) + LogBytesPerWord); + __ add (entry, entry, r0); + + // Check the validity of the cache entry by testing whether the + // _indices field contains Bytecode::_getfield in b1 byte. + __ load (r0, Address(entry, ConstantPoolCacheEntry::indices_offset())); + __ shift_right (r0, r0, 16); + __ andi_ (r0, r0, 0xff); + __ compare (r0, Bytecodes::_getfield); + __ bne (slow_path); + + // Calculate the type and offset of the field + const Register offset = r7; + const Register type = r8; + + __ load (offset, Address(entry, ConstantPoolCacheEntry::f2_offset())); + __ load (type, Address(entry, ConstantPoolCacheEntry::flags_offset())); + ConstantPoolCacheEntry::verify_tosBits(); + __ shift_right (type, type, ConstantPoolCacheEntry::tosBits); + + // Load the value + Label is_object, is_int, is_byte, is_short, is_char; + + __ compare (type, atos); + __ beq (is_object); + __ compare (type, itos); + __ beq (is_int); + __ compare (type, btos); + __ beq (is_byte); + __ compare (type, stos); + __ beq (is_short); + __ compare (type, ctos); + __ beq (is_char); + + __ load (r3, (intptr_t) "error: unknown type: %d\n"); + __ mr (r4, type); + __ call (CAST_FROM_FN_PTR(address, printf)); + __ should_not_reach_here (__FILE__, __LINE__); + + __ bind (is_object); + __ load_indexed (r3, object, offset); + __ blr (); + + __ bind (is_int); + __ lwax (r3, object, offset); + __ blr (); + + __ bind (is_byte); + __ lbax (r3, object, offset); + __ blr (); + + __ bind (is_short); + __ lhax (r3, object, offset); + __ blr (); + + __ bind (is_char); + __ lhzx (r3, object, offset); + __ blr (); + + return start; +} + +// C++ Interpreter stub for calling a native method. +// This sets up a somewhat different looking stack for calling the +// native method than the typical interpreter frame setup but still +// has the pointer to an interpreter state. + +address InterpreterGenerator::generate_native_entry(bool synchronized) +{ + const Register handler = r14; + const Register function = r15; + + assert_different_registers(Rmethod, Rlocals, Rthread, Rstate, Rmonitor, + handler, function); + + // We use the same code for synchronized and not + if (native_entry) + return native_entry; + + address start = __ pc(); + + // Allocate and initialize our stack frame. + __ load (Rstate, 0); + generate_compute_interpreter_state(true); + + // Make sure method is native and not abstract +#ifdef ASSERT + { + Label ok; + __ lwz (r0, Address(Rmethod, methodOopDesc::access_flags_offset())); + __ andi_ (r0, r0, JVM_ACC_NATIVE | JVM_ACC_ABSTRACT); + __ compare (r0, JVM_ACC_NATIVE); + __ beq (ok); + __ should_not_reach_here (__FILE__, __LINE__); + __ bind (ok); + } +#endif + + // Lock if necessary + Label not_synchronized_1; + + __ bne (CRsync, not_synchronized_1); + __ lock_object (Rmonitor); + __ bind (not_synchronized_1); + + // Get signature handler + const Address signature_handler_addr( + Rmethod, methodOopDesc::signature_handler_offset()); + + Label return_to_caller, got_signature_handler; + + __ load (handler, signature_handler_addr); + __ compare (handler, 0); + __ bne (got_signature_handler); + __ mr (r3, Rthread); + __ mr (r4, Rmethod); + __ call (CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call)); + __ load (r0, Address(Rthread, Thread::pending_exception_offset())); + __ compare (r0, 0); + __ bne (return_to_caller); + __ load (handler, signature_handler_addr); + __ bind (got_signature_handler); + + // Get the native function entry point + const Address native_function_addr( + Rmethod, methodOopDesc::native_function_offset()); + + Label got_function; + + __ load (function, native_function_addr); + __ compare (function, 0); + __ bne (got_function); + __ mr (r3, Rthread); + __ mr (r4, Rmethod); + __ call (CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call)); + __ load (r0, Address(Rthread, Thread::pending_exception_offset())); + __ compare (r0, 0); + __ bne (return_to_caller); + __ load (function, native_function_addr); + __ bind (got_function); + + // Call signature handler + __ mtlr (handler); + __ blrl (); + __ mr (handler, r0); + + // Pass JNIEnv + __ la (r3, Address(Rthread, JavaThread::jni_environment_offset())); + + // Pass mirror handle if static + const Address oop_temp_addr = STATE(_oop_temp); + + Label not_static; + + __ bne (CRstatic, not_static); + __ get_mirror_handle (r4); + __ store (r4, oop_temp_addr); + __ la (r4, oop_temp_addr); + __ bind (not_static); + + // Set up the Java frame anchor + __ set_last_Java_frame (); + + // Change the thread state to native + const Address thread_state_addr(Rthread, JavaThread::thread_state_offset()); +#ifdef ASSERT + { + Label ok; + __ lwz (r0, thread_state_addr); + __ compare (r0, _thread_in_Java); + __ beq (ok); + __ should_not_reach_here (__FILE__, __LINE__); + __ bind (ok); + } +#endif + __ load (r0, _thread_in_native); + __ stw (r0, thread_state_addr); + + // Make the call + __ call (function); + + // The result will be in r3 (and maybe r4 on 32-bit) or f1. + // Wherever it is, we need to store it before calling anything + const Register r3_save = r16; +#ifdef PPC32 + const Register r4_save = r17; +#endif + const FloatRegister f1_save = f14; + + __ mr (r3_save, r3); +#ifdef PPC32 + __ mr (r4_save, r4); +#endif + __ fmr (f1_save, f1); + + // Switch thread to "native transition" state before reading the + // synchronization state. This additional state is necessary + // because reading and testing the synchronization state is not + // atomic with respect to garbage collection. + __ load (r0, _thread_in_native_trans); + __ stw (r0, thread_state_addr); + + // Write serialization page + if(os::is_MP()) { + __ serialize_memory (r3, r4); + } + + // Check for safepoint operation in progress and/or pending + // suspend requests + Label block, no_block; + + __ load (r3, (intptr_t) SafepointSynchronize::address_of_state()); + __ lwz (r0, Address(r3, 0)); + __ compare (r0, SafepointSynchronize::_not_synchronized); + __ bne (block); + __ lwz (r0, Address(Rthread, JavaThread::suspend_flags_offset())); + __ compare (r0, 0); + __ beq (no_block); + __ bind (block); + __ mr (r3, Rthread); + __ call (CAST_FROM_FN_PTR(address, + JavaThread::check_special_condition_for_native_trans)); + __ bind (no_block); + + // Change the thread state + __ load (r0, _thread_in_Java); + __ stw (r0, thread_state_addr); + + // Reset the frame anchor + __ reset_last_Java_frame (); + + // If the result was an OOP then unbox it and store it in the frame + // (where it will be safe from garbage collection) before we release + // the handle it might be protected by + Label non_oop, store_oop; + + __ load (r0, (intptr_t) AbstractInterpreter::result_handler(T_OBJECT)); + __ compare (r0, handler); + __ bne (non_oop); + __ compare (r3_save, 0); + __ beq (store_oop); + __ load (r3_save, Address(r3_save, 0)); + __ bind (store_oop); + __ store (r3_save, STATE(_oop_temp)); + __ bind (non_oop); + + // Reset handle block + __ load (r3, Address(Rthread, JavaThread::active_handles_offset())); + __ load (r0, 0); + __ stw (r0, Address(r3, JNIHandleBlock::top_offset_in_bytes())); + + // If there is an exception we skip the result handler and return. + // Note that this also skips unlocking which seems totally wrong, + // but apparently this is what the asm interpreter does so we do + // too. + __ load (r0, Address(Rthread, Thread::pending_exception_offset())); + __ compare (r0, 0); + __ bne (return_to_caller); + + // Unlock if necessary + Label not_synchronized_2; + + __ bne (CRsync, not_synchronized_2); + __ unlock_object (Rmonitor); + __ bind (not_synchronized_2); + + // Restore saved result and call the result handler + __ mr (r3, r3_save); +#ifdef PPC32 + __ mr (r4, r4_save); +#endif + __ fmr (f1, f1_save); + __ mtlr (handler); + __ blrl (); + + // Unwind the current activation and return + __ bind (return_to_caller); + + generate_unwind_interpreter_state(); + __ blr (); + + native_entry = start; + return start; +} + +// Initial entry to C++ interpreter from the call_stub. +// This entry point is called the frame manager since it handles the +// generation of interpreter activation frames via requests directly +// from the vm (via call_stub) and via requests from the interpreter. +// The requests from the call_stub happen directly thru the entry +// point. Requests from the interpreter happen via returning from the +// interpreter and examining the message the interpreter has returned +// to the frame manager. The frame manager can take the following +// requests: +// +// NO_REQUEST - error, should never happen. +// MORE_MONITORS - need a new monitor. Shuffle the expression stack +// on down and allocate a new monitor. +// CALL_METHOD - set up a new activation to call a new method. Very +// similar to what happens during entry during the entry +// via the call stub. +// RETURN_FROM_METHOD - remove an activation. Return to interpreter +// or call stub. +// +// Arguments: +// Rmethod: address of methodOop +// Rlocals: address of first parameter +// Rthread: address of current thread +// +// Stack layout at entry: +// | ... | +// +------------------------------+ +// +-> | Link area | +// | +------------------------------+ ----------------------------- +// | | Register save area | high addresses +// | +------------------------------+ +// | | Caller's local variables | +// | +------------------------------+ +// | | Parameter 0 | +// | | ... | +// | | Parameter n-1 | +// | +------------------------------+ +// | | Padding | +// | +------------------------------+ +// | | Parameter list space (ppc64) | +// | +------------------------------+ +// +---+ Link area | low addresses +// +------------------------------+ ----------------------------- +// +// We are free to blow any registers we like because the call_stub +// which brought us here initially has preserved the callee save +// registers already. + +address InterpreterGenerator::generate_normal_entry(bool synchronized) +{ + assert_different_registers(Rmethod, Rlocals, Rthread, Rstate, Rmonitor); + + Label re_dispatch; + Label call_interpreter; + Label call_method; + Label call_non_interpreted_method; + Label return_with_exception; + Label return_from_method; + Label resume_interpreter; + Label return_to_initial_caller; + Label more_monitors; + Label throwing_exception; + + // We use the same code for synchronized and not + if (normal_entry) + return normal_entry; + + address start = __ pc(); + + // There are two ways in which we can arrive at this entry. + // There is the special case where a normal interpreted method + // calls another normal interpreted method, and there is the + // general case of when we enter from somewhere else: from + // call_stub, from C1 or C2, or from a fast accessor which + // deferred. In the special case we're already in frame manager + // code: we arrive at re_dispatch with Rstate containing the + // previous interpreter state. In the general case we arrive + // at start with no previous interpreter state so we set Rstate + // to NULL to indicate this. + __ bind (fast_accessor_slow_entry_path); + __ load (Rstate, 0); + __ bind (re_dispatch); + + // Adjust the caller's stack frame to accomodate any additional + // local variables we have contiguously with our parameters. + generate_adjust_callers_stack(); + + // Allocate and initialize our stack frame. + generate_compute_interpreter_state(false); + + // Call the interpreter ============================================== + __ bind (call_interpreter); + + // We can setup the frame anchor with everything we want at + // this point as we are thread_in_Java and no safepoints can + // occur until we go to vm mode. We do have to clear flags + // on return from vm but that is it + __ set_last_Java_frame (); + + // Call interpreter + address interpreter = JvmtiExport::can_post_interpreter_events() ? + CAST_FROM_FN_PTR(address, BytecodeInterpreter::runWithChecks) : + CAST_FROM_FN_PTR(address, BytecodeInterpreter::run); + + __ mr (r3, Rstate); + __ call (interpreter); + + // Clear the frame anchor + __ reset_last_Java_frame (); + + // Examine the message from the interpreter to decide what to do + __ lwz (r4, STATE(_msg)); + __ compare (r4, BytecodeInterpreter::call_method); + __ beq (call_method); + __ compare (r4, BytecodeInterpreter::return_from_method); + __ beq (return_from_method); + __ compare (r4, BytecodeInterpreter::more_monitors); + __ beq (more_monitors); + __ compare (r4, BytecodeInterpreter::throwing_exception); + __ beq (throwing_exception); + + __ load (r3, (intptr_t) "error: bad message from interpreter: %d\n"); + __ call (CAST_FROM_FN_PTR(address, printf)); + __ should_not_reach_here (__FILE__, __LINE__); + + // Handle a call_method message ====================================== + __ bind (call_method); + + __ load (Rmethod, STATE(_result._to_call._callee)); + __ load (Rlocals, STATE(_stack)); + __ lhz (r0, Address(Rmethod, methodOopDesc::size_of_parameters_offset())); + __ shift_left (r0, r0, LogBytesPerWord); + __ add (Rlocals, Rlocals, r0); + + __ load (r0, STATE(_result._to_call._callee_entry_point)); + __ load (r3, (intptr_t) start); + __ compare (r0, r3); + __ bne (call_non_interpreted_method); + + // Interpreted methods are intercepted and re-dispatched ----------- + __ load (r0, CAST_FROM_FN_PTR(intptr_t, RecursiveInterpreterActivation)); + __ mtlr (r0); + __ b (re_dispatch); + + // Non-interpreted methods are dispatched normally ----------------- + __ bind (call_non_interpreted_method); + __ mtlr (r0); + __ blrl (); + + // Restore Rstate + __ load (Rstate, Address(r1, StackFrame::back_chain_offset * wordSize)); + __ subi (Rstate, Rstate, sizeof(BytecodeInterpreter)); + + // Check for pending exceptions + __ load (r0, Address(Rthread, Thread::pending_exception_offset())); + __ compare (r0, 0); + __ bne (return_with_exception); + + // Convert the result and resume + generate_convert_result(CppInterpreter::_tosca_to_stack); + __ b (resume_interpreter); + + // Handle a return_from_method message =============================== + __ bind (return_from_method); + + __ load (r0, STATE(_prev_link)); + __ compare (r0, 0); + __ beq (return_to_initial_caller); + + // "Return" from a re-dispatch ------------------------------------- + + generate_convert_result(CppInterpreter::_stack_to_stack); + generate_unwind_interpreter_state(); + + // Resume the interpreter + __ bind (resume_interpreter); + + __ store (Rlocals, STATE(_stack)); + __ load (Rlocals, STATE(_locals)); + __ load (Rmethod, STATE(_method)); + __ load (r0, BytecodeInterpreter::method_resume); + __ stw (r0, STATE(_msg)); + __ b (call_interpreter); + + // Return to the initial caller (call_stub etc) -------------------- + __ bind (return_to_initial_caller); + + generate_convert_result(CppInterpreter::_stack_to_native_abi); + generate_unwind_interpreter_state(); + __ blr (); + + // Handle a more_monitors message ==================================== + __ bind (more_monitors); + + generate_more_monitors(); + + __ load (r0, BytecodeInterpreter::got_monitors); + __ stw (r0, STATE(_msg)); + __ b (call_interpreter); + + // Handle a throwing_exception message =============================== + __ bind (throwing_exception); + + // Check we actually have an exception +#ifdef ASSERT + { + Label ok; + __ load (r0, Address(Rthread, Thread::pending_exception_offset())); + __ compare (r0, 0); + __ bne (ok); + __ should_not_reach_here (__FILE__, __LINE__); + __ bind (ok); + } +#endif + + // Return to wherever + generate_unwind_interpreter_state(); + __ bind (return_with_exception); + __ compare (Rstate, 0); + __ bne (resume_interpreter); + __ blr (); + + normal_entry = start; + return start; +} + +// Adjust the caller's stack frame to accomodate any additional +// local variables we have contiguously with our parameters. +// +// Arguments: +// Rmethod: address of methodOop +// Rlocals: address of local variables +// +// Stack layout at entry: +// | ... | +// +------------------------------+ +// +-> | Link area | +// | +------------------------------+ ----------------------------- +// | | Register save area | high addresses +// | +------------------------------+ +// | | Caller's local variables | +// | +------------------------------+ +// | | Parameter 0 | +// | | ... | +// | | Parameter n-1 | +// | +------------------------------+ +// | | Padding | +// | +------------------------------+ +// | | Parameter list space (ppc64) | +// | +------------------------------+ +// +---+ Link area | low addresses +// +------------------------------+ ----------------------------- +// +// Stack layout at exit: +// | ... | +// +------------------------------+ +// +-> | Link area | +// | +------------------------------+ ----------------------------- +// | | Register save area | high addresses +// | +------------------------------+ +// | | Caller's local variables | +// | +------------------------------+ +// | | Parameter 0 | <-- Rlocals +// | | ... | +// | | Parameter n-1 | +// | | Local variable n | +// | | ... | +// | | Local variable m-1 | +// | +------------------------------+ +// | | Padding | +// | +------------------------------+ +// | | Parameter list space (ppc64) | +// | +------------------------------+ +// +---+ Link area | low addresses +// +------------------------------+ ----------------------------- + +void CppInterpreterGenerator::generate_adjust_callers_stack() +{ + StackFrame frame; + + const int frame_header_size = frame.unaligned_size() + slop_factor; + + const Address param_words_addr( + Rmethod, methodOopDesc::size_of_parameters_offset()); + const Address local_words_addr( + Rmethod, methodOopDesc::size_of_locals_offset()); + + const Register param_words = r3; + const Register local_words = r4; + + Label loop, done; + + // Check whether extra locals are actually required + __ lhz (param_words, param_words_addr); + __ lhz (local_words, local_words_addr); + __ compare (param_words, local_words); + __ beq (done); + + // Extend the frame if necessary + const Register required_bytes = r5; + const Register available_bytes = r6; + + __ shift_left (required_bytes, local_words, LogBytesPerWord); + __ sub (available_bytes, Rlocals, r1); + __ subi (available_bytes, available_bytes, frame_header_size); + __ maybe_extend_frame (required_bytes, available_bytes); + + // Zero the extra locals + const Register dst = r7; + + __ shift_left (dst, param_words, LogBytesPerWord); + __ sub (dst, Rlocals, dst); + __ sub (r0, local_words, param_words); + __ mtctr (r0); + __ load (r0, 0); + __ bind (loop); + __ store (r0, Address(dst, 0)); + __ subi (dst, dst, wordSize); + __ bdnz (loop); + + __ bind (done); +} + +// Create a new C++ interpreter stack frame and interpreter state +// object +// +// Arguments: +// Rmethod: address of methodOop +// Rlocals: address of local variables +// Rstate: previous frame manager state (NULL from call_stub etc) +// +// Returns: +// Rstate: current frame manager state +// CRsync: whether the method is synchronized +// Rmonitor: initial monitor (if synchronized) +// CRstatic: whether the method is static +// +// The frame we create: +// | ... | +// +------------------------------+ +// +-> | Link area | +// | +------------------------------+ ----------------------------- +// | | Interpreter state | <-- Rstate high addresses +// | | ... | +// | | ... | +// | +------------------------------+ +// | | Monitor 0 (if synchronized) | +// | +------------------------------+ +// | | Expression stack slot 0 | +// | | ... | +// | | Expression stack slot p-1 | +// | +------------------------------+ +// | | Padding | +// | +------------------------------+ +// | | Parameter list space (ppc64) | +// | +------------------------------+ +// +---+ Link area | low addresses +// +------------------------------+ ----------------------------- + +void CppInterpreterGenerator::generate_compute_interpreter_state(bool native) +{ + StackFrame frame; + + const Address stack_words_addr( + Rmethod, methodOopDesc::max_stack_offset()); + const Address access_flags_addr( + Rmethod, methodOopDesc::access_flags_offset()); + + Label not_synchronized_1, not_synchronized_2, not_synchronized_3; + Label not_static, init_monitor; + + const int monitor_size = frame::interpreter_frame_monitor_size() * wordSize; + + // Calculate the access flags conditions + const Register access_flags = r3; + + __ lwz (access_flags, access_flags_addr); + __ andi_ (r0, access_flags, JVM_ACC_SYNCHRONIZED); + __ compare (CRsync, r0, JVM_ACC_SYNCHRONIZED); + __ andi_ (r0, access_flags, JVM_ACC_STATIC); + __ compare (CRstatic, r0, JVM_ACC_STATIC); + + const int basic_frame_size = + frame.unaligned_size() + sizeof(BytecodeInterpreter) + slop_factor; + + // Calculate the frame size + const Register stack_size = r3; + const Register frame_size = r4; + const Register padding = r5; + + if (native) { + __ load (frame_size, basic_frame_size); + } + else { + __ lhz (stack_size, stack_words_addr); + __ shift_left (stack_size, stack_size, LogBytesPerWord); + __ addi (frame_size, stack_size, basic_frame_size); + } + __ bne (CRsync, not_synchronized_1); + __ addi (frame_size, frame_size, monitor_size); + __ bind (not_synchronized_1); + __ calc_padding_for_alignment (padding, frame_size, 16); + __ add (frame_size, frame_size, padding); + + // Save the link register and create the new frame + __ mflr (r0); + __ store (r0, Address(r1, StackFrame::lr_save_offset * wordSize)); + __ neg (r0, frame_size); + __ store_update_indexed (r1, r1, r0); + + // Calculate everything's addresses + const Register stack_limit = r6; + const Register stack = r7; + const Register stack_base = Rmonitor; + const Register monitor_base = r8; + + __ addi (stack_limit, r1, frame.start_of_locals() + slop_factor - wordSize); + __ add (stack_limit, stack_limit, padding); + if (native) + __ mr (stack, stack_limit); + else + __ add (stack, stack_limit, stack_size); + __ addi (stack_base, stack, wordSize); + __ mr (monitor_base, stack_base); + __ bne (CRsync, not_synchronized_2); + __ addi (monitor_base, monitor_base, monitor_size); + __ bind (not_synchronized_2); + __ mr (r0, Rstate); + __ mr (Rstate, monitor_base); + + // Initialise the interpreter state object + __ store (Rlocals, STATE(_locals)); + __ store (Rmethod, STATE(_method)); + __ store (Rstate, STATE(_self_link)); + __ store (r0, STATE(_prev_link)); + __ store (stack_limit, STATE(_stack_limit)); + __ store (stack, STATE(_stack)); + __ store (stack_base, STATE(_stack_base)); + __ store (monitor_base, STATE(_monitor_base)); + __ store (Rthread, STATE(_thread)); + +#ifdef ASSERT + { + Label ok; + __ load (r3, ThreadLocalStorage::thread_index()); + __ call (CAST_FROM_FN_PTR(address, pthread_getspecific)); + __ compare (Rthread, r3); + __ beq (ok); + __ should_not_reach_here (__FILE__, __LINE__); + __ bind (ok); + } +#endif + + if (!native) { + __ load (r3, Address(Rmethod, methodOopDesc::const_offset())); + __ addi (r3, r3, in_bytes(constMethodOopDesc::codes_offset())); + __ store (r3, STATE(_bcp)); + } + + __ load (r3, Address(Rmethod, methodOopDesc::constants_offset())); + __ load (r3, Address(r3, constantPoolOopDesc::cache_offset_in_bytes())); + __ store (r3, STATE(_constants)); + + __ load (r3, BytecodeInterpreter::method_entry); + __ stw (r3, STATE(_msg)); + + __ load (r3, 0); + if (native) + __ store (r3, STATE(_bcp)); + __ store (r3, STATE(_oop_temp)); + __ store (r3, STATE(_mdx)); + __ store (r3, STATE(_result._to_call._callee)); + + // Initialise the monitor if synchronized + __ bne (CRsync, not_synchronized_3); + __ bne (CRstatic, not_static); + __ get_mirror_handle (r3); + __ b (init_monitor); + __ bind (not_static); + __ load (r3, Address(Rlocals, 0)); + __ bind (init_monitor); + __ store (r3, Address(Rmonitor, BasicObjectLock::obj_offset_in_bytes())); + __ bind (not_synchronized_3); +} + +// Adjust the current stack frame to accomodate an additional monitor. +// +// Arguments: +// Rmethod: address of methodOop +// Rstate: frame manager state + +void CppInterpreterGenerator::generate_more_monitors() +{ + StackFrame frame; + + const int frame_header_size = frame.unaligned_size() + slop_factor; + const int monitor_size = frame::interpreter_frame_monitor_size() * wordSize; + + const Address stack_words_addr(Rmethod, methodOopDesc::max_stack_offset()); + + Label loop_start, loop_test; + + // Extend the frame if necessary + const Register required_bytes = r3; + const Register available_bytes = r4; + + __ load (required_bytes, frame_header_size + monitor_size); + __ load (available_bytes, STATE(_stack_limit)); + __ addi (available_bytes, available_bytes, wordSize); + __ sub (available_bytes, available_bytes, r1); + __ maybe_extend_frame (required_bytes, available_bytes); + + // Move the expression stack contents + const Register src = r3; + const Register end = r4; + const Register dst = r5; + + __ load (src, STATE(_stack)); + __ addi (src, src, wordSize); + __ load (end, STATE(_stack_base)); + __ subi (dst, src, monitor_size); + __ b (loop_test); + __ bind (loop_start); + __ load (r0, Address(src, 0)); + __ store (r0, Address(dst, 0)); + __ addi (src, src, wordSize); + __ addi (dst, dst, wordSize); + __ bind (loop_test); + __ compare (src, end); + __ blt (loop_start); + + // Move the expression stack pointers + const Register tmp = r3; + + __ load (tmp, STATE(_stack_limit)); + __ subi (tmp, tmp, monitor_size); + __ store (tmp, STATE(_stack_limit)); + __ load (tmp, STATE(_stack)); + __ subi (tmp, tmp, monitor_size); + __ store (tmp, STATE(_stack)); + __ load (tmp, STATE(_stack_base)); + __ subi (tmp, tmp, monitor_size); + __ store (tmp, STATE(_stack_base)); + + // Zero the new monitor so the interpreter can find it. + // NB tmp at this point contains _stack_base, the address + // of the word after the expression stack -- which just + // happens to be the address of our new monitor. + __ load (r0, 0); + __ store (r0, Address(tmp, BasicObjectLock::obj_offset_in_bytes())); +} + +// Convert the a method's return value from one format to another + +void CppInterpreterGenerator::generate_convert_result(address* converter_array) +{ + __ load (r5, (intptr_t) converter_array); + __ lwz (r0, Address(Rmethod, methodOopDesc::result_index_offset())); + __ shift_left (r0, r0, LogBytesPerWord); + __ load_indexed (r0, r5, r0); + __ mtlr (r0); + __ blrl (); +} + +// Remove the activation created by generate_compute_interpreter_state. +// +// Arguments: +// Rstate: frame manager state +// +// Returns: +// Rstate: previous frame manager state (NULL from call_stub etc) + +void CppInterpreterGenerator::generate_unwind_interpreter_state() +{ + __ load (Rstate, STATE(_prev_link)); + __ load (r1, Address(r1, StackFrame::back_chain_offset * wordSize)); + __ load (r0, Address(r1, StackFrame::lr_save_offset * wordSize)); + __ mtlr (r0); +} + +address AbstractInterpreterGenerator::generate_method_entry( + AbstractInterpreter::MethodKind kind) { + + address entry_point = NULL; + bool synchronized = false; + + switch (kind) { + case Interpreter::zerolocals: + break; + + case Interpreter::zerolocals_synchronized: + synchronized = true; + break; + + case Interpreter::native: + entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); + break; + + case Interpreter::native_synchronized: + entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); + break; + + case Interpreter::empty: + entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); + break; + + case Interpreter::accessor: + entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); + break; + + case Interpreter::abstract: + entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); + break; + + case Interpreter::java_lang_math_sin: + case Interpreter::java_lang_math_cos: + case Interpreter::java_lang_math_tan: + case Interpreter::java_lang_math_abs: + case Interpreter::java_lang_math_log: + case Interpreter::java_lang_math_log10: + case Interpreter::java_lang_math_sqrt: + entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); + break; + + default: + ShouldNotReachHere(); + } + + if (entry_point) + return entry_point; + + return ((InterpreterGenerator*)this)->generate_normal_entry(false); +} + +InterpreterGenerator::InterpreterGenerator(StubQueue* code) + : CppInterpreterGenerator(code) { + generate_all(); // down here so it can be "virtual" +} + +int AbstractInterpreter::size_top_interpreter_activation(methodOop method) +{ + StackFrame frame; + + int call_stub_frame = round_to( + StubRoutines::call_stub_base_size() + + method->max_locals() * wordSize, 16); + + int interpreter_frame = round_to( + frame.unaligned_size() + + slop_factor + + method->max_stack() * wordSize + + (method->is_synchronized() ? + frame::interpreter_frame_monitor_size() * wordSize : 0) + + sizeof(BytecodeInterpreter), 16); + + return (call_stub_frame + interpreter_frame) / wordSize; +} + +// Deoptimization helpers for C++ interpreter + +int AbstractInterpreter::layout_activation(methodOop method, + int tempcount, + int popframe_extra_args, + int moncount, + int callee_param_count, + int callee_locals, + frame* caller, + frame* interpreter_frame, + bool is_top_frame) +{ + Unimplemented(); +} + +address CppInterpreter::return_entry(TosState state, int length) +{ + Unimplemented(); +} + +address CppInterpreter::deopt_entry(TosState state, int length) +{ + Unimplemented(); +} + +#endif // CC_INTERP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,32 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + + protected: + // Size of interpreter code. Increase if too small. Interpreter will + // fail with a guarantee ("not enough space for interpreter generation") + // if too small. Maximum size is with JVMTI and TaggedStackInterpreter. + const static int InterpreterCodeSize = 16 * K; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/debug_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,32 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_debug_ppc.cpp.incl" + +void pd_ps(frame f) +{ + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/disassembler_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,46 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// The disassembler prints out ppc code annotated +// with Java specific information. + +class Disassembler +{ + public: + static void decode(CodeBlob *cb, outputStream* st = NULL) + { + Unimplemented(); + } + + static void decode(nmethod* nm, outputStream* st = NULL) + { + Unimplemented(); + } + + static void decode(u_char* begin, u_char* end, outputStream* st = NULL) + { + Unimplemented(); + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/dump_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,37 @@ +/* + * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_dump_ppc.cpp.incl" + +void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list, + void** vtable, + char** md_top, + char* md_end, + char** mc_top, + char* mc_end) +{ + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/frame_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,122 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_frame_ppc.cpp.incl" + +int frame::_call_wrapper_offset = 0; + +#ifdef ASSERT +void RegisterMap::check_location_valid() +{ + Unimplemented(); +} +#endif + +bool frame::is_interpreted_frame() const +{ + return Interpreter::contains(pc()); +} + +frame frame::sender_for_entry_frame(RegisterMap *map) const +{ + assert(map != NULL, "map must be set"); + // Java frame called from C; skip all C frames and return top C + // frame of that chunk as the sender + JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor(); + assert(!entry_frame_is_first(), "next Java fp must be non zero"); + assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack"); + map->clear(); + assert(map->include_argument_oops(), "should be set by clear"); + return frame(jfa->last_Java_sp(), jfa->last_Java_pc()); +} + +frame frame::sender_for_interpreter_frame(RegisterMap *map) const +{ + return frame(sender_sp()); +} + +frame frame::sender(RegisterMap* map) const +{ + // Default is not to follow arguments; the various + // sender_for_xxx methods update this accordingly. + map->set_include_argument_oops(false); + + if (is_entry_frame()) + return sender_for_entry_frame(map); + + if (is_interpreted_frame()) + return sender_for_interpreter_frame(map); + + Unimplemented(); +} + +#ifdef CC_INTERP +BasicObjectLock* frame::interpreter_frame_monitor_begin() const +{ + return get_interpreterState()->monitor_base(); +} + +BasicObjectLock* frame::interpreter_frame_monitor_end() const +{ + return (BasicObjectLock*) get_interpreterState()->stack_base(); +} +#endif // CC_INTERP + +void frame::patch_pc(Thread* thread, address pc) +{ + Unimplemented(); +} + +bool frame::safe_for_sender(JavaThread *thread) +{ + Unimplemented(); +} + +void frame::pd_gc_epilog() +{ +} + +bool frame::is_interpreted_frame_valid() const +{ + Unimplemented(); +} + +BasicType frame::interpreter_frame_result(oop* oop_result, + jvalue* value_result) +{ + Unimplemented(); +} + +int frame::frame_size() const +{ + Unimplemented(); +} + +intptr_t* frame::interpreter_frame_tos_at(jint offset) const +{ + int index = (Interpreter::expr_offset_in_bytes(offset) / wordSize); + return &interpreter_frame_tos_address()[index]; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/frame_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,66 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// A frame represents a physical stack frame (an activation). Frames +// can be C or Java frames, and the Java frames can be interpreted or +// compiled. In contrast, vframes represent source-level activations, +// so that one physical frame can correspond to multiple source level +// frames because of inlining. A frame is comprised of {pc, sp} + + public: + enum { + pc_return_offset = 0 + }; + + public: + // Constructors + frame(intptr_t* sp); + frame(intptr_t* sp, address pc); + + // accessors for the instance variables + intptr_t* fp() const + { + return sp(); + } + +#ifdef CC_INTERP + inline interpreterState get_interpreterState() const; +#endif // CC_INTERP + + private: + static int _call_wrapper_offset; + + public: + static int call_wrapper_offset() + { + assert(_call_wrapper_offset != 0, "call_wrapper_offset not set"); + return _call_wrapper_offset; + } + + static void set_call_wrapper_offset(int offset) + { + assert(_call_wrapper_offset == 0, "call_wrapper_offset already set"); + _call_wrapper_offset = offset; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,175 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Inline functions for ppc frames + +// Constructors + +inline frame::frame() +{ + _sp = NULL; + _pc = NULL; + _cb = NULL; + _deopt_state = unknown; +} + +inline frame::frame(intptr_t* sp, address pc) +{ + _sp = sp; + _pc = pc; + assert(_pc != NULL, "no pc?"); + _cb = CodeCache::find_blob(_pc); + if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { + _pc = (((nmethod*)_cb)->get_original_pc(this)); + _deopt_state = is_deoptimized; + } else { + _deopt_state = not_deoptimized; + } +} + +inline frame::frame(intptr_t* sp) +{ + _sp = sp; + _pc = *((address *) sp + StackFrame::lr_save_offset); + assert(_pc != NULL, "no pc?"); + _cb = CodeCache::find_blob(_pc); + if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { + _pc = (((nmethod*)_cb)->get_original_pc(this)); + _deopt_state = is_deoptimized; + } else { + _deopt_state = not_deoptimized; + } +} + +// Accessors + +inline intptr_t* frame::sender_sp() const +{ + return (intptr_t *) *sp(); +} + +inline intptr_t* frame::link() const +{ + return sender_sp(); +} + +#ifdef CC_INTERP +inline interpreterState frame::get_interpreterState() const +{ + return (interpreterState) + ((address) sender_sp() - sizeof(BytecodeInterpreter)); +} + +inline intptr_t** frame::interpreter_frame_locals_addr() const +{ + assert(is_interpreted_frame(), "must be interpreted"); + return &(get_interpreterState()->_locals); +} + +inline intptr_t* frame::interpreter_frame_bcx_addr() const +{ + assert(is_interpreted_frame(), "must be interpreted"); + return (intptr_t*) &(get_interpreterState()->_bcp); +} + +inline constantPoolCacheOop* frame::interpreter_frame_cache_addr() const +{ + assert(is_interpreted_frame(), "must be interpreted"); + return &(get_interpreterState()->_constants); +} + +inline methodOop* frame::interpreter_frame_method_addr() const +{ + assert(is_interpreted_frame(), "must be interpreted"); + return &(get_interpreterState()->_method); +} + +inline intptr_t* frame::interpreter_frame_mdx_addr() const +{ + assert(is_interpreted_frame(), "must be interpreted"); + return (intptr_t*) &(get_interpreterState()->_mdx); +} + +inline intptr_t* frame::interpreter_frame_tos_address() const +{ + assert(is_interpreted_frame(), "must be interpreted"); + return get_interpreterState()->_stack + 1; +} +#endif // CC_INTERP + +inline int frame::interpreter_frame_monitor_size() +{ + return BasicObjectLock::size(); +} + +inline intptr_t* frame::interpreter_frame_expression_stack() const +{ + intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end(); + return monitor_end - 1; +} + +inline jint frame::interpreter_frame_expression_stack_direction() +{ + return -1; +} + +// Return a unique id for this frame. The id must have a value where +// we can distinguish identity and younger/older relationship. NULL +// represents an invalid (incomparable) frame. +inline intptr_t* frame::id() const +{ + return sp(); +} + +inline JavaCallWrapper* frame::entry_frame_call_wrapper() const +{ + assert(is_entry_frame(), "must be an entry frame"); + return *(JavaCallWrapper**) ((address) sender_sp() - call_wrapper_offset()); +} + +inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) +{ + Unimplemented(); +} + +inline oop frame::saved_oop_result(RegisterMap* map) const +{ + Unimplemented(); +} + +inline bool frame::is_older(intptr_t* id) const +{ + Unimplemented(); +} + +inline intptr_t* frame::entry_frame_argument_at(int offset) const +{ + Unimplemented(); +} + +inline intptr_t* frame::unextended_sp() const +{ + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/globals_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// +// Set the default values for platform dependent flags used by the +// runtime system. See globals.hpp for details of what they do. +// + +define_pd_global(bool, ConvertSleepToYield, true); +define_pd_global(bool, ShareVtableStubs, true); +define_pd_global(bool, CountInterpCalls, true); +define_pd_global(bool, NeedsDeoptSuspend, false); + +define_pd_global(bool, ImplicitNullChecks, true); +define_pd_global(bool, UncommonNullCast, true); + +define_pd_global(intx, CodeEntryAlignment, 32); +define_pd_global(uintx, TLABSize, 0); +#ifdef PPC64 +define_pd_global(uintx, NewSize, ScaleForWordSize(2048 * K)); +#else +define_pd_global(uintx, NewSize, ScaleForWordSize(1024 * K)); +#endif // PPC64 +define_pd_global(intx, InlineFrequencyCount, 100); +define_pd_global(intx, PreInflateSpin, 10); + +define_pd_global(intx, StackYellowPages, 2); +define_pd_global(intx, StackRedPages, 1); +define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1)); + +define_pd_global(bool, RewriteBytecodes, true); +define_pd_global(bool, RewriteFrequentPairs, true);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/icBuffer_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,52 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_icBuffer_ppc.cpp.incl" + +int InlineCacheBuffer::ic_stub_code_size() +{ + // NB set this once the functions below are implemented + return 4; +} + +void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin, + oop cached_oop, + address entry_point) { + // NB ic_stub_code_size() must return the size of the code we generate + Unimplemented(); +} + +address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) +{ + // NB ic_stub_code_size() must return the size of the code we generate + Unimplemented(); +} + +oop InlineCacheBuffer::ic_buffer_cached_oop(address code_begin) +{ + // NB ic_stub_code_size() must return the size of the code we generate + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/icache_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,101 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_icache_ppc.cpp.incl" + +#define __ _masm-> + +#ifdef ASSERT +static int get_cache_block_size() +{ + // Measure the cache block size by zeroing the first cache block + // within a page or non-zero bytes and seeing how many bytes got + // zeroed. + int pagesize = getpagesize(); + unsigned char *page; + if (posix_memalign((void **)&page, pagesize, pagesize) != 0) + return -1; + memset(page, 0xff, pagesize); + asm volatile("dcbz 0, %0" : : "r"(page)); + if (page[0] != 0) + return -1; + page[pagesize - 1] = 0xff; + int blocksize = 0; + while (page[blocksize] == 0) + blocksize++; + free(page); + return blocksize; +} +#endif // ASSERT + +void ICacheStubGenerator::generate_icache_flush( + ICache::flush_icache_stub_t* flush_icache_stub) { + + StubCodeMark mark(this, "ICache", "flush_icache_stub"); + + assert(ICache::line_size <= get_cache_block_size(), "line_size too large"); + assert(ICache::line_size == 1 << ICache::log2_line_size, "doh"); + + address start = __ enter(); + + const Register start_addr = r3; + const Register lines = r4; + const Register magic = r5; + + const Register addr = r12; + + Label loop1, loop2; + + __ compare (lines, 0); + __ blelr (); + + __ mr (addr, start_addr); + __ mtctr (lines); + __ bind (loop1); + __ dcbf (0, addr); + __ addi (addr, addr, ICache::line_size); + __ bdnz (loop1); + + __ sync (); + + __ mr (addr, start_addr); + __ mtctr (lines); + __ bind (loop2); + __ icbi (0, addr); + __ addi (addr, addr, ICache::line_size); + __ bdnz (loop2); + + __ isync (); + + __ mr (r3, magic); + __ blr (); + + // Check we got the stub size right + assert(__ pc() - start == ICache::stub_size, "wrong stub size"); + + // Must be set here so StubCodeMark destructor can call the flush stub. + *flush_icache_stub = (ICache::flush_icache_stub_t)start; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/icache_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,43 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Interface for updating the instruction cache. Whenever the VM +// modifies code, part of the processor instruction cache potentially +// has to be flushed. + +class ICache : public AbstractICache { + public: + enum { +#ifdef PPC32 + stub_size = 64, // Size of the icache flush stub in bytes +#else + stub_size = 80, // Size of the icache flush stub in bytes +#endif // PPC32 + line_size = 128, // Icache line size in bytes + log2_line_size = 7 // log2(line_size) + }; + + // Use default implementation +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/interp_masm_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,121 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_interp_masm_ppc.cpp.incl" + +// Lock object +// +// Arguments: +// monitor: BasicObjectLock to be used for locking + +void InterpreterMacroAssembler::lock_object(Register entry) +{ + assert (!UseHeavyMonitors, "not supported"); + assert (!UseBiasedLocking, "not supported"); + + const Register lockee = r3; + const Register mark = r4; + const Register displaced = r5; + + assert_different_registers(entry, lockee, mark, displaced); + + Label done; + + load(lockee, Address(entry, BasicObjectLock::obj_offset_in_bytes())); + la(mark, Address(lockee, oopDesc::mark_offset_in_bytes())); + + // This is based on the bit in BytecodeInterpreter::run() + // that handles got_monitors messages. The code in the + // comments is taken from there. + + // displaced = lockee->mark()->set_unlocked() + load(displaced, Address(mark, 0)); + ori(displaced, displaced, markOopDesc::unlocked_value); + + // entry->lock()->set_displaced_header(displaced) + store(displaced, Address(entry, BasicObjectLock::lock_offset_in_bytes() + + BasicLock::displaced_header_offset_in_bytes())); + + // Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) + // If this succeeds we saw an unlocked object and are done. + cmpxchg_(entry, mark, displaced); + beq(done); + + unimplemented(__FILE__, __LINE__); + bind(done); +} + +// Unlocks an object. Throws an IllegalMonitorException if +// object is not locked by current thread. +// +// Arguments: +// monitor: BasicObjectLock for lock +// +void InterpreterMacroAssembler::unlock_object(Register entry) +{ + assert (!UseHeavyMonitors, "not supported"); + assert (!UseBiasedLocking, "not supported"); + + const Register lockee = r3; + const Register mark = r4; + const Register lock = r5; + const Register header = r6; + + assert_different_registers(entry, lockee, mark, lock, header); + + Label unlock, done; + + load(lockee, Address(entry, BasicObjectLock::obj_offset_in_bytes())); + la(mark, Address(lockee, oopDesc::mark_offset_in_bytes())); + + // Check that the object has not already been unlocked + compare(lockee, 0); + bne(unlock); + unimplemented(__FILE__, __LINE__); + bind(unlock); + + // lock = entry->lock() + la(lock, Address(entry, BasicObjectLock::lock_offset_in_bytes())); + + // header = lock->displaced_header() + load(header, Address(lock, BasicLock::displaced_header_offset_in_bytes())); + + // entry->set_obj(NULL) + load(r0, 0); + load(r0, Address(entry, BasicObjectLock::obj_offset_in_bytes())); + + // If it was recursive then we're done + compare(header, 0); + beq(done); + + // Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) + // If this succeeds we unlocked the object and are done. + cmpxchg_(header, mark, lock); + beq(done); + + unimplemented(__FILE__, __LINE__); + bind(done); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/interp_masm_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,36 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file specializes the assember with interpreter-specific macros + +class InterpreterMacroAssembler : public MacroAssembler { + public: + InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {} + + // Object locking + void lock_object(Register entry); + void unlock_object(Register entry); +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/interpreterGenerator_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,37 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + + // Generation of Interpreter + // + friend class AbstractInterpreterGenerator; + + private: + address generate_normal_entry(bool synchronized); + address generate_native_entry(bool synchronized); + address generate_abstract_entry(); + address generate_math_entry(AbstractInterpreter::MethodKind kind); + address generate_empty_entry(); + address generate_accessor_entry();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/interpreterRT_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,329 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_interpreterRT_ppc.cpp.incl" + +#define __ _masm-> + +// Implementation of SignatureHandlerGenerator + +void InterpreterRuntime::SignatureHandlerGenerator::pass_int() +{ + const Address src(Rlocals, Interpreter::local_offset_in_bytes(offset())); + + if (_gp_reg <= gp_reg_max) { + __ lwa (as_Register(_gp_reg++), src); +#ifdef PPC64 + _st_arg++; +#endif + } + else { + pass_on_stack(src, T_INT); + } +} + +void InterpreterRuntime::SignatureHandlerGenerator::pass_long() +{ +#ifdef PPC32 + const Address srch(Rlocals, Interpreter::local_offset_in_bytes(offset())); + const Address srcl(Rlocals, Interpreter::local_offset_in_bytes(offset()+1)); + + if (_gp_reg < gp_reg_max) { + if (!(_gp_reg & 1)) + _gp_reg++; + __ lwz (as_Register(_gp_reg++), srcl); + __ lwz (as_Register(_gp_reg++), srch); + } + else { + pass_on_stack(srcl, T_LONG); + } +#else + const Address src(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1)); + + if (_gp_reg <= gp_reg_max) { + __ ld (as_Register(_gp_reg++), src); + _st_arg++; + } + else { + pass_on_stack(src, T_LONG); + } +#endif // PPC32 +} + +void InterpreterRuntime::SignatureHandlerGenerator::pass_float() +{ + const Address src(Rlocals, Interpreter::local_offset_in_bytes(offset())); + + if (_fp_reg <= fp_reg_max) { + __ lfs (as_FloatRegister(_fp_reg++), src); +#ifdef PPC64 + _st_arg++; +#endif + } + else { + pass_on_stack(src, T_FLOAT); + } +} + +void InterpreterRuntime::SignatureHandlerGenerator::pass_double() +{ + const Address src(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1)); + + if (_fp_reg <= fp_reg_max) { + __ lfd (as_FloatRegister(_fp_reg++), src); +#ifdef PPC64 + _st_arg++; +#endif + } + else { + pass_on_stack(src, T_DOUBLE); + } +} + +void InterpreterRuntime::SignatureHandlerGenerator::pass_object() +{ + const Address src(Rlocals, Interpreter::local_offset_in_bytes(offset())); + + if (_gp_reg <= gp_reg_max) { + const Register dst = as_Register(_gp_reg++); + Label null; + + __ load (dst, src); + __ compare (dst, 0); + __ beq (null); + __ la (dst, src); + __ bind (null); + +#ifdef PPC64 + _st_arg++; +#endif + } + else { + pass_on_stack(src, T_OBJECT); + } +} + +void InterpreterRuntime::SignatureHandlerGenerator::pass_on_stack( + const Address& src, BasicType type) +{ +#ifdef PPC32 + if (_st_arg & 1) { + if (type == T_LONG || type == T_FLOAT || type == T_DOUBLE) + _st_arg++; + } +#endif // PPC32 + + assert(src.base() == Rlocals, "what?"); + _st_args->append(StackArgument( + _masm, + src.displacement(), + (StackFrame::link_area_words + _st_arg++) * wordSize, + type)); + +#ifdef PPC32 + if (type == T_LONG || type == T_FLOAT || type == T_DOUBLE) + _st_arg++; +#endif // PPC32 +} + +void InterpreterRuntime::StackArgument::pass() +{ + const Address src(Rlocals, _src_offset); + const Address dst(r1, _dst_offset); + Label null; + + switch (_type) { + case T_INT: + __ lwa (r0, src); + __ store (r0, dst); + break; + + case T_LONG: +#ifdef PPC32 + __ lwz (r0, src); + __ stw (r0, dst); + __ lwz (r0, Address(Rlocals, _src_offset + wordSize)); + __ stw (r0, Address(r1, _dst_offset + wordSize)); +#else + __ ld (r0, src); + __ std (r0, dst); +#endif + break; + + case T_FLOAT: +#ifdef PPC32 + __ lfs (f0, src); + __ stfd (f0, dst); +#else + __ lwz (r0, src); + __ stw (r0, Address(r1, _dst_offset + wordSize)); +#endif + break; + + case T_DOUBLE: + __ lfd (f0, src); + __ stfd (f0, dst); + break; + + case T_OBJECT: + __ load (r0, src); + __ compare (r0, 0); + __ beq (null); + __ la (r0, src); + __ bind (null); + __ store (r0, dst); + break; + + default: + ShouldNotReachHere(); + } +} + +void InterpreterRuntime::SignatureHandlerGenerator::generate( + uint64_t fingerprint) +{ + // Generate code to handle register arguments + iterate(fingerprint); + + // Generate code to handle stack arguments + if (_st_arg > StackFrame::min_params) { + const Register required_bytes = r11; + const Register available_bytes = r12; + + __ load (required_bytes, _st_arg * wordSize); +#ifdef CC_INTERP + // The area we have to play with is the area between the link + // area and the expression stack (which has zero size, this + // being a native method). Note that we treat any slop_factor + // as available space here. Note also that this is duplicated + // in AbstractInterpreterGenerator::generate_slow_signature_handler. + __ load (available_bytes, + Address(Rstate, BytecodeInterpreter::stack_limit_offset())); + __ addi (available_bytes, available_bytes, + (1 - StackFrame::link_area_words) * wordSize); + __ sub (available_bytes, available_bytes, r1); +#else + Unimplemented(); +#endif + __ maybe_extend_frame (required_bytes, available_bytes); + + for (int i = 0; i < _st_args->length(); i++) + _st_args->at(i).pass(); + } + + // Return result handler + __ load (r0, (intptr_t)Interpreter::result_handler(method()->result_type())); + __ blr (); + + __ flush (); +} + + +// Implementation of SlowSignatureHandler + +void InterpreterRuntime::SlowSignatureHandler::pass_int() +{ + Unimplemented(); +} + +void InterpreterRuntime::SlowSignatureHandler::pass_long() +{ +#ifdef PPC32 + intptr_t srch = *(intptr_t *) + (_from + Interpreter::local_offset_in_bytes(offset())); + intptr_t srcl = *(intptr_t *) + (_from + Interpreter::local_offset_in_bytes(offset() + 1)); + + if (_gp_regs < _gp_reg_max) { + if (!((_gp_reg_max - _gp_regs) & 1)) + _gp_regs++; + *(_gp_regs++) = srcl; + *(_gp_regs++) = srch; + } + else { + *(_st_args++) = srcl; + *(_st_args++) = srch; + } +#else + intptr_t src = *(intptr_t *) + (_from + Interpreter::local_offset_in_bytes(offset() + 1)); + + if (_gp_regs <= _gp_reg_max) { + *(_gp_regs++) = src; + _st_args++; + } + else { + *(_st_args++) = src; + } +#endif +} + +void InterpreterRuntime::SlowSignatureHandler::pass_float() +{ + Unimplemented(); +} + +void InterpreterRuntime::SlowSignatureHandler::pass_double() +{ + Unimplemented(); +} + +void InterpreterRuntime::SlowSignatureHandler::pass_object() +{ + Unimplemented(); +} + +IRT_ENTRY(address, + InterpreterRuntime::slow_signature_handler(JavaThread* thread, + methodOopDesc* method, + intptr_t* from, + intptr_t* to)) + methodHandle m(thread, (methodOop) method); + assert(m->is_native(), "sanity check"); + + // Handle arguments + intptr_t *st_args = to; +#ifdef PPC32 + intptr_t *gp_regs = st_args + (method->size_of_parameters() - 3) * 3; +#else + intptr_t *gp_regs = st_args + (method->size_of_parameters() + 2); +#endif + intptr_t *fp_regs = gp_regs + (gp_reg_max + 1 - gp_reg_start); + + SlowSignatureHandler(m, + (address) from, + gp_regs, + (double *) fp_regs, + st_args).iterate(UCONST64(-1)); + + // Return result handler + return Interpreter::result_handler(m->result_type()); +IRT_END + + +// Implementation of SignatureHandlerLibrary + +void SignatureHandlerLibrary::pd_set_handler(address handler) {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/interpreterRT_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,151 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// native method calls + +class StackArgument +{ + private: + MacroAssembler* _masm; + int _src_offset; + int _dst_offset; + BasicType _type; + + public: + StackArgument() + : _masm(NULL), + _src_offset(0), + _dst_offset(0), + _type(T_ILLEGAL) {} + + StackArgument(MacroAssembler* masm, + int src_offset, + int dst_offset, + BasicType type) + : _masm(masm), + _src_offset(src_offset), + _dst_offset(dst_offset), + _type(type) {} + + void pass(); +}; + +enum { + gp_reg_start = 4, // r3 contains the JNIEnv + gp_reg_max = 10, + fp_reg_start = 1, +#ifdef PPC32 + fp_reg_max = 8 +#else + fp_reg_max = 13 +#endif // PPC32 +}; + +class SignatureHandlerGenerator : public NativeSignatureIterator +{ + private: + MacroAssembler* _masm; + + int _gp_reg; + int _fp_reg; + int _st_arg; + + GrowableArray<StackArgument>* _st_args; + + private: + void pass_int(); + void pass_long(); + void pass_float(); + void pass_double(); + void pass_object(); + + void pass_on_stack(const Address& src, BasicType type); + + public: + SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) + : NativeSignatureIterator(method) + { + _masm = new MacroAssembler(buffer); + + _gp_reg = gp_reg_start; + if (method->is_static()) + _gp_reg++; + _fp_reg = fp_reg_start; + +#ifdef PPC32 + _st_arg = 0; +#else + _st_arg = method->is_static() ? 2 : 1; +#endif + + _st_args = new GrowableArray<StackArgument>(); + } + + void generate(uint64_t fingerprint); +}; + +class SlowSignatureHandler : public NativeSignatureIterator +{ + private: + address _from; + + intptr_t *_gp_regs; + double *_fp_regs; + intptr_t *_st_args; + + intptr_t *_gp_reg_max; + double *_fp_reg_max; + + private: + void pass_int(); + void pass_long(); + void pass_float(); + void pass_double(); + void pass_object(); + + public: + SlowSignatureHandler(methodHandle method, + address from, + intptr_t *gp_regs, + double *fp_regs, + intptr_t *st_args) + : NativeSignatureIterator(method) + { + _from = from; + + _gp_regs = gp_regs; + if (method->is_static()) + _gp_regs++; + _fp_regs = fp_regs; + + _st_args = st_args; +#ifdef PPC64 + _st_args += method->is_static() ? 2 : 1; +#endif + + _gp_reg_max = gp_regs + gp_reg_max - gp_reg_start; + _fp_reg_max = fp_regs + fp_reg_max - fp_reg_start; + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,187 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_interpreter_ppc.cpp.incl" + +#define __ _masm-> + +address AbstractInterpreterGenerator::generate_slow_signature_handler() +{ + address start = __ pc(); + + const Address param_words_addr( + Rmethod, methodOopDesc::size_of_parameters_offset()); + + const Register required_bytes = r11; + const Register available_bytes = r12; + const Register register_images = r14; + + // Calculate the size of the parameter list space. We can't + // know how much we'll need before parsing the signature so + // we allocate for the worst case. Note that this calculation + // is repeated in InterpreterRuntime::slow_signature_handler. + __ lhz (required_bytes, param_words_addr); +#ifdef PPC32 + // We can always fit at least three parameters in registers + __ subi (required_bytes, required_bytes, 3); + + // Floats get converted to doubles and may need aligning + __ shift_left (r0, required_bytes, 1); + __ add (required_bytes, required_bytes, r0); +#else + // Allocate space for JNIEnv and a possible mirror handle. + __ addi (required_bytes, required_bytes, 2); +#endif + __ shift_left (required_bytes, required_bytes, LogBytesPerWord); + __ mr (register_images, required_bytes); + + // Add to this the size of the local variable space + __ addi (required_bytes, required_bytes, + (InterpreterRuntime::gp_reg_max + 1 - + InterpreterRuntime::gp_reg_start) * wordSize + + (InterpreterRuntime::fp_reg_max + 1 - + InterpreterRuntime::fp_reg_start) * 8); + + // Extend the frame +#ifdef CC_INTERP + // The area we have to play with is the area between the link + // area and the expression stack (which has zero size, this + // being a native method). Note that we treat any slop_factor + // as available space here. Note also that this is duplicated + // in InterpreterRuntime::SignatureHandlerGenerator::generate. + __ load (available_bytes, + Address(Rstate, BytecodeInterpreter::stack_limit_offset())); + __ addi (available_bytes, available_bytes, + (1 - StackFrame::link_area_words) * wordSize); + __ sub (available_bytes, available_bytes, r1); +#else + Unimplemented(); +#endif + __ maybe_extend_frame (required_bytes, available_bytes); + + // Fill in the parameter list space and register images + StackFrame frame; + + __ mr (r3, Rthread); + __ mr (r4, Rmethod); + __ mr (r5, Rlocals); + __ la (r6, Address(r1, StackFrame::link_area_words * wordSize)); + + __ prolog (frame); + __ call (CAST_FROM_FN_PTR(address, + InterpreterRuntime::slow_signature_handler)); + __ epilog (frame); + + // Load the register images into the registers + const Register src = r11; + + __ addi (src, r1, StackFrame::link_area_words * wordSize); + __ add (src, src, register_images); + + int offset = 0; + for (int i = InterpreterRuntime::gp_reg_start; + i <= InterpreterRuntime::gp_reg_max; i++) { + __ load (as_Register(i), Address(src, offset)); + offset += wordSize; + } + for (int i = InterpreterRuntime::fp_reg_start; + i <= InterpreterRuntime::fp_reg_max; i++) { + __ lfd (as_FloatRegister(i), Address(src, offset)); + offset += 8; + } + + // Return the result handler + __ mr (r0, r3); + __ blr (); + + return start; +} + +address InterpreterGenerator::generate_math_entry( + AbstractInterpreter::MethodKind kind) +{ + if (!InlineIntrinsics) + return NULL; + + address start = __ pc(); + + switch (kind) { + case Interpreter::java_lang_math_sin: + __ unimplemented (__FILE__, __LINE__); + break; + + case Interpreter::java_lang_math_cos: + __ unimplemented (__FILE__, __LINE__); + break; + + case Interpreter::java_lang_math_tan: + __ unimplemented (__FILE__, __LINE__); + break; + + case Interpreter::java_lang_math_abs: + __ unimplemented (__FILE__, __LINE__); + break; + + case Interpreter::java_lang_math_log: + __ unimplemented (__FILE__, __LINE__); + break; + + case Interpreter::java_lang_math_log10: + __ unimplemented (__FILE__, __LINE__); + break; + + case Interpreter::java_lang_math_sqrt: + __ unimplemented (__FILE__, __LINE__); + break; + + default: + ShouldNotReachHere(); + } + + return start; +} + +address InterpreterGenerator::generate_abstract_entry() +{ + return UnimplementedEntry(); +} + +int AbstractInterpreter::size_activation(methodOop method, + int tempcount, + int popframe_extra_args, + int moncount, + int callee_param_count, + int callee_locals, + bool is_top_frame) +{ + Unimplemented(); +} + +void Deoptimization::unwind_callee_save_values(frame* f, + vframeArray* vframe_array) +{ + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/interpreter_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,56 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + public: + static int expr_index_at(int i) + { + return stackElementWords() * i; + } + static int expr_tag_index_at(int i) + { + assert(TaggedStackInterpreter, "should not call this"); + Unimplemented(); + } + + static int expr_offset_in_bytes(int i) + { + return stackElementSize() * i; + } + static int expr_tag_offset_in_bytes(int i) + { + assert(TaggedStackInterpreter, "should not call this"); + Unimplemented(); + } + + static int local_index_at(int i) + { + assert(i <= 0, "local direction already negated"); + return stackElementWords() * i + (value_offset_in_bytes() / wordSize); + } + static int local_tag_index_at(int i) + { + assert(TaggedStackInterpreter, "should not call this"); + Unimplemented(); + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/javaFrameAnchor_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,72 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +public: + // Each arch must define reset, save, restore + // These are used by objects that only care about: + // 1 - initializing a new state (thread creation, javaCalls) + // 2 - saving a current state (javaCalls) + // 3 - restoring an old state (javaCalls) + + void clear() + { + // clearing _last_Java_sp must be first + _last_Java_sp = NULL; + // fence? + _last_Java_pc = NULL; + } + + void copy(JavaFrameAnchor* src) + { + // In order to make sure the transition state is valid for "this" + // We must clear _last_Java_sp before copying the rest of the new + // data + // + // Hack Alert: Temporary bugfix for 4717480/4721647 To act like + // previous version (pd_cache_state) don't NULL _last_Java_sp + // unless the value is changing + // + if (_last_Java_sp != src->_last_Java_sp) + _last_Java_sp = NULL; + + _last_Java_pc = src->_last_Java_pc; + // Must be last so profiler will always see valid frame if + // has_last_frame() is true + _last_Java_sp = src->_last_Java_sp; + } + + bool walkable() + { + return true; + } + + void make_walkable(JavaThread* thread) + { + } + + intptr_t* last_Java_sp() const + { + return _last_Java_sp; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/jniFastGetField_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,67 @@ +/* + * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_jniFastGetField_ppc.cpp.incl" + +address JNI_FastGetField::generate_fast_get_boolean_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_byte_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_char_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_short_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_int_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_long_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_float_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_double_field() +{ + return (address) -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/jniTypes_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,108 @@ +/* + * Copyright 1998-2002 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file holds platform-dependent routines used to write primitive jni +// types to the array of arguments passed into JavaCalls::call + +class JNITypes : AllStatic { + // These functions write a java primitive type (in native format) + // to a java stack slot array to be passed as an argument to JavaCalls:calls. + // I.e., they are functionally 'push' operations if they have a 'pos' + // formal parameter. Note that jlong's and jdouble's are written + // _in reverse_ of the order in which they appear in the interpreter + // stack. This is because call stubs (see stubGenerator_ppc.cpp) + // reverse the argument list constructed by JavaCallArguments (see + // javaCalls.hpp). + +private: + // Helper routines. + static inline void put_int2 (jint *from, jint *to) { to[0] = from[0]; to[1] = from[1]; } + static inline void put_int2 (jint *from, jint *to, int& pos) { put_int2 (from, (jint *)((intptr_t *)to + pos)); pos += 2; } + static inline void put_int2r(jint *from, jint *to) { to[0] = from[1]; to[1] = from[0]; } + static inline void put_int2r(jint *from, jint *to, int& pos) { put_int2r(from, (jint *)((intptr_t *)to + pos)); pos += 2; } + +public: + // Ints are stored in native format in one JavaCallArgument slot at *to. + static inline void put_int(jint from, intptr_t *to) { *(jint *)(to + 0 ) = from; } + static inline void put_int(jint from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = from; } + static inline void put_int(jint *from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = *from; } + +#ifdef PPC64 + // Longs are stored in native format in one JavaCallArgument slot at *(to+1). + static inline void put_long(jlong from, intptr_t *to) { *(jlong *)(to + 1 + 0) = from; } + static inline void put_long(jlong from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = from; pos += 2; } + static inline void put_long(jlong *from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = *from; pos += 2; } +#else + // Longs are stored in reversed native word format in two JavaCallArgument slots at *to. + // The high half is in *(to+1) and the low half in *to. + static inline void put_long(jlong from, intptr_t *to) { put_int2r((jint *)&from, (jint *)to); } + static inline void put_long(jlong from, intptr_t *to, int& pos) { put_int2r((jint *)&from, (jint *)to, pos); } + static inline void put_long(jlong *from, intptr_t *to, int& pos) { put_int2r((jint *) from, (jint *)to, pos); } +#endif + + // Oops are stored in native format in one JavaCallArgument slot at *to. + static inline void put_obj(oop from, intptr_t *to) { *(oop *)(to + 0 ) = from; } + static inline void put_obj(oop from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = from; } + static inline void put_obj(oop *from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = *from; } + + // Floats are stored in native format in one JavaCallArgument slot at *to. + static inline void put_float(jfloat from, intptr_t *to) { *(jfloat *)(to + 0 ) = from; } + static inline void put_float(jfloat from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = from; } + static inline void put_float(jfloat *from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = *from; } + +#ifdef PPC64 + // Doubles are stored in native word format in one JavaCallArgument slot at *(to+1). + static inline void put_double(jdouble from, intptr_t *to) { *(jdouble *)(to + 1 + 0) = from; } + static inline void put_double(jdouble from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = from; pos += 2; } + static inline void put_double(jdouble *from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = *from; pos += 2; } +#else + // Doubles are stored in reversed native word format in two JavaCallArgument slots at *to. + static inline void put_double(jdouble from, intptr_t *to) { put_int2r((jint *)&from, (jint *)to); } + static inline void put_double(jdouble from, intptr_t *to, int& pos) { put_int2r((jint *)&from, (jint *)to, pos); } + static inline void put_double(jdouble *from, intptr_t *to, int& pos) { put_int2r((jint *) from, (jint *)to, pos); } +#endif + + // The get_xxx routines, on the other hand, actually _do_ fetch + // java primitive types from the interpreter stack. + static inline jint get_int(intptr_t *from) { return *(jint *)from; } + +#ifdef PPC64 + static inline jlong get_long(intptr_t *from) { return *(jlong *)from; } +#else + static inline jlong get_long(intptr_t *from) { return ((jlong)(*( signed int *)((jint *)from )) << 32) | + ((jlong)(*(unsigned int *)((jint *)from + 1)) << 0); } +#endif + + static inline oop get_obj(intptr_t *from) { return *(oop *)from; } + static inline jfloat get_float(intptr_t *from) { return *(jfloat *)from; } + +#ifdef PPC64 + static inline jdouble get_double(intptr_t *from) { return *(jdouble *)from; } +#else + static inline jdouble get_double(intptr_t *from) { jlong jl = ((jlong)(*( signed int *)((jint *)from )) << 32) | + ((jlong)(*(unsigned int *)((jint *)from + 1)) << 0); + return *(jdouble *)&jl; } +#endif + +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/jni_ppc.h Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,32 @@ +/* + * Copyright 1997-2004 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +#define JNIEXPORT +#define JNIIMPORT +#define JNICALL + +typedef int jint; +typedef long long jlong; +typedef signed char jbyte;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/nativeInst_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,166 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// We have interfaces for the following instructions: +// - NativeInstruction +// - - NativeCall +// - - NativeMovConstReg +// - - NativeMovConstRegPatching +// - - NativeJump +// - - NativeIllegalOpCode +// - - NativeReturn +// - - NativeReturnX (return with argument) +// - - NativePushConst +// - - NativeTstRegMem + +// The base class for different kinds of native instruction abstractions. +// Provides the primitive operations to manipulate code relative to this. + +class NativeInstruction VALUE_OBJ_CLASS_SPEC +{ + public: + bool is_safepoint_poll() + { + Unimplemented(); + } +}; + +class NativeCall : public NativeInstruction +{ + public: + enum ppc_specific_constants { + instruction_size = 4, + }; + + address instruction_address() const + { + Unimplemented(); + } + + address next_instruction_address() const + { + Unimplemented(); + } + + address return_address() const + { + Unimplemented(); + } + + address destination() const + { + Unimplemented(); + } + + void set_destination_mt_safe(address dest) + { + Unimplemented(); + } + + void verify_alignment() + { + Unimplemented(); + } + + void verify() + { + Unimplemented(); + } + + static bool is_call_before(address return_address) + { + Unimplemented(); + } +}; + +inline NativeCall* nativeCall_before(address return_address) +{ + Unimplemented(); +} + +inline NativeCall* nativeCall_at(address address) +{ + Unimplemented(); +} + +class NativeMovConstReg : public NativeInstruction +{ + public: + address next_instruction_address() const + { + Unimplemented(); + } + + intptr_t data() const + { + Unimplemented(); + } + + void set_data(intptr_t x) + { + Unimplemented(); + } +}; + +inline NativeMovConstReg* nativeMovConstReg_at(address address) +{ + Unimplemented(); +} + +class NativeJump : public NativeInstruction +{ + public: + enum ppc_specific_constants { + instruction_size = 4, + }; + + address jump_destination() const + { + Unimplemented(); + } + + void set_jump_destination(address dest) + { + Unimplemented(); + } + + static void check_verified_entry_alignment(address entry, + address verified_entry) + { + Unimplemented(); + } + + static void patch_verified_entry(address entry, + address verified_entry, + address dest) + { + Unimplemented(); + } +}; + +inline NativeJump* nativeJump_at(address address) +{ + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/registerMap_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,39 @@ +/* + * Copyright 1998-2007 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// machine-dependent implemention for register maps + friend class frame; + + private: + // This is the hook for finding a register in an "well-known" location, + // such as a register block of a predetermined format. + // Since there is none, we just return NULL. + // See registerMap_sparc.hpp for an example of grabbing registers + // from register save areas of a standard layout. + address pd_location(VMReg reg) const {return NULL;} + + // no PD state to clear or copy: + void pd_clear() {} + void pd_initialize() {} + void pd_initialize_from(const RegisterMap* map) {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/register_definitions_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,115 @@ +/* + * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_register_definitions_ppc.cpp.incl" + +REGISTER_DEFINITION(Register, r0); +REGISTER_DEFINITION(Register, r1); +REGISTER_DEFINITION(Register, r2); +REGISTER_DEFINITION(Register, r3); +REGISTER_DEFINITION(Register, r4); +REGISTER_DEFINITION(Register, r5); +REGISTER_DEFINITION(Register, r6); +REGISTER_DEFINITION(Register, r7); +REGISTER_DEFINITION(Register, r8); +REGISTER_DEFINITION(Register, r9); +REGISTER_DEFINITION(Register, r10); +REGISTER_DEFINITION(Register, r11); +REGISTER_DEFINITION(Register, r12); +REGISTER_DEFINITION(Register, r13); +REGISTER_DEFINITION(Register, r14); +REGISTER_DEFINITION(Register, r15); +REGISTER_DEFINITION(Register, r16); +REGISTER_DEFINITION(Register, r17); +REGISTER_DEFINITION(Register, r18); +REGISTER_DEFINITION(Register, r19); +REGISTER_DEFINITION(Register, r20); +REGISTER_DEFINITION(Register, r21); +REGISTER_DEFINITION(Register, r22); +REGISTER_DEFINITION(Register, r23); +REGISTER_DEFINITION(Register, r24); +REGISTER_DEFINITION(Register, r25); +REGISTER_DEFINITION(Register, r26); +REGISTER_DEFINITION(Register, r27); +REGISTER_DEFINITION(Register, r28); +REGISTER_DEFINITION(Register, r29); +REGISTER_DEFINITION(Register, r30); +REGISTER_DEFINITION(Register, r31); + +REGISTER_DEFINITION(FloatRegister, f0); +REGISTER_DEFINITION(FloatRegister, f1); +REGISTER_DEFINITION(FloatRegister, f2); +REGISTER_DEFINITION(FloatRegister, f3); +REGISTER_DEFINITION(FloatRegister, f4); +REGISTER_DEFINITION(FloatRegister, f5); +REGISTER_DEFINITION(FloatRegister, f6); +REGISTER_DEFINITION(FloatRegister, f7); +REGISTER_DEFINITION(FloatRegister, f8); +REGISTER_DEFINITION(FloatRegister, f9); +REGISTER_DEFINITION(FloatRegister, f10); +REGISTER_DEFINITION(FloatRegister, f11); +REGISTER_DEFINITION(FloatRegister, f12); +REGISTER_DEFINITION(FloatRegister, f13); +REGISTER_DEFINITION(FloatRegister, f14); +REGISTER_DEFINITION(FloatRegister, f15); +REGISTER_DEFINITION(FloatRegister, f16); +REGISTER_DEFINITION(FloatRegister, f17); +REGISTER_DEFINITION(FloatRegister, f18); +REGISTER_DEFINITION(FloatRegister, f19); +REGISTER_DEFINITION(FloatRegister, f20); +REGISTER_DEFINITION(FloatRegister, f21); +REGISTER_DEFINITION(FloatRegister, f22); +REGISTER_DEFINITION(FloatRegister, f23); +REGISTER_DEFINITION(FloatRegister, f24); +REGISTER_DEFINITION(FloatRegister, f25); +REGISTER_DEFINITION(FloatRegister, f26); +REGISTER_DEFINITION(FloatRegister, f27); +REGISTER_DEFINITION(FloatRegister, f28); +REGISTER_DEFINITION(FloatRegister, f29); +REGISTER_DEFINITION(FloatRegister, f30); +REGISTER_DEFINITION(FloatRegister, f31); + +REGISTER_DEFINITION(ConditionRegister, cr0); +REGISTER_DEFINITION(ConditionRegister, cr1); +REGISTER_DEFINITION(ConditionRegister, cr2); +REGISTER_DEFINITION(ConditionRegister, cr3); +REGISTER_DEFINITION(ConditionRegister, cr4); +REGISTER_DEFINITION(ConditionRegister, cr5); +REGISTER_DEFINITION(ConditionRegister, cr6); +REGISTER_DEFINITION(ConditionRegister, cr7); + +REGISTER_DEFINITION(SpecialPurposeRegister, xer); +REGISTER_DEFINITION(SpecialPurposeRegister, lr); +REGISTER_DEFINITION(SpecialPurposeRegister, ctr); + +// Non-volatile registers used by the interpreter +REGISTER_DEFINITION(Register, Rmethod); +REGISTER_DEFINITION(Register, Rlocals); +REGISTER_DEFINITION(Register, Rthread); +#ifdef CC_INTERP +REGISTER_DEFINITION(Register, Rstate); +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/register_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_register_ppc.cpp.incl" + +const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers; +const int ConcreteRegisterImpl::max_fpr = + ConcreteRegisterImpl::max_gpr + FloatRegisterImpl::number_of_registers; + +const char* RegisterImpl::name() const { + const char* names[number_of_registers] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" + }; + return is_valid() ? names[encoding()] : "noreg"; +} + +const char* FloatRegisterImpl::name() const { + const char* names[number_of_registers] = { + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" + }; + return is_valid() ? names[encoding()] : "noreg"; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/register_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,250 @@ +/* + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class VMRegImpl; +typedef VMRegImpl* VMReg; + +// Use Register as shortcut +class RegisterImpl; +typedef RegisterImpl* Register; + +inline Register as_Register(int encoding) { + return (Register)(intptr_t) encoding; +} + +// The implementation of integer registers for the ppc architecture +class RegisterImpl : public AbstractRegisterImpl { + public: + enum { + number_of_registers = 32 + }; + + // construction + inline friend Register as_Register(int encoding); + VMReg as_VMReg(); + + // derived registers, offsets, and addresses + Register successor() const + { + return as_Register(encoding() + 1); + } + + // accessors + int encoding() const + { + assert(is_valid(), "invalid register"); + return (intptr_t)this; + } + bool is_valid() const + { + return 0 <= (intptr_t) this && (intptr_t)this < number_of_registers; + } + const char* name() const; +}; + +// The integer registers of the ppc architecture +CONSTANT_REGISTER_DECLARATION(Register, r0, (0)); +CONSTANT_REGISTER_DECLARATION(Register, r1, (1)); +CONSTANT_REGISTER_DECLARATION(Register, r2, (2)); +CONSTANT_REGISTER_DECLARATION(Register, r3, (3)); +CONSTANT_REGISTER_DECLARATION(Register, r4, (4)); +CONSTANT_REGISTER_DECLARATION(Register, r5, (5)); +CONSTANT_REGISTER_DECLARATION(Register, r6, (6)); +CONSTANT_REGISTER_DECLARATION(Register, r7, (7)); +CONSTANT_REGISTER_DECLARATION(Register, r8, (8)); +CONSTANT_REGISTER_DECLARATION(Register, r9, (9)); +CONSTANT_REGISTER_DECLARATION(Register, r10, (10)); +CONSTANT_REGISTER_DECLARATION(Register, r11, (11)); +CONSTANT_REGISTER_DECLARATION(Register, r12, (12)); +CONSTANT_REGISTER_DECLARATION(Register, r13, (13)); +CONSTANT_REGISTER_DECLARATION(Register, r14, (14)); +CONSTANT_REGISTER_DECLARATION(Register, r15, (15)); +CONSTANT_REGISTER_DECLARATION(Register, r16, (16)); +CONSTANT_REGISTER_DECLARATION(Register, r17, (17)); +CONSTANT_REGISTER_DECLARATION(Register, r18, (18)); +CONSTANT_REGISTER_DECLARATION(Register, r19, (19)); +CONSTANT_REGISTER_DECLARATION(Register, r20, (20)); +CONSTANT_REGISTER_DECLARATION(Register, r21, (21)); +CONSTANT_REGISTER_DECLARATION(Register, r22, (22)); +CONSTANT_REGISTER_DECLARATION(Register, r23, (23)); +CONSTANT_REGISTER_DECLARATION(Register, r24, (24)); +CONSTANT_REGISTER_DECLARATION(Register, r25, (25)); +CONSTANT_REGISTER_DECLARATION(Register, r26, (26)); +CONSTANT_REGISTER_DECLARATION(Register, r27, (27)); +CONSTANT_REGISTER_DECLARATION(Register, r28, (28)); +CONSTANT_REGISTER_DECLARATION(Register, r29, (29)); +CONSTANT_REGISTER_DECLARATION(Register, r30, (30)); +CONSTANT_REGISTER_DECLARATION(Register, r31, (31)); + +// Use FloatRegister as shortcut +class FloatRegisterImpl; +typedef FloatRegisterImpl* FloatRegister; + +inline FloatRegister as_FloatRegister(int encoding) { + return (FloatRegister)(intptr_t) encoding; +} + +// The implementation of floating point registers for the ppc architecture +class FloatRegisterImpl : public AbstractRegisterImpl { + public: + enum { + number_of_registers = 32 + }; + + // construction + inline friend FloatRegister as_FloatRegister(int encoding); + VMReg as_VMReg(); + + // derived registers, offsets, and addresses + FloatRegister successor() const + { + return as_FloatRegister(encoding() + 1); + } + + // accessors + int encoding() const + { + assert(is_valid(), "invalid register"); + return (intptr_t)this; + } + bool is_valid() const + { + return 0 <= (intptr_t) this && (intptr_t)this < number_of_registers; + } + const char* name() const; +}; + +// The floating point registers of the ppc architecture +CONSTANT_REGISTER_DECLARATION(FloatRegister, f0, (0)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f1, (1)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f2, (2)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f3, (3)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f4, (4)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f5, (5)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f6, (6)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f7, (7)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f8, (8)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f9, (9)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f10, (10)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f11, (11)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f12, (12)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f13, (13)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f14, (14)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f15, (15)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f16, (16)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f17, (17)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f18, (18)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f19, (19)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f20, (20)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f21, (21)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f22, (22)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f23, (23)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f24, (24)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f25, (25)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f26, (26)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f27, (27)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f28, (28)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f29, (29)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f30, (30)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, f31, (31)); + +// Use ConditionRegister as shortcut +class ConditionRegisterImpl; +typedef ConditionRegisterImpl* ConditionRegister; + +inline ConditionRegister as_ConditionRegister(int encoding) { + return (ConditionRegister)(intptr_t) encoding; +} + +// The implementation of condition registers for the ppc architecture +class ConditionRegisterImpl : public AbstractRegisterImpl { + public: + enum { + number_of_registers = 8 + }; + + // construction + inline friend ConditionRegister as_ConditionRegister(int encoding); + + // accessors + int encoding() const + { + assert(is_valid(), "invalid register"); + return (intptr_t)this; + } + bool is_valid() const + { + return 0 <= (intptr_t) this && (intptr_t)this < number_of_registers; + } +}; + +// The condition registers registers of the ppc architecture +CONSTANT_REGISTER_DECLARATION(ConditionRegister, cr0, (0)); +CONSTANT_REGISTER_DECLARATION(ConditionRegister, cr1, (1)); +CONSTANT_REGISTER_DECLARATION(ConditionRegister, cr2, (2)); +CONSTANT_REGISTER_DECLARATION(ConditionRegister, cr3, (3)); +CONSTANT_REGISTER_DECLARATION(ConditionRegister, cr4, (4)); +CONSTANT_REGISTER_DECLARATION(ConditionRegister, cr5, (5)); +CONSTANT_REGISTER_DECLARATION(ConditionRegister, cr6, (6)); +CONSTANT_REGISTER_DECLARATION(ConditionRegister, cr7, (7)); + +// Use SpecialPurposeRegister as shortcut +class SpecialPurposeRegisterImpl; +typedef SpecialPurposeRegisterImpl* SpecialPurposeRegister; + +// The implementation of special purpose registers for the ppc architecture +class SpecialPurposeRegisterImpl : public AbstractRegisterImpl { + public: + enum { + number_of_registers = 3 + }; + + // accessors + int encoding() const + { + assert(is_valid(), "invalid register"); + return (intptr_t)this; + } + bool is_valid() const + { + return (intptr_t)this == 1 || (intptr_t)this == 8 || (intptr_t)this == 9; + } +}; + +// The special purpose registers registers of the ppc architecture +CONSTANT_REGISTER_DECLARATION(SpecialPurposeRegister, xer, (1)); +CONSTANT_REGISTER_DECLARATION(SpecialPurposeRegister, lr, (8)); +CONSTANT_REGISTER_DECLARATION(SpecialPurposeRegister, ctr, (9)); + +class ConcreteRegisterImpl : public AbstractRegisterImpl { + public: + enum { + number_of_registers = RegisterImpl::number_of_registers + + FloatRegisterImpl::number_of_registers + }; + + static const int max_gpr; + static const int max_fpr; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/relocInfo_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,68 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_relocInfo_ppc.cpp.incl" + +void Relocation::pd_set_data_value(address x, intptr_t o) +{ + Unimplemented(); +} + +address Relocation::pd_call_destination(address orig_addr) +{ + Unimplemented(); +} + +void Relocation::pd_set_call_destination(address x) +{ + Unimplemented(); +} + +address Relocation::pd_get_address_from_code() +{ + Unimplemented(); +} + +address* Relocation::pd_address_in_code() +{ + Unimplemented(); +} + +int Relocation::pd_breakpoint_size() +{ + Unimplemented(); +} + +void Relocation::pd_swap_in_breakpoint(address x, short* instrs, + int instrlen) +{ + Unimplemented(); +} + +void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) +{ + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/relocInfo_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,34 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + // machine-dependent parts of class relocInfo + private: + enum + { +#ifdef XXX_EVIL_EVIL_EVIL + offset_unit = 1, + format_width = 1 +#endif // XXX_EVIL_EVIL_EVIL + };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,248 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_sharedRuntime_ppc.cpp.incl" + +DeoptimizationBlob *SharedRuntime::_deopt_blob; +SafepointBlob *SharedRuntime::_polling_page_safepoint_handler_blob; +SafepointBlob *SharedRuntime::_polling_page_return_handler_blob; +RuntimeStub *SharedRuntime::_wrong_method_blob; +RuntimeStub *SharedRuntime::_ic_miss_blob; +RuntimeStub *SharedRuntime::_resolve_opt_virtual_call_blob; +RuntimeStub *SharedRuntime::_resolve_virtual_call_blob; +RuntimeStub *SharedRuntime::_resolve_static_call_blob; + +#define __ masm-> + +// Read the array of BasicTypes from a signature, and compute where +// the arguments should go. Values in the VMRegPair regs array refer +// to 4-byte quantities. XXX describe the mapping + +// Note that the INPUTS in sig_bt are in units of Java argument words, +// which are either 32-bit or 64-bit depending on the build. The +// OUTPUTS are in 32-bit units regardless of build. + +// XXX I'm not very confident I have all the set1/set2's and ++/+=2's right + +int SharedRuntime::java_calling_convention(const BasicType *sig_bt, + VMRegPair *regs, + int total_args_passed, + int is_outgoing) +{ + static const Register int_arg_register[8] = { + r3, r4, r5, r6, r7, r8, r9, r10 + }; + const int int_reg_max = 8; + +#ifdef PPC32 + static const FloatRegister fp_arg_register[8] = { + f1, f2, f3, f4, f5, f6, f7, f8 + }; + const int fp_reg_max = 8; +#else + static const FloatRegister fp_arg_register[13] = { + f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13 + }; + const int fp_reg_max = 13; +#endif // PPC32 + + int int_args = 0; + int fp_args = 0; + int stk_args = 0; + + const int slots_per_reg = wordSize / 4; + + for (int i = 0; i < total_args_passed; i++) { + switch (sig_bt[i]) { + case T_BOOLEAN: + case T_CHAR: + case T_BYTE: + case T_SHORT: + case T_INT: +#ifdef PPC32 + case T_OBJECT: + case T_ARRAY: + case T_ADDRESS: +#endif // PPC32 + if (int_args < int_reg_max) + regs[i].set1(int_arg_register[int_args++]->as_VMReg()); + else + regs[i].set1(VMRegImpl::stack2reg(stk_args += slots_per_reg)); + break; + + case T_LONG: + assert(sig_bt[i + 1] == T_VOID, "expecting void in other half"); +#ifdef PPC32 + if (int_args < int_reg_max - 1) { + if (int_args & 1) + int_args++; + regs[i].set2(int_arg_register[int_args += 2]->as_VMReg()); + } + else { + if (stk_args & 1) + stk_args++; + regs[i].set2(VMRegImpl::stack2reg(stk_args += 2)); + } + break; +#else + // fall through + case T_OBJECT: + case T_ARRAY: + case T_ADDRESS: + if (int_args < int_reg_max) + regs[i].set2(int_arg_register[int_args++]->as_VMReg()); + else + regs[i].set2(VMRegImpl::stack2reg(stk_args += 2)); + break; +#endif // PPC32 + + case T_FLOAT: + if (fp_args < fp_reg_max) + regs[i].set1(fp_arg_register[fp_args++]->as_VMReg()); + else + regs[i].set1(VMRegImpl::stack2reg(stk_args += slots_per_reg)); + break; + + case T_DOUBLE: + assert(sig_bt[i + 1] == T_VOID, "expecting void in other half"); + if (fp_args < fp_reg_max) + regs[i].set2(fp_arg_register[fp_args++]->as_VMReg()); + else { + if (stk_args & 1) + stk_args++; + regs[i].set2(VMRegImpl::stack2reg(stk_args += 2)); + } + break; + + case T_VOID: + assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), + "expecting long or double in other half"); + regs[i].set_bad(); + break; + + default: + ShouldNotReachHere(); + } + } + return stk_args; +} + +AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters( + MacroAssembler *masm, + int total_args_passed, + int comp_args_on_stack, + const BasicType *sig_bt, + const VMRegPair *regs) +{ + address i2c_entry = UnimplementedStub(); + address c2i_entry = UnimplementedStub(); + address c2i_unverified_entry = UnimplementedStub(); + return new AdapterHandlerEntry(i2c_entry, c2i_entry, c2i_unverified_entry); +} + +nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, + methodHandle method, + int total_in_args, + int comp_args_on_stack, + BasicType *in_sig_bt, + VMRegPair *in_regs, + BasicType ret_type) +{ + Unimplemented(); +} + +int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) +{ + Unimplemented(); +} + +uint SharedRuntime::out_preserve_stack_slots() +{ + Unimplemented(); +} + +static RuntimeStub* generate_unimplemented_runtime_stub(const char* file, + int line, + const char* name) +{ + ResourceMark rm; + CodeBuffer buffer(name, 1000, 512); + MacroAssembler* masm = new MacroAssembler(&buffer); + int frame_size_in_words = 0; // XXX + OopMapSet *oop_maps = new OopMapSet(); + StackFrame frame = StackFrame(); + __ enter(); + __ prolog(frame); + __ unimplemented(file, line); + __ epilog(frame); + __ blr(); + int frame_complete = __ offset(); // XXX + masm->flush(); + return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, + frame_size_in_words, oop_maps, true); +} + +static SafepointBlob* generate_unimplemented_safepoint_blob(const char* file, + int line) +{ + ResourceMark rm; + CodeBuffer buffer("handler_blob", 2048, 1024); + MacroAssembler* masm = new MacroAssembler(&buffer); + int frame_size_in_words = 0; // XXX + OopMapSet *oop_maps = new OopMapSet(); + StackFrame frame = StackFrame(); + __ enter(); + __ prolog(frame); + __ unimplemented(file, line); + __ epilog(frame); + __ blr(); + masm->flush(); + return SafepointBlob::create(&buffer, oop_maps, frame_size_in_words); +} + +void SharedRuntime::generate_stubs() +{ + _wrong_method_blob = + generate_unimplemented_runtime_stub(__FILE__, __LINE__, + "wrong_method_stub"); + _ic_miss_blob = + generate_unimplemented_runtime_stub(__FILE__, __LINE__, + "ic_miss_stub"); + _resolve_opt_virtual_call_blob = + generate_unimplemented_runtime_stub(__FILE__, __LINE__, + "resolve_opt_virtual_call"); + _resolve_virtual_call_blob = + generate_unimplemented_runtime_stub(__FILE__, __LINE__, + "resolve_virtual_call"); + _resolve_static_call_blob = + generate_unimplemented_runtime_stub(__FILE__, __LINE__, + "resolve_static_call"); + + _polling_page_safepoint_handler_blob = + generate_unimplemented_safepoint_blob(__FILE__, __LINE__); + _polling_page_return_handler_blob = + generate_unimplemented_safepoint_blob(__FILE__, __LINE__); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,512 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_stubGenerator_ppc.cpp.incl" + +// Declaration and definition of StubGenerator (no .hpp file). +// For a more detailed description of the stub routine structure +// see the comment in stubRoutines.hpp + +int StubRoutines::_call_stub_base_size = 0; + +#define __ _masm-> + +class StubGenerator: public StubCodeGenerator +{ + private: + // Call stubs are used to call Java from C + // + // Arguments: + // r3: call wrapper address address + // r4: result address + // r5: result type BasicType + // r6: method methodOop + // r7: (interpreter) entry point address + // r8: parameters intptr_t* + // r9: parameter size (in words) int + // r10: thread Thread* + + // The general layout of stack frames is identical for both ABIs: + // + // | ... | + // +-> | Caller's link area | high addresses + // | +----------------------+ + // | | Register save area | + // | | Local variable space | + // | | Parameter list space | + // +---+ Link area | low addresses + // +----------------------+ + // + // Specifically: + // * The local variable space is where the method stack will go. + // At method entry this is populated with the parameters. + // The entry then extends this to accomodate locals. + // * We don't use the parameter list space at all (though ppc64 + // requires us to allocate one) + // * We do a full register save before we enter the interpreter. + // + // So the specific layouts are as follows: + // + // 32-bit ABI: + // + // | ... | + // +--------------------------------+ + // | LR save word | + // +-> | Back chain | + // | +--------------------------------+ ----------------------------- + // | | GPR save area r31 | high addresses + // | | ... | 18 words + // | | r14 | + // | +--------------------------------+ + // | | CR save area | 1 word + // | +--------------------------------+ + // | | Local variable space | + // | | result_type | 1 word + // | | result | 1 word + // | | call_wrapper | 1 word + // | | parameter 0 | + // | | ... | n words + // | | parameter n-1 | + // | | padding | 0-3 words + // | +--------------------------------+ + // | | LR save word | 1 word + // +---+ Back chain | 1 word low addresses + // +--------------------------------+ ----------------------------- + // + // 64-bit ABI: + // + // | ... | + // | LR save word | + // | CR save word | + // +-> | Back chain | + // | +--------------------------------+ ----------------------------- + // | | GPR save area r31 | high addresses + // | | ... | 18 words + // | | r14 | + // | +--------------------------------+ + // | | Local variable space | + // | | result_type | 1 word + // | | result | 1 word + // | | call_wrapper | 1 word + // | | parameter 0 | + // | | ... | n words + // | | parameter n-1 | + // | | padding | 0-1 words + // | +--------------------------------+ + // | | Parameter list space | 8 (unused) words + // | +--------------------------------+ + // | | TOC save word | 1 word + // | | Reserved | 2 words + // | | LR save word | 1 word + // | | CR save word | 1 word + // +---+ Back chain | 1 word low addresses + // +--------------------------------+ ----------------------------- + + address generate_call_stub(address& return_address) + { + assert (!TaggedStackInterpreter, "not supported"); + + StubCodeMark mark(this, "StubRoutines", "call_stub"); + address start = __ enter(); + + const Register call_wrapper = r3; + const Register result = r4; + const Register result_type = r5; + const Register method = r6; + const Register entry_point = r7; + const Register parameters = r8; + const Register parameter_words = r9; + const Register thread = r10; + +#ifdef ASSERT + // Make sure we have no pending exceptions + { + StackFrame frame; + Label label; + + __ load (r0, Address(thread, Thread::pending_exception_offset())); + __ compare (r0, 0); + __ beq (label); + __ prolog (frame); + __ should_not_reach_here (__FILE__, __LINE__); + __ epilog (frame); + __ blr (); + __ bind (label); + } +#endif // ASSERT + + // Calculate the frame size + StackFrame frame; + for (int i = 0; i < StackFrame::max_crfs; i++) + frame.get_cr_field(); + for (int i = 0; i < StackFrame::max_gprs; i++) + frame.get_register(); + StubRoutines::set_call_stub_base_size(frame.unaligned_size() + 3*wordSize); + // the 3 extra words are for call_wrapper, result and result_type + + const Register parameter_bytes = parameter_words; + + __ shift_left (parameter_bytes, parameter_words, LogBytesPerWord); + + const Register frame_size = r11; + const Register padding = r12; + + __ addi (frame_size, parameter_bytes, StubRoutines::call_stub_base_size()); + __ calc_padding_for_alignment (padding, frame_size, 16); + __ add (frame_size, frame_size, padding); + + // Save the link register and create the new frame + __ mflr (r0); + __ store (r0, Address(r1, StackFrame::lr_save_offset * wordSize)); + __ neg (r0, frame_size); + __ store_update_indexed (r1, r1, r0); +#ifdef PPC64 + __ mfcr (r0); + __ store (r0, Address(r1, StackFrame::cr_save_offset * wordSize)); +#endif // PPC64 + + // Calculate the address of the interpreter's local variables + const Register locals = frame_size; + + __ addi (locals, r1, frame.start_of_locals() - wordSize); + __ add (locals, locals, padding); + __ add (locals, locals, parameter_bytes); + + // Store the call wrapper address and the result stuff + const int initial_offset = 1; + int offset = initial_offset; + + __ store (call_wrapper, Address(locals, offset++ * wordSize)); + __ store (result, Address(locals, offset++ * wordSize)); + __ store (result_type, Address(locals, offset++ * wordSize)); + + // Store the registers +#ifdef PPC32 + __ mfcr (r0); + __ store (r0, Address(locals, offset++ * wordSize)); +#endif // PPC32 + for (int i = 14; i < 32; i++) { + __ store (as_Register(i), Address(locals, offset++ * wordSize)); + } + const int final_offset = offset; + + // Store the location of call_wrapper + frame::set_call_wrapper_offset((final_offset - initial_offset) * wordSize); + +#ifdef ASSERT + // Check that we wrote all the way to the end of the frame. + // The frame may have been resized when we return from the + // interpreter, so the start of the frame may have moved + // but the end will be where we left it and we rely on this + // to find our stuff. + { + StackFrame frame; + Label label; + + __ load (r3, Address(r1, 0)); + __ subi (r3, r3, final_offset * wordSize); + __ compare (r3, locals); + __ beq (label); + __ prolog (frame); + __ should_not_reach_here (__FILE__, __LINE__); + __ epilog (frame); + __ blr (); + __ bind (label); + } +#endif // ASSERT + + // Pass parameters if any + { + Label loop, done; + + __ compare (parameter_bytes, 0); + __ ble (done); + + const Register src = parameters; + const Register dst = padding; + + __ mr (dst, locals); + __ shift_right (r0, parameter_bytes, LogBytesPerWord); + __ mtctr (r0); + __ bind (loop); + __ load (r0, Address(src, 0)); + __ store (r0, Address(dst, 0)); + __ addi (src, src, wordSize); + __ subi (dst, dst, wordSize); + __ bdnz (loop); + + __ bind (done); + } + + // Make the call + __ mr (Rmethod, method); + __ mr (Rlocals, locals); + __ mr (Rthread, thread); + __ mtlr (entry_point); + __ blrl(); + + // This is used to identify call_stub stack frames + return_address = __ pc(); + + // Figure out where our stuff is stored + __ load (locals, Address(r1, 0)); + __ subi (locals, locals, final_offset * wordSize); + +#ifdef ASSERT + // Rlocals should contain the address we just calculated. + { + StackFrame frame; + Label label; + + __ compare (Rlocals, locals); + __ beq (label); + __ prolog (frame); + __ should_not_reach_here (__FILE__, __LINE__); + __ epilog (frame); + __ blr (); + __ bind (label); + } +#endif // ASSERT + + // Is an exception being thrown? + Label exit; + + __ load (r0, Address(Rthread, Thread::pending_exception_offset())); + __ compare (r0, 0); + __ bne (exit); + + // Store result depending on type + const Register result_addr = r6; + + Label is_int, is_long, is_object; + + offset = initial_offset + 1; // skip call_wrapper + __ load (result_addr, Address(locals, offset++ * wordSize)); + __ load (result_type, Address(locals, offset++ * wordSize)); + __ compare (result_type, T_INT); + __ beq (is_int); + __ compare (result_type, T_LONG); + __ beq (is_long); + __ compare (result_type, T_OBJECT); + __ beq (is_object); + + __ should_not_reach_here (__FILE__, __LINE__); + + __ bind (is_int); + __ stw (r3, Address(result_addr, 0)); + __ b (exit); + + __ bind (is_long); +#ifdef PPC32 + __ store (r4, Address(result_addr, wordSize)); +#endif + __ store (r3, Address(result_addr, 0)); + __ b (exit); + + __ bind (is_object); + __ store (r3, Address(result_addr, 0)); + //__ b (exit); + + // Restore the registers + __ bind (exit); +#ifdef PPC32 + __ load (r0, Address(locals, offset++ * wordSize)); + __ mtcr (r0); +#endif // PPC32 + for (int i = 14; i < 32; i++) { + __ load (as_Register(i), Address(locals, offset++ * wordSize)); + } +#ifdef PPC64 + __ load (r0, Address(r1, StackFrame::cr_save_offset * wordSize)); + __ mtcr (r0); +#endif // PPC64 + assert (offset == final_offset, "save and restore must match"); + + // Unwind and return + __ load (r1, Address(r1, StackFrame::back_chain_offset * wordSize)); + __ load (r0, Address(r1, StackFrame::lr_save_offset * wordSize)); + __ mtlr (r0); + __ blr (); + + return start; + } + + // These stubs get called from some dumb test routine. + // I'll write them properly when they're called from + // something that's actually doing something. + address generate_arraycopy_stub(const char *name, int line) + { + StubCodeMark mark(this, "StubRoutines", name); + address start = __ enter(); + + const Register from = r3; // source array address + const Register to = r4; // destination array address + const Register count = r5; // element count + + __ compare (count, 0); + __ beqlr (); + __ unimplemented (__FILE__, line); + __ blr (); + + return start; + + } + + void generate_arraycopy_stubs() + { + // Call the conjoint generation methods immediately after + // the disjoint ones so that short branches from the former + // to the latter can be generated. + StubRoutines::_jbyte_disjoint_arraycopy = + generate_arraycopy_stub("jbyte_disjoint_arraycopy", __LINE__); + StubRoutines::_jbyte_arraycopy = + generate_arraycopy_stub("jbyte_arraycopy", __LINE__); + + StubRoutines::_jshort_disjoint_arraycopy = + generate_arraycopy_stub("jshort_disjoint_arraycopy", __LINE__); + StubRoutines::_jshort_arraycopy = + generate_arraycopy_stub("jshort_arraycopy", __LINE__); + + StubRoutines::_jint_disjoint_arraycopy = + generate_arraycopy_stub("jint_disjoint_arraycopy", __LINE__); + StubRoutines::_jint_arraycopy = + generate_arraycopy_stub("jint_arraycopy", __LINE__); + + StubRoutines::_jlong_disjoint_arraycopy = + generate_arraycopy_stub("jlong_disjoint_arraycopy", __LINE__); + StubRoutines::_jlong_arraycopy = + generate_arraycopy_stub("jlong_arraycopy", __LINE__); + + StubRoutines::_oop_disjoint_arraycopy = UnimplementedStub(); + StubRoutines::_oop_arraycopy = UnimplementedStub(); + + StubRoutines::_checkcast_arraycopy = UnimplementedStub(); + StubRoutines::_unsafe_arraycopy = UnimplementedStub(); + StubRoutines::_generic_arraycopy = UnimplementedStub(); + + // We don't generate specialized code for HeapWord-aligned source + // arrays, so just use the code we've already generated + StubRoutines::_arrayof_jbyte_disjoint_arraycopy = + StubRoutines::_jbyte_disjoint_arraycopy; + StubRoutines::_arrayof_jbyte_arraycopy = + StubRoutines::_jbyte_arraycopy; + + StubRoutines::_arrayof_jshort_disjoint_arraycopy = + StubRoutines::_jshort_disjoint_arraycopy; + StubRoutines::_arrayof_jshort_arraycopy = + StubRoutines::_jshort_arraycopy; + + StubRoutines::_arrayof_jint_disjoint_arraycopy = + StubRoutines::_jint_disjoint_arraycopy; + StubRoutines::_arrayof_jint_arraycopy = + StubRoutines::_jint_arraycopy; + + StubRoutines::_arrayof_jlong_disjoint_arraycopy = + StubRoutines::_jlong_disjoint_arraycopy; + StubRoutines::_arrayof_jlong_arraycopy = + StubRoutines::_jlong_arraycopy; + + StubRoutines::_arrayof_oop_disjoint_arraycopy = + StubRoutines::_oop_disjoint_arraycopy; + StubRoutines::_arrayof_oop_arraycopy = + StubRoutines::_oop_arraycopy; + } + + void generate_initial() + { + // Generates all stubs and initializes the entry points + + // entry points that exist in all platforms Note: This is code + // that could be shared among different platforms - however the + // benefit seems to be smaller than the disadvantage of having a + // much more complicated generator structure. See also comment in + // stubRoutines.hpp. + + StubRoutines::_forward_exception_entry = UnimplementedStub(); + StubRoutines::_call_stub_entry = + generate_call_stub(StubRoutines::_call_stub_return_address); + StubRoutines::_catch_exception_entry = UnimplementedStub(); + + // atomic calls + StubRoutines::_atomic_xchg_entry = UnimplementedStub(); + StubRoutines::_atomic_xchg_ptr_entry = UnimplementedStub(); + StubRoutines::_atomic_cmpxchg_entry = UnimplementedStub(); + StubRoutines::_atomic_cmpxchg_ptr_entry = UnimplementedStub(); + StubRoutines::_atomic_cmpxchg_long_entry = UnimplementedStub(); + StubRoutines::_atomic_add_entry = UnimplementedStub(); + StubRoutines::_atomic_add_ptr_entry = UnimplementedStub(); + StubRoutines::_fence_entry = UnimplementedStub(); + + // amd64 does this here, sparc does it in generate_all() + StubRoutines::_handler_for_unsafe_access_entry = + UnimplementedStub(); + } + + void generate_all() + { + // Generates all stubs and initializes the entry points + + // These entry points require SharedInfo::stack0 to be set up in + // non-core builds and need to be relocatable, so they each + // fabricate a RuntimeStub internally. + StubRoutines::_throw_AbstractMethodError_entry = + UnimplementedStub(); + + StubRoutines::_throw_ArithmeticException_entry = + UnimplementedStub(); + + StubRoutines::_throw_NullPointerException_entry = + UnimplementedStub(); + + StubRoutines::_throw_NullPointerException_at_call_entry = + UnimplementedStub(); + + StubRoutines::_throw_StackOverflowError_entry = + UnimplementedStub(); + + // support for verify_oop (must happen after universe_init) + StubRoutines::_verify_oop_subroutine_entry = + UnimplementedStub(); + + // arraycopy stubs used by compilers + generate_arraycopy_stubs(); + } + + public: + StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) + { + if (all) { + generate_all(); + } else { + generate_initial(); + } + } +}; + +void StubGenerator_generate(CodeBuffer* code, bool all) +{ + StubGenerator g(code, all); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/stubRoutines_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,56 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file holds the platform specific parts of the StubRoutines +// definition. See stubRoutines.hpp for a description on how to +// extend it. + + public: + static bool returns_to_call_stub(address return_pc) + { + return return_pc == _call_stub_return_address; + } + + enum platform_dependent_constants + { + code_size1 = 4 * K, // The assembler will fail with a guarantee + code_size2 = 12 * K // if these are too small. Simply increase + }; // them if that happens. + + private: + static int _call_stub_base_size; + + public: + static int call_stub_base_size() + { + assert(_call_stub_base_size != 0, "call_stub_base_size not set"); + return _call_stub_base_size; + } + + static void set_call_stub_base_size(int size) + { + assert(_call_stub_base_size == 0, "call_stub_base_size already set"); + _call_stub_base_size = size; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/vmStructs_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,52 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// These are the CPU-specific fields, types and integer +// constants required by the Serviceability Agent. This file is +// referenced by vmStructs.cpp. + +#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */ + /* be present there) */ + +#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */ + /* be present there) */ + +#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */ + /* be present there) */ + +#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */ + /* be present there) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/vm_version_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,32 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class VM_Version : public Abstract_VM_Version { + public: + static const char* cpu_features() + { + return ""; + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/vmreg_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,45 @@ +/* + * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_vmreg_ppc.cpp.incl" + +void VMRegImpl::set_regName() +{ + int i = 0; + Register reg = ::as_Register(0); + for ( ; i < ConcreteRegisterImpl::max_gpr ; ) { + regName[i++] = reg->name(); + reg = reg->successor(); + } + FloatRegister freg = ::as_FloatRegister(0); + for ( ; i < ConcreteRegisterImpl::max_fpr ; ) { + regName[i++] = freg->name(); + freg = freg->successor(); + } + for ( ; i < ConcreteRegisterImpl::number_of_registers; i++) { + Unimplemented(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/vmreg_ppc.inline.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,32 @@ +/* + * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ +inline VMReg RegisterImpl::as_VMReg() +{ + return VMRegImpl::as_VMReg(encoding()); +} +inline VMReg FloatRegisterImpl::as_VMReg() +{ + return VMRegImpl::as_VMReg(encoding() + ConcreteRegisterImpl::max_gpr); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/ppc/vm/vtableStubs_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,47 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_vtableStubs_ppc.cpp.incl" + +VtableStub* VtableStubs::create_vtable_stub(int vtable_index) +{ + Unimplemented(); +} + +VtableStub* VtableStubs::create_itable_stub(int vtable_index) +{ + Unimplemented(); +} + +int VtableStub::pd_code_size_limit(bool is_vtable_stub) +{ + Unimplemented(); +} + +int VtableStub::pd_code_alignment() +{ + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,160 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Implementation of class atomic + +// inline void Atomic::store(jbyte store_value, jbyte* dest) +// { +// Unimplemented(); +// } +// inline void Atomic::store(jshort store_value, jshort* dest) +// { +// Unimplemented(); +// } +// inline void Atomic::store(jint store_value, jint* dest) +// { +// Unimplemented(); +// } +// inline void Atomic::store(jlong store_value, jlong* dest) +// { +// Unimplemented(); +// } +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) +{ + Unimplemented(); +} +// inline void Atomic::store_ptr(void* store_value, void* dest) +// { +// Unimplemented(); +// } + +// inline void Atomic::store(jbyte store_value, volatile jbyte* dest) +// { +// Unimplemented(); +// } +// inline void Atomic::store(jshort store_value, volatile jshort* dest) +// { +// Unimplemented(); +// } +inline void Atomic::store(jint store_value, volatile jint* dest) +{ + *dest = store_value; +} +// inline void Atomic::store(jlong store_value, volatile jlong* dest) +// { +// Unimplemented(); +// } +// inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) +// { +// Unimplemented(); +// } +// inline void Atomic::store_ptr(void* store_value, volatile void* dest) +// { +// Unimplemented(); +// } + +inline jint Atomic::add(jint add_value, volatile jint* dest) +{ + return __sync_add_and_fetch(dest, add_value); +} + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) +{ + return __sync_add_and_fetch(dest, add_value); +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) +{ + return (void*)add_ptr(add_value, (volatile intptr_t*)dest); +} + +inline void Atomic::inc(volatile jint* dest) +{ + add(1, dest); +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) +{ + add_ptr(1, dest); +} + +inline void Atomic::inc_ptr(volatile void* dest) +{ + add_ptr(1, dest); +} + +inline void Atomic::dec(volatile jint* dest) +{ + add(-1, dest); +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) +{ + add_ptr(-1, dest); +} + +inline void Atomic::dec_ptr(volatile void* dest) +{ + add_ptr(-1, dest); +} + +inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) +{ + // __sync_lock_test_and_set is a bizarrely named atomic exchange + // operation. Note that some platforms only support this with the + // limitation that the only valid value to store is the immediate + // constant 1. There is a test for this in JNI_CreateJavaVM(). + return __sync_lock_test_and_set (dest, exchange_value); +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) +{ + return __sync_lock_test_and_set (dest, exchange_value); +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) +{ + return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); +} + +inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value) +{ + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); +} + +inline jlong Atomic::cmpxchg(jlong exchange_value, volatile jlong* dest, jlong compare_value) +{ + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) +{ + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) +{ + return (void*)cmpxchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest, (intptr_t)compare_value); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/bytes_linux_ppc.inline.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,43 @@ +/* + * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Efficient swapping of data bytes from Java byte +// ordering to native byte ordering and vice versa. + +#include <byteswap.h> + +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); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// +// Set the default values for platform dependent flags used by the +// runtime system. See globals.hpp for details of what they do. +// + +define_pd_global(bool, DontYieldALot, false); +#ifdef PPC64 +define_pd_global(intx, ThreadStackSize, 1024); +define_pd_global(intx, VMThreadStackSize, 1024); +#else +define_pd_global(intx, ThreadStackSize, 512); +define_pd_global(intx, VMThreadStackSize, 512); +#endif // PPC64 +define_pd_global(intx, SurvivorRatio, 8); +define_pd_global(intx, CompilerThreadStackSize, 0); +define_pd_global(uintx, JVMInvokeMethodSlack, 8192); + +define_pd_global(bool, UseVectoredExceptions, false);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/linux_ppc.s Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,76 @@ +# +# Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007 Red Hat, Inc. +# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + + .global SpinPause + .global SafeFetch32 + .global SafeFetchN + + # int SpinPause() +SpinPause: + nop + blr + + # int SafeFetch32(int *adr, int errValue) + # intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) +SafeFetch32: +SafeFetchN: + mr %r5, %r3 + mr %r3, %r4 + lwz %r3, 0(%r5) + blr + + .global _Copy_conjoint_jints_atomic + + # void _Copy_conjoint_jints_atomic(jint* from, + # jint* to, + # size_t count) + # if (from > to) { + # for (int i = 0; i < count; i++) { + # to[count] = from[count]; + # } + # } else { + # while (count-- >= 0) { + # to[count] = from[count]; + # } + # } +_Copy_conjoint_jints_atomic: + slwi %r5, %r5, 2 + cmpw %r3, %r4 + ble 3f +cla_LeftToRight: + li %r6, 0 + b 2f +1: lwzx %r0, %r3, %r6 + stwx %r0, %r4, %r6 + addi %r6, %r6, 4 +2: cmpw %r6, %r5 + blt 1b + blr +cla_RightToLeft: + subi %r5, %r5, 4 + lwzx %r0, %r3, %r5 + stwx %r0, %r4, %r5 +3: cmpwi %r5, 0 + bgt cla_RightToLeft + blr
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/linux_ppc64.s Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,96 @@ +# +# Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007 Red Hat, Inc. +# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + + .global SpinPause + .global SafeFetch32 + .global SafeFetchN + + .section ".opd","aw" +SpinPause: .quad .SpinPause, .TOC.@tocbase,0 +SafeFetch32: .quad .SafeFetch32, .TOC.@tocbase,0 +SafeFetchN: .quad .SafeFetchN, .TOC.@tocbase,0 + .previous + .global .SpinPause + .global .SafeFetch32 + .global .SafeFetchN + + # int SpinPause() +.SpinPause: + nop + blr + + # int SafeFetch32(int *adr, int errValue) +.SafeFetch32: + mr %r5, %r3 + mr %r3, %r4 + lwz %r3, 0(%r5) + blr + + # intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) +.SafeFetchN: + mr %r5, %r3 + mr %r3, %r4 + ld %r3, 0(%r5) + blr + + + .global _Copy_conjoint_jlongs_atomic + .section ".opd","aw" +_Copy_conjoint_jlongs_atomic: + .quad ._Copy_conjoint_jlongs_atomic, .TOC.@tocbase,0 + .previous + .global ._Copy_conjoint_jlongs_atomic + + # void _Copy_conjoint_jlongs_atomic(jlong* from, + # jlong* to, + # size_t count) + # if (from > to) { + # for (int i = 0; i < count; i++) { + # to[count] = from[count]; + # } + # } else { + # while (count-- >= 0) { + # to[count] = from[count]; + # } + # } +._Copy_conjoint_jlongs_atomic: + sldi %r5, %r5, 3 + cmpd %r3, %r4 + ble 3f +cla_LeftToRight: + li %r6, 0 + b 2f +1: ldx %r0, %r3, %r6 + stdx %r0, %r4, %r6 + addi %r6, %r6, 8 +2: cmpd %r6, %r5 + blt 1b + blr +cla_RightToLeft: + subi %r5, %r5, 8 + ldx %r0, %r3, %r5 + stdx %r0, %r4, %r5 +3: cmpdi %r5, 0 + bgt cla_RightToLeft + blr
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/orderAccess_linux_ppc.inline.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,101 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +inline void OrderAccess::loadload() { acquire(); } +inline void OrderAccess::storestore() { release(); } +inline void OrderAccess::loadstore() { acquire(); } +inline void OrderAccess::storeload() { fence(); } + +inline void OrderAccess::acquire() +{ + __sync_synchronize(); +} + +inline void OrderAccess::release() +{ + __sync_synchronize(); +} + +inline void OrderAccess::fence() +{ + __sync_synchronize(); +} + +inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { return *p; } +inline jshort OrderAccess::load_acquire(volatile jshort* p) { return *p; } +inline jint OrderAccess::load_acquire(volatile jint* p) { return *p; } +inline jlong OrderAccess::load_acquire(volatile jlong* p) { return *p; } +inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { return *p; } +inline jushort OrderAccess::load_acquire(volatile jushort* p) { return *p; } +inline juint OrderAccess::load_acquire(volatile juint* p) { return *p; } +inline julong OrderAccess::load_acquire(volatile julong* p) { return *p; } +inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { return *p; } +inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return *p; } + +inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { return *p; } +inline void* OrderAccess::load_ptr_acquire(volatile void* p) { return *(void* volatile *)p; } +inline void* OrderAccess::load_ptr_acquire(const volatile void* p) { return *(void* const volatile *)p; } + +inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { *p = v; } +inline void OrderAccess::release_store(volatile jshort* p, jshort v) { *p = v; } +inline void OrderAccess::release_store(volatile jint* p, jint v) { *p = v; } +inline void OrderAccess::release_store(volatile jlong* p, jlong v) { *p = v; } +inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { *p = v; } +inline void OrderAccess::release_store(volatile jushort* p, jushort v) { *p = v; } +inline void OrderAccess::release_store(volatile juint* p, juint v) { *p = v; } +inline void OrderAccess::release_store(volatile julong* p, julong v) { *p = v; } +inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { *p = v; } +inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { *p = v; } + +inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { *p = v; } +inline void OrderAccess::release_store_ptr(volatile void* p, void* v) { *(void* volatile *)p = v; } + +inline void OrderAccess::store_fence(jbyte* p, jbyte v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jshort* p, jshort v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jint* p, jint v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jlong* p, jlong v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jubyte* p, jubyte v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jushort* p, jushort v) { *p = v; fence(); } +inline void OrderAccess::store_fence(juint* p, juint v) { *p = v; fence(); } +inline void OrderAccess::store_fence(julong* p, julong v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jfloat* p, jfloat v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jdouble* p, jdouble v) { *p = v; fence(); } + +inline void OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v) { *p = v; fence(); } +inline void OrderAccess::store_ptr_fence(void** p, void* v) { *p = v; fence(); } + +inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) { *p = v; fence(); } +inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) { *p = v; fence(); } +inline void OrderAccess::release_store_fence(volatile jint* p, jint v) { *p = v; fence(); } +inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { *p = v; fence(); } +inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { *p = v; fence(); } +inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { *p = v; fence(); } +inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { *p = v; fence(); } +inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { *p = v; fence(); } +inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { *p = v; fence(); } +inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { *p = v; fence(); } + +inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { *p = v; fence(); } +inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) { *(void* volatile *)p = v; fence(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,305 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// do not include precompiled header file +#include "incls/_os_linux_ppc.cpp.incl" + +address os::current_stack_pointer() +{ + register address *r1 __asm__ ("r1"); + return *r1; +} + +frame os::get_sender_for_C_frame(frame* fr) +{ + return frame(fr->sender_sp()); +} + +frame os::current_frame() +{ + frame myframe((intptr_t*) os::current_stack_pointer()); + return os::get_sender_for_C_frame(&myframe); +} + +char* os::non_memory_address_word() +{ + Unimplemented(); +} + +void os::initialize_thread() +{ + // Nothing to do. +} + +address os::Linux::ucontext_get_pc(ucontext_t* uc) +{ + Unimplemented(); +} + +ExtendedPC os::fetch_frame_from_context(void* ucVoid, + intptr_t** ret_sp, + intptr_t** ret_fp) { + Unimplemented(); +} + +frame os::fetch_frame_from_context(void* ucVoid) +{ + Unimplemented(); +} + +julong os::allocatable_physical_memory(julong size) +{ + Unimplemented(); +} + +extern "C" int +JVM_handle_linux_signal(int sig, + siginfo_t* info, + void* ucVoid, + int abort_if_unrecognized) +{ + ucontext_t* uc = (ucontext_t*) ucVoid; + + Thread* t = ThreadLocalStorage::get_thread_slow(); + + SignalHandlerMark shm(t); + + // Note: it's not uncommon that JNI code uses signal/sigset to + // install then restore certain signal handler (e.g. to temporarily + // block SIGPIPE, or have a SIGILL handler when detecting CPU + // type). When that happens, JVM_handle_linux_signal() might be + // invoked with junk info/ucVoid. To avoid unnecessary crash when + // libjsig is not preloaded, try handle signals that do not require + // siginfo/ucontext first. + + if (sig == SIGPIPE || sig == SIGXFSZ) { + // allow chained handler to go first + if (os::Linux::chained_handler(sig, info, ucVoid)) { + return true; + } else { + if (PrintMiscellaneous && (WizardMode || Verbose)) { + char buf[64]; + warning("Ignoring %s - see bugs 4229104 or 646499219", + os::exception_name(sig, buf, sizeof(buf))); + } + return true; + } + } + + char *fmt = "caught unhandled signal %d"; + char buf[64]; + + sprintf(buf, fmt, sig); + fatal(buf); +} + +void os::Linux::init_thread_fpu_state(void) +{ + // Nothing to do +} + +int os::Linux::get_fpu_control_word() +{ + Unimplemented(); +} + +void os::Linux::set_fpu_control_word(int fpu) +{ + Unimplemented(); +} + +/////////////////////////////////////////////////////////////////////////////// +// thread stack + +size_t os::Linux::min_stack_allowed = 64 * K; + +bool os::Linux::supports_variable_stack_size() +{ + return true; +} + +size_t os::Linux::default_stack_size(os::ThreadType thr_type) +{ + // default stack size (compiler thread needs larger stack) +#ifdef PPC64 + size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); +#else + size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K); +#endif // PPC64 + return s; +} + +size_t os::Linux::default_guard_size(os::ThreadType thr_type) +{ + // Creating guard page is very expensive. Java thread has HotSpot + // guard page, only enable glibc guard page for non-Java threads. + return (thr_type == java_thread ? 0 : page_size()); +} + +// Java thread: +// +// Low memory addresses +// +------------------------+ +// | |\ JavaThread created by VM does not have glibc +// | glibc guard page | - guard, attached Java thread usually has +// | |/ 1 page glibc guard. +// P1 +------------------------+ Thread::stack_base() - Thread::stack_size() +// | |\ +// | HotSpot Guard Pages | - red and yellow pages +// | |/ +// +------------------------+ JavaThread::stack_yellow_zone_base() +// | |\ +// | Normal Stack | - +// | |/ +// P2 +------------------------+ Thread::stack_base() +// +// Non-Java thread: +// +// Low memory addresses +// +------------------------+ +// | |\ +// | glibc guard page | - usually 1 page +// | |/ +// P1 +------------------------+ Thread::stack_base() - Thread::stack_size() +// | |\ +// | Normal Stack | - +// | |/ +// P2 +------------------------+ Thread::stack_base() +// +// ** P1 (aka bottom) and size ( P2 = P1 - size) are the address and stack size returned from +// pthread_attr_getstack() + +static void current_stack_region(address* bottom, size_t* size) { + if (os::Linux::is_initial_thread()) { + // initial thread needs special handling because pthread_getattr_np() + // may return bogus value. + *bottom = os::Linux::initial_thread_stack_bottom(); + *size = os::Linux::initial_thread_stack_size(); + } else { + pthread_attr_t attr; + + int rslt = pthread_getattr_np(pthread_self(), &attr); + + // JVM needs to know exact stack location, abort if it fails + if (rslt != 0) { + if (rslt == ENOMEM) { + vm_exit_out_of_memory(0, "pthread_getattr_np"); + } else { + fatal1("pthread_getattr_np failed with errno = %d", rslt); + } + } + + if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0 ) { + fatal("Can not locate current stack attributes!"); + } + + pthread_attr_destroy(&attr); + + } + assert(os::current_stack_pointer() >= *bottom && + os::current_stack_pointer() < *bottom + *size, "just checking"); +} + +address os::current_stack_base() +{ + address bottom; + size_t size; + current_stack_region(&bottom, &size); + return bottom + size; +} + +size_t os::current_stack_size() +{ + // stack size includes normal stack and HotSpot guard pages + address bottom; + size_t size; + current_stack_region(&bottom, &size); + return size; +} + +///////////////////////////////////////////////////////////////////////////// +// helper functions for fatal error handler + +void os::print_context(outputStream* st, void* context) +{ + Unimplemented(); +} + +///////////////////////////////////////////////////////////////////////////// +// Stubs for things that should be in linux_ppc.s + +extern "C" { + +#ifndef PPC32 + void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) + { + Unimplemented(); + } +#endif // !PPC32 + +#ifndef PPC64 + void _Copy_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) + { +#if defined(PPC32) && defined(XXX_EVIL_EVIL_EVIL) + _Copy_conjoint_jints_atomic((jint *) from, (jint *) to, count * 2); +#else + Unimplemented(); +#endif // PPC32 && XXX_EVIL_EVIL_EVIL + } +#endif // !PPC64 + + void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) + { + Unimplemented(); + } + void _Copy_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) + { + Unimplemented(); + } + void _Copy_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, + size_t count) { + Unimplemented(); + } + void _Copy_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) + { + Unimplemented(); + } + void _Copy_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, + size_t count) { + Unimplemented(); + } + + // Implementations of atomic operations not supported by processors. + // -- http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Atomic-Builtins.html +#ifndef PPC64 + long long unsigned int __sync_val_compare_and_swap_8( + volatile void *ptr, + long long unsigned int oldval, + long long unsigned int newval) + { + Unimplemented(); + } +#endif // !PPC64 +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,33 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + static void setup_fpu() + { + } + + // Used to register dynamic code cache area with the OS + // Note: Currently only used in 64 bit Windows implementations + static bool register_code_area(char *low, char *high) { return true; } +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/prefetch_linux_ppc.inline.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,34 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +inline void Prefetch::read(void* loc, intx interval) +{ + // XXX could we do something here? +} + +inline void Prefetch::write(void* loc, intx interval) +{ + // XXX could we do something here? +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.cpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,42 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_threadLS_linux_ppc.cpp.incl" + +void ThreadLocalStorage::generate_code_for_get_thread() +{ + // nothing to do +} + +void ThreadLocalStorage::pd_init() +{ + // nothing to do +} + +void ThreadLocalStorage::pd_set_thread(Thread* thread) +{ + os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,32 @@ +/* + * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Processor dependent parts of ThreadLocalStorage + +public: + + static Thread* thread() + { + return (Thread*) os::thread_local_storage_at(thread_index()); + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/thread_linux_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +private: + void pd_initialize() + { + _anchor.clear(); + } + + frame pd_last_frame() + { + assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); + if (_anchor.last_Java_pc() != NULL) { + return frame(_anchor.last_Java_sp(), _anchor.last_Java_pc()); + } else { + // This will pick up pc from sp + return frame(_anchor.last_Java_sp()); + } + } + +public: + void set_base_of_stack_pointer(intptr_t* base_sp) + { + } + + void record_base_of_stack_pointer() + { + } + + bool pd_get_top_frame_for_signal_handler(frame* fr_addr, + void* ucontext, + bool isInJava) + { + Unimplemented(); + } + + // These routines are only used on cpu architectures that + // have separate register stacks (Itanium). + static bool register_stack_overflow() { return false; } + static void enable_register_stack_guard() {} + static void disable_register_stack_guard() {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/os_cpu/linux_ppc/vm/vmStructs_linux_ppc.hpp Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,45 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// These are the OS and CPU-specific fields, types and integer +// constants required by the Serviceability Agent. This file is +// referenced by vmStructs.cpp. + +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry() + + +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry() + +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry() + +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/j2se/src/solaris/bin/ergo_ppc.c Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,58 @@ +/* + * Copyright 1998-2007 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +#include "ergo.h" + + +/* Methods for solaris-sparc and linux-sparc: these are easy. */ + +/* Ask the OS how many processors there are. */ +static unsigned long +physical_processors(void) { + const unsigned long sys_processors = sysconf(_SC_NPROCESSORS_CONF); + + JLI_TraceLauncher("sysconf(_SC_NPROCESSORS_CONF): %lu\n", sys_processors); + return sys_processors; +} + +/* The sparc version of the "server-class" predicate. */ +jboolean +ServerClassMachineImpl(void) { + jboolean result = JNI_FALSE; + /* How big is a server class machine? */ + const unsigned long server_processors = 2UL; + const uint64_t server_memory = 2UL * GB; + const uint64_t actual_memory = physical_memory(); + + /* Is this a server class machine? */ + if (actual_memory >= server_memory) { + const unsigned long actual_processors = physical_processors(); + if (actual_processors >= server_processors) { + result = JNI_TRUE; + } + } + JLI_TraceLauncher("unix_" LIBARCHNAME "_ServerClassMachine: %s\n", + (result == JNI_TRUE ? "JNI_TRUE" : "JNI_FALSE")); + return result; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/j2se/src/solaris/bin/ppc/jvm.cfg Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,44 @@ +# +# @(#)jvm.cfg 1.7 07/05/05 +# +# +# Copyright 2002-2003 Sun Microsystems, 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. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# +# +# +# List of JVMs that can be used as an option to java, javac, etc. +# Order is important -- first in this list is the default JVM. +# NOTE that this both this file and its format are UNSUPPORTED and +# WILL GO AWAY in a future release. +# +# You may also select a JVM in an arbitrary location with the +# "-XXaltjvm=<jvm_dir>" option, but that too is unsupported +# and may not be available in a future release. +# +-server KNOWN +-hotspot ERROR +-classic WARN +-client IGNORE +-native ERROR +-green ERROR
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/j2se/src/solaris/bin/ppc64/jvm.cfg Mon Nov 12 06:37:43 2007 -0500 @@ -0,0 +1,44 @@ +# +# @(#)jvm.cfg 1.7 07/05/05 +# +# +# Copyright 2002-2003 Sun Microsystems, 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. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# +# +# +# List of JVMs that can be used as an option to java, javac, etc. +# Order is important -- first in this list is the default JVM. +# NOTE that this both this file and its format are UNSUPPORTED and +# WILL GO AWAY in a future release. +# +# You may also select a JVM in an arbitrary location with the +# "-XXaltjvm=<jvm_dir>" option, but that too is unsupported +# and may not be available in a future release. +# +-server KNOWN +-hotspot ERROR +-classic WARN +-client IGNORE +-native ERROR +-green ERROR