Bug 522314 - Make x86 virtual stack pointer code optional, g=gal.

--HG--
extra : rebase_source : c0feec3b6f94580fab0e8569a817bf36db7ed1ab
This commit is contained in:
Graydon Hoare 2009-10-23 13:46:09 -07:00
Родитель 06f788fd82
Коммит 5ae535ee36
4 изменённых файлов: 82 добавлений и 13 удалений

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

@ -7475,6 +7475,7 @@ js_InitJIT(JSTraceMonitor *tm)
#if defined NANOJIT_IA32
avmplus::AvmCore::config.use_cmov =
avmplus::AvmCore::config.sse2 = CheckForSSE2();
avmplus::AvmCore::config.fixed_esp = true;
#endif
#if defined NANOJIT_ARM

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

@ -184,14 +184,38 @@ namespace nanojit
max_regs = iargs;
int32_t istack = iargs-max_regs; // first 2 4B args are in registers
int32_t pushsize = 4*istack + 8*fargs; // actual stack space used
int32_t extra = 0;
const int32_t pushsize = 4*istack + 8*fargs; // actual stack space used
// In case of fastcall, stdcall and thiscall the callee cleans up the stack,
// and since we reserve max_stk_args words in the prolog to call functions
// and don't adjust the stack pointer individually for each call we have
// to undo here any changes the callee just did to the stack.
if (pushsize && abi != ABI_CDECL)
SUBi(SP, pushsize);
#if _MSC_VER
// msc only provides 4-byte alignment, anything more than 4 on windows
// x86-32 requires dynamic ESP alignment in prolog/epilog and static
// esp-alignment here.
uint32_t align = 4;//NJ_ALIGN_STACK;
#else
uint32_t align = NJ_ALIGN_STACK;
#endif
if (pushsize) {
if (config.fixed_esp) {
// In case of fastcall, stdcall and thiscall the callee cleans up the stack,
// and since we reserve max_stk_args words in the prolog to call functions
// and don't adjust the stack pointer individually for each call we have
// to undo here any changes the callee just did to the stack.
if (abi != ABI_CDECL)
SUBi(SP, pushsize);
} else {
// stack re-alignment
// only pop our adjustment amount since callee pops args in FASTCALL mode
extra = alignUp(pushsize, align) - pushsize;
if (call->_abi == ABI_CDECL) {
// with CDECL only, caller pops args
ADDi(SP, extra+pushsize);
} else if (extra > 0) {
ADDi(SP, extra);
}
}
}
NanoAssert(ins->isop(LIR_pcall) || ins->isop(LIR_fcall));
if (!indirect) {
@ -215,10 +239,12 @@ namespace nanojit
ArgSize sizes[MAXARGS];
uint32_t argc = call->get_sizes(sizes);
int32_t stkd = 0;
if (indirect) {
argc--;
asm_arg(ARGSIZE_P, ins->arg(argc), EAX, stkd);
if (!config.fixed_esp)
stkd = 0;
}
for(uint32_t i=0; i < argc; i++)
@ -230,10 +256,16 @@ namespace nanojit
r = argRegs[n++]; // tell asm_arg what reg to use
}
asm_arg(sz, ins->arg(j), r, stkd);
if (!config.fixed_esp)
stkd = 0;
}
if (pushsize > max_stk_args)
max_stk_args = pushsize;
if (config.fixed_esp) {
if (pushsize > max_stk_args)
max_stk_args = pushsize;
} else if (extra > 0) {
SUBi(SP, extra);
}
}
Register Assembler::nRegisterAllocFromSet(RegisterMask set)
@ -1320,7 +1352,10 @@ namespace nanojit
}
}
else {
asm_stkarg(p, stkd);
if (config.fixed_esp)
asm_stkarg(p, stkd);
else
asm_pusharg(p);
}
}
else
@ -1330,6 +1365,29 @@ namespace nanojit
}
}
void Assembler::asm_pusharg(LInsp p)
{
// arg goes on stack
if (!p->isUsed() && p->isconst())
{
// small const we push directly
PUSHi(p->imm32());
}
else if (!p->isUsed() || p->isop(LIR_alloc))
{
Register ra = findRegFor(p, GpRegs);
PUSHr(ra);
}
else if (!p->hasKnownReg())
{
PUSHm(disp(p), FP);
}
else
{
PUSHr(p->getReg());
}
}
void Assembler::asm_stkarg(LInsp p, int32_t& stkd)
{
// arg goes on stack
@ -1364,6 +1422,8 @@ namespace nanojit
*/
evictIfActive(FST0);
}
if (!config.fixed_esp)
SUBi(ESP,8);
stkd += sizeof(double);
}

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

@ -174,7 +174,7 @@ namespace nanojit
#define DECLARE_PLATFORM_REGALLOC()
#define DECLARE_PLATFORM_ASSEMBLER() \
const static Register argRegs[2], retRegs[2];\
const static Register argRegs[2], retRegs[2]; \
int32_t max_stk_args;\
void nativePageReset();\
void nativePageSetup();\
@ -182,8 +182,9 @@ namespace nanojit
void asm_stkarg(LInsp p, int32_t& stkd);\
void asm_farg(LInsp, int32_t& stkd);\
void asm_arg(ArgSize sz, LInsp p, Register r, int32_t& stkd);\
void asm_pusharg(LInsp);\
void asm_fcmp(LIns *cond);\
void asm_cmp(LIns *cond);\
void asm_cmp(LIns *cond); \
void asm_div_mod(LIns *cond);
#define swapptrs() { NIns* _tins = _nIns; _nIns=_nExitIns; _nExitIns=_tins; }
@ -521,6 +522,11 @@ namespace nanojit
*(--_nIns) = (uint8_t) ( 0x50 | (r) ); \
asm_output("push %s",gpn(r)); } while(0)
#define PUSHm(d,b) do { \
count_pushld();\
ALUm(0xff, 6, d, b); \
asm_output("push %d(%s)",d,gpn(b)); } while(0)
#define POPr(r) do { \
count_pop();\
underrunProtect(1); \

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

@ -202,6 +202,8 @@ namespace avmplus {
// Whether or not we can use SSE2 instructions and conditional moves.
bool sse2;
bool use_cmov;
// Whether to use a virtual stack pointer
bool fixed_esp;
#endif
#if defined (AVMPLUS_ARM)