Only generate offline asm for the ARCHS (xcodebuild) or the current system (CMake)
[WebKit-https.git] / Source / JavaScriptCore / offlineasm / backends.rb
1 # Copyright (C) 2011, 2016 Apple Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
5 # are met:
6 # 1. Redistributions of source code must retain the above copyright
7 #    notice, this list of conditions and the following disclaimer.
8 # 2. Redistributions in binary form must reproduce the above copyright
9 #    notice, this list of conditions and the following disclaimer in the
10 #    documentation and/or other materials provided with the distribution.
11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22 # THE POSSIBILITY OF SUCH DAMAGE.
23
24 require "config"
25 require "arm"
26 require "arm64"
27 require "ast"
28 require "x86"
29 require "mips"
30 require "cloop"
31
32 BACKENDS =
33     [
34      "X86",
35      "X86_WIN",
36      "X86_64",
37      "X86_64_WIN",
38      "ARM",
39      "ARMv7",
40      "ARMv7_TRADITIONAL",
41      "ARM64",
42      "MIPS",
43      "C_LOOP"
44     ]
45
46 # Keep the set of working backends separate from the set of backends that might be
47 # supported. This is great because the BACKENDS list is almost like a reserved
48 # words list, in that it causes settings resolution to treat those words specially.
49 # Hence this lets us set aside the name of a backend we might want to support in
50 # the future while not actually supporting the backend yet.
51 WORKING_BACKENDS =
52     [
53      "X86",
54      "X86_WIN",
55      "X86_64",
56      "X86_64_WIN",
57      "ARM",
58      "ARMv7",
59      "ARMv7_TRADITIONAL",
60      "ARM64",
61      "MIPS",
62      "C_LOOP"
63     ]
64
65 BACKEND_PATTERN = Regexp.new('\\A(' + BACKENDS.join(')|(') + ')\\Z')
66
67 $allBackends = {}
68 $validBackends = {}
69 BACKENDS.each {
70     | backend |
71     $validBackends[backend] = true
72     $allBackends[backend] = true
73 }
74
75 def canonicalizeBackendNames(backendNames)
76     newBackendNames = []
77     backendNames.each {
78         | backendName |
79         backendName = backendName.upcase
80         if backendName =~ /ARM.*/
81             backendName.sub!(/ARMV7(S?)(.*)/) { | _ | 'ARMv7' + $1.downcase + $2 }
82         end
83         backendName = "X86" if backendName == "I386"
84         newBackendNames << backendName
85         newBackendNames << "ARMv7" if backendName == "ARMv7s"
86     }
87     newBackendNames.uniq
88 end
89
90 def includeOnlyBackends(list)
91     newValidBackends = {}
92     list.each {
93         | backend |
94         if $validBackends[backend]
95             newValidBackends[backend] = true
96         end
97     }
98     $validBackends = newValidBackends
99 end
100
101 def isBackend?(backend)
102     $allBackends[backend]
103 end
104
105 def isValidBackend?(backend)
106     $validBackends[backend]
107 end
108
109 def validBackends
110     $validBackends.keys
111 end
112
113 class LoweringError < StandardError
114     attr_reader :originString
115     
116     def initialize(e, originString)
117         super "#{e} (due to #{originString})"
118         @originString = originString
119         set_backtrace e.backtrace
120     end
121 end
122
123 class Node
124     def lower(name)
125         begin
126             $activeBackend = name
127             send("lower" + name)
128         rescue => e
129             raise LoweringError.new(e, codeOriginString)
130         end
131     end
132 end
133
134 # Overrides for lower() for those nodes that are backend-agnostic
135
136 class Label
137     def lower(name)
138         $asm.debugAnnotation codeOrigin.debugDirective if $enableDebugAnnotations
139         $asm.putsLabel(self.name[1..-1], @global)
140     end
141 end
142
143 class LocalLabel
144     def lower(name)
145         $asm.putsLocalLabel "_offlineasm_#{self.name[1..-1]}"
146     end
147 end
148
149 class LabelReference
150     def asmLabel
151         if extern?
152             Assembler.externLabelReference(name[1..-1])
153         else
154             Assembler.labelReference(name[1..-1])
155         end
156     end
157
158     def cLabel
159         Assembler.cLabelReference(name[1..-1])
160     end
161 end
162
163 class LocalLabelReference
164     def asmLabel
165         Assembler.localLabelReference("_offlineasm_"+name[1..-1])
166     end
167
168     def cLabel
169         Assembler.cLocalLabelReference("_offlineasm_"+name[1..-1])
170     end
171 end
172
173 class Skip
174     def lower(name)
175     end
176 end
177
178 class Sequence
179     def lower(name)
180         $activeBackend = name
181         if respond_to? "getModifiedList#{name}"
182             newList = send("getModifiedList#{name}")
183             newList.each {
184                 | node |
185                 node.lower(name)
186             }
187         elsif respond_to? "lower#{name}"
188             send("lower#{name}")
189         else
190             @list.each {
191                 | node |
192                 node.lower(name)
193             }
194         end
195     end
196 end
197