progress towards fixing the ARM build

This commit is contained in:
Joel Dice 2011-01-28 17:16:08 -07:00
parent cac232a84e
commit 17449eaf1b
3 changed files with 145 additions and 77 deletions

View File

@ -164,13 +164,12 @@ inline int carry16(intptr_t v) { return static_cast<int16_t>(v) < 0 ? 1 : 0; }
inline bool isOfWidth(long long i, int size) { return static_cast<unsigned long long>(i) >> size == 0; }
inline bool isOfWidth(int i, int size) { return static_cast<unsigned>(i) >> size == 0; }
const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1);
const unsigned FrameHeaderSize = 1;
const unsigned StackAlignmentInBytes = 8;
const unsigned StackAlignmentInWords = StackAlignmentInBytes / BytesPerWord;
const int ThreadRegister = 8;
const int FrameRegister = 12;
const int StackRegister = 13;
const int LinkRegister = 14;
const int ProgramCounter = 15;
@ -865,6 +864,51 @@ void subR(Context* con, unsigned size, Assembler::Register* a, Assembler::Regist
}
}
void
addC(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b, Assembler::Register* dst)
{
assert(c, size == BytesPerWord);
int32_t v = a->value->value();
if (v) {
if (v > 0 and v < 1024 and v % 4 == 0) {
emit(c, addi(dst->low, b->low, v >> 2, 15));
} else {
emit(c, addi(dst->low, b->low, lo8(v)));
if (not isOfWidth(v, 8)) {
emit(c, addi(dst->low, b->low, hi8(v), 12));
if (not isOfWidth(v, 16)) {
emit(c, addi(dst->low, b->low, lo8(hi16(v)), 8));
if (not isOfWidth(v, 24)) {
emit(c, addi(dst->low, b->low, hi8(hi16(v)), 4));
}
}
}
}
} else {
moveRR(c, size, b, size, dst);
}
}
void
subC(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b, Assembler::Register* dst)
{
assert(c, size == BytesPerWord);
int32_t v = a->value->value();
if (v > 0 and v < 256) {
emit(c, subi(dst->low, b->low, v));
} else if (v > 0 and v < 1024 and v % 4 == 0) {
emit(c, subi(dst->low, b->low, v >> 2, 15));
} else {
ResolvedPromise promise(- v);
Assembler::Constant constant(&promise);
addC(c, size, &constant, b, dst);
}
}
void multiplyR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) {
if (size == 8) {
bool useTemporaries = b->low == t->low;
@ -1569,6 +1613,55 @@ memoryBarrier(Context*) {}
// END OPERATION COMPILERS
void
nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED,
unsigned footprint, int32_t*, void* link, void* stackLimit,
unsigned targetParameterFootprint UNUSED, void** ip, void** stack)
{
assert(c, *ip >= start);
assert(c, *ip <= start + (size / BytesPerWord));
uint32_t* instruction = static_cast<uint32_t*>(*ip);
if ((*start >> 20) == 0xe59) {
// skip stack overflow check
start += 3;
}
if (instruction <= start) {
*ip = link;
return;
}
unsigned offset = footprint + FrameHeaderSize
- (stackLimit == *stack ? 1 : 0);
if (instruction <= start + 2) {
*ip = link;
*stack = reinterpret_cast<void**>(*stack) + offset;
}
if (*instruction == 0xe12fff1e) { // return
*ip = link;
return;
}
if (TailCalls) {
if (argumentFootprint(targetParameterFootprint) > StackAlignmentInWords) {
offset += argumentFootprint(targetParameterFootprint)
- StackAlignmentInWords;
}
// todo: check for post-non-tail-call stack adjustment of the form
// "add sp, sp, #offset"
// todo: use frameTable to check for and handle tail calls
}
*ip = reinterpret_cast<void**>(*stack)[offset];
*stack = reinterpret_cast<void**>(*stack) + offset;
}
void
populateTables(ArchitectureContext* c)
{
@ -1701,9 +1794,6 @@ class MyArchitecture: public Assembler::Architecture {
virtual bool reserved(int register_) {
switch (register_) {
case FrameRegister:
return UseFramePointer;
case LinkRegister:
case StackRegister:
case ThreadRegister:
@ -1788,6 +1878,15 @@ class MyArchitecture: public Assembler::Architecture {
- FrameHeaderSize;
}
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
int32_t* frameTable, void* link, void* stackLimit,
unsigned targetParameterFootprint, void** ip,
void** stack)
{
::nextFrame(&c, static_cast<uint32_t*>(start), size, footprint, frameTable,
link, stackLimit, targetParameterFootprint, ip, stack);
}
virtual void* frameIp(void* stack) {
return stack ? static_cast<void**>(stack)[returnAddressOffset()] : 0;
}
@ -1809,7 +1908,7 @@ class MyArchitecture: public Assembler::Architecture {
}
virtual int framePointerOffset() {
return -2;
return 0;
}
virtual void nextFrame(void** stack, void**) {
@ -2010,14 +2109,6 @@ class MyAssembler: public Assembler {
}
virtual void saveFrame(unsigned stackOffset) {
appendFrameSizeEvent(&c, FrameSizePoison);
// ???
Register returnAddress(LinkRegister);
Memory returnAddressDst(StackRegister, - BytesPerWord);
moveAndUpdateRM(&c, BytesPerWord, &returnAddress, BytesPerWord,
&returnAddressDst);
Register stack(StackRegister);
Memory stackDst(ThreadRegister, stackOffset);
moveRM(&c, BytesPerWord, &stack, BytesPerWord, &stackDst);
@ -2053,7 +2144,7 @@ class MyAssembler: public Assembler {
offset += ceiling(arguments[i].size, BytesPerWord);
} else {
Memory dst(ThreadRegister, (offset + FrameFooterSize) * BytesPerWord);
Memory dst(StackRegister, offset * BytesPerWord);
apply(Move,
arguments[i].size, arguments[i].type, arguments[i].operand,
@ -2065,79 +2156,62 @@ class MyAssembler: public Assembler {
}
virtual void allocateFrame(unsigned footprint) {
Register stack(StackRegister);
Constant footprintConstant(resolved(&c, footprint * BytesPerWord));
subCR(&c, BytesPerWord, &footprintConstant, BytesPerWord, &stack,
BytesPerWord, &stack);
footprint += FrameHeaderSize;
appendFrameSizeEvent(&c, footprint);
// larger frames may require multiple subtract/add instructions
// to allocate/deallocate, and nextFrame will need to be taught
// how to handle them:
assert(&c, footprint < 256);
Register stack(StackRegister);
ResolvedPromise footprintPromise(footprint * BytesPerWord);
Constant footprintConstant(&footprintPromise);
subC(&c, BytesPerWord, &footprintConstant, &stack, &stack);
Register returnAddress(LinkRegister);
Memory returnAddressDst(StackRegister, (footprint - 1) * BytesPerWord);
moveRM(&c, BytesPerWord, &returnAddress, BytesPerWord, &returnAddressDst);
if (UseFramePointer) {
Register frame(FrameRegister);
Memory frameDst(StackRegister, (footprint - 2) * BytesPerWord);
moveRM(&c, BytesPerWord, &frame, BytesPerWord, &frameDst);
}
}
virtual void adjustFrame(unsigned difference) {
appendFrameSizeEvent(&c, - difference);
Register stack(StackRegister);
Constant differenceConstant(resolved(&c, difference * BytesPerWord));
subCR(&c, BytesPerWord, &differenceConstant, BytesPerWord, &stack,
BytesPerWord, &stack);
appendFrameSizeEvent(&c, difference);
ResolvedPromise differencePromise(difference * BytesPerWord);
Constant differenceConstant(&differencePromise);
subC(&c, BytesPerWord, &differenceConstant, &stack, &stack);
}
virtual void popFrame(unsigned frameFootprint) {
if (UseFramePointer) {
Register frame(FrameRegister);
Memory frameSrc(StackRegister, (frameFootprint - 1) * BytesPerWord);
moveMR(&c, BytesPerWord, &frameSrc, BytesPerWord, &frame);
}
virtual void popFrame(unsigned footprint) {
footprint += FrameHeaderSize;
Register returnAddress(LinkRegister);
Memory returnAddressSrc
(StackRegister, (frameFootprint - 1) * BytesPerWord);
Memory returnAddressSrc(StackRegister, (footprint - 1) * BytesPerWord);
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &returnAddress);
Register stack(StackRegister);
Constant differenceConstant(resolved(&c, frameFootprint * BytesPerWord));
addCR(&c, BytesPerWord, &differenceConstant, BytesPerWord, &stack,
BytesPerWord, &stack);
appendFrameSizeEvent(&c, - frameFootprint);
ResolvedPromise footprintPromise(footprint * BytesPerWord);
Constant footprintConstant(&footprintPromise);
addC(&c, BytesPerWord, &footprintConstant, &stack, &stack);
}
virtual void popFrameForTailCall(unsigned footprint,
int offset,
int returnAddressSurrogate,
int framePointerSurrogate)
int framePointerSurrogate UNUSED)
{
assert(&c, framePointerSurrogate == NoRegister);
if (TailCalls) {
if (offset) {
if (UseFramePointer) {
Register frame(FrameRegister);
Memory frameSrc(StackRegister, (footprint - 1) * BytesPerWord);
moveMR(&c, BytesPerWord, &frameSrc, BytesPerWord, &frame);
}
Register link(LinkRegister);
Memory returnAddressSrc
(StackRegister, (footprint - 1) * BytesPerWord);
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &link);
Register stack(StackRegister);
Constant footprintConstant
(resolved(&c, (footprint - offset + 1) * BytesPerWord));
addCR(&c, BytesPerWord, &footprintConstant, BytesPerWord, &stack);
appendFrameSizeEvent(&c, - (frameFootprint - offset + 1));
ResolvedPromise footprintPromise
((footprint - offset + 1) * BytesPerWord);
Constant footprintConstant(&footprintPromise);
addC(&c, BytesPerWord, &footprintConstant, &stack, &stack);
if (returnAddressSurrogate != NoRegister) {
assert(&c, offset > 0);
@ -2146,14 +2220,6 @@ class MyAssembler: public Assembler {
Memory dst(StackRegister, (offset - 1) * BytesPerWord);
moveRM(&c, BytesPerWord, &ras, BytesPerWord, &dst);
}
if (framePointerSurrogate != NoRegister) {
assert(&c, offset > 0);
Register las(framePointerSurrogate);
Memory dst(StackRegister, (offset - 2) * BytesPerWord);
moveRM(&c, BytesPerWord, &las, BytesPerWord, &dst);
}
} else {
popFrame(footprint);
}
@ -2175,26 +2241,19 @@ class MyAssembler: public Assembler {
offset = argumentFootprint - StackAlignmentInWords;
Register stack(StackRegister);
Constant adjustment(resolved(&c, offset * BytesPerWord));
addCR(&c, BytesPerWord, &adjustment, BytesPerWord, &stack);
appendFrameSizeEvent(&c, - offset);
ResolvedPromise adjustmentPromise(offset * BytesPerWord);
Constant adjustment(&adjustmentPromise);
addC(&c, BytesPerWord, &adjustment, &stack, &stack);
} else {
offset = 0;
}
return_(&c);
// todo: this is not necessary if there are no instructions to
// follow:
appendFrameSizeEvent(&c, frameFootprint + offset);
}
virtual void popFrameAndUpdateStackAndReturn(unsigned frameFootprint,
unsigned stackOffsetFromThread)
{
appendFrameSizeEvent(&c, FrameSizePoison);
popFrame(frameFootprint);
Register stack(StackRegister);
@ -2372,6 +2431,14 @@ class MyAssembler: public Assembler {
return c.code.length();
}
virtual unsigned frameEventCount() {
return 0;
}
virtual FrameEvent* firstFrameEvent() {
return 0;
}
virtual void dispose() {
c.code.dispose();
}

View File

@ -19,6 +19,7 @@
#define IP_REGISTER(context) (context->uc_mcontext.arm_pc)
#define STACK_REGISTER(context) (context->uc_mcontext.arm_sp)
#define THREAD_REGISTER(context) (context->uc_mcontext.arm_ip)
#define LINK_REGISTER(context) (context->uc_mcontext.arm_lr)
extern "C" uint64_t
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,

View File

@ -22,7 +22,7 @@
# define GLOBAL(x) x
#endif
#define THREAD_STACK 2152
#define THREAD_STACK 2148
#define THREAD_CONTINUATION 2156
#define THREAD_EXCEPTION 44
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2160