Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/hotspot/cpu/ppc/registerMap_ppc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2026 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

#include "runtime/registerMap.hpp"

address RegisterMap::pd_location(VMReg base_reg, int slot_idx) const {
if (base_reg->is_VectorRegister()) {
// Not all physical slots belonging to a VectorRegister have corresponding
// valid VMReg locations in the RegisterMap.
// (See RegisterSaver::push_frame_reg_args_and_save_live_registers.)
// However, the slots are always saved to the stack in a contiguous region
// of memory so we can calculate the address of the upper slots by
// offsetting from the base address.
assert(base_reg->is_concrete(), "must pass base reg");
address base_location = location(base_reg, nullptr);
if (base_location != nullptr) {
intptr_t offset_in_bytes = slot_idx * VMRegImpl::stack_slot_size;
return base_location + offset_in_bytes;
} else {
return nullptr;
}
} else {
return location(base_reg->next(slot_idx), nullptr);
}
}
8 changes: 3 additions & 5 deletions src/hotspot/cpu/ppc/registerMap_ppc.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013 SAP SE. All rights reserved.
* Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2026 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -35,9 +35,7 @@
// Since there is none, we just return null.
address pd_location(VMReg reg) const { return nullptr; }

address pd_location(VMReg base_reg, int slot_idx) const {
return location(base_reg->next(slot_idx), nullptr);
}
address pd_location(VMReg base_reg, int slot_idx) const;

