From 2a71b752767f5091357091b20060fab1e396a8e7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 25 Jan 2010 08:25:04 +1100 Subject: [PATCH] Bug 534313 - nanojit: split isQuad() into isI64() + isF64() + is64(). r=dvander,stejohns. --HG-- extra : convert_revision : f24a70adec4c24dffd3a9c6c3572c5755938291a --- js/src/nanojit/Assembler.cpp | 7 +++---- js/src/nanojit/Assembler.h | 2 +- js/src/nanojit/LIR.cpp | 19 ++++++++++++++++--- js/src/nanojit/LIR.h | 3 --- js/src/nanojit/Native.h | 3 --- js/src/nanojit/NativeARM.cpp | 15 +++++++-------- js/src/nanojit/NativePPC.cpp | 16 ++++++++++------ js/src/nanojit/NativePPC.h | 3 +++ js/src/nanojit/NativeSparc.cpp | 6 ++---- js/src/nanojit/NativeX64.cpp | 29 ++++++++++++++++------------- js/src/nanojit/Nativei386.cpp | 11 ++++------- js/src/nanojit/Nativei386.h | 6 +++--- 12 files changed, 65 insertions(+), 55 deletions(-) diff --git a/js/src/nanojit/Assembler.cpp b/js/src/nanojit/Assembler.cpp index b1ececc488fc..15d9cfc7c703 100755 --- a/js/src/nanojit/Assembler.cpp +++ b/js/src/nanojit/Assembler.cpp @@ -319,7 +319,7 @@ namespace nanojit NanoAssert(arIndex == (uint32_t)n-1); i = n-1; } - else if (ins->isQuad()) { + else if (ins->isI64() || ins->isF64()) { NanoAssert(_entries[i + 1]==ins); i += 1; // skip high word } @@ -664,7 +664,7 @@ namespace nanojit verbose_only( if (d && (_logc->lcbits & LC_Assembly)) { setOutputForEOL(" <= spill %s", _thisfrag->lirbuf->names->formatRef(ins)); } ) - asm_spill(r, d, pop, ins->isQuad()); + asm_spill(r, d, pop, ins->isI64() || ins->isF64()); } // XXX: This function is error-prone and should be phased out; see bug 513615. @@ -1793,8 +1793,7 @@ namespace nanojit continue; } - const char* rname = ins->isQuad() ? fpn(r) : gpn(r); - VMPI_sprintf(s, " %s(%s)", rname, n); + VMPI_sprintf(s, " %s(%s)", gpn(r), n); s += VMPI_strlen(s); } } diff --git a/js/src/nanojit/Assembler.h b/js/src/nanojit/Assembler.h index 3291959c18e3..65ab673f6239 100644 --- a/js/src/nanojit/Assembler.h +++ b/js/src/nanojit/Assembler.h @@ -151,7 +151,7 @@ namespace nanojit inline /*static*/ uint32_t AR::nStackSlotsFor(LIns* ins) { - return ins->isop(LIR_alloc) ? (ins->size()>>2) : (ins->isQuad() ? 2 : 1); + return ins->isop(LIR_alloc) ? (ins->size()>>2) : ((ins->isI64() || ins->isF64()) ? 2 : 1); } inline uint32_t AR::stackSlotsNeeded() const diff --git a/js/src/nanojit/LIR.cpp b/js/src/nanojit/LIR.cpp index 612805c3b24b..86780b52355f 100644 --- a/js/src/nanojit/LIR.cpp +++ b/js/src/nanojit/LIR.cpp @@ -907,8 +907,19 @@ namespace nanojit iffalse = tmp; } - if (use_cmov) - return ins3((iftrue->isQuad() || iffalse->isQuad()) ? LIR_qcmov : LIR_cmov, cond, iftrue, iffalse); + if (use_cmov) { + LOpcode op = LIR_cmov; + if (iftrue->isI32() && iffalse->isI32()) { + op = LIR_cmov; + } else if (iftrue->isI64() && iffalse->isI64()) { + op = LIR_qcmov; + } else if (iftrue->isF64() && iffalse->isF64()) { + NanoAssertMsg(0, "LIR_fcmov doesn't exist yet, sorry"); + } else { + NanoAssert(0); // type error + } + return ins3(op, cond, iftrue, iffalse); + } LInsp ncond = ins1(LIR_neg, cond); // cond ? -1 : 0 return ins2(LIR_or, @@ -964,7 +975,8 @@ namespace nanojit ignore = true; } else { d = top - d; - if (ins->oprnd1()->isQuad()) { + LTy ty = ins->oprnd1()->retType(); + if (ty == LTy_I64 || ty == LTy_F64) { // storing 8 bytes if (stk->get(d) && stk->get(d-1)) { ignore = true; @@ -975,6 +987,7 @@ namespace nanojit } else { // storing 4 bytes + NanoAssert(ty == LTy_I32); if (stk->get(d)) { ignore = true; } else { diff --git a/js/src/nanojit/LIR.h b/js/src/nanojit/LIR.h index 067a3b7112ce..497738cca0d4 100644 --- a/js/src/nanojit/LIR.h +++ b/js/src/nanojit/LIR.h @@ -577,9 +577,6 @@ namespace nanojit bool isF64() const { return retType() == LTy_F64; } - bool isQuad() const { - return isI64() || isF64(); - } bool isPtr() const { #ifdef NANOJIT_64BIT return isI64(); diff --git a/js/src/nanojit/Native.h b/js/src/nanojit/Native.h index 1c1e73f4fe15..80c38fd17a4a 100644 --- a/js/src/nanojit/Native.h +++ b/js/src/nanojit/Native.h @@ -132,7 +132,6 @@ namespace nanojit { #ifdef NJ_NO_VARIADIC_MACROS static void asm_output(const char *f, ...) {} #define gpn(r) regNames[(r)] - #define fpn(r) regNames[(r)] #elif defined(NJ_VERBOSE) // Used for printing native instructions. Like Assembler::outputf(), // but only outputs if LC_Assembly is set. Also prepends the output @@ -147,11 +146,9 @@ namespace nanojit { } \ } while (0) /* no semi */ #define gpn(r) regNames[(r)] - #define fpn(r) regNames[(r)] #else #define asm_output(...) #define gpn(r) - #define fpn(r) #endif /* NJ_VERBOSE */ #endif // __nanojit_Native__ diff --git a/js/src/nanojit/NativeARM.cpp b/js/src/nanojit/NativeARM.cpp index 71967df79ab3..b0cf1ef2fc7f 100644 --- a/js/src/nanojit/NativeARM.cpp +++ b/js/src/nanojit/NativeARM.cpp @@ -769,13 +769,13 @@ Assembler::asm_regarg(ArgSize sz, LInsp p, Register r) void Assembler::asm_stkarg(LInsp arg, int stkd) { - bool isQuad = arg->isQuad(); + bool isF64 = arg->isF64(); Register rr; if (arg->isUsed() && (rr = arg->getReg(), isKnownReg(rr))) { // The argument resides somewhere in registers, so we simply need to // push it onto the stack. - if (!ARM_VFP || !isQuad) { + if (!ARM_VFP || !isF64) { NanoAssert(IsGpReg(rr)); STR(rr, SP, stkd); @@ -800,7 +800,7 @@ Assembler::asm_stkarg(LInsp arg, int stkd) // The argument does not reside in registers, so we need to get some // memory for it and then copy it onto the stack. int d = findMemFor(arg); - if (!isQuad) { + if (!isF64) { STR(IP, SP, stkd); if (arg->isop(LIR_alloc)) { asm_add_imm(IP, FP, d); @@ -1323,7 +1323,7 @@ Assembler::asm_load64(LInsp ins) return; } - NanoAssert(ins->isQuad()); + NanoAssert(ins->isF64()); LIns* base = ins->oprnd1(); int offset = ins->disp(); @@ -2195,8 +2195,7 @@ Assembler::asm_cmp(LIns *cond) LInsp lhs = cond->oprnd1(); LInsp rhs = cond->oprnd2(); - // Not supported yet. - NanoAssert(!lhs->isQuad() && !rhs->isQuad()); + NanoAssert(lhs->isI32() && rhs->isI32()); // ready to issue the compare if (rhs->isconst()) { @@ -2542,13 +2541,13 @@ Assembler::asm_load32(LInsp ins) void Assembler::asm_cmov(LInsp ins) { - NanoAssert(ins->opcode() == LIR_cmov); + LOpcode op = ins->opcode(); LIns* condval = ins->oprnd1(); LIns* iftrue = ins->oprnd2(); LIns* iffalse = ins->oprnd3(); NanoAssert(condval->isCmp()); - NanoAssert(!iftrue->isQuad() && !iffalse->isQuad()); + NanoAssert(op == LIR_cmov && iftrue->isI32() && iffalse->isI32()); const Register rr = prepResultReg(ins, GpRegs); diff --git a/js/src/nanojit/NativePPC.cpp b/js/src/nanojit/NativePPC.cpp index 2ab5f39f4322..225e2e56c681 100644 --- a/js/src/nanojit/NativePPC.cpp +++ b/js/src/nanojit/NativePPC.cpp @@ -319,7 +319,7 @@ namespace nanojit } void Assembler::asm_store64(LOpcode op, LIns *value, int32_t dr, LIns *base) { - NanoAssert(value->isQuad()); + NanoAssert(value->isI64() || value->isF64()); switch (op) { case LIR_stfi: @@ -662,11 +662,14 @@ namespace nanojit else { d = findMemFor(i); if (IsFpReg(r)) { - NanoAssert(i->isQuad()); + NanoAssert(i->isI64() || i->isF64()); LFD(r, d, FP); - } else if (i->isQuad()) { + } else if (i->isI64() || i->isF64()) { + NanoAssert(IsGpReg(r)); LD(r, d, FP); } else { + NanoAssert(i->isI32()); + NanoAssert(IsGpReg(r)); LWZ(r, d, FP); } } @@ -799,7 +802,7 @@ namespace nanojit if (p->isop(LIR_alloc)) { NanoAssert(isS16(d)); ADDI(r, FP, d); - } else if (p->isQuad()) { + } else if (p->isI64() || p->isF64()) { LD(r, d, FP); } else { LWZ(r, d, FP); @@ -1183,13 +1186,14 @@ namespace nanojit } void Assembler::asm_cmov(LIns *ins) { - NanoAssert(ins->isop(LIR_cmov) || ins->isop(LIR_qcmov)); + LOpcode op = ins->opcode(); LIns* cond = ins->oprnd1(); LIns* iftrue = ins->oprnd2(); LIns* iffalse = ins->oprnd3(); NanoAssert(cond->isCmp()); - NanoAssert(iftrue->isQuad() == iffalse->isQuad()); + NanoAssert((op == LIR_cmov && iftrue->isI32() && iffalse->isI32()) || + (op == LIR_qcmov && iftrue->isI64() && iffalse->isI64())); // fixme: we could handle fpu registers here, too, since we're just branching Register rr = prepResultReg(ins, GpRegs); diff --git a/js/src/nanojit/NativePPC.h b/js/src/nanojit/NativePPC.h index 9e14dbfe5e61..437983954a79 100644 --- a/js/src/nanojit/NativePPC.h +++ b/js/src/nanojit/NativePPC.h @@ -259,6 +259,9 @@ namespace nanojit static const int NumSavedRegs = 18; // R13-R30 #endif + static inline bool IsGpReg(Register r) { + return r <= R31; + } static inline bool IsFpReg(Register r) { return r >= F0; } diff --git a/js/src/nanojit/NativeSparc.cpp b/js/src/nanojit/NativeSparc.cpp index 5551988f3434..99150fc33542 100644 --- a/js/src/nanojit/NativeSparc.cpp +++ b/js/src/nanojit/NativeSparc.cpp @@ -577,9 +577,7 @@ namespace nanojit LInsp lhs = cond->oprnd1(); LInsp rhs = cond->oprnd2(); - NanoAssert((!lhs->isQuad() && !rhs->isQuad()) || (lhs->isQuad() && rhs->isQuad())); - - NanoAssert(!lhs->isQuad() && !rhs->isQuad()); + NanoAssert(lhs->isI32() && rhs->isI32()); // ready to issue the compare if (rhs->isconst()) @@ -805,7 +803,7 @@ namespace nanojit LIns* iffalse = ins->oprnd3(); NanoAssert(condval->isCmp()); - NanoAssert(op == LIR_qcmov || (!iftrue->isQuad() && !iffalse->isQuad())); + NanoAssert(op == LIR_cmov && iftrue->isI32() && iffalse->isI32()); const Register rr = prepResultReg(ins, GpRegs); diff --git a/js/src/nanojit/NativeX64.cpp b/js/src/nanojit/NativeX64.cpp index 84d56f8dffe8..8eaa5a659558 100644 --- a/js/src/nanojit/NativeX64.cpp +++ b/js/src/nanojit/NativeX64.cpp @@ -932,7 +932,7 @@ namespace nanojit void Assembler::asm_regarg(ArgSize sz, LIns *p, Register r) { if (sz == ARGSIZE_I) { - NanoAssert(!p->isQuad()); + NanoAssert(p->isI32()); if (p->isconst()) { asm_quad(r, int64_t(p->imm32())); return; @@ -940,7 +940,7 @@ namespace nanojit // sign extend int32 to int64 MOVSXDR(r, r); } else if (sz == ARGSIZE_U) { - NanoAssert(!p->isQuad()); + NanoAssert(p->isI32()); if (p->isconst()) { asm_quad(r, uint64_t(uint32_t(p->imm32()))); return; @@ -965,11 +965,11 @@ namespace nanojit MOVQSPR(stk_off, r); // movq [rsp+d8], r if (sz == ARGSIZE_I) { // extend int32 to int64 - NanoAssert(!p->isQuad()); + NanoAssert(p->isI32()); MOVSXDR(r, r); } else if (sz == ARGSIZE_U) { // extend uint32 to uint64 - NanoAssert(!p->isQuad()); + NanoAssert(p->isI32()); MOVLR(r, r); } } else { @@ -1003,7 +1003,7 @@ namespace nanojit void Assembler::asm_u2f(LIns *ins) { Register r = prepResultReg(ins, FpRegs); Register b = findRegFor(ins->oprnd1(), GpRegs); - NanoAssert(!ins->oprnd1()->isQuad()); + NanoAssert(ins->oprnd1()->isI32()); // since oprnd1 value is 32bit, its okay to zero-extend the value without worrying about clobbering. CVTSQ2SD(r, b); // convert int64 to double XORPS(r); // xorps xmmr,xmmr to break dependency chains @@ -1013,7 +1013,7 @@ namespace nanojit void Assembler::asm_f2i(LIns *ins) { LIns *lhs = ins->oprnd1(); - NanoAssert(!ins->isQuad() && lhs->isQuad()); + NanoAssert(ins->isI32() && lhs->isF64()); Register r = prepareResultReg(ins, GpRegs); Register b = findRegFor(lhs, FpRegs); @@ -1027,8 +1027,8 @@ namespace nanojit LIns* iftrue = ins->oprnd2(); LIns* iffalse = ins->oprnd3(); NanoAssert(cond->isCmp()); - NanoAssert((ins->isop(LIR_qcmov) && iftrue->isQuad() && iffalse->isQuad()) || - (ins->isop(LIR_cmov) && !iftrue->isQuad() && !iffalse->isQuad())); + NanoAssert((ins->isop(LIR_cmov) && iftrue->isI32() && iffalse->isI32()) || + (ins->isop(LIR_qcmov) && iftrue->isI64() && iffalse->isI64())); // this code assumes that neither LD nor MR nor MRcc set any of the condition flags. // (This is true on Intel, is it true on all architectures?) @@ -1313,12 +1313,15 @@ namespace nanojit else { int d = findMemFor(ins); if (IsFpReg(r)) { - NanoAssert(ins->isQuad()); + NanoAssert(ins->isI64() || ins->isF64()); // load 64bits into XMM. don't know if double or int64, assume double. MOVSDRM(r, d, FP); - } else if (ins->isQuad()) { + } else if (ins->isI64() || ins->isF64()) { + NanoAssert(IsGpReg(r)); MOVQRM(r, d, FP); } else { + NanoAssert(ins->isI32()); + NanoAssert(IsGpReg(r)); MOVLRM(r, d, FP); } } @@ -1428,7 +1431,7 @@ namespace nanojit } void Assembler::asm_load32(LIns *ins) { - NanoAssert(!ins->isQuad()); + NanoAssert(ins->isI32()); Register r, b; int32_t d; regalloc_load(ins, GpRegs, r, d, b); @@ -1461,7 +1464,7 @@ namespace nanojit } void Assembler::asm_store64(LOpcode op, LIns *value, int d, LIns *base) { - NanoAssert(value->isQuad()); + NanoAssert(value->isI64() || value->isF64()); switch (op) { case LIR_stqi: { @@ -1498,7 +1501,7 @@ namespace nanojit // single-byte stores with REX prefix. const RegisterMask SrcRegs = (op == LIR_stb) ? SingleByteStoreRegs : GpRegs; - NanoAssert(!value->isQuad()); + NanoAssert(value->isI32()); Register b = getBaseReg(base, d, BaseRegs); Register r = findRegFor(value, SrcRegs & ~rmask(b)); diff --git a/js/src/nanojit/Nativei386.cpp b/js/src/nanojit/Nativei386.cpp index 8e7fda9d462d..27398f44051a 100644 --- a/js/src/nanojit/Nativei386.cpp +++ b/js/src/nanojit/Nativei386.cpp @@ -831,10 +831,7 @@ namespace nanojit LInsp lhs = cond->oprnd1(); LInsp rhs = cond->oprnd2(); - NanoAssert((!lhs->isQuad() && !rhs->isQuad()) || (lhs->isQuad() && rhs->isQuad())); - - // Not supported yet. - NanoAssert(!lhs->isQuad() && !rhs->isQuad()); + NanoAssert(lhs->isI32() && rhs->isI32()); // Ready to issue the compare. if (rhs->isconst()) { @@ -1255,7 +1252,7 @@ namespace nanojit LIns* iffalse = ins->oprnd3(); NanoAssert(condval->isCmp()); - NanoAssert(op == LIR_qcmov || (!iftrue->isQuad() && !iffalse->isQuad())); + NanoAssert(op == LIR_cmov && iftrue->isI32() && iffalse->isI32()); const Register rr = prepResultReg(ins, GpRegs); @@ -1609,7 +1606,7 @@ namespace nanojit void Assembler::asm_farg(LInsp ins, int32_t& stkd) { - NanoAssert(ins->isQuad()); + NanoAssert(ins->isF64()); Register r = findRegFor(ins, FpRegs); if (rmask(r) & XmmRegs) { SSE_STQ(stkd, SP, r); @@ -1895,7 +1892,7 @@ namespace nanojit NanoAssert(condop >= LIR_feq && condop <= LIR_fge); LIns* lhs = cond->oprnd1(); LIns* rhs = cond->oprnd2(); - NanoAssert(lhs->isQuad() && rhs->isQuad()); + NanoAssert(lhs->isF64() && rhs->isF64()); if (config.sse2) { // First, we convert (a < b) into (b > a), and (a <= b) into (b >= a). diff --git a/js/src/nanojit/Nativei386.h b/js/src/nanojit/Nativei386.h index 8bf53b57c6c9..440bccff1738 100644 --- a/js/src/nanojit/Nativei386.h +++ b/js/src/nanojit/Nativei386.h @@ -928,7 +928,7 @@ namespace nanojit #define FCHS() do { count_fpu(); FPUc(0xd9e0); asm_output("fchs"); } while(0) #define FLD1() do { count_fpu(); FPUc(0xd9e8); asm_output("fld1"); fpu_push(); } while(0) #define FLDZ() do { count_fpu(); FPUc(0xd9ee); asm_output("fldz"); fpu_push(); } while(0) -#define FFREE(r) do { count_fpu(); FPU(0xddc0, r); asm_output("ffree %s",fpn(r)); } while(0) +#define FFREE(r) do { count_fpu(); FPU(0xddc0, r); asm_output("ffree %s",gpn(r)); } while(0) #define FST32(p,d,b) do { count_stq(); FPUm(0xd902|(p), d, b); asm_output("fst%s32 %d(%s)",((p)?"p":""),d,gpn(b)); if (p) fpu_pop(); } while(0) #define FSTQ(p,d,b) do { count_stq(); FPUm(0xdd02|(p), d, b); asm_output("fst%sq %d(%s)",((p)?"p":""),d,gpn(b)); if (p) fpu_pop(); } while(0) #define FSTPQ(d,b) FSTQ(1,d,b) @@ -957,10 +957,10 @@ namespace nanojit #define FDIVRdm(m) do { const double* const dm = m; \ count_ldq(); FPUdm(0xdc07, dm); asm_output("fdivr (%p)",(void*)dm); } while(0) #define FINCSTP() do { count_fpu(); FPUc(0xd9f7); asm_output("fincstp"); } while(0) -#define FSTP(r) do { count_fpu(); FPU(0xddd8, r&7); asm_output("fstp %s",fpn(r)); fpu_pop();} while(0) +#define FSTP(r) do { count_fpu(); FPU(0xddd8, r&7); asm_output("fstp %s",gpn(r)); fpu_pop();} while(0) #define FCOMP() do { count_fpu(); FPUc(0xD8D9); asm_output("fcomp"); fpu_pop();} while(0) #define FCOMPP() do { count_fpu(); FPUc(0xDED9); asm_output("fcompp"); fpu_pop();fpu_pop();} while(0) -#define FLDr(r) do { count_ldq(); FPU(0xd9c0,r); asm_output("fld %s",fpn(r)); fpu_push(); } while(0) +#define FLDr(r) do { count_ldq(); FPU(0xd9c0,r); asm_output("fld %s",gpn(r)); fpu_push(); } while(0) #define EMMS() do { count_fpu(); FPUc(0x0f77); asm_output("emms"); } while (0) // standard direct call