blob: 479b950b65cae308e63eb9265a14ce1d8816a9ee [file] [log] [blame]
// Copyright 2011 Google Inc. All Rights Reserved.
#include "context_x86.h"
#include "object.h"
namespace art {
namespace x86 {
X86Context::X86Context() {
#ifndef NDEBUG
// Initialize registers with easy to spot debug values
for (int i=0; i < 8; i++) {
gprs_[i] = 0xEBAD6070+i;
}
eip_ = 0xEBAD601F;
#endif
}
void X86Context::FillCalleeSaves(const Frame& fr) {
Method* method = fr.GetMethod();
uint32_t core_spills = method->GetCoreSpillMask();
size_t spill_count = __builtin_popcount(core_spills);
CHECK_EQ(method->GetFpSpillMask(), 0u);
if (spill_count > 0) {
// Lowest number spill is furthest away, walk registers and fill into context
int j = 1;
for(int i = 0; i < 8; i++) {
if (((core_spills >> i) & 1) != 0) {
gprs_[i] = fr.LoadCalleeSave(spill_count - j);
j++;
}
}
}
}
void X86Context::DoLongJump() {
#if defined(__i386__)
// Load ESP and EIP
gprs_[ESP] -= 4; // push EIP for return
*((uintptr_t*)(gprs_[ESP])) = eip_;
asm volatile (
"pushl %4\n\t"
"pushl %0\n\t"
"pushl %1\n\t"
"pushl %2\n\t"
"pushl %3\n\t"
"pushl %4\n\t"
"pushl %5\n\t"
"pushl %6\n\t"
"pushl %7\n\t"
"popal\n\t"
"popl %%esp\n\t"
"ret\n\t"
: //output
: "g"(gprs_[EAX]), "g"(gprs_[ECX]), "g"(gprs_[EDX]), "g"(gprs_[EBX]),
"g"(gprs_[ESP]), "g"(gprs_[EBP]), "g"(gprs_[ESI]), "g"(gprs_[EDI])
:); // clobber
#else
UNIMPLEMENTED(FATAL);
#endif
}
} // namespace x86
} // namespace art