blob: 7210ac287583891606b318ee83ef2e1796e6e6ce [file] [log] [blame]
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001/*
2 * Copyright (C) 2008 Apple Inc.
eric@webkit.org6a210e72010-04-22 13:24:56 +00003 * Copyright (C) 2009, 2010 University of Szeged
barraclough@apple.com5ea68952009-07-17 21:56:28 +00004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef MacroAssemblerARM_h
29#define MacroAssemblerARM_h
30
mjs@apple.comcc668212010-01-04 11:38:56 +000031#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
barraclough@apple.com5ea68952009-07-17 21:56:28 +000032
33#include "ARMAssembler.h"
34#include "AbstractMacroAssembler.h"
35
36namespace JSC {
37
38class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler> {
ossy@webkit.orgcb981302009-11-06 07:28:56 +000039 static const int DoubleConditionMask = 0x0f;
40 static const int DoubleConditionBitSpecial = 0x10;
41 COMPILE_ASSERT(!(DoubleConditionBitSpecial & DoubleConditionMask), DoubleConditionBitSpecial_should_not_interfere_with_ARMAssembler_Condition_codes);
barraclough@apple.com5ea68952009-07-17 21:56:28 +000042public:
barraclough@apple.comcdab3602010-07-01 22:56:58 +000043 typedef ARMRegisters::FPRegisterID FPRegisterID;
oliver@apple.com2c012fa2011-05-17 20:02:41 +000044 static const int MaximumCompactPtrAlignedAddressOffset = 0x7FFFFFFF;
barraclough@apple.comcdab3602010-07-01 22:56:58 +000045
barraclough@apple.com03cd2482011-04-20 18:44:35 +000046 enum RelationalCondition {
barraclough@apple.com5ea68952009-07-17 21:56:28 +000047 Equal = ARMAssembler::EQ,
48 NotEqual = ARMAssembler::NE,
49 Above = ARMAssembler::HI,
50 AboveOrEqual = ARMAssembler::CS,
51 Below = ARMAssembler::CC,
52 BelowOrEqual = ARMAssembler::LS,
53 GreaterThan = ARMAssembler::GT,
54 GreaterThanOrEqual = ARMAssembler::GE,
55 LessThan = ARMAssembler::LT,
barraclough@apple.com03cd2482011-04-20 18:44:35 +000056 LessThanOrEqual = ARMAssembler::LE
57 };
58
59 enum ResultCondition {
barraclough@apple.com5ea68952009-07-17 21:56:28 +000060 Overflow = ARMAssembler::VS,
61 Signed = ARMAssembler::MI,
62 Zero = ARMAssembler::EQ,
63 NonZero = ARMAssembler::NE
64 };
65
66 enum DoubleCondition {
ossy@webkit.orgcb981302009-11-06 07:28:56 +000067 // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
68 DoubleEqual = ARMAssembler::EQ,
69 DoubleNotEqual = ARMAssembler::NE | DoubleConditionBitSpecial,
barraclough@apple.com9ef61d52009-08-06 05:33:27 +000070 DoubleGreaterThan = ARMAssembler::GT,
71 DoubleGreaterThanOrEqual = ARMAssembler::GE,
ossy@webkit.orgcb981302009-11-06 07:28:56 +000072 DoubleLessThan = ARMAssembler::CC,
73 DoubleLessThanOrEqual = ARMAssembler::LS,
74 // If either operand is NaN, these conditions always evaluate to true.
75 DoubleEqualOrUnordered = ARMAssembler::EQ | DoubleConditionBitSpecial,
76 DoubleNotEqualOrUnordered = ARMAssembler::NE,
77 DoubleGreaterThanOrUnordered = ARMAssembler::HI,
78 DoubleGreaterThanOrEqualOrUnordered = ARMAssembler::CS,
barraclough@apple.com2ffca6f2009-11-04 23:59:14 +000079 DoubleLessThanOrUnordered = ARMAssembler::LT,
80 DoubleLessThanOrEqualOrUnordered = ARMAssembler::LE,
barraclough@apple.com5ea68952009-07-17 21:56:28 +000081 };
82
eric@webkit.org734dd062009-08-20 00:02:24 +000083 static const RegisterID stackPointerRegister = ARMRegisters::sp;
eric@webkit.org6fe95ae2009-10-26 22:49:23 +000084 static const RegisterID linkRegister = ARMRegisters::lr;
barraclough@apple.com5ea68952009-07-17 21:56:28 +000085
86 static const Scale ScalePtr = TimesFour;
87
88 void add32(RegisterID src, RegisterID dest)
89 {
90 m_assembler.adds_r(dest, dest, src);
91 }
92
oliver@apple.combe4e0672011-03-28 17:14:57 +000093 void add32(TrustedImm32 imm, Address address)
barraclough@apple.com5ea68952009-07-17 21:56:28 +000094 {
eric@webkit.org734dd062009-08-20 00:02:24 +000095 load32(address, ARMRegisters::S1);
96 add32(imm, ARMRegisters::S1);
97 store32(ARMRegisters::S1, address);
barraclough@apple.com5ea68952009-07-17 21:56:28 +000098 }
99
oliver@apple.combe4e0672011-03-28 17:14:57 +0000100 void add32(TrustedImm32 imm, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000101 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000102 m_assembler.adds_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000103 }
104
105 void add32(Address src, RegisterID dest)
106 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000107 load32(src, ARMRegisters::S1);
108 add32(ARMRegisters::S1, dest);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000109 }
110
111 void and32(RegisterID src, RegisterID dest)
112 {
113 m_assembler.ands_r(dest, dest, src);
114 }
115
oliver@apple.combe4e0672011-03-28 17:14:57 +0000116 void and32(TrustedImm32 imm, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000117 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000118 ARMWord w = m_assembler.getImm(imm.m_value, ARMRegisters::S0, true);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000119 if (w & ARMAssembler::OP2_INV_IMM)
120 m_assembler.bics_r(dest, dest, w & ~ARMAssembler::OP2_INV_IMM);
121 else
122 m_assembler.ands_r(dest, dest, w);
123 }
124
barraclough@apple.comc4a3fa82009-11-06 09:35:03 +0000125 void lshift32(RegisterID shift_amount, RegisterID dest)
126 {
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000127 ARMWord w = ARMAssembler::getOp2(0x1f);
128 ASSERT(w != ARMAssembler::INVALID_IMM);
129 m_assembler.and_r(ARMRegisters::S0, shift_amount, w);
barraclough@apple.comc4a3fa82009-11-06 09:35:03 +0000130
131 m_assembler.movs_r(dest, m_assembler.lsl_r(dest, ARMRegisters::S0));
132 }
133
oliver@apple.combe4e0672011-03-28 17:14:57 +0000134 void lshift32(TrustedImm32 imm, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000135 {
136 m_assembler.movs_r(dest, m_assembler.lsl(dest, imm.m_value & 0x1f));
137 }
138
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000139 void mul32(RegisterID src, RegisterID dest)
140 {
141 if (src == dest) {
eric@webkit.org734dd062009-08-20 00:02:24 +0000142 move(src, ARMRegisters::S0);
143 src = ARMRegisters::S0;
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000144 }
145 m_assembler.muls_r(dest, dest, src);
146 }
147
oliver@apple.combe4e0672011-03-28 17:14:57 +0000148 void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000149 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000150 move(imm, ARMRegisters::S0);
151 m_assembler.muls_r(dest, src, ARMRegisters::S0);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000152 }
153
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000154 void neg32(RegisterID srcDest)
155 {
156 m_assembler.rsbs_r(srcDest, srcDest, ARMAssembler::getOp2(0));
157 }
158
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000159 void not32(RegisterID dest)
160 {
161 m_assembler.mvns_r(dest, dest);
162 }
163
164 void or32(RegisterID src, RegisterID dest)
165 {
166 m_assembler.orrs_r(dest, dest, src);
167 }
168
oliver@apple.combe4e0672011-03-28 17:14:57 +0000169 void or32(TrustedImm32 imm, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000170 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000171 m_assembler.orrs_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000172 }
173
174 void rshift32(RegisterID shift_amount, RegisterID dest)
175 {
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000176 ARMWord w = ARMAssembler::getOp2(0x1f);
177 ASSERT(w != ARMAssembler::INVALID_IMM);
178 m_assembler.and_r(ARMRegisters::S0, shift_amount, w);
barraclough@apple.comc4a3fa82009-11-06 09:35:03 +0000179
180 m_assembler.movs_r(dest, m_assembler.asr_r(dest, ARMRegisters::S0));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000181 }
oliver@apple.com5b6a0d32011-07-01 16:33:46 +0000182
oliver@apple.combe4e0672011-03-28 17:14:57 +0000183 void rshift32(TrustedImm32 imm, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000184 {
oliver@apple.com5b6a0d32011-07-01 16:33:46 +0000185 rshift32(dest, imm, dest);
186 }
187
188 void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
189 {
190 m_assembler.movs_r(dest, m_assembler.asr(src, imm.m_value & 0x1f));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000191 }
oliver@apple.com429ede02010-04-30 07:56:38 +0000192
193 void urshift32(RegisterID shift_amount, RegisterID dest)
194 {
195 ARMWord w = ARMAssembler::getOp2(0x1f);
196 ASSERT(w != ARMAssembler::INVALID_IMM);
197 m_assembler.and_r(ARMRegisters::S0, shift_amount, w);
198
199 m_assembler.movs_r(dest, m_assembler.lsr_r(dest, ARMRegisters::S0));
200 }
201
oliver@apple.combe4e0672011-03-28 17:14:57 +0000202 void urshift32(TrustedImm32 imm, RegisterID dest)
oliver@apple.com429ede02010-04-30 07:56:38 +0000203 {
204 m_assembler.movs_r(dest, m_assembler.lsr(dest, imm.m_value & 0x1f));
205 }
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000206
207 void sub32(RegisterID src, RegisterID dest)
208 {
209 m_assembler.subs_r(dest, dest, src);
210 }
211
oliver@apple.combe4e0672011-03-28 17:14:57 +0000212 void sub32(TrustedImm32 imm, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000213 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000214 m_assembler.subs_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000215 }
216
oliver@apple.combe4e0672011-03-28 17:14:57 +0000217 void sub32(TrustedImm32 imm, Address address)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000218 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000219 load32(address, ARMRegisters::S1);
220 sub32(imm, ARMRegisters::S1);
221 store32(ARMRegisters::S1, address);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000222 }
223
224 void sub32(Address src, RegisterID dest)
225 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000226 load32(src, ARMRegisters::S1);
227 sub32(ARMRegisters::S1, dest);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000228 }
229
230 void xor32(RegisterID src, RegisterID dest)
231 {
232 m_assembler.eors_r(dest, dest, src);
233 }
234
oliver@apple.combe4e0672011-03-28 17:14:57 +0000235 void xor32(TrustedImm32 imm, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000236 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000237 m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000238 }
239
loki@webkit.org0f28f9b2010-11-20 22:02:36 +0000240 void countLeadingZeros32(RegisterID src, RegisterID dest)
241 {
242#if WTF_ARM_ARCH_AT_LEAST(5)
243 m_assembler.clz_r(dest, src);
244#else
245 UNUSED_PARAM(src);
246 UNUSED_PARAM(dest);
247 ASSERT_NOT_REACHED();
248#endif
249 }
250
loki@webkit.org2acccd02010-03-09 09:36:06 +0000251 void load8(ImplicitAddress address, RegisterID dest)
252 {
253 m_assembler.dataTransfer32(true, dest, address.base, address.offset, true);
254 }
255
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000256 void load32(ImplicitAddress address, RegisterID dest)
257 {
258 m_assembler.dataTransfer32(true, dest, address.base, address.offset);
259 }
260
261 void load32(BaseIndex address, RegisterID dest)
262 {
263 m_assembler.baseIndexTransfer32(true, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
264 }
265
mjs@apple.comcc668212010-01-04 11:38:56 +0000266#if CPU(ARMV5_OR_LOWER)
eric@webkit.org16d65d12009-09-26 02:27:02 +0000267 void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest);
268#else
269 void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
270 {
271 load32(address, dest);
272 }
273#endif
274
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000275 DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
276 {
277 DataLabel32 dataLabel(this);
eric@webkit.org734dd062009-08-20 00:02:24 +0000278 m_assembler.ldr_un_imm(ARMRegisters::S0, 0);
279 m_assembler.dtr_ur(true, dest, address.base, ARMRegisters::S0);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000280 return dataLabel;
281 }
oliver@apple.com2c012fa2011-05-17 20:02:41 +0000282
283 DataLabelCompact load32WithCompactAddressOffsetPatch(Address address, RegisterID dest)
284 {
285 DataLabelCompact dataLabel(this);
286 load32WithAddressOffsetPatch(address, dest);
287 return dataLabel;
288 }
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000289
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000290 void load16(BaseIndex address, RegisterID dest)
291 {
eric@webkit.org25809632010-05-08 20:03:31 +0000292 m_assembler.add_r(ARMRegisters::S1, address.base, m_assembler.lsl(address.index, address.scale));
293 load16(Address(ARMRegisters::S1, address.offset), dest);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000294 }
oliver@apple.com771ce2d2010-05-06 20:04:28 +0000295
296 void load16(ImplicitAddress address, RegisterID dest)
297 {
298 if (address.offset >= 0)
eric@webkit.org25809632010-05-08 20:03:31 +0000299 m_assembler.ldrh_u(dest, address.base, m_assembler.getOffsetForHalfwordDataTransfer(address.offset, ARMRegisters::S0));
oliver@apple.com771ce2d2010-05-06 20:04:28 +0000300 else
eric@webkit.org25809632010-05-08 20:03:31 +0000301 m_assembler.ldrh_d(dest, address.base, m_assembler.getOffsetForHalfwordDataTransfer(-address.offset, ARMRegisters::S0));
oliver@apple.com771ce2d2010-05-06 20:04:28 +0000302 }
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000303
304 DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
305 {
306 DataLabel32 dataLabel(this);
eric@webkit.org734dd062009-08-20 00:02:24 +0000307 m_assembler.ldr_un_imm(ARMRegisters::S0, 0);
308 m_assembler.dtr_ur(false, src, address.base, ARMRegisters::S0);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000309 return dataLabel;
310 }
311
312 void store32(RegisterID src, ImplicitAddress address)
313 {
314 m_assembler.dataTransfer32(false, src, address.base, address.offset);
315 }
316
317 void store32(RegisterID src, BaseIndex address)
318 {
319 m_assembler.baseIndexTransfer32(false, src, address.base, address.index, static_cast<int>(address.scale), address.offset);
320 }
321
oliver@apple.combe4e0672011-03-28 17:14:57 +0000322 void store32(TrustedImm32 imm, ImplicitAddress address)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000323 {
barraclough@apple.com0192e2c2009-08-06 05:22:42 +0000324 if (imm.m_isPointer)
eric@webkit.org734dd062009-08-20 00:02:24 +0000325 m_assembler.ldr_un_imm(ARMRegisters::S1, imm.m_value);
barraclough@apple.com0192e2c2009-08-06 05:22:42 +0000326 else
eric@webkit.org734dd062009-08-20 00:02:24 +0000327 move(imm, ARMRegisters::S1);
328 store32(ARMRegisters::S1, address);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000329 }
330
331 void store32(RegisterID src, void* address)
332 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000333 m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
334 m_assembler.dtr_u(false, src, ARMRegisters::S0, 0);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000335 }
336
oliver@apple.combe4e0672011-03-28 17:14:57 +0000337 void store32(TrustedImm32 imm, void* address)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000338 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000339 m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
barraclough@apple.com0192e2c2009-08-06 05:22:42 +0000340 if (imm.m_isPointer)
eric@webkit.org734dd062009-08-20 00:02:24 +0000341 m_assembler.ldr_un_imm(ARMRegisters::S1, imm.m_value);
barraclough@apple.com0192e2c2009-08-06 05:22:42 +0000342 else
eric@webkit.org734dd062009-08-20 00:02:24 +0000343 m_assembler.moveImm(imm.m_value, ARMRegisters::S1);
344 m_assembler.dtr_u(false, ARMRegisters::S1, ARMRegisters::S0, 0);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000345 }
346
347 void pop(RegisterID dest)
348 {
349 m_assembler.pop_r(dest);
350 }
351
352 void push(RegisterID src)
353 {
354 m_assembler.push_r(src);
355 }
356
357 void push(Address address)
358 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000359 load32(address, ARMRegisters::S1);
360 push(ARMRegisters::S1);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000361 }
362
oliver@apple.combe4e0672011-03-28 17:14:57 +0000363 void push(TrustedImm32 imm)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000364 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000365 move(imm, ARMRegisters::S0);
366 push(ARMRegisters::S0);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000367 }
368
oliver@apple.combe4e0672011-03-28 17:14:57 +0000369 void move(TrustedImm32 imm, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000370 {
barraclough@apple.com0192e2c2009-08-06 05:22:42 +0000371 if (imm.m_isPointer)
372 m_assembler.ldr_un_imm(dest, imm.m_value);
373 else
374 m_assembler.moveImm(imm.m_value, dest);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000375 }
376
377 void move(RegisterID src, RegisterID dest)
378 {
379 m_assembler.mov_r(dest, src);
380 }
381
oliver@apple.combe4e0672011-03-28 17:14:57 +0000382 void move(TrustedImmPtr imm, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000383 {
oliver@apple.combe4e0672011-03-28 17:14:57 +0000384 move(TrustedImm32(imm), dest);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000385 }
386
387 void swap(RegisterID reg1, RegisterID reg2)
388 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000389 m_assembler.mov_r(ARMRegisters::S0, reg1);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000390 m_assembler.mov_r(reg1, reg2);
eric@webkit.org734dd062009-08-20 00:02:24 +0000391 m_assembler.mov_r(reg2, ARMRegisters::S0);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000392 }
393
394 void signExtend32ToPtr(RegisterID src, RegisterID dest)
395 {
396 if (src != dest)
397 move(src, dest);
398 }
399
400 void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
401 {
402 if (src != dest)
403 move(src, dest);
404 }
405
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000406 Jump branch8(RelationalCondition cond, Address left, TrustedImm32 right)
loki@webkit.org2acccd02010-03-09 09:36:06 +0000407 {
408 load8(left, ARMRegisters::S1);
409 return branch32(cond, ARMRegisters::S1, right);
410 }
411
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000412 Jump branch32(RelationalCondition cond, RegisterID left, RegisterID right, int useConstantPool = 0)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000413 {
414 m_assembler.cmp_r(left, right);
barraclough@apple.com970af2c2009-08-13 05:58:36 +0000415 return Jump(m_assembler.jmp(ARMCondition(cond), useConstantPool));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000416 }
417
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000418 Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right, int useConstantPool = 0)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000419 {
barraclough@apple.com0192e2c2009-08-06 05:22:42 +0000420 if (right.m_isPointer) {
eric@webkit.org734dd062009-08-20 00:02:24 +0000421 m_assembler.ldr_un_imm(ARMRegisters::S0, right.m_value);
422 m_assembler.cmp_r(left, ARMRegisters::S0);
loki@webkit.org5b1bd322010-10-27 13:48:11 +0000423 } else {
commit-queue@webkit.org7af1b442011-05-30 23:49:51 +0000424 ARMWord tmp = (right.m_value == 0x80000000) ? ARMAssembler::INVALID_IMM : m_assembler.getOp2(-right.m_value);
loki@webkit.org5b1bd322010-10-27 13:48:11 +0000425 if (tmp != ARMAssembler::INVALID_IMM)
426 m_assembler.cmn_r(left, tmp);
427 else
428 m_assembler.cmp_r(left, m_assembler.getImm(right.m_value, ARMRegisters::S0));
429 }
barraclough@apple.com970af2c2009-08-13 05:58:36 +0000430 return Jump(m_assembler.jmp(ARMCondition(cond), useConstantPool));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000431 }
432
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000433 Jump branch32(RelationalCondition cond, RegisterID left, Address right)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000434 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000435 load32(right, ARMRegisters::S1);
436 return branch32(cond, left, ARMRegisters::S1);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000437 }
438
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000439 Jump branch32(RelationalCondition cond, Address left, RegisterID right)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000440 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000441 load32(left, ARMRegisters::S1);
442 return branch32(cond, ARMRegisters::S1, right);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000443 }
444
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000445 Jump branch32(RelationalCondition cond, Address left, TrustedImm32 right)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000446 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000447 load32(left, ARMRegisters::S1);
448 return branch32(cond, ARMRegisters::S1, right);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000449 }
450
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000451 Jump branch32(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000452 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000453 load32(left, ARMRegisters::S1);
454 return branch32(cond, ARMRegisters::S1, right);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000455 }
456
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000457 Jump branch32WithUnalignedHalfWords(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
eric@webkit.org16d65d12009-09-26 02:27:02 +0000458 {
459 load32WithUnalignedHalfWords(left, ARMRegisters::S1);
460 return branch32(cond, ARMRegisters::S1, right);
461 }
462
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000463 Jump branch16(RelationalCondition cond, BaseIndex left, RegisterID right)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000464 {
465 UNUSED_PARAM(cond);
466 UNUSED_PARAM(left);
467 UNUSED_PARAM(right);
468 ASSERT_NOT_REACHED();
469 return jump();
470 }
471
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000472 Jump branch16(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000473 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000474 load16(left, ARMRegisters::S0);
475 move(right, ARMRegisters::S1);
476 m_assembler.cmp_r(ARMRegisters::S0, ARMRegisters::S1);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000477 return m_assembler.jmp(ARMCondition(cond));
478 }
479
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000480 Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
loki@webkit.org2acccd02010-03-09 09:36:06 +0000481 {
482 load8(address, ARMRegisters::S1);
483 return branchTest32(cond, ARMRegisters::S1, mask);
484 }
485
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000486 Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000487 {
488 ASSERT((cond == Zero) || (cond == NonZero));
489 m_assembler.tst_r(reg, mask);
490 return Jump(m_assembler.jmp(ARMCondition(cond)));
491 }
492
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000493 Jump branchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000494 {
495 ASSERT((cond == Zero) || (cond == NonZero));
eric@webkit.org734dd062009-08-20 00:02:24 +0000496 ARMWord w = m_assembler.getImm(mask.m_value, ARMRegisters::S0, true);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000497 if (w & ARMAssembler::OP2_INV_IMM)
eric@webkit.org734dd062009-08-20 00:02:24 +0000498 m_assembler.bics_r(ARMRegisters::S0, reg, w & ~ARMAssembler::OP2_INV_IMM);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000499 else
500 m_assembler.tst_r(reg, w);
501 return Jump(m_assembler.jmp(ARMCondition(cond)));
502 }
503
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000504 Jump branchTest32(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000505 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000506 load32(address, ARMRegisters::S1);
507 return branchTest32(cond, ARMRegisters::S1, mask);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000508 }
509
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000510 Jump branchTest32(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000511 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000512 load32(address, ARMRegisters::S1);
513 return branchTest32(cond, ARMRegisters::S1, mask);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000514 }
515
516 Jump jump()
517 {
518 return Jump(m_assembler.jmp());
519 }
520
521 void jump(RegisterID target)
522 {
eric@webkit.org6a210e72010-04-22 13:24:56 +0000523 m_assembler.bx(target);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000524 }
525
526 void jump(Address address)
527 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000528 load32(address, ARMRegisters::pc);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000529 }
530
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000531 Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000532 {
533 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
534 add32(src, dest);
535 return Jump(m_assembler.jmp(ARMCondition(cond)));
536 }
537
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000538 Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000539 {
540 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
541 add32(imm, dest);
542 return Jump(m_assembler.jmp(ARMCondition(cond)));
543 }
544
545 void mull32(RegisterID src1, RegisterID src2, RegisterID dest)
546 {
547 if (src1 == dest) {
eric@webkit.org734dd062009-08-20 00:02:24 +0000548 move(src1, ARMRegisters::S0);
549 src1 = ARMRegisters::S0;
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000550 }
eric@webkit.org734dd062009-08-20 00:02:24 +0000551 m_assembler.mull_r(ARMRegisters::S1, dest, src2, src1);
552 m_assembler.cmp_r(ARMRegisters::S1, m_assembler.asr(dest, 31));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000553 }
554
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000555 Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000556 {
557 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
558 if (cond == Overflow) {
559 mull32(src, dest, dest);
560 cond = NonZero;
561 }
562 else
563 mul32(src, dest);
564 return Jump(m_assembler.jmp(ARMCondition(cond)));
565 }
566
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000567 Jump branchMul32(ResultCondition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000568 {
569 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
570 if (cond == Overflow) {
eric@webkit.org734dd062009-08-20 00:02:24 +0000571 move(imm, ARMRegisters::S0);
572 mull32(ARMRegisters::S0, src, dest);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000573 cond = NonZero;
574 }
575 else
576 mul32(imm, src, dest);
577 return Jump(m_assembler.jmp(ARMCondition(cond)));
578 }
579
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000580 Jump branchSub32(ResultCondition cond, RegisterID src, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000581 {
582 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
583 sub32(src, dest);
584 return Jump(m_assembler.jmp(ARMCondition(cond)));
585 }
586
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000587 Jump branchSub32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000588 {
589 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
590 sub32(imm, dest);
591 return Jump(m_assembler.jmp(ARMCondition(cond)));
592 }
593
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000594 Jump branchNeg32(ResultCondition cond, RegisterID srcDest)
ggaren@apple.com5a0ed292010-03-22 18:33:23 +0000595 {
596 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
597 neg32(srcDest);
598 return Jump(m_assembler.jmp(ARMCondition(cond)));
599 }
600
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000601 Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest)
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000602 {
603 ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
604 or32(src, dest);
605 return Jump(m_assembler.jmp(ARMCondition(cond)));
606 }
607
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000608 void breakpoint()
609 {
610 m_assembler.bkpt(0);
611 }
612
613 Call nearCall()
614 {
eric@webkit.org6a210e72010-04-22 13:24:56 +0000615#if WTF_ARM_ARCH_AT_LEAST(5)
616 ensureSpace(2 * sizeof(ARMWord), sizeof(ARMWord));
617 m_assembler.loadBranchTarget(ARMRegisters::S1, ARMAssembler::AL, true);
618 return Call(m_assembler.blx(ARMRegisters::S1), Call::LinkableNear);
619#else
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000620 prepareCall();
barraclough@apple.com970af2c2009-08-13 05:58:36 +0000621 return Call(m_assembler.jmp(ARMAssembler::AL, true), Call::LinkableNear);
eric@webkit.org6a210e72010-04-22 13:24:56 +0000622#endif
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000623 }
624
625 Call call(RegisterID target)
626 {
loki@webkit.orgea6cf182010-11-24 13:04:35 +0000627 return Call(m_assembler.blx(target), Call::None);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000628 }
629
630 void call(Address address)
631 {
632 call32(address.base, address.offset);
633 }
634
635 void ret()
636 {
eric@webkit.org6a210e72010-04-22 13:24:56 +0000637 m_assembler.bx(linkRegister);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000638 }
639
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000640 void compare32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000641 {
642 m_assembler.cmp_r(left, right);
643 m_assembler.mov_r(dest, ARMAssembler::getOp2(0));
644 m_assembler.mov_r(dest, ARMAssembler::getOp2(1), ARMCondition(cond));
645 }
646
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000647 void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000648 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000649 m_assembler.cmp_r(left, m_assembler.getImm(right.m_value, ARMRegisters::S0));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000650 m_assembler.mov_r(dest, ARMAssembler::getOp2(0));
651 m_assembler.mov_r(dest, ARMAssembler::getOp2(1), ARMCondition(cond));
652 }
653
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000654 void test32(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000655 {
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000656 if (mask.m_value == -1)
commit-queue@webkit.org4fa9acd2011-02-01 14:40:03 +0000657 m_assembler.cmp_r(0, reg);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000658 else
commit-queue@webkit.org4fa9acd2011-02-01 14:40:03 +0000659 m_assembler.tst_r(reg, m_assembler.getImm(mask.m_value, ARMRegisters::S0));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000660 m_assembler.mov_r(dest, ARMAssembler::getOp2(0));
661 m_assembler.mov_r(dest, ARMAssembler::getOp2(1), ARMCondition(cond));
662 }
663
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000664 void test32(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest)
commit-queue@webkit.org4fa9acd2011-02-01 14:40:03 +0000665 {
666 load32(address, ARMRegisters::S1);
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000667 test32(cond, ARMRegisters::S1, mask, dest);
commit-queue@webkit.org4fa9acd2011-02-01 14:40:03 +0000668 }
669
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000670 void test8(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest)
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000671 {
commit-queue@webkit.org4fa9acd2011-02-01 14:40:03 +0000672 load8(address, ARMRegisters::S1);
barraclough@apple.comcc5c3512011-04-20 19:02:01 +0000673 test32(cond, ARMRegisters::S1, mask, dest);
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000674 }
675
oliver@apple.combe4e0672011-03-28 17:14:57 +0000676 void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000677 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000678 m_assembler.add_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000679 }
680
oliver@apple.combe4e0672011-03-28 17:14:57 +0000681 void add32(TrustedImm32 imm, AbsoluteAddress address)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000682 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000683 m_assembler.ldr_un_imm(ARMRegisters::S1, reinterpret_cast<ARMWord>(address.m_ptr));
684 m_assembler.dtr_u(true, ARMRegisters::S1, ARMRegisters::S1, 0);
685 add32(imm, ARMRegisters::S1);
686 m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address.m_ptr));
687 m_assembler.dtr_u(false, ARMRegisters::S1, ARMRegisters::S0, 0);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000688 }
689
oliver@apple.combe4e0672011-03-28 17:14:57 +0000690 void sub32(TrustedImm32 imm, AbsoluteAddress address)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000691 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000692 m_assembler.ldr_un_imm(ARMRegisters::S1, reinterpret_cast<ARMWord>(address.m_ptr));
693 m_assembler.dtr_u(true, ARMRegisters::S1, ARMRegisters::S1, 0);
694 sub32(imm, ARMRegisters::S1);
695 m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address.m_ptr));
696 m_assembler.dtr_u(false, ARMRegisters::S1, ARMRegisters::S0, 0);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000697 }
698
barraclough@apple.com94e12c12011-03-13 21:26:16 +0000699 void load32(const void* address, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000700 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000701 m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
702 m_assembler.dtr_u(true, dest, ARMRegisters::S0, 0);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000703 }
704
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000705 Jump branch32(RelationalCondition cond, AbsoluteAddress left, RegisterID right)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000706 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000707 load32(left.m_ptr, ARMRegisters::S1);
708 return branch32(cond, ARMRegisters::S1, right);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000709 }
710
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000711 Jump branch32(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000712 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000713 load32(left.m_ptr, ARMRegisters::S1);
714 return branch32(cond, ARMRegisters::S1, right);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000715 }
716
loki@webkit.org0f28f9b2010-11-20 22:02:36 +0000717 void relativeTableJump(RegisterID index, int scale)
718 {
719 ASSERT(scale >= 0 && scale <= 31);
720 m_assembler.add_r(ARMRegisters::pc, ARMRegisters::pc, m_assembler.lsl(index, scale));
721
722 // NOP the default prefetching
723 m_assembler.mov_r(ARMRegisters::r0, ARMRegisters::r0);
724 }
725
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000726 Call call()
727 {
eric@webkit.org6a210e72010-04-22 13:24:56 +0000728#if WTF_ARM_ARCH_AT_LEAST(5)
729 ensureSpace(2 * sizeof(ARMWord), sizeof(ARMWord));
730 m_assembler.loadBranchTarget(ARMRegisters::S1, ARMAssembler::AL, true);
731 return Call(m_assembler.blx(ARMRegisters::S1), Call::Linkable);
732#else
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000733 prepareCall();
barraclough@apple.com970af2c2009-08-13 05:58:36 +0000734 return Call(m_assembler.jmp(ARMAssembler::AL, true), Call::Linkable);
eric@webkit.org6a210e72010-04-22 13:24:56 +0000735#endif
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000736 }
737
738 Call tailRecursiveCall()
739 {
740 return Call::fromTailJump(jump());
741 }
742
743 Call makeTailRecursiveCall(Jump oldJump)
744 {
745 return Call::fromTailJump(oldJump);
746 }
747
oliver@apple.combe4e0672011-03-28 17:14:57 +0000748 DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000749 {
750 DataLabelPtr dataLabel(this);
751 m_assembler.ldr_un_imm(dest, reinterpret_cast<ARMWord>(initialValue.m_value));
752 return dataLabel;
753 }
754
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000755 Jump branchPtrWithPatch(RelationalCondition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000756 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000757 dataLabel = moveWithPatch(initialRightValue, ARMRegisters::S1);
758 Jump jump = branch32(cond, left, ARMRegisters::S1, true);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000759 return jump;
760 }
761
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000762 Jump branchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000763 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000764 load32(left, ARMRegisters::S1);
765 dataLabel = moveWithPatch(initialRightValue, ARMRegisters::S0);
766 Jump jump = branch32(cond, ARMRegisters::S0, ARMRegisters::S1, true);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000767 return jump;
768 }
769
oliver@apple.combe4e0672011-03-28 17:14:57 +0000770 DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000771 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000772 DataLabelPtr dataLabel = moveWithPatch(initialValue, ARMRegisters::S1);
773 store32(ARMRegisters::S1, address);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000774 return dataLabel;
775 }
776
777 DataLabelPtr storePtrWithPatch(ImplicitAddress address)
778 {
oliver@apple.combe4e0672011-03-28 17:14:57 +0000779 return storePtrWithPatch(TrustedImmPtr(0), address);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000780 }
781
782 // Floating point operators
783 bool supportsFloatingPoint() const
784 {
zoltan@webkit.org212e83e2009-09-15 11:29:33 +0000785 return s_isVFPPresent;
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000786 }
787
788 bool supportsFloatingPointTruncate() const
789 {
loki@webkit.org86097ad2010-08-25 07:52:16 +0000790 return s_isVFPPresent;
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000791 }
792
oliver@apple.com2bd947e2010-04-29 03:57:16 +0000793 bool supportsFloatingPointSqrt() const
794 {
zherczeg@webkit.orgfa3e9212010-04-29 14:08:44 +0000795 return s_isVFPPresent;
oliver@apple.com2bd947e2010-04-29 03:57:16 +0000796 }
oliver@apple.com5b6a0d32011-07-01 16:33:46 +0000797 bool supportsDoubleBitops() const { return false; }
oliver@apple.com2bd947e2010-04-29 03:57:16 +0000798
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000799 void loadDouble(ImplicitAddress address, FPRegisterID dest)
800 {
barraclough@apple.com9ef61d52009-08-06 05:33:27 +0000801 m_assembler.doubleTransfer(true, dest, address.base, address.offset);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000802 }
803
oliver@apple.com2bd947e2010-04-29 03:57:16 +0000804 void loadDouble(const void* address, FPRegisterID dest)
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000805 {
806 m_assembler.ldr_un_imm(ARMRegisters::S0, (ARMWord)address);
807 m_assembler.fdtr_u(true, dest, ARMRegisters::S0, 0);
808 }
809
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000810 void storeDouble(FPRegisterID src, ImplicitAddress address)
811 {
barraclough@apple.com9ef61d52009-08-06 05:33:27 +0000812 m_assembler.doubleTransfer(false, src, address.base, address.offset);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000813 }
814
815 void addDouble(FPRegisterID src, FPRegisterID dest)
816 {
zherczeg@webkit.orgb6994142010-08-13 06:49:16 +0000817 m_assembler.vadd_f64_r(dest, dest, src);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000818 }
819
820 void addDouble(Address src, FPRegisterID dest)
821 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000822 loadDouble(src, ARMRegisters::SD0);
823 addDouble(ARMRegisters::SD0, dest);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000824 }
825
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000826 void divDouble(FPRegisterID src, FPRegisterID dest)
827 {
zherczeg@webkit.orgb6994142010-08-13 06:49:16 +0000828 m_assembler.vdiv_f64_r(dest, dest, src);
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000829 }
830
831 void divDouble(Address src, FPRegisterID dest)
832 {
833 ASSERT_NOT_REACHED(); // Untested
834 loadDouble(src, ARMRegisters::SD0);
835 divDouble(ARMRegisters::SD0, dest);
836 }
837
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000838 void subDouble(FPRegisterID src, FPRegisterID dest)
839 {
zherczeg@webkit.orgb6994142010-08-13 06:49:16 +0000840 m_assembler.vsub_f64_r(dest, dest, src);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000841 }
842
843 void subDouble(Address src, FPRegisterID dest)
844 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000845 loadDouble(src, ARMRegisters::SD0);
846 subDouble(ARMRegisters::SD0, dest);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000847 }
848
849 void mulDouble(FPRegisterID src, FPRegisterID dest)
850 {
zherczeg@webkit.orgb6994142010-08-13 06:49:16 +0000851 m_assembler.vmul_f64_r(dest, dest, src);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000852 }
853
854 void mulDouble(Address src, FPRegisterID dest)
855 {
eric@webkit.org734dd062009-08-20 00:02:24 +0000856 loadDouble(src, ARMRegisters::SD0);
857 mulDouble(ARMRegisters::SD0, dest);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000858 }
859
zherczeg@webkit.orgfa3e9212010-04-29 14:08:44 +0000860 void sqrtDouble(FPRegisterID src, FPRegisterID dest)
oliver@apple.com2bd947e2010-04-29 03:57:16 +0000861 {
zherczeg@webkit.orgb6994142010-08-13 06:49:16 +0000862 m_assembler.vsqrt_f64_r(dest, src);
oliver@apple.com2bd947e2010-04-29 03:57:16 +0000863 }
oliver@apple.com5b6a0d32011-07-01 16:33:46 +0000864
865 void andnotDouble(FPRegisterID, FPRegisterID)
866 {
867 ASSERT_NOT_REACHED();
868 }
oliver@apple.com2bd947e2010-04-29 03:57:16 +0000869
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000870 void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
871 {
zherczeg@webkit.orgb6994142010-08-13 06:49:16 +0000872 m_assembler.vmov_vfp_r(dest << 1, src);
873 m_assembler.vcvt_f64_s32_r(dest, dest << 1);
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000874 }
875
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000876 void convertInt32ToDouble(Address src, FPRegisterID dest)
877 {
878 ASSERT_NOT_REACHED(); // Untested
879 // flds does not worth the effort here
880 load32(src, ARMRegisters::S1);
881 convertInt32ToDouble(ARMRegisters::S1, dest);
882 }
883
884 void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
885 {
886 ASSERT_NOT_REACHED(); // Untested
887 // flds does not worth the effort here
888 m_assembler.ldr_un_imm(ARMRegisters::S1, (ARMWord)src.m_ptr);
889 m_assembler.dtr_u(true, ARMRegisters::S1, ARMRegisters::S1, 0);
890 convertInt32ToDouble(ARMRegisters::S1, dest);
891 }
892
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000893 Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
894 {
zherczeg@webkit.orgb6994142010-08-13 06:49:16 +0000895 m_assembler.vcmp_f64_r(left, right);
896 m_assembler.vmrs_apsr();
ossy@webkit.orgcb981302009-11-06 07:28:56 +0000897 if (cond & DoubleConditionBitSpecial)
898 m_assembler.cmp_r(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::VS);
899 return Jump(m_assembler.jmp(static_cast<ARMAssembler::Condition>(cond & ~DoubleConditionMask)));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000900 }
901
902 // Truncates 'src' to an integer, and places the resulting 'dest'.
903 // If the result is not representable as a 32 bit value, branch.
904 // May also branch for some values that are representable in 32 bits
loki@webkit.org86097ad2010-08-25 07:52:16 +0000905 // (specifically, in this case, INT_MIN and INT_MAX).
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000906 Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
907 {
loki@webkit.org86097ad2010-08-25 07:52:16 +0000908 m_assembler.vcvtr_s32_f64_r(ARMRegisters::SD0 << 1, src);
909 // If VCVTR.S32.F64 can't fit the result into a 32-bit
910 // integer, it saturates at INT_MAX or INT_MIN. Testing this is
911 // probably quicker than testing FPSCR for exception.
912 m_assembler.vmov_arm_r(dest, ARMRegisters::SD0 << 1);
913 m_assembler.sub_r(ARMRegisters::S0, dest, ARMAssembler::getOp2(0x80000000));
914 m_assembler.cmn_r(ARMRegisters::S0, ARMAssembler::getOp2(1), ARMCondition(NotEqual));
915 return Jump(m_assembler.jmp(ARMCondition(Equal)));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000916 }
917
ossy@webkit.orgcb981302009-11-06 07:28:56 +0000918 // Convert 'src' to an integer, and places the resulting 'dest'.
919 // If the result is not representable as a 32 bit value, branch.
920 // May also branch for some values that are representable in 32 bits
921 // (specifically, in this case, 0).
922 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
923 {
zherczeg@webkit.orgb6994142010-08-13 06:49:16 +0000924 m_assembler.vcvt_s32_f64_r(ARMRegisters::SD0 << 1, src);
925 m_assembler.vmov_arm_r(dest, ARMRegisters::SD0 << 1);
ossy@webkit.orgcb981302009-11-06 07:28:56 +0000926
927 // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
zherczeg@webkit.orgb6994142010-08-13 06:49:16 +0000928 m_assembler.vcvt_f64_s32_r(ARMRegisters::SD0, ARMRegisters::SD0 << 1);
zoltan@webkit.org086fa8f2009-11-17 07:16:22 +0000929 failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, ARMRegisters::SD0));
ossy@webkit.orgcb981302009-11-06 07:28:56 +0000930
931 // If the result is zero, it might have been -0.0, and 0.0 equals to -0.0
932 failureCases.append(branchTest32(Zero, dest));
933 }
934
barraclough@apple.com07d783c2011-01-07 00:38:37 +0000935 Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID scratch)
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000936 {
937 m_assembler.mov_r(ARMRegisters::S0, ARMAssembler::getOp2(0));
barraclough@apple.com07d783c2011-01-07 00:38:37 +0000938 convertInt32ToDouble(ARMRegisters::S0, scratch);
939 return branchDouble(DoubleNotEqual, reg, scratch);
940 }
941
942 Jump branchDoubleZeroOrNaN(FPRegisterID reg, FPRegisterID scratch)
943 {
944 m_assembler.mov_r(ARMRegisters::S0, ARMAssembler::getOp2(0));
945 convertInt32ToDouble(ARMRegisters::S0, scratch);
946 return branchDouble(DoubleEqualOrUnordered, reg, scratch);
zoltan@webkit.org1916f842009-11-14 00:44:42 +0000947 }
948
oliver@apple.com31df1c82011-05-20 01:33:46 +0000949 void nop()
950 {
951 m_assembler.nop();
952 }
953
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000954protected:
barraclough@apple.com03cd2482011-04-20 18:44:35 +0000955 ARMAssembler::Condition ARMCondition(RelationalCondition cond)
956 {
957 return static_cast<ARMAssembler::Condition>(cond);
958 }
959
960 ARMAssembler::Condition ARMCondition(ResultCondition cond)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000961 {
962 return static_cast<ARMAssembler::Condition>(cond);
963 }
964
barraclough@apple.com970af2c2009-08-13 05:58:36 +0000965 void ensureSpace(int insnSpace, int constSpace)
966 {
967 m_assembler.ensureSpace(insnSpace, constSpace);
968 }
969
970 int sizeOfConstantPool()
971 {
972 return m_assembler.sizeOfConstantPool();
973 }
974
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000975 void prepareCall()
976 {
eric@webkit.org6a210e72010-04-22 13:24:56 +0000977#if WTF_ARM_ARCH_VERSION < 5
eric@webkit.org6fe95ae2009-10-26 22:49:23 +0000978 ensureSpace(2 * sizeof(ARMWord), sizeof(ARMWord));
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000979
eric@webkit.org6fe95ae2009-10-26 22:49:23 +0000980 m_assembler.mov_r(linkRegister, ARMRegisters::pc);
eric@webkit.org6a210e72010-04-22 13:24:56 +0000981#endif
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000982 }
983
984 void call32(RegisterID base, int32_t offset)
985 {
eric@webkit.org6a210e72010-04-22 13:24:56 +0000986#if WTF_ARM_ARCH_AT_LEAST(5)
987 int targetReg = ARMRegisters::S1;
988#else
989 int targetReg = ARMRegisters::pc;
990#endif
991 int tmpReg = ARMRegisters::S1;
992
eric@webkit.org734dd062009-08-20 00:02:24 +0000993 if (base == ARMRegisters::sp)
barraclough@apple.com5ea68952009-07-17 21:56:28 +0000994 offset += 4;
995
996 if (offset >= 0) {
997 if (offset <= 0xfff) {
998 prepareCall();
eric@webkit.org6a210e72010-04-22 13:24:56 +0000999 m_assembler.dtr_u(true, targetReg, base, offset);
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001000 } else if (offset <= 0xfffff) {
eric@webkit.org6a210e72010-04-22 13:24:56 +00001001 m_assembler.add_r(tmpReg, base, ARMAssembler::OP2_IMM | (offset >> 12) | (10 << 8));
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001002 prepareCall();
eric@webkit.org6a210e72010-04-22 13:24:56 +00001003 m_assembler.dtr_u(true, targetReg, tmpReg, offset & 0xfff);
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001004 } else {
loki@webkit.orge5c430e2010-07-13 18:56:18 +00001005 m_assembler.moveImm(offset, tmpReg);
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001006 prepareCall();
loki@webkit.orge5c430e2010-07-13 18:56:18 +00001007 m_assembler.dtr_ur(true, targetReg, base, tmpReg);
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001008 }
1009 } else {
1010 offset = -offset;
1011 if (offset <= 0xfff) {
1012 prepareCall();
eric@webkit.org6a210e72010-04-22 13:24:56 +00001013 m_assembler.dtr_d(true, targetReg, base, offset);
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001014 } else if (offset <= 0xfffff) {
eric@webkit.org6a210e72010-04-22 13:24:56 +00001015 m_assembler.sub_r(tmpReg, base, ARMAssembler::OP2_IMM | (offset >> 12) | (10 << 8));
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001016 prepareCall();
eric@webkit.org6a210e72010-04-22 13:24:56 +00001017 m_assembler.dtr_d(true, targetReg, tmpReg, offset & 0xfff);
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001018 } else {
loki@webkit.orge5c430e2010-07-13 18:56:18 +00001019 m_assembler.moveImm(offset, tmpReg);
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001020 prepareCall();
loki@webkit.orge5c430e2010-07-13 18:56:18 +00001021 m_assembler.dtr_dr(true, targetReg, base, tmpReg);
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001022 }
1023 }
eric@webkit.org6a210e72010-04-22 13:24:56 +00001024#if WTF_ARM_ARCH_AT_LEAST(5)
1025 m_assembler.blx(targetReg);
1026#endif
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001027 }
1028
barraclough@apple.com96e73432009-07-22 03:24:34 +00001029private:
1030 friend class LinkBuffer;
1031 friend class RepatchBuffer;
1032
1033 static void linkCall(void* code, Call call, FunctionPtr function)
1034 {
barraclough@apple.com0d15b9e2011-05-26 04:12:41 +00001035 ARMAssembler::linkCall(code, call.m_label, function.value());
barraclough@apple.com96e73432009-07-22 03:24:34 +00001036 }
1037
1038 static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
1039 {
1040 ARMAssembler::relinkCall(call.dataLocation(), destination.executableAddress());
1041 }
1042
1043 static void repatchCall(CodeLocationCall call, FunctionPtr destination)
1044 {
1045 ARMAssembler::relinkCall(call.dataLocation(), destination.executableAddress());
1046 }
1047
zoltan@webkit.org212e83e2009-09-15 11:29:33 +00001048 static const bool s_isVFPPresent;
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001049};
1050
1051}
1052
mjs@apple.comcc668212010-01-04 11:38:56 +00001053#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
barraclough@apple.com5ea68952009-07-17 21:56:28 +00001054
1055#endif // MacroAssemblerARM_h