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
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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] = {
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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() {
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user