fix ARM64 tails=true build

This commit is contained in:
Joel Dice 2014-12-30 09:37:26 -07:00
parent 76bfcaa8c0
commit e3ea60fc31
2 changed files with 46 additions and 16 deletions

View File

@ -130,10 +130,10 @@ void nextFrame(ArchitectureContext* con,
unsigned shift = (*instruction >> 22) & 1; unsigned shift = (*instruction >> 22) & 1;
switch (shift) { switch (shift) {
case 0: case 0:
offset -= value; offset -= value / TargetBytesPerWord;
break; break;
case 1: case 1:
offset -= value << 12; offset -= (value << 12) / TargetBytesPerWord;
break; break;
default: default:
abort(con); abort(con);
@ -769,6 +769,11 @@ class MyAssembler : public Assembler {
// how to handle them: // how to handle them:
assertT(&con, footprint < 256); assertT(&con, footprint < 256);
// todo: ARM64 frame allocation should be of the form:
// stp x29, x30, [sp,#size]!
// and deallocation should be of the form:
// ldp x29, x30, [sp],#size
lir::RegisterPair stack(StackRegister); lir::RegisterPair stack(StackRegister);
ResolvedPromise footprintPromise(footprint * TargetBytesPerWord); ResolvedPromise footprintPromise(footprint * TargetBytesPerWord);
lir::Constant footprintConstant(&footprintPromise); lir::Constant footprintConstant(&footprintPromise);
@ -875,10 +880,19 @@ class MyAssembler : public Assembler {
return_(&con); return_(&con);
} }
virtual void popFrameAndUpdateStackAndReturn(unsigned frameFootprint, virtual void popFrameAndUpdateStackAndReturn(unsigned footprint,
unsigned stackOffsetFromThread) unsigned stackOffsetFromThread)
{ {
popFrame(frameFootprint); footprint += FrameHeaderSize;
lir::RegisterPair returnAddress(LinkRegister);
lir::Memory returnAddressSrc(StackRegister,
(footprint - 1) * TargetBytesPerWord);
moveMR(&con,
TargetBytesPerWord,
&returnAddressSrc,
TargetBytesPerWord,
&returnAddress);
lir::RegisterPair stack(StackRegister); lir::RegisterPair stack(StackRegister);
lir::Memory newStackSrc(ThreadRegister, stackOffsetFromThread); lir::Memory newStackSrc(ThreadRegister, stackOffsetFromThread);

View File

@ -139,8 +139,8 @@ uint32_t addi(Register Rd, Register Rn, int value, int shift, unsigned size)
uint32_t mov(Register Rd, Register Rn, unsigned size) uint32_t mov(Register Rd, Register Rn, unsigned size)
{ {
return Rn.index() == 31 ? addi(Rd, Rn, 0, 0, size) return Rn.index() == 31 or Rd.index() == 31 ? addi(Rd, Rn, 0, 0, size)
: orr(Rd, Register(31), Rn, size); : orr(Rd, Register(31), Rn, size);
} }
uint32_t movz(Register Rd, int value, unsigned shift, unsigned size) uint32_t movz(Register Rd, int value, unsigned shift, unsigned size)
@ -653,6 +653,10 @@ void moveCR2(Context* c,
moveRR(c, size, &tmp, size, dst); moveRR(c, size, &tmp, size, dst);
c->client->releaseTemporary(tmp.low); c->client->releaseTemporary(tmp.low);
} else if (callOffset == 0 and src->value->resolved()) { } else if (callOffset == 0 and src->value->resolved()) {
// todo: Is it better performance-wise to load using immediate
// moves or via a PC-relative constant pool? Does it depend on
// how many significant bits there are?
int64_t value = src->value->value(); int64_t value = src->value->value();
if (value >= 0) { if (value >= 0) {
append(c, movz(dst->low, value & 0xFFFF, 0, size)); append(c, movz(dst->low, value & 0xFFFF, 0, size));
@ -1195,16 +1199,28 @@ void moveMR(Context* c,
unsigned dstSize, unsigned dstSize,
lir::RegisterPair* dst) lir::RegisterPair* dst)
{ {
load(c, if (dst->low.index() == 31) {
srcSize, assertT(c, c->client == 0); // the compiler should never ask us to
src->base, // load the SP; we'll only get here
src->offset, // when assembling a thunk
src->index,
src->scale, lir::RegisterPair tmp(Register(9)); // we're in a thunk, so we can
dstSize, // clobber this
dst,
true, load(c, srcSize, src->base, src->offset, src->index, src->scale, dstSize, &tmp, true, true);
true); moveRR(c, dstSize, &tmp, dstSize, dst);
} else {
load(c,
srcSize,
src->base,
src->offset,
src->index,
src->scale,
dstSize,
dst,
true,
true);
}
} }
void moveZMR(Context* c, void moveZMR(Context* c,