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
// (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;
}
// we have 32 float register * 2 halves
if (reg < 60 + 128) {
// we have 32 float register * 4 halves
if (reg < slots_of_int_registers + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers) {
return rc_float;
}

View File

@ -604,7 +604,9 @@ class InternalAddress: public Address {
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 {
PLDL1KEEP = 0b00000, PLDL1STRM, PLDL2KEEP, PLDL2STRM, PLDL3KEEP, PLDL3STRM,
PSTL1KEEP = 0b10000, PSTL1STRM, PSTL2KEEP, PSTL2STRM, PSTL3KEEP, PSTL3STRM,

View File

@ -26,10 +26,12 @@
#include "precompiled.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
= 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* names[number_of_registers] = {

View File

@ -44,7 +44,8 @@ class RegisterImpl: public AbstractRegisterImpl {
enum {
number_of_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
@ -127,7 +128,10 @@ inline FloatRegister as_FloatRegister(int encoding) {
class FloatRegisterImpl: public AbstractRegisterImpl {
public:
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
@ -193,8 +197,8 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl {
// There is no requirement that any ordering here matches any ordering c2 gives
// it's optoregs.
number_of_registers = (2 * RegisterImpl::number_of_registers +
4 * FloatRegisterImpl::number_of_registers +
number_of_registers = (RegisterImpl::max_slots_per_register * RegisterImpl::number_of_registers +
FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers +
1) // flags
};

View File

@ -100,15 +100,15 @@ class RegisterSaver {
// Capture info about frame layout
enum layout {
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 "natural" place and will override any oopMap
// setting for it. We must therefore force the layout
// so that it agrees with the frame sender code.
r0_off = fpu_state_off+FPUStateSizeInWords,
rfp_off = r0_off + 30 * 2,
return_off = rfp_off + 2, // slot for return address
reg_save_size = return_off + 2};
r0_off = fpu_state_off + FPUStateSizeInWords,
rfp_off = r0_off + (RegisterImpl::number_of_registers - 2) * RegisterImpl::max_slots_per_register,
return_off = rfp_off + RegisterImpl::max_slots_per_register, // slot for return address
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 (save_vectors) {
// 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;
}
#else
assert(!save_vectors, "vectors are generated only by C2 and JVMCI");
#endif
int frame_size_in_bytes = align_up(additional_frame_words*wordSize +
reg_save_size*BytesPerInt, 16);
int frame_size_in_bytes = align_up(additional_frame_words * wordSize +
reg_save_size * BytesPerInt, 16);
// OopMap frame size is in compiler stack slots (jint's) not bytes or words
int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
// 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.
int frame_size_in_words = frame_size_in_bytes / wordSize;
*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++) {
Register r = as_Register(i);
if (r < rheapbase && r != rscratch1 && r != rscratch2) {
int sp_offset = 2 * (i + 32); // SP offsets are in 4-byte words,
// register slots are 8 bytes
// wide, 32 floating-point
// registers
// SP offsets are in 4-byte words.
// Register slots are 8 bytes wide, 32 floating-point registers.
int sp_offset = RegisterImpl::max_slots_per_register * i +
FloatRegisterImpl::save_slots_per_register * FloatRegisterImpl::number_of_registers;
oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset + additional_frame_slots),
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++) {
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),
r->as_VMReg());
}

View File

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

View File

@ -38,13 +38,14 @@ inline Register as_Register() {
assert( is_Register(), "must be");
// Yuk
return ::as_Register(value() >> 1);
return ::as_Register(value() / RegisterImpl::max_slots_per_register);
}
inline FloatRegister as_FloatRegister() {
assert( is_FloatRegister() && is_even(value()), "must be" );
// 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() {

View File

@ -28,11 +28,12 @@
inline VMReg RegisterImpl::as_VMReg() {
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() {
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