Title: [147729] trunk/Source/_javascript_Core
Revision
147729
Author
[email protected]
Date
2013-04-05 02:05:03 -0700 (Fri, 05 Apr 2013)

Log Message

LLint should be able to use x87 instead of SSE for floating pointer

https://bugs.webkit.org/show_bug.cgi?id=112239

Reviewed by Filip Pizlo.

Implements LLInt floating point operations in x87, to ensure we support
x86 without SSE2.

X86 (except 64bit) now defaults to using x87 instructions in order to
support all 32bit x86 back to i686. The implementation uses the fucomi
instruction from i686 which sets the new minimum.

* offlineasm/x86.rb:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (147728 => 147729)


--- trunk/Source/_javascript_Core/ChangeLog	2013-04-05 08:59:30 UTC (rev 147728)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-04-05 09:05:03 UTC (rev 147729)
@@ -1,3 +1,20 @@
+2013-04-05  Allan Sandfeld Jensen  <[email protected]>
+
+        LLint should be able to use x87 instead of SSE for floating pointer
+
+        https://bugs.webkit.org/show_bug.cgi?id=112239
+
+        Reviewed by Filip Pizlo.
+
+        Implements LLInt floating point operations in x87, to ensure we support
+        x86 without SSE2.
+
+        X86 (except 64bit) now defaults to using x87 instructions in order to
+        support all 32bit x86 back to i686. The implementation uses the fucomi
+        instruction from i686 which sets the new minimum.
+
+        * offlineasm/x86.rb:
+
 2013-04-04  Christophe Dumez  <[email protected]>
 
         Unreviewed EFL build fix.

Modified: trunk/Source/_javascript_Core/offlineasm/x86.rb (147728 => 147729)


--- trunk/Source/_javascript_Core/offlineasm/x86.rb	2013-04-05 08:59:30 UTC (rev 147728)
+++ trunk/Source/_javascript_Core/offlineasm/x86.rb	2013-04-05 09:05:03 UTC (rev 147729)
@@ -34,6 +34,17 @@
     end
 end
 
+def useX87
+    case $activeBackend
+    when "X86"
+        true
+    when "X86_64"
+        false
+    else
+        raise "bad value for $activeBackend: #{$activeBackend}"
+    end
+end
+
 class SpecialRegister < NoChildren
     def x86Operand(kind)
         raise unless @name =~ /^r/
@@ -255,6 +266,7 @@
 class FPRegisterID
     def x86Operand(kind)
         raise unless kind == :double
+        raise if useX87
         case name
         when "ft0", "fa0", "fr"
             "%xmm0"
@@ -272,6 +284,26 @@
             raise "Bad register #{name} for X86 at #{codeOriginString}"
         end
     end
+    def x87Operand(offset)
+        raise unless useX87
+        raise unless offset == 0 or offset == 1
+        case name
+        when "ft0", "fa0", "fr"
+            "%st(#{0 + offset})"
+        when "ft1", "fa1"
+            "%st(#{1 + offset})"
+        when "ft2", "fa2"
+            "%st(#{2 + offset})"
+        when "ft3", "fa3"
+            "%st(#{3 + offset})"
+        when "ft4"
+            "%st(#{4 + offset})"
+        when "ft5"
+            "%st(#{5 + offset})"
+        else
+            raise "Bad register #{name} for X86 at #{codeOriginString}"
+        end
+    end
     def x86CallOperand(kind)
         "*#{x86Operand(kind)}"
     end
@@ -422,7 +454,7 @@
         when :quad
             isX64 ? "q" : raise
         when :double
-            "sd"
+            not useX87 ? "sd" : raise
         else
             raise
         end
@@ -478,13 +510,26 @@
     end
     
     def handleX86DoubleBranch(branchOpcode, mode)
-        case mode
-        when :normal
-            $asm.puts "ucomisd #{operands[1].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
-        when :reverse
-            $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+        if useX87
+            case mode
+            when :normal
+                $asm.puts "fld #{operands[0].x87Operand(0)}"
+                $asm.puts "fucomip #{operands[1].x87Operand(1)}"
+            when :reverse
+                $asm.puts "fld #{operands[1].x87Operand(0)}"
+                $asm.puts "fucomip #{operands[0].x87Operand(1)}"
+            else
+                raise mode.inspect
+            end
         else
-            raise mode.inspect
+            case mode
+            when :normal
+                $asm.puts "ucomisd #{operands[1].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
+            when :reverse
+                $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+            else
+                raise mode.inspect
+            end
         end
         $asm.puts "#{branchOpcode} #{operands[2].asmLabel}"
     end
@@ -749,22 +794,87 @@
             $asm.puts "movswl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
         when "storeb"
             $asm.puts "movb #{x86Operands(:byte, :byte)}"
