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:
Nicholas Nethercote 2009-12-15 12:54:26 +11:00
Родитель c0406d1d88
Коммит f4b66179a4
15 изменённых файлов: 103 добавлений и 111 удалений

Просмотреть файл

@ -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)