mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 858022 - Fix baseline compiler crashes on hardware without SSE2. r=dvander
This commit is contained in:
parent
210f563736
commit
03dc58891f
@ -14,5 +14,9 @@
|
||||
using namespace JSC;
|
||||
MacroAssemblerX86Common::SSECheckState MacroAssemblerX86Common::s_sseCheckState = NotCheckedSSE;
|
||||
|
||||
#ifdef DEBUG
|
||||
bool MacroAssemblerX86Common::s_floatingPointDisabled = false;
|
||||
#endif
|
||||
|
||||
#endif /* WTF_CPU_X86 || WTF_CPU_X86_64 */
|
||||
|
||||
|
@ -1374,6 +1374,15 @@ private:
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if (s_floatingPointDisabled) {
|
||||
// Disable SSE2.
|
||||
s_sseCheckState = HasSSE;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const int SSEFeatureBit = 1 << 25;
|
||||
static const int SSE2FeatureBit = 1 << 26;
|
||||
static const int SSE3FeatureBit = 1 << 0;
|
||||
@ -1407,6 +1416,10 @@ private:
|
||||
|
||||
static bool isSSE2Present()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (s_floatingPointDisabled)
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1489,6 +1502,15 @@ private:
|
||||
|
||||
return s_sseCheckState >= HasSSE4_2;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static bool s_floatingPointDisabled;
|
||||
|
||||
public:
|
||||
static void SetFloatingPointDisabled() {
|
||||
s_floatingPointDisabled = true;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
@ -1662,6 +1662,9 @@ DoCompareFallback(JSContext *cx, BaselineFrame *frame, ICCompare_Fallback *stub,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!cx->runtime->jitSupportsFloatingPoint && (lhs.isNumber() || rhs.isNumber()))
|
||||
return true;
|
||||
|
||||
if (lhs.isNumber() && rhs.isNumber()) {
|
||||
IonSpew(IonSpew_BaselineIC, " Generating %s(Number, Number) stub", js_CodeName[op]);
|
||||
|
||||
@ -2070,7 +2073,7 @@ DoToBoolFallback(JSContext *cx, BaselineFrame *frame, ICToBool_Fallback *stub, H
|
||||
return true;
|
||||
}
|
||||
|
||||
if (arg.isDouble()) {
|
||||
if (arg.isDouble() && cx->runtime->jitSupportsFloatingPoint) {
|
||||
IonSpew(IonSpew_BaselineIC, " Generating ToBool(Double) stub.");
|
||||
ICToBool_Double::Compiler compiler(cx);
|
||||
ICStub *doubleStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
@ -2456,6 +2459,9 @@ DoBinaryArithFallback(JSContext *cx, BaselineFrame *frame, ICBinaryArith_Fallbac
|
||||
JS_ASSERT(ret.isNumber());
|
||||
|
||||
if (lhs.isDouble() || rhs.isDouble() || ret.isDouble()) {
|
||||
if (!cx->runtime->jitSupportsFloatingPoint)
|
||||
return true;
|
||||
|
||||
switch (op) {
|
||||
case JSOP_ADD:
|
||||
case JSOP_SUB:
|
||||
@ -2912,7 +2918,10 @@ DoUnaryArithFallback(JSContext *cx, BaselineFrame *frame, ICUnaryArith_Fallback
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val.isNumber() && res.isNumber() && op == JSOP_NEG) {
|
||||
if (val.isNumber() && res.isNumber() &&
|
||||
op == JSOP_NEG &&
|
||||
cx->runtime->jitSupportsFloatingPoint)
|
||||
{
|
||||
IonSpew(IonSpew_BaselineIC, " Generating %s(Number => Number) stub", js_CodeName[op]);
|
||||
// Unlink int32 stubs, the double stub handles both cases and TI specializes for both.
|
||||
stub->unlinkStubsWithKind(cx, ICStub::UnaryArith_Int32);
|
||||
@ -3255,6 +3264,15 @@ static bool TryAttachNativeGetElemStub(JSContext *cx, HandleScript script,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
TypedArrayRequiresFloatingPoint(JSObject *obj)
|
||||
{
|
||||
uint32_t type = TypedArray::type(obj);
|
||||
return (type == TypedArray::TYPE_UINT32 ||
|
||||
type == TypedArray::TYPE_FLOAT32 ||
|
||||
type == TypedArray::TYPE_FLOAT64);
|
||||
}
|
||||
|
||||
static bool
|
||||
TryAttachGetElemStub(JSContext *cx, HandleScript script, ICGetElem_Fallback *stub,
|
||||
HandleValue lhs, HandleValue rhs, HandleValue res)
|
||||
@ -3303,6 +3321,9 @@ TryAttachGetElemStub(JSContext *cx, HandleScript script, ICGetElem_Fallback *stu
|
||||
if (obj->isTypedArray() && rhs.isInt32() && res.isNumber() &&
|
||||
!TypedArrayGetElemStubExists(stub, obj))
|
||||
{
|
||||
if (!cx->runtime->jitSupportsFloatingPoint && TypedArrayRequiresFloatingPoint(obj))
|
||||
return true;
|
||||
|
||||
IonSpew(IonSpew_BaselineIC, " Generating GetElem(TypedArray[Int32]) stub");
|
||||
ICGetElem_TypedArray::Compiler compiler(cx, obj->lastProperty(), TypedArray::type(obj));
|
||||
ICStub *typedArrayStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
@ -3828,6 +3849,9 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
|
||||
}
|
||||
|
||||
if (obj->isTypedArray() && index.isInt32() && rhs.isNumber()) {
|
||||
if (!cx->runtime->jitSupportsFloatingPoint && TypedArrayRequiresFloatingPoint(obj))
|
||||
return true;
|
||||
|
||||
uint32_t len = TypedArray::length(obj);
|
||||
int32_t idx = index.toInt32();
|
||||
bool expectOutOfBounds = (idx < 0) || (static_cast<uint32_t>(idx) >= len);
|
||||
@ -3980,9 +4004,14 @@ ICSetElem_Dense::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.storeValue(R0, element);
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
// Convert to double and jump back.
|
||||
// Convert to double and jump back. Note that double arrays are only
|
||||
// created by IonMonkey, so if we have no floating-point support
|
||||
// Ion is disabled and there should be no double arrays.
|
||||
masm.bind(&convertDoubles);
|
||||
if (cx->runtime->jitSupportsFloatingPoint)
|
||||
masm.convertInt32ValueToDouble(valueAddr, R0.scratchReg(), &convertDoublesDone);
|
||||
else
|
||||
masm.breakpoint();
|
||||
masm.jump(&convertDoublesDone);
|
||||
|
||||
// Failure case - fail but first unstow R0 and R1
|
||||
@ -4143,9 +4172,14 @@ ICSetElemDenseAddCompiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.storeValue(R0, element);
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
// Convert to double and jump back.
|
||||
// Convert to double and jump back. Note that double arrays are only
|
||||
// created by IonMonkey, so if we have no floating-point support
|
||||
// Ion is disabled and there should be no double arrays.
|
||||
masm.bind(&convertDoubles);
|
||||
if (cx->runtime->jitSupportsFloatingPoint)
|
||||
masm.convertInt32ValueToDouble(valueAddr, R0.scratchReg(), &convertDoublesDone);
|
||||
else
|
||||
masm.breakpoint();
|
||||
masm.jump(&convertDoublesDone);
|
||||
|
||||
// Failure case - fail but first unstow R0 and R1
|
||||
@ -4218,10 +4252,14 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
// If the value is a double, clamp to uint8 and jump back.
|
||||
// Else, jump to failure.
|
||||
masm.bind(¬Int32);
|
||||
if (cx->runtime->jitSupportsFloatingPoint) {
|
||||
masm.branchTestDouble(Assembler::NotEqual, value, &failure);
|
||||
masm.unboxDouble(value, FloatReg0);
|
||||
masm.clampDoubleToUint8(FloatReg0, secondScratch);
|
||||
masm.jump(&clamped);
|
||||
} else {
|
||||
masm.jump(&failure);
|
||||
}
|
||||
} else {
|
||||
Label notInt32;
|
||||
masm.branchTestInt32(Assembler::NotEqual, value, ¬Int32);
|
||||
@ -4236,10 +4274,14 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
// Else, jump to failure.
|
||||
Label failureRestoreRegs;
|
||||
masm.bind(¬Int32);
|
||||
if (cx->runtime->jitSupportsFloatingPoint) {
|
||||
masm.branchTestDouble(Assembler::NotEqual, value, &failure);
|
||||
masm.unboxDouble(value, FloatReg0);
|
||||
masm.branchTruncateDouble(FloatReg0, secondScratch, &failureRestoreRegs);
|
||||
masm.jump(&isInt32);
|
||||
} else {
|
||||
masm.jump(&failure);
|
||||
}
|
||||
|
||||
// Writing to secondScratch may have clobbered R0 or R1, restore them
|
||||
// first.
|
||||
@ -6511,6 +6553,18 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
DoubleValueToInt32ForSwitch(Value *v)
|
||||
{
|
||||
double d = v->toDouble();
|
||||
int32_t truncated = int32_t(d);
|
||||
if (d != double(truncated))
|
||||
return false;
|
||||
|
||||
v->setInt32(truncated);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ICTableSwitch::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
@ -6537,10 +6591,27 @@ ICTableSwitch::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.bind(¬Int32);
|
||||
|
||||
masm.branchTestDouble(Assembler::NotEqual, R0, &outOfRange);
|
||||
if (cx->runtime->jitSupportsFloatingPoint) {
|
||||
masm.unboxDouble(R0, FloatReg0);
|
||||
|
||||
// N.B. -0 === 0, so convert -0 to a 0 int32.
|
||||
masm.convertDoubleToInt32(FloatReg0, key, &outOfRange, /* negativeZeroCheck = */ false);
|
||||
} else {
|
||||
// Pass pointer to double value.
|
||||
masm.pushValue(R0);
|
||||
masm.movePtr(StackPointer, R0.scratchReg());
|
||||
|
||||
masm.setupUnalignedABICall(1, scratch);
|
||||
masm.passABIArg(R0.scratchReg());
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, DoubleValueToInt32ForSwitch));
|
||||
|
||||
// If the function returns |true|, the value has been converted to
|
||||
// int32.
|
||||
masm.mov(ReturnReg, scratch);
|
||||
masm.popValue(R0);
|
||||
masm.branchTest32(Assembler::Zero, scratch, scratch, &outOfRange);
|
||||
masm.unboxInt32(R0, key);
|
||||
}
|
||||
masm.jump(&isInt32);
|
||||
|
||||
masm.bind(&outOfRange);
|
||||
|
@ -249,7 +249,8 @@ struct BaselineScript
|
||||
}
|
||||
};
|
||||
|
||||
inline bool IsBaselineEnabled(JSContext *cx)
|
||||
inline bool
|
||||
IsBaselineEnabled(JSContext *cx)
|
||||
{
|
||||
return cx->hasOption(JSOPTION_BASELINE);
|
||||
}
|
||||
|
@ -198,6 +198,8 @@ IonRuntime::initialize(JSContext *cx)
|
||||
if (!functionWrappers_ || !functionWrappers_->init())
|
||||
return false;
|
||||
|
||||
if (cx->runtime->jitSupportsFloatingPoint) {
|
||||
// Initialize some Ion-only stubs that require floating-point support.
|
||||
if (!bailoutTables_.reserve(FrameSizeClass::ClassLimit().classId()))
|
||||
return false;
|
||||
|
||||
@ -215,6 +217,11 @@ IonRuntime::initialize(JSContext *cx)
|
||||
if (!bailoutHandler_)
|
||||
return false;
|
||||
|
||||
invalidator_ = generateInvalidator(cx);
|
||||
if (!invalidator_)
|
||||
return false;
|
||||
}
|
||||
|
||||
argumentsRectifier_ = generateArgumentsRectifier(cx, SequentialExecution, &argumentsRectifierReturnAddr_);
|
||||
if (!argumentsRectifier_)
|
||||
return false;
|
||||
@ -225,10 +232,6 @@ IonRuntime::initialize(JSContext *cx)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
invalidator_ = generateInvalidator(cx);
|
||||
if (!invalidator_)
|
||||
return false;
|
||||
|
||||
enterJIT_ = generateEnterJIT(cx, EnterJitOptimized);
|
||||
if (!enterJIT_)
|
||||
return false;
|
||||
|
@ -278,9 +278,11 @@ class AssemblerX86Shared
|
||||
}
|
||||
|
||||
void movsd(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.movsd_rr(src.code(), dest.code());
|
||||
}
|
||||
void movsd(const Operand &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::FPREG:
|
||||
masm.movsd_rr(src.fpu(), dest.code());
|
||||
@ -296,6 +298,7 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void movsd(const FloatRegister &src, const Operand &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (dest.kind()) {
|
||||
case Operand::FPREG:
|
||||
masm.movsd_rr(src.code(), dest.fpu());
|
||||
@ -311,6 +314,7 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void movss(const Operand &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::REG_DISP:
|
||||
masm.movss_mr(src.disp(), src.base(), dest.code());
|
||||
@ -323,6 +327,7 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void movss(const FloatRegister &src, const Operand &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (dest.kind()) {
|
||||
case Operand::REG_DISP:
|
||||
masm.movss_rm(src.code(), dest.disp(), dest.base());
|
||||
@ -335,6 +340,7 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void movdqa(const Operand &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::REG_DISP:
|
||||
masm.movdqa_mr(src.disp(), src.base(), dest.code());
|
||||
@ -347,6 +353,7 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void movdqa(const FloatRegister &src, const Operand &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (dest.kind()) {
|
||||
case Operand::REG_DISP:
|
||||
masm.movdqa_rm(src.code(), dest.disp(), dest.base());
|
||||
@ -359,9 +366,11 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void cvtss2sd(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.cvtss2sd_rr(src.code(), dest.code());
|
||||
}
|
||||
void cvtsd2ss(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.cvtsd2ss_rr(src.code(), dest.code());
|
||||
}
|
||||
void movzbl(const Operand &src, const Register &dest) {
|
||||
@ -655,6 +664,9 @@ class AssemblerX86Shared
|
||||
masm.int3();
|
||||
}
|
||||
|
||||
static bool HasSSE2() {
|
||||
return JSC::MacroAssembler::getSSEState() >= JSC::MacroAssembler::HasSSE2;
|
||||
}
|
||||
static bool HasSSE41() {
|
||||
return JSC::MacroAssembler::getSSEState() >= JSC::MacroAssembler::HasSSE4_1;
|
||||
}
|
||||
@ -1052,12 +1064,15 @@ class AssemblerX86Shared
|
||||
}
|
||||
|
||||
void unpcklps(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.unpcklps_rr(src.code(), dest.code());
|
||||
}
|
||||
void pinsrd(const Register &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.pinsrd_rr(src.code(), dest.code());
|
||||
}
|
||||
void pinsrd(const Operand &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::REG:
|
||||
masm.pinsrd_rr(src.reg(), dest.code());
|
||||
@ -1070,16 +1085,20 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void psrldq(Imm32 shift, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.psrldq_rr(dest.code(), shift.value);
|
||||
}
|
||||
void psllq(Imm32 shift, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.psllq_rr(dest.code(), shift.value);
|
||||
}
|
||||
void psrlq(Imm32 shift, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.psrlq_rr(dest.code(), shift.value);
|
||||
}
|
||||
|
||||
void cvtsi2sd(const Operand &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::REG:
|
||||
masm.cvtsi2sd_rr(src.reg(), dest.code());
|
||||
@ -1095,12 +1114,15 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void cvttsd2si(const FloatRegister &src, const Register &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.cvttsd2si_rr(src.code(), dest.code());
|
||||
}
|
||||
void cvtsi2sd(const Register &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.cvtsi2sd_rr(src.code(), dest.code());
|
||||
}
|
||||
void movmskpd(const FloatRegister &src, const Register &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.movmskpd_rr(src.code(), dest.code());
|
||||
}
|
||||
void ptest(const FloatRegister &lhs, const FloatRegister &rhs) {
|
||||
@ -1108,21 +1130,27 @@ class AssemblerX86Shared
|
||||
masm.ptest_rr(rhs.code(), lhs.code());
|
||||
}
|
||||
void ucomisd(const FloatRegister &lhs, const FloatRegister &rhs) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.ucomisd_rr(rhs.code(), lhs.code());
|
||||
}
|
||||
void pcmpeqw(const FloatRegister &lhs, const FloatRegister &rhs) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.pcmpeqw_rr(rhs.code(), lhs.code());
|
||||
}
|
||||
void movd(const Register &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.movd_rr(src.code(), dest.code());
|
||||
}
|
||||
void movd(const FloatRegister &src, const Register &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.movd_rr(src.code(), dest.code());
|
||||
}
|
||||
void addsd(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.addsd_rr(src.code(), dest.code());
|
||||
}
|
||||
void addsd(const Operand &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::FPREG:
|
||||
masm.addsd_rr(src.fpu(), dest.code());
|
||||
@ -1140,9 +1168,11 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void subsd(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.subsd_rr(src.code(), dest.code());
|
||||
}
|
||||
void subsd(const Operand &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::FPREG:
|
||||
masm.subsd_rr(src.fpu(), dest.code());
|
||||
@ -1155,9 +1185,11 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void mulsd(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.mulsd_rr(src.code(), dest.code());
|
||||
}
|
||||
void mulsd(const Operand &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::FPREG:
|
||||
masm.mulsd_rr(src.fpu(), dest.code());
|
||||
@ -1170,9 +1202,11 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void divsd(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.divsd_rr(src.code(), dest.code());
|
||||
}
|
||||
void divsd(const Operand &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
switch (src.kind()) {
|
||||
case Operand::FPREG:
|
||||
masm.divsd_rr(src.fpu(), dest.code());
|
||||
@ -1185,20 +1219,25 @@ class AssemblerX86Shared
|
||||
}
|
||||
}
|
||||
void xorpd(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.xorpd_rr(src.code(), dest.code());
|
||||
}
|
||||
void orpd(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.orpd_rr(src.code(), dest.code());
|
||||
}
|
||||
void andpd(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.andpd_rr(src.code(), dest.code());
|
||||
}
|
||||
void sqrtsd(const FloatRegister &src, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.sqrtsd_rr(src.code(), dest.code());
|
||||
}
|
||||
void roundsd(const FloatRegister &src, const FloatRegister &dest,
|
||||
JSC::X86Assembler::RoundingMode mode)
|
||||
{
|
||||
JS_ASSERT(HasSSE41());
|
||||
masm.roundsd_rr(src.code(), dest.code(), mode);
|
||||
}
|
||||
void fstp(const Operand &src) {
|
||||
|
@ -432,6 +432,7 @@ class Assembler : public AssemblerX86Shared
|
||||
}
|
||||
|
||||
void movsd(const double *dp, const FloatRegister &dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.movsd_mr((const void *)dp, dest.code());
|
||||
}
|
||||
|
||||
@ -448,6 +449,7 @@ class Assembler : public AssemblerX86Shared
|
||||
return masm.currentOffset();
|
||||
}
|
||||
CodeOffsetLabel movsdWithPatch(void *addr, FloatRegister dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.movsd_mr(addr, dest.code());
|
||||
return masm.currentOffset();
|
||||
}
|
||||
@ -458,6 +460,7 @@ class Assembler : public AssemblerX86Shared
|
||||
return masm.currentOffset();
|
||||
}
|
||||
CodeOffsetLabel movsdWithPatch(FloatRegister dest, void *addr) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.movsd_rm(dest.code(), addr);
|
||||
return masm.currentOffset();
|
||||
}
|
||||
@ -484,10 +487,12 @@ class Assembler : public AssemblerX86Shared
|
||||
return masm.currentOffset();
|
||||
}
|
||||
CodeOffsetLabel movssWithPatch(Address src, FloatRegister dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.movss_mr_disp32(src.offset, src.base.code(), dest.code());
|
||||
return masm.currentOffset();
|
||||
}
|
||||
CodeOffsetLabel movsdWithPatch(Address src, FloatRegister dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.movsd_mr_disp32(src.offset, src.base.code(), dest.code());
|
||||
return masm.currentOffset();
|
||||
}
|
||||
@ -506,10 +511,12 @@ class Assembler : public AssemblerX86Shared
|
||||
return masm.currentOffset();
|
||||
}
|
||||
CodeOffsetLabel movssWithPatch(FloatRegister src, Address dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.movss_rm_disp32(src.code(), dest.offset, dest.base.code());
|
||||
return masm.currentOffset();
|
||||
}
|
||||
CodeOffsetLabel movsdWithPatch(FloatRegister src, Address dest) {
|
||||
JS_ASSERT(HasSSE2());
|
||||
masm.movsd_rm_disp32(src.code(), dest.offset, dest.base.code());
|
||||
return masm.currentOffset();
|
||||
}
|
||||
|
@ -665,8 +665,14 @@ IonRuntime::generatePreBarrier(JSContext *cx, MIRType type)
|
||||
{
|
||||
MacroAssembler masm;
|
||||
|
||||
RegisterSet save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
RegisterSet save;
|
||||
if (cx->runtime->jitSupportsFloatingPoint) {
|
||||
save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet(FloatRegisters::VolatileMask));
|
||||
} else {
|
||||
save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet());
|
||||
}
|
||||
masm.PushRegsInMask(save);
|
||||
|
||||
JS_ASSERT(PreBarrierReg == edx);
|
||||
|
@ -147,7 +147,7 @@ def main(argv):
|
||||
['--no-baseline'],
|
||||
['--no-baseline', '--ion-eager'],
|
||||
['--baseline-eager'],
|
||||
['--baseline-eager', '--no-ti'],
|
||||
['--baseline-eager', '--no-ti', '--no-fpu'],
|
||||
# Below, equivalents the old shell flags: ,m,am,amd,n,mn,amn,amdn,mdn
|
||||
['--no-baseline', '--no-ion', '--no-jm', '--no-ti'],
|
||||
['--no-baseline', '--no-ion', '--no-ti'],
|
||||
|
@ -46,4 +46,4 @@ var rec = asmLink(asmCompile(USE_ASM+"function rec(i) { i=i|0; if (!i) return 0;
|
||||
assertEq(rec(100), 100);
|
||||
assertEq(rec(1000), 1000);
|
||||
assertThrowsInstanceOf(function() rec(100000000000), InternalError);
|
||||
assertEq(rec(10000), 10000);
|
||||
assertEq(rec(2000), 2000);
|
||||
|
@ -686,6 +686,24 @@ JS_FRIEND_API(bool) JS::isGCEnabled() { return true; }
|
||||
|
||||
static const JSSecurityCallbacks NullSecurityCallbacks = { };
|
||||
|
||||
static bool
|
||||
JitSupportsFloatingPoint()
|
||||
{
|
||||
#if defined(JS_METHODJIT) || defined(JS_ION)
|
||||
if (!JSC::MacroAssembler().supportsFloatingPoint())
|
||||
return false;
|
||||
|
||||
#if defined(JS_ION) && WTF_ARM_ARCH_VERSION == 6
|
||||
if (!js::ion::hasVFP())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
PerThreadData::PerThreadData(JSRuntime *runtime)
|
||||
: PerThreadDataFriendFields(),
|
||||
runtime_(runtime),
|
||||
@ -893,6 +911,7 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
|
||||
noGCOrAllocationCheck(0),
|
||||
#endif
|
||||
jitHardening(false),
|
||||
jitSupportsFloatingPoint(false),
|
||||
ionPcScriptCache(NULL),
|
||||
threadPool(this),
|
||||
ctypesActivityCallback(NULL),
|
||||
@ -990,6 +1009,8 @@ JSRuntime::init(uint32_t maxbytes)
|
||||
return false;
|
||||
|
||||
nativeStackBase = GetNativeStackBase();
|
||||
|
||||
jitSupportsFloatingPoint = JitSupportsFloatingPoint();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1304,6 +1304,8 @@ struct JSRuntime : private JS::shadow::Runtime,
|
||||
|
||||
bool jitHardening;
|
||||
|
||||
bool jitSupportsFloatingPoint;
|
||||
|
||||
// Used to reset stack limit after a signaled interrupt (i.e. ionStackLimit_ = -1)
|
||||
// has been noticed by Ion/Baseline.
|
||||
void resetIonStackLimit() {
|
||||
|
@ -2382,31 +2382,6 @@ class TypeConstraintFreezeStack : public TypeConstraint
|
||||
// TypeCompartment
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline bool
|
||||
TypeInferenceSupported()
|
||||
{
|
||||
#ifdef JS_METHODJIT
|
||||
// JM+TI will generate FPU instructions with TI enabled. As a workaround,
|
||||
// we disable TI to prevent this on platforms which do not have FPU
|
||||
// support.
|
||||
JSC::MacroAssembler masm;
|
||||
if (!masm.supportsFloatingPoint())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if WTF_ARM_ARCH_VERSION == 6
|
||||
#ifdef JS_ION
|
||||
return js::ion::hasVFP();
|
||||
#else
|
||||
// If building for ARMv6 targets, we can't be guaranteed an FPU,
|
||||
// so we hardcode TI off for consistency (see bug 793740).
|
||||
return false;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TypeCompartment::TypeCompartment()
|
||||
{
|
||||
PodZero(this);
|
||||
@ -2418,7 +2393,7 @@ TypeZone::init(JSContext *cx)
|
||||
{
|
||||
if (!cx ||
|
||||
!cx->hasOption(JSOPTION_TYPE_INFERENCE) ||
|
||||
!TypeInferenceSupported())
|
||||
!cx->runtime->jitSupportsFloatingPoint)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -5295,6 +5295,8 @@ main(int argc, char **argv, char **envp)
|
||||
|| !op.addIntOption('\0', "baseline-uses-before-compile", "COUNT",
|
||||
"Wait for COUNT calls or iterations before baseline-compiling "
|
||||
"(default: 10)", -1)
|
||||
|| !op.addBoolOption('\0', "no-fpu", "Pretend CPU does not support floating-point operations "
|
||||
"to test JIT codegen (no-op on platforms other than x86).")
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
|| !op.addBoolOption('\0', "ggc", "Enable Generational GC")
|
||||
#endif
|
||||
@ -5329,6 +5331,11 @@ main(int argc, char **argv, char **envp)
|
||||
OOM_maxAllocations = op.getIntOption('A');
|
||||
if (op.getBoolOption('O'))
|
||||
OOM_printAllocationCount = true;
|
||||
|
||||
#if defined(JS_CPU_X86)
|
||||
if (op.getBoolOption("no-fpu"))
|
||||
JSC::MacroAssembler::SetFloatingPointDisabled();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use the same parameters as the browser in xpcjsruntime.cpp. */
|
||||
|
Loading…
Reference in New Issue
Block a user