// no PD state to clear or copy:
void pd_clear() {}
Expand Down
27 changes: 18 additions & 9 deletions src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class RegisterSaver {

// During deoptimization only the result registers need to be restored
// all the other values have already been extracted.
static void restore_result_registers(MacroAssembler* masm, int frame_size_in_bytes);
static void restore_result_registers(MacroAssembler* masm, int frame_size_in_bytes, bool save_vectors);

// Constants and data structures:

Expand Down Expand Up @@ -355,7 +355,7 @@ OopMap* RegisterSaver::push_frame_reg_args_and_save_live_registers(MacroAssemble
}

// Note that generate_oop_map in the following loop is only used for the
// polling_page_vectors_safepoint_handler_blob.
// polling_page_vectors_safepoint_handler_blob and the deopt_blob.
// The order in which the vector contents are stored depends on Endianess and
// the utilized instructions (PowerArchitecturePPC64).
assert(is_aligned(offset, StackAlignmentInBytes), "should be");
Expand All @@ -367,6 +367,7 @@ OopMap* RegisterSaver::push_frame_reg_args_and_save_live_registers(MacroAssemble

__ stxvp(as_VectorRegister(reg_num).to_vsr(), offset, R1_SP);
// Note: The contents were read in the same order (see loadV16_Power9 node in ppc.ad).
// RegisterMap::pd_location only uses the first VMReg for each VectorRegister.
if (generate_oop_map) {
map->set_callee_saved(VMRegImpl::stack2reg(offset >> 2),
RegisterSaver_LiveVecRegs[i LITTLE_ENDIAN_ONLY(+1) ].vmreg);
Expand All @@ -386,6 +387,7 @@ OopMap* RegisterSaver::push_frame_reg_args_and_save_live_registers(MacroAssemble
__ stxvd2x(as_VectorRegister(reg_num)->to_vsr(), R31, R1_SP);
}
// Note: The contents were read in the same order (see loadV16_Power8 / loadV16_Power9 node in ppc.ad).
// RegisterMap::pd_location only uses the first VMReg for each VectorRegister.
if (generate_oop_map) {
VMReg vsr = RegisterSaver_LiveVecRegs[i].vmreg;
map->set_callee_saved(VMRegImpl::stack2reg(offset >> 2), vsr);
Expand Down Expand Up @@ -572,10 +574,14 @@ void RegisterSaver::restore_argument_registers_and_pop_frame(MacroAssembler*masm
}

// Restore the registers that might be holding a result.
void RegisterSaver::restore_result_registers(MacroAssembler* masm, int frame_size_in_bytes) {
void RegisterSaver::restore_result_registers(MacroAssembler* masm, int frame_size_in_bytes, bool save_vectors) {
const int regstosave_num = sizeof(RegisterSaver_LiveRegs) /
sizeof(RegisterSaver::LiveRegType);
const int register_save_size = regstosave_num * reg_size; // VS registers not relevant here.
const int vecregstosave_num = save_vectors ? (sizeof(RegisterSaver_LiveVecRegs) /
sizeof(RegisterSaver::LiveRegType))
: 0;
const int register_save_size = regstosave_num * reg_size + vecregstosave_num * vec_reg_size;

const int register_save_offset = frame_size_in_bytes - register_save_size;

// restore all result registers (ints and floats)
Expand Down Expand Up @@ -604,7 +610,7 @@ void RegisterSaver::restore_result_registers(MacroAssembler* masm, int frame_siz
offset += reg_size;
}

assert(offset == frame_size_in_bytes, "consistency check");
assert(offset == frame_size_in_bytes - (save_vectors ? vecregstosave_num * vec_reg_size : 0), "consistency check");
}

// Is vector's size (in bytes) bigger than a size saved by default?
Expand Down Expand Up @@ -2993,7 +2999,8 @@ void SharedRuntime::generate_deopt_blob() {
&first_frame_size_in_bytes,
/*generate_oop_map=*/ true,
return_pc_adjustment_no_exception,
RegisterSaver::return_pc_is_lr);
RegisterSaver::return_pc_is_lr,
/*save_vectors*/ SuperwordUseVSX);
assert(map != nullptr, "OopMap must have been created");

__ li(exec_mode_reg, Deoptimization::Unpack_deopt);
Expand Down Expand Up @@ -3028,7 +3035,8 @@ void SharedRuntime::generate_deopt_blob() {
&first_frame_size_in_bytes,
/*generate_oop_map=*/ false,
/*return_pc_adjustment_exception=*/ 0,
RegisterSaver::return_pc_is_pre_saved);
RegisterSaver::return_pc_is_pre_saved,
/*save_vectors*/ SuperwordUseVSX);

// Deopt during an exception. Save exec mode for unpack_frames.
__ li(exec_mode_reg, Deoptimization::Unpack_exception);
Expand All @@ -3046,7 +3054,8 @@ void SharedRuntime::generate_deopt_blob() {
&first_frame_size_in_bytes,
/*generate_oop_map=*/ false,
/*return_pc_adjustment_reexecute=*/ 0,
RegisterSaver::return_pc_is_pre_saved);
RegisterSaver::return_pc_is_pre_saved,
/*save_vectors*/ SuperwordUseVSX);
__ li(exec_mode_reg, Deoptimization::Unpack_reexecute);
#endif

Expand All @@ -3072,7 +3081,7 @@ void SharedRuntime::generate_deopt_blob() {

// Restore only the result registers that have been saved
// by save_volatile_registers(...).
RegisterSaver::restore_result_registers(masm, first_frame_size_in_bytes);
RegisterSaver::restore_result_registers(masm, first_frame_size_in_bytes, /*save_vectors*/ SuperwordUseVSX);

// reload the exec mode from the UnrollBlock (it might have changed)
__ lwz(exec_mode_reg, in_bytes(Deoptimization::UnrollBlock::unpack_kind_offset()), unroll_block_reg);
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/cpu/ppc/vm_version_ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include "asm/assembler.inline.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "compiler/compilerDefinitions.inline.hpp"
#include "compiler/disassembler.hpp"
#include "jvm.h"
#include "memory/resourceArea.hpp"
Expand Down Expand Up @@ -103,7 +104,7 @@ void VM_Version::initialize() {

if (PowerArchitecturePPC64 >= 9) {
// Performance is good since Power9.
if (FLAG_IS_DEFAULT(SuperwordUseVSX)) {
if (FLAG_IS_DEFAULT(SuperwordUseVSX) && CompilerConfig::is_c2_enabled()) {
FLAG_SET_ERGO(SuperwordUseVSX, true);
}
}
Expand Down
Loading