2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef ValueRecovery_h
27 #define ValueRecovery_h
29 #include "DataFormat.h"
31 #include "MacroAssembler.h"
32 #include "VirtualRegister.h"
34 #include <wtf/Platform.h>
38 // Describes how to recover a given bytecode virtual register at a given
40 enum ValueRecoveryTechnique
{
41 // It's already in the register file at the right location.
42 AlreadyInRegisterFile
,
43 // It's already in the register file but unboxed.
44 AlreadyInRegisterFileAsUnboxedInt32
,
45 AlreadyInRegisterFileAsUnboxedCell
,
46 AlreadyInRegisterFileAsUnboxedBoolean
,
47 AlreadyInRegisterFileAsUnboxedDouble
,
48 // It's in a register.
57 // It's in the register file, but at a different location.
58 DisplacedInRegisterFile
,
59 // It's in the register file, at a different location, and it's unboxed.
60 Int32DisplacedInRegisterFile
,
61 DoubleDisplacedInRegisterFile
,
62 CellDisplacedInRegisterFile
,
63 BooleanDisplacedInRegisterFile
,
66 // Don't know how to recover it.
73 : m_technique(DontKnow
)
77 static ValueRecovery
alreadyInRegisterFile()
80 result
.m_technique
= AlreadyInRegisterFile
;
84 static ValueRecovery
alreadyInRegisterFileAsUnboxedInt32()
87 result
.m_technique
= AlreadyInRegisterFileAsUnboxedInt32
;
91 static ValueRecovery
alreadyInRegisterFileAsUnboxedCell()
94 result
.m_technique
= AlreadyInRegisterFileAsUnboxedCell
;
98 static ValueRecovery
alreadyInRegisterFileAsUnboxedBoolean()
100 ValueRecovery result
;
101 result
.m_technique
= AlreadyInRegisterFileAsUnboxedBoolean
;
105 static ValueRecovery
alreadyInRegisterFileAsUnboxedDouble()
107 ValueRecovery result
;
108 result
.m_technique
= AlreadyInRegisterFileAsUnboxedDouble
;
112 static ValueRecovery
inGPR(MacroAssembler::RegisterID gpr
, DataFormat dataFormat
)
114 ASSERT(dataFormat
!= DataFormatNone
);
115 #if USE(JSVALUE32_64)
116 ASSERT(dataFormat
== DataFormatInteger
|| dataFormat
== DataFormatCell
|| dataFormat
== DataFormatBoolean
);
118 ValueRecovery result
;
119 if (dataFormat
== DataFormatInteger
)
120 result
.m_technique
= UnboxedInt32InGPR
;
121 else if (dataFormat
== DataFormatBoolean
)
122 result
.m_technique
= UnboxedBooleanInGPR
;
124 result
.m_technique
= InGPR
;
125 result
.m_source
.gpr
= gpr
;
129 static ValueRecovery
uint32InGPR(MacroAssembler::RegisterID gpr
)
131 ValueRecovery result
;
132 result
.m_technique
= UInt32InGPR
;
133 result
.m_source
.gpr
= gpr
;
137 #if USE(JSVALUE32_64)
138 static ValueRecovery
inPair(MacroAssembler::RegisterID tagGPR
, MacroAssembler::RegisterID payloadGPR
)
140 ValueRecovery result
;
141 result
.m_technique
= InPair
;
142 result
.m_source
.pair
.tagGPR
= tagGPR
;
143 result
.m_source
.pair
.payloadGPR
= payloadGPR
;
148 static ValueRecovery
inFPR(MacroAssembler::FPRegisterID fpr
)
150 ValueRecovery result
;
151 result
.m_technique
= InFPR
;
152 result
.m_source
.fpr
= fpr
;
156 static ValueRecovery
displacedInRegisterFile(VirtualRegister virtualReg
, DataFormat dataFormat
)
158 ValueRecovery result
;
159 switch (dataFormat
) {
160 case DataFormatInteger
:
161 result
.m_technique
= Int32DisplacedInRegisterFile
;
164 case DataFormatDouble
:
165 result
.m_technique
= DoubleDisplacedInRegisterFile
;
169 result
.m_technique
= CellDisplacedInRegisterFile
;
172 case DataFormatBoolean
:
173 result
.m_technique
= BooleanDisplacedInRegisterFile
;
177 ASSERT(dataFormat
!= DataFormatNone
&& dataFormat
!= DataFormatStorage
);
178 result
.m_technique
= DisplacedInRegisterFile
;
181 result
.m_source
.virtualReg
= virtualReg
;
185 static ValueRecovery
constant(JSValue value
)
187 ValueRecovery result
;
188 result
.m_technique
= Constant
;
189 result
.m_source
.constant
= JSValue::encode(value
);
193 ValueRecoveryTechnique
technique() const { return m_technique
; }
195 bool isConstant() const { return m_technique
== Constant
; }
197 bool isInRegisters() const
199 switch (m_technique
) {
201 case UnboxedInt32InGPR
:
202 case UnboxedBooleanInGPR
:
203 #if USE(JSVALUE32_64)
213 bool isAlreadyInRegisterFile() const
215 switch (technique()) {
216 case AlreadyInRegisterFile
:
217 case AlreadyInRegisterFileAsUnboxedInt32
:
218 case AlreadyInRegisterFileAsUnboxedCell
:
219 case AlreadyInRegisterFileAsUnboxedBoolean
:
220 case AlreadyInRegisterFileAsUnboxedDouble
:
227 MacroAssembler::RegisterID
gpr() const
229 ASSERT(m_technique
== InGPR
|| m_technique
== UnboxedInt32InGPR
|| m_technique
== UnboxedBooleanInGPR
|| m_technique
== UInt32InGPR
);
233 #if USE(JSVALUE32_64)
234 MacroAssembler::RegisterID
tagGPR() const
236 ASSERT(m_technique
== InPair
);
237 return m_source
.pair
.tagGPR
;
240 MacroAssembler::RegisterID
payloadGPR() const
242 ASSERT(m_technique
== InPair
);
243 return m_source
.pair
.payloadGPR
;
247 MacroAssembler::FPRegisterID
fpr() const
249 ASSERT(m_technique
== InFPR
);
253 VirtualRegister
virtualRegister() const
255 ASSERT(m_technique
== DisplacedInRegisterFile
|| m_technique
== Int32DisplacedInRegisterFile
|| m_technique
== DoubleDisplacedInRegisterFile
|| m_technique
== CellDisplacedInRegisterFile
|| m_technique
== BooleanDisplacedInRegisterFile
);
256 return m_source
.virtualReg
;
259 JSValue
constant() const
261 ASSERT(m_technique
== Constant
);
262 return JSValue::decode(m_source
.constant
);
265 void dump(FILE* out
) const
267 switch (technique()) {
268 case AlreadyInRegisterFile
:
271 case AlreadyInRegisterFileAsUnboxedInt32
:
272 fprintf(out
, "(int32)");
274 case AlreadyInRegisterFileAsUnboxedCell
:
275 fprintf(out
, "(cell)");
277 case AlreadyInRegisterFileAsUnboxedBoolean
:
278 fprintf(out
, "(bool)");
280 case AlreadyInRegisterFileAsUnboxedDouble
:
281 fprintf(out
, "(double)");
284 fprintf(out
, "%%r%d", gpr());
286 case UnboxedInt32InGPR
:
287 fprintf(out
, "int32(%%r%d)", gpr());
289 case UnboxedBooleanInGPR
:
290 fprintf(out
, "bool(%%r%d)", gpr());
293 fprintf(out
, "uint32(%%r%d)", gpr());
296 fprintf(out
, "%%fr%d", fpr());
298 #if USE(JSVALUE32_64)
300 fprintf(out
, "pair(%%r%d, %%r%d)", tagGPR(), payloadGPR());
303 case DisplacedInRegisterFile
:
304 fprintf(out
, "*%d", virtualRegister());
306 case Int32DisplacedInRegisterFile
:
307 fprintf(out
, "*int32(%d)", virtualRegister());
309 case DoubleDisplacedInRegisterFile
:
310 fprintf(out
, "*double(%d)", virtualRegister());
312 case CellDisplacedInRegisterFile
:
313 fprintf(out
, "*cell(%d)", virtualRegister());
315 case BooleanDisplacedInRegisterFile
:
316 fprintf(out
, "*bool(%d)", virtualRegister());
319 fprintf(out
, "[%s]", constant().description());
325 fprintf(out
, "?%d", technique());
331 ValueRecoveryTechnique m_technique
;
333 MacroAssembler::RegisterID gpr
;
334 MacroAssembler::FPRegisterID fpr
;
335 #if USE(JSVALUE32_64)
337 MacroAssembler::RegisterID tagGPR
;
338 MacroAssembler::RegisterID payloadGPR
;
341 VirtualRegister virtualReg
;
342 EncodedJSValue constant
;
348 #endif // ValueRecovery_h