Eliminate {push,pop}CalleeSaves in favor of individual pushes & pops
https://bugs.webkit.org/show_bug.cgi?id=127155

Reviewed by Geoffrey Garen.

Eliminated the offline assembler instructions {push,pop}CalleeSaves as well as the
ARM64 specific {push,pop}LRAndFP and replaced them with individual push and pop
instructions. Where the registers referenced by the added push and pop instructions
are not part of the offline assembler register aliases, used a newly added "emit"
offline assembler instruction which takes a string literal and outputs that
string as a native instruction.

* llint/LowLevelInterpreter.asm:
* offlineasm/arm.rb:
* offlineasm/arm64.rb:
* offlineasm/ast.rb:
* offlineasm/cloop.rb:
* offlineasm/instructions.rb:
* offlineasm/mips.rb:
* offlineasm/parser.rb:
* offlineasm/sh4.rb:
* offlineasm/transform.rb:
* offlineasm/x86.rb:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@172429 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/offlineasm/arm.rb b/Source/JavaScriptCore/offlineasm/arm.rb
index c922436..44cfbe5 100644
--- a/Source/JavaScriptCore/offlineasm/arm.rb
+++ b/Source/JavaScriptCore/offlineasm/arm.rb
@@ -466,18 +466,6 @@
                 | op |
                 $asm.puts "push { #{op.armOperand} }"
             }
-        when "popCalleeSaves"
-            if isARMv7
-                $asm.puts "pop {r4-r6, r8-r11}"                
-            else
-                $asm.puts "pop {r4-r10}"
-            end
-        when "pushCalleeSaves"
-            if isARMv7
-                $asm.puts "push {r4-r6, r8-r11}"
-            else
-                $asm.puts "push {r4-r10}"
-            end
         when "move"
             if operands[0].immediate?
                 armMoveImmediate(operands[0].value, operands[1])
diff --git a/Source/JavaScriptCore/offlineasm/arm64.rb b/Source/JavaScriptCore/offlineasm/arm64.rb
index 76d3dcc..bdc84f5 100644
--- a/Source/JavaScriptCore/offlineasm/arm64.rb
+++ b/Source/JavaScriptCore/offlineasm/arm64.rb
@@ -586,22 +586,6 @@
                 | ops |
                 $asm.puts "stp #{ops[0].arm64Operand(:ptr)}, #{ops[1].arm64Operand(:ptr)}, [sp, #-16]!"
             }
-        when "popLRAndFP"
-            $asm.puts "ldp x29, x30, [sp], #16"
-        when "pushLRAndFP"
-            $asm.puts "stp x29, x30, [sp, #-16]!"
-        when "popCalleeSaves"
-            $asm.puts "ldp x28, x27, [sp], #16"
-            $asm.puts "ldp x26, x25, [sp], #16"
-            $asm.puts "ldp x24, x23, [sp], #16"
-            $asm.puts "ldp x22, x21, [sp], #16"
-            $asm.puts "ldp x20, x19, [sp], #16"
-        when "pushCalleeSaves"
-            $asm.puts "stp x20, x19, [sp, #-16]!"
-            $asm.puts "stp x22, x21, [sp, #-16]!"
-            $asm.puts "stp x24, x23, [sp, #-16]!"
-            $asm.puts "stp x26, x25, [sp, #-16]!"
-            $asm.puts "stp x28, x27, [sp, #-16]!"
         when "move"
             if operands[0].immediate?
                 emitARM64MoveImmediate(operands[0].value, operands[1])
diff --git a/Source/JavaScriptCore/offlineasm/ast.rb b/Source/JavaScriptCore/offlineasm/ast.rb
index dc2de5e..1241b7f 100644
--- a/Source/JavaScriptCore/offlineasm/ast.rb
+++ b/Source/JavaScriptCore/offlineasm/ast.rb
@@ -580,6 +580,44 @@
     end
 end
 
+class StringLiteral < NoChildren
+    attr_reader :value
+    
+    def initialize(codeOrigin, value)
+        super(codeOrigin)
+        @value = value[1..-2]
+        raise "Bad string literal #{value.inspect} at #{codeOriginString}" unless value.is_a? String
+    end
+    
+    def dump
+        "#{value}"
+    end
+    
+    def ==(other)
+        other.is_a? StringLiteral and other.value == @value
+    end
+    
+    def address?
+        false
+    end
+    
+    def label?
+        false
+    end
+    
+    def immediate?
+        false
+    end
+    
+    def immediateOperand?
+        false
+    end
+        
+    def register?
+        false
+    end
+end
+
 class RegisterID < NoChildren
     attr_reader :name
     
