[JSC] Add Div/Mod and fix Mul for B3 ARM64
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jan 2016 00:11:25 +0000 (00:11 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jan 2016 00:11:25 +0000 (00:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=152978

Patch by Benjamin Poulain <bpoulain@apple.com> on 2016-01-11
Reviewed by Filip Pizlo.

Add the 3 operands forms of Mul.
Remove the form taking immediate on ARM64, there are no such instruction.

Add Div with sdiv.

Unfortunately, I discovered ChillMod's division by zero
makes it non-trivial on ARM64. I just made it into a macro like on x86.

* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::mul32):
(JSC::MacroAssemblerARM64::mul64):
(JSC::MacroAssemblerARM64::div32):
(JSC::MacroAssemblerARM64::div64):
* b3/B3LowerMacros.cpp:
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::lower):
* b3/air/AirOpcode.opcodes:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@194873 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/assembler/MacroAssemblerARM64.h
Source/JavaScriptCore/b3/B3LowerMacros.cpp
Source/JavaScriptCore/b3/B3LowerToAir.cpp
Source/JavaScriptCore/b3/air/AirOpcode.opcodes

index 2699100..1f6acc0 100644 (file)
@@ -1,3 +1,28 @@
+2016-01-11  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Add Div/Mod and fix Mul for B3 ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=152978
+
+        Reviewed by Filip Pizlo.
+
+        Add the 3 operands forms of Mul.
+        Remove the form taking immediate on ARM64, there are no such instruction.
+
+        Add Div with sdiv.
+
+        Unfortunately, I discovered ChillMod's division by zero
+        makes it non-trivial on ARM64. I just made it into a macro like on x86.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::mul32):
+        (JSC::MacroAssemblerARM64::mul64):
+        (JSC::MacroAssemblerARM64::div32):
+        (JSC::MacroAssemblerARM64::div64):
+        * b3/B3LowerMacros.cpp:
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::lower):
+        * b3/air/AirOpcode.opcodes:
+
 2016-01-11  Keith Miller  <keith_miller@apple.com>
 
         Arrays should use the InternalFunctionAllocationProfile when constructing new Arrays
index c568727..b6e9ac7 100644 (file)
@@ -472,21 +472,41 @@ public:
     {
         lshift64(dest, imm, dest);
     }
+
+    void mul32(RegisterID left, RegisterID right, RegisterID dest)
+    {
+        m_assembler.mul<32>(dest, left, right);
+    }
     
     void mul32(RegisterID src, RegisterID dest)
     {
         m_assembler.mul<32>(dest, dest, src);
     }
-    
+
+    void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+    {
+        move(imm, getCachedDataTempRegisterIDAndInvalidate());
+        m_assembler.mul<32>(dest, src, dataTempRegister);
+    }
+
     void mul64(RegisterID src, RegisterID dest)
     {
         m_assembler.mul<64>(dest, dest, src);
     }
 
-    void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+    void mul64(RegisterID left, RegisterID right, RegisterID dest)
     {
-        move(imm, getCachedDataTempRegisterIDAndInvalidate());
-        m_assembler.mul<32>(dest, src, dataTempRegister);
+        m_assembler.mul<64>(dest, left, right);
+    }
+
+    void div32(RegisterID dividend, RegisterID divisor, RegisterID dest)
+    {
+        m_assembler.sdiv<32>(dest, dividend, divisor);
+    }
+
+    void div64(RegisterID dividend, RegisterID divisor, RegisterID dest)
+    {
+        m_assembler.sdiv<64>(dest, dividend, divisor);
     }
 
     void neg32(RegisterID dest)
index 0e72a4a..04e7a55 100644 (file)
@@ -84,6 +84,7 @@ private:
                         m_value->child(0),
                         m_value->child(1));
                     m_value->replaceWithIdentity(result);
+                    m_changed = true;
                 } else if (m_value->type() == Float) {
                     Value* numeratorAsDouble = m_insertionSet.insert<Value>(m_index, FloatToDouble, m_origin, m_value->child(0));
                     Value* denominatorAsDouble = m_insertionSet.insert<Value>(m_index, FloatToDouble, m_origin, m_value->child(1));
@@ -95,6 +96,13 @@ private:
                         denominatorAsDouble);
                     Value* result = m_insertionSet.insert<Value>(m_index, DoubleToFloat, m_origin, doubleMod);
                     m_value->replaceWithIdentity(result);