-        when "loadd", "moved", "stored"
-            $asm.puts "movsd #{x86Operands(:double, :double)}"
+        when "loadd"
+            if useX87
+                $asm.puts "fldl #{operands[0].x86Operand(:double)}"
+                $asm.puts "fstp #{operands[1].x87Operand(1)}"
+            else
+                $asm.puts "movsd #{x86Operands(:double, :double)}"
+            end
+        when "moved"
+            if useX87
+                $asm.puts "fld #{operands[0].x87Operand(0)}"
+                $asm.puts "fstp #{operands[0].x87Operand(1)}"
+            else
+                $asm.puts "movsd #{x86Operands(:double, :double)}"
+            end
+        when "stored"
+            if useX87
+                $asm.puts "fld #{operands[0].x87Operand(0)}"
+                $asm.puts "fstpl #{operands[1].x86Operand(:double)}"
+            else
+                $asm.puts "movsd #{x86Operands(:double, :double)}"
+            end
         when "addd"
-            $asm.puts "addsd #{x86Operands(:double, :double)}"
+            if useX87
+                $asm.puts "fld #{operands[0].x87Operand(0)}"
+                $asm.puts "faddp %st, #{operands[1].x87Operand(1)}"
+            else
+                $asm.puts "addsd #{x86Operands(:double, :double)}"
+            end
         when "divd"
-            $asm.puts "divsd #{x86Operands(:double, :double)}"
+            if useX87
+                $asm.puts "fld #{operands[0].x87Operand(0)}"
+                $asm.puts "fdivrp %st, #{operands[1].x87Operand(1)}"
+            else
+                $asm.puts "divsd #{x86Operands(:double, :double)}"
+            end
         when "subd"
-            $asm.puts "subsd #{x86Operands(:double, :double)}"
+            if useX87
+                $asm.puts "fld #{operands[0].x87Operand(0)}"
+                $asm.puts "fsubrp %st, #{operands[1].x87Operand(1)}"
+            else
+                $asm.puts "subsd #{x86Operands(:double, :double)}"
+            end
         when "muld"
-            $asm.puts "mulsd #{x86Operands(:double, :double)}"
+            if useX87
+                $asm.puts "fld #{operands[0].x87Operand(0)}"
+                $asm.puts "fmulp %st, #{operands[1].x87Operand(1)}"
+            else
+                $asm.puts "mulsd #{x86Operands(:double, :double)}"
+            end
         when "sqrtd"
-            $asm.puts "sqrtsd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+            if useX87
+                $asm.puts "fld #{operands[0].x87Operand(0)}"
+                $asm.puts "fsqrtl"
+                $asm.puts "fstp #{operands[1].x87Operand(1)}"
+            else
+                $asm.puts "sqrtsd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+            end
         when "ci2d"
-            $asm.puts "cvtsi2sd #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:double)}"
+            if useX87
+                if isX64
+                    $asm.puts "sub#{x86Suffix(:ptr)} $4, %rsp"
+                    $asm.puts "movl #{operands[0].x86Operand(:int)}, 0(%rsp)"
+                    $asm.puts "fildl 0(%rsp)"
+                    $asm.puts "add#{x86Suffix(:ptr)} $4, %rsp"
+                else
+                    $asm.puts "sub#{x86Suffix(:ptr)} $4, %esp"
+                    $asm.puts "movl #{operands[0].x86Operand(:int)}, 0(%esp)"
+                    $asm.puts "fildl 0(%esp)"
+                    $asm.puts "add#{x86Suffix(:ptr)} $4, %esp"
+                end
+                $asm.puts "fstp #{operands[1].x87Operand(1)}"
+            else
+                $asm.puts "cvtsi2sd #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:double)}"
+            end
         when "bdeq"
-            $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+            if useX87
+                $asm.puts "fld #{operands[1].x87Operand(0)}"
+                $asm.puts "fucomip #{operands[0].x87Operand(1)}"
+            else
+                $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+            end
             if operands[0] == operands[1]
                 # This is just a jump ordered, which is a jnp.
                 $asm.puts "jnp #{operands[2].asmLabel}"
@@ -787,7 +897,12 @@
         when "bdequn"
             handleX86DoubleBranch("je", :normal)
         when "bdnequn"
-            $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+            if useX87
+                $asm.puts "fld #{operands[1].x87Operand(0)}"
+                $asm.puts "fucomip #{operands[0].x87Operand(1)}"
+            else
+                $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+            end
             if operands[0] == operands[1]
                 # This is just a jump unordered, which is a jp.
                 $asm.puts "jp #{operands[2].asmLabel}"
@@ -809,21 +924,41 @@
         when "bdltequn"
             handleX86DoubleBranch("jbe", :normal)
         when "btd2i"
+            # FIXME: unused and unimplemented for x87
+            raise if useX87
             $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
             $asm.puts "cmpl $0x80000000 #{operands[1].x86Operand(:int)}"
             $asm.puts "je #{operands[2].asmLabel}"
         when "td2i"
+            # FIXME: unused and unimplemented for x87
+            raise if useX87
             $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
         when "bcd2i"
