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 "methodjit/BaseAssembler.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 Assembler
: public BaseAssembler
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 loadSlot(RegisterID obj
, RegisterID clobber
, uint32 slot
, bool inlineAccess
,
97 RegisterID type
, RegisterID data
) {
98 JS_ASSERT(type
!= data
);
99 Address
address(obj
, JSObject::getFixedSlotOffset(slot
));
101 loadPtr(Address(obj
, offsetof(JSObject
, slots
)), clobber
);
102 address
= Address(clobber
, slot
* sizeof(Value
));
105 loadValueAsComponents(address
, type
, data
);
108 template <typename T
>
109 void loadValue(T address
, RegisterID dst
) {
110 loadPtr(address
, dst
);
113 void convertValueToType(RegisterID val
) {
114 andPtr(Registers::TypeMaskReg
, val
);
117 void convertValueToPayload(RegisterID val
) {
118 andPtr(Registers::PayloadMaskReg
, val
);
121 // Returns a label after the one Value load.
122 template <typename T
>
123 Label
loadValueAsComponents(T address
, RegisterID type
, RegisterID payload
) {
124 loadValue(address
, type
);
127 move(Registers::PayloadMaskReg
, payload
);
128 andPtr(type
, payload
);
129 xorPtr(payload
, type
);
134 void loadValueAsComponents(const Value
&val
, RegisterID type
, RegisterID payload
) {
135 move(Imm64(val
.asRawBits() & JSVAL_TAG_MASK
), type
);
136 move(Imm64(val
.asRawBits() & JSVAL_PAYLOAD_MASK
), payload
);
139 template <typename T
>
140 void storeValueFromComponents(RegisterID type
, RegisterID payload
, T address
) {
141 move(type
, Registers::ValueReg
);
142 orPtr(payload
, Registers::ValueReg
);
143 storeValue(Registers::ValueReg
, address
);
146 template <typename T
>
147 void storeValueFromComponents(ImmTag type
, RegisterID payload
, T address
) {
148 move(type
, Registers::ValueReg
);
149 orPtr(payload
, Registers::ValueReg
);
150 storeValue(Registers::ValueReg
, address
);
153 template <typename T
>
154 void loadTypeTag(T address
, RegisterID reg
) {
155 loadValue(address
, reg
);
156 convertValueToType(reg
);
159 template <typename T
>
160 void storeTypeTag(ImmTag imm
, T address
) {
161 loadPayload(address
, Registers::ValueReg
);
162 orPtr(imm
, Registers::ValueReg
);
163 storePtr(Registers::ValueReg
, valueOf(address
));
166 template <typename T
>
167 void storeTypeTag(RegisterID reg
, T address
) {
168 /* The type tag must be stored in shifted format. */
169 loadPayload(address
, Registers::ValueReg
);
170 orPtr(reg
, Registers::ValueReg
);
171 storePtr(Registers::ValueReg
, valueOf(address
));
174 template <typename T
>
175 void loadPayload(T address
, RegisterID reg
) {
176 loadValue(address
, reg
);
177 convertValueToPayload(reg
);
180 template <typename T
>
181 void storePayload(RegisterID reg
, T address
) {
182 /* Not for doubles. */
183 loadTypeTag(address
, Registers::ValueReg
);
184 orPtr(reg
, Registers::ValueReg
);
185 storePtr(Registers::ValueReg
, valueOf(address
));
188 template <typename T
>
189 void storePayload(ImmPayload imm
, T address
) {
190 /* Not for doubles. */
191 storePtr(imm
, valueOf(address
));
194 template <typename T
>
195 void storeValue(RegisterID reg
, T address
) {
196 storePtr(reg
, valueOf(address
));
199 template <typename T
>
200 void storeValue(const Value
&v
, T address
) {
202 jv
.asBits
= JSVAL_BITS(Jsvalify(v
));
204 storePtr(Imm64(jv
.asBits
), valueOf(address
));
207 template <typename T
>
208 void storeValue(const ValueRemat
&vr
, T address
) {
210 storeValue(Valueify(vr
.u
.v
), address
);
211 else if (vr
.u
.s
.isTypeKnown
)
212 storeValueFromComponents(ImmType(vr
.u
.s
.type
.knownType
), vr
.u
.s
.data
, address
);
214 storeValueFromComponents(vr
.u
.s
.type
.reg
, vr
.u
.s
.data
, address
);
217 void loadPrivate(Address privAddr
, RegisterID to
) {
218 loadPtr(privAddr
, to
);
219 lshiftPtr(Imm32(1), to
);
222 void loadFunctionPrivate(RegisterID base
, RegisterID to
) {
223 Address
priv(base
, offsetof(JSObject
, privateData
));
227 Jump
testNull(Assembler::Condition cond
, RegisterID reg
) {
228 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_NULL
));
231 Jump
testNull(Assembler::Condition cond
, Address address
) {
232 loadValue(address
, Registers::ValueReg
);
233 return testNull(cond
, Registers::ValueReg
);
236 Jump
testUndefined(Assembler::Condition cond
, RegisterID reg
) {
237 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_UNDEFINED
));
240 Jump
testUndefined(Assembler::Condition cond
, Address address
) {
241 loadValue(address
, Registers::ValueReg
);
242 return testUndefined(cond
, Registers::ValueReg
);
245 Jump
testInt32(Assembler::Condition cond
, RegisterID reg
) {
246 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_INT32
));
249 Jump
testInt32(Assembler::Condition cond
, Address address
) {
250 loadTypeTag(address
, Registers::ValueReg
);
251 return testInt32(cond
, Registers::ValueReg
);
254 Jump
testNumber(Assembler::Condition cond
, RegisterID reg
) {
255 cond
= (cond
== Assembler::Equal
) ? Assembler::Below
: Assembler::AboveOrEqual
;
256 return branchPtr(cond
, reg
,
257 ImmTag(JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET
));
260 Jump
testNumber(Assembler::Condition cond
, Address address
) {
261 loadValue(address
, Registers::ValueReg
);
262 return testNumber(cond
, Registers::ValueReg
);
265 Jump
testPrimitive(Assembler::Condition cond
, RegisterID reg
) {
266 cond
= (cond
== Assembler::Equal
) ? Assembler::Below
: Assembler::AboveOrEqual
;
267 return branchPtr(cond
, reg
,
268 ImmTag(JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET
));
271 Jump
testPrimitive(Assembler::Condition cond
, Address address
) {
272 loadValue(address
, Registers::ValueReg
);
273 return testPrimitive(cond
, Registers::ValueReg
);
276 Jump
testObject(Assembler::Condition cond
, RegisterID reg
) {
277 cond
= (cond
== Assembler::Equal
) ? Assembler::AboveOrEqual
: Assembler::Below
;
278 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_OBJECT
));
281 Jump
testObject(Assembler::Condition cond
, Address address
) {
282 loadValue(address
, Registers::ValueReg
);
283 return testObject(cond
, Registers::ValueReg
);
286 Jump
testDouble(Assembler::Condition cond
, RegisterID reg
) {
287 cond
= (cond
== Assembler::Equal
) ? Assembler::BelowOrEqual
: Assembler::Above
;
288 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_MAX_DOUBLE
));
291 Jump
testDouble(Assembler::Condition cond
, Address address
) {
292 loadValue(address
, Registers::ValueReg
);
293 return testDouble(cond
, Registers::ValueReg
);
296 Jump
testBoolean(Assembler::Condition cond
, RegisterID reg
) {
297 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_BOOLEAN
));
300 Jump
testBoolean(Assembler::Condition cond
, Address address
) {
301 loadTypeTag(address
, Registers::ValueReg
);
302 return testBoolean(cond
, Registers::ValueReg
);
305 Jump
testString(Assembler::Condition cond
, RegisterID reg
) {
306 return branchPtr(cond
, reg
, ImmTag(JSVAL_SHIFTED_TAG_STRING
));
309 Jump
testString(Assembler::Condition cond
, Address address
) {
310 loadTypeTag(address
, Registers::ValueReg
);
311 return testString(cond
, Registers::ValueReg
);
315 } /* namespace mjit */