|
|
@@ -5972,11 +5972,57 @@ LowererMD::SaveDoubleToVar(IR::RegOpnd * dstOpnd, IR::RegOpnd *opndFloat, IR::In
|
|
|
#else
|
|
|
|
|
|
// s1 = MOVD opndFloat
|
|
|
+ IR::RegOpnd *s1 = IR::RegOpnd::New(TyMachReg, m_func);
|
|
|
+ IR::Instr *movd = IR::Instr::New(Js::OpCode::MOVD, s1, opndFloat, m_func);
|
|
|
+ instrInsert->InsertBefore(movd);
|
|
|
+
|
|
|
+ if (m_func->GetJnFunction()->GetIsAsmjsMode())
|
|
|
+ {
|
|
|
+ // s1 = MOVD src
|
|
|
+ // tmp = NOT s1
|
|
|
+ // tmp = AND tmp, 0x7FF0000000000000ull
|
|
|
+ // test tmp, tmp
|
|
|
+ // je helper
|
|
|
+ // jmp done
|
|
|
+ // helper:
|
|
|
+ // tmp2 = AND s1, 0x000FFFFFFFFFFFFFull
|
|
|
+ // test tmp2, tmp2
|
|
|
+ // je done
|
|
|
+ // s1 = JavascriptNumber::k_Nan
|
|
|
+ // done:
|
|
|
+
|
|
|
+ IR::RegOpnd *tmp = IR::RegOpnd::New(TyMachReg, m_func);
|
|
|
+ IR::Instr * newInstr = IR::Instr::New(Js::OpCode::NOT, tmp, s1, m_func);
|
|
|
+ instrInsert->InsertBefore(newInstr);
|
|
|
+ LowererMD::MakeDstEquSrc1(newInstr);
|
|
|
+
|
|
|
+ newInstr = IR::Instr::New(Js::OpCode::AND, tmp, tmp, IR::AddrOpnd::New((Js::Var)0x7FF0000000000000, IR::AddrOpndKindConstantVar, m_func, true), m_func);
|
|
|
+ instrInsert->InsertBefore(newInstr);
|
|
|
+ LowererMD::Legalize(newInstr);
|
|
|
+
|
|
|
+ IR::LabelInstr* helper = Lowerer::InsertLabel(true, instrInsert);
|
|
|
+
|
|
|
+ Lowerer::InsertTestBranch(tmp, tmp, Js::OpCode::BrEq_A, helper, helper);
|
|
|
+
|
|
|
+ IR::LabelInstr* done = Lowerer::InsertLabel(isHelper, instrInsert);
|
|
|
+
|
|
|
+ Lowerer::InsertBranch(Js::OpCode::Br, done, helper);
|
|
|
+
|
|
|
+ IR::RegOpnd *tmp2 = IR::RegOpnd::New(TyMachReg, m_func);
|
|
|
+
|
|
|
+ newInstr = IR::Instr::New(Js::OpCode::AND, tmp2, s1, IR::AddrOpnd::New((Js::Var)0x000FFFFFFFFFFFFFull, IR::AddrOpndKindConstantVar, m_func, true), m_func);
|
|
|
+ done->InsertBefore(newInstr);
|
|
|
+ LowererMD::Legalize(newInstr);
|
|
|
+
|
|
|
+ Lowerer::InsertTestBranch(tmp2, tmp2, Js::OpCode::BrEq_A, done, done);
|
|
|
+
|
|
|
+ IR::Opnd * opndNaN = IR::AddrOpnd::New((Js::Var)Js::JavascriptNumber::k_Nan, IR::AddrOpndKindConstantVar, m_func, true);
|
|
|
+ Lowerer::InsertMove(s1, opndNaN, done);
|
|
|
+ }
|
|
|
+
|
|
|
// s1 = XOR s1, FloatTag_Value
|
|
|
// dst = s1
|
|
|
-
|
|
|
- IR::RegOpnd *s1 = IR::RegOpnd::New(TyMachReg, this->m_func);
|
|
|
- IR::Instr *movd = IR::Instr::New(Js::OpCode::MOVD, s1, opndFloat, this->m_func);
|
|
|
+
|
|
|
IR::Instr *setTag = IR::Instr::New(Js::OpCode::XOR,
|
|
|
s1,
|
|
|
s1,
|
|
|
@@ -5987,7 +6033,6 @@ LowererMD::SaveDoubleToVar(IR::RegOpnd * dstOpnd, IR::RegOpnd *opndFloat, IR::In
|
|
|
this->m_func);
|
|
|
IR::Instr *movDst = IR::Instr::New(Js::OpCode::MOV, dstOpnd, s1, this->m_func);
|
|
|
|
|
|
- instrInsert->InsertBefore(movd);
|
|
|
instrInsert->InsertBefore(setTag);
|
|
|
instrInsert->InsertBefore(movDst);
|
|
|
LowererMD::Legalize(setTag);
|
|
|
@@ -7705,6 +7750,11 @@ LowererMD::InsertConvertFloat64ToInt32(const RoundMode roundMode, IR::Opnd *cons
|
|
|
void
|
|
|
LowererMD::EmitFloatToInt(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert)
|
|
|
{
|
|
|
+#ifdef _M_IX86
|
|
|
+ // We should only generate this if sse2 is available
|
|
|
+ Assert(AutoSystemInfo::Data.SSE2Available());
|
|
|
+#endif
|
|
|
+
|
|
|
IR::LabelInstr *labelDone = IR::LabelInstr::New(Js::OpCode::Label, this->m_func);
|
|
|
IR::LabelInstr *labelHelper = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, true);
|
|
|
IR::Instr *instr;
|
|
|
@@ -7714,37 +7764,20 @@ LowererMD::EmitFloatToInt(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert)
|
|
|
// $Helper
|
|
|
instrInsert->InsertBefore(labelHelper);
|
|
|
|
|
|
-#ifdef _M_X64
|
|
|
- // On x64, we can simply pass the var, this way we don't have to worry having to
|
|
|
- // pass a double in a param reg
|
|
|
-
|
|
|
- // s1 = MOVD src
|
|
|
- IR::RegOpnd *s1 = IR::RegOpnd::New(TyMachReg, this->m_func);
|
|
|
- instr = IR::Instr::New(Js::OpCode::MOVD, s1, src, this->m_func);
|
|
|
- instrInsert->InsertBefore(instr);
|
|
|
-
|
|
|
- // s1 = XOR s1, FloatTag_Value
|
|
|
- instr = IR::Instr::New(Js::OpCode::XOR, s1, s1,
|
|
|
- IR::AddrOpnd::New((Js::Var)Js::FloatTag_Value, IR::AddrOpndKindConstantVar, this->m_func, /* dontEncode = */ true),
|
|
|
- this->m_func);
|
|
|
- instrInsert->InsertBefore(instr);
|
|
|
- LowererMD::Legalize(instr);
|
|
|
-
|
|
|
- // dst = ToInt32_Full(s1, scriptContext);
|
|
|
- m_lowerer->LoadScriptContext(instrInsert);
|
|
|
- LoadHelperArgument(instrInsert, s1);
|
|
|
+ IR::Opnd * arg = src;
|
|
|
+ if (src->IsFloat32())
|
|
|
+ {
|
|
|
+ arg = IR::RegOpnd::New(TyFloat64, m_func);
|
|
|
|
|
|
- instr = IR::Instr::New(Js::OpCode::CALL, dst, this->m_func);
|
|
|
- instrInsert->InsertBefore(instr);
|
|
|
- this->ChangeToHelperCall(instr, IR::HelperConv_ToInt32_Full);
|
|
|
-#else
|
|
|
+ EmitFloat32ToFloat64(arg, src, instrInsert);
|
|
|
+ }
|
|
|
// dst = ToInt32Core(src);
|
|
|
- LoadDoubleHelperArgument(instrInsert, src);
|
|
|
+ LoadDoubleHelperArgument(instrInsert, arg);
|
|
|
|
|
|
instr = IR::Instr::New(Js::OpCode::CALL, dst, this->m_func);
|
|
|
instrInsert->InsertBefore(instr);
|
|
|
this->ChangeToHelperCall(instr, IR::HelperConv_ToInt32Core);
|
|
|
-#endif
|
|
|
+
|
|
|
// $Done
|
|
|
instrInsert->InsertBefore(labelDone);
|
|
|
}
|
|
|
@@ -9018,28 +9051,11 @@ IR::Opnd* LowererMD::IsOpndNegZero(IR::Opnd* opnd, IR::Instr* instr)
|
|
|
{
|
|
|
IR::Opnd * isNegZero = IR::RegOpnd::New(TyInt32, this->m_func);
|
|
|
|
|
|
-#if defined(_M_IX86)
|
|
|
LoadDoubleHelperArgument(instr, opnd);
|
|
|
IR::Instr * helperCallInstr = IR::Instr::New(Js::OpCode::CALL, isNegZero, this->m_func);
|
|
|
instr->InsertBefore(helperCallInstr);
|
|
|
this->ChangeToHelperCall(helperCallInstr, IR::HelperIsNegZero);
|
|
|
|
|
|
-#else
|
|
|
- IR::RegOpnd* regXMM0 = IR::RegOpnd::New(nullptr, (RegNum)FIRST_FLOAT_ARG_REG, TyMachDouble, this->m_func);
|
|
|
- regXMM0->m_isCallArg = true;
|
|
|
- IR::Instr * movInstr = IR::Instr::New(Js::OpCode::MOVSD, regXMM0, opnd, this->m_func);
|
|
|
- instr->InsertBefore(movInstr);
|
|
|
-
|
|
|
- IR::RegOpnd* reg1 = IR::RegOpnd::New(TyMachReg, this->m_func);
|
|
|
- IR::AddrOpnd* helperAddr = IR::AddrOpnd::New((Js::Var)IR::GetMethodOriginalAddress(IR::HelperIsNegZero), IR::AddrOpndKind::AddrOpndKindDynamicMisc, this->m_func);
|
|
|
- IR::Instr* mov = IR::Instr::New(Js::OpCode::MOV, reg1, helperAddr, this->m_func);
|
|
|
- instr->InsertBefore(mov);
|
|
|
-
|
|
|
- IR::Instr *helperCallInstr = IR::Instr::New(Js::OpCode::CALL, isNegZero, reg1, this->m_func);
|
|
|
- instr->InsertBefore(helperCallInstr);
|
|
|
-
|
|
|
-#endif
|
|
|
-
|
|
|
return isNegZero;
|
|
|
}
|
|
|
|