Skip to content

Commit

Permalink
add nontrapping float-to-int conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeHolman committed Apr 19, 2018
1 parent 12f6c94 commit 4c0beef
Show file tree
Hide file tree
Showing 25 changed files with 430 additions and 163 deletions.
1 change: 1 addition & 0 deletions lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13884,6 +13884,7 @@ GlobOpt::PreLowerCanonicalize(IR::Instr *instr, Value **pSrc1Val, Value **pSrc2V
case Js::OpCode::TrapIfUnalignedAccess:
case Js::OpCode::FromVar:
case Js::OpCode::Conv_Prim:
case Js::OpCode::Conv_Prim_Sat:
case Js::OpCode::LdC_A_I4:
case Js::OpCode::LdStr:
case Js::OpCode::InitFld:
Expand Down
2 changes: 2 additions & 0 deletions lib/Backend/GlobOptExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ GlobOpt::CSEAddInstr(
break;

case Js::OpCode::Conv_Prim:
case Js::OpCode::Conv_Prim_Sat:
exprAttributes = ConvAttributes(instr->GetDst()->IsUnsigned(), instr->GetSrc1()->IsUnsigned());
break;
}
Expand Down Expand Up @@ -534,6 +535,7 @@ GlobOpt::CSEOptimize(BasicBlock *block, IR::Instr * *const instrRef, Value **pSr
break;

case Js::OpCode::Conv_Prim:
case Js::OpCode::Conv_Prim_Sat:
exprAttributes = ConvAttributes(instr->GetDst()->IsUnsigned(), instr->GetSrc1()->IsUnsigned());
break;

Expand Down
60 changes: 53 additions & 7 deletions lib/Backend/IRBuilderAsmJs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2054,18 +2054,30 @@ IRBuilderAsmJs::BuildInt1Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::R
IR::RegOpnd * srcOpnd = BuildSrcOpnd(srcRegSlot, TyFloat64);
srcOpnd->SetValueType(ValueType::Float);
IR::RegOpnd * dstOpnd = nullptr;
Js::OpCode op = Js::OpCode::Nop;
switch (newOpcode)
{
case Js::OpCodeAsmJs::Conv_DTI:
dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
op = Js::OpCode::Conv_Prim;
break;
case Js::OpCodeAsmJs::Conv_DTU:
dstOpnd = BuildDstOpnd(dstRegSlot, TyUint32);
op = Js::OpCode::Conv_Prim;
break;
case Js::OpCodeAsmJs::Conv_Sat_DTI:
dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
op = Js::OpCode::Conv_Prim_Sat;
break;
case Js::OpCodeAsmJs::Conv_Sat_DTU:
dstOpnd = BuildDstOpnd(dstRegSlot, TyUint32);
op = Js::OpCode::Conv_Prim_Sat;
break;
case Js::OpCodeAsmJs::Conv_Check_DTI:
case Js::OpCodeAsmJs::Conv_Check_DTU:
{
IR::RegOpnd* tmpDst = IR::RegOpnd::New(TyFloat64, m_func);
op = Js::OpCode::Conv_Prim;
tmpDst->SetValueType(ValueType::Float);
AddInstr(IR::Instr::New(Js::OpCode::TrapIfTruncOverflow, tmpDst, srcOpnd, m_func), offset);
dstOpnd = BuildDstOpnd(dstRegSlot, newOpcode == Js::OpCodeAsmJs::Conv_Check_DTI ? TyInt32 : TyUint32);
Expand All @@ -2077,7 +2089,7 @@ IRBuilderAsmJs::BuildInt1Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::R
Assume(UNREACHED);
}
dstOpnd->SetValueType(ValueType::GetInt(false));
IR::Instr * instr = IR::Instr::New(Js::OpCode::Conv_Prim, dstOpnd, srcOpnd, m_func);
IR::Instr * instr = IR::Instr::New(op, dstOpnd, srcOpnd, m_func);
AddInstr(instr, offset);
}

Expand All @@ -2098,6 +2110,14 @@ IRBuilderAsmJs::BuildInt1Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::Re
dstOpnd = BuildDstOpnd(dstRegSlot, TyUint32);
op = Js::OpCode::Conv_Prim;
break;
case Js::OpCodeAsmJs::Conv_Sat_FTI:
dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
op = Js::OpCode::Conv_Prim_Sat;
break;
case Js::OpCodeAsmJs::Conv_Sat_FTU:
dstOpnd = BuildDstOpnd(dstRegSlot, TyUint32);
op = Js::OpCode::Conv_Prim_Sat;
break;
case Js::OpCodeAsmJs::Reinterpret_FTI:
dstOpnd = BuildDstOpnd(dstRegSlot, TyInt32);
op = Js::OpCode::Reinterpret_Prim;
Expand Down Expand Up @@ -3338,25 +3358,43 @@ IRBuilderAsmJs::BuildInt1Long1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::Reg
void
IRBuilderAsmJs::BuildLong1Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstRegSlot, Js::RegSlot src1RegSlot)
{
IR::RegOpnd * src1Opnd = BuildSrcOpnd(src1RegSlot, TyFloat32);
IR::RegOpnd * srcOpnd = BuildSrcOpnd(src1RegSlot, TyFloat32);
IR::RegOpnd * dstOpnd = nullptr;
Js::OpCode op = Js::OpCode::Nop;
bool trapping = false;
switch (newOpcode)
{
case Js::OpCodeAsmJs::Conv_Check_FTL:
dstOpnd = BuildDstOpnd(dstRegSlot, TyInt64);
op = Js::OpCode::Conv_Prim;
trapping = true;
break;
case Js::OpCodeAsmJs::Conv_Check_FTUL:
dstOpnd = BuildDstOpnd(dstRegSlot, TyUint64);
op = Js::OpCode::Conv_Prim;
trapping = true;
break;
case Js::OpCodeAsmJs::Conv_Sat_FTL:
dstOpnd = BuildDstOpnd(dstRegSlot, TyInt64);
op = Js::OpCode::Conv_Prim_Sat;
break;
case Js::OpCodeAsmJs::Conv_Sat_FTUL:
dstOpnd = BuildDstOpnd(dstRegSlot, TyUint64);
op = Js::OpCode::Conv_Prim_Sat;
break;
default:
Assume(UNREACHED);
}

IR::RegOpnd* tmpDst = IR::RegOpnd::New(src1Opnd->GetType(), m_func);
tmpDst->SetValueType(ValueType::Float);
AddInstr(IR::Instr::New(Js::OpCode::TrapIfTruncOverflow, tmpDst, src1Opnd, m_func), offset);
dstOpnd->m_dontDeadStore = true;
IR::Instr * instr = IR::Instr::New(Js::OpCode::Conv_Prim, dstOpnd, tmpDst, m_func);
if (trapping)
{
IR::RegOpnd* tmpDst = IR::RegOpnd::New(srcOpnd->GetType(), m_func);
tmpDst->SetValueType(ValueType::Float);
AddInstr(IR::Instr::New(Js::OpCode::TrapIfTruncOverflow, tmpDst, srcOpnd, m_func), offset);
dstOpnd->m_dontDeadStore = true;
srcOpnd = tmpDst;
}
IR::Instr * instr = IR::Instr::New(op, dstOpnd, srcOpnd, m_func);
AddInstr(instr, offset);
}

Expand Down Expand Up @@ -3401,6 +3439,14 @@ IRBuilderAsmJs::BuildLong1Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::
dstType = TyUint64;
doTruncTrapCheck = true;
break;
case Js::OpCodeAsmJs::Conv_Sat_DTL:
op = Js::OpCode::Conv_Prim_Sat;
dstType = TyInt64;
break;
case Js::OpCodeAsmJs::Conv_Sat_DTUL:
op = Js::OpCode::Conv_Prim_Sat;
dstType = TyUint64;
break;
case Js::OpCodeAsmJs::Reinterpret_DTL:
op = Js::OpCode::Reinterpret_Prim;
dstType = TyInt64;
Expand Down
15 changes: 9 additions & 6 deletions lib/Backend/JnHelperMethodList.h
Original file line number Diff line number Diff line change
Expand Up @@ -547,12 +547,15 @@ HELPERCALL(DirectMath_NearestFlt, (float(*)(float)) Wasm::WasmMath::Nearest<floa
HELPERCALL(PopCnt32, Math::PopCnt32, 0)
HELPERCALL(PopCnt64, (int64(*)(int64)) Wasm::WasmMath::PopCnt<int64>, 0)

#define CONVERSION_HELPER(HELPER_TYPE) HELPERCALL(HELPER_TYPE, Js::JavascriptConversion::##HELPER_TYPE, AttrCanThrow)
CONVERSION_HELPER(F32TOI64)
CONVERSION_HELPER(F32TOU64)
CONVERSION_HELPER(F64TOI64)
CONVERSION_HELPER(F64TOU64)
#undef CONVERSION_HELPER
HELPERCALL(F32ToI64, (int64(*)(float, Js::ScriptContext*)) Wasm::WasmMath::F32ToI64<false /* saturating */>, AttrCanThrow)
HELPERCALL(F32ToU64, (uint64(*)(float, Js::ScriptContext*)) Wasm::WasmMath::F32ToU64<false /* saturating */>, AttrCanThrow)
HELPERCALL(F64ToI64, (int64(*)(double, Js::ScriptContext*)) Wasm::WasmMath::F64ToI64<false /* saturating */>, AttrCanThrow)
HELPERCALL(F64ToU64, (uint64(*)(double, Js::ScriptContext*)) Wasm::WasmMath::F64ToU64<false /* saturating */>, AttrCanThrow)

HELPERCALL(F32ToI64Sat, (int64(*)(float, Js::ScriptContext*)) Wasm::WasmMath::F32ToI64<true /* saturating */>, AttrCanThrow)
HELPERCALL(F32ToU64Sat, (uint64(*)(float, Js::ScriptContext*)) Wasm::WasmMath::F32ToU64<true /* saturating */>, AttrCanThrow)
HELPERCALL(F64ToI64Sat, (int64(*)(double, Js::ScriptContext*)) Wasm::WasmMath::F64ToI64<true /* saturating */>, AttrCanThrow)
HELPERCALL(F64ToU64Sat, (uint64(*)(double, Js::ScriptContext*)) Wasm::WasmMath::F64ToU64<true /* saturating */>, AttrCanThrow)

HELPERCALL(I64TOF64, Js::JavascriptConversion::LongToDouble, 0)
HELPERCALL(UI64TOF64, Js::JavascriptConversion::ULongToDouble, 0)
Expand Down
25 changes: 20 additions & 5 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1914,11 +1914,16 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
Assert(UNREACHED);
}
break;
case Js::OpCode::Conv_Prim_Sat:
{
GenerateTruncWithCheck<true /* Saturate */>(instr);
break;
}
case Js::OpCode::Conv_Prim:
{
if (IR::Instr::FindSingleDefInstr(Js::OpCode::TrapIfTruncOverflow, instr->GetSrc1()))
{
GenerateTruncWithCheck(instr);
GenerateTruncWithCheck<false /* Saturate */>(instr);
break;
}

Expand Down Expand Up @@ -19789,13 +19794,14 @@ IR::RegOpnd * Lowerer::GetRegOpnd(IR::Opnd* opnd, IR::Instr* insertInstr, Func*
return regOpnd;
}

void Lowerer::GenerateTruncWithCheck(IR::Instr* instr)
template <bool Saturate>
void Lowerer::GenerateTruncWithCheck(_In_ IR::Instr* instr)
{

Assert(instr->GetSrc1()->IsFloat());
if (instr->GetDst()->IsInt32() || instr->GetDst()->IsUInt32())
{
m_lowererMD.GenerateTruncWithCheck(instr);
m_lowererMD.GenerateTruncWithCheck<Saturate>(instr);
}
else
{
Expand All @@ -19810,8 +19816,17 @@ void Lowerer::GenerateTruncWithCheck(IR::Instr* instr)
{
m_lowererMD.LoadDoubleHelperArgument(instr, instr->GetSrc1());
}
IR::JnHelperMethod helperList[2][2] = { IR::HelperF32TOI64, IR::HelperF32TOU64, IR::HelperF64TOI64 ,IR::HelperF64TOU64 };
IR::JnHelperMethod helper = helperList[instr->GetSrc1()->GetType() != TyFloat32][instr->GetDst()->GetType() == TyUint64];
IR::JnHelperMethod helper;
if (Saturate)
{
IR::JnHelperMethod helperList[2][2] = { IR::HelperF32ToI64Sat, IR::HelperF32ToU64Sat, IR::HelperF64ToI64Sat ,IR::HelperF64ToU64Sat };
helper = helperList[instr->GetSrc1()->GetType() != TyFloat32][instr->GetDst()->GetType() == TyUint64];
}
else
{
IR::JnHelperMethod helperList[2][2] = { IR::HelperF32ToI64, IR::HelperF32ToU64, IR::HelperF64ToI64 ,IR::HelperF64ToU64 };
helper = helperList[instr->GetSrc1()->GetType() != TyFloat32][instr->GetDst()->GetType() == TyUint64];
}
instr->UnlinkSrc1();
this->m_lowererMD.ChangeToHelperCall(instr, helper);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/Lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ class Lowerer
void GenerateFastInlineMathClz(IR::Instr* instr);
void GenerateCtz(IR::Instr* instr);
void GeneratePopCnt(IR::Instr* instr);
void GenerateTruncWithCheck(IR::Instr* instr);
template <bool Saturate> void GenerateTruncWithCheck(_In_ IR::Instr* instr);
void GenerateFastInlineMathFround(IR::Instr* instr);
void GenerateFastInlineRegExpExec(IR::Instr * instr);
bool GenerateFastPush(IR::Opnd *baseOpndParam, IR::Opnd *src, IR::Instr *callInstr, IR::Instr *insertInstr, IR::LabelInstr *labelHelper, IR::LabelInstr *doneLabel, IR::LabelInstr * bailOutLabelHelper, bool returnLength = false);
Expand Down
59 changes: 48 additions & 11 deletions lib/Backend/LowerMDShared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4722,11 +4722,17 @@ IR::Opnd* LowererMD::Subtract2To31(IR::Opnd* src1, IR::Opnd* intMinFP, IRType ty
return adjSrc;
}

IR::Opnd* LowererMD::GenerateTruncChecks(IR::Instr* instr)
template <bool Saturate>
IR::Opnd*
LowererMD::GenerateTruncChecks(_In_ IR::Instr* instr, _In_opt_ IR::LabelInstr* doneLabel)
{
AnalysisAssert(!Saturate || doneLabel);

IR::LabelInstr * conversion = IR::LabelInstr::New(Js::OpCode::Label, m_func);
IR::LabelInstr * throwLabel = IR::LabelInstr::New(Js::OpCode::Label, m_func, true);
IR::LabelInstr * nanLabel = Saturate ? IR::LabelInstr::New(Js::OpCode::Label, m_func, true) : nullptr;
IR::LabelInstr * oobLabel = IR::LabelInstr::New(Js::OpCode::Label, m_func, true);
IR::Opnd* src1 = instr->GetSrc1();
IR::Opnd* dst = instr->GetDst();

IR::Opnd * src64 = nullptr;
if (src1->IsFloat32())
Expand All @@ -4739,31 +4745,57 @@ IR::Opnd* LowererMD::GenerateTruncChecks(IR::Instr* instr)
src64 = src1;
}

IR::RegOpnd* limitReg = MaterializeDoubleConstFromInt(instr->GetDst()->IsUInt32() ?
IR::RegOpnd* limitReg = MaterializeDoubleConstFromInt(dst->IsUInt32() ?
m_func->GetThreadContextInfo()->GetDoubleNegOneAddr() :
m_func->GetThreadContextInfo()->GetDoubleIntMinMinusOneAddr(), instr);

m_lowerer->InsertCompareBranch(src64, limitReg, Js::OpCode::BrLe_A, throwLabel, instr);
m_lowerer->InsertCompareBranch(src64, limitReg, Js::OpCode::BrLe_A, oobLabel, instr);

limitReg = MaterializeDoubleConstFromInt(instr->GetDst()->IsUInt32() ?
limitReg = MaterializeDoubleConstFromInt(dst->IsUInt32() ?
m_func->GetThreadContextInfo()->GetDoubleUintMaxPlusOneAddr() :
m_func->GetThreadContextInfo()->GetDoubleIntMaxPlusOneAddr(), instr);

m_lowerer->InsertCompareBranch(limitReg, src64, Js::OpCode::BrGt_A, conversion, instr, true /*no NaN check*/);
instr->InsertBefore(throwLabel);
this->m_lowerer->GenerateThrow(IR::IntConstOpnd::New(SCODE_CODE(VBSERR_Overflow), TyInt32, m_func), instr);
//no jump here we aren't coming back

instr->InsertBefore(oobLabel);
if (Saturate)
{
IR::LabelInstr * tooBigLabel = IR::LabelInstr::New(Js::OpCode::Label, m_func, true);
IR::RegOpnd* zeroReg = IR::RegOpnd::New(TyFloat64, m_func);
LoadFloatZero(zeroReg, instr);

m_lowerer->InsertCompareBranch(src64, zeroReg, Js::OpCode::BrGt_A, tooBigLabel, instr, true /*no NaN check*/);
instr->InsertBefore(IR::BranchInstr::New(Js::OpCode::JP, nanLabel, m_func));

m_lowerer->InsertMove(dst, IR::IntConstOpnd::New(dst->IsUnsigned() ? 0 : INT32_MIN, dst->GetType(), m_func), instr);
m_lowerer->InsertBranch(Js::OpCode::Br, doneLabel, instr);

instr->InsertBefore(tooBigLabel);
m_lowerer->InsertMove(dst, IR::IntConstOpnd::New(dst->IsUnsigned() ? UINT32_MAX : INT32_MAX, dst->GetType(), m_func), instr);
m_lowerer->InsertBranch(Js::OpCode::Br, doneLabel, instr);

instr->InsertBefore(nanLabel);
m_lowerer->InsertMove(dst, IR::IntConstOpnd::New(0, dst->GetType(), m_func), instr);
m_lowerer->InsertBranch(Js::OpCode::Br, doneLabel, instr);
}
else
{
m_lowerer->GenerateThrow(IR::IntConstOpnd::New(SCODE_CODE(VBSERR_Overflow), TyInt32, m_func), instr);
//no jump here we aren't coming back
}

instr->InsertBefore(conversion);
return src64;
}

template <bool Saturate>
void
LowererMD::GenerateTruncWithCheck(IR::Instr * instr)
LowererMD::GenerateTruncWithCheck(_In_ IR::Instr * instr)
{
Assert(AutoSystemInfo::Data.SSE2Available());

IR::Opnd* src64 = GenerateTruncChecks(instr); //converts src to double and checks if MIN <= src <= MAX
IR::LabelInstr * doneLabel = Saturate ? IR::LabelInstr::New(Js::OpCode::Label, m_func) : nullptr;
IR::Opnd* src64 = GenerateTruncChecks<Saturate>(instr, doneLabel); //converts src to double and checks if MIN <= src <= MAX

IR::Opnd* dst = instr->GetDst();

Expand All @@ -4784,12 +4816,17 @@ LowererMD::GenerateTruncWithCheck(IR::Instr * instr)
{
instr->InsertBefore(IR::Instr::New(Js::OpCode::CVTTSD2SI, dst, src64, m_func));
}

if (Saturate)
{
instr->InsertBefore(doneLabel);
}
instr->UnlinkSrc1();
instr->UnlinkDst();
instr->Remove();
}

template void LowererMD::GenerateTruncWithCheck<false>(_In_ IR::Instr * instr);
template void LowererMD::GenerateTruncWithCheck<true>(_In_ IR::Instr * instr);

void
LowererMD::GenerateCtz(IR::Instr * instr)
Expand Down
4 changes: 2 additions & 2 deletions lib/Backend/LowerMDShared.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ class LowererMD
void GenerateClz(IR::Instr * instr);
void GenerateCtz(IR::Instr * instr);
void GeneratePopCnt(IR::Instr * instr);
void GenerateTruncWithCheck(IR::Instr * instr);
IR::Opnd* GenerateTruncChecks(IR::Instr* instr);
template <bool Saturate> void GenerateTruncWithCheck(_In_ IR::Instr * instr);
template <bool Saturate> IR::Opnd* GenerateTruncChecks(_In_ IR::Instr* instr, _In_opt_ IR::LabelInstr* doneLabel);
IR::RegOpnd* MaterializeDoubleConstFromInt(intptr_t constAddr, IR::Instr* instr);
IR::RegOpnd* MaterializeConstFromBits(int intConst, IRType type, IR::Instr* instr);
IR::Opnd* Subtract2To31(IR::Opnd* src1, IR::Opnd* intMinFP, IRType type, IR::Instr* instr);
Expand Down
1 change: 1 addition & 0 deletions lib/Backend/arm/LowerMD.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class LowererMD
void GenerateClz(IR::Instr * instr);
void GenerateCtz(IR::Instr * instr) { Assert(UNREACHED); }
void GeneratePopCnt(IR::Instr * instr) { Assert(UNREACHED); }
template <bool Saturate>
void GenerateTruncWithCheck(IR::Instr * instr) { Assert(UNREACHED); }
void GenerateFastDivByPow2(IR::Instr *instr);
bool GenerateFastAdd(IR::Instr * instrAdd);
Expand Down
1 change: 1 addition & 0 deletions lib/Backend/arm64/LowerMD.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class LowererMD
void GenerateClz(IR::Instr * instr);
void GenerateCtz(IR::Instr * instr) { Assert(UNREACHED); }
void GeneratePopCnt(IR::Instr * instr) { Assert(UNREACHED); }
template <bool Saturate>
void GenerateTruncWithCheck(IR::Instr * instr) { Assert(UNREACHED); }
void GenerateFastDivByPow2(IR::Instr *instr);
bool GenerateFastDivAndRem(IR::Instr* instrDiv, IR::LabelInstr* bailOutLabel = false);
Expand Down
1 change: 1 addition & 0 deletions lib/Common/ConfigFlagsList.h
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,7 @@ FLAGR(Boolean, WasmExperimental, "Enable WebAssembly experimental features", DEF
// Not having the DEFAULT_CONFIG_XXXX macro ensures we use CONFIG_FLAG_RELEASE instead of CONFIG_FLAG
FLAGPR_EXPERIMENTAL_WASM(Boolean, WasmSignExtends , "Use new WebAssembly sign extension operators")
FLAGPR_EXPERIMENTAL_WASM(Boolean, WasmSimd , "Enable SIMD in WebAssembly")
FLAGPR_EXPERIMENTAL_WASM(Boolean, NontrappingConversions, "Enable non-trapping float-to-int conversions in WebAssembly")

FLAGNR(Boolean, AssertBreak , "Debug break on assert", false)
FLAGNR(Boolean, AssertPopUp , "Pop up asserts (default: false)", false)
Expand Down
1 change: 1 addition & 0 deletions lib/Runtime/ByteCode/OpCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ MACRO_BACKEND_ONLY( ToVar, Reg2, OpTempNumberProducin
// TODO: Consider changing the code so we don't have mark this as CallsValueOf
MACRO_BACKEND_ONLY( FromVar, Reg2, OpTempNumberSources|OpTempObjectSources|OpCanCSE)
MACRO_BACKEND_ONLY( Conv_Prim, Reg2, OpTempNumberProducing|OpTempNumberSources|OpCanCSE|OpPostOpDbgBailOut) // Convert between primitives (int32/float64)
MACRO_BACKEND_ONLY( Conv_Prim_Sat, Reg2, OpTempNumberProducing|OpTempNumberSources|OpCanCSE) // Convert between primitives (int/float), saturating OOB values
MACRO_BACKEND_ONLY( Conv_Bool, Reg2, OpTempNumberSources|OpCanCSE) // Convert from i4 to bool
MACRO_BACKEND_ONLY( Reinterpret_Prim, Reg2, OpTempNumberProducing|OpTempNumberSources|OpCanCSE) // Reinterpret bits between primitives (int32/float32)
MACRO_BACKEND_ONLY( TrapIfTruncOverflow, Reg2, OpSideEffect)
Expand Down
9 changes: 9 additions & 0 deletions lib/Runtime/ByteCode/OpCodesAsmJs.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,15 @@ MACRO_EXTEND_WMS( Conv_Check_FTUL , Long1Float1 , None
MACRO_EXTEND_WMS( Conv_Check_DTL , Long1Double1 , None )
MACRO_EXTEND_WMS( Conv_Check_DTUL , Long1Double1 , None )

MACRO_EXTEND_WMS( Conv_Sat_DTI , Int1Double1 , None )
MACRO_EXTEND_WMS( Conv_Sat_FTI , Int1Float1 , None )
MACRO_EXTEND_WMS( Conv_Sat_DTU , Int1Double1 , None )
MACRO_EXTEND_WMS( Conv_Sat_FTU , Int1Float1 , None )
MACRO_EXTEND_WMS( Conv_Sat_FTL , Long1Float1 , None )
MACRO_EXTEND_WMS( Conv_Sat_FTUL , Long1Float1 , None )
MACRO_EXTEND_WMS( Conv_Sat_DTL , Long1Double1 , None )
MACRO_EXTEND_WMS( Conv_Sat_DTUL , Long1Double1 , None )


// InOut tracing opcodes
MACRO_EXTEND_WMS( PrintFuncName , Int2, None)
Expand Down
Loading

0 comments on commit 4c0beef

Please sign in to comment.