1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=4 sw=4 et tw=99:
4 * ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
20 * The Initial Developer of the Original Code is
21 * Brendan Eich <brendan@mozilla.org>
24 * Sean Stangl <sstangl@mozilla.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #if !defined jsjaeger_assembler64_h__ && defined JS_METHODJIT && defined JS_PUNBOX64
41 #define jsjaeger_assembler64_h__
43 #include "assembler/assembler/MacroAssembler.h"
44 #include "methodjit/MachineRegs.h"
45 #include "methodjit/RematInfo.h"
50 struct Imm64
: JSC::MacroAssembler::ImmPtr
53 : ImmPtr((const void *)u
)
57 /* Tag stored in shifted format. */
58 struct ImmTag
: JSC::MacroAssembler::ImmPtr
60 ImmTag(JSValueShiftedTag shtag
)
61 : ImmPtr((const void *)shtag
)
65 struct ImmType
: ImmTag
67 ImmType(JSValueType type
)
68 : ImmTag(JSValueShiftedTag(JSVAL_TYPE_TO_SHIFTED_TAG(type
)))
72 struct ImmPayload
: Imm64
74 ImmPayload(uint64 payload
)
79 class PunboxAssembler
: public JSC::MacroAssembler
81 static const uint32 PAYLOAD_OFFSET
= 0;
84 static const JSC::MacroAssembler::Scale JSVAL_SCALE
= JSC::MacroAssembler::TimesEight
;
87 T
payloadOf(T address
) {
92 T
valueOf(T address
) {
96 void loadInlineSlot(RegisterID objReg
, uint32 slot
,
97 RegisterID typeReg
, RegisterID dataReg
) {
98 Address
address(objReg
, JSObject::getFixedSlotOffset(slot
));
99 loadValueAsComponents(address
, typeReg
, dataReg
);
102 template <typename T
>
103 void loadValue(T address
, RegisterID dst
) {
104 loadPtr(address
, dst
);
107 void convertValueToType(RegisterID val
) {
108 andPtr(Registers::TypeMaskReg
, val
);
111 void convertValueToPayload(RegisterID val
) {
112 andPtr(Registers::PayloadMaskReg
, val
);
115 // Returns a label after the one Value load.
116 template <typename T
>
117 Label
loadValueAsComponents(T address
, RegisterID type
, RegisterID payload
) {
118 loadValue(address
, type
);
121 move(Registers::PayloadMaskReg
, payload
);
122 andPtr(type
, payload
);
123 xorPtr(payload
, type
);
128 void loadValueAsComponents(const Value
&val
, RegisterID type
, RegisterID payload
) {
129 move(Imm64(val
.asRawBits() & JSVAL_TAG_MASK
), type
);
130 move(Imm64(val
.asRawBits() & JSVAL_PAYLOAD_MASK
), payload
);
133 template <typename T
>
134 void storeValueFromComponents(RegisterID type
, RegisterID payload
, T address
) {
135 move(type
, Registers::ValueReg
);
136 orPtr(payload
, Registers::ValueReg
);
137 storeValue(Registers::ValueReg
, address
);
140 template <typename T
>
141 void storeValueFromComponents(ImmTag type
, RegisterID payload
, T address
) {
142 move(type
, Registers::ValueReg
);
143 orPtr(payload
, Registers::ValueReg
);
144 storeValue(Registers::ValueReg
, address
);
147 template <typename T
>
148 void loadTypeTag(T address
, RegisterID reg
) {
149 loadValue(address
, reg
);
150 convertValueToType(reg
);
153 template <typename T
>
154 void storeTypeTag(ImmTag imm
, T address
) {
155 loadPayload(address
, Registers::ValueReg
);
156 orPtr(imm
, Registers::ValueReg
);
157 storePtr(Registers::ValueReg
, valueOf(address
));
160 template <typename T
>
161 void storeTypeTag(RegisterID reg
, T address
) {
162 /* The type tag must be stored in shifted format. */
163 loadPayload(address
, Registers::ValueReg
);
164 orPtr(reg
, Registers::ValueReg
);
165 storePtr(Registers::ValueReg
, valueOf(address
));
168 template <typename T
>
169 void loadPayload(T address
, RegisterID reg
) {
170 loadValue(address
, reg
);
171 convertValueToPayload(reg
);
174 template <typename T
>
175 void storePayload(RegisterID reg
, T address
) {
176 /* Not for doubles. */
177 loadTypeTag(address
, Registers::ValueReg
);
178 orPtr(reg
, Registers::ValueReg
);
179 storePtr(Registers::ValueReg
, valueOf(address
));
182 template <typename T
>
183 void storePayload(ImmPayload imm
, T address
) {
184 /* Not for doubles. */
185 storePtr(imm
, valueOf(address
));
188 template <typename T
>
189 void storeValue(RegisterID reg
, T address
) {
190 storePtr(reg
, valueOf(address
));
193 template <typename T
>
194 void storeValue(const Value
&v
, T address
) {
196 jv
.asBits
= JSVAL_BITS(Jsvalify(v
));
198 storePtr(Imm64(jv
.asBits
), valueOf(address
));
201 template <typename T
>
202 void storeValue(const ValueRemat
&vr
, T address
) {
204 storeValue(vr
.value(), address
);
205 else if (vr
.isTypeKnown())
206 storeValueFromComponents(ImmType(vr
.knownType()), vr
.dataReg(), address
);
208 storeValueFromComponents(vr
.typeReg(), vr
.dataReg(), address
);
211 void loadPrivate(Address privAddr
, RegisterID to
) {
212 loadPtr(privAddr
, to
);
213 lshiftPtr(Imm32(1), to
);
216 void loadFunctionPrivate(RegisterID base
, RegisterID to
) {
217 Address
priv(base
, offsetof(JSObject
, privateData
));
221 Jump
testNull(Condition cond
, RegisterID reg
) {
222 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_NULL
));
225 Jump
testNull(Condition cond
, Address address
) {
226 loadValue(address
, Registers::ValueReg
);
227 return testNull(cond
, Registers::ValueReg
);
230 Jump
testUndefined(Condition cond
, RegisterID reg
) {
231 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_UNDEFINED
));
234 Jump
testUndefined(Condition cond
, Address address
) {
235 loadValue(address
, Registers::ValueReg
);
236 return testUndefined(cond
, Registers::ValueReg
);
239 Jump
testInt32(Condition cond
, RegisterID reg
) {
240 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_INT32
));
243 Jump
testInt32(Condition cond
, Address address
) {
244 loadTypeTag(address
, Registers::ValueReg
);
245 return testInt32(cond
, Registers::ValueReg
);
248 Jump
testNumber(Condition cond
, RegisterID reg
) {
249 cond
= (cond
== Equal
) ? Below
: AboveOrEqual
;
250 return branchPtr(cond
, reg
,
251 ImmTag(JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET
));
254 Jump
testNumber(Condition cond
, Address address
) {
255 loadValue(address
, Registers::ValueReg
);
256 return testNumber(cond
, Registers::ValueReg
);
259 Jump
testPrimitive(Condition cond
, RegisterID reg
) {
260 cond
= (cond
== Equal
) ? Below
: AboveOrEqual
;
261 return branchPtr(cond
, reg
,
262 ImmTag(JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET
));
265 Jump
testPrimitive(Condition cond
, Address address
) {
266 loadValue(address
, Registers::ValueReg
);
267 return testPrimitive(cond
, Registers::ValueReg
);
270 Jump
testObject(Condition cond
, RegisterID reg
) {
271 cond
= (cond
== Equal
) ? AboveOrEqual
: Below
;
272 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_OBJECT
));
275 Jump
testObject(Condition cond
, Address address
) {
276 loadValue(address
, Registers::ValueReg
);
277 return testObject(cond
, Registers::ValueReg
);
280 Jump
testDouble(Condition cond
, RegisterID reg
) {
281 cond
= (cond
== Equal
) ? BelowOrEqual
: Above
;
282 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_MAX_DOUBLE
));
285 Jump
testDouble(Condition cond
, Address address
) {
286 loadValue(address
, Registers::ValueReg
);
287 return testDouble(cond
, Registers::ValueReg
);
290 Jump
testBoolean(Condition cond
, RegisterID reg
) {
291 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_BOOLEAN
));
294 Jump
testBoolean(Condition cond
, Address address
) {
295 loadTypeTag(address
, Registers::ValueReg
);
296 return testBoolean(cond
, Registers::ValueReg
);
299 Jump
testString(Condition cond
, RegisterID reg
) {
300 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_STRING
));
303 Jump
testString(Condition cond
, Address address
) {
304 loadTypeTag(address
, Registers::ValueReg
);
305 return testString(cond
, Registers::ValueReg
);
308 template <typename T
>
309 Jump
fastArrayLoadSlot(T address
, RegisterID typeReg
, RegisterID dataReg
) {
310 loadValueAsComponents(address
, typeReg
, dataReg
);
311 return branchPtr(Equal
, typeReg
, ImmType(JSVAL_TYPE_MAGIC
));
315 typedef PunboxAssembler ValueAssembler
;
317 } /* namespace mjit */