From dffe9f48e772b07f4af9f3c30121cbe7c9a12efd Mon Sep 17 00:00:00 2001 From: Suchismith Roy Date: Mon, 27 Apr 2026 08:39:18 +0000 Subject: [PATCH] 8374575: [PPC64] Remove support for SuperwordUseVSX on Power 8 Reviewed-by: mdoerr, varadam --- .../ppc/gc/shared/barrierSetAssembler_ppc.cpp | 14 +-- src/hotspot/cpu/ppc/globals_ppc.hpp | 3 +- src/hotspot/cpu/ppc/macroAssembler_ppc.cpp | 16 +--- src/hotspot/cpu/ppc/matcher_ppc.hpp | 4 +- src/hotspot/cpu/ppc/ppc.ad | 96 +++++-------------- src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp | 18 +--- src/hotspot/cpu/ppc/vm_version_ppc.cpp | 3 + 7 files changed, 39 insertions(+), 115 deletions(-) diff --git a/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp index 3692b247989..db20439b066 100644 --- a/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp @@ -354,19 +354,9 @@ int SaveLiveRegisters::iterate_over_register_mask(IterationAction action, int of Register spill_addr = R0; int spill_offset = offset - reg_save_index * BytesPerWord; if (action == ACTION_SAVE) { - if (PowerArchitecturePPC64 >= 9) { - _masm->stxv(vs_reg, spill_offset, R1_SP); - } else { - _masm->addi(spill_addr, R1_SP, spill_offset); - _masm->stxvd2x(vs_reg, spill_addr); - } + _masm->stxv(vs_reg, spill_offset, R1_SP); } else if (action == ACTION_RESTORE) { - if (PowerArchitecturePPC64 >= 9) { - _masm->lxv(vs_reg, spill_offset, R1_SP); - } else { - _masm->addi(spill_addr, R1_SP, spill_offset); - _masm->lxvd2x(vs_reg, spill_addr); - } + _masm->lxv(vs_reg, spill_offset, R1_SP); } else { assert(action == ACTION_COUNT_ONLY, "Sanity"); } diff --git a/src/hotspot/cpu/ppc/globals_ppc.hpp b/src/hotspot/cpu/ppc/globals_ppc.hpp index 927a8cc2be3..d46bb733ea7 100644 --- a/src/hotspot/cpu/ppc/globals_ppc.hpp +++ b/src/hotspot/cpu/ppc/globals_ppc.hpp @@ -116,7 +116,8 @@ define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong); \ /* special instructions */ \ product(bool, SuperwordUseVSX, false, \ - "Use VSX instructions for superword optimization.") \ + "Use VSX instructions for superword optimization " \ + "(default for Power9 and later).") \ \ product(bool, UseByteReverseInstructions, false, DIAGNOSTIC, \ "Use byte reverse instructions.") \ diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp index b4deaefa65c..3efedc31d8f 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp @@ -799,13 +799,7 @@ void MacroAssembler::save_nonvolatile_registers(Register dst, int offset, bool i } } else { for (int i = 20; i < 32; i++) { - if (PowerArchitecturePPC64 >= 9) { - stxv(as_VectorRegister(i)->to_vsr(), offset, dst); - } else { - Register spill_addr = R0; - addi(spill_addr, dst, offset); - stxvd2x(as_VectorRegister(i)->to_vsr(), spill_addr); - } + stxv(as_VectorRegister(i)->to_vsr(), offset, dst); offset += 16; } } @@ -838,13 +832,7 @@ void MacroAssembler::restore_nonvolatile_registers(Register src, int offset, boo } } else { for (int i = 20; i < 32; i++) { - if (PowerArchitecturePPC64 >= 9) { - lxv(as_VectorRegister(i)->to_vsr(), offset, src); - } else { - Register spill_addr = R0; - addi(spill_addr, src, offset); - lxvd2x(as_VectorRegister(i)->to_vsr(), spill_addr); - } + lxv(as_VectorRegister(i)->to_vsr(), offset, src); offset += 16; } } diff --git a/src/hotspot/cpu/ppc/matcher_ppc.hpp b/src/hotspot/cpu/ppc/matcher_ppc.hpp index cbe882648b8..88a189d670e 100644 --- a/src/hotspot/cpu/ppc/matcher_ppc.hpp +++ b/src/hotspot/cpu/ppc/matcher_ppc.hpp @@ -38,10 +38,10 @@ return false; } - // The PPC implementation uses VSX lxvd2x/stxvd2x instructions (if + // The PPC implementation uses VSX lxv/stxv instructions (if // SuperwordUseVSX). They do not have alignment requirements. // Some VSX storage access instructions cannot encode arbitrary displacements - // (e.g. lxv). None of them is currently used. + // (e.g. lxv). We use memoryAlg16 for them. static constexpr bool misaligned_vectors_ok() { return true; } diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index c605c3432fb..00549ac8508 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -1818,52 +1818,26 @@ uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *r // VectorRegister->Memory Spill. else if (src_lo_rc == rc_vec && dst_lo_rc == rc_stack) { VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr(); - if (PowerArchitecturePPC64 >= 9) { - if (masm) { - __ stxv(Rsrc, dst_offset, R1_SP); // matches storeV16_Power9 - } - size += 4; - } else { - if (masm) { - __ addi(R0, R1_SP, dst_offset); - __ stxvd2x(Rsrc, R0); // matches storeV16_Power8 - } - size += 8; + if (masm) { + __ stxv(Rsrc, dst_offset, R1_SP); // matches storeV16 } + size += 4; #ifndef PRODUCT if (st != nullptr) { - if (PowerArchitecturePPC64 >= 9) { - st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "STXV", Matcher::regName[src_lo], dst_offset); - } else { - st->print("%-7s R0, R1_SP, %d \t// vector spill copy\n\t" - "%-7s %s, [R0] \t// vector spill copy", "ADDI", dst_offset, "STXVD2X", Matcher::regName[src_lo]); - } + st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "STXV", Matcher::regName[src_lo], dst_offset); } #endif // !PRODUCT } // Memory->VectorRegister Spill. else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vec) { VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr(); - if (PowerArchitecturePPC64 >= 9) { - if (masm) { - __ lxv(Rdst, src_offset, R1_SP); - } - size += 4; - } else { - if (masm) { - __ addi(R0, R1_SP, src_offset); - __ lxvd2x(Rdst, R0); - } - size += 8; + if (masm) { + __ lxv(Rdst, src_offset, R1_SP); } + size += 4; #ifndef PRODUCT if (st != nullptr) { - if (PowerArchitecturePPC64 >= 9) { - st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "LXV", Matcher::regName[dst_lo], src_offset); - } else { - st->print("%-7s R0, R1_SP, %d \t// vector spill copy\n\t" - "%-7s %s, [R0] \t// vector spill copy", "ADDI", src_offset, "LXVD2X", Matcher::regName[dst_lo]); - } + st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "LXV", Matcher::regName[dst_lo], src_offset); } #endif // !PRODUCT } @@ -2284,7 +2258,7 @@ bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { case Op_UMaxV: return bt == T_INT || bt == T_LONG; case Op_NegVI: - return PowerArchitecturePPC64 >= 9 && bt == T_INT; + return bt == T_INT; } return true; // Per default match rules are supported. } @@ -2322,10 +2296,12 @@ OptoRegPair Matcher::vector_return_value(uint ideal_reg) { // Vector width in bytes. int Matcher::vector_width_in_bytes(BasicType bt) { if (SuperwordUseVSX) { - assert(MaxVectorSize == 16, ""); + assert(MaxVectorSize == 16, + "SuperwordUseVSX requires MaxVectorSize 16, got " INT64_FORMAT, (int64_t)MaxVectorSize); return 16; } else { - assert(MaxVectorSize == 8, ""); + assert(MaxVectorSize == 8, + "expected MaxVectorSize 8, got " INT64_FORMAT, (int64_t)MaxVectorSize); return 8; } } @@ -2333,10 +2309,14 @@ int Matcher::vector_width_in_bytes(BasicType bt) { // Vector ideal reg. uint Matcher::vector_ideal_reg(int size) { if (SuperwordUseVSX) { - assert(MaxVectorSize == 16 && size == 16, ""); + assert(MaxVectorSize == 16 && size == 16, + "SuperwordUseVSX requires MaxVectorSize 16 and size 16, got MaxVectorSize=" INT64_FORMAT ", size=%d", + (int64_t)MaxVectorSize, size); return Op_VecX; } else { - assert(MaxVectorSize == 8 && size == 8, ""); + assert(MaxVectorSize == 8 && size == 8, + "expected MaxVectorSize 8 and size 8, got MaxVectorSize=" INT64_FORMAT ", size=%d", + (int64_t)MaxVectorSize, size); return Op_RegL; } } @@ -5413,23 +5393,9 @@ instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ ins_pipe(pipe_class_memory); %} -// Load Aligned Packed Byte -// Note: The Power8 instruction loads the contents in a special order in Little Endian mode. -instruct loadV16_Power8(vecX dst, indirect mem) %{ - predicate(n->as_LoadVector()->memory_size() == 16 && PowerArchitecturePPC64 == 8); - match(Set dst (LoadVector mem)); - ins_cost(MEMORY_REF_COST); - format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} - size(4); - ins_encode %{ - __ lxvd2x($dst$$VectorRegister.to_vsr(), $mem$$Register); - %} - ins_pipe(pipe_class_default); -%} - -instruct loadV16_Power9(vecX dst, memoryAlg16 mem) %{ - predicate(n->as_LoadVector()->memory_size() == 16 && PowerArchitecturePPC64 >= 9); +instruct loadV16(vecX dst, memoryAlg16 mem) %{ + predicate(n->as_LoadVector()->memory_size() == 16); match(Set dst (LoadVector mem)); ins_cost(MEMORY_REF_COST); @@ -6424,23 +6390,9 @@ instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ ins_pipe(pipe_class_memory); %} -// Store Packed Byte long register to memory -// Note: The Power8 instruction stores the contents in a special order in Little Endian mode. -instruct storeV16_Power8(indirect mem, vecX src) %{ - predicate(n->as_StoreVector()->memory_size() == 16 && PowerArchitecturePPC64 == 8); - match(Set mem (StoreVector mem src)); - ins_cost(MEMORY_REF_COST); - format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} - size(4); - ins_encode %{ - __ stxvd2x($src$$VectorRegister.to_vsr(), $mem$$Register); - %} - ins_pipe(pipe_class_default); -%} - -instruct storeV16_Power9(memoryAlg16 mem, vecX src) %{ - predicate(n->as_StoreVector()->memory_size() == 16 && PowerArchitecturePPC64 >= 9); +instruct storeV16(memoryAlg16 mem, vecX src) %{ + predicate(n->as_StoreVector()->memory_size() == 16); match(Set mem (StoreVector mem src)); ins_cost(MEMORY_REF_COST); @@ -13657,7 +13609,7 @@ instruct vneg2D_reg(vecX dst, vecX src) %{ instruct vneg4I_reg(vecX dst, vecX src) %{ match(Set dst (NegVI src)); - predicate(PowerArchitecturePPC64 >= 9 && Matcher::vector_element_basic_type(n) == T_INT); + predicate(Matcher::vector_element_basic_type(n) == T_INT); format %{ "VNEGW $dst,$src\t// negate int vector" %} size(4); ins_encode %{ diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index 53644210415..54336e9f62b 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -360,7 +360,7 @@ OopMap* RegisterSaver::push_frame_reg_args_and_save_live_registers(MacroAssemble assert(RegisterSaver_LiveVecRegs[i + 1].reg_num == reg_num + 1, "or use other instructions!"); __ 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). + // Note: The contents were read in the same order (see loadV16 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), @@ -374,13 +374,8 @@ OopMap* RegisterSaver::push_frame_reg_args_and_save_live_registers(MacroAssemble for (int i = 0; i < vecregstosave_num; i++) { int reg_num = RegisterSaver_LiveVecRegs[i].reg_num; - if (PowerArchitecturePPC64 >= 9) { - __ stxv(as_VectorRegister(reg_num)->to_vsr(), offset, R1_SP); - } else { - __ li(R31, offset); - __ 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). + __ stxv(as_VectorRegister(reg_num)->to_vsr(), offset, R1_SP); + // Note: The contents were read in the same order (see loadV16 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; @@ -464,12 +459,7 @@ void RegisterSaver::restore_live_registers_and_pop_frame(MacroAssembler* masm, for (int i = 0; i < vecregstosave_num; i++) { int reg_num = RegisterSaver_LiveVecRegs[i].reg_num; - if (PowerArchitecturePPC64 >= 9) { - __ lxv(as_VectorRegister(reg_num).to_vsr(), offset, R1_SP); - } else { - __ li(R31, offset); - __ lxvd2x(as_VectorRegister(reg_num).to_vsr(), R31, R1_SP); - } + __ lxv(as_VectorRegister(reg_num).to_vsr(), offset, R1_SP); offset += vec_reg_size; } diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.cpp b/src/hotspot/cpu/ppc/vm_version_ppc.cpp index 3e3b1103c86..be05ec1dfb3 100644 --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp @@ -109,6 +109,9 @@ void VM_Version::initialize() { if (FLAG_IS_DEFAULT(SuperwordUseVSX) && CompilerConfig::is_c2_enabled()) { FLAG_SET_ERGO(SuperwordUseVSX, true); } + } else if (SuperwordUseVSX) { + warning("SuperwordUseVSX specified, but needs at least Power9."); + FLAG_SET_DEFAULT(SuperwordUseVSX, false); } MaxVectorSize = SuperwordUseVSX ? 16 : 8;