finish implementing operations64.cpp for ARM64 support

This is totally untested so far.
This commit is contained in:
Joel Dice 2014-12-22 12:57:18 -07:00
parent a6e88a8faa
commit b519e245e2
2 changed files with 360 additions and 71 deletions

View File

@ -16,16 +16,17 @@
#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64 #if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64
namespace avian { namespace {
namespace codegen {
namespace arm {
inline int fpr(Register reg) using namespace avian::codegen;
using namespace avian::codegen::arm;
Register fpr(Register reg)
{ {
return reg.index() - N_GPRS; return Register(reg.index() - N_GPRS);
} }
inline int fpr(lir::RegisterPair* reg) Register fpr(lir::RegisterPair* reg)
{ {
return fpr(reg->low); return fpr(reg->low);
} }
@ -104,19 +105,19 @@ uint32_t br(Register Rn)
return 0xd61f0000 | (Rn.index() << 5); return 0xd61f0000 | (Rn.index() << 5);
} }
uint32_t fmovFdFn(int Fd, int Fn, unsigned size) uint32_t fmovFdFn(Register Fd, Register Fn, unsigned size)
{ {
return (size == 8 ? 0x1e604000 : 0x1e204000) | (Fn << 5) | Fd; return (size == 8 ? 0x1e604000 : 0x1e204000) | (Fn.index() << 5) | Fd.index();
} }
uint32_t fmovRdFn(Register Rd, int Fn, unsigned size) uint32_t fmovRdFn(Register Rd, Register Fn, unsigned size)
{ {
return (size == 8 ? 0x9e660000 : 0x1e260000) | (Fn << 5) | Rd.index(); return (size == 8 ? 0x9e660000 : 0x1e260000) | (Fn.index() << 5) | Rd.index();
} }
uint32_t fmovFdRn(int Fd, Register Rn, unsigned size) uint32_t fmovFdRn(Register Fd, Register Rn, unsigned size)
{ {
return (size == 8 ? 0x9e670000 : 0x1e270000) | (Rn.index() << 5) | Fd; return (size == 8 ? 0x9e670000 : 0x1e270000) | (Rn.index() << 5) | Fd.index();
} }
uint32_t orr(Register Rd, Register Rn, Register Rm, unsigned size) uint32_t orr(Register Rd, Register Rn, Register Rm, unsigned size)
@ -162,6 +163,18 @@ uint32_t sub(Register Rd, Register Rn, Register Rm, unsigned size)
return (size == 8 ? 0xcb000000 : 0x4b000000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index(); return (size == 8 ? 0xcb000000 : 0x4b000000) | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index();
} }
uint32_t and_(Register Rd, Register Rn, Register Rm, unsigned size)
{
return (size == 8 ? 0x8a000000 : 0x0a000000) | (Rm.index() << 16)
| (Rn.index() << 5) | Rd.index();
}
uint32_t eor(Register Rd, Register Rn, Register Rm, unsigned size)
{
return (size == 8 ? 0xca000000 : 0x4a000000) | (Rm.index() << 16)
| (Rn.index() << 5) | Rd.index();
}
uint32_t madd(Register Rd, Register Rn, Register Rm, Register Ra, unsigned size) uint32_t madd(Register Rd, Register Rn, Register Rm, Register Ra, unsigned size)
{ {
return (size == 8 ? 0x9b000000 : 0x1b000000) return (size == 8 ? 0x9b000000 : 0x1b000000)
@ -185,36 +198,288 @@ uint32_t subi(Register Rd, Register Rn, int value, int shift, unsigned size)
| (value << 10) | (Rn.index() << 5) | Rd.index(); | (value << 10) | (Rn.index() << 5) | Rd.index();
} }
uint32_t fabs(int Fd, int Fn, unsigned size) uint32_t fabs_(Register Fd, Register Fn, unsigned size)
{ {
return (size == 8 ? 0x1e60c000 : 0x1e20c000) | (Fn << 5) | Fd; return (size == 8 ? 0x1e60c000 : 0x1e20c000) | (Fn.index() << 5) | Fd.index();
} }
uint32_t fneg(int Fd, int Fn, unsigned size) uint32_t fneg(Register Fd, Register Fn, unsigned size)
{ {
return (size == 8 ? 0x1e614000 : 0x1e214000) | (Fn << 5) | Fd; return (size == 8 ? 0x1e614000 : 0x1e214000) | (Fn.index() << 5) | Fd.index();
} }
uint32_t fcvtSdDn(int Fd, int Fn) uint32_t fsqrt(Register Fd, Register Fn, unsigned size)
{ {
return 0x1e624000 | (Fn << 5) | Fd; return (size == 8 ? 0x1e61c000 : 0x1e21c000) | (Fn.index() << 5) | Fd.index();
} }
uint32_t fcvtDdSn(int Fd, int Fn) uint32_t fadd(Register Fd, Register Fn, Register Fm, unsigned size)
{ {
return 0x1e22c000 | (Fn << 5) | Fd; return (size == 8 ? 0x1e602800 : 0x1e202800) | (Fm.index() << 16)
| (Fn.index() << 5) | Fd.index();
} }
uint32_t fcvtasXdDn(Register Rd, int Fn) uint32_t fsub(Register Fd, Register Fn, Register Fm, unsigned size)
{ {
return 0x9e640000 | (Fn << 5) | Rd.index(); return (size == 8 ? 0x1e603800 : 0x1e203800) | (Fm.index() << 16)
| (Fn.index() << 5) | Fd.index();
} }
uint32_t fcvtasWdSn(Register Rd, int Fn) uint32_t fmul(Register Fd, Register Fn, Register Fm, unsigned size)
{ {
return 0x1e240000 | (Fn << 5) | Rd.index(); return (size == 8 ? 0x1e600800 : 0x1e200800) | (Fm.index() << 16)
| (Fn.index() << 5) | Fd.index();
} }
uint32_t fdiv(Register Fd, Register Fn, Register Fm, unsigned size)
{
return (size == 8 ? 0x1e601800 : 0x1e201800) | (Fm.index() << 16)
| (Fn.index() << 5) | Fd.index();
}
uint32_t fcvtSdDn(Register Fd, Register Fn)
{
return 0x1e624000 | (Fn.index() << 5) | Fd.index();
}
uint32_t fcvtDdSn(Register Fd, Register Fn)
{
return 0x1e22c000 | (Fn.index() << 5) | Fd.index();
}
uint32_t fcvtasXdDn(Register Rd, Register Fn)
{
return 0x9e640000 | (Fn.index() << 5) | Rd.index();
}
uint32_t fcvtasWdSn(Register Rd, Register Fn)
{
return 0x1e240000 | (Fn.index() << 5) | Rd.index();
}
uint32_t scvtfDdWn(Register Fd, Register Rn)
{
return 0x1e620000 | (Rn.index() << 5) | Fd.index();
}
uint32_t scvtfSdWn(Register Fd, Register Rn)
{
return 0x1e220000 | (Rn.index() << 5) | Fd.index();
}
uint32_t strFs(Register Fs, Register Rn, Register Rm, unsigned size)
{
return (size == 8 ? 0xfc206800 : 0xbc206800) | (Rm.index() << 16)
| (Rn.index() << 5) | Fs.index();
}
uint32_t strb(Register Rs, Register Rn, Register Rm)
{
return 0x38206800 | (Rm.index() << 16) | (Rn.index() << 5) | Rs.index();
}
uint32_t strh(Register Rs, Register Rn, Register Rm)
{
return 0x78206800 | (Rm.index() << 16) | (Rn.index() << 5) | Rs.index();
}
uint32_t striFs(Register Fs, Register Rn, int offset, unsigned size)
{
return (size == 8 ? 0xfc000000 : 0xbc000000) | (offset << 16)
| (Rn.index() << 5) | Fs.index();
}
uint32_t str(Register Rs, Register Rn, Register Rm, unsigned size)
{
return (size == 8 ? 0xf8206800 : 0xb8206800) | (Rm.index() << 16)
| (Rn.index() << 5) | Rs.index();
}
uint32_t strbi(Register Rs, Register Rn, int offset)
{
return 0x39000000 | (offset << 10) | (Rn.index() << 5) | Rs.index();
}
uint32_t strhi(Register Rs, Register Rn, int offset)
{
return 0x79000000 | (offset << 10) | (Rn.index() << 5) | Rs.index();
}
uint32_t stri(Register Rs, Register Rn, int offset, unsigned size)
{
return (size == 8 ? 0xb9000000 : 0xf9000000) | (offset << 10)
| (Rn.index() << 5) | Rs.index();
}
uint32_t ldrFd(Register Fd, Register Rn, Register Rm, unsigned size)
{
return (size == 8 ? 0xfc606800 : 0xbc606800) | (Rm.index() << 16)
| (Rn.index() << 5) | Fd.index();
}
uint32_t ldrb(Register Rd, Register Rn, Register Rm)
{
return 0x38606800 | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index();
}
uint32_t ldrsb(Register Rd, Register Rn, Register Rm)
{
return 0x38e06800 | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index();
}
uint32_t ldrh(Register Rd, Register Rn, Register Rm)
{
return 0x78606800 | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index();
}
uint32_t ldrsh(Register Rd, Register Rn, Register Rm)
{
return 0x78e06800 | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index();
}
uint32_t ldrsw(Register Rd, Register Rn, Register Rm)
{
return 0xb8a06800 | (Rm.index() << 16) | (Rn.index() << 5) | Rd.index();
}
uint32_t ldr(Register Rd, Register Rn, Register Rm, unsigned size)
{
return (size == 8 ? 0xf8606800 : 0xb8606800) | (Rm.index() << 16)
| (Rn.index() << 5) | Rd.index();
}
uint32_t ldriFd(Register Fd, Register Rn, int offset, unsigned size)
{
return (size == 8 ? 0xfc400000 : 0xbc400000) | (offset << 16)
| (Rn.index() << 5) | Fd.index();
}
uint32_t ldrbi(Register Rd, Register Rn, int offset)
{
return 0x39400000 | (offset << 10) | (Rn.index() << 5) | Rd.index();
}
uint32_t ldrsbi(Register Rd, Register Rn, int offset)
{
return 0x39c00000 | (offset << 10) | (Rn.index() << 5) | Rd.index();
}
uint32_t ldrhi(Register Rd, Register Rn, int offset)
{
return 0x79400000 | (offset << 10) | (Rn.index() << 5) | Rd.index();
}
uint32_t ldrshi(Register Rd, Register Rn, int offset)
{
return 0x79c00000 | (offset << 10) | (Rn.index() << 5) | Rd.index();
}
uint32_t ldrswi(Register Rd, Register Rn, int offset)
{
return 0xb9800000 | (offset << 10) | (Rn.index() << 5) | Rd.index();
}
uint32_t ldri(Register Rd, Register Rn, int offset, unsigned size)
{
return (size == 8 ? 0xb9400000 : 0xf9400000) | (offset << 10)
| (Rn.index() << 5) | Rd.index();
}
uint32_t fcmp(Register Fn, Register Fm, unsigned size)
{
return (size == 8 ? 0x1e602000 : 0x1e202000) | (Fm.index() << 16)
| (Fn.index() << 5);
}
uint32_t neg(Register Rd, Register Rm, unsigned size)
{
return (size == 8 ? 0xcb0003e0 : 0x4b0003e0) | (Rm.index() << 16)
| Rd.index();
}
uint32_t cmp(Register Rn, Register Rm, unsigned size)
{
return (size == 8 ? 0xeb00001f : 0x6b00001f) | (Rm.index() << 16)
| (Rn.index() << 5);
}
uint32_t cmpi(Register Rn, int value, unsigned shift, unsigned size)
{
return (size == 8 ? 0xf100001f : 0x7100001f) | (shift == 12 ? 0x400000 : 0)
| (value << 10) | (Rn.index() << 5);
}
uint32_t b(int offset)
{
return 0x14000000 | (offset >> 2);
}
uint32_t bl(int offset)
{
return 0x94000000 | (offset >> 2);
}
uint32_t blr(Register Rn)
{
return 0xd63f0000 | (Rn.index() << 5);
}
uint32_t beq(int offset)
{
return 0x54000000 | (offset >> 2);
}
uint32_t bne(int offset)
{
return 0x54000001 | (offset >> 2);
}
uint32_t blt(int offset)
{
return 0x5400000b | (offset >> 2);
}
uint32_t bgt(int offset)
{
return 0x5400000c | (offset >> 2);
}
uint32_t ble(int offset)
{
return 0x5400000d | (offset >> 2);
}
uint32_t bge(int offset)
{
return 0x5400000a | (offset >> 2);
}
uint32_t bhi(int offset)
{
return 0x54000008 | (offset >> 2);
}
uint32_t bpl(int offset)
{
return 0x54000005 | (offset >> 2);
}
uint32_t brk(int flag)
{
return 0xd4200020 | (flag << 5);
}
uint32_t dmb(int flag)
{
return 0xd50330bf | (flag << 8);
}
} // namespace
namespace avian {
namespace codegen {
namespace arm {
using namespace avian::util; using namespace avian::util;
void shiftLeftR(Context* c, void shiftLeftR(Context* c,
@ -533,9 +798,9 @@ void int2FloatRR(Context* c,
lir::RegisterPair* b) lir::RegisterPair* b)
{ {
if (size == 8) { if (size == 8) {
append(c, scvtfDdWn(fpr(b), b->low)); append(c, scvtfDdWn(fpr(a), b->low));
} else { } else {
append(c, scvtfSdWn(fpr(b), b->low)); append(c, scvtfSdWn(fpr(a), b->low));
} }
} }
@ -554,7 +819,7 @@ void floatAddR(Context* c,
lir::RegisterPair* b, lir::RegisterPair* b,
lir::RegisterPair* dst) lir::RegisterPair* dst)
{ {
append(c, fadd(fpr, dst, fpr(b), fpr(a), size)); append(c, fadd(fpr(dst), fpr(b), fpr(a), size));
} }
void floatSubtractR(Context* c, void floatSubtractR(Context* c,
@ -563,7 +828,7 @@ void floatSubtractR(Context* c,
lir::RegisterPair* b, lir::RegisterPair* b,
lir::RegisterPair* dst) lir::RegisterPair* dst)
{ {
append(c, fsub(fpr, dst, fpr(b), fpr(a), size)); append(c, fsub(fpr(dst), fpr(b), fpr(a), size));
} }
void floatMultiplyR(Context* c, void floatMultiplyR(Context* c,
@ -572,7 +837,7 @@ void floatMultiplyR(Context* c,
lir::RegisterPair* b, lir::RegisterPair* b,
lir::RegisterPair* dst) lir::RegisterPair* dst)
{ {
append(c, fmul(fpr, dst, fpr(b), fpr(a), size)); append(c, fmul(fpr(dst), fpr(b), fpr(a), size));
} }
void floatDivideR(Context* c, void floatDivideR(Context* c,
@ -581,19 +846,19 @@ void floatDivideR(Context* c,
lir::RegisterPair* b, lir::RegisterPair* b,
lir::RegisterPair* dst) lir::RegisterPair* dst)
{ {
append(c, fdiv(fpr, dst, fpr(b), fpr(a), size)); append(c, fdiv(fpr(dst), fpr(b), fpr(a), size));
} }
int normalize(Context* c, Register normalize(Context* c,
int offset, int offset,
int index, Register index,
unsigned scale, unsigned scale,
bool* preserveIndex, bool* preserveIndex,
bool* release) bool* release)
{ {
if (offset != 0 or scale != 1) { if (offset != 0 or scale != 1) {
lir::Register normalizedIndex( lir::RegisterPair normalizedIndex(
*preserveIndex ? con->client->acquireTemporary(GPR_MASK) : index); *preserveIndex ? c->client->acquireTemporary(GPR_MASK) : index);
if (*preserveIndex) { if (*preserveIndex) {
*release = true; *release = true;
@ -602,10 +867,10 @@ int normalize(Context* c,
*release = false; *release = false;
} }
int scaled; Register scaled;
if (scale != 1) { if (scale != 1) {
lir::Register unscaledIndex(index); lir::RegisterPair unscaledIndex(index);
ResolvedPromise scalePromise(log(scale)); ResolvedPromise scalePromise(log(scale));
lir::Constant scaleConstant(&scalePromise); lir::Constant scaleConstant(&scalePromise);
@ -622,12 +887,12 @@ int normalize(Context* c,
} }
if (offset != 0) { if (offset != 0) {
lir::Register untranslatedIndex(scaled); lir::RegisterPair untranslatedIndex(scaled);
ResolvedPromise offsetPromise(offset); ResolvedPromise offsetPromise(offset);
lir::Constant offsetConstant(&offsetPromise); lir::Constant offsetConstant(&offsetPromise);
lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK));
moveCR(c, moveCR(c,
vm::TargetBytesPerWord, vm::TargetBytesPerWord,
&offsetConstant, &offsetConstant,
@ -638,7 +903,7 @@ int normalize(Context* c,
&tmp, &tmp,
&untranslatedIndex, &untranslatedIndex,
&normalizedIndex); &normalizedIndex);
con->client->releaseTemporary(tmp.low); c->client->releaseTemporary(tmp.low);
} }
return normalizedIndex.low; return normalizedIndex.low;
@ -651,15 +916,21 @@ int normalize(Context* c,
void store(Context* c, void store(Context* c,
unsigned size, unsigned size,
lir::RegisterPair* src, lir::RegisterPair* src,
int base, Register base,
int offset, int offset,
int index, Register index,
unsigned scale, unsigned scale,
bool preserveIndex) bool preserveIndex)
{ {
if (index != lir::NoRegister) { if (index != NoRegister) {
bool release; bool release;
int normalized
// todo: browsing the instruction set, it looks like we could do a
// scaled store or load in a single instruction if the offset is
// zero, and we could simplify things for the case of non-zero
// offsets also
Register normalized
= normalize(c, offset, index, scale, &preserveIndex, &release); = normalize(c, offset, index, scale, &preserveIndex, &release);
if (isFpr(src)) { if (isFpr(src)) {
@ -726,7 +997,7 @@ void store(Context* c,
} }
} }
} else { } else {
lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK));
ResolvedPromise offsetPromise(offset); ResolvedPromise offsetPromise(offset);
lir::Constant offsetConstant(&offsetPromise); lir::Constant offsetConstant(&offsetPromise);
moveCR(c, moveCR(c,
@ -755,18 +1026,18 @@ void moveRM(Context* c,
void load(Context* c, void load(Context* c,
unsigned srcSize, unsigned srcSize,
int base, Register base,
int offset, int offset,
int index, Register index,
unsigned scale, unsigned scale,
unsigned dstSize, unsigned dstSize,
lir::RegisterPair* dst, lir::RegisterPair* dst,
bool preserveIndex, bool preserveIndex,
bool signExtend) bool signExtend)
{ {
if (index != lir::NoRegister) { if (index != NoRegister) {
bool release; bool release;
int normalized Register normalized
= normalize(c, offset, index, scale, &preserveIndex, &release); = normalize(c, offset, index, scale, &preserveIndex, &release);
if (isFpr(dst)) { // FPR load if (isFpr(dst)) { // FPR load
@ -819,7 +1090,7 @@ void load(Context* c,
switch (srcSize) { switch (srcSize) {
case 4: case 4:
case 8: case 8:
append(c, ldriFd(fpr(dst->low), base, offset)); append(c, ldriFd(fpr(dst->low), base, offset, srcSize));
break; break;
default: default:
@ -848,7 +1119,7 @@ void load(Context* c,
if (signExtend and srcSize == 4 and dstSize == 8) { if (signExtend and srcSize == 4 and dstSize == 8) {
append(c, ldrswi(dst->low, base, offset)); append(c, ldrswi(dst->low, base, offset));
} else { } else {
append(c, ldri(dst->low, base, offset, size)); append(c, ldri(dst->low, base, offset, srcSize));
} }
break; break;
@ -857,7 +1128,7 @@ void load(Context* c,
} }
} }
} else { } else {
lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK));
ResolvedPromise offsetPromise(offset); ResolvedPromise offsetPromise(offset);
lir::Constant offsetConstant(&offsetPromise); lir::Constant offsetConstant(&offsetPromise);
moveCR(c, moveCR(c,
@ -927,7 +1198,7 @@ void andC(Context* c,
if (~v) { if (~v) {
bool useTemporary = b->low == dst->low; bool useTemporary = b->low == dst->low;
lir::Register tmp(dst->low); lir::RegisterPair tmp(dst->low);
if (useTemporary) { if (useTemporary) {
tmp.low = c->client->acquireTemporary(GPR_MASK); tmp.low = c->client->acquireTemporary(GPR_MASK);
} }
@ -972,7 +1243,7 @@ void moveAR(Context* c,
lir::Constant constant(src->address); lir::Constant constant(src->address);
moveCR(c, srcSize, &constant, dstSize, dst); moveCR(c, srcSize, &constant, dstSize, dst);
lir::Memory memory(dst->low, 0, -1, 0); lir::Memory memory(dst->low, 0, NoRegister, 0);
moveMR(c, dstSize, &memory, dstSize, dst); moveMR(c, dstSize, &memory, dstSize, dst);
} }
@ -995,7 +1266,7 @@ void compareRR(Context* c,
void compareCR(Context* c, void compareCR(Context* c,
unsigned aSize, unsigned aSize,
lir::Constant* a, lir::Constant* a,
unsigned bSize, unsigned bSize UNUSED,
lir::RegisterPair* b) lir::RegisterPair* b)
{ {
assertT(c, aSize == bSize); assertT(c, aSize == bSize);
@ -1003,9 +1274,9 @@ void compareCR(Context* c,
int32_t v = a->value->value(); int32_t v = a->value->value();
if (v) { if (v) {
if (v > 0 and v < 0x1000) { if (v > 0 and v < 0x1000) {
append(c, cmpi(b->low, v, 0, size)); append(c, cmpi(b->low, v, 0, aSize));
} 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, size)); append(c, cmpi(b->low, v >> 12, 12, aSize));
} else { } else {
// todo // todo
abort(c); abort(c);
@ -1021,7 +1292,7 @@ void compareCM(Context* c,
{ {
assertT(c, aSize == bSize); assertT(c, aSize == bSize);
lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK));
moveMR(c, bSize, b, bSize, &tmp); moveMR(c, bSize, b, bSize, &tmp);
compareCR(c, aSize, a, bSize, &tmp); compareCR(c, aSize, a, bSize, &tmp);
c->client->releaseTemporary(tmp.low); c->client->releaseTemporary(tmp.low);
@ -1035,7 +1306,7 @@ void compareRM(Context* c,
{ {
assertT(c, aSize == bSize); assertT(c, aSize == bSize);
lir::Register tmp(c->client->acquireTemporary(GPR_MASK)); lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK));
moveMR(c, bSize, b, bSize, &tmp); moveMR(c, bSize, b, bSize, &tmp);
compareRR(c, aSize, a, bSize, &tmp); compareRR(c, aSize, a, bSize, &tmp);
c->client->releaseTemporary(tmp.low); c->client->releaseTemporary(tmp.low);
@ -1083,7 +1354,7 @@ int32_t branch(Context* c, lir::TernaryOperation op)
void conditional(Context* c, int32_t branch, lir::Constant* target) void conditional(Context* c, int32_t branch, lir::Constant* target)
{ {
appendOffsetTask(c, target->value, offsetPromise(con)); appendOffsetTask(c, target->value, offsetPromise(c));
append(c, branch); append(c, branch);
} }
@ -1149,7 +1420,7 @@ ShiftMaskPromise* shiftMaskPromise(Context* c,
unsigned shift, unsigned shift,
int64_t mask) int64_t mask)
{ {
return new (con->zone) ShiftMaskPromise(base, shift, mask); return new (c->zone) ShiftMaskPromise(base, shift, mask);
} }
void moveCM(Context* c, void moveCM(Context* c,
@ -1170,10 +1441,10 @@ void moveCM(Context* c,
} break; } break;
default: default:
lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); lir::RegisterPair tmp(c->client->acquireTemporary(GPR_MASK));
moveCR(c, srcSize, src, dstSize, &tmp); moveCR(c, srcSize, src, dstSize, &tmp);
moveRM(c, dstSize, &tmp, dstSize, dst); moveRM(c, dstSize, &tmp, dstSize, dst);
con->client->releaseTemporary(tmp.low); c->client->releaseTemporary(tmp.low);
} }
} }
@ -1206,7 +1477,8 @@ void longCallC(Context* c, unsigned size UNUSED, lir::Constant* target)
{ {
assertT(c, size == vm::TargetBytesPerWord); assertT(c, size == vm::TargetBytesPerWord);
lir::Register tmp(9); // a non-arg reg that we don't mind clobbering lir::RegisterPair tmp(
Register(9)); // a non-arg reg that we don't mind clobbering
moveCR2(c, vm::TargetBytesPerWord, target, &tmp, offsetPromise(c)); moveCR2(c, vm::TargetBytesPerWord, target, &tmp, offsetPromise(c));
callR(c, vm::TargetBytesPerWord, &tmp); callR(c, vm::TargetBytesPerWord, &tmp);
} }
@ -1215,7 +1487,8 @@ void longJumpC(Context* c, unsigned size UNUSED, lir::Constant* target)
{ {
assertT(c, size == vm::TargetBytesPerWord); assertT(c, size == vm::TargetBytesPerWord);
lir::Register tmp(9); // a non-arg reg that we don't mind clobbering lir::RegisterPair tmp(
Register(9)); // a non-arg reg that we don't mind clobbering
moveCR2(c, vm::TargetBytesPerWord, target, &tmp, offsetPromise(c)); moveCR2(c, vm::TargetBytesPerWord, target, &tmp, offsetPromise(c));
jumpR(c, vm::TargetBytesPerWord, &tmp); jumpR(c, vm::TargetBytesPerWord, &tmp);
} }
@ -1246,7 +1519,7 @@ void trap(Context* c)
void memoryBarrier(Context* c) void memoryBarrier(Context* c)
{ {
append(c, dmb()); append(c, dmb(0xF));
} }
void loadBarrier(Context* c) void loadBarrier(Context* c)
@ -1264,6 +1537,21 @@ void storeLoadBarrier(Context* c)
memoryBarrier(c); memoryBarrier(c);
} }
bool needJump(MyBlock*)
{
return false;
}
unsigned padding(MyBlock*, unsigned)
{
return 0;
}
void resolve(MyBlock*)
{
// ignore
}
} // namespace arm } // namespace arm
} // namespace codegen } // namespace codegen
} // namespace avian } // namespace avian

View File

@ -14,6 +14,8 @@
#include <avian/codegen/lir.h> #include <avian/codegen/lir.h>
#include <avian/codegen/assembler.h> #include <avian/codegen/assembler.h>
#include "avian/environment.h"
namespace avian { namespace avian {
namespace codegen { namespace codegen {
namespace arm { namespace arm {
@ -21,11 +23,10 @@ namespace arm {
const uint64_t MASK_LO32 = 0xffffffff; const uint64_t MASK_LO32 = 0xffffffff;
const unsigned MASK_LO8 = 0xff; const unsigned MASK_LO8 = 0xff;
#ifdef ARCH_arm64 #if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM64
constexpr Register ThreadRegister(19); constexpr Register ThreadRegister(19);
constexpr Register StackRegister(31); constexpr Register StackRegister(31);
constexpr Register LinkRegister(30); constexpr Register LinkRegister(30);
constexpr Register LinkRegister(29);
constexpr Register ProgramCounter(0xFE); // i.e. unaddressable constexpr Register ProgramCounter(0xFE); // i.e. unaddressable
const int N_GPRS = 32; const int N_GPRS = 32;