mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
fd4721f7f0
commit
387808d7b9
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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) ); \
|
||||
|
@ -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);
|
||||
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user