зеркало из https://github.com/mozilla/gecko-dev.git
fixes to enable ARM nanojit to build, at least
This commit is contained in:
Родитель
cd748b3d56
Коммит
627b88fb8f
|
@ -214,7 +214,7 @@ namespace nanojit
|
||||||
|
|
||||||
// nothing free, steal one
|
// nothing free, steal one
|
||||||
// LSRA says pick the one with the furthest use
|
// LSRA says pick the one with the furthest use
|
||||||
LIns* vic = findVictim(regs,allow);
|
LIns* vic = findVictim(regs, allow);
|
||||||
NanoAssert(vic != NULL);
|
NanoAssert(vic != NULL);
|
||||||
|
|
||||||
Reservation* resv = getresv(vic);
|
Reservation* resv = getresv(vic);
|
||||||
|
@ -527,6 +527,16 @@ namespace nanojit
|
||||||
{
|
{
|
||||||
return findRegFor(i, rmask(w));
|
return findRegFor(i, rmask(w));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Register Assembler::getBaseReg(LIns *i, int &d, RegisterMask allow)
|
||||||
|
{
|
||||||
|
if (i->isop(LIR_alloc)) {
|
||||||
|
d += findMemFor(i);
|
||||||
|
return FP;
|
||||||
|
} else {
|
||||||
|
return findRegFor(i, allow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Register Assembler::findRegFor(LIns* i, RegisterMask allow)
|
Register Assembler::findRegFor(LIns* i, RegisterMask allow)
|
||||||
{
|
{
|
||||||
|
@ -554,6 +564,8 @@ namespace nanojit
|
||||||
resv = reserveAlloc(i);
|
resv = reserveAlloc(i);
|
||||||
|
|
||||||
r = resv->reg;
|
r = resv->reg;
|
||||||
|
|
||||||
|
#ifdef AVMPLUS_IA32
|
||||||
if (r != UnknownReg &&
|
if (r != UnknownReg &&
|
||||||
((rmask(r)&XmmRegs) && !(allow&XmmRegs) ||
|
((rmask(r)&XmmRegs) && !(allow&XmmRegs) ||
|
||||||
(rmask(r)&x87Regs) && !(allow&x87Regs)))
|
(rmask(r)&x87Regs) && !(allow&x87Regs)))
|
||||||
|
@ -563,6 +575,7 @@ namespace nanojit
|
||||||
evict(r);
|
evict(r);
|
||||||
r = UnknownReg;
|
r = UnknownReg;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (r == UnknownReg)
|
if (r == UnknownReg)
|
||||||
{
|
{
|
||||||
|
@ -610,6 +623,20 @@ namespace nanojit
|
||||||
return rr;
|
return rr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Assembler::asm_spilli(LInsp i, Reservation *resv, bool pop)
|
||||||
|
{
|
||||||
|
int d = disp(resv);
|
||||||
|
Register rr = resv->reg;
|
||||||
|
bool quad = i->opcode() == LIR_param || i->isQuad();
|
||||||
|
asm_spill(rr, d, pop, quad);
|
||||||
|
if (d)
|
||||||
|
{
|
||||||
|
verbose_only(if (_verbose) {
|
||||||
|
outputf(" spill %s",_thisfrag->lirbuf->names->formatRef(i));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Assembler::freeRsrcOf(LIns *i, bool pop)
|
void Assembler::freeRsrcOf(LIns *i, bool pop)
|
||||||
{
|
{
|
||||||
Reservation* resv = getresv(i);
|
Reservation* resv = getresv(i);
|
||||||
|
@ -667,13 +694,7 @@ namespace nanojit
|
||||||
// No 64-bit immediates so fall-back to below
|
// No 64-bit immediates so fall-back to below
|
||||||
}
|
}
|
||||||
else if (!rhs->isQuad()) {
|
else if (!rhs->isQuad()) {
|
||||||
Register r;
|
Register r = getBaseReg(lhs, c, GpRegs);
|
||||||
if (lhs->isop(LIR_alloc)) {
|
|
||||||
r = FP;
|
|
||||||
c += findMemFor(lhs);
|
|
||||||
} else {
|
|
||||||
r = findRegFor(lhs, GpRegs);
|
|
||||||
}
|
|
||||||
CMPi(r, c);
|
CMPi(r, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1070,7 +1091,11 @@ namespace nanojit
|
||||||
JMP(_epilogue);
|
JMP(_epilogue);
|
||||||
}
|
}
|
||||||
assignSavedParams();
|
assignSavedParams();
|
||||||
|
#ifdef NANOJIT_IA32
|
||||||
findSpecificRegFor(ins->oprnd1(), FST0);
|
findSpecificRegFor(ins->oprnd1(), FST0);
|
||||||
|
#else
|
||||||
|
NanoAssert(false);
|
||||||
|
#endif
|
||||||
fpu_pop();
|
fpu_pop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1135,13 +1160,12 @@ namespace nanojit
|
||||||
// incoming arg in register
|
// incoming arg in register
|
||||||
prepResultReg(ins, rmask(argRegs[a]));
|
prepResultReg(ins, rmask(argRegs[a]));
|
||||||
} else {
|
} else {
|
||||||
// incoming arg is on stack, and EAX points nearby (see genPrologue)
|
// incoming arg is on stack, and EBP points nearby (see genPrologue)
|
||||||
//_nvprof("param-evict-eax",1);
|
Register r = prepResultReg(ins, GpRegs);
|
||||||
Register r = prepResultReg(ins, GpRegs & ~rmask(EAX));
|
|
||||||
int d = (a - abi_regcount) * sizeof(intptr_t) + 8;
|
int d = (a - abi_regcount) * sizeof(intptr_t) + 8;
|
||||||
LD(r, d, FP);
|
LD(r, d, FP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// saved param
|
// saved param
|
||||||
prepResultReg(ins, rmask(savedRegs[a]));
|
prepResultReg(ins, rmask(savedRegs[a]));
|
||||||
|
@ -1243,14 +1267,8 @@ namespace nanojit
|
||||||
LIns* base = ins->oprnd1();
|
LIns* base = ins->oprnd1();
|
||||||
LIns* disp = ins->oprnd2();
|
LIns* disp = ins->oprnd2();
|
||||||
Register rr = prepResultReg(ins, GpRegs);
|
Register rr = prepResultReg(ins, GpRegs);
|
||||||
Register ra;
|
|
||||||
int d = disp->constval();
|
int d = disp->constval();
|
||||||
if (base->isop(LIR_alloc)) {
|
Register ra = getBaseReg(base, d, GpRegs);
|
||||||
ra = FP;
|
|
||||||
d += findMemFor(base);
|
|
||||||
} else {
|
|
||||||
ra = findRegFor(base, GpRegs);
|
|
||||||
}
|
|
||||||
if (op == LIR_ldcb)
|
if (op == LIR_ldcb)
|
||||||
LD8Z(rr, d, ra);
|
LD8Z(rr, d, ra);
|
||||||
else
|
else
|
||||||
|
|
|
@ -226,8 +226,9 @@ namespace nanojit
|
||||||
void unionRegisterState(RegAlloc& saved);
|
void unionRegisterState(RegAlloc& saved);
|
||||||
void assignSaved(RegAlloc &saved, RegisterMask skip);
|
void assignSaved(RegAlloc &saved, RegisterMask skip);
|
||||||
LInsp findVictim(RegAlloc& regs, RegisterMask allow);
|
LInsp findVictim(RegAlloc& regs, RegisterMask allow);
|
||||||
|
|
||||||
int findMemFor(LIns* i);
|
Register getBaseReg(LIns *i, int &d, RegisterMask allow);
|
||||||
|
int findMemFor(LIns* i);
|
||||||
Register findRegFor(LIns* i, RegisterMask allow);
|
Register findRegFor(LIns* i, RegisterMask allow);
|
||||||
void findRegFor2(RegisterMask allow, LIns* ia, Reservation* &ra, LIns *ib, Reservation* &rb);
|
void findRegFor2(RegisterMask allow, LIns* ia, Reservation* &ra, LIns *ib, Reservation* &rb);
|
||||||
Register findSpecificRegFor(LIns* i, Register w);
|
Register findSpecificRegFor(LIns* i, Register w);
|
||||||
|
@ -290,7 +291,7 @@ namespace nanojit
|
||||||
void asm_restore(LInsp, Reservation*, Register);
|
void asm_restore(LInsp, Reservation*, Register);
|
||||||
void asm_load(int d, Register r);
|
void asm_load(int d, Register r);
|
||||||
void asm_spilli(LInsp i, Reservation *resv, bool pop);
|
void asm_spilli(LInsp i, Reservation *resv, bool pop);
|
||||||
void asm_spill(Register rr, int d, bool pop=false, bool quad=false);
|
void asm_spill(Register rr, int d, bool pop, bool quad);
|
||||||
void asm_load64(LInsp i);
|
void asm_load64(LInsp i);
|
||||||
void asm_pusharg(LInsp p);
|
void asm_pusharg(LInsp p);
|
||||||
NIns* asm_adjustBranch(NIns* at, NIns* target);
|
NIns* asm_adjustBranch(NIns* at, NIns* target);
|
||||||
|
|
|
@ -1049,22 +1049,23 @@ namespace nanojit
|
||||||
NanoAssert(op != LIR_skip); // LIR_skip here is just an error condition
|
NanoAssert(op != LIR_skip); // LIR_skip here is just an error condition
|
||||||
|
|
||||||
ArgSize sizes[2*MAXARGS];
|
ArgSize sizes[2*MAXARGS];
|
||||||
uint32_t argc = ci->get_sizes(sizes);
|
int32_t argc = ci->get_sizes(sizes);
|
||||||
|
|
||||||
#ifdef NJ_SOFTFLOAT
|
#ifdef NJ_SOFTFLOAT
|
||||||
if (op == LIR_fcall)
|
if (op == LIR_fcall)
|
||||||
op = LIR_callh;
|
op = LIR_callh;
|
||||||
LInsp args2[MAXARGS*2]; // arm could require 2 args per double
|
LInsp args2[MAXARGS*2]; // arm could require 2 args per double
|
||||||
int32_t j = 0;
|
int32_t j = 0;
|
||||||
for (int32_t i = 0; i < MAXARGS; i++) {
|
int32_t i = 0;
|
||||||
|
while (j < argc) {
|
||||||
argt >>= 2;
|
argt >>= 2;
|
||||||
ArgSize a = ArgSize(argt&3);
|
ArgSize a = ArgSize(argt&3);
|
||||||
if (a == ARGSIZE_F) {
|
if (a == ARGSIZE_F) {
|
||||||
LInsp q = args[i];
|
LInsp q = args[i++];
|
||||||
args2[j++] = ins1(LIR_qhi, q);
|
args2[j++] = ins1(LIR_qhi, q);
|
||||||
args2[j++] = ins1(LIR_qlo, q);
|
args2[j++] = ins1(LIR_qlo, q);
|
||||||
} else if (a != ARGSIZE_NONE) {
|
} else {
|
||||||
args2[j++] = args[i];
|
args2[j++] = args[i++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args = args2;
|
args = args2;
|
||||||
|
@ -1074,13 +1075,13 @@ namespace nanojit
|
||||||
NanoAssert(argc <= MAXARGS);
|
NanoAssert(argc <= MAXARGS);
|
||||||
uint32_t words = argwords(argc);
|
uint32_t words = argwords(argc);
|
||||||
ensureRoom(words+LIns::callInfoWords+1+argc); // ins size + possible tramps
|
ensureRoom(words+LIns::callInfoWords+1+argc); // ins size + possible tramps
|
||||||
for (uint32_t i=0; i < argc; i++)
|
for (int32_t i=0; i < argc; i++)
|
||||||
args[i] = ensureReferenceable(args[i], argc-i);
|
args[i] = ensureReferenceable(args[i], argc-i);
|
||||||
uint8_t* offs = (uint8_t*)_buf->next();
|
uint8_t* offs = (uint8_t*)_buf->next();
|
||||||
LIns *l = _buf->next() + words;
|
LIns *l = _buf->next() + words;
|
||||||
*(const CallInfo **)l = ci;
|
*(const CallInfo **)l = ci;
|
||||||
l += LIns::callInfoWords;
|
l += LIns::callInfoWords;
|
||||||
for (uint32_t i=0; i < argc; i++)
|
for (int32_t i=0; i < argc; i++)
|
||||||
offs[i] = (uint8_t) l->reference(args[i]);
|
offs[i] = (uint8_t) l->reference(args[i]);
|
||||||
#if defined NANOJIT_64BIT
|
#if defined NANOJIT_64BIT
|
||||||
l->initOpcode(op);
|
l->initOpcode(op);
|
||||||
|
|
|
@ -64,16 +64,15 @@ const char* regNames[] = {"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10
|
||||||
|
|
||||||
const Register Assembler::argRegs[] = { R0, R1, R2, R3 };
|
const Register Assembler::argRegs[] = { R0, R1, R2, R3 };
|
||||||
const Register Assembler::retRegs[] = { R0, R1 };
|
const Register Assembler::retRegs[] = { R0, R1 };
|
||||||
|
const Register Assembler::savedRegs[] = { R4, R5, R6, R7, R8, R9, R10 };
|
||||||
|
|
||||||
void
|
void
|
||||||
Assembler::nInit(AvmCore*)
|
Assembler::nInit(AvmCore*)
|
||||||
{
|
{
|
||||||
// all ARMs have conditional move
|
|
||||||
avmplus::AvmCore::cmov_available = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NIns*
|
NIns*
|
||||||
Assembler::genPrologue(RegisterMask needSaving)
|
Assembler::genPrologue()
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Prologue
|
* Prologue
|
||||||
|
@ -81,16 +80,14 @@ Assembler::genPrologue(RegisterMask needSaving)
|
||||||
|
|
||||||
// NJ_RESV_OFFSET is space at the top of the stack for us
|
// NJ_RESV_OFFSET is space at the top of the stack for us
|
||||||
// to use for parameter passing (8 bytes at the moment)
|
// to use for parameter passing (8 bytes at the moment)
|
||||||
uint32_t stackNeeded = 4 * _activation.highwatermark + NJ_STACK_OFFSET;
|
uint32_t stackNeeded = STACK_GRANULARITY * _activation.highwatermark + NJ_STACK_OFFSET;
|
||||||
uint32_t savingCount = 0;
|
uint32_t savingCount = 0;
|
||||||
|
|
||||||
uint32_t savingMask = 0;
|
uint32_t savingMask = SavedRegs | rmask(FP) | rmask(LR);
|
||||||
savingCount = 9; //R4-R10,R11,LR
|
savingCount = NumSavedRegs+2;
|
||||||
savingMask = SavedRegs | rmask(FRAME_PTR);
|
|
||||||
(void)needSaving;
|
|
||||||
|
|
||||||
// so for alignment purposes we've pushed return addr, fp, and savingCount registers
|
// so for alignment purposes we've pushed return addr, fp, and savingCount registers
|
||||||
uint32_t stackPushed = 4 * (2+savingCount);
|
uint32_t stackPushed = STACK_GRANULARITY * savingCount;
|
||||||
uint32_t aligned = alignUp(stackNeeded + stackPushed, NJ_ALIGN_STACK);
|
uint32_t aligned = alignUp(stackNeeded + stackPushed, NJ_ALIGN_STACK);
|
||||||
int32_t amt = aligned - stackPushed;
|
int32_t amt = aligned - stackPushed;
|
||||||
|
|
||||||
|
@ -102,8 +99,8 @@ Assembler::genPrologue(RegisterMask needSaving)
|
||||||
verbose_only( verbose_output(" patch entry"); )
|
verbose_only( verbose_output(" patch entry"); )
|
||||||
NIns *patchEntry = _nIns;
|
NIns *patchEntry = _nIns;
|
||||||
|
|
||||||
MR(FRAME_PTR, SP);
|
MR(FP, SP);
|
||||||
PUSH_mask(savingMask|rmask(LR));
|
PUSH_mask(savingMask);
|
||||||
return patchEntry;
|
return patchEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +127,7 @@ Assembler::nFragExit(LInsp guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pop the stack frame first
|
// pop the stack frame first
|
||||||
MR(SP, FRAME_PTR);
|
MR(SP, FP);
|
||||||
|
|
||||||
#ifdef NJ_VERBOSE
|
#ifdef NJ_VERBOSE
|
||||||
if (_frago->core()->config.show_stats) {
|
if (_frago->core()->config.show_stats) {
|
||||||
|
@ -146,11 +143,14 @@ Assembler::nFragExit(LInsp guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
NIns*
|
NIns*
|
||||||
Assembler::genEpilogue(RegisterMask restore)
|
Assembler::genEpilogue()
|
||||||
{
|
{
|
||||||
BX(LR); // return
|
BX(LR); // return
|
||||||
MR(R0,R2); // return LinkRecord*
|
|
||||||
RegisterMask savingMask = restore | rmask(FRAME_PTR) | rmask(LR);
|
// this is needed if we jump here from nFragExit
|
||||||
|
//MR(R0,R2); // return LinkRecord*
|
||||||
|
|
||||||
|
RegisterMask savingMask = SavedRegs | rmask(FP) | rmask(LR);
|
||||||
POP_mask(savingMask); // regs
|
POP_mask(savingMask); // regs
|
||||||
return _nIns;
|
return _nIns;
|
||||||
}
|
}
|
||||||
|
@ -252,6 +252,62 @@ Assembler::asm_call(LInsp ins)
|
||||||
roffset = 1;
|
roffset = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Assembler::asm_arg(ArgSize sz, LInsp p, Register r)
|
||||||
|
{
|
||||||
|
if (sz == ARGSIZE_Q)
|
||||||
|
{
|
||||||
|
// ref arg - use lea
|
||||||
|
if (r != UnknownReg)
|
||||||
|
{
|
||||||
|
// arg in specific reg
|
||||||
|
int da = findMemFor(p);
|
||||||
|
LEA(r, da, FP);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NanoAssert(0); // not supported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (sz == ARGSIZE_LO)
|
||||||
|
{
|
||||||
|
if (r != UnknownReg) {
|
||||||
|
// arg goes in specific register
|
||||||
|
if (p->isconst()) {
|
||||||
|
LDi(r, p->constval());
|
||||||
|
} else {
|
||||||
|
Reservation* rA = getresv(p);
|
||||||
|
if (rA) {
|
||||||
|
if (rA->reg == UnknownReg) {
|
||||||
|
// load it into the arg reg
|
||||||
|
int d = findMemFor(p);
|
||||||
|
if (p->isop(LIR_alloc)) {
|
||||||
|
LEA(r, d, FP);
|
||||||
|
} else {
|
||||||
|
LD(r, d, FP);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// it must be in a saved reg
|
||||||
|
MR(r, rA->reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// this is the last use, so fine to assign it
|
||||||
|
// to the scratch reg, it's dead after this point.
|
||||||
|
findSpecificRegFor(p, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
asm_pusharg(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NanoAssert(sz == ARGSIZE_F);
|
||||||
|
asm_farg(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Assembler::nMarkExecute(Page* page, int32_t count, bool enable)
|
Assembler::nMarkExecute(Page* page, int32_t count, bool enable)
|
||||||
|
@ -399,15 +455,11 @@ Assembler::asm_restore(LInsp i, Reservation *resv, Register r)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Assembler::asm_spill(LInsp i, Reservation *resv, bool pop)
|
Assembler::asm_spill(Register rr, int d, bool pop, bool quad)
|
||||||
{
|
{
|
||||||
(void)i;
|
(void) pop;
|
||||||
(void)pop;
|
(void) quad;
|
||||||
//fprintf (stderr, "resv->arIndex: %d\n", resv->arIndex);
|
if (d) {
|
||||||
if (resv->arIndex) {
|
|
||||||
int d = disp(resv);
|
|
||||||
// save to spill location
|
|
||||||
Register rr = resv->reg;
|
|
||||||
if (IsFpReg(rr)) {
|
if (IsFpReg(rr)) {
|
||||||
if (isS8(d >> 2)) {
|
if (isS8(d >> 2)) {
|
||||||
FSTD(rr, FP, d);
|
FSTD(rr, FP, d);
|
||||||
|
@ -418,11 +470,6 @@ Assembler::asm_spill(LInsp i, Reservation *resv, bool pop)
|
||||||
} else {
|
} else {
|
||||||
STR(rr, FP, d);
|
STR(rr, FP, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
verbose_only(if (_verbose){
|
|
||||||
outputf(" spill %s",_thisfrag->lirbuf->names->formatRef(i));
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,7 +670,7 @@ Assembler::asm_nongp_copy(Register r, Register s)
|
||||||
}
|
}
|
||||||
|
|
||||||
Register
|
Register
|
||||||
Assembler::asm_binop_rhs_reg(LInsp ins)
|
Assembler::asm_binop_rhs_reg(LInsp)
|
||||||
{
|
{
|
||||||
return UnknownReg;
|
return UnknownReg;
|
||||||
}
|
}
|
||||||
|
@ -871,7 +918,7 @@ Assembler::LD32_nochk(Register r, int32_t imm)
|
||||||
void
|
void
|
||||||
Assembler::B_cond_chk(ConditionCode _c, NIns* _t, bool _chk)
|
Assembler::B_cond_chk(ConditionCode _c, NIns* _t, bool _chk)
|
||||||
{
|
{
|
||||||
int32 offs = PC_OFFSET_FROM(_t,_nIns-1);
|
int32_t offs = PC_OFFSET_FROM(_t,_nIns-1);
|
||||||
//fprintf(stderr, "B_cond_chk target: 0x%08x offset: %d @0x%08x\n", _t, offs, _nIns-1);
|
//fprintf(stderr, "B_cond_chk target: 0x%08x offset: %d @0x%08x\n", _t, offs, _nIns-1);
|
||||||
if (isS24(offs)) {
|
if (isS24(offs)) {
|
||||||
if (_chk) underrunProtect(4);
|
if (_chk) underrunProtect(4);
|
||||||
|
@ -1094,7 +1141,7 @@ Assembler::asm_fcmp(LInsp ins)
|
||||||
}
|
}
|
||||||
|
|
||||||
Register
|
Register
|
||||||
Assembler::asm_prep_fcall(Reservation* rR, LInsp ins)
|
Assembler::asm_prep_fcall(Reservation*, LInsp)
|
||||||
{
|
{
|
||||||
// We have nothing to do here; we do it all in asm_call.
|
// We have nothing to do here; we do it all in asm_call.
|
||||||
return UnknownReg;
|
return UnknownReg;
|
||||||
|
|
|
@ -42,6 +42,17 @@
|
||||||
#define __nanojit_NativeArm__
|
#define __nanojit_NativeArm__
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef PERFM
|
||||||
|
#include "../vprof/vprof.h"
|
||||||
|
#define count_instr() _nvprof("arm",1)
|
||||||
|
#define count_prolog() _nvprof("arm-prolog",1); count_instr();
|
||||||
|
#define count_imt() _nvprof("arm-imt",1) count_instr()
|
||||||
|
#else
|
||||||
|
#define count_instr()
|
||||||
|
#define count_prolog()
|
||||||
|
#define count_imt()
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace nanojit
|
namespace nanojit
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -50,7 +61,7 @@ const int NJ_LOG2_PAGE_SIZE = 12; // 4K
|
||||||
// If NJ_ARM_VFP is defined, then VFP is assumed to
|
// If NJ_ARM_VFP is defined, then VFP is assumed to
|
||||||
// be present. If it's not defined, then softfloat
|
// be present. If it's not defined, then softfloat
|
||||||
// is used, and NJ_SOFTFLOAT is defined.
|
// is used, and NJ_SOFTFLOAT is defined.
|
||||||
#define NJ_ARM_VFP
|
//#define NJ_ARM_VFP
|
||||||
|
|
||||||
#ifdef NJ_ARM_VFP
|
#ifdef NJ_ARM_VFP
|
||||||
|
|
||||||
|
@ -107,10 +118,6 @@ typedef enum {
|
||||||
|
|
||||||
FirstFloatReg = 16,
|
FirstFloatReg = 16,
|
||||||
LastFloatReg = 22,
|
LastFloatReg = 22,
|
||||||
|
|
||||||
// helpers
|
|
||||||
FRAME_PTR = 11,
|
|
||||||
ESP = SP,
|
|
||||||
|
|
||||||
FirstReg = 0,
|
FirstReg = 0,
|
||||||
#ifdef NJ_ARM_VFP
|
#ifdef NJ_ARM_VFP
|
||||||
|
@ -152,13 +159,15 @@ typedef struct _FragInfo {
|
||||||
NIns* epilogue;
|
NIns* epilogue;
|
||||||
} FragInfo;
|
} FragInfo;
|
||||||
|
|
||||||
#ifdef ARM_VFP
|
#ifdef NJ_ARM_VFP
|
||||||
static const RegisterMask SavedFpRegs = 1<<D0 | 1<<D1 | 1<<D2 | 1<<D3 | 1<<D4 | 1<<D5 | 1<<D6 | 1<<D7;
|
static const RegisterMask SavedFpRegs = 1<<D0 | 1<<D1 | 1<<D2 | 1<<D3 | 1<<D4 | 1<<D5 | 1<<D6 | 1<<D7;
|
||||||
|
static const RegisterMask SavedRegs = 1<<R4 | 1<<R5 | 1<<R6 | 1<<R7 | 1<<R8 | 1<<R9 | 1<<R10 | SavedFpRegs;
|
||||||
|
static const int NumSavedRegs = 15;
|
||||||
#else
|
#else
|
||||||
static const RegisterMask SavedFpRegs = 0;
|
static const RegisterMask SavedFpRegs = 0;
|
||||||
#endif
|
static const RegisterMask SavedRegs = 1<<R4 | 1<<R5 | 1<<R6 | 1<<R7 | 1<<R8 | 1<<R9 | 1<<R10;
|
||||||
static const int NumSavedRegs = 7;
|
static const int NumSavedRegs = 7;
|
||||||
static const RegisterMask SavedRegs = 1<<R4 | 1<<R5 | 1<<R6 | 1<<R7 | 1<<R8 | 1<<R9 | 1<<R10 | SavedFpRegs;
|
#endif
|
||||||
static const RegisterMask FpRegs = 1<<D0 | 1<<D1 | 1<<D2 | 1<<D3 | 1<<D4 | 1<<D5 | 1<<D6; // no D7; S14-S15 are used for i2f/u2f.
|
static const RegisterMask FpRegs = 1<<D0 | 1<<D1 | 1<<D2 | 1<<D3 | 1<<D4 | 1<<D5 | 1<<D6; // no D7; S14-S15 are used for i2f/u2f.
|
||||||
static const RegisterMask GpRegs = 0x07FF;
|
static const RegisterMask GpRegs = 0x07FF;
|
||||||
static const RegisterMask AllowableFlagRegs = 1<<R0 | 1<<R1 | 1<<R2 | 1<<R3 | 1<<R4 | 1<<R5 | 1<<R6 | 1<<R7 | 1<<R8 | 1<<R9 | 1<<R10;
|
static const RegisterMask AllowableFlagRegs = 1<<R0 | 1<<R1 | 1<<R2 | 1<<R3 | 1<<R4 | 1<<R5 | 1<<R6 | 1<<R7 | 1<<R8 | 1<<R9 | 1<<R10;
|
||||||
|
@ -218,8 +227,6 @@ verbose_only( extern const char* regNames[]; )
|
||||||
|
|
||||||
#define IMM32(imm) *(--_nIns) = (NIns)((imm));
|
#define IMM32(imm) *(--_nIns) = (NIns)((imm));
|
||||||
|
|
||||||
#define FUNCADDR(addr) ( ((int)addr) )
|
|
||||||
|
|
||||||
#define OP_IMM (1<<25)
|
#define OP_IMM (1<<25)
|
||||||
#define OP_STAT (1<<20)
|
#define OP_STAT (1<<20)
|
||||||
|
|
||||||
|
|
|
@ -60,12 +60,7 @@ namespace nanojit
|
||||||
#endif
|
#endif
|
||||||
const Register Assembler::argRegs[] = { R0, R1, R2, R3 };
|
const Register Assembler::argRegs[] = { R0, R1, R2, R3 };
|
||||||
const Register Assembler::retRegs[] = { R0, R1 };
|
const Register Assembler::retRegs[] = { R0, R1 };
|
||||||
|
|
||||||
#ifdef NJ_THUMB_JIT
|
|
||||||
const Register Assembler::savedRegs[] = { R4, R5, R6, R7 };
|
const Register Assembler::savedRegs[] = { R4, R5, R6, R7 };
|
||||||
#else
|
|
||||||
const Register Assembler::savedRegs[] = { R4, R5, R6, R7, R8, R9, R10 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Assembler::nInit(AvmCore*)
|
void Assembler::nInit(AvmCore*)
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,27 +64,22 @@ namespace nanojit
|
||||||
/* ARM registers */
|
/* ARM registers */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
R0 = 0,
|
R0 = 0, // 32bit return value, aka A1
|
||||||
R1 = 1,
|
R1 = 1, // msw of 64bit return value, A2
|
||||||
R2 = 2,
|
R2 = 2, // A3
|
||||||
R3 = 3,
|
R3 = 3, // A4
|
||||||
R4 = 4,
|
R4 = 4, // V1
|
||||||
R5 = 5,
|
R5 = 5, // V2
|
||||||
R6 = 6,
|
R6 = 6, // V3
|
||||||
R7 = 7,
|
R7 = 7, // V4
|
||||||
R8 = 8,
|
R8 = 8, // V5
|
||||||
//R9 = 9,
|
R9 = 9, // V6, SB (stack base)
|
||||||
//R10 = 10,
|
R10 = 10, // V7, SL
|
||||||
//R11 = 11,
|
FP = 11, // V8, frame pointer
|
||||||
IP = 12,
|
IP = 12, // intra-procedure call scratch register
|
||||||
SP = 13,
|
SP = 13, // stack pointer
|
||||||
LR = 14,
|
LR = 14, // link register (BL sets LR = return address)
|
||||||
PC = 15,
|
PC = 15, // program counter
|
||||||
|
|
||||||
FP = SP,
|
|
||||||
|
|
||||||
// helpers
|
|
||||||
FRAME_PTR = R7,
|
|
||||||
|
|
||||||
FirstReg = 0,
|
FirstReg = 0,
|
||||||
LastReg = 5,
|
LastReg = 5,
|
||||||
|
|
|
@ -545,13 +545,7 @@ namespace nanojit
|
||||||
{
|
{
|
||||||
if (value->isconst())
|
if (value->isconst())
|
||||||
{
|
{
|
||||||
Register rb;
|
Register rb = getBaseReg(base, dr, GpRegs);
|
||||||
if (base->isop(LIR_alloc)) {
|
|
||||||
rb = FP;
|
|
||||||
dr += findMemFor(base);
|
|
||||||
} else {
|
|
||||||
rb = findRegFor(base, GpRegs);
|
|
||||||
}
|
|
||||||
int c = value->constval();
|
int c = value->constval();
|
||||||
STi(rb, dr, c);
|
STi(rb, dr, c);
|
||||||
}
|
}
|
||||||
|
@ -616,20 +610,6 @@ namespace nanojit
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::asm_spilli(LInsp i, Reservation *resv, bool pop)
|
|
||||||
{
|
|
||||||
int d = disp(resv);
|
|
||||||
Register rr = resv->reg;
|
|
||||||
bool quad = i->opcode() == LIR_param || i->isQuad();
|
|
||||||
asm_spill(rr, d, pop, quad);
|
|
||||||
if (d)
|
|
||||||
{
|
|
||||||
verbose_only(if (_verbose) {
|
|
||||||
outputf(" spill %s",_thisfrag->lirbuf->names->formatRef(i));
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Assembler::asm_load64(LInsp ins)
|
void Assembler::asm_load64(LInsp ins)
|
||||||
{
|
{
|
||||||
LIns* base = ins->oprnd1();
|
LIns* base = ins->oprnd1();
|
||||||
|
@ -640,13 +620,7 @@ namespace nanojit
|
||||||
if (rr != UnknownReg && rmask(rr) & XmmRegs)
|
if (rr != UnknownReg && rmask(rr) & XmmRegs)
|
||||||
{
|
{
|
||||||
freeRsrcOf(ins, false);
|
freeRsrcOf(ins, false);
|
||||||
Register rb;
|
Register rb = getBaseReg(base, db, GpRegs);
|
||||||
if (base->isop(LIR_alloc)) {
|
|
||||||
rb = FP;
|
|
||||||
db += findMemFor(base);
|
|
||||||
} else {
|
|
||||||
rb = findRegFor(base, GpRegs);
|
|
||||||
}
|
|
||||||
SSE_LDQ(rr, db, rb);
|
SSE_LDQ(rr, db, rb);
|
||||||
}
|
}
|
||||||
#if defined NANOJIT_AMD64
|
#if defined NANOJIT_AMD64
|
||||||
|
|
Загрузка…
Ссылка в новой задаче