+                    m_changed = true;
+                } else if (isARM64()) {
+                    Value* divResult = m_insertionSet.insert<Value>(m_index, ChillDiv, m_origin, m_value->child(0), m_value->child(1));
+                    Value* multipliedBack = m_insertionSet.insert<Value>(m_index, Mul, m_origin, divResult, m_value->child(1));
+                    Value* result = m_insertionSet.insert<Value>(m_index, Sub, m_origin, m_value->child(0), multipliedBack);
+                    m_value->replaceWithIdentity(result);
+                    m_changed = true;
                 }
                 break;
             }
@@ -104,7 +112,34 @@ private:
             }
 
             case ChillMod: {
-                makeDivisionChill(Mod);
+                if (isARM64()) {
+                    BasicBlock* before = m_blockInsertionSet.splitForward(m_block, m_index, &m_insertionSet);
+                    BasicBlock* zeroDenCase = m_blockInsertionSet.insertBefore(m_block);
+                    BasicBlock* normalModCase = m_blockInsertionSet.insertBefore(m_block);
+
+                    before->replaceLastWithNew<ControlValue>(
+                        m_proc, Branch, m_origin, m_value->child(1),
+                        FrequentedBlock(normalModCase, FrequencyClass::Normal),
+                        FrequentedBlock(zeroDenCase, FrequencyClass::Rare));
+
+                    Value* divResult = normalModCase->appendNew<Value>(m_proc, ChillDiv, m_origin, m_value->child(0), m_value->child(1));
+                    Value* multipliedBack = normalModCase->appendNew<Value>(m_proc, Mul, m_origin, divResult, m_value->child(1));
+                    Value* result = normalModCase->appendNew<Value>(m_proc, Sub, m_origin, m_value->child(0), multipliedBack);
+                    UpsilonValue* normalResult = normalModCase->appendNew<UpsilonValue>(m_proc, m_origin, result);
+                    normalModCase->appendNew<ControlValue>(m_proc, Jump, m_origin, FrequentedBlock(m_block));
+
+                    UpsilonValue* zeroResult = zeroDenCase->appendNew<UpsilonValue>(
+                        m_proc, m_origin,
+                        zeroDenCase->appendIntConstant(m_proc, m_value, 0));
+                    zeroDenCase->appendNew<ControlValue>(m_proc, Jump, m_origin, FrequentedBlock(m_block));
+
+                    Value* phi = m_insertionSet.insert<Value>(m_index, Phi, m_value->type(), m_origin);
+                    normalResult->setPhi(phi);
+                    zeroResult->setPhi(phi);
+                    m_value->replaceWithIdentity(phi);
+                    m_changed = true;
+                } else
+                    makeDivisionChill(Mod);
                 break;
             }
 
index 5fa15a4..cee4c4f 100644 (file)
@@ -1641,21 +1641,25 @@ private:
             return;
         }
 
+        case ChillDiv:
+            RELEASE_ASSERT(isARM64());
+            FALLTHROUGH;
         case Div: {
-            if (isInt(m_value->type())) {
 #if CPU(X86) || CPU(X86_64)
+            if (isInt(m_value->type())) {
                 lowerX86Div();
                 append(Move, Tmp(X86Registers::eax), tmp(m_value));
-#endif
                 return;
             }
-            ASSERT(isFloat(m_value->type()));
+#endif
+            ASSERT(!isX86() || isFloat(m_value->type()));
 
-            appendBinOp<Air::Oops, Air::Oops, DivDouble, DivFloat>(m_value->child(0), m_value->child(1));
+            appendBinOp<Div32, Div64, DivDouble, DivFloat>(m_value->child(0), m_value->child(1));
             return;
         }
 
         case Mod: {
+            RELEASE_ASSERT(isX86());
 #if CPU(X86) || CPU(X86_64)
             lowerX86Div();
             append(Move, Tmp(X86Registers::edx), tmp(m_value));
index a72986f..4a21c7d 100644 (file)
@@ -186,11 +186,21 @@ Mul32 U:G:32, UZD:G:32
     x86: Addr, Tmp
 
 Mul32 U:G:32, U:G:32, ZD:G:32
-    Imm, Tmp, Tmp
+    arm64: Tmp, Tmp, Tmp
+    x86: Imm, Tmp, Tmp
 
 64: Mul64 U:G:64, UD:G:64
     Tmp, Tmp
 
+arm64: Mul64 U:G:64, U:G:64, D:G:64
+    Tmp, Tmp, Tmp
+
+arm64: Div32 U:G:32, U:G:32, ZD:G:32
+    Tmp, Tmp, Tmp
+
+arm64: Div64 U:G:64, U:G:64, D:G:64
+    Tmp, Tmp, Tmp
+
 arm64: MulDouble U:F:64, U:F:64, D:F:64
     Tmp, Tmp, Tmp