mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 14:25:52 +00:00
b=484561; [arm] fix broken LIR_alloc; r=graydon
This commit is contained in:
parent
4dbeb963a1
commit
d19089acad
@ -422,7 +422,7 @@ void
|
||||
Assembler::asm_qjoin(LIns *ins)
|
||||
{
|
||||
int d = findMemFor(ins);
|
||||
AvmAssert(d);
|
||||
NanoAssert(d);
|
||||
LIns* lo = ins->oprnd1();
|
||||
LIns* hi = ins->oprnd2();
|
||||
|
||||
@ -438,11 +438,17 @@ Assembler::asm_qjoin(LIns *ins)
|
||||
void
|
||||
Assembler::asm_store32(LIns *value, int dr, LIns *base)
|
||||
{
|
||||
// make sure what is in a register
|
||||
Reservation *rA, *rB;
|
||||
findRegFor2(GpRegs, value, rA, base, rB);
|
||||
Register ra = rA->reg;
|
||||
Register rb = rB->reg;
|
||||
Register ra, rb;
|
||||
if (base->isop(LIR_alloc)) {
|
||||
rb = FP;
|
||||
dr += findMemFor(base);
|
||||
ra = findRegFor(value, GpRegs);
|
||||
} else {
|
||||
findRegFor2(GpRegs, value, rA, base, rB);
|
||||
ra = rA->reg;
|
||||
rb = rB->reg;
|
||||
}
|
||||
STR(ra, rb, dr);
|
||||
}
|
||||
|
||||
@ -451,9 +457,22 @@ Assembler::asm_restore(LInsp i, Reservation *resv, Register r)
|
||||
{
|
||||
if (i->isop(LIR_alloc)) {
|
||||
asm_add_imm(r, FP, disp(resv));
|
||||
} else {
|
||||
}
|
||||
#if 0
|
||||
/* This seriously regresses crypto-aes (by about 50%!), with or
|
||||
* without the S8/U8 check (which ensures that we can do this
|
||||
* const load in one instruction). I have no idea why, because a
|
||||
* microbenchmark of const mov vs. loading from memory shows that
|
||||
* the mov is faster, though not by much.
|
||||
*/
|
||||
else if (i->isconst() && (isS8(i->constval()) || isU8(i->constval()))) {
|
||||
if (!resv->arIndex)
|
||||
reserveFree(i);
|
||||
asm_ld_imm(r, i->constval());
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
int d = findMemFor(i);
|
||||
|
||||
if (IsFpReg(r)) {
|
||||
if (isS8(d >> 2)) {
|
||||
FLDD(r, FP, d);
|
||||
@ -697,34 +716,6 @@ Assembler::asm_mmq(Register rd, int dd, Register rs, int ds)
|
||||
LDR(t, rs, ds);
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::asm_pusharg(LInsp arg)
|
||||
{
|
||||
Reservation* argRes = getresv(arg);
|
||||
bool quad = arg->isQuad();
|
||||
|
||||
if (argRes && argRes->reg != UnknownReg) {
|
||||
if (!quad) {
|
||||
STR_preindex(argRes->reg, SP, -4);
|
||||
} else {
|
||||
FSTD(argRes->reg, SP, 0);
|
||||
SUBi(SP, SP, 8);
|
||||
}
|
||||
} else {
|
||||
int d = findMemFor(arg);
|
||||
|
||||
if (!quad) {
|
||||
STR_preindex(IP, SP, -4);
|
||||
LDR(IP, FP, d);
|
||||
} else {
|
||||
STR_preindex(IP, SP, -4);
|
||||
LDR(IP, FP, d+4);
|
||||
STR_preindex(IP, SP, -4);
|
||||
LDR(IP, FP, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::nativePageReset()
|
||||
{
|
||||
@ -983,7 +974,9 @@ Assembler::asm_add_imm(Register rd, Register rn, int32_t imm, int stat)
|
||||
pos = false;
|
||||
}
|
||||
|
||||
while (immval && ((immval & 0x3) == 0)) {
|
||||
while (immval > 255 &&
|
||||
immval && ((immval & 0x3) == 0))
|
||||
{
|
||||
immval >>= 2;
|
||||
rot--;
|
||||
}
|
||||
@ -1383,10 +1376,10 @@ Assembler::asm_arith(LInsp ins)
|
||||
}
|
||||
allow &= ~rmask(rb);
|
||||
} else if ((op == LIR_add||op == LIR_addp) && lhs->isop(LIR_alloc) && rhs->isconst()) {
|
||||
// add alloc+const, use lea
|
||||
// add alloc+const, rr wants the address of the allocated space plus a constant
|
||||
Register rr = prepResultReg(ins, allow);
|
||||
int d = findMemFor(lhs) + rhs->constval();
|
||||
LEA(rr, d, FP);
|
||||
asm_add_imm(rr, FP, d);
|
||||
}
|
||||
|
||||
Register rr = prepResultReg(ins, allow);
|
||||
@ -1620,49 +1613,67 @@ Assembler::asm_int(LInsp ins)
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::asm_arg(ArgSize sz, LInsp p, Register r)
|
||||
Assembler::asm_pusharg(LInsp arg)
|
||||
{
|
||||
if (sz == ARGSIZE_Q) {
|
||||
// ref arg - use lea
|
||||
if (r != UnknownReg) {
|
||||
// arg in specific reg
|
||||
int da = findMemFor(p);
|
||||
LEA(r, da, FP);
|
||||
Reservation* argRes = getresv(arg);
|
||||
bool quad = arg->isQuad();
|
||||
|
||||
if (argRes && argRes->reg != UnknownReg) {
|
||||
if (!quad) {
|
||||
STR_preindex(argRes->reg, SP, -4);
|
||||
} 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)) {
|
||||
asm_add_imm(r, FP, d);
|
||||
} else {
|
||||
LD(r, d, FP);
|
||||
}
|
||||
} else {
|
||||
// it must be in a saved reg
|
||||
MOV(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);
|
||||
FSTD(argRes->reg, SP, 0);
|
||||
SUBi(SP, SP, 8);
|
||||
}
|
||||
} else {
|
||||
NanoAssert(sz == ARGSIZE_F);
|
||||
asm_farg(p);
|
||||
int d = findMemFor(arg);
|
||||
|
||||
if (!quad) {
|
||||
STR_preindex(IP, SP, -4);
|
||||
LDR(IP, FP, d);
|
||||
} else {
|
||||
STR_preindex(IP, SP, -4);
|
||||
LDR(IP, FP, d+4);
|
||||
STR_preindex(IP, SP, -4);
|
||||
LDR(IP, FP, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::asm_arg(ArgSize sz, LInsp p, Register r)
|
||||
{
|
||||
// this only handles ARGSIZE_LO; we don't support ARGSIZE_Q,
|
||||
// and ARGSIZE_F is handled by asm_arm_farg
|
||||
NanoAssert(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)) {
|
||||
asm_add_imm(r, FP, d);
|
||||
} else {
|
||||
LDR(r, FP, d);
|
||||
}
|
||||
} else {
|
||||
// it must be in a saved reg
|
||||
MOV(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,8 +197,6 @@ verbose_only( extern const char* shiftNames[]; )
|
||||
int* _nExitSlot;
|
||||
|
||||
|
||||
#define asm_farg(i) NanoAssert(false)
|
||||
|
||||
//printf("jmp_l_n count=%d, nins=%X, %X = %X\n", (_c), nins, _nIns, ((intptr_t)(nins+(_c))-(intptr_t)_nIns - 4) );
|
||||
|
||||
#define swapptrs() { \
|
||||
@ -535,27 +533,6 @@ enum {
|
||||
asm_output("str %s, [%s], %d", gpn(_d), gpn(_n), (_off)); \
|
||||
} while(0)
|
||||
|
||||
// There isn't really a LEA on ARM; this basically computes _r = _b + #_d, either as a
|
||||
// ADD _r, _b, #_d (if _d < 256)
|
||||
// or as a if (_d <= 1020)
|
||||
// MOV _r, #(_d>>2)
|
||||
// ADD _r, _b, _r << 2
|
||||
#define LEA(_r,_d,_b) do { \
|
||||
NanoAssert((_d)<=1020); \
|
||||
NanoAssert(((_d)&3)==0); \
|
||||
NanoAssert((_b) == FP); \
|
||||
if ((_d)<256) { \
|
||||
underrunProtect(4); \
|
||||
*(--_nIns) = (NIns)( COND_AL | (0x28<<20) | ((_b)<<16) | ((_r)<<12) | ((_d)&0xFF) ); \
|
||||
} else { \
|
||||
underrunProtect(8); \
|
||||
*(--_nIns) = (NIns)( COND_AL | (0x4<<21) | ((_b)<<16) | ((_r)<<12) | (2<<7)| (_r) ); \
|
||||
*(--_nIns) = (NIns)( COND_AL | (0x3B<<20) | ((_r)<<12) | (((_d)>>2)&0xFF) ); \
|
||||
} \
|
||||
asm_output("lea %s, %d(SP)", gpn(_r), _d); \
|
||||
} while(0)
|
||||
|
||||
|
||||
//#define RET() underrunProtect(1); *(--_nIns) = 0xc3; asm_output("ret")
|
||||
//#define NOP() underrunProtect(1); *(--_nIns) = 0x90; asm_output("nop")
|
||||
//#define INT3() underrunProtect(1); *(--_nIns) = 0xcc; asm_output("int3")
|
||||
|
Loading…
Reference in New Issue
Block a user