Skip to content

Commit e6fa85b

Browse files
author
Vladimir Ivanov
committed
8256058: Improve vector register handling in RegisterMap::pd_location() on x86
Reviewed-by: kvn
1 parent be6c893 commit e6fa85b

File tree

1 file changed

+28
-16
lines changed

1 file changed

+28
-16
lines changed

src/hotspot/cpu/x86/registerMap_x86.cpp

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,35 @@
2828

2929
address RegisterMap::pd_location(VMReg reg) const {
3030
if (reg->is_XMMRegister()) {
31-
int regBase = reg->value() - ConcreteRegisterImpl::max_fpr;
32-
if (regBase % 4 == 0) {
33-
// Reads of the low and high 16 byte parts should be handled by location itself
34-
// because they have separate callee saved entries.
35-
// See RegisterSaver::save_live_registers().
36-
return NULL;
31+
int reg_base = reg->value() - ConcreteRegisterImpl::max_fpr;
32+
int base_reg_enc = (reg_base / XMMRegisterImpl::max_slots_per_register);
33+
assert(base_reg_enc >= 0 && base_reg_enc < XMMRegisterImpl::number_of_registers, "invalid XMMRegister: %d", base_reg_enc);
34+
VMReg base_reg = as_XMMRegister(base_reg_enc)->as_VMReg();
35+
intptr_t offset_in_bytes = (reg->value() - base_reg->value()) * VMRegImpl::stack_slot_size;
36+
if (base_reg_enc > 15) {
37+
if (offset_in_bytes == 0) {
38+
return NULL; // ZMM16-31 are stored in full.
39+
}
40+
} else {
41+
if (offset_in_bytes == 0 || offset_in_bytes == 16 || offset_in_bytes == 32) {
42+
// Reads of the low and high 16 byte parts should be handled by location itself because
43+
// they have separate callee saved entries (see RegisterSaver::save_live_registers()).
44+
return NULL;
45+
}
46+
// The upper part of YMM0-15 and ZMM0-15 registers are saved separately in the frame.
47+
if (offset_in_bytes > 32) {
48+
base_reg = base_reg->next(8);
49+
offset_in_bytes -= 32;
50+
} else if (offset_in_bytes > 16) {
51+
base_reg = base_reg->next(4);
52+
offset_in_bytes -= 16;
53+
} else {
54+
// XMM0-15 case (0 < offset_in_bytes < 16). No need to adjust base register (or offset).
55+
}
3756
}
38-
VMReg baseReg = as_XMMRegister(regBase / XMMRegisterImpl::max_slots_per_register)->as_VMReg();
39-
intptr_t offset = (reg->value() - baseReg->value()) * VMRegImpl::stack_slot_size; // offset in bytes
40-
if (offset >= 16) {
41-
// The high part of YMM registers are saved in a their own area in the frame
42-
baseReg = baseReg->next()->next()->next()->next();
43-
offset -= 16;
44-
}
45-
address baseLocation = location(baseReg);
46-
if (baseLocation != NULL) {
47-
return baseLocation + offset;
57+
address base_location = location(base_reg);
58+
if (base_location != NULL) {
59+
return base_location + offset_in_bytes;
4860
}
4961
}
5062
return NULL;

0 commit comments

Comments
 (0)