Explorar o código

using builtins for SSE2

George Kuan %!s(int64=9) %!d(string=hai) anos
pai
achega
d79f5d635e

+ 12 - 0
lib/Backend/JnHelperMethod.cpp

@@ -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
     //

+ 5 - 0
lib/Backend/JnHelperMethodList.h

@@ -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)

+ 12 - 0
lib/Backend/Lower.cpp

@@ -2986,10 +2986,22 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
             break;
 
         case Js::OpCode::Trunc_A:
+            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:
+            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

+ 1 - 1
lib/Backend/LowerMDShared.cpp

@@ -8788,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());

+ 0 - 2
lib/Backend/LowerMDShared.h

@@ -193,8 +193,6 @@ public:
 #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);

+ 12 - 12
test/wasm/misc.wast

@@ -4,23 +4,23 @@
 ;;-------------------------------------------------------------------------------------------------------
 
 (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)
+  ;;(func $copysign64 (param f64) (param f64) (result f64)
   ;;  (return (f64.copysign (get_local 0) (get_local 1))))
-  (func (param i32) (result i32)
+  (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 $nearest32 (param f32) (result f32)
     (return (f32.nearest (get_local 0))))
-  (func (param i32) (result i32)
+  (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" 1)
-  (export "trunc" 2)
-  (export "nearest" 3)
-  (export "ifeqz" 4)
+  (export "f32copysign" $copysign32)
+  ;;(export "f64copysign" $copysign64)
+  (export "eqz" $eqz32)
+  (export "trunc" $trunc32)
+  (export "nearest" $nearest32)
+  (export "ifeqz" $ifeqz)
 )