]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGGPRInfo.h
JavaScriptCore-1097.13.tar.gz
[apple/javascriptcore.git] / dfg / DFGGPRInfo.h
CommitLineData
14957cd0
A
1/*
2 * Copyright (C) 2011 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 DFGGPRInfo_h
27#define DFGGPRInfo_h
28
29#if ENABLE(DFG_JIT)
30
31#include <assembler/MacroAssembler.h>
32#include <dfg/DFGRegisterBank.h>
33
34namespace JSC { namespace DFG {
35
36typedef MacroAssembler::RegisterID GPRReg;
37#define InvalidGPRReg ((GPRReg)-1)
38
6fe7ccc8
A
39#if USE(JSVALUE64)
40class JSValueRegs {
41public:
42 JSValueRegs()
43 : m_gpr(InvalidGPRReg)
44 {
45 }
46
47 explicit JSValueRegs(GPRReg gpr)
48 : m_gpr(gpr)
49 {
50 }
51
52 bool operator!() const { return m_gpr == InvalidGPRReg; }
53
54 GPRReg gpr() const { return m_gpr; }
55
56private:
57 GPRReg m_gpr;
58};
59
60class JSValueSource {
61public:
62 JSValueSource()
63 : m_offset(notAddress())
64 , m_base(InvalidGPRReg)
65 {
66 }
67
68 JSValueSource(JSValueRegs regs)
69 : m_offset(notAddress())
70 , m_base(regs.gpr())
71 {
72 }
73
74 explicit JSValueSource(GPRReg gpr)
75 : m_offset(notAddress())
76 , m_base(gpr)
77 {
78 }
79
80 JSValueSource(MacroAssembler::Address address)
81 : m_offset(address.offset)
82 , m_base(address.base)
83 {
84 ASSERT(m_offset != notAddress());
85 ASSERT(m_base != InvalidGPRReg);
86 }
87
88 static JSValueSource unboxedCell(GPRReg payloadGPR)
89 {
90 return JSValueSource(payloadGPR);
91 }
92
93 bool operator!() const { return m_base == InvalidGPRReg; }
94
95 bool isAddress() const { return m_offset != notAddress(); }
96
97 int32_t offset() const
98 {
99 ASSERT(isAddress());
100 return m_offset;
101 }
102
103 GPRReg base() const
104 {
105 ASSERT(isAddress());
106 return m_base;
107 }
108
109 GPRReg gpr() const
110 {
111 ASSERT(!isAddress());
112 return m_base;
113 }
114
115 MacroAssembler::Address asAddress() const { return MacroAssembler::Address(base(), offset()); }
116
117private:
118 static inline int32_t notAddress() { return 0x80000000; }
119
120 int32_t m_offset;
121 GPRReg m_base;
122};
123#endif
124
125#if USE(JSVALUE32_64)
126class JSValueRegs {
127public:
128 JSValueRegs()
129 : m_tagGPR(static_cast<int8_t>(InvalidGPRReg))
130 , m_payloadGPR(static_cast<int8_t>(InvalidGPRReg))
131 {
132 }
133
134 JSValueRegs(GPRReg tagGPR, GPRReg payloadGPR)
135 : m_tagGPR(tagGPR)
136 , m_payloadGPR(payloadGPR)
137 {
138 ASSERT((static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg) == (static_cast<GPRReg>(payloadGPR) == InvalidGPRReg));
139 }
140
141 bool operator!() const { return static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg; }
142
143 GPRReg tagGPR() const { return static_cast<GPRReg>(m_tagGPR); }
144 GPRReg payloadGPR() const { return static_cast<GPRReg>(m_payloadGPR); }
145
146private:
147 int8_t m_tagGPR;
148 int8_t m_payloadGPR;
149};
150
151class JSValueSource {
152public:
153 JSValueSource()
154 : m_offset(notAddress())
155 , m_baseOrTag(static_cast<int8_t>(InvalidGPRReg))
156 , m_payload(static_cast<int8_t>(InvalidGPRReg))
157 , m_tagType(0)
158 {
159 }
160
161 JSValueSource(JSValueRegs regs)
162 : m_offset(notAddress())
163 , m_baseOrTag(regs.tagGPR())
164 , m_payload(regs.payloadGPR())
165 , m_tagType(0)
166 {
167 }
168
169 JSValueSource(GPRReg tagGPR, GPRReg payloadGPR)
170 : m_offset(notAddress())
171 , m_baseOrTag(static_cast<int8_t>(tagGPR))
172 , m_payload(static_cast<int8_t>(payloadGPR))
173 , m_tagType(0)
174 {
175 }
176
177 JSValueSource(MacroAssembler::Address address)
178 : m_offset(address.offset)
179 , m_baseOrTag(static_cast<int8_t>(address.base))
180 , m_payload(static_cast<int8_t>(InvalidGPRReg))
181 , m_tagType(0)
182 {
183 ASSERT(m_offset != notAddress());
184 ASSERT(static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg);
185 }
186
187 static JSValueSource unboxedCell(GPRReg payloadGPR)
188 {
189 JSValueSource result;
190 result.m_offset = notAddress();
191 result.m_baseOrTag = static_cast<int8_t>(InvalidGPRReg);
192 result.m_payload = static_cast<int8_t>(payloadGPR);
193 result.m_tagType = static_cast<int8_t>(JSValue::CellTag);
194 return result;
195 }
196
197 bool operator!() const { return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg && static_cast<GPRReg>(m_payload) == InvalidGPRReg; }
198
199 bool isAddress() const
200 {
201 ASSERT(!!*this);
202 return m_offset != notAddress();
203 }
204
205 int32_t offset() const
206 {
207 ASSERT(isAddress());
208 return m_offset;
209 }
210
211 GPRReg base() const
212 {
213 ASSERT(isAddress());
214 return static_cast<GPRReg>(m_baseOrTag);
215 }
216
217 GPRReg tagGPR() const
218 {
219 ASSERT(!isAddress() && m_baseOrTag != InvalidGPRReg);
220 return static_cast<GPRReg>(m_baseOrTag);
221 }
222
223 GPRReg payloadGPR() const
224 {
225 ASSERT(!isAddress());
226 return static_cast<GPRReg>(m_payload);
227 }
228
229 bool hasKnownTag() const
230 {
231 ASSERT(!!*this);
232 ASSERT(!isAddress());
233 return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg;
234 }
235
236 uint32_t tag() const
237 {
238 return static_cast<int32_t>(m_tagType);
239 }
240
241 MacroAssembler::Address asAddress(unsigned additionalOffset = 0) const { return MacroAssembler::Address(base(), offset() + additionalOffset); }
242
243private:
244 static inline int32_t notAddress() { return 0x80000000; }
245
246 int32_t m_offset;
247 int8_t m_baseOrTag;
248 int8_t m_payload;
249 int8_t m_tagType; // Contains the low bits of the tag.
250};
251#endif
252
253#if CPU(X86)
254#define NUMBER_OF_ARGUMENT_REGISTERS 0
255
256class GPRInfo {
257public:
258 typedef GPRReg RegisterType;
259 static const unsigned numberOfRegisters = 5;
260
261 // Temporary registers.
262 static const GPRReg regT0 = X86Registers::eax;
263 static const GPRReg regT1 = X86Registers::edx;
264 static const GPRReg regT2 = X86Registers::ecx;
265 static const GPRReg regT3 = X86Registers::ebx;
266 static const GPRReg regT4 = X86Registers::esi;
267 // These registers match the baseline JIT.
268 static const GPRReg cachedResultRegister = regT0;
269 static const GPRReg cachedResultRegister2 = regT1;
270 static const GPRReg callFrameRegister = X86Registers::edi;
271 // These constants provide the names for the general purpose argument & return value registers.
272 static const GPRReg argumentGPR0 = X86Registers::ecx; // regT2
273 static const GPRReg argumentGPR1 = X86Registers::edx; // regT1
274 static const GPRReg returnValueGPR = X86Registers::eax; // regT0
275 static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
276 static const GPRReg nonPreservedNonReturnGPR = X86Registers::ecx;
277
278 static GPRReg toRegister(unsigned index)
279 {
280 ASSERT(index < numberOfRegisters);
281 static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4 };
282 return registerForIndex[index];
283 }
284
285 static unsigned toIndex(GPRReg reg)
286 {
287 ASSERT(reg != InvalidGPRReg);
288 ASSERT(reg < 8);
289 static const unsigned indexForRegister[8] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 4, InvalidIndex };
290 unsigned result = indexForRegister[reg];
291 ASSERT(result != InvalidIndex);
292 return result;
293 }
294
295 static const char* debugName(GPRReg reg)
296 {
297 ASSERT(reg != InvalidGPRReg);
298 ASSERT(reg < 8);
299 static const char* nameForRegister[8] = {
300 "eax", "ecx", "edx", "ebx",
301 "esp", "ebp", "esi", "edi",
302 };
303 return nameForRegister[reg];
304 }
305private:
306
307 static const unsigned InvalidIndex = 0xffffffff;
308};
309
310#endif
311
312#if CPU(X86_64)
313#define NUMBER_OF_ARGUMENT_REGISTERS 6
314
14957cd0
A
315class GPRInfo {
316public:
317 typedef GPRReg RegisterType;
318 static const unsigned numberOfRegisters = 9;
319
6fe7ccc8
A
320 // These registers match the baseline JIT.
321 static const GPRReg cachedResultRegister = X86Registers::eax;
14957cd0
A
322 static const GPRReg timeoutCheckRegister = X86Registers::r12;
323 static const GPRReg callFrameRegister = X86Registers::r13;
324 static const GPRReg tagTypeNumberRegister = X86Registers::r14;
325 static const GPRReg tagMaskRegister = X86Registers::r15;
326 // Temporary registers.
327 static const GPRReg regT0 = X86Registers::eax;
328 static const GPRReg regT1 = X86Registers::edx;
329 static const GPRReg regT2 = X86Registers::ecx;
330 static const GPRReg regT3 = X86Registers::ebx;
331 static const GPRReg regT4 = X86Registers::edi;
332 static const GPRReg regT5 = X86Registers::esi;
333 static const GPRReg regT6 = X86Registers::r8;
334 static const GPRReg regT7 = X86Registers::r9;
335 static const GPRReg regT8 = X86Registers::r10;
336 // These constants provide the names for the general purpose argument & return value registers.
337 static const GPRReg argumentGPR0 = X86Registers::edi; // regT4
338 static const GPRReg argumentGPR1 = X86Registers::esi; // regT5
339 static const GPRReg argumentGPR2 = X86Registers::edx; // regT1
340 static const GPRReg argumentGPR3 = X86Registers::ecx; // regT2
6fe7ccc8
A
341 static const GPRReg argumentGPR4 = X86Registers::r8; // regT6
342 static const GPRReg argumentGPR5 = X86Registers::r9; // regT7
14957cd0
A
343 static const GPRReg returnValueGPR = X86Registers::eax; // regT0
344 static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
6fe7ccc8 345 static const GPRReg nonPreservedNonReturnGPR = X86Registers::esi;
14957cd0
A
346
347 static GPRReg toRegister(unsigned index)
348 {
349 ASSERT(index < numberOfRegisters);
350 static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regT8 };
351 return registerForIndex[index];
352 }
353
354 static unsigned toIndex(GPRReg reg)
355 {
356 ASSERT(reg != InvalidGPRReg);
357 ASSERT(reg < 16);
358 static const unsigned indexForRegister[16] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 5, 4, 6, 7, 8, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
359 unsigned result = indexForRegister[reg];
360 ASSERT(result != InvalidIndex);
361 return result;
362 }
363
14957cd0
A
364 static const char* debugName(GPRReg reg)
365 {
366 ASSERT(reg != InvalidGPRReg);
367 ASSERT(reg < 16);
368 static const char* nameForRegister[16] = {
369 "rax", "rcx", "rdx", "rbx",
370 "rsp", "rbp", "rsi", "rdi",
371 "r8", "r9", "r10", "r11",
372 "r12", "r13", "r14", "r15"
373 };
374 return nameForRegister[reg];
375 }
6fe7ccc8
A
376private:
377
378 static const unsigned InvalidIndex = 0xffffffff;
379};
380
14957cd0 381#endif
6fe7ccc8
A
382
383#if CPU(ARM_THUMB2)
384#define NUMBER_OF_ARGUMENT_REGISTERS 4
385
386class GPRInfo {
387public:
388 typedef GPRReg RegisterType;
389 static const unsigned numberOfRegisters = 8;
390
391 // Temporary registers.
392 static const GPRReg regT0 = ARMRegisters::r0;
393 static const GPRReg regT1 = ARMRegisters::r1;
394 static const GPRReg regT2 = ARMRegisters::r2;
395 static const GPRReg regT3 = ARMRegisters::r4;
396 static const GPRReg regT4 = ARMRegisters::r8;
397 static const GPRReg regT5 = ARMRegisters::r9;
398 static const GPRReg regT6 = ARMRegisters::r10;
399 static const GPRReg regT7 = ARMRegisters::r11;
400 // These registers match the baseline JIT.
401 static const GPRReg cachedResultRegister = regT0;
402 static const GPRReg cachedResultRegister2 = regT1;
403 static const GPRReg callFrameRegister = ARMRegisters::r5;
404 // These constants provide the names for the general purpose argument & return value registers.
405 static const GPRReg argumentGPR0 = ARMRegisters::r0; // regT0
406 static const GPRReg argumentGPR1 = ARMRegisters::r1; // regT1
407 static const GPRReg argumentGPR2 = ARMRegisters::r2; // regT2
408 // FIXME: r3 is currently used be the MacroAssembler as a temporary - it seems
409 // This could threoretically be a problem if theis is used in code generation
410 // between the arguments being set up, and the call being made. That said,
411 // any change introducing a problem here is likely to be immediately apparent!
412 static const GPRReg argumentGPR3 = ARMRegisters::r3; // FIXME!
413 static const GPRReg returnValueGPR = ARMRegisters::r0; // regT0
414 static const GPRReg returnValueGPR2 = ARMRegisters::r1; // regT1
415 static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r2;
416
417 static GPRReg toRegister(unsigned index)
418 {
419 ASSERT(index < numberOfRegisters);
420 static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7 };
421 return registerForIndex[index];
422 }
423
424 static unsigned toIndex(GPRReg reg)
425 {
426 ASSERT(reg != InvalidGPRReg);
427 ASSERT(reg < 16);
428 static const unsigned indexForRegister[16] = { 0, 1, 2, InvalidIndex, 3, InvalidIndex, InvalidIndex, InvalidIndex, 4, 5, 6, 7, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
429 unsigned result = indexForRegister[reg];
430 ASSERT(result != InvalidIndex);
431 return result;
432 }
433
434 static const char* debugName(GPRReg reg)
435 {
436 ASSERT(reg != InvalidGPRReg);
437 ASSERT(reg < 16);
438 static const char* nameForRegister[16] = {
439 "r0", "r1", "r2", "r3",
440 "r4", "r5", "r6", "r7",
441 "r8", "r9", "r10", "r11",
442 "r12", "r13", "r14", "r15"
443 };
444 return nameForRegister[reg];
445 }
14957cd0
A
446private:
447
448 static const unsigned InvalidIndex = 0xffffffff;
449};
450
6fe7ccc8
A
451#endif
452
14957cd0
A
453typedef RegisterBank<GPRInfo>::iterator gpr_iterator;
454
455} } // namespace JSC::DFG
456
457#endif
458#endif