Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion lib/Backend/JnHelperMethod.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "Backend.h"
Expand Down Expand Up @@ -220,6 +220,18 @@ DECLSPEC_GUARDIGNORE _NOINLINE void * const GetNonTableMethodAddress(JnHelperMet
case HelperDirectMath_CeilFlt:
return (float(*)(float))ceil;

case HelperDirectMath_TruncDb:
return (double(*)(double))trunc;

case HelperDirectMath_TruncFlt:
return (float(*)(float))trunc;

case HelperDirectMath_NearestDb:
return (double(*)(double))round;

case HelperDirectMath_NearestFlt:
return (float(*)(float))round;

//
// These are statically initialized to an import thunk, but let's keep them out of the table in case a new CRT changes this
//
Expand Down
5 changes: 5 additions & 0 deletions lib/Backend/JnHelperMethodList.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,11 @@ HELPERCALL(DirectMath_FloorFlt, nullptr, 0)
HELPERCALL(DirectMath_CeilDb, nullptr, 0)
HELPERCALL(DirectMath_CeilFlt, nullptr, 0)

HELPERCALL(DirectMath_TruncDb, nullptr, 0)
HELPERCALL(DirectMath_TruncFlt, nullptr, 0)
HELPERCALL(DirectMath_NearestDb, nullptr, 0)
HELPERCALL(DirectMath_NearestFlt, nullptr, 0)

#ifdef _M_IX86
HELPERCALL(DirectMath_Acos, nullptr, 0)
HELPERCALL(DirectMath_Asin, nullptr, 0)
Expand Down
16 changes: 14 additions & 2 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2986,11 +2986,23 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
break;

case Js::OpCode::Trunc_A:
m_lowererMD.GenerateTrunc(instr);
if (!AutoSystemInfo::Data.SSE4_1Available())
{
m_lowererMD.HelperCallForAsmMathBuiltin(instr, IR::HelperDirectMath_TruncFlt, IR::HelperDirectMath_TruncDb);
break;
}

m_lowererMD.GenerateFastInlineBuiltInCall(instr, (IR::JnHelperMethod)0);
break;

case Js::OpCode::Nearest_A:
m_lowererMD.GenerateNearest(instr);
if (!AutoSystemInfo::Data.SSE4_1Available())
{
m_lowererMD.HelperCallForAsmMathBuiltin(instr, IR::HelperDirectMath_NearestFlt, IR::HelperDirectMath_NearestDb);
break;
}

m_lowererMD.GenerateFastInlineBuiltInCall(instr, (IR::JnHelperMethod)0);
break;
#endif //ENABLE_WASM

Expand Down
44 changes: 22 additions & 22 deletions lib/Backend/LowerMDShared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6131,18 +6131,6 @@ LowererMD::GenerateCopysign(IR::Instr * instr)
instr->m_opcode = Js::OpCode::ORPS;
Legalize(instr);
};

void
LowererMD::GenerateTrunc(IR::Instr * instr)
{
Assert(UNREACHED);
}

void
LowererMD::GenerateNearest(IR::Instr * instr)
{
Assert(UNREACHED);
}
#endif //ENABLE_WASM