@@ -889,6 +927,8 @@
             $asm.putLocalAnnotation
         when "globalAnnotation"
             $asm.putGlobalAnnotation
+        when "emit"
+          $asm.puts "#{operands[0].dump}"
         else
             raise "Unhandled opcode #{opcode} at #{codeOriginString}"
         end
diff --git a/Source/JavaScriptCore/offlineasm/cloop.rb b/Source/JavaScriptCore/offlineasm/cloop.rb
index d0cbc06..04a69981 100644
--- a/Source/JavaScriptCore/offlineasm/cloop.rb
+++ b/Source/JavaScriptCore/offlineasm/cloop.rb
@@ -1104,9 +1104,6 @@
                 $asm.putc "POP(#{op.clDump});"
             }
 
-        when "pushCalleeSaves"
-        when "popCalleeSaves"
-
 
         # A convenience and compact call to crash because we don't want to use
         # the generic llint crash mechanism which relies on the availability
diff --git a/Source/JavaScriptCore/offlineasm/instructions.rb b/Source/JavaScriptCore/offlineasm/instructions.rb
index 44280e7..9196e3c 100644
--- a/Source/JavaScriptCore/offlineasm/instructions.rb
+++ b/Source/JavaScriptCore/offlineasm/instructions.rb
@@ -30,6 +30,7 @@
 
 MACRO_INSTRUCTIONS =
     [
+     "emit",
      "addi",
      "andi",
      "lshifti",
@@ -248,8 +249,6 @@
      "bnz",
      "leai",
      "leap",
-     "pushCalleeSaves",
-     "popCalleeSaves",
      "memfence"
     ]
 
@@ -267,9 +266,7 @@
 
 ARM64_INSTRUCTIONS =
     [
-     "pcrtoaddr",    # Address from PC relative offset - adr instruction
-     "popLRAndFP",   # ARM64 requires registers to be pushed and popped in pairs,
-     "pushLRAndFP"   # therefore we do LR (link register) and FP (frame pointer) together.
+     "pcrtoaddr"    # Address from PC relative offset - adr instruction
     ]
 
 RISC_INSTRUCTIONS =
diff --git a/Source/JavaScriptCore/offlineasm/mips.rb b/Source/JavaScriptCore/offlineasm/mips.rb
index 686f58f..1760106 100644
--- a/Source/JavaScriptCore/offlineasm/mips.rb
+++ b/Source/JavaScriptCore/offlineasm/mips.rb
@@ -850,20 +850,6 @@
                 $asm.puts "addiu $sp, $sp, -4"
                 $asm.puts "sw #{op.mipsOperand}, 0($sp)"
             }
-        when "popCalleeSaves"
-            $asm.puts "lw $16, 0($sp)"
-            $asm.puts "lw $17, 4($sp)"
-            $asm.puts "lw $18, 8($sp)"
-            $asm.puts "lw $19, 12($sp)"
-            $asm.puts "lw $20, 16($sp)"
-            $asm.puts "addiu $sp, $sp, 20"
-        when "pushCalleeSaves"
-            $asm.puts "addiu $sp, $sp, -20"
-            $asm.puts "sw $20, 16($sp)"
-            $asm.puts "sw $19, 12($sp)"
-            $asm.puts "sw $18, 8($sp)"
-            $asm.puts "sw $17, 4($sp)"
-            $asm.puts "sw $16, 0($sp)"
         when "move", "sxi2p", "zxi2p"
             if operands[0].is_a? Immediate
                 mipsMoveImmediate(operands[0].value, operands[1])
diff --git a/Source/JavaScriptCore/offlineasm/parser.rb b/Source/JavaScriptCore/offlineasm/parser.rb
index 04f70a4..a122a68 100644
--- a/Source/JavaScriptCore/offlineasm/parser.rb
+++ b/Source/JavaScriptCore/offlineasm/parser.rb
@@ -165,6 +165,8 @@
             result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
         when /\A[:,\(\)\[\]=\+\-~\|&^*]/
             result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
