Bug 527178 - NJ: all our efforts at handling valid displacements are defeated (take 2a). r=graydon,gal.

--HG--
extra : convert_revision : c2be4b89e09d6dd1b8c83b14240d00d57c084419
This commit is contained in:
Nicholas Nethercote 2009-12-18 08:24:39 +11:00
parent fd4721f7f0
commit 387808d7b9
15 changed files with 90 additions and 114 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1227,11 +1227,11 @@ Assembler::asm_store32(LOpcode op, LIns *value, int dr, LIns *base)
findRegFor2(GpRegs, value, ra, base, rb);
}
if (!isS12(dr)) {
if (isU12(-dr) || isU12(dr)) {
STR(ra, rb, dr);
} else {
STR(ra, IP, 0);
asm_add_imm(IP, rb, dr);
} else {
STR(ra, rb, dr);
}
}
@ -1912,7 +1912,7 @@ Assembler::asm_ld_imm(Register d, int32_t imm, bool chk /* = true */)
++_nSlot;
offset += sizeof(_nSlot);
}
NanoAssert(isS12(offset) && (offset <= -8));
NanoAssert((isU12(-offset) || isU12(offset)) && (offset <= -8));
// Write the literal.
*(_nSlot++) = imm;
@ -2486,22 +2486,39 @@ 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);
if (isU12(-d) || isU12(d)) {
LDRB(rr, ra, d);
} else {
LDRB(rr, IP, 0);
asm_add_imm(IP, ra, d);
}
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-byte aligned. (Not all ARM machines
// can handle unaligned accesses.)
// Similar to the ldcb/ldzb case, but the max offset is smaller.
if (isU8(-d) || isU8(d)) {
LDRH(rr, ra, d);
} else {
LDRH(rr, IP, 0);
asm_add_imm(IP, ra, d);
}
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 (isU12(-d) || isU12(d)) {
LDR(rr, ra, d);
} else {
LDR(rr, IP, 0);
asm_add_imm(IP, ra, d);
}
return;
case LIR_ldsb:
case LIR_ldss:

View File

@ -182,15 +182,8 @@ static const RegisterMask FpRegs = 1<<D0 | 1<<D1 | 1<<D2 | 1<<D3 | 1<<D4 | 1<<D5
static const RegisterMask GpRegs = 0xFFFF;
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;
#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)
@ -664,7 +657,7 @@ enum {
#define STR(_d,_n,_off) do { \
NanoAssert(IsGpReg(_d) && IsGpReg(_n)); \
NanoAssert(isS12(_off)); \
NanoAssert(isU12(_off) || isU12(-_off)); \
underrunProtect(4); \
if ((_off)<0) *(--_nIns) = (NIns)( COND_AL | (0x50<<20) | ((_n)<<16) | ((_d)<<12) | ((-(_off))&0xFFF) ); \
else *(--_nIns) = (NIns)( COND_AL | (0x58<<20) | ((_n)<<16) | ((_d)<<12) | ((_off)&0xFFF) ); \

View File

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

View File

@ -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;
}

View File

@ -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);
@ -769,7 +769,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:

View File

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

View File

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

View File

@ -330,9 +330,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;
}

View File

@ -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:
@ -1254,7 +1254,7 @@ namespace nanojit
}
}
Register ra = getBaseReg(op, base, d, GpRegs);
Register ra = getBaseReg(base, d, GpRegs);
switch(op) {
case LIR_ldzb:
case LIR_ldcb:

View File

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