8233948: AArch64: Incorrect mapping between OptoReg and VMReg for high 64 bits of Vector Register
Reviewed-by: adinn
This commit is contained in:
parent
81ec9e3087
commit
30559e6431
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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] = {
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user