Commit 7a2651cb authored by Joey Gouly's avatar Joey Gouly Committed by Commit Bot

[arm64] Cleanup TODO around handling of x18

Use `padreg` instead of x18 to maintain alignment in the CPURegList.

Also clean up some comments and tidy up RequiredStackSizeForCallerSaved
and PushCallerSaved.

Change-Id: I80a780e5649e69a1746c43f37c2d1d875120c7a0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1581609Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Martyn Capewell <martyn.capewell@arm.com>
Cr-Commit-Position: refs/heads/master@{#60987}
parent 2209d169
......@@ -98,6 +98,18 @@ void CPURegList::RemoveCalleeSaved() {
}
}
void CPURegList::Align() {
// Use padreg, if necessary, to maintain stack alignment.
if (Count() % 2 != 0) {
if (IncludesAliasOf(padreg)) {
Remove(padreg);
} else {
Combine(padreg);
}
}
DCHECK_EQ(Count() % 2, 0);
}
CPURegList CPURegList::GetCalleeSaved(int size) {
return CPURegList(CPURegister::kRegister, size, 19, 29);
......
......@@ -55,12 +55,6 @@ void CopyRegListToFrame(MacroAssembler* masm, const Register& dst,
masm->Sub(dst, dst, dst_offset);
}
// TODO(jgruber): There's a hack here to explicitly skip restoration of the
// so-called 'arm64 platform register' x18. The register may be in use by the
// OS, thus we should not clobber it. Instead of this hack, it would be nicer
// not to add x18 to the list of saved registers in the first place. The
// complication here is that we require `reg_list.Count() % 2 == 0` in multiple
// spots.
void RestoreRegList(MacroAssembler* masm, const CPURegList& reg_list,
const Register& src_base, int src_offset) {
DCHECK_EQ(reg_list.Count() % 2, 0);
......@@ -74,8 +68,8 @@ void RestoreRegList(MacroAssembler* masm, const CPURegList& reg_list,
Register src = temps.AcquireX();
masm->Add(src, src_base, src_offset);
// x18 is the platform register and is reserved for the use of platform ABIs.
restore_list.Remove(x18);
// No need to restore padreg.
restore_list.Remove(padreg);
// Restore every register in restore_list from src.
while (!restore_list.IsEmpty()) {
......
......@@ -40,25 +40,11 @@ CPURegList TurboAssembler::DefaultFPTmpList() {
int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
Register exclusion) const {
int bytes = 0;
auto list = kCallerSaved;
// We only allow one exclusion register, so if the list is of even length
// before exclusions, it must still be afterwards, to maintain alignment.
// Therefore, we can ignore the exclusion register in the computation.
// However, we leave it in the argument list to mirror the prototype for
// Push/PopCallerSaved().
// X18 is excluded from caller-saved register list on ARM64 which makes
// caller-saved registers in odd number. padreg is used accordingly to
// maintain the alignment.
DCHECK_EQ(list.Count() % 2, 1);
if (exclusion.Is(no_reg)) {
bytes += kXRegSizeInBits / 8;
} else {
bytes -= kXRegSizeInBits / 8;
}
list.Remove(exclusion);
list.Align();
bytes += list.Count() * kXRegSizeInBits / 8;
int bytes = list.Count() * kXRegSizeInBits / 8;
if (fp_mode == kSaveFPRegs) {
DCHECK_EQ(kCallerSavedV.Count() % 2, 0);
......@@ -69,20 +55,13 @@ int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
int TurboAssembler::PushCallerSaved(SaveFPRegsMode fp_mode,
Register exclusion) {
int bytes = 0;
auto list = kCallerSaved;
list.Remove(exclusion);
list.Align();
// X18 is excluded from caller-saved register list on ARM64, use padreg
// accordingly to maintain alignment.
if (!exclusion.Is(no_reg)) {
list.Remove(exclusion);
} else {
list.Combine(padreg);
}
DCHECK_EQ(list.Count() % 2, 0);
PushCPURegList(list);
bytes += list.Count() * kXRegSizeInBits / 8;
int bytes = list.Count() * kXRegSizeInBits / 8;
if (fp_mode == kSaveFPRegs) {
DCHECK_EQ(kCallerSavedV.Count() % 2, 0);
......@@ -101,16 +80,9 @@ int TurboAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion) {
}
auto list = kCallerSaved;
list.Remove(exclusion);
list.Align();
// X18 is excluded from caller-saved register list on ARM64, use padreg
// accordingly to maintain alignment.
if (!exclusion.Is(no_reg)) {
list.Remove(exclusion);
} else {
list.Combine(padreg);
}
DCHECK_EQ(list.Count() % 2, 0);
PopCPURegList(list);
bytes += list.Count() * kXRegSizeInBits / 8;
......@@ -3378,11 +3350,8 @@ void MacroAssembler::Printf(const char * format,
TmpList()->set_list(0);
FPTmpList()->set_list(0);
// x18 is the platform register and is reserved for the use of platform ABIs.
// It is not part of the kCallerSaved list, but we add it here anyway to
// ensure `reg_list.Count() % 2 == 0` which is required in multiple spots.
CPURegList saved_registers = kCallerSaved;
saved_registers.Combine(x18.code());
saved_registers.Align();
// Preserve all caller-saved registers as well as NZCV.
// PushCPURegList asserts that the size of each list is a multiple of 16
......
......@@ -626,6 +626,9 @@ class V8_EXPORT_PRIVATE CPURegList {
// preparing registers for an AAPCS64 function call, for example.
void RemoveCalleeSaved();
// Align the list to 16 bytes.
void Align();
CPURegister PopLowestIndex();
CPURegister PopHighestIndex();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment