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 * David Anderson <danderson@mozilla.com>
25 * David Mandelin <dmandelin@mozilla.com>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #if !defined jsjaeger_assembler_h__ && defined JS_METHODJIT && defined JS_NUNBOX32
42 #define jsjaeger_assembler_h__
44 #include "methodjit/BaseAssembler.h"
50 * Don't use ImmTag. Use ImmType instead.
51 * TODO: ImmTag should really just be for internal use...
53 class ImmTag
: public JSC::MacroAssembler::Imm32
56 ImmTag(JSValueTag mask
)
61 struct ImmType
: ImmTag
63 ImmType(JSValueType type
)
64 : ImmTag(JSVAL_TYPE_TO_TAG(type
))
68 class Assembler
: public BaseAssembler
70 static const uint32 PAYLOAD_OFFSET
= 0;
71 static const uint32 TAG_OFFSET
= 4;
74 static const JSC::MacroAssembler::Scale JSVAL_SCALE
= JSC::MacroAssembler::TimesEight
;
76 Address
payloadOf(Address address
) {
80 BaseIndex
payloadOf(BaseIndex address
) {
84 Address
tagOf(Address address
) {
85 return Address(address
.base
, address
.offset
+ TAG_OFFSET
);
88 BaseIndex
tagOf(BaseIndex address
) {
89 return BaseIndex(address
.base
, address
.index
, address
.scale
, address
.offset
+ TAG_OFFSET
);
92 void loadSlot(RegisterID obj
, RegisterID clobber
, uint32 slot
, RegisterID type
, RegisterID data
) {
93 JS_ASSERT(type
!= data
);
94 Address
address(obj
, offsetof(JSObject
, fslots
) + slot
* sizeof(Value
));
95 RegisterID activeAddressReg
= obj
;
96 if (slot
>= JS_INITIAL_NSLOTS
) {
97 loadPtr(Address(obj
, offsetof(JSObject
, dslots
)), clobber
);
98 address
= Address(clobber
, (slot
- JS_INITIAL_NSLOTS
) * sizeof(Value
));
99 activeAddressReg
= clobber
;
101 if (activeAddressReg
== type
) {
102 loadPayload(address
, data
);
103 loadTypeTag(address
, type
);
105 loadTypeTag(address
, type
);
106 loadPayload(address
, data
);
110 void loadTypeTag(Address address
, RegisterID reg
) {
111 load32(tagOf(address
), reg
);
114 void loadTypeTag(BaseIndex address
, RegisterID reg
) {
115 load32(tagOf(address
), reg
);
118 void storeTypeTag(ImmType imm
, Address address
) {
119 store32(imm
, tagOf(address
));
122 void storeTypeTag(ImmType imm
, BaseIndex address
) {
123 store32(imm
, tagOf(address
));
126 void storeTypeTag(RegisterID reg
, Address address
) {
127 store32(reg
, tagOf(address
));
130 void storeTypeTag(RegisterID reg
, BaseIndex address
) {
131 store32(reg
, tagOf(address
));
134 void loadPayload(Address address
, RegisterID reg
) {
135 load32(payloadOf(address
), reg
);
138 void loadPayload(BaseIndex address
, RegisterID reg
) {
139 load32(payloadOf(address
), reg
);
142 void storePayload(RegisterID reg
, Address address
) {
143 store32(reg
, payloadOf(address
));
146 void storePayload(RegisterID reg
, BaseIndex address
) {
147 store32(reg
, payloadOf(address
));
150 void storePayload(Imm32 imm
, Address address
) {
151 store32(imm
, payloadOf(address
));
154 /* Loads type first, then payload, returning label after type load. */
155 Label
loadValueAsComponents(Address address
, RegisterID type
, RegisterID payload
) {
156 loadTypeTag(address
, type
);
158 loadPayload(address
, payload
);
162 Label
loadValueAsComponents(BaseIndex address
, RegisterID type
, RegisterID payload
) {
163 loadTypeTag(address
, type
);
165 loadPayload(address
, payload
);
170 * Stores type first, then payload.
172 void storeValue(const Value
&v
, Address address
) {
174 jv
.asBits
= JSVAL_BITS(Jsvalify(v
));
176 store32(ImmTag(jv
.s
.tag
), tagOf(address
));
177 store32(Imm32(jv
.s
.payload
.u32
), payloadOf(address
));
180 void storeValue(const Value
&v
, BaseIndex address
) {
182 jv
.asBits
= JSVAL_BITS(Jsvalify(v
));
184 store32(ImmTag(jv
.s
.tag
), tagOf(address
));
185 store32(Imm32(jv
.s
.payload
.u32
), payloadOf(address
));
189 * Performs type store before payload store, even for Undefined.
190 * Returns label after type store.
192 Label
storeValueForIC(const Value
&v
, Address address
) {
194 jv
.asBits
= JSVAL_BITS(Jsvalify(v
));
196 store32(ImmTag(jv
.s
.tag
), tagOf(address
));
198 store32(Imm32(jv
.s
.payload
.u32
), payloadOf(address
));
202 void loadPrivate(Address privAddr
, RegisterID to
) {
203 loadPtr(privAddr
, to
);
206 void loadFunctionPrivate(RegisterID base
, RegisterID to
) {
207 Address
privSlot(base
, offsetof(JSObject
, fslots
) +
208 JSSLOT_PRIVATE
* sizeof(Value
));
209 loadPtr(privSlot
, to
);
212 Jump
testNull(Assembler::Condition cond
, RegisterID reg
) {
213 return branch32(cond
, reg
, ImmTag(JSVAL_TAG_NULL
));
216 Jump
testNull(Assembler::Condition cond
, Address address
) {
217 return branch32(cond
, tagOf(address
), ImmTag(JSVAL_TAG_NULL
));
220 Jump
testInt32(Assembler::Condition cond
, RegisterID reg
) {
221 return branch32(cond
, reg
, ImmTag(JSVAL_TAG_INT32
));
224 Jump
testInt32(Assembler::Condition cond
, Address address
) {
225 return branch32(cond
, tagOf(address
), ImmTag(JSVAL_TAG_INT32
));
228 Jump
testNumber(Assembler::Condition cond
, RegisterID reg
) {
229 cond
= (cond
== Assembler::Equal
) ? Assembler::BelowOrEqual
: Assembler::Above
;
230 return branch32(cond
, reg
, ImmTag(JSVAL_TAG_INT32
));
233 Jump
testNumber(Assembler::Condition cond
, Address address
) {
234 cond
= (cond
== Assembler::Equal
) ? Assembler::BelowOrEqual
: Assembler::Above
;
235 return branch32(cond
, tagOf(address
), ImmTag(JSVAL_TAG_INT32
));
238 Jump
testPrimitive(Assembler::Condition cond
, RegisterID reg
) {
239 cond
= (cond
== Assembler::NotEqual
) ? Assembler::AboveOrEqual
: Assembler::Below
;
240 return branch32(cond
, reg
, ImmTag(JSVAL_TAG_OBJECT
));
243 Jump
testPrimitive(Assembler::Condition cond
, Address address
) {
244 cond
= (cond
== Assembler::NotEqual
) ? Assembler::AboveOrEqual
: Assembler::Below
;
245 return branch32(cond
, tagOf(address
), ImmTag(JSVAL_TAG_OBJECT
));
248 Jump
testObject(Assembler::Condition cond
, RegisterID reg
) {
249 return branch32(cond
, reg
, ImmTag(JSVAL_TAG_OBJECT
));
252 Jump
testObject(Assembler::Condition cond
, Address address
) {
253 return branch32(cond
, tagOf(address
), ImmTag(JSVAL_TAG_OBJECT
));
256 Jump
testDouble(Assembler::Condition cond
, RegisterID reg
) {
257 Assembler::Condition opcond
;
258 if (cond
== Assembler::Equal
)
259 opcond
= Assembler::Below
;
261 opcond
= Assembler::AboveOrEqual
;
262 return branch32(opcond
, reg
, ImmTag(JSVAL_TAG_CLEAR
));
265 Jump
testDouble(Assembler::Condition cond
, Address address
) {
266 Assembler::Condition opcond
;
267 if (cond
== Assembler::Equal
)
268 opcond
= Assembler::Below
;
270 opcond
= Assembler::AboveOrEqual
;
271 return branch32(opcond
, tagOf(address
), ImmTag(JSVAL_TAG_CLEAR
));
274 Jump
testBoolean(Assembler::Condition cond
, RegisterID reg
) {
275 return branch32(cond
, reg
, ImmTag(JSVAL_TAG_BOOLEAN
));
278 Jump
testBoolean(Assembler::Condition cond
, Address address
) {
279 return branch32(cond
, tagOf(address
), ImmTag(JSVAL_TAG_BOOLEAN
));
282 Jump
testString(Assembler::Condition cond
, RegisterID reg
) {
283 return branch32(cond
, reg
, ImmTag(JSVAL_TAG_STRING
));
286 Jump
testString(Assembler::Condition cond
, Address address
) {
287 return branch32(cond
, tagOf(address
), ImmTag(JSVAL_TAG_STRING
));
292 } /* namespace mjit */