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() { ...@@ -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) { CPURegList CPURegList::GetCalleeSaved(int size) {
return CPURegList(CPURegister::kRegister, size, 19, 29); return CPURegList(CPURegister::kRegister, size, 19, 29);
......
...@@ -55,12 +55,6 @@ void CopyRegListToFrame(MacroAssembler* masm, const Register& dst, ...@@ -55,12 +55,6 @@ void CopyRegListToFrame(MacroAssembler* masm, const Register& dst,
masm->Sub(dst, dst, dst_offset); 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, void RestoreRegList(MacroAssembler* masm, const CPURegList& reg_list,
const Register& src_base, int src_offset) { const Register& src_base, int src_offset) {
DCHECK_EQ(reg_list.Count() % 2, 0); DCHECK_EQ(reg_list.Count() % 2, 0);
...@@ -74,8 +68,8 @@ void RestoreRegList(MacroAssembler* masm, const CPURegList& reg_list, ...@@ -74,8 +68,8 @@ void RestoreRegList(MacroAssembler* masm, const CPURegList& reg_list,
Register src = temps.AcquireX(); Register src = temps.AcquireX();
masm->Add(src, src_base, src_offset); masm->Add(src, src_base, src_offset);
// x18 is the platform register and is reserved for the use of platform ABIs. // No need to restore padreg.
restore_list.Remove(x18); restore_list.Remove(padreg);
// Restore every register in restore_list from src. // Restore every register in restore_list from src.
while (!restore_list.IsEmpty()) { while (!restore_list.IsEmpty()) {
......
...@@ -40,25 +40,11 @@ CPURegList TurboAssembler::DefaultFPTmpList() { ...@@ -40,25 +40,11 @@ CPURegList TurboAssembler::DefaultFPTmpList() {
int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode, int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
Register exclusion) const { Register exclusion) const {
int bytes = 0;
auto list = kCallerSaved; auto list = kCallerSaved;
// We only allow one exclusion register, so if the list is of even length list.Remove(exclusion);
// before exclusions, it must still be afterwards, to maintain alignment. list.Align();
// 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;
}
bytes += list.Count() * kXRegSizeInBits / 8; int bytes = list.Count() * kXRegSizeInBits / 8;
if (fp_mode == kSaveFPRegs) { if (fp_mode == kSaveFPRegs) {
DCHECK_EQ(kCallerSavedV.Count() % 2, 0); DCHECK_EQ(kCallerSavedV.Count() % 2, 0);
...@@ -69,20 +55,13 @@ int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode, ...@@ -69,20 +55,13 @@ int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
int TurboAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, int TurboAssembler::PushCallerSaved(SaveFPRegsMode fp_mode,
Register exclusion) { Register exclusion) {
int bytes = 0;
auto list = kCallerSaved; auto list = kCallerSaved;
// X18 is excluded from caller-saved register list on ARM64, use padreg
// accordingly to maintain alignment.
if (!exclusion.Is(no_reg)) {
list.Remove(exclusion); list.Remove(exclusion);
} else { list.Align();
list.Combine(padreg);
}
DCHECK_EQ(list.Count() % 2, 0);
PushCPURegList(list); PushCPURegList(list);
bytes += list.Count() * kXRegSizeInBits / 8;
int bytes = list.Count() * kXRegSizeInBits / 8;
if (fp_mode == kSaveFPRegs) { if (fp_mode == kSaveFPRegs) {
DCHECK_EQ(kCallerSavedV.Count() % 2, 0); DCHECK_EQ(kCallerSavedV.Count() % 2, 0);
...@@ -101,16 +80,9 @@ int TurboAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion) { ...@@ -101,16 +80,9 @@ int TurboAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion) {
} }
auto list = kCallerSaved; auto list = kCallerSaved;
// X18 is excluded from caller-saved register list on ARM64, use padreg
// accordingly to maintain alignment.
if (!exclusion.Is(no_reg)) {
list.Remove(exclusion); list.Remove(exclusion);
} else { list.Align();
list.Combine(padreg);
}
DCHECK_EQ(list.Count() % 2, 0);
PopCPURegList(list); PopCPURegList(list);
bytes += list.Count() * kXRegSizeInBits / 8; bytes += list.Count() * kXRegSizeInBits / 8;
...@@ -3378,11 +3350,8 @@ void MacroAssembler::Printf(const char * format, ...@@ -3378,11 +3350,8 @@ void MacroAssembler::Printf(const char * format,
TmpList()->set_list(0); TmpList()->set_list(0);
FPTmpList()->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; CPURegList saved_registers = kCallerSaved;
saved_registers.Combine(x18.code()); saved_registers.Align();
// Preserve all caller-saved registers as well as NZCV. // Preserve all caller-saved registers as well as NZCV.
// PushCPURegList asserts that the size of each list is a multiple of 16 // PushCPURegList asserts that the size of each list is a multiple of 16
......
...@@ -626,6 +626,9 @@ class V8_EXPORT_PRIVATE CPURegList { ...@@ -626,6 +626,9 @@ class V8_EXPORT_PRIVATE CPURegList {
// preparing registers for an AAPCS64 function call, for example. // preparing registers for an AAPCS64 function call, for example.
void RemoveCalleeSaved(); void RemoveCalleeSaved();
// Align the list to 16 bytes.
void Align();
CPURegister PopLowestIndex(); CPURegister PopLowestIndex();
CPURegister PopHighestIndex(); 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