void
Expand Down Expand Up @@ -8800,7 +8788,7 @@ LowererMD::LowerFloatCondBranch(IR::BranchInstr *instrBranch, bool ignoreNan)
}
void LowererMD::HelperCallForAsmMathBuiltin(IR::Instr* instr, IR::JnHelperMethod helperMethodFloat, IR::JnHelperMethod helperMethodDouble)
{
Assert(instr->m_opcode == Js::OpCode::InlineMathFloor || instr->m_opcode == Js::OpCode::InlineMathCeil);
Assert(instr->m_opcode == Js::OpCode::InlineMathFloor || instr->m_opcode == Js::OpCode::InlineMathCeil || instr->m_opcode == Js::OpCode::Trunc_A || instr->m_opcode == Js::OpCode::Nearest_A);
AssertMsg(instr->GetDst()->IsFloat(), "dst must be float.");
Assert(instr->GetDst()->GetType() == instr->GetSrc1()->GetType());
Assert(!instr->GetSrc2());
Expand Down Expand Up @@ -8930,6 +8918,10 @@ void LowererMD::GenerateFastInlineBuiltInCall(IR::Instr* instr, IR::JnHelperMeth
case Js::OpCode::InlineMathFloor:
case Js::OpCode::InlineMathCeil:
case Js::OpCode::InlineMathRound:
#ifdef ENABLE_WASM
case Js::OpCode::Trunc_A:
case Js::OpCode::Nearest_A:
#endif //ENABLE_WASM
{
Assert(AutoSystemInfo::Data.SSE4_1Available());
Assert(instr->GetDst()->IsInt32() || instr->GetDst()->IsFloat());
Expand Down Expand Up @@ -9161,19 +9153,27 @@ void LowererMD::GenerateFastInlineBuiltInCall(IR::Instr* instr, IR::JnHelperMeth
}

// ROUNDSD srcCopy, srcCopy, round_mode
IR::Opnd * roundMode;
if(isNotCeil)
IR::Opnd * roundMode = nullptr;

switch (instr->m_opcode)
{
#ifdef ENABLE_WASM
case Js::OpCode::Trunc_A:
roundMode = IR::IntConstOpnd::New(0x03, TyInt32, this->m_func);
break;
case Js::OpCode::Nearest_A:
roundMode = IR::IntConstOpnd::New(0x00, TyInt32, this->m_func);
break;
#endif //ENABLE_WASM
case Js::OpCode::InlineMathRound:
case Js::OpCode::InlineMathFloor:
roundMode = IR::IntConstOpnd::New(0x01, TyInt32, this->m_func);
}
else if (instr->GetDst()->IsInt32() || instr->m_opcode != Js::OpCode::InlineMathFloor)
{
break;
case Js::OpCode::InlineMathCeil:
roundMode = IR::IntConstOpnd::New(0x02, TyInt32, this->m_func);
break;
}
else
{
roundMode = IR::IntConstOpnd::New(0x03, TyInt32, this->m_func);
}

IR::Instr* roundInstr = IR::Instr::New(src->IsFloat64() ? Js::OpCode::ROUNDSD : Js::OpCode::ROUNDSS, roundedFloat, roundedFloat, roundMode, this->m_func);

instr->InsertBefore(roundInstr);
Expand Down
2 changes: 0 additions & 2 deletions lib/Backend/LowerMDShared.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,6 @@ class LowererMD
#endif

void GenerateCopysign(IR::Instr * instr);
void GenerateTrunc(IR::Instr * instr);
void GenerateNearest(IR::Instr * instr);

static IR::Instr *LoadFloatZero(IR::Opnd * opndDst, IR::Instr * instrInsert);
static IR::Instr *LoadFloatValue(IR::Opnd * opndDst, double value, IR::Instr * instrInsert);
Expand Down
9 changes: 5 additions & 4 deletions lib/WasmReader/WasmBinaryOpCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ WASM_UNARY__OPCODE(F32Neg, 0x7c, F_F , Neg_Flt , false)
WASM_BINARY_OPCODE(F32CopySign, 0x7d, F_FF, Copysign_Flt , false)
WASM_UNARY__OPCODE(F32Ceil, 0x7e, F_F , Ceil_Flt , false)
WASM_UNARY__OPCODE(F32Floor, 0x7f, F_F , Floor_Flt , false)
WASM_UNARY__OPCODE(F32Trunc, 0x80, F_F , Trunc_Flt , true)
WASM_UNARY__OPCODE(F32NearestInt, 0x81, F_F , Nearest_Flt , true)
WASM_UNARY__OPCODE(F32Trunc, 0x80, F_F , Trunc_Flt , false)
WASM_UNARY__OPCODE(F32NearestInt, 0x81, F_F , Nearest_Flt , false)
WASM_UNARY__OPCODE(F32Sqrt, 0x82, F_F , Sqrt_Flt , false)
WASM_BINARY_OPCODE(F32Eq, 0x83, I_FF, CmEq_Flt , false)
WASM_BINARY_OPCODE(F32Ne, 0x84, I_FF, CmNe_Flt , false)
Expand All @@ -211,8 +211,8 @@ WASM_UNARY__OPCODE(F64Neg, 0x90, D_D , Neg_Db , false)
WASM_BINARY_OPCODE(F64CopySign, 0x91, D_DD, Copysign_Db , true)
WASM_UNARY__OPCODE(F64Ceil, 0x92, D_D , Ceil_Db , false)
WASM_UNARY__OPCODE(F64Floor, 0x93, D_D , Floor_Db , false)
WASM_UNARY__OPCODE(F64Trunc, 0x94, D_D , Trunc_Db , true)
WASM_UNARY__OPCODE(F64NearestInt, 0x95, D_D , Nearest_Db , true)
WASM_UNARY__OPCODE(F64Trunc, 0x94, D_D , Trunc_Db , false)
WASM_UNARY__OPCODE(F64NearestInt, 0x95, D_D , Nearest_Db , false)
WASM_UNARY__OPCODE(F64Sqrt, 0x96, D_D , Sqrt_Db , false)
WASM_BINARY_OPCODE(F64Eq, 0x97, I_DD, CmEq_Db , false)
WASM_BINARY_OPCODE(F64Ne, 0x98, I_DD, CmNe_Db , false)
Expand Down Expand Up @@ -248,6 +248,7 @@ WASM_UNARY__OPCODE(I64ReinterpretF64, 0xb5, L_D , Nop , true)
WASM_BINARY_OPCODE(I32Ror, 0xb6, I_II, Ror_Int , false)
WASM_BINARY_OPCODE(I32Rol, 0xb7, I_II, Rol_Int , false)


#undef WASM_OPCODE
#undef WASM_SIGNATURE
#undef WASM_CTRL_OPCODE
Expand Down
26 changes: 26 additions & 0 deletions test/wasm/misc.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,31 @@
1
0
0
0
-1
NaN
NaN
Infinity
-Infinity
0
-1
NaN
NaN
Infinity
-Infinity
1
0
0
-1
-2
NaN
NaN
Infinity
-Infinity
0
-1
-2
NaN
NaN
Infinity
-Infinity
33 changes: 26 additions & 7 deletions test/wasm/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,32 @@ print(a.f32copysign(255.0,1.0)); // == 255.0
print(a.eqz(0)); // == 1
print(a.eqz(-1)); // == 0
print(a.eqz(1)); // == 0
//print(a.trunc(0.5)); // == 0
//print(a.trunc(-1.5)); // == -1
//print(a.trunc(Number.NaN)); // == NaN
//print(a.trunc(-Number.NaN)); // == -NaN
print(a.trunc(0.5)); // == 0
print(a.trunc(-1.5)); // == -1
print(a.trunc(NaN)); // == NaN
print(a.trunc(-NaN)); // == NaN
print(a.trunc(Infinity)); // == Infinity
print(a.trunc(-Infinity)); // == -Infinity
print(a.f64trunc(0.5)); // == 0
print(a.f64trunc(-1.5)); // == -1
print(a.f64trunc(NaN)); // == NaN
print(a.f64trunc(-NaN)); // == NaN
print(a.f64trunc(Infinity)); // == Infinity
print(a.f64trunc(-Infinity)); // == -Infinity
print(a.ifeqz(0)); // == 1
print(a.ifeqz(-1)); // == 0
//print(a.nearest(-0.1)); // == 0
//print(a.nearest(-0.7)); // == -1
//print(a.nearest(-1.5)); // == -2
print(a.nearest(-0.1)); // == 0
print(a.nearest(-0.7)); // == -1
print(a.nearest(-1.5)); // == -2
print(a.nearest(NaN)); // == NaN
print(a.nearest(-NaN)); // == NaN
print(a.nearest(Infinity)); // == Infinity
print(a.nearest(-Infinity)); // == -Infinity
print(a.f64nearest(-0.1)); // == 0
print(a.f64nearest(-0.7)); // == -1
print(a.f64nearest(-1.5)); // == -2
print(a.f64nearest(NaN)); // == NaN
print(a.f64nearest(-NaN)); // == NaN
print(a.f64nearest(Infinity)); // == Infinity
print(a.f64nearest(-Infinity)); // == -Infinity
//print(a.f64copysign(255.0,-1.0)); // == -255.0
Binary file modified test/wasm/misc.wasm
Binary file not shown.
32 changes: 19 additions & 13 deletions test/wasm/misc.wast
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,29 @@
;;-------------------------------------------------------------------------------------------------------

(module
(func (param f32) (param f32) (result f32)
(func $copysign32 (param f32) (param f32) (result f32)
(return (f32.copysign (get_local 0) (get_local 1))))
(func (param f64) (param f64) (result f64)
(return (f64.copysign (get_local 0) (get_local 1))))
(func (param i32) (result i32)
;;(func $copysign64 (param f64) (param f64) (result f64)
;; (return (f64.copysign (get_local 0) (get_local 1))))
(func $eqz32 (param i32) (result i32)
(return (i32.eqz (get_local 0))))
(func (param f32) (result f32)
(func $trunc32 (param f32) (result f32)
(return (f32.trunc (get_local 0))))
(func (param f32) (result f32)
(func $trunc64 (param f64) (result f64)
(return (f64.trunc (get_local 0))))
(func $nearest32 (param f32) (result f32)
(return (f32.nearest (get_local 0))))
(func (param i32) (result i32)
(func $nearest64 (param f64) (result f64)
(return (f64.nearest (get_local 0))))
(func $ifeqz (param i32) (result i32)
(if (i32.eqz (get_local 0)) (return (i32.const 1)))
(return (i32.const 0)))
(export "f32copysign" 0)
(export "f64copysign" 1)
(export "eqz" 2)
(export "trunc" 3)
(export "nearest" 4)
(export "ifeqz" 5)
(export "f32copysign" $copysign32)
;;(export "f64copysign" $copysign64)
(export "eqz" $eqz32)
(export "trunc" $trunc32)
(export "f64trunc" $trunc64)
(export "nearest" $nearest32)
(export "f64nearest" $nearest64)
(export "ifeqz" $ifeqz)
)