8233948: AArch64: Incorrect mapping between OptoReg and VMReg for high 64 bits of Vector Register

Reviewed-by: adinn
This commit is contained in:
Joshua Zhu 2019-12-06 10:41:01 +08:00
parent 81ec9e3087
commit 30559e6431
8 changed files with 47 additions and 32 deletions

View File

@ -1857,13 +1857,14 @@ static enum RC rc_class(OptoReg::Name reg) {
// we have 30 int registers * 2 halves // we have 30 int registers * 2 halves
// (rscratch1 and rscratch2 are omitted) // (rscratch1 and rscratch2 are omitted)
int slots_of_int_registers = RegisterImpl::max_slots_per_register * (RegisterImpl::number_of_registers - 2);
if (reg < 60) { if (reg < slots_of_int_registers) {
return rc_int; return rc_int;
} }
// we have 32 float register * 2 halves // we have 32 float register * 4 halves
if (reg < 60 + 128) { if (reg < slots_of_int_registers + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers) {
return rc_float; return rc_float;
} }

View File

@ -604,7 +604,9 @@ class InternalAddress: public Address {
InternalAddress(address target) : Address(target, relocInfo::internal_word_type) {} InternalAddress(address target) : Address(target, relocInfo::internal_word_type) {}
}; };
const int FPUStateSizeInWords = 32 * 2; const int FPUStateSizeInWords = FloatRegisterImpl::number_of_registers *
FloatRegisterImpl::save_slots_per_register;
typedef enum { typedef enum {
PLDL1KEEP = 0b00000, PLDL1STRM, PLDL2KEEP, PLDL2STRM, PLDL3KEEP, PLDL3STRM, PLDL1KEEP = 0b00000, PLDL1STRM, PLDL2KEEP, PLDL2STRM, PLDL3KEEP, PLDL3STRM,
PSTL1KEEP = 0b10000, PSTL1STRM, PSTL2KEEP, PSTL2STRM, PSTL3KEEP, PSTL3STRM, PSTL1KEEP = 0b10000, PSTL1STRM, PSTL2KEEP, PSTL2STRM, PSTL3KEEP, PSTL3STRM,

View File

@ -26,10 +26,12 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "register_aarch64.hpp" #include "register_aarch64.hpp"
const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers << 1; const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers *
RegisterImpl::max_slots_per_register;
const int ConcreteRegisterImpl::max_fpr const int ConcreteRegisterImpl::max_fpr
= ConcreteRegisterImpl::max_gpr + (FloatRegisterImpl::number_of_registers << 1); = ConcreteRegisterImpl::max_gpr +
FloatRegisterImpl::number_of_registers * FloatRegisterImpl::max_slots_per_register;
const char* RegisterImpl::name() const { const char* RegisterImpl::name() const {
const char* names[number_of_registers] = { const char* names[number_of_registers] = {

View File

@ -44,7 +44,8 @@ class RegisterImpl: public AbstractRegisterImpl {
enum { enum {
number_of_registers = 32, number_of_registers = 32,
number_of_byte_registers = 32, number_of_byte_registers = 32,
number_of_registers_for_jvmci = 34 // Including SP and ZR. number_of_registers_for_jvmci = 34, // Including SP and ZR.
max_slots_per_register = 2
}; };
// derived registers, offsets, and addresses // derived registers, offsets, and addresses
@ -127,7 +128,10 @@ inline FloatRegister as_FloatRegister(int encoding) {
class FloatRegisterImpl: public AbstractRegisterImpl { class FloatRegisterImpl: public AbstractRegisterImpl {
public: public:
enum { enum {
number_of_registers = 32 number_of_registers = 32,
max_slots_per_register = 4,
save_slots_per_register = 2,
extra_save_slots_per_register = max_slots_per_register - save_slots_per_register
}; };
// construction // construction
@ -193,8 +197,8 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl {
// There is no requirement that any ordering here matches any ordering c2 gives // There is no requirement that any ordering here matches any ordering c2 gives
// it's optoregs. // it's optoregs.
number_of_registers = (2 * RegisterImpl::number_of_registers + number_of_registers = (RegisterImpl::max_slots_per_register * RegisterImpl::number_of_registers +
4 * FloatRegisterImpl::number_of_registers + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers +
1) // flags 1) // flags
}; };

View File

@ -100,15 +100,15 @@ class RegisterSaver {
// Capture info about frame layout // Capture info about frame layout
enum layout { enum layout {
fpu_state_off = 0, fpu_state_off = 0,
fpu_state_end = fpu_state_off+FPUStateSizeInWords-1, fpu_state_end = fpu_state_off + FPUStateSizeInWords - 1,
// The frame sender code expects that rfp will be in // The frame sender code expects that rfp will be in
// the "natural" place and will override any oopMap // the "natural" place and will override any oopMap
// setting for it. We must therefore force the layout // setting for it. We must therefore force the layout
// so that it agrees with the frame sender code. // so that it agrees with the frame sender code.
r0_off = fpu_state_off+FPUStateSizeInWords, r0_off = fpu_state_off + FPUStateSizeInWords,
rfp_off = r0_off + 30 * 2, rfp_off = r0_off + (RegisterImpl::number_of_registers - 2) * RegisterImpl::max_slots_per_register,
return_off = rfp_off + 2, // slot for return address return_off = rfp_off + RegisterImpl::max_slots_per_register, // slot for return address
reg_save_size = return_off + 2}; reg_save_size = return_off + RegisterImpl::max_slots_per_register};
}; };
@ -116,19 +116,20 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
#if COMPILER2_OR_JVMCI #if COMPILER2_OR_JVMCI
if (save_vectors) { if (save_vectors) {
// Save upper half of vector registers // Save upper half of vector registers
int vect_words = 32 * 8 / wordSize; int vect_words = FloatRegisterImpl::number_of_registers * FloatRegisterImpl::extra_save_slots_per_register /
VMRegImpl::slots_per_word;
additional_frame_words += vect_words; additional_frame_words += vect_words;
} }
#else #else
assert(!save_vectors, "vectors are generated only by C2 and JVMCI"); assert(!save_vectors, "vectors are generated only by C2 and JVMCI");
#endif #endif
int frame_size_in_bytes = align_up(additional_frame_words*wordSize + int frame_size_in_bytes = align_up(additional_frame_words * wordSize +
reg_save_size*BytesPerInt, 16); reg_save_size * BytesPerInt, 16);
// OopMap frame size is in compiler stack slots (jint's) not bytes or words // OopMap frame size is in compiler stack slots (jint's) not bytes or words
int frame_size_in_slots = frame_size_in_bytes / BytesPerInt; int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
// The caller will allocate additional_frame_words // The caller will allocate additional_frame_words
int additional_frame_slots = additional_frame_words*wordSize / BytesPerInt; int additional_frame_slots = additional_frame_words * wordSize / BytesPerInt;
// CodeBlob frame size is in words. // CodeBlob frame size is in words.
int frame_size_in_words = frame_size_in_bytes / wordSize; int frame_size_in_words = frame_size_in_bytes / wordSize;
*total_frame_words = frame_size_in_words; *total_frame_words = frame_size_in_words;
@ -148,10 +149,10 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
for (int i = 0; i < RegisterImpl::number_of_registers; i++) { for (int i = 0; i < RegisterImpl::number_of_registers; i++) {
Register r = as_Register(i); Register r = as_Register(i);
if (r < rheapbase && r != rscratch1 && r != rscratch2) { if (r < rheapbase && r != rscratch1 && r != rscratch2) {
int sp_offset = 2 * (i + 32); // SP offsets are in 4-byte words, // SP offsets are in 4-byte words.
// register slots are 8 bytes // Register slots are 8 bytes wide, 32 floating-point registers.
// wide, 32 floating-point int sp_offset = RegisterImpl::max_slots_per_register * i +
// registers FloatRegisterImpl::save_slots_per_register * FloatRegisterImpl::number_of_registers;
oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset + additional_frame_slots), oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset + additional_frame_slots),
r->as_VMReg()); r->as_VMReg());
} }
@ -159,7 +160,8 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
for (int i = 0; i < FloatRegisterImpl::number_of_registers; i++) { for (int i = 0; i < FloatRegisterImpl::number_of_registers; i++) {
FloatRegister r = as_FloatRegister(i); FloatRegister r = as_FloatRegister(i);
int sp_offset = save_vectors ? (4 * i) : (2 * i); int sp_offset = save_vectors ? (FloatRegisterImpl::max_slots_per_register * i) :
(FloatRegisterImpl::save_slots_per_register * i);
oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset), oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
r->as_VMReg()); r->as_VMReg());
} }

View File

@ -33,15 +33,17 @@ void VMRegImpl::set_regName() {
Register reg = ::as_Register(0); Register reg = ::as_Register(0);
int i; int i;
for (i = 0; i < ConcreteRegisterImpl::max_gpr ; ) { for (i = 0; i < ConcreteRegisterImpl::max_gpr ; ) {
regName[i++] = reg->name(); for (int j = 0 ; j < RegisterImpl::max_slots_per_register ; j++) {
regName[i++] = reg->name(); regName[i++] = reg->name();
}
reg = reg->successor(); reg = reg->successor();
} }
FloatRegister freg = ::as_FloatRegister(0); FloatRegister freg = ::as_FloatRegister(0);
for ( ; i < ConcreteRegisterImpl::max_fpr ; ) { for ( ; i < ConcreteRegisterImpl::max_fpr ; ) {
regName[i++] = freg->name(); for (int j = 0 ; j < FloatRegisterImpl::max_slots_per_register ; j++) {
regName[i++] = freg->name(); regName[i++] = freg->name();
}
freg = freg->successor(); freg = freg->successor();
} }

View File

@ -38,13 +38,14 @@ inline Register as_Register() {
assert( is_Register(), "must be"); assert( is_Register(), "must be");
// Yuk // Yuk
return ::as_Register(value() >> 1); return ::as_Register(value() / RegisterImpl::max_slots_per_register);
} }
inline FloatRegister as_FloatRegister() { inline FloatRegister as_FloatRegister() {
assert( is_FloatRegister() && is_even(value()), "must be" ); assert( is_FloatRegister() && is_even(value()), "must be" );
// Yuk // Yuk
return ::as_FloatRegister((value() - ConcreteRegisterImpl::max_gpr) >> 1); return ::as_FloatRegister((value() - ConcreteRegisterImpl::max_gpr) /
FloatRegisterImpl::max_slots_per_register);
} }
inline bool is_concrete() { inline bool is_concrete() {

View File

@ -28,11 +28,12 @@
inline VMReg RegisterImpl::as_VMReg() { inline VMReg RegisterImpl::as_VMReg() {
if( this==noreg ) return VMRegImpl::Bad(); if( this==noreg ) return VMRegImpl::Bad();
return VMRegImpl::as_VMReg(encoding() << 1 ); return VMRegImpl::as_VMReg(encoding() * RegisterImpl::max_slots_per_register);
} }
inline VMReg FloatRegisterImpl::as_VMReg() { inline VMReg FloatRegisterImpl::as_VMReg() {
return VMRegImpl::as_VMReg((encoding() << 1) + ConcreteRegisterImpl::max_gpr); return VMRegImpl::as_VMReg((encoding() * FloatRegisterImpl::max_slots_per_register) +
ConcreteRegisterImpl::max_gpr);
} }
#endif // CPU_AARCH64_VMREG_AARCH64_INLINE_HPP #endif // CPU_AARCH64_VMREG_AARCH64_INLINE_HPP