diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 93d02511798..b705b288e58 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -8890,70 +8890,6 @@ CodeGenerator::visitHasClass(LHasClass *ins) return true; } -bool -CodeGenerator::visitAsmJSCall(LAsmJSCall *ins) -{ - MAsmJSCall *mir = ins->mir(); - -#if defined(JS_CODEGEN_ARM) - if (!UseHardFpABI() && mir->callee().which() == MAsmJSCall::Callee::Builtin) { - // The soft ABI passes floating point arguments in GPRs. Since basically - // nothing is set up to handle this, the values are placed in the - // corresponding VFP registers, then transferred to GPRs immediately - // before the call. The mapping is sN <-> rN, where double registers - // can be treated as their two component single registers. - for (unsigned i = 0, e = ins->numOperands(); i < e; i++) { - LAllocation *a = ins->getOperand(i); - if (a->isFloatReg()) { - FloatRegister fr = ToFloatRegister(a); - if (fr.isDouble()) { - uint32_t srcId = fr.singleOverlay().id(); - masm.ma_vxfer(fr, Register::FromCode(srcId), Register::FromCode(srcId + 1)); - } else { - uint32_t srcId = fr.id(); - masm.ma_vxfer(fr, Register::FromCode(srcId)); - } - } - } - } -#endif - - if (mir->spIncrement()) - masm.freeStack(mir->spIncrement()); - - JS_ASSERT((sizeof(AsmJSFrame) + masm.framePushed()) % AsmJSStackAlignment == 0); - -#ifdef DEBUG - static_assert(AsmJSStackAlignment >= ABIStackAlignment, - "The asm.js stack alignment should subsume the ABI-required alignment"); - static_assert(AsmJSStackAlignment % ABIStackAlignment == 0, - "The asm.js stack alignment should subsume the ABI-required alignment"); - Label ok; - masm.branchTestPtr(Assembler::Zero, StackPointer, Imm32(AsmJSStackAlignment - 1), &ok); - masm.breakpoint(); - masm.bind(&ok); -#endif - - MAsmJSCall::Callee callee = mir->callee(); - switch (callee.which()) { - case MAsmJSCall::Callee::Internal: - masm.call(mir->desc(), callee.internal()); - break; - case MAsmJSCall::Callee::Dynamic: - masm.call(mir->desc(), ToRegister(ins->getOperand(mir->dynamicCalleeOperandIndex()))); - break; - case MAsmJSCall::Callee::Builtin: - masm.call(AsmJSImmPtr(callee.builtin())); - break; - } - - if (mir->spIncrement()) - masm.reserveStack(mir->spIncrement()); - - postAsmJSCall(ins); - return true; -} - bool CodeGenerator::visitAsmJSParameter(LAsmJSParameter *lir) { diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index 56e59f4b95f..d5173a4af6f 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -301,7 +301,6 @@ class CodeGenerator : public CodeGeneratorSpecific bool visitIsObject(LIsObject *lir); bool visitHaveSameClass(LHaveSameClass *lir); bool visitHasClass(LHasClass *lir); - bool visitAsmJSCall(LAsmJSCall *lir); bool visitAsmJSParameter(LAsmJSParameter *lir); bool visitAsmJSReturn(LAsmJSReturn *ret); bool visitAsmJSVoidReturn(LAsmJSVoidReturn *ret); diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index 7e8f7c1bd84..caa55f28f41 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -1775,6 +1775,52 @@ CodeGeneratorARM::visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStati MOZ_CRASH("NYI"); } +bool +CodeGeneratorARM::visitAsmJSCall(LAsmJSCall *ins) +{ + MAsmJSCall *mir = ins->mir(); + + if (UseHardFpABI() || mir->callee().which() != MAsmJSCall::Callee::Builtin) { + emitAsmJSCall(ins); + return true; + } + + // The soft ABI passes floating point arguments in GPRs. Since basically + // nothing is set up to handle this, the values are placed in the + // corresponding VFP registers, then transferred to GPRs immediately + // before the call. The mapping is sN <-> rN, where double registers + // can be treated as their two component single registers. + + for (unsigned i = 0, e = ins->numOperands(); i < e; i++) { + LAllocation *a = ins->getOperand(i); + if (a->isFloatReg()) { + FloatRegister fr = ToFloatRegister(a); + if (fr.isDouble()) { + uint32_t srcId = fr.singleOverlay().id(); + masm.ma_vxfer(fr, Register::FromCode(srcId), Register::FromCode(srcId + 1)); + } else { + uint32_t srcId = fr.id(); + masm.ma_vxfer(fr, Register::FromCode(srcId)); + } + } + } + + emitAsmJSCall(ins); + + switch (mir->type()) { + case MIRType_Double: + masm.ma_vxfer(r0, r1, d0); + break; + case MIRType_Float32: + masm.as_vxfer(r0, InvalidReg, VFPRegister(d0).singleOverlay(), Assembler::CoreToFloat); + break; + default: + break; + } + + return true; +} + bool CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins) { diff --git a/js/src/jit/arm/CodeGenerator-arm.h b/js/src/jit/arm/CodeGenerator-arm.h index 76ad584bff5..fefb08bb682 100644 --- a/js/src/jit/arm/CodeGenerator-arm.h +++ b/js/src/jit/arm/CodeGenerator-arm.h @@ -194,6 +194,7 @@ class CodeGeneratorARM : public CodeGeneratorShared bool visitNegF(LNegF *lir); bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins); + bool visitAsmJSCall(LAsmJSCall *ins); bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins); bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins); bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins); @@ -205,23 +206,8 @@ class CodeGeneratorARM : public CodeGeneratorShared bool visitForkJoinGetSlice(LForkJoinGetSlice *ins); bool generateInvalidateEpilogue(); - protected: - void postAsmJSCall(LAsmJSCall *lir) { - if (!UseHardFpABI() && lir->mir()->callee().which() == MAsmJSCall::Callee::Builtin) { - switch (lir->mir()->type()) { - case MIRType_Double: - masm.ma_vxfer(r0, r1, d0); - break; - case MIRType_Float32: - masm.as_vxfer(r0, InvalidReg, VFPRegister(d0).singleOverlay(), - Assembler::CoreToFloat); - break; - default: - break; - } - } - } + protected: bool visitEffectiveAddress(LEffectiveAddress *ins); bool visitUDiv(LUDiv *ins); bool visitUMod(LUMod *ins); diff --git a/js/src/jit/mips/CodeGenerator-mips.cpp b/js/src/jit/mips/CodeGenerator-mips.cpp index a112d81f4e0..f7f5bac3495 100644 --- a/js/src/jit/mips/CodeGenerator-mips.cpp +++ b/js/src/jit/mips/CodeGenerator-mips.cpp @@ -1889,6 +1889,12 @@ CodeGeneratorMIPS::visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStat MOZ_CRASH("NYI"); } +bool +CodeGeneratorMIPS::visitAsmJSCall(LAsmJSCall *ins) +{ + emitAsmJSCall(ins); +} + bool CodeGeneratorMIPS::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins) { diff --git a/js/src/jit/mips/CodeGenerator-mips.h b/js/src/jit/mips/CodeGenerator-mips.h index b6d16aa858c..bd512fde042 100644 --- a/js/src/jit/mips/CodeGenerator-mips.h +++ b/js/src/jit/mips/CodeGenerator-mips.h @@ -247,6 +247,7 @@ class CodeGeneratorMIPS : public CodeGeneratorShared bool visitNegF(LNegF *lir); bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins); + bool visitAsmJSCall(LAsmJSCall *ins); bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins); bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins); bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins); @@ -259,9 +260,8 @@ class CodeGeneratorMIPS : public CodeGeneratorShared bool visitForkJoinGetSlice(LForkJoinGetSlice *ins); bool generateInvalidateEpilogue(); - protected: - void postAsmJSCall(LAsmJSCall *lir) {} + protected: bool visitEffectiveAddress(LEffectiveAddress *ins); bool visitUDiv(LUDiv *ins); bool visitUMod(LUMod *ins); diff --git a/js/src/jit/none/CodeGenerator-none.h b/js/src/jit/none/CodeGenerator-none.h index be9560da285..e1bf0035647 100644 --- a/js/src/jit/none/CodeGenerator-none.h +++ b/js/src/jit/none/CodeGenerator-none.h @@ -50,7 +50,6 @@ class CodeGeneratorNone : public CodeGeneratorShared ValueOperand ToOutValue(LInstruction *) { MOZ_CRASH(); } ValueOperand ToTempValue(LInstruction *, size_t) { MOZ_CRASH(); } bool generateInvalidateEpilogue() { MOZ_CRASH(); } - void postAsmJSCall(LAsmJSCall *) { MOZ_CRASH(); } }; typedef CodeGeneratorNone CodeGeneratorSpecific; diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index 6bd7ea8b8ec..97ecdeeaf40 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -1161,6 +1161,43 @@ CodeGeneratorShared::omitOverRecursedCheck() const return frameSize() < 64 && !gen->performsCall(); } +void +CodeGeneratorShared::emitAsmJSCall(LAsmJSCall *ins) +{ + MAsmJSCall *mir = ins->mir(); + + if (mir->spIncrement()) + masm.freeStack(mir->spIncrement()); + + JS_ASSERT((sizeof(AsmJSFrame) + masm.framePushed()) % AsmJSStackAlignment == 0); + +#ifdef DEBUG + static_assert(AsmJSStackAlignment >= ABIStackAlignment && + AsmJSStackAlignment % ABIStackAlignment == 0, + "The asm.js stack alignment should subsume the ABI-required alignment"); + Label ok; + masm.branchTestPtr(Assembler::Zero, StackPointer, Imm32(AsmJSStackAlignment - 1), &ok); + masm.breakpoint(); + masm.bind(&ok); +#endif + + MAsmJSCall::Callee callee = mir->callee(); + switch (callee.which()) { + case MAsmJSCall::Callee::Internal: + masm.call(mir->desc(), callee.internal()); + break; + case MAsmJSCall::Callee::Dynamic: + masm.call(mir->desc(), ToRegister(ins->getOperand(mir->dynamicCalleeOperandIndex()))); + break; + case MAsmJSCall::Callee::Builtin: + masm.call(AsmJSImmPtr(callee.builtin())); + break; + } + + if (mir->spIncrement()) + masm.reserveStack(mir->spIncrement()); +} + void CodeGeneratorShared::emitPreBarrier(Register base, const LAllocation *index) { diff --git a/js/src/jit/shared/CodeGenerator-shared.h b/js/src/jit/shared/CodeGenerator-shared.h index 24899fb2164..97924672fa8 100644 --- a/js/src/jit/shared/CodeGenerator-shared.h +++ b/js/src/jit/shared/CodeGenerator-shared.h @@ -348,6 +348,8 @@ class CodeGeneratorShared : public LInstructionVisitor bool emitTruncateDouble(FloatRegister src, Register dest, MInstruction *mir); bool emitTruncateFloat32(FloatRegister src, Register dest, MInstruction *mir); + void emitAsmJSCall(LAsmJSCall *ins); + void emitPreBarrier(Register base, const LAllocation *index); void emitPreBarrier(Address address); diff --git a/js/src/jit/x64/CodeGenerator-x64.cpp b/js/src/jit/x64/CodeGenerator-x64.cpp index dae7680ca0e..0b869618632 100644 --- a/js/src/jit/x64/CodeGenerator-x64.cpp +++ b/js/src/jit/x64/CodeGenerator-x64.cpp @@ -240,6 +240,13 @@ CodeGeneratorX64::visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStati MOZ_CRASH("NYI"); } +bool +CodeGeneratorX64::visitAsmJSCall(LAsmJSCall *ins) +{ + emitAsmJSCall(ins); + return true; +} + bool CodeGeneratorX64::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins) { diff --git a/js/src/jit/x64/CodeGenerator-x64.h b/js/src/jit/x64/CodeGenerator-x64.h index 9b80c96e02d..b24cc823b92 100644 --- a/js/src/jit/x64/CodeGenerator-x64.h +++ b/js/src/jit/x64/CodeGenerator-x64.h @@ -41,6 +41,7 @@ class CodeGeneratorX64 : public CodeGeneratorX86Shared bool visitTruncateFToInt32(LTruncateFToInt32 *ins); bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins); + bool visitAsmJSCall(LAsmJSCall *ins); bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins); bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins); bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins); @@ -49,8 +50,6 @@ class CodeGeneratorX64 : public CodeGeneratorX86Shared bool visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins); bool visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir); bool visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir); - - void postAsmJSCall(LAsmJSCall *lir) {} }; typedef CodeGeneratorX64 CodeGeneratorSpecific; diff --git a/js/src/jit/x86/CodeGenerator-x86.cpp b/js/src/jit/x86/CodeGenerator-x86.cpp index fe6930adacc..9cf75d92209 100644 --- a/js/src/jit/x86/CodeGenerator-x86.cpp +++ b/js/src/jit/x86/CodeGenerator-x86.cpp @@ -331,6 +331,33 @@ CodeGeneratorX86::visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic return true; } +bool +CodeGeneratorX86::visitAsmJSCall(LAsmJSCall *ins) +{ + MAsmJSCall *mir = ins->mir(); + + emitAsmJSCall(ins); + + if (IsFloatingPointType(mir->type()) && mir->callee().which() == MAsmJSCall::Callee::Builtin) { + if (mir->type() == MIRType_Float32) { + masm.reserveStack(sizeof(float)); + Operand op(esp, 0); + masm.fstp32(op); + masm.loadFloat32(op, ReturnFloat32Reg); + masm.freeStack(sizeof(float)); + } else { + JS_ASSERT(mir->type() == MIRType_Double); + masm.reserveStack(sizeof(double)); + Operand op(esp, 0); + masm.fstp(op); + masm.loadDouble(op, ReturnDoubleReg); + masm.freeStack(sizeof(double)); + } + } + + return true; +} + bool CodeGeneratorX86::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins) { @@ -547,28 +574,6 @@ CodeGeneratorX86::visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins) return true; } -void -CodeGeneratorX86::postAsmJSCall(LAsmJSCall *lir) -{ - MAsmJSCall *mir = lir->mir(); - if (!IsFloatingPointType(mir->type()) || mir->callee().which() != MAsmJSCall::Callee::Builtin) - return; - - if (mir->type() == MIRType_Float32) { - masm.reserveStack(sizeof(float)); - Operand op(esp, 0); - masm.fstp32(op); - masm.loadFloat32(op, ReturnFloat32Reg); - masm.freeStack(sizeof(float)); - } else { - masm.reserveStack(sizeof(double)); - Operand op(esp, 0); - masm.fstp(op); - masm.loadDouble(op, ReturnDoubleReg); - masm.freeStack(sizeof(double)); - } -} - void DispatchIonCache::initializeAddCacheState(LInstruction *ins, AddCacheState *addState) { diff --git a/js/src/jit/x86/CodeGenerator-x86.h b/js/src/jit/x86/CodeGenerator-x86.h index 4fae88f49e5..f71a3070ca0 100644 --- a/js/src/jit/x86/CodeGenerator-x86.h +++ b/js/src/jit/x86/CodeGenerator-x86.h @@ -58,6 +58,7 @@ class CodeGeneratorX86 : public CodeGeneratorX86Shared bool visitTruncateFToInt32(LTruncateFToInt32 *ins); bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins); + bool visitAsmJSCall(LAsmJSCall *ins); bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins); bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins); bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins); @@ -67,8 +68,6 @@ class CodeGeneratorX86 : public CodeGeneratorX86Shared bool visitOutOfLineTruncate(OutOfLineTruncate *ool); bool visitOutOfLineTruncateFloat32(OutOfLineTruncateFloat32 *ool); - - void postAsmJSCall(LAsmJSCall *lir); }; typedef CodeGeneratorX86 CodeGeneratorSpecific;