[vm, simarm64] Extract CalleeRegisterVerifier class
Closes https://github.com/dart-lang/sdk/pull/63012 GitOrigin-RevId: 56b29e0480f66e41ddd15e24249a5be75aed13ca Change-Id: I55ed703a366aefd3b273acd74a6c99c91ed38759 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/491682 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
d65783ef59
commit
a6a403c0b9
@@ -4019,6 +4019,54 @@ void Simulator::ExecuteTrace() {
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies that callee-saved registers are preserved across Dart execution.
|
||||
// On construction, saves and overwrites callee-saved registers with a known
|
||||
// value. On destruction, asserts that the known value is still present and
|
||||
// restores the original values.
|
||||
class CalleeRegisterVerifier {
|
||||
public:
|
||||
explicit CalleeRegisterVerifier(Simulator* sim)
|
||||
: sim_(sim),
|
||||
callee_saved_value_(
|
||||
bit_cast<int64_t, double>(static_cast<double>(sim->get_icount()))) {
|
||||
for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
|
||||
const Register r = static_cast<Register>(i);
|
||||
preserved_cpu_[i - kAbiFirstPreservedCpuReg] = sim->get_register(r);
|
||||
sim->set_register(nullptr, r, callee_saved_value_);
|
||||
}
|
||||
// Only the bottom half of the V registers must be preserved.
|
||||
for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
|
||||
const VRegister r = static_cast<VRegister>(i);
|
||||
preserved_fpu_[i - kAbiFirstPreservedFpuReg] = sim->get_vregisterd(r, 0);
|
||||
sim->set_vregisterd(r, 0, callee_saved_value_);
|
||||
sim->set_vregisterd(r, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
~CalleeRegisterVerifier() {
|
||||
for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
|
||||
const Register r = static_cast<Register>(i);
|
||||
ASSERT(callee_saved_value_ == sim_->get_register(r));
|
||||
sim_->set_register(nullptr, r,
|
||||
preserved_cpu_[i - kAbiFirstPreservedCpuReg]);
|
||||
}
|
||||
for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
|
||||
const VRegister r = static_cast<VRegister>(i);
|
||||
ASSERT(callee_saved_value_ == sim_->get_vregisterd(r, 0));
|
||||
sim_->set_vregisterd(r, 0, preserved_fpu_[i - kAbiFirstPreservedFpuReg]);
|
||||
sim_->set_vregisterd(r, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Simulator* const sim_;
|
||||
const int64_t callee_saved_value_;
|
||||
int64_t preserved_cpu_[kAbiPreservedCpuRegCount];
|
||||
int64_t preserved_fpu_[kAbiPreservedFpuRegCount];
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CalleeRegisterVerifier);
|
||||
};
|
||||
|
||||
int64_t Simulator::Call(int64_t entry,
|
||||
int64_t parameter0,
|
||||
int64_t parameter1,
|
||||
@@ -4061,43 +4109,10 @@ int64_t Simulator::Call(int64_t entry,
|
||||
// the LR the simulation stops when returning to this call point.
|
||||
set_register(nullptr, LR, kEndSimulatingPC);
|
||||
|
||||
// Remember the values of callee-saved registers, and set them up with a
|
||||
// known value so that we are able to check that they are preserved
|
||||
// properly across Dart execution.
|
||||
int64_t preserved_vals[kAbiPreservedCpuRegCount];
|
||||
const double dicount = static_cast<double>(icount_);
|
||||
const int64_t callee_saved_value = bit_cast<int64_t, double>(dicount);
|
||||
for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
|
||||
const Register r = static_cast<Register>(i);
|
||||
preserved_vals[i - kAbiFirstPreservedCpuReg] = get_register(r);
|
||||
set_register(nullptr, r, callee_saved_value);
|
||||
}
|
||||
|
||||
// Only the bottom half of the V registers must be preserved.
|
||||
int64_t preserved_dvals[kAbiPreservedFpuRegCount];
|
||||
for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
|
||||
const VRegister r = static_cast<VRegister>(i);
|
||||
preserved_dvals[i - kAbiFirstPreservedFpuReg] = get_vregisterd(r, 0);
|
||||
set_vregisterd(r, 0, callee_saved_value);
|
||||
set_vregisterd(r, 1, 0);
|
||||
}
|
||||
|
||||
// Start the simulation.
|
||||
Execute();
|
||||
|
||||
// Check that the callee-saved registers have been preserved,
|
||||
// and restore them with the original value.
|
||||
for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
|
||||
const Register r = static_cast<Register>(i);
|
||||
ASSERT(callee_saved_value == get_register(r));
|
||||
set_register(nullptr, r, preserved_vals[i - kAbiFirstPreservedCpuReg]);
|
||||
}
|
||||
|
||||
for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
|
||||
const VRegister r = static_cast<VRegister>(i);
|
||||
ASSERT(callee_saved_value == get_vregisterd(r, 0));
|
||||
set_vregisterd(r, 0, preserved_dvals[i - kAbiFirstPreservedFpuReg]);
|
||||
set_vregisterd(r, 1, 0);
|
||||
{
|
||||
// Verify callee-saved registers are preserved across Dart execution.
|
||||
CalleeRegisterVerifier callee_saved(this);
|
||||
Execute();
|
||||
}
|
||||
|
||||
// Restore the SP register and return R0.
|
||||
|
||||
Reference in New Issue
Block a user