зеркало из https://github.com/mozilla/pjs.git
Bug 527178 - NJ: all our efforts at handling valid displacements are defeated (take 2). r=graydon,gal.
--HG-- extra : convert_revision : 2bd8a736808d4a2582233d05832f11899ccc2fd7
This commit is contained in:
Родитель
c0406d1d88
Коммит
f4b66179a4
|
@ -335,20 +335,12 @@ namespace nanojit
|
|||
return findRegFor(i, rmask(w));
|
||||
}
|
||||
|
||||
// The 'op' argument is the opcode of the instruction containing the
|
||||
// displaced i[d] operand we're finding a register for. It is only used
|
||||
// for differentiating classes of valid displacement in the native
|
||||
// backends; a bit of a hack.
|
||||
Register Assembler::getBaseReg(LOpcode op, LIns *i, int &d, RegisterMask allow)
|
||||
Register Assembler::getBaseReg(LIns *i, int &d, RegisterMask allow)
|
||||
{
|
||||
#if !PEDANTIC
|
||||
if (i->isop(LIR_alloc)) {
|
||||
int d2 = d;
|
||||
d2 += findMemFor(i);
|
||||
if (isValidDisplacement(op, d2)) {
|
||||
d = d2;
|
||||
return FP;
|
||||
}
|
||||
d += findMemFor(i);
|
||||
return FP;
|
||||
}
|
||||
#else
|
||||
(void) d;
|
||||
|
|
|
@ -272,7 +272,7 @@ namespace nanojit
|
|||
void assignSaved(RegAlloc &saved, RegisterMask skip);
|
||||
LInsp findVictim(RegisterMask allow);
|
||||
|
||||
Register getBaseReg(LOpcode op, LIns *i, int &d, RegisterMask allow);
|
||||
Register getBaseReg(LIns *i, int &d, RegisterMask allow);
|
||||
int findMemFor(LIns* i);
|
||||
Register findRegFor(LIns* i, RegisterMask allow);
|
||||
void findRegFor2(RegisterMask allow, LIns* ia, Register &ra, LIns *ib, Register &rb);
|
||||
|
|
|
@ -227,7 +227,6 @@ namespace nanojit
|
|||
|
||||
LInsp LirBufWriter::insStore(LOpcode op, LInsp val, LInsp base, int32_t d)
|
||||
{
|
||||
base = insDisp(op, base, d);
|
||||
LInsSti* insSti = (LInsSti*)_buf->makeRoom(sizeof(LInsSti));
|
||||
LIns* ins = insSti->getLIns();
|
||||
ins->initLInsSti(op, val, base, d);
|
||||
|
@ -268,7 +267,6 @@ namespace nanojit
|
|||
|
||||
LInsp LirBufWriter::insLoad(LOpcode op, LInsp base, int32_t d)
|
||||
{
|
||||
base = insDisp(op, base, d);
|
||||
LInsLd* insLd = (LInsLd*)_buf->makeRoom(sizeof(LInsLd));
|
||||
LIns* ins = insLd->getLIns();
|
||||
ins->initLInsLd(op, base, d);
|
||||
|
|
|
@ -51,6 +51,51 @@
|
|||
*/
|
||||
namespace nanojit
|
||||
{
|
||||
enum LOpcode
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
#pragma warning(disable:4480) // nonstandard extension used: specifying underlying type for enum
|
||||
: unsigned
|
||||
#endif
|
||||
{
|
||||
#define OPDEF(op, number, repKind, retType) \
|
||||
LIR_##op = (number),
|
||||
#include "LIRopcode.tbl"
|
||||
LIR_sentinel,
|
||||
#undef OPDEF
|
||||
|
||||
#ifdef NANOJIT_64BIT
|
||||
# define PTR_SIZE(a,b) b
|
||||
#else
|
||||
# define PTR_SIZE(a,b) a
|
||||
#endif
|
||||
|
||||
// pointer op aliases
|
||||
LIR_ldp = PTR_SIZE(LIR_ld, LIR_ldq),
|
||||
LIR_ldcp = PTR_SIZE(LIR_ldc, LIR_ldqc),
|
||||
LIR_stpi = PTR_SIZE(LIR_sti, LIR_stqi),
|
||||
LIR_piadd = PTR_SIZE(LIR_add, LIR_qiadd),
|
||||
LIR_piand = PTR_SIZE(LIR_and, LIR_qiand),
|
||||
LIR_pilsh = PTR_SIZE(LIR_lsh, LIR_qilsh),
|
||||
LIR_pirsh = PTR_SIZE(LIR_rsh, LIR_qirsh),
|
||||
LIR_pursh = PTR_SIZE(LIR_ush, LIR_qursh),
|
||||
LIR_pcmov = PTR_SIZE(LIR_cmov, LIR_qcmov),
|
||||
LIR_pior = PTR_SIZE(LIR_or, LIR_qior),
|
||||
LIR_pxor = PTR_SIZE(LIR_xor, LIR_qxor),
|
||||
LIR_addp = PTR_SIZE(LIR_iaddp, LIR_qaddp),
|
||||
LIR_peq = PTR_SIZE(LIR_eq, LIR_qeq),
|
||||
LIR_plt = PTR_SIZE(LIR_lt, LIR_qlt),
|
||||
LIR_pgt = PTR_SIZE(LIR_gt, LIR_qgt),
|
||||
LIR_ple = PTR_SIZE(LIR_le, LIR_qle),
|
||||
LIR_pge = PTR_SIZE(LIR_ge, LIR_qge),
|
||||
LIR_pult = PTR_SIZE(LIR_ult, LIR_qult),
|
||||
LIR_pugt = PTR_SIZE(LIR_ugt, LIR_qugt),
|
||||
LIR_pule = PTR_SIZE(LIR_ule, LIR_qule),
|
||||
LIR_puge = PTR_SIZE(LIR_uge, LIR_quge),
|
||||
LIR_alloc = PTR_SIZE(LIR_ialloc, LIR_qalloc),
|
||||
LIR_pcall = PTR_SIZE(LIR_icall, LIR_qcall),
|
||||
LIR_param = PTR_SIZE(LIR_iparam, LIR_qparam)
|
||||
};
|
||||
|
||||
struct GuardRecord;
|
||||
struct SideExit;
|
||||
|
||||
|
@ -955,14 +1000,6 @@ namespace nanojit
|
|||
|
||||
class LirWriter
|
||||
{
|
||||
protected:
|
||||
LInsp insDisp(LOpcode op, LInsp base, int32_t& d) {
|
||||
if (!isValidDisplacement(op, d)) {
|
||||
base = ins2i(LIR_piadd, base, d);
|
||||
d = 0;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
public:
|
||||
LirWriter *out;
|
||||
|
||||
|
|
|
@ -54,53 +54,6 @@
|
|||
# define IF_PEDANTIC(...)
|
||||
#endif
|
||||
|
||||
namespace nanojit {
|
||||
enum LOpcode
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
#pragma warning(disable:4480) // nonstandard extension used: specifying underlying type for enum
|
||||
: unsigned
|
||||
#endif
|
||||
{
|
||||
#define OPDEF(op, number, repKind, retType) \
|
||||
LIR_##op = (number),
|
||||
#include "LIRopcode.tbl"
|
||||
LIR_sentinel,
|
||||
#undef OPDEF
|
||||
|
||||
#ifdef NANOJIT_64BIT
|
||||
# define PTR_SIZE(a,b) b
|
||||
#else
|
||||
# define PTR_SIZE(a,b) a
|
||||
#endif
|
||||
|
||||
// pointer op aliases
|
||||
LIR_ldp = PTR_SIZE(LIR_ld, LIR_ldq),
|
||||
LIR_ldcp = PTR_SIZE(LIR_ldc, LIR_ldqc),
|
||||
LIR_stpi = PTR_SIZE(LIR_sti, LIR_stqi),
|
||||
LIR_piadd = PTR_SIZE(LIR_add, LIR_qiadd),
|
||||
LIR_piand = PTR_SIZE(LIR_and, LIR_qiand),
|
||||
LIR_pilsh = PTR_SIZE(LIR_lsh, LIR_qilsh),
|
||||
LIR_pirsh = PTR_SIZE(LIR_rsh, LIR_qirsh),
|
||||
LIR_pursh = PTR_SIZE(LIR_ush, LIR_qursh),
|
||||
LIR_pcmov = PTR_SIZE(LIR_cmov, LIR_qcmov),
|
||||
LIR_pior = PTR_SIZE(LIR_or, LIR_qior),
|
||||
LIR_pxor = PTR_SIZE(LIR_xor, LIR_qxor),
|
||||
LIR_addp = PTR_SIZE(LIR_iaddp, LIR_qaddp),
|
||||
LIR_peq = PTR_SIZE(LIR_eq, LIR_qeq),
|
||||
LIR_plt = PTR_SIZE(LIR_lt, LIR_qlt),
|
||||
LIR_pgt = PTR_SIZE(LIR_gt, LIR_qgt),
|
||||
LIR_ple = PTR_SIZE(LIR_le, LIR_qle),
|
||||
LIR_pge = PTR_SIZE(LIR_ge, LIR_qge),
|
||||
LIR_pult = PTR_SIZE(LIR_ult, LIR_qult),
|
||||
LIR_pugt = PTR_SIZE(LIR_ugt, LIR_qugt),
|
||||
LIR_pule = PTR_SIZE(LIR_ule, LIR_qule),
|
||||
LIR_puge = PTR_SIZE(LIR_uge, LIR_quge),
|
||||
LIR_alloc = PTR_SIZE(LIR_ialloc, LIR_qalloc),
|
||||
LIR_pcall = PTR_SIZE(LIR_icall, LIR_qcall),
|
||||
LIR_param = PTR_SIZE(LIR_iparam, LIR_qparam)
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef NANOJIT_IA32
|
||||
#include "Nativei386.h"
|
||||
#elif defined(NANOJIT_ARM)
|
||||
|
|
|
@ -2199,7 +2199,7 @@ Assembler::asm_cmp(LIns *cond)
|
|||
TST(r,r);
|
||||
// No 64-bit immediates so fall-back to below
|
||||
} else if (!rhs->isQuad()) {
|
||||
Register r = getBaseReg(condop, lhs, c, GpRegs);
|
||||
Register r = getBaseReg(lhs, c, GpRegs);
|
||||
asm_cmpi(r, c);
|
||||
} else {
|
||||
NanoAssert(0);
|
||||
|
@ -2490,22 +2490,54 @@ Assembler::asm_load32(LInsp ins)
|
|||
int d = ins->disp();
|
||||
|
||||
Register rr = prepResultReg(ins, GpRegs);
|
||||
Register ra = getBaseReg(op, base, d, GpRegs);
|
||||
Register ra = getBaseReg(base, d, GpRegs);
|
||||
|
||||
switch(op) {
|
||||
switch (op) {
|
||||
case LIR_ldzb:
|
||||
case LIR_ldcb:
|
||||
LDRB(rr, ra, d);
|
||||
// These are expected to be 2 or 4-byte aligned.
|
||||
if (isS12(d)) {
|
||||
LDRB(rr, ra, d);
|
||||
} else {
|
||||
// If the offset doesn't fit in 12-bits we can't use it, so we
|
||||
// recompute 'base' with a smaller (zero) offset. If
|
||||
// getBaseReg() returned FP, we can't use it, and so we must
|
||||
// find a GpReg for 'base'. Otherwise getBaseReg() must have
|
||||
// returned a GpReg.
|
||||
if (ra == FP)
|
||||
ra = findRegFor(base, GpRegs);
|
||||
NanoAssert(IsGpReg(ra));
|
||||
LDRB(rr, IP, 0);
|
||||
// Nb: getBaseReg() may have modified 'd', so we must use
|
||||
// ins->disp() here instead of 'd'.
|
||||
asm_add_imm(IP, ra, ins->disp());
|
||||
}
|
||||
return;
|
||||
case LIR_ldzs:
|
||||
case LIR_ldcs:
|
||||
// these are expected to be 2 or 4-byte aligned
|
||||
LDRH(rr, ra, d);
|
||||
// These are expected to be 2 or 4-byte aligned.
|
||||
if (isS12(d)) {
|
||||
LDRH(rr, ra, d);
|
||||
} else {
|
||||
if (ra == FP)
|
||||
ra = findRegFor(base, GpRegs);
|
||||
NanoAssert(IsGpReg(ra));
|
||||
LDRH(rr, IP, 0);
|
||||
asm_add_imm(IP, ra, ins->disp());
|
||||
}
|
||||
return;
|
||||
case LIR_ld:
|
||||
case LIR_ldc:
|
||||
// these are expected to be 4-byte aligned
|
||||
LDR(rr, ra, d);
|
||||
// These are expected to be 4-byte aligned.
|
||||
if (isS12(d)) {
|
||||
LDR(rr, ra, d);
|
||||
} else {
|
||||
if (ra == FP)
|
||||
ra = findRegFor(base, GpRegs);
|
||||
NanoAssert(IsGpReg(ra));
|
||||
LDR(rr, IP, 0);
|
||||
asm_add_imm(IP, ra, ins->disp());
|
||||
}
|
||||
return;
|
||||
case LIR_ldsb:
|
||||
case LIR_ldss:
|
||||
|
|
|
@ -185,12 +185,6 @@ static const RegisterMask AllowableFlagRegs = 1<<R0 | 1<<R1 | 1<<R2 | 1<<R3 | 1<
|
|||
#define isS12(offs) ((-(1<<12)) <= (offs) && (offs) < (1<<12))
|
||||
#define isU12(offs) (((offs) & 0xfff) == (offs))
|
||||
|
||||
static inline bool isValidDisplacement(LOpcode op, int32_t d) {
|
||||
if (op == LIR_ldcs)
|
||||
return (d >= 0) ? isU8(d) : isU8(-d);
|
||||
return isS12(d);
|
||||
}
|
||||
|
||||
#define IsFpReg(_r) ((rmask((Register)_r) & (FpRegs)) != 0)
|
||||
#define IsGpReg(_r) ((rmask((Register)_r) & (GpRegs)) != 0)
|
||||
#define FpRegNum(_fpr) ((_fpr) - FirstFloatReg)
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace nanojit
|
|||
LIns* base = ins->oprnd1();
|
||||
int d = ins->disp();
|
||||
Register rr = prepResultReg(ins, GpRegs);
|
||||
Register ra = getBaseReg(ins->opcode(), base, d, GpRegs);
|
||||
Register ra = getBaseReg(base, d, GpRegs);
|
||||
|
||||
switch(ins->opcode()) {
|
||||
case LIR_ldzb:
|
||||
|
@ -204,7 +204,7 @@ namespace nanojit
|
|||
}
|
||||
|
||||
Register rs = findRegFor(value, GpRegs);
|
||||
Register ra = value == base ? rs : getBaseReg(LIR_sti, base, dr, GpRegs & ~rmask(rs));
|
||||
Register ra = value == base ? rs : getBaseReg(base, dr, GpRegs & ~rmask(rs));
|
||||
|
||||
#if !PEDANTIC
|
||||
if (isS16(dr)) {
|
||||
|
@ -250,7 +250,7 @@ namespace nanojit
|
|||
#endif
|
||||
|
||||
int dr = ins->disp();
|
||||
Register ra = getBaseReg(ins->opcode(), base, dr, GpRegs);
|
||||
Register ra = getBaseReg(base, dr, GpRegs);
|
||||
|
||||
#ifdef NANOJIT_64BIT
|
||||
if (rmask(rr) & GpRegs) {
|
||||
|
@ -325,7 +325,7 @@ namespace nanojit
|
|||
return;
|
||||
}
|
||||
|
||||
Register ra = getBaseReg(LIR_stqi, base, dr, GpRegs);
|
||||
Register ra = getBaseReg(base, dr, GpRegs);
|
||||
|
||||
#if !PEDANTIC && !defined NANOJIT_64BIT
|
||||
if (value->isop(LIR_quad) && isS16(dr) && isS16(dr+4)) {
|
||||
|
|
|
@ -258,9 +258,6 @@ namespace nanojit
|
|||
static const int NumSavedRegs = 18; // R13-R30
|
||||
#endif
|
||||
|
||||
static inline bool isValidDisplacement(LOpcode, int32_t) {
|
||||
return true;
|
||||
}
|
||||
static inline bool IsFpReg(Register r) {
|
||||
return r >= F0;
|
||||
}
|
||||
|
|
|
@ -325,7 +325,7 @@ namespace nanojit
|
|||
underrunProtect(20);
|
||||
if (value->isconst())
|
||||
{
|
||||
Register rb = getBaseReg(LIR_sti, base, dr, GpRegs);
|
||||
Register rb = getBaseReg(base, dr, GpRegs);
|
||||
int c = value->imm32();
|
||||
STW32(L2, dr, rb);
|
||||
SET32(c, L2);
|
||||
|
@ -589,7 +589,7 @@ namespace nanojit
|
|||
ANDCC(r, r, G0);
|
||||
}
|
||||
else if (!rhs->isQuad()) {
|
||||
Register r = getBaseReg(condop, lhs, c, GpRegs);
|
||||
Register r = getBaseReg(lhs, c, GpRegs);
|
||||
SUBCC(r, L2, G0);
|
||||
SET32(c, L2);
|
||||
}
|
||||
|
@ -770,7 +770,7 @@ namespace nanojit
|
|||
LIns* base = ins->oprnd1();
|
||||
int d = ins->disp();
|
||||
Register rr = prepResultReg(ins, GpRegs);
|
||||
Register ra = getBaseReg(ins->opcode(), base, d, GpRegs);
|
||||
Register ra = getBaseReg(base, d, GpRegs);
|
||||
switch(op) {
|
||||
case LIR_ldzb:
|
||||
case LIR_ldcb:
|
||||
|
|
|
@ -191,10 +191,6 @@ namespace nanojit
|
|||
1<<F22;
|
||||
static const RegisterMask AllowableFlagRegs = GpRegs;
|
||||
|
||||
static inline bool isValidDisplacement(LOpcode, int32_t) {
|
||||
return true;
|
||||
}
|
||||
|
||||
verbose_only( extern const char* regNames[]; )
|
||||
|
||||
#define DECLARE_PLATFORM_STATS()
|
||||
|
|
|
@ -1368,7 +1368,7 @@ namespace nanojit
|
|||
void Assembler::regalloc_load(LIns *ins, RegisterMask allow, Register &rr, int32_t &dr, Register &rb) {
|
||||
dr = ins->disp();
|
||||
LIns *base = ins->oprnd1();
|
||||
rb = getBaseReg(ins->opcode(), base, dr, BaseRegs);
|
||||
rb = getBaseReg(base, dr, BaseRegs);
|
||||
if (ins->isUnusedOrHasUnknownReg() || !(allow & rmask(ins->getReg()))) {
|
||||
rr = prepResultReg(ins, allow & ~rmask(rb));
|
||||
} else {
|
||||
|
@ -1446,7 +1446,7 @@ namespace nanojit
|
|||
void Assembler::asm_store64(LOpcode op, LIns *value, int d, LIns *base) {
|
||||
NanoAssert(value->isQuad());
|
||||
|
||||
Register b = getBaseReg(LIR_stqi, base, d, BaseRegs);
|
||||
Register b = getBaseReg(base, d, BaseRegs);
|
||||
Register r;
|
||||
|
||||
// if we have to choose a register, use a GPR, but not the base reg
|
||||
|
@ -1516,7 +1516,7 @@ namespace nanojit
|
|||
GpRegs;
|
||||
|
||||
NanoAssert(!value->isQuad());
|
||||
Register b = getBaseReg(LIR_sti, base, d, BaseRegs);
|
||||
Register b = getBaseReg(base, d, BaseRegs);
|
||||
Register r = findRegFor(value, SrcRegs & ~rmask(b));
|
||||
|
||||
switch (op) {
|
||||
|
|
|
@ -329,9 +329,6 @@ namespace nanojit
|
|||
static const int NumArgRegs = 6;
|
||||
#endif
|
||||
|
||||
static inline bool isValidDisplacement(LOpcode, int32_t) {
|
||||
return true;
|
||||
}
|
||||
static inline bool IsFpReg(Register r) {
|
||||
return ((1<<r) & FpRegs) != 0;
|
||||
}
|
||||
|
|
|
@ -476,7 +476,7 @@ namespace nanojit
|
|||
{
|
||||
if (value->isconst())
|
||||
{
|
||||
Register rb = getBaseReg(LIR_sti, base, dr, GpRegs);
|
||||
Register rb = getBaseReg(base, dr, GpRegs);
|
||||
int c = value->imm32();
|
||||
switch(op) {
|
||||
case LIR_stb:
|
||||
|
@ -566,7 +566,7 @@ namespace nanojit
|
|||
if (isKnownReg(rr) && rmask(rr) & XmmRegs)
|
||||
{
|
||||
freeRsrcOf(ins, false);
|
||||
Register rb = getBaseReg(ins->opcode(), base, db, GpRegs);
|
||||
Register rb = getBaseReg(base, db, GpRegs);
|
||||
switch (ins->opcode()) {
|
||||
case LIR_ldq:
|
||||
case LIR_ldqc:
|
||||
|
@ -899,7 +899,7 @@ namespace nanojit
|
|||
Register r = findRegFor(lhs, GpRegs);
|
||||
TEST(r,r);
|
||||
} else if (!rhs->isQuad()) {
|
||||
Register r = getBaseReg(condop, lhs, c, GpRegs);
|
||||
Register r = getBaseReg(lhs, c, GpRegs);
|
||||
CMPi(r, c);
|
||||
}
|
||||
}
|
||||
|
@ -1255,7 +1255,7 @@ namespace nanojit
|
|||
}
|
||||
}
|
||||
|
||||
Register ra = getBaseReg(op, base, d, GpRegs);
|
||||
Register ra = getBaseReg(base, d, GpRegs);
|
||||
switch(op) {
|
||||
case LIR_ldzb:
|
||||
case LIR_ldcb:
|
||||
|
|
|
@ -157,10 +157,6 @@ namespace nanojit
|
|||
|
||||
static const RegisterMask AllowableFlagRegs = 1<<EAX |1<<ECX | 1<<EDX | 1<<EBX;
|
||||
|
||||
static inline bool isValidDisplacement(LOpcode, int32_t) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#define _rmask_(r) (1<<(r))
|
||||
#define _is_xmm_reg_(r) ((_rmask_(r)&XmmRegs)!=0)
|
||||
#define _is_x87_reg_(r) ((_rmask_(r)&x87Regs)!=0)
|
||||
|
|
Загрузка…
Ссылка в новой задаче