-            $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
-            $asm.puts "testl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
-            $asm.puts "je #{operands[2].asmLabel}"
-            $asm.puts "cvtsi2sd #{operands[1].x86Operand(:int)}, %xmm7"
-            $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, %xmm7"
-            $asm.puts "jp #{operands[2].asmLabel}"
-            $asm.puts "jne #{operands[2].asmLabel}"
+            if useX87
+                raise if isX64
+                $asm.puts "fld #{operands[0].x87Operand(0)}"
+                $asm.puts "sub#{x86Suffix(:ptr)} $4, %esp"
+                $asm.puts "fistl 0(%esp)"
+                $asm.puts "ficomp 0(%esp)"
+                $asm.puts "popl #{operands[1].x86Operand(:int)}"
+                $asm.puts "jp #{operands[2].asmLabel}"
+                $asm.puts "jne #{operands[2].asmLabel}"
+            else
+                $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
+                $asm.puts "testl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
+                $asm.puts "je #{operands[2].asmLabel}"
+                $asm.puts "cvtsi2sd #{operands[1].x86Operand(:int)}, %xmm7"
+                $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, %xmm7"
+                $asm.puts "jp #{operands[2].asmLabel}"
+                $asm.puts "jne #{operands[2].asmLabel}"
+            end
         when "movdz"
-            $asm.puts "xorpd #{operands[0].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
+            if useX87
+                $asm.puts "fldzl"
+                $asm.puts "fstp #{operands[0].x87Operand(1)}"
+            else
+                $asm.puts "xorpd #{operands[0].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
+            end
         when "pop"
             $asm.puts "pop #{operands[0].x86Operand(:ptr)}"
         when "push"
@@ -1117,19 +1252,55 @@
         when "idivi"
             $asm.puts "idivl #{operands[0].x86Operand(:int)}"
         when "fii2d"
-            $asm.puts "movd #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:double)}"
-            $asm.puts "movd #{operands[1].x86Operand(:int)}, %xmm7"
-            $asm.puts "psllq $32, %xmm7"
-            $asm.puts "por %xmm7, #{operands[2].x86Operand(:double)}"
+            if useX87
+                raise if isX64
+                $asm.puts "sub#{x86Suffix(:ptr)} $8, %esp"
+                $asm.puts "movl #{operands[0].x86Operand(:int)}, 0(%esp)"
+                $asm.puts "movl #{operands[1].x86Operand(:int)}, 4(%esp)"
+                $asm.puts "fldl 0(%esp)"
+                $asm.puts "add#{x86Suffix(:ptr)} $8, %esp"
+                $asm.puts "fstp #{operands[2].x87Operand(1)}"
+            else
+                $asm.puts "movd #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:double)}"
+                $asm.puts "movd #{operands[1].x86Operand(:int)}, %xmm7"
+                $asm.puts "psllq $32, %xmm7"
+                $asm.puts "por %xmm7, #{operands[2].x86Operand(:double)}"
+            end
         when "fd2ii"
-            $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
-            $asm.puts "movsd #{operands[0].x86Operand(:double)}, %xmm7"
-            $asm.puts "psrlq $32, %xmm7"
-            $asm.puts "movd %xmm7, #{operands[2].x86Operand(:int)}"
+            if useX87
+                raise if isX64
+                $asm.puts "fld #{operands[0].x87Operand(0)}"
+                $asm.puts "sub#{x86Suffix(:ptr)} $8, %esp"
+                $asm.puts "fstpl 0(%esp)"
+                $asm.puts "movl 0(%esp), #{operands[1].x86Operand(:int)}"
+                $asm.puts "movl 4(%esp), #{operands[2].x86Operand(:int)}"
+                $asm.puts "add#{x86Suffix(:ptr)} $8, %esp"
+            else
+                $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
+                $asm.puts "movsd #{operands[0].x86Operand(:double)}, %xmm7"
+                $asm.puts "psrlq $32, %xmm7"
+                $asm.puts "movd %xmm7, #{operands[2].x86Operand(:int)}"
+            end
         when "fq2d"
-            $asm.puts "movd #{operands[0].x86Operand(:quad)}, #{operands[1].x86Operand(:double)}"
+            if useX87
+                raise unless isX64
+                $asm.puts "push #{operands[0].x86Operand(:quad)}"
+                $asm.puts "fldl 0(%rsp)"
+                $asm.puts "add#{x86Suffix(:ptr)} $8, %rsp"
+                $asm.puts "fstp #{operands[1].x87Operand(1)}"
+            else
+                $asm.puts "movq #{operands[0].x86Operand(:quad)}, #{operands[1].x86Operand(:double)}"
+            end
         when "fd2q"
-            $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:quad)}"
+            if useX87
+                raise unless isX64
+                $asm.puts "fld #{operands[0].x87Operand(0)}"
+                $asm.puts "sub#{x86Suffix(:ptr)} $8, %rsp"
+                $asm.puts "fstpl 0(%rsp)"
+                $asm.puts "pop #{operands[1].x86Operand(:quad)}"
+            else
+                $asm.puts "movq #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:quad)}"
+            end
         when "bo"
             $asm.puts "jo #{operands[0].asmLabel}"
         when "bs"
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to