mirror of
https://github.com/corda/corda.git
synced 2025-01-31 16:35:43 +00:00
more ARM64 bugfixes, more passing tests
This commit is contained in:
parent
cbea966d1d
commit
78735b35a8
@ -89,11 +89,11 @@ void nextFrame(ArchitectureContext* con,
|
|||||||
void** stack)
|
void** stack)
|
||||||
{
|
{
|
||||||
assertT(con, *ip >= start);
|
assertT(con, *ip >= start);
|
||||||
assertT(con, *ip <= start + (size / TargetBytesPerWord));
|
assertT(con, *ip <= start + (size / 4));
|
||||||
|
|
||||||
uint32_t* instruction = static_cast<uint32_t*>(*ip);
|
uint32_t* instruction = static_cast<uint32_t*>(*ip);
|
||||||
|
|
||||||
if ((*start >> 20) == 0xe59) {
|
if ((*start >> 20) == (TargetBytesPerWord == 8 ? 0xf94 : 0xe59)) {
|
||||||
// skip stack overflow check
|
// skip stack overflow check
|
||||||
start += 3;
|
start += 3;
|
||||||
}
|
}
|
||||||
@ -111,7 +111,8 @@ void nextFrame(ArchitectureContext* con,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*instruction == 0xe12fff1e) { // return
|
if (*instruction == (TargetBytesPerWord == 8 ? 0xd61f03c0 : 0xe12fff1e)) {
|
||||||
|
// return
|
||||||
*ip = link;
|
*ip = link;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -124,7 +125,21 @@ void nextFrame(ArchitectureContext* con,
|
|||||||
|
|
||||||
// check for post-non-tail-call stack adjustment of the form "sub
|
// check for post-non-tail-call stack adjustment of the form "sub
|
||||||
// sp, sp, #offset":
|
// sp, sp, #offset":
|
||||||
if ((*instruction >> 12) == 0xe24dd) {
|
if (TargetBytesPerWord == 8 and (*instruction & 0xff0003ff) == 0xd10003ff)
|
||||||
|
{
|
||||||
|
unsigned value = (*instruction >> 10) & 0xfff;
|
||||||
|
unsigned shift = (*instruction >> 22) & 1;
|
||||||
|
switch (shift) {
|
||||||
|
case 0:
|
||||||
|
offset -= value;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
offset -= value << 12;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort(con);
|
||||||
|
}
|
||||||
|
} else if (TargetBytesPerWord == 4 and (*instruction >> 12) == 0xe24dd) {
|
||||||
unsigned value = *instruction & 0xff;
|
unsigned value = *instruction & 0xff;
|
||||||
unsigned rotation = (*instruction >> 8) & 0xf;
|
unsigned rotation = (*instruction >> 8) & 0xf;
|
||||||
switch (rotation) {
|
switch (rotation) {
|
||||||
|
@ -378,7 +378,7 @@ uint32_t ldrshi(Register Rd, Register Rn, int offset)
|
|||||||
|
|
||||||
uint32_t ldrswi(Register Rd, Register Rn, int offset)
|
uint32_t ldrswi(Register Rd, Register Rn, int offset)
|
||||||
{
|
{
|
||||||
return 0xb9800000 | (offset << 10) | (Rn.index() << 5) | Rd.index();
|
return 0xb9800000 | ((offset >> 2) << 10) | (Rn.index() << 5) | Rd.index();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ldri(Register Rd, Register Rn, int offset, unsigned size)
|
uint32_t ldri(Register Rd, Register Rn, int offset, unsigned size)
|
||||||
@ -642,7 +642,7 @@ void moveCR2(Context* c,
|
|||||||
c->client->releaseTemporary(tmp.low);
|
c->client->releaseTemporary(tmp.low);
|
||||||
} else if (src->value->resolved()) {
|
} else if (src->value->resolved()) {
|
||||||
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));
|
||||||
if (value >> 16) {
|
if (value >> 16) {
|
||||||
append(c, movk(dst->low, (value >> 16) & 0xFFFF, 16, size));
|
append(c, movk(dst->low, (value >> 16) & 0xFFFF, 16, size));
|
||||||
@ -695,7 +695,7 @@ void subR(Context* c,
|
|||||||
lir::RegisterPair* b,
|
lir::RegisterPair* b,
|
||||||
lir::RegisterPair* dst)
|
lir::RegisterPair* dst)
|
||||||
{
|
{
|
||||||
append(c, sub(dst->low, a->low, b->low, size));
|
append(c, sub(dst->low, b->low, a->low, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addC(Context* c,
|
void addC(Context* c,
|
||||||
@ -1137,6 +1137,7 @@ void load(Context* c,
|
|||||||
case 4:
|
case 4:
|
||||||
case 8:
|
case 8:
|
||||||
if (signExtend and srcSize == 4 and dstSize == 8) {
|
if (signExtend and srcSize == 4 and dstSize == 8) {
|
||||||
|
assertT(c, offset == (offset & (~3)));
|
||||||
append(c, ldrswi(dst->low, base, offset));
|
append(c, ldrswi(dst->low, base, offset));
|
||||||
} else {
|
} else {
|
||||||
assertT(c, offset == (offset & (srcSize == 8 ? (~7) : (~3))));
|
assertT(c, offset == (offset & (srcSize == 8 ? (~7) : (~3))));
|
||||||
@ -1293,17 +1294,24 @@ void compareCR(Context* c,
|
|||||||
{
|
{
|
||||||
assertT(c, aSize == bSize);
|
assertT(c, aSize == bSize);
|
||||||
|
|
||||||
int32_t v = a->value->value();
|
if (!isFpr(b) && a->value->resolved()) {
|
||||||
if (v) {
|
int32_t v = a->value->value();
|
||||||
if (v > 0 and v < 0x1000) {
|
if (v == 0) {
|
||||||
|
append(c, cmp(b->low, Register(31), aSize));
|
||||||
|
return;
|
||||||
|
} else if (v > 0 and v < 0x1000) {
|
||||||
append(c, cmpi(b->low, v, 0, aSize));
|
append(c, cmpi(b->low, v, 0, aSize));
|
||||||
|
return;
|
||||||
} else if (v > 0 and v < 0x1000000 and v % 0x1000 == 0) {
|
} else if (v > 0 and v < 0x1000000 and v % 0x1000 == 0) {
|
||||||
append(c, cmpi(b->low, v >> 12, 12, aSize));
|
append(c, cmpi(b->low, v >> 12, 12, aSize));
|
||||||
} else {
|
return;
|
||||||
// todo
|
|
||||||
abort(c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK));
|
||||||
|
moveCR(c, aSize, a, bSize, &tmp);
|
||||||
|
compareRR(c, bSize, &tmp, bSize, b);
|
||||||
|
c->client->releaseTemporary(tmp.low);
|
||||||
}
|
}
|
||||||
|
|
||||||
void compareCM(Context* c,
|
void compareCM(Context* c,
|
||||||
@ -1474,23 +1482,10 @@ void moveCM(Context* c,
|
|||||||
unsigned dstSize,
|
unsigned dstSize,
|
||||||
lir::Memory* dst)
|
lir::Memory* dst)
|
||||||
{
|
{
|
||||||
switch (dstSize) {
|
lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK));
|
||||||
case 8: {
|
moveCR(c, srcSize, src, dstSize, &tmp);
|
||||||
lir::Constant srcHigh(shiftMaskPromise(c, src->value, 32, 0xFFFFFFFF));
|
moveRM(c, dstSize, &tmp, dstSize, dst);
|
||||||
lir::Constant srcLow(shiftMaskPromise(c, src->value, 0, 0xFFFFFFFF));
|
c->client->releaseTemporary(tmp.low);
|
||||||
|
|
||||||
lir::Memory dstLow(dst->base, dst->offset + 4, dst->index, dst->scale);
|
|
||||||
|
|
||||||
moveCM(c, 4, &srcLow, 4, &dstLow);
|
|
||||||
moveCM(c, 4, &srcHigh, 4, dst);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK));
|
|
||||||
moveCR(c, srcSize, src, dstSize, &tmp);
|
|
||||||
moveRM(c, dstSize, &tmp, dstSize, dst);
|
|
||||||
c->client->releaseTemporary(tmp.low);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void negateRR(Context* c,
|
void negateRR(Context* c,
|
||||||
|
@ -102,7 +102,7 @@ GLOBAL(vmInvoke_safeStack):
|
|||||||
str xzr, [x19, #TARGET_THREAD_STACK]
|
str xzr, [x19, #TARGET_THREAD_STACK]
|
||||||
|
|
||||||
// restore return type
|
// restore return type
|
||||||
ldr w5, [sp,#16]!
|
ldr w5, [sp],#16
|
||||||
|
|
||||||
// restore callee-saved register values
|
// restore callee-saved register values
|
||||||
ldp x19, x20, [sp,#16]
|
ldp x19, x20, [sp,#16]
|
||||||
@ -110,7 +110,7 @@ GLOBAL(vmInvoke_safeStack):
|
|||||||
ldp x23, x24, [sp,#48]
|
ldp x23, x24, [sp,#48]
|
||||||
ldp x25, x26, [sp,#64]
|
ldp x25, x26, [sp,#64]
|
||||||
ldp x27, x28, [sp,#80]
|
ldp x27, x28, [sp,#80]
|
||||||
ldp x29, x30, [sp,#96]!
|
ldp x29, x30, [sp],#96
|
||||||
|
|
||||||
LOCAL(vmInvoke_return):
|
LOCAL(vmInvoke_return):
|
||||||
br x30
|
br x30
|
||||||
|
Loading…
x
Reference in New Issue
Block a user