diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index e12f63ccfe7c..d6a5177a6081 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -2841,9 +2841,9 @@ ICBinaryArith_Double::Compiler::generateStubCode(MacroAssembler &masm) break; case JSOP_MOD: masm.setupUnalignedABICall(2, R0.scratchReg()); - masm.passABIArg(FloatReg0); - masm.passABIArg(FloatReg1); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MacroAssembler::DOUBLE); + masm.passABIArg(FloatReg0, MoveOp::DOUBLE); + masm.passABIArg(FloatReg1, MoveOp::DOUBLE); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MoveOp::DOUBLE); JS_ASSERT(ReturnFloatReg == FloatReg0); break; default: @@ -2968,7 +2968,7 @@ ICBinaryArith_DoubleWithInt32::Compiler::generateStubCode(MacroAssembler &masm) masm.bind(&truncateABICall); masm.push(intReg); masm.setupUnalignedABICall(1, scratchReg); - masm.passABIArg(FloatReg0); + masm.passABIArg(FloatReg0, MoveOp::DOUBLE); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::ToInt32)); masm.storeCallResult(scratchReg); masm.pop(intReg); @@ -3117,7 +3117,7 @@ ICUnaryArith_Double::Compiler::generateStubCode(MacroAssembler &masm) masm.bind(&truncateABICall); masm.setupUnalignedABICall(1, scratchReg); - masm.passABIArg(FloatReg0); + masm.passABIArg(FloatReg0, MoveOp::DOUBLE); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::ToInt32)); masm.storeCallResult(scratchReg); diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index b6fac075a84a..6a03835e0605 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +/* -*- Mnde: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sts=4 et sw=4 tw=99: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -1177,13 +1177,28 @@ CodeGenerator::visitMoveGroup(LMoveGroup *group) const LAllocation *from = move.from(); const LAllocation *to = move.to(); + LDefinition::Type type = move.type(); // No bogus moves. JS_ASSERT(*from != *to); JS_ASSERT(!from->isConstant()); JS_ASSERT(from->isDouble() == to->isDouble()); - MoveOp::Kind kind = from->isDouble() ? MoveOp::DOUBLE : MoveOp::GENERAL; + MoveOp::Kind kind; + switch (type) { + case LDefinition::OBJECT: + case LDefinition::SLOTS: +#ifdef JS_NUNBOX32 + case LDefinition::TYPE: + case LDefinition::PAYLOAD: +#else + case LDefinition::BOX: +#endif + case LDefinition::GENERAL: kind = MoveOp::GENERAL; break; + case LDefinition::FLOAT32: + case LDefinition::DOUBLE: kind = MoveOp::DOUBLE; break; + default: MOZ_ASSUME_UNREACHABLE("Unexpected move type"); + } if (!resolver.addMove(toMoveOperand(from), toMoveOperand(to), kind)) return false; @@ -3035,9 +3050,9 @@ bool CodeGenerator::visitAtan2D(LAtan2D *lir) FloatRegister x = ToFloatRegister(lir->x()); masm.setupUnalignedABICall(2, temp); - masm.passABIArg(y); - masm.passABIArg(x); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaAtan2), MacroAssembler::DOUBLE); + masm.passABIArg(y, MoveOp::DOUBLE); + masm.passABIArg(x, MoveOp::DOUBLE); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaAtan2), MoveOp::DOUBLE); JS_ASSERT(ToFloatRegister(lir->output()) == ReturnFloatReg); return true; @@ -3050,9 +3065,9 @@ bool CodeGenerator::visitHypot(LHypot *lir) FloatRegister y = ToFloatRegister(lir->y()); masm.setupUnalignedABICall(2, temp); - masm.passABIArg(x); - masm.passABIArg(y); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaHypot), MacroAssembler::DOUBLE); + masm.passABIArg(x, MoveOp::DOUBLE); + masm.passABIArg(y, MoveOp::DOUBLE); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaHypot), MoveOp::DOUBLE); JS_ASSERT(ToFloatRegister(lir->output()) == ReturnFloatReg); return true; @@ -3791,10 +3806,10 @@ CodeGenerator::visitPowI(LPowI *ins) // its scratch register. We can therefore save an input register by // reusing the scratch register to pass constants to callWithABI. masm.setupUnalignedABICall(2, temp); - masm.passABIArg(value); + masm.passABIArg(value, MoveOp::DOUBLE); masm.passABIArg(power); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::powi), MacroAssembler::DOUBLE); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::powi), MoveOp::DOUBLE); JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg); return true; @@ -3808,9 +3823,9 @@ CodeGenerator::visitPowD(LPowD *ins) Register temp = ToRegister(ins->temp()); masm.setupUnalignedABICall(2, temp); - masm.passABIArg(value); - masm.passABIArg(power); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaPow), MacroAssembler::DOUBLE); + masm.passABIArg(value, MoveOp::DOUBLE); + masm.passABIArg(power, MoveOp::DOUBLE); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaPow), MoveOp::DOUBLE); JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg); return true; @@ -3826,7 +3841,7 @@ CodeGenerator::visitRandom(LRandom *ins) masm.setupUnalignedABICall(1, temp2); masm.passABIArg(temp); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, math_random_no_outparam), MacroAssembler::DOUBLE); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, math_random_no_outparam), MoveOp::DOUBLE); JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg); return true; @@ -3846,7 +3861,7 @@ CodeGenerator::visitMathFunctionD(LMathFunctionD *ins) masm.movePtr(ImmPtr(mathCache), temp); masm.passABIArg(temp); } - masm.passABIArg(input); + masm.passABIArg(input, MoveOp::DOUBLE); # define MAYBE_CACHED(fcn) (mathCache ? (void*)fcn ## _impl : (void*)fcn ## _uncached) @@ -3927,7 +3942,7 @@ CodeGenerator::visitMathFunctionD(LMathFunctionD *ins) # undef MAYBE_CACHED - masm.callWithABI(funptr, MacroAssembler::DOUBLE); + masm.callWithABI(funptr, MoveOp::DOUBLE); return true; } @@ -3939,7 +3954,7 @@ CodeGenerator::visitMathFunctionF(LMathFunctionF *ins) JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg); masm.setupUnalignedABICall(1, temp); - masm.passABIArg(input); + masm.passABIArg(input, MoveOp::DOUBLE); void *funptr = nullptr; switch (ins->mir()->function()) { @@ -3956,7 +3971,7 @@ CodeGenerator::visitMathFunctionF(LMathFunctionF *ins) MOZ_ASSUME_UNREACHABLE("Unknown or unsupported float32 math function"); } - masm.callWithABI(funptr, MacroAssembler::FLOAT); + masm.callWithABI(funptr, MoveOp::DOUBLE); return true; } @@ -3970,13 +3985,13 @@ CodeGenerator::visitModD(LModD *ins) JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg); masm.setupUnalignedABICall(2, temp); - masm.passABIArg(lhs); - masm.passABIArg(rhs); + masm.passABIArg(lhs, MoveOp::DOUBLE); + masm.passABIArg(rhs, MoveOp::DOUBLE); if (gen->compilingAsmJS()) - masm.callWithABI(AsmJSImm_ModD, MacroAssembler::DOUBLE); + masm.callWithABI(AsmJSImm_ModD, MoveOp::DOUBLE); else - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MacroAssembler::DOUBLE); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MoveOp::DOUBLE); return true; } diff --git a/js/src/jit/IonMacroAssembler.h b/js/src/jit/IonMacroAssembler.h index 4a03191b8973..297c1c3bb654 100644 --- a/js/src/jit/IonMacroAssembler.h +++ b/js/src/jit/IonMacroAssembler.h @@ -865,12 +865,12 @@ class MacroAssembler : public MacroAssemblerSpecific // been made so that a safepoint can be made at that location. template - void callWithABINoProfiling(const T &fun, Result result = GENERAL) { + void callWithABINoProfiling(const T &fun, MoveOp::Kind result = MoveOp::GENERAL) { MacroAssemblerSpecific::callWithABI(fun, result); } template - void callWithABI(const T &fun, Result result = GENERAL) { + void callWithABI(const T &fun, MoveOp::Kind result = MoveOp::GENERAL) { leaveSPSFrame(); callWithABINoProfiling(fun, result); reenterSPSFrame(); diff --git a/js/src/jit/MoveResolver.h b/js/src/jit/MoveResolver.h index 3ae8a50fd053..099125b57f3d 100644 --- a/js/src/jit/MoveResolver.h +++ b/js/src/jit/MoveResolver.h @@ -18,38 +18,39 @@ namespace jit { // guaranteed that Operand looks like this on all ISAs. class MoveOperand { + public: enum Kind { + // A register in the "integer", aka "general purpose", class. REG, + // A register in the "float" register class. FLOAT_REG, - ADDRESS, - FLOAT_ADDRESS, + // A memory region. + MEMORY, + // The address of a memory region. EFFECTIVE_ADDRESS }; + private: Kind kind_; uint32_t code_; int32_t disp_; public: - enum AddressKind { - MEMORY = ADDRESS, - EFFECTIVE = EFFECTIVE_ADDRESS, - FLOAT = FLOAT_ADDRESS - }; - MoveOperand() { } explicit MoveOperand(const Register ®) : kind_(REG), code_(reg.code()) { } explicit MoveOperand(const FloatRegister ®) : kind_(FLOAT_REG), code_(reg.code()) { } - MoveOperand(const Register ®, int32_t disp, AddressKind addrKind = MEMORY) - : kind_((Kind) addrKind), + MoveOperand(const Register ®, int32_t disp, Kind kind = MEMORY) + : kind_(kind), code_(reg.code()), disp_(disp) { + JS_ASSERT(isMemoryOrEffectiveAddress()); + // With a zero offset, this is a plain reg-to-reg move. - if (disp == 0 && addrKind == EFFECTIVE) + if (disp == 0 && kind_ == EFFECTIVE_ADDRESS) kind_ = REG; } MoveOperand(const MoveOperand &other) @@ -63,18 +64,15 @@ class MoveOperand bool isGeneralReg() const { return kind_ == REG; } - bool isDouble() const { - return kind_ == FLOAT_REG || kind_ == FLOAT_ADDRESS; - } bool isMemory() const { - return kind_ == ADDRESS; - } - bool isFloatAddress() const { - return kind_ == FLOAT_ADDRESS; + return kind_ == MEMORY; } bool isEffectiveAddress() const { return kind_ == EFFECTIVE_ADDRESS; } + bool isMemoryOrEffectiveAddress() const { + return isMemory() || isEffectiveAddress(); + } Register reg() const { JS_ASSERT(isGeneralReg()); return Register::FromCode(code_); @@ -84,10 +82,11 @@ class MoveOperand return FloatRegister::FromCode(code_); } Register base() const { - JS_ASSERT(isMemory() || isEffectiveAddress() || isFloatAddress()); + JS_ASSERT(isMemoryOrEffectiveAddress()); return Register::FromCode(code_); } int32_t disp() const { + JS_ASSERT(isMemoryOrEffectiveAddress()); return disp_; } @@ -96,7 +95,7 @@ class MoveOperand return false; if (code_ != other.code_) return false; - if (isMemory() || isEffectiveAddress()) + if (isMemoryOrEffectiveAddress()) return disp_ == other.disp_; return true; } diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 512aad71c061..a8bc75f6f74d 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -3508,13 +3508,14 @@ MacroAssemblerARMCompat::setupUnalignedABICall(uint32_t args, const Register &sc } #ifdef JS_CPU_ARM_HARDFP void -MacroAssemblerARMCompat::passABIArg(const MoveOperand &from) +MacroAssemblerARMCompat::passABIArg(const MoveOperand &from, MoveOp::Kind kind) { MoveOperand to; ++passedArgs_; if (!enoughMemory_) return; - if (from.isDouble()) { + switch (kind) { + case MoveOp::DOUBLE: { FloatRegister fr; if (GetFloatArgReg(usedIntSlots_, usedFloatSlots_, &fr)) { if (!from.isFloatReg() || from.floatReg() != fr) { @@ -3528,7 +3529,9 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from) enoughMemory_ = moveResolver_.addMove(from, MoveOperand(sp, disp), MoveOp::DOUBLE); } usedFloatSlots_++; - } else { + break; + } + case MoveOp::GENERAL: { Register r; if (GetIntArgReg(usedIntSlots_, usedFloatSlots_, &r)) { if (!from.isGeneralReg() || from.reg() != r) { @@ -3540,31 +3543,39 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from) enoughMemory_ = moveResolver_.addMove(from, MoveOperand(sp, disp), MoveOp::GENERAL); } usedIntSlots_++; + break; + } + default: + MOZ_ASSUME_UNREACHABLE("Unexpected argument kind"); } } #else void -MacroAssemblerARMCompat::passABIArg(const MoveOperand &from) +MacroAssemblerARMCompat::passABIArg(const MoveOperand &from, MoveOp::Kind kind) { MoveOperand to; uint32_t increment = 1; bool useResolver = true; ++passedArgs_; - MoveOp::Kind kind = MoveOp::GENERAL; - if (from.isDouble()) { + switch (kind) { + case MoveOp::DOUBLE: // Double arguments need to be rounded up to the nearest doubleword // boundary, even if it is in a register! usedSlots_ = (usedSlots_ + 1) & ~1; increment = 2; - kind = MoveOp::DOUBLE; + break; + case MoveOp::GENERAL: + break; + default: + MOZ_ASSUME_UNREACHABLE("Unexpected argument kind"); } Register destReg; MoveOperand dest; if (GetIntArgReg(usedSlots_, 0, &destReg)) { - if (from.isDouble()) { + if (kind == MoveOp::DOUBLE) { floatArgsInGPR[destReg.code() >> 1] = from; floatArgsInGPRValid[destReg.code() >> 1] = true; useResolver = false; @@ -3588,13 +3599,13 @@ MacroAssemblerARMCompat::passABIArg(const MoveOperand &from) void MacroAssemblerARMCompat::passABIArg(const Register ®) { - passABIArg(MoveOperand(reg)); + passABIArg(MoveOperand(reg), MoveOp::GENERAL); } void -MacroAssemblerARMCompat::passABIArg(const FloatRegister &freg) +MacroAssemblerARMCompat::passABIArg(const FloatRegister &freg, MoveOp::Kind kind) { - passABIArg(MoveOperand(freg)); + passABIArg(MoveOperand(freg), kind); } void MacroAssemblerARMCompat::checkStackAlignment() @@ -3642,7 +3653,7 @@ MacroAssemblerARMCompat::callWithABIPre(uint32_t *stackAdjust) if (from.isFloatReg()) { ma_vxfer(VFPRegister(from.floatReg()), to0, to1); } else { - JS_ASSERT(from.isFloatAddress()); + JS_ASSERT(from.isMemory()); // Note: We can safely use the MoveOperand's displacement here, // even if the base is SP: MoveEmitter::toOperand adjusts // SP-relative operands by the difference between the current @@ -3664,25 +3675,25 @@ MacroAssemblerARMCompat::callWithABIPre(uint32_t *stackAdjust) } void -MacroAssemblerARMCompat::callWithABIPost(uint32_t stackAdjust, Result result) +MacroAssemblerARMCompat::callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result) { if (secondScratchReg_ != lr) ma_mov(secondScratchReg_, lr); switch (result) { - case DOUBLE: + case MoveOp::DOUBLE: #ifndef JS_CPU_ARM_HARDFP // Move double from r0/r1 to ReturnFloatReg. as_vxfer(r0, r1, ReturnFloatReg, CoreToFloat); break; #endif - case FLOAT: + case MoveOp::FLOAT32: #ifndef JS_CPU_ARM_HARDFP // Move float32 from r0 to ReturnFloatReg. as_vxfer(r0, InvalidReg, VFPRegister(d0).singleOverlay(), CoreToFloat); break; #endif - case GENERAL: + case MoveOp::GENERAL: break; default: @@ -3702,7 +3713,7 @@ MacroAssemblerARMCompat::callWithABIPost(uint32_t stackAdjust, Result result) } void -MacroAssemblerARMCompat::callWithABI(void *fun, Result result) +MacroAssemblerARMCompat::callWithABI(void *fun, MoveOp::Kind result) { uint32_t stackAdjust; callWithABIPre(&stackAdjust); @@ -3711,7 +3722,7 @@ MacroAssemblerARMCompat::callWithABI(void *fun, Result result) } void -MacroAssemblerARMCompat::callWithABI(AsmJSImmPtr imm, Result result) +MacroAssemblerARMCompat::callWithABI(AsmJSImmPtr imm, MoveOp::Kind result) { uint32_t stackAdjust; callWithABIPre(&stackAdjust); @@ -3720,7 +3731,7 @@ MacroAssemblerARMCompat::callWithABI(AsmJSImmPtr imm, Result result) } void -MacroAssemblerARMCompat::callWithABI(const Address &fun, Result result) +MacroAssemblerARMCompat::callWithABI(const Address &fun, MoveOp::Kind result) { // Load the callee in r12, no instruction between the ldr and call // should clobber it. Note that we can't use fun.base because it may diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index ad0e79f2c58f..91612e990896 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -485,12 +485,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM setFramePushed(framePushed_ + value); } public: - enum Result { - GENERAL, - DOUBLE, - FLOAT - }; - MacroAssemblerARMCompat() : inCall_(false), enoughMemory_(true), @@ -1409,9 +1403,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM // automatically adjusted. It is extremely important that esp-relative // addresses are computed *after* setupABICall(). Furthermore, no // operations should be emitted while setting arguments. - void passABIArg(const MoveOperand &from); + void passABIArg(const MoveOperand &from, MoveOp::Kind kind); void passABIArg(const Register ®); - void passABIArg(const FloatRegister ®); + void passABIArg(const FloatRegister ®, MoveOp::Kind kind); void passABIArg(const ValueOperand ®s); protected: @@ -1419,13 +1413,13 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM private: void callWithABIPre(uint32_t *stackAdjust); - void callWithABIPost(uint32_t stackAdjust, Result result); + void callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result); public: // Emits a call to a C/C++ function, resolving all argument moves. - void callWithABI(void *fun, Result result = GENERAL); - void callWithABI(AsmJSImmPtr imm, Result result = GENERAL); - void callWithABI(const Address &fun, Result result = GENERAL); + void callWithABI(void *fun, MoveOp::Kind result = MoveOp::GENERAL); + void callWithABI(AsmJSImmPtr imm, MoveOp::Kind result = MoveOp::GENERAL); + void callWithABI(const Address &fun, MoveOp::Kind result = MoveOp::GENERAL); CodeOffsetLabel labelForPatch() { return CodeOffsetLabel(nextOffset().getOffset()); diff --git a/js/src/jit/arm/MoveEmitter-arm.cpp b/js/src/jit/arm/MoveEmitter-arm.cpp index f5ded1122b99..c7543d7e9543 100644 --- a/js/src/jit/arm/MoveEmitter-arm.cpp +++ b/js/src/jit/arm/MoveEmitter-arm.cpp @@ -58,7 +58,7 @@ MoveEmitterARM::spillSlot() const Operand MoveEmitterARM::toOperand(const MoveOperand &operand, bool isFloat) const { - if (operand.isMemory() || operand.isEffectiveAddress() || operand.isFloatAddress()) { + if (operand.isMemoryOrEffectiveAddress()) { if (operand.base() != StackPointer) { JS_ASSERT(operand.disp() < 1024 && operand.disp() > -1024); return Operand(operand.base(), operand.disp()); @@ -193,7 +193,7 @@ MoveEmitterARM::emitMove(const MoveOperand &from, const MoveOperand &to) MOZ_ASSUME_UNREACHABLE("strange move!"); } } else if (to.isGeneralReg()) { - JS_ASSERT(from.isMemory() || from.isEffectiveAddress()); + JS_ASSERT(from.isMemoryOrEffectiveAddress()); if (from.isMemory()) masm.ma_ldr(toOperand(from, false), to.reg()); else @@ -202,7 +202,7 @@ MoveEmitterARM::emitMove(const MoveOperand &from, const MoveOperand &to) // Memory to memory gpr move. Register reg = tempReg(); - JS_ASSERT(from.isMemory() || from.isEffectiveAddress()); + JS_ASSERT(from.isMemoryOrEffectiveAddress()); if (from.isMemory()) masm.ma_ldr(toOperand(from, false), reg); else diff --git a/js/src/jit/arm/Trampoline-arm.cpp b/js/src/jit/arm/Trampoline-arm.cpp index 6a7291338d3f..a53d0d02dd9d 100644 --- a/js/src/jit/arm/Trampoline-arm.cpp +++ b/js/src/jit/arm/Trampoline-arm.cpp @@ -735,22 +735,22 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) MoveOperand from; switch (f.argProperties(explicitArg)) { case VMFunction::WordByValue: - masm.passABIArg(MoveOperand(argsBase, argDisp)); + masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL); argDisp += sizeof(void *); break; case VMFunction::DoubleByValue: // Values should be passed by reference, not by value, so we // assert that the argument is a double-precision float. JS_ASSERT(f.argPassedInFloatReg(explicitArg)); - masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::FLOAT)); + masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::DOUBLE); argDisp += sizeof(double); break; case VMFunction::WordByRef: - masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE)); + masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), MoveOp::GENERAL); argDisp += sizeof(void *); break; case VMFunction::DoubleByRef: - masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE)); + masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), MoveOp::GENERAL); argDisp += 2 * sizeof(void *); break; } diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index bb6aecb62e36..410af5d2b062 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -768,7 +768,7 @@ CodeGeneratorShared::visitOutOfLineTruncateSlow(OutOfLineTruncateSlow *ool) } masm.setupUnalignedABICall(1, dest); - masm.passABIArg(src); + masm.passABIArg(src, MoveOp::DOUBLE); if (gen->compilingAsmJS()) masm.callWithABI(AsmJSImm_ToInt32); else diff --git a/js/src/jit/shared/MoveEmitter-x86-shared.cpp b/js/src/jit/shared/MoveEmitter-x86-shared.cpp index 51ef2b76b73e..0054a2c0e718 100644 --- a/js/src/jit/shared/MoveEmitter-x86-shared.cpp +++ b/js/src/jit/shared/MoveEmitter-x86-shared.cpp @@ -170,7 +170,7 @@ MoveEmitterX86::toAddress(const MoveOperand &operand) const Operand MoveEmitterX86::toOperand(const MoveOperand &operand) const { - if (operand.isMemory() || operand.isEffectiveAddress() || operand.isFloatAddress()) + if (operand.isMemoryOrEffectiveAddress()) return Operand(toAddress(operand)); if (operand.isGeneralReg()) return Operand(operand.reg()); @@ -255,7 +255,7 @@ MoveEmitterX86::emitGeneralMove(const MoveOperand &from, const MoveOperand &to) if (from.isGeneralReg()) { masm.mov(from.reg(), toOperand(to)); } else if (to.isGeneralReg()) { - JS_ASSERT(from.isMemory() || from.isEffectiveAddress()); + JS_ASSERT(from.isMemoryOrEffectiveAddress()); if (from.isMemory()) masm.loadPtr(toAddress(from), to.reg()); else diff --git a/js/src/jit/x64/MacroAssembler-x64.cpp b/js/src/jit/x64/MacroAssembler-x64.cpp index 395a90955272..e9591858bfe8 100644 --- a/js/src/jit/x64/MacroAssembler-x64.cpp +++ b/js/src/jit/x64/MacroAssembler-x64.cpp @@ -134,10 +134,11 @@ MacroAssemblerX64::setupUnalignedABICall(uint32_t args, const Register &scratch) } void -MacroAssemblerX64::passABIArg(const MoveOperand &from) +MacroAssemblerX64::passABIArg(const MoveOperand &from, MoveOp::Kind kind) { MoveOperand to; - if (from.isDouble()) { + switch (kind) { + case MoveOp::DOUBLE: { FloatRegister dest; if (GetFloatArgReg(passedIntArgs_, passedFloatArgs_++, &dest)) { if (from.isFloatReg() && from.floatReg() == dest) { @@ -147,10 +148,15 @@ MacroAssemblerX64::passABIArg(const MoveOperand &from) to = MoveOperand(dest); } else { to = MoveOperand(StackPointer, stackForCall_); - stackForCall_ += sizeof(double); + switch (kind) { + case MoveOp::DOUBLE: stackForCall_ += sizeof(double); break; + default: MOZ_ASSUME_UNREACHABLE("Unexpected float register class argument kind"); + } } enoughMemory_ = moveResolver_.addMove(from, to, MoveOp::DOUBLE); - } else { + break; + } + case MoveOp::GENERAL: { Register dest; if (GetIntArgReg(passedIntArgs_++, passedFloatArgs_, &dest)) { if (from.isGeneralReg() && from.reg() == dest) { @@ -163,19 +169,23 @@ MacroAssemblerX64::passABIArg(const MoveOperand &from) stackForCall_ += sizeof(int64_t); } enoughMemory_ = moveResolver_.addMove(from, to, MoveOp::GENERAL); + break; + } + default: + MOZ_ASSUME_UNREACHABLE("Unexpected argument kind"); } } void MacroAssemblerX64::passABIArg(const Register ®) { - passABIArg(MoveOperand(reg)); + passABIArg(MoveOperand(reg), MoveOp::GENERAL); } void -MacroAssemblerX64::passABIArg(const FloatRegister ®) +MacroAssemblerX64::passABIArg(const FloatRegister ®, MoveOp::Kind kind) { - passABIArg(MoveOperand(reg)); + passABIArg(MoveOperand(reg), kind); } void @@ -219,7 +229,7 @@ MacroAssemblerX64::callWithABIPre(uint32_t *stackAdjust) } void -MacroAssemblerX64::callWithABIPost(uint32_t stackAdjust, Result result) +MacroAssemblerX64::callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result) { freeStack(stackAdjust); if (dynamicAlignment_) @@ -230,7 +240,7 @@ MacroAssemblerX64::callWithABIPost(uint32_t stackAdjust, Result result) } void -MacroAssemblerX64::callWithABI(void *fun, Result result) +MacroAssemblerX64::callWithABI(void *fun, MoveOp::Kind result) { uint32_t stackAdjust; callWithABIPre(&stackAdjust); @@ -239,7 +249,7 @@ MacroAssemblerX64::callWithABI(void *fun, Result result) } void -MacroAssemblerX64::callWithABI(AsmJSImmPtr imm, Result result) +MacroAssemblerX64::callWithABI(AsmJSImmPtr imm, MoveOp::Kind result) { uint32_t stackAdjust; callWithABIPre(&stackAdjust); @@ -259,7 +269,7 @@ IsIntArgReg(Register reg) } void -MacroAssemblerX64::callWithABI(Address fun, Result result) +MacroAssemblerX64::callWithABI(Address fun, MoveOp::Kind result) { if (IsIntArgReg(fun.base)) { // Callee register may be clobbered for an argument. Move the callee to diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 28f4eed9f6f8..d8bd8b36d077 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -79,12 +79,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared using MacroAssemblerX86Shared::callWithExitFrame; using MacroAssemblerX86Shared::branch32; - enum Result { - GENERAL, - DOUBLE, - FLOAT - }; - MacroAssemblerX64() : inCall_(false), enoughMemory_(true) @@ -1199,19 +1193,19 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared // automatically adjusted. It is extremely important that esp-relative // addresses are computed *after* setupABICall(). Furthermore, no // operations should be emitted while setting arguments. - void passABIArg(const MoveOperand &from); + void passABIArg(const MoveOperand &from, MoveOp::Kind kind); void passABIArg(const Register ®); - void passABIArg(const FloatRegister ®); + void passABIArg(const FloatRegister ®, MoveOp::Kind kind); private: void callWithABIPre(uint32_t *stackAdjust); - void callWithABIPost(uint32_t stackAdjust, Result result); + void callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result); public: // Emits a call to a C/C++ function, resolving all argument moves. - void callWithABI(void *fun, Result result = GENERAL); - void callWithABI(AsmJSImmPtr imm, Result result = GENERAL); - void callWithABI(Address fun, Result result = GENERAL); + void callWithABI(void *fun, MoveOp::Kind result = MoveOp::GENERAL); + void callWithABI(AsmJSImmPtr imm, MoveOp::Kind result = MoveOp::GENERAL); + void callWithABI(Address fun, MoveOp::Kind result = MoveOp::GENERAL); void handleFailureWithHandler(void *handler); void handleFailureWithHandlerTail(); diff --git a/js/src/jit/x64/Trampoline-x64.cpp b/js/src/jit/x64/Trampoline-x64.cpp index 14348720e429..0ebc99a01326 100644 --- a/js/src/jit/x64/Trampoline-x64.cpp +++ b/js/src/jit/x64/Trampoline-x64.cpp @@ -586,25 +586,24 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) size_t argDisp = 0; // Copy arguments. - if (f.explicitArgs) { - for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) { - MoveOperand from; - switch (f.argProperties(explicitArg)) { - case VMFunction::WordByValue: - if (f.argPassedInFloatReg(explicitArg)) - masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::FLOAT)); - else - masm.passABIArg(MoveOperand(argsBase, argDisp)); - argDisp += sizeof(void *); - break; - case VMFunction::WordByRef: - masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE)); - argDisp += sizeof(void *); - break; - case VMFunction::DoubleByValue: - case VMFunction::DoubleByRef: - MOZ_ASSUME_UNREACHABLE("NYI: x64 callVM should not be used with 128bits values."); - } + for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) { + MoveOperand from; + switch (f.argProperties(explicitArg)) { + case VMFunction::WordByValue: + if (f.argPassedInFloatReg(explicitArg)) + masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::DOUBLE); + else + masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL); + argDisp += sizeof(void *); + break; + case VMFunction::WordByRef: + masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), + MoveOp::GENERAL); + argDisp += sizeof(void *); + break; + case VMFunction::DoubleByValue: + case VMFunction::DoubleByRef: + MOZ_ASSUME_UNREACHABLE("NYI: x64 callVM should not be used with 128bits values."); } } diff --git a/js/src/jit/x86/CodeGenerator-x86.cpp b/js/src/jit/x86/CodeGenerator-x86.cpp index 534518ff2eaa..48914c71a1fd 100644 --- a/js/src/jit/x86/CodeGenerator-x86.cpp +++ b/js/src/jit/x86/CodeGenerator-x86.cpp @@ -900,7 +900,7 @@ CodeGeneratorX86::visitOutOfLineTruncate(OutOfLineTruncate *ool) saveVolatile(output); masm.setupUnalignedABICall(1, output); - masm.passABIArg(input); + masm.passABIArg(input, MoveOp::DOUBLE); if (gen->compilingAsmJS()) masm.callWithABI(AsmJSImm_ToInt32); else @@ -991,7 +991,7 @@ CodeGeneratorX86::visitOutOfLineTruncateFloat32(OutOfLineTruncateFloat32 *ool) masm.push(input); masm.setupUnalignedABICall(1, output); masm.cvtss2sd(input, input); - masm.passABIArg(input); + masm.passABIArg(input, MoveOp::DOUBLE); if (gen->compilingAsmJS()) masm.callWithABI(AsmJSImm_ToInt32); diff --git a/js/src/jit/x86/MacroAssembler-x86.cpp b/js/src/jit/x86/MacroAssembler-x86.cpp index c430c2778441..3a1629fe45d9 100644 --- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -163,29 +163,34 @@ MacroAssemblerX86::setupUnalignedABICall(uint32_t args, const Register &scratch) } void -MacroAssemblerX86::passABIArg(const MoveOperand &from) +MacroAssemblerX86::passABIArg(const MoveOperand &from, MoveOp::Kind kind) { ++passedArgs_; MoveOperand to = MoveOperand(StackPointer, stackForCall_); - if (from.isDouble()) { + switch (kind) { + case MoveOp::DOUBLE: stackForCall_ += sizeof(double); enoughMemory_ &= moveResolver_.addMove(from, to, MoveOp::DOUBLE); - } else { + break; + case MoveOp::GENERAL: stackForCall_ += sizeof(int32_t); enoughMemory_ &= moveResolver_.addMove(from, to, MoveOp::GENERAL); + break; + default: + MOZ_ASSUME_UNREACHABLE("Unexpected argument kind"); } } void MacroAssemblerX86::passABIArg(const Register ®) { - passABIArg(MoveOperand(reg)); + passABIArg(MoveOperand(reg), MoveOp::GENERAL); } void -MacroAssemblerX86::passABIArg(const FloatRegister ®) +MacroAssemblerX86::passABIArg(const FloatRegister ®, MoveOp::Kind kind) { - passABIArg(MoveOperand(reg)); + passABIArg(MoveOperand(reg), kind); } void @@ -230,16 +235,16 @@ MacroAssemblerX86::callWithABIPre(uint32_t *stackAdjust) } void -MacroAssemblerX86::callWithABIPost(uint32_t stackAdjust, Result result) +MacroAssemblerX86::callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result) { freeStack(stackAdjust); - if (result == DOUBLE) { + if (result == MoveOp::DOUBLE) { reserveStack(sizeof(double)); fstp(Operand(esp, 0)); loadDouble(Operand(esp, 0), ReturnFloatReg); freeStack(sizeof(double)); } - if (result == FLOAT) { + if (result == MoveOp::FLOAT32) { reserveStack(sizeof(float)); fstp32(Operand(esp, 0)); loadFloat(Operand(esp, 0), ReturnFloatReg); @@ -253,7 +258,7 @@ MacroAssemblerX86::callWithABIPost(uint32_t stackAdjust, Result result) } void -MacroAssemblerX86::callWithABI(void *fun, Result result) +MacroAssemblerX86::callWithABI(void *fun, MoveOp::Kind result) { uint32_t stackAdjust; callWithABIPre(&stackAdjust); @@ -262,7 +267,7 @@ MacroAssemblerX86::callWithABI(void *fun, Result result) } void -MacroAssemblerX86::callWithABI(AsmJSImmPtr fun, Result result) +MacroAssemblerX86::callWithABI(AsmJSImmPtr fun, MoveOp::Kind result) { uint32_t stackAdjust; callWithABIPre(&stackAdjust); @@ -271,7 +276,7 @@ MacroAssemblerX86::callWithABI(AsmJSImmPtr fun, Result result) } void -MacroAssemblerX86::callWithABI(const Address &fun, Result result) +MacroAssemblerX86::callWithABI(const Address &fun, MoveOp::Kind result) { uint32_t stackAdjust; callWithABIPre(&stackAdjust); diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index e7ee36481786..eb4a64cb8ae7 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -70,12 +70,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared using MacroAssemblerX86Shared::callWithExitFrame; using MacroAssemblerX86Shared::branch32; - enum Result { - GENERAL, - DOUBLE, - FLOAT - }; - MacroAssemblerX86() : inCall_(false), enoughMemory_(true) @@ -1043,19 +1037,19 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared // automatically adjusted. It is extremely important that esp-relative // addresses are computed *after* setupABICall(). Furthermore, no // operations should be emitted while setting arguments. - void passABIArg(const MoveOperand &from); + void passABIArg(const MoveOperand &from, MoveOp::Kind kind); void passABIArg(const Register ®); - void passABIArg(const FloatRegister ®); + void passABIArg(const FloatRegister ®, MoveOp::Kind kind); private: void callWithABIPre(uint32_t *stackAdjust); - void callWithABIPost(uint32_t stackAdjust, Result result); + void callWithABIPost(uint32_t stackAdjust, MoveOp::Kind result); public: // Emits a call to a C/C++ function, resolving all argument moves. - void callWithABI(void *fun, Result result = GENERAL); - void callWithABI(AsmJSImmPtr fun, Result result = GENERAL); - void callWithABI(const Address &fun, Result result = GENERAL); + void callWithABI(void *fun, MoveOp::Kind result = MoveOp::GENERAL); + void callWithABI(AsmJSImmPtr fun, MoveOp::Kind result = MoveOp::GENERAL); + void callWithABI(const Address &fun, MoveOp::Kind result = MoveOp::GENERAL); // Used from within an Exit frame to handle a pending exception. void handleFailureWithHandler(void *handler); diff --git a/js/src/jit/x86/Trampoline-x86.cpp b/js/src/jit/x86/Trampoline-x86.cpp index 2c6558ccee22..6b584b6cbfc1 100644 --- a/js/src/jit/x86/Trampoline-x86.cpp +++ b/js/src/jit/x86/Trampoline-x86.cpp @@ -614,31 +614,31 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) size_t argDisp = 0; // Copy arguments. - if (f.explicitArgs) { - for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) { - MoveOperand from; - switch (f.argProperties(explicitArg)) { - case VMFunction::WordByValue: - masm.passABIArg(MoveOperand(argsBase, argDisp)); - argDisp += sizeof(void *); - break; - case VMFunction::DoubleByValue: - // We don't pass doubles in float registers on x86, so no need - // to check for argPassedInFloatReg. - masm.passABIArg(MoveOperand(argsBase, argDisp)); - argDisp += sizeof(void *); - masm.passABIArg(MoveOperand(argsBase, argDisp)); - argDisp += sizeof(void *); - break; - case VMFunction::WordByRef: - masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE)); - argDisp += sizeof(void *); - break; - case VMFunction::DoubleByRef: - masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE)); - argDisp += 2 * sizeof(void *); - break; - } + for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) { + MoveOperand from; + switch (f.argProperties(explicitArg)) { + case VMFunction::WordByValue: + masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL); + argDisp += sizeof(void *); + break; + case VMFunction::DoubleByValue: + // We don't pass doubles in float registers on x86, so no need + // to check for argPassedInFloatReg. + masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL); + argDisp += sizeof(void *); + masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL); + argDisp += sizeof(void *); + break; + case VMFunction::WordByRef: + masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), + MoveOp::GENERAL); + argDisp += sizeof(void *); + break; + case VMFunction::DoubleByRef: + masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), + MoveOp::GENERAL); + argDisp += 2 * sizeof(void *); + break; } }