initial import
[vuplus_webkit] / Source / JavaScriptCore / assembler / MacroAssembler.h
1 /*
2  * Copyright (C) 2008 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef MacroAssembler_h
27 #define MacroAssembler_h
28
29 #if ENABLE(ASSEMBLER)
30
31 #if CPU(ARM_THUMB2)
32 #include "MacroAssemblerARMv7.h"
33 namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; };
34
35 #elif CPU(ARM_TRADITIONAL)
36 #include "MacroAssemblerARM.h"
37 namespace JSC { typedef MacroAssemblerARM MacroAssemblerBase; };
38
39 #elif CPU(MIPS)
40 #include "MacroAssemblerMIPS.h"
41 namespace JSC {
42 typedef MacroAssemblerMIPS MacroAssemblerBase;
43 };
44
45 #elif CPU(X86)
46 #include "MacroAssemblerX86.h"
47 namespace JSC { typedef MacroAssemblerX86 MacroAssemblerBase; };
48
49 #elif CPU(X86_64)
50 #include "MacroAssemblerX86_64.h"
51 namespace JSC { typedef MacroAssemblerX86_64 MacroAssemblerBase; };
52
53 #elif CPU(SH4)
54 #include "MacroAssemblerSH4.h"
55 namespace JSC {
56 typedef MacroAssemblerSH4 MacroAssemblerBase;
57 };
58
59 #else
60 #error "The MacroAssembler is not supported on this platform."
61 #endif
62
63
64 namespace JSC {
65
66 class MacroAssembler : public MacroAssemblerBase {
67 public:
68
69     using MacroAssemblerBase::pop;
70     using MacroAssemblerBase::jump;
71     using MacroAssemblerBase::branch32;
72     using MacroAssemblerBase::branch16;
73 #if CPU(X86_64)
74     using MacroAssemblerBase::branchPtr;
75     using MacroAssemblerBase::branchTestPtr;
76 #endif
77
78
79     // Platform agnostic onvenience functions,
80     // described in terms of other macro assembly methods.
81     void pop()
82     {
83         addPtr(TrustedImm32(sizeof(void*)), stackPointerRegister);
84     }
85     
86     void peek(RegisterID dest, int index = 0)
87     {
88         loadPtr(Address(stackPointerRegister, (index * sizeof(void*))), dest);
89     }
90
91     void poke(RegisterID src, int index = 0)
92     {
93         storePtr(src, Address(stackPointerRegister, (index * sizeof(void*))));
94     }
95
96     void poke(TrustedImm32 value, int index = 0)
97     {
98         store32(value, Address(stackPointerRegister, (index * sizeof(void*))));
99     }
100
101     void poke(TrustedImmPtr imm, int index = 0)
102     {
103         storePtr(imm, Address(stackPointerRegister, (index * sizeof(void*))));
104     }
105
106
107     // Backwards banches, these are currently all implemented using existing forwards branch mechanisms.
108     void branchPtr(RelationalCondition cond, RegisterID op1, TrustedImmPtr imm, Label target)
109     {
110         branchPtr(cond, op1, imm).linkTo(target, this);
111     }
112
113     void branch32(RelationalCondition cond, RegisterID op1, RegisterID op2, Label target)
114     {
115         branch32(cond, op1, op2).linkTo(target, this);
116     }
117
118     void branch32(RelationalCondition cond, RegisterID op1, TrustedImm32 imm, Label target)
119     {
120         branch32(cond, op1, imm).linkTo(target, this);
121     }
122
123     void branch32(RelationalCondition cond, RegisterID left, Address right, Label target)
124     {
125         branch32(cond, left, right).linkTo(target, this);
126     }
127
128     Jump branch32(RelationalCondition cond, TrustedImm32 left, RegisterID right)
129     {
130         return branch32(commute(cond), right, left);
131     }
132
133     void branch16(RelationalCondition cond, BaseIndex left, RegisterID right, Label target)
134     {
135         branch16(cond, left, right).linkTo(target, this);
136     }
137     
138     void branchTestPtr(ResultCondition cond, RegisterID reg, Label target)
139     {
140         branchTestPtr(cond, reg).linkTo(target, this);
141     }
142
143     void jump(Label target)
144     {
145         jump().linkTo(target, this);
146     }
147
148     // Commute a relational condition, returns a new condition that will produce
149     // the same results given the same inputs but with their positions exchanged.
150     static RelationalCondition commute(RelationalCondition condition)
151     {
152         switch (condition) {
153         case Above:
154             return Below;
155         case AboveOrEqual:
156             return BelowOrEqual;
157         case Below:
158             return Above;
159         case BelowOrEqual:
160             return AboveOrEqual;
161         case GreaterThan:
162             return LessThan;
163         case GreaterThanOrEqual:
164             return LessThanOrEqual;
165         case LessThan:
166             return GreaterThan;
167         case LessThanOrEqual:
168             return GreaterThanOrEqual;
169         default:
170             break;
171         }
172
173         ASSERT(condition == Equal || condition == NotEqual);
174         return condition;
175     }
176     
177
178     // Ptr methods
179     // On 32-bit platforms (i.e. x86), these methods directly map onto their 32-bit equivalents.
180     // FIXME: should this use a test for 32-bitness instead of this specific exception?
181 #if !CPU(X86_64)
182     void addPtr(RegisterID src, RegisterID dest)
183     {
184         add32(src, dest);
185     }
186
187     void addPtr(TrustedImm32 imm, RegisterID srcDest)
188     {
189         add32(imm, srcDest);
190     }
191
192     void addPtr(TrustedImmPtr imm, RegisterID dest)
193     {
194         add32(TrustedImm32(imm), dest);
195     }
196
197     void addPtr(TrustedImm32 imm, RegisterID src, RegisterID dest)
198     {
199         add32(imm, src, dest);
200     }
201
202     void andPtr(RegisterID src, RegisterID dest)
203     {
204         and32(src, dest);
205     }
206
207     void andPtr(TrustedImm32 imm, RegisterID srcDest)
208     {
209         and32(imm, srcDest);
210     }
211
212     void orPtr(RegisterID src, RegisterID dest)
213     {
214         or32(src, dest);
215     }
216
217     void orPtr(TrustedImmPtr imm, RegisterID dest)
218     {
219         or32(TrustedImm32(imm), dest);
220     }
221
222     void orPtr(TrustedImm32 imm, RegisterID dest)
223     {
224         or32(imm, dest);
225     }
226
227     void subPtr(RegisterID src, RegisterID dest)
228     {
229         sub32(src, dest);
230     }
231     
232     void subPtr(TrustedImm32 imm, RegisterID dest)
233     {
234         sub32(imm, dest);
235     }
236     
237     void subPtr(TrustedImmPtr imm, RegisterID dest)
238     {
239         sub32(TrustedImm32(imm), dest);
240     }
241
242     void xorPtr(RegisterID src, RegisterID dest)
243     {
244         xor32(src, dest);
245     }
246
247     void xorPtr(TrustedImm32 imm, RegisterID srcDest)
248     {
249         xor32(imm, srcDest);
250     }
251
252
253     void loadPtr(ImplicitAddress address, RegisterID dest)
254     {
255         load32(address, dest);
256     }
257
258     void loadPtr(BaseIndex address, RegisterID dest)
259     {
260         load32(address, dest);
261     }
262
263     void loadPtr(void* address, RegisterID dest)
264     {
265         load32(address, dest);
266     }
267
268     DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
269     {
270         return load32WithAddressOffsetPatch(address, dest);
271     }
272     
273     DataLabelCompact loadPtrWithCompactAddressOffsetPatch(Address address, RegisterID dest)
274     {
275         return load32WithCompactAddressOffsetPatch(address, dest);
276     }
277
278     void comparePtr(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
279     {
280         compare32(cond, left, right, dest);
281     }
282
283     void storePtr(RegisterID src, ImplicitAddress address)
284     {
285         store32(src, address);
286     }
287
288     void storePtr(RegisterID src, BaseIndex address)
289     {
290         store32(src, address);
291     }
292
293     void storePtr(RegisterID src, void* address)
294     {
295         store32(src, address);
296     }
297
298     void storePtr(TrustedImmPtr imm, ImplicitAddress address)
299     {
300         store32(TrustedImm32(imm), address);
301     }
302
303     void storePtr(TrustedImmPtr imm, void* address)
304     {
305         store32(TrustedImm32(imm), address);
306     }
307
308     DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
309     {
310         return store32WithAddressOffsetPatch(src, address);
311     }
312
313
314     Jump branchPtr(RelationalCondition cond, RegisterID left, RegisterID right)
315     {
316         return branch32(cond, left, right);
317     }
318
319     Jump branchPtr(RelationalCondition cond, RegisterID left, TrustedImmPtr right)
320     {
321         return branch32(cond, left, TrustedImm32(right));
322     }
323
324     Jump branchPtr(RelationalCondition cond, RegisterID left, Address right)
325     {
326         return branch32(cond, left, right);
327     }
328
329     Jump branchPtr(RelationalCondition cond, Address left, RegisterID right)
330     {
331         return branch32(cond, left, right);
332     }
333
334     Jump branchPtr(RelationalCondition cond, AbsoluteAddress left, RegisterID right)
335     {
336         return branch32(cond, left, right);
337     }
338
339     Jump branchPtr(RelationalCondition cond, Address left, TrustedImmPtr right)
340     {
341         return branch32(cond, left, TrustedImm32(right));
342     }
343
344     Jump branchPtr(RelationalCondition cond, AbsoluteAddress left, TrustedImmPtr right)
345     {
346         return branch32(cond, left, TrustedImm32(right));
347     }
348
349     Jump branchTestPtr(ResultCondition cond, RegisterID reg, RegisterID mask)
350     {
351         return branchTest32(cond, reg, mask);
352     }
353
354     Jump branchTestPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
355     {
356         return branchTest32(cond, reg, mask);
357     }
358
359     Jump branchTestPtr(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
360     {
361         return branchTest32(cond, address, mask);
362     }
363
364     Jump branchTestPtr(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
365     {
366         return branchTest32(cond, address, mask);
367     }
368
369
370     Jump branchAddPtr(ResultCondition cond, RegisterID src, RegisterID dest)
371     {
372         return branchAdd32(cond, src, dest);
373     }
374
375     Jump branchSubPtr(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
376     {
377         return branchSub32(cond, imm, dest);
378     }
379     using MacroAssemblerBase::branchTest8;
380     Jump branchTest8(ResultCondition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1))
381     {
382         return MacroAssemblerBase::branchTest8(cond, Address(address.base, address.offset), mask);
383     }
384 #endif
385
386 };
387
388 } // namespace JSC
389
390 #endif // ENABLE(ASSEMBLER)
391
392 #endif // MacroAssembler_h