+        when /\A".*"/
+            result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
         else
             raise "Lexer error at #{CodeOrigin.new(fileName, lineNumber).to_s}, unexpected sequence #{str[0..20].inspect}"
         end
@@ -212,6 +214,10 @@
     token =~ /\A[0-9]/
 end
 
+def isString(token)
+    token =~ /\A".*"/
+end
+
 #
 # The parser. Takes an array of tokens and returns an AST. Methods
 # other than parse(tokens) are not for public consumption.
@@ -397,6 +403,10 @@
             result = Immediate.new(@tokens[@idx].codeOrigin, @tokens[@idx].string.to_i)
             @idx += 1
             result
+        elsif isString @tokens[@idx]
+            result = StringLiteral.new(@tokens[@idx].codeOrigin, @tokens[@idx].string)
+            @idx += 1
+            result
         elsif isIdentifier @tokens[@idx]
             codeOrigin, names = parseColonColon
             if names.size > 1
@@ -438,7 +448,7 @@
     end
     
     def couldBeExpression
-        @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or isInteger(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
+        @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or isInteger(@tokens[@idx]) or isString(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
     end
     
     def parseExpressionAdd
diff --git a/Source/JavaScriptCore/offlineasm/sh4.rb b/Source/JavaScriptCore/offlineasm/sh4.rb
index 54c0556..0241f38 100644
--- a/Source/JavaScriptCore/offlineasm/sh4.rb
+++ b/Source/JavaScriptCore/offlineasm/sh4.rb
@@ -1091,18 +1091,6 @@
             else
                 $asm.puts "mov.l #{sh4Operands(operands)}, @-r15"
             end
-        when "popCalleeSaves"
-            $asm.puts "mov.l @r15+, r8"
-            $asm.puts "mov.l @r15+, r9"
-            $asm.puts "mov.l @r15+, r10"
-            $asm.puts "mov.l @r15+, r11"
-            $asm.puts "mov.l @r15+, r13"
-        when "pushCalleeSaves"
-            $asm.puts "mov.l r13, @-r15"
-            $asm.puts "mov.l r11, @-r15"
-            $asm.puts "mov.l r10, @-r15"
-            $asm.puts "mov.l r9, @-r15"
-            $asm.puts "mov.l r8, @-r15"
         when "break"
             # This special opcode always generates an illegal instruction exception.
             $asm.puts ".word 0xfffd"
diff --git a/Source/JavaScriptCore/offlineasm/transform.rb b/Source/JavaScriptCore/offlineasm/transform.rb
index c77bf63..84dd041 100644
--- a/Source/JavaScriptCore/offlineasm/transform.rb
+++ b/Source/JavaScriptCore/offlineasm/transform.rb
@@ -423,6 +423,11 @@
     end
 end
 
+class StringLiteral
+    def validate
+    end
+end
+
 class RegisterID
     def validate
     end
diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb
index 3be1d26..3771956 100644
--- a/Source/JavaScriptCore/offlineasm/x86.rb
+++ b/Source/JavaScriptCore/offlineasm/x86.rb
@@ -1146,38 +1146,6 @@
                 | op |
                 $asm.puts "push #{op.x86Operand(:ptr)}"
             }
-        when "popCalleeSaves"
-            if isX64
-                if isMSVC
-                    $asm.puts "pop " + register("rsi")
-                    $asm.puts "pop " + register("rdi")
-                end
-                $asm.puts "pop " + register("rbx")
-                $asm.puts "pop " + register("r15")
-                $asm.puts "pop " + register("r14")
-                $asm.puts "pop " + register("r13")
-                $asm.puts "pop " + register("r12")
-            else
-                $asm.puts "pop " + register("ebx")
-                $asm.puts "pop " + register("edi")
-                $asm.puts "pop " + register("esi")
-            end
-        when "pushCalleeSaves"
-            if isX64
-                $asm.puts "push " + register("r12")
-                $asm.puts "push " + register("r13")
-                $asm.puts "push " + register("r14")
-                $asm.puts "push " + register("r15")
-                $asm.puts "push " + register("rbx")
-                if isMSVC
-                    $asm.puts "push " + register("rdi")
-                    $asm.puts "push " + register("rsi")
-                end
-            else
-                $asm.puts "push " + register("esi")
-                $asm.puts "push " + register("edi")
-                $asm.puts "push " + register("ebx")
-            end
         when "move"
             handleMove
         when "sxi2q"