blob: 9a1ffc36458353388054bce1865288755ab7f2e5 [file] [log] [blame]
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001/*
2 * Copyright (C) 2009-2011 STMicroelectronics. All rights reserved.
3 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*/
26
27#ifndef MacroAssemblerSH4_h
28#define MacroAssemblerSH4_h
29
30#if ENABLE(ASSEMBLER) && CPU(SH4)
31
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +000032#include "SH4Assembler.h"
commit-queue@webkit.orga6448d82011-05-23 16:40:10 +000033#include "AbstractMacroAssembler.h"
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +000034#include <wtf/Assertions.h>
35
36namespace JSC {
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +000037
38class MacroAssemblerSH4 : public AbstractMacroAssembler<SH4Assembler> {
39public:
40 typedef SH4Assembler::FPRegisterID FPRegisterID;
41
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +000042 static const Scale ScalePtr = TimesFour;
43 static const FPRegisterID fscratch = SH4Registers::fr10;
44 static const RegisterID stackPointerRegister = SH4Registers::sp;
45 static const RegisterID linkRegister = SH4Registers::pr;
46 static const RegisterID scratchReg3 = SH4Registers::r13;
47
commit-queue@webkit.org44334562011-08-18 02:56:13 +000048 static const int MaximumCompactPtrAlignedAddressOffset = 60;
oliver@apple.com2c012fa2011-05-17 20:02:41 +000049
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +000050 enum RelationalCondition {
51 Equal = SH4Assembler::EQ,
52 NotEqual = SH4Assembler::NE,
53 Above = SH4Assembler::HI,
54 AboveOrEqual = SH4Assembler::HS,
55 Below = SH4Assembler::LI,
56 BelowOrEqual = SH4Assembler::LS,
57 GreaterThan = SH4Assembler::GT,
58 GreaterThanOrEqual = SH4Assembler::GE,
59 LessThan = SH4Assembler::LT,
60 LessThanOrEqual = SH4Assembler::LE
61 };
62
63 enum ResultCondition {
64 Overflow = SH4Assembler::OF,
65 Signed = SH4Assembler::SI,
66 Zero = SH4Assembler::EQ,
67 NonZero = SH4Assembler::NE
68 };
69
70 enum DoubleCondition {
71 // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
72 DoubleEqual = SH4Assembler::EQ,
73 DoubleNotEqual = SH4Assembler::NE,
74 DoubleGreaterThan = SH4Assembler::GT,
75 DoubleGreaterThanOrEqual = SH4Assembler::GE,
76 DoubleLessThan = SH4Assembler::LT,
77 DoubleLessThanOrEqual = SH4Assembler::LE,
78 // If either operand is NaN, these conditions always evaluate to true.
79 DoubleEqualOrUnordered = SH4Assembler::EQU,
80 DoubleNotEqualOrUnordered = SH4Assembler::NEU,
81 DoubleGreaterThanOrUnordered = SH4Assembler::GTU,
82 DoubleGreaterThanOrEqualOrUnordered = SH4Assembler::GEU,
83 DoubleLessThanOrUnordered = SH4Assembler::LTU,
84 DoubleLessThanOrEqualOrUnordered = SH4Assembler::LEU,
85 };
86
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +000087 RegisterID claimScratch()
88 {
89 return m_assembler.claimScratch();
90 }
91
92 void releaseScratch(RegisterID reg)
93 {
94 m_assembler.releaseScratch(reg);
95 }
96
97 // Integer arithmetic operations
98
99 void add32(RegisterID src, RegisterID dest)
100 {
101 m_assembler.addlRegReg(src, dest);
102 }
103
104 void add32(TrustedImm32 imm, RegisterID dest)
105 {
106 if (m_assembler.isImmediate(imm.m_value)) {
107 m_assembler.addlImm8r(imm.m_value, dest);
108 return;
109 }
110
111 RegisterID scr = claimScratch();
112 m_assembler.loadConstant(imm.m_value, scr);
113 m_assembler.addlRegReg(scr, dest);
114 releaseScratch(scr);
115 }
116
117 void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
118 {
119 if (src != dest)
120 m_assembler.movlRegReg(src, dest);
121 add32(imm, dest);
122 }
123
124 void add32(TrustedImm32 imm, Address address)
125 {
126 RegisterID scr = claimScratch();
127 load32(address, scr);
128 add32(imm, scr);
129 store32(scr, address);
130 releaseScratch(scr);
131 }
132
133 void add32(Address src, RegisterID dest)
134 {
135 RegisterID scr = claimScratch();
136 load32(src, scr);
137 m_assembler.addlRegReg(scr, dest);
138 releaseScratch(scr);
139 }
140
141 void and32(RegisterID src, RegisterID dest)
142 {
143 m_assembler.andlRegReg(src, dest);
144 }
145
146 void and32(TrustedImm32 imm, RegisterID dest)
147 {
148 if ((imm.m_value <= 255) && (imm.m_value >= 0) && (dest == SH4Registers::r0)) {
149 m_assembler.andlImm8r(imm.m_value, dest);
150 return;
151 }
152
153 RegisterID scr = claimScratch();
154 m_assembler.loadConstant((imm.m_value), scr);
155 m_assembler.andlRegReg(scr, dest);
156 releaseScratch(scr);
157 }
158
159 void lshift32(RegisterID shiftamount, RegisterID dest)
160 {
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000161 if (shiftamount == SH4Registers::r0)
162 m_assembler.andlImm8r(0x1f, shiftamount);
163 else {
164 RegisterID scr = claimScratch();
165 m_assembler.loadConstant(0x1f, scr);
166 m_assembler.andlRegReg(scr, shiftamount);
167 releaseScratch(scr);
168 }
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000169 m_assembler.shllRegReg(dest, shiftamount);
170 }
171
172 void rshift32(int imm, RegisterID dest)
173 {
174 RegisterID scr = claimScratch();
175 m_assembler.loadConstant(-imm, scr);
176 m_assembler.shaRegReg(dest, scr);
177 releaseScratch(scr);
178 }
179
180 void lshift32(TrustedImm32 imm, RegisterID dest)
181 {
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000182 if (!imm.m_value)
183 return;
184
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000185 if ((imm.m_value == 1) || (imm.m_value == 2) || (imm.m_value == 8) || (imm.m_value == 16)) {
186 m_assembler.shllImm8r(imm.m_value, dest);
187 return;
188 }
189
190 RegisterID scr = claimScratch();
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000191 m_assembler.loadConstant((imm.m_value & 0x1f) , scr);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000192 m_assembler.shllRegReg(dest, scr);
193 releaseScratch(scr);
194 }
195
196 void mul32(RegisterID src, RegisterID dest)
197 {
198 m_assembler.imullRegReg(src, dest);
199 m_assembler.stsmacl(dest);
200 }
201
202 void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
203 {
204 RegisterID scr = claimScratch();
205 move(imm, scr);
206 if (src != dest)
207 move(src, dest);
208 mul32(scr, dest);
209 releaseScratch(scr);
210 }
211
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000212 void or32(RegisterID src, RegisterID dest)
213 {
214 m_assembler.orlRegReg(src, dest);
215 }
216
217 void or32(TrustedImm32 imm, RegisterID dest)
218 {
219 if ((imm.m_value <= 255) && (imm.m_value >= 0) && (dest == SH4Registers::r0)) {
220 m_assembler.orlImm8r(imm.m_value, dest);
221 return;
222 }
223
224 RegisterID scr = claimScratch();
225 m_assembler.loadConstant(imm.m_value, scr);
226 m_assembler.orlRegReg(scr, dest);
227 releaseScratch(scr);
228 }
229
barraclough@apple.com8328f632011-09-21 18:33:43 +0000230 void or32(RegisterID op1, RegisterID op2, RegisterID dest)
231 {
232 if (op1 == op2)
233 move(op1, dest);
234 else if (op1 == dest)
235 or32(op2, dest);
236 else {
237 move(op2, dest);
238 or32(op1, dest);
239 }
240 }
241
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000242 void rshift32(RegisterID shiftamount, RegisterID dest)
243 {
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000244 if (shiftamount == SH4Registers::r0)
245 m_assembler.andlImm8r(0x1f, shiftamount);
246 else {
247 RegisterID scr = claimScratch();
248 m_assembler.loadConstant(0x1f, scr);
249 m_assembler.andlRegReg(scr, shiftamount);
250 releaseScratch(scr);
251 }
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000252 m_assembler.neg(shiftamount, shiftamount);
253 m_assembler.shaRegReg(dest, shiftamount);
254 }
255
256 void rshift32(TrustedImm32 imm, RegisterID dest)
257 {
258 if (imm.m_value & 0x1f)
259 rshift32(imm.m_value & 0x1f, dest);
260 }
261
commit-queue@webkit.org44334562011-08-18 02:56:13 +0000262 void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
263 {
264 if (src != dest)
265 move(src, dest);
266 rshift32(imm, dest);
267 }
268
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000269 void sub32(RegisterID src, RegisterID dest)
270 {
271 m_assembler.sublRegReg(src, dest);
272 }
273
274 void sub32(TrustedImm32 imm, AbsoluteAddress address, RegisterID scratchReg)
275 {
276 RegisterID result = claimScratch();
277
278 m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg);
279 m_assembler.movlMemReg(scratchReg, result);
280
281 if (m_assembler.isImmediate(-imm.m_value))
282 m_assembler.addlImm8r(-imm.m_value, result);
283 else {
284 m_assembler.loadConstant(imm.m_value, scratchReg3);
285 m_assembler.sublRegReg(scratchReg3, result);
286 }
287
288 store32(result, scratchReg);
289 releaseScratch(result);
290 }
291
292 void sub32(TrustedImm32 imm, AbsoluteAddress address)
293 {
294 RegisterID result = claimScratch();
295 RegisterID scratchReg = claimScratch();
296
297 m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg);
298 m_assembler.movlMemReg(scratchReg, result);
299
300 if (m_assembler.isImmediate(-imm.m_value))
301 m_assembler.addlImm8r(-imm.m_value, result);
302 else {
303 m_assembler.loadConstant(imm.m_value, scratchReg3);
304 m_assembler.sublRegReg(scratchReg3, result);
305 }
306
307 store32(result, scratchReg);
308 releaseScratch(result);
309 releaseScratch(scratchReg);
310 }
311
312 void add32(TrustedImm32 imm, AbsoluteAddress address, RegisterID scratchReg)
313 {
314 RegisterID result = claimScratch();
315
316 m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg);
317 m_assembler.movlMemReg(scratchReg, result);
318
319 if (m_assembler.isImmediate(imm.m_value))
320 m_assembler.addlImm8r(imm.m_value, result);
321 else {
322 m_assembler.loadConstant(imm.m_value, scratchReg3);
323 m_assembler.addlRegReg(scratchReg3, result);
324 }
325
326 store32(result, scratchReg);
327 releaseScratch(result);
328 }
329
330 void add32(TrustedImm32 imm, AbsoluteAddress address)
331 {
332 RegisterID result = claimScratch();
333 RegisterID scratchReg = claimScratch();
334
335 m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg);
336 m_assembler.movlMemReg(scratchReg, result);
337
338 if (m_assembler.isImmediate(imm.m_value))
339 m_assembler.addlImm8r(imm.m_value, result);
340 else {
341 m_assembler.loadConstant(imm.m_value, scratchReg3);
342 m_assembler.addlRegReg(scratchReg3, result);
343 }
344
345 store32(result, scratchReg);
346 releaseScratch(result);
347 releaseScratch(scratchReg);
348 }
349
350 void sub32(TrustedImm32 imm, RegisterID dest)
351 {
352 if (m_assembler.isImmediate(-imm.m_value)) {
353 m_assembler.addlImm8r(-imm.m_value, dest);
354 return;
355 }
356
357 RegisterID scr = claimScratch();
358 m_assembler.loadConstant(imm.m_value, scr);
359 m_assembler.sublRegReg(scr, dest);
360 releaseScratch(scr);
361 }
362
363 void sub32(Address src, RegisterID dest)
364 {
365 RegisterID scr = claimScratch();
366 load32(src, scr);
367 m_assembler.sublRegReg(scr, dest);
368 releaseScratch(scr);
369 }
370
371 void xor32(RegisterID src, RegisterID dest)
372 {
373 m_assembler.xorlRegReg(src, dest);
374 }
375
376 void xor32(TrustedImm32 imm, RegisterID srcDest)
377 {
barraclough@apple.coma6bdfc82012-02-27 18:26:23 +0000378 if (imm.m_value == -1) {
379 m_assembler.notlReg(srcDest, srcDest);
380 return;
381 }
382
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000383 if ((srcDest != SH4Registers::r0) || (imm.m_value > 255) || (imm.m_value < 0)) {
384 RegisterID scr = claimScratch();
385 m_assembler.loadConstant((imm.m_value), scr);
386 m_assembler.xorlRegReg(scr, srcDest);
387 releaseScratch(scr);
388 return;
389 }
390
391 m_assembler.xorlImm8r(imm.m_value, srcDest);
392 }
393
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000394 void compare32(int imm, RegisterID dst, RelationalCondition cond)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000395 {
396 if (((cond == Equal) || (cond == NotEqual)) && (dst == SH4Registers::r0) && m_assembler.isImmediate(imm)) {
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000397 m_assembler.cmpEqImmR0(imm, dst);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000398 return;
399 }
400
401 RegisterID scr = claimScratch();
402 m_assembler.loadConstant(imm, scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000403 m_assembler.cmplRegReg(scr, dst, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000404 releaseScratch(scr);
405 }
406
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000407 void compare32(int offset, RegisterID base, RegisterID left, RelationalCondition cond)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000408 {
409 RegisterID scr = claimScratch();
410 if (!offset) {
411 m_assembler.movlMemReg(base, scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000412 m_assembler.cmplRegReg(scr, left, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000413 releaseScratch(scr);
414 return;
415 }
416
417 if ((offset < 0) || (offset >= 64)) {
418 m_assembler.loadConstant(offset, scr);
419 m_assembler.addlRegReg(base, scr);
420 m_assembler.movlMemReg(scr, scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000421 m_assembler.cmplRegReg(scr, left, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000422 releaseScratch(scr);
423 return;
424 }
425
426 m_assembler.movlMemReg(offset >> 2, base, scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000427 m_assembler.cmplRegReg(scr, left, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000428 releaseScratch(scr);
429 }
430
431 void testImm(int imm, int offset, RegisterID base)
432 {
433 RegisterID scr = claimScratch();
434 RegisterID scr1 = claimScratch();
435
436 if ((offset < 0) || (offset >= 64)) {
437 m_assembler.loadConstant(offset, scr);
438 m_assembler.addlRegReg(base, scr);
439 m_assembler.movlMemReg(scr, scr);
440 } else if (offset)
441 m_assembler.movlMemReg(offset >> 2, base, scr);
442 else
443 m_assembler.movlMemReg(base, scr);
444 if (m_assembler.isImmediate(imm))
445 m_assembler.movImm8(imm, scr1);
446 else
447 m_assembler.loadConstant(imm, scr1);
448
449 m_assembler.testlRegReg(scr, scr1);
450 releaseScratch(scr);
451 releaseScratch(scr1);
452 }
453
454 void testlImm(int imm, RegisterID dst)
455 {
456 if ((dst == SH4Registers::r0) && (imm <= 255) && (imm >= 0)) {
457 m_assembler.testlImm8r(imm, dst);
458 return;
459 }
460
461 RegisterID scr = claimScratch();
462 m_assembler.loadConstant(imm, scr);
463 m_assembler.testlRegReg(scr, dst);
464 releaseScratch(scr);
465 }
466
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000467 void compare32(RegisterID right, int offset, RegisterID base, RelationalCondition cond)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000468 {
469 if (!offset) {
470 RegisterID scr = claimScratch();
471 m_assembler.movlMemReg(base, scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000472 m_assembler.cmplRegReg(right, scr, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000473 releaseScratch(scr);
474 return;
475 }
476
477 if ((offset < 0) || (offset >= 64)) {
478 RegisterID scr = claimScratch();
479 m_assembler.loadConstant(offset, scr);
480 m_assembler.addlRegReg(base, scr);
481 m_assembler.movlMemReg(scr, scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000482 m_assembler.cmplRegReg(right, scr, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000483 releaseScratch(scr);
484 return;
485 }
486
487 RegisterID scr = claimScratch();
488 m_assembler.movlMemReg(offset >> 2, base, scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000489 m_assembler.cmplRegReg(right, scr, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000490 releaseScratch(scr);
491 }
492
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000493 void compare32(int imm, int offset, RegisterID base, RelationalCondition cond)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000494 {
495 if (!offset) {
496 RegisterID scr = claimScratch();
497 RegisterID scr1 = claimScratch();
498 m_assembler.movlMemReg(base, scr);
499 m_assembler.loadConstant(imm, scr1);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000500 m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000501 releaseScratch(scr1);
502 releaseScratch(scr);
503 return;
504 }
505
506 if ((offset < 0) || (offset >= 64)) {
507 RegisterID scr = claimScratch();
508 RegisterID scr1 = claimScratch();
509 m_assembler.loadConstant(offset, scr);
510 m_assembler.addlRegReg(base, scr);
511 m_assembler.movlMemReg(scr, scr);
512 m_assembler.loadConstant(imm, scr1);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000513 m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000514 releaseScratch(scr1);
515 releaseScratch(scr);
516 return;
517 }
518
519 RegisterID scr = claimScratch();
520 RegisterID scr1 = claimScratch();
521 m_assembler.movlMemReg(offset >> 2, base, scr);
522 m_assembler.loadConstant(imm, scr1);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000523 m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000524 releaseScratch(scr1);
525 releaseScratch(scr);
526 }
527
528 // Memory access operation
529
530 void load32(ImplicitAddress address, RegisterID dest)
531 {
532 load32(address.base, address.offset, dest);
533 }
534
535 void load8(ImplicitAddress address, RegisterID dest)
536 {
537 load8(address.base, address.offset, dest);
538 }
539
msaboff@apple.com2cc41502011-09-12 22:17:53 +0000540 void load8(BaseIndex address, RegisterID dest)
541 {
542 RegisterID scr = claimScratch();
543 move(address.index, scr);
544 lshift32(TrustedImm32(address.scale), scr);
545 add32(address.base, scr);
546 load8(scr, address.offset, dest);
547 releaseScratch(scr);
548 }
549
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000550 void load32(BaseIndex address, RegisterID dest)
551 {
552 RegisterID scr = claimScratch();
553 move(address.index, scr);
554 lshift32(TrustedImm32(address.scale), scr);
555 add32(address.base, scr);
556 load32(scr, address.offset, dest);
557 releaseScratch(scr);
558 }
559
barraclough@apple.com8328f632011-09-21 18:33:43 +0000560 void load32(const void* address, RegisterID dest)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000561 {
barraclough@apple.com8328f632011-09-21 18:33:43 +0000562 m_assembler.loadConstant(reinterpret_cast<uint32_t>(const_cast<void*>(address)), dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000563 m_assembler.movlMemReg(dest, dest);
564 }
565
566 void load32(RegisterID base, int offset, RegisterID dest)
567 {
568 if (!offset) {
569 m_assembler.movlMemReg(base, dest);
570 return;
571 }
572
573 if ((offset >= 0) && (offset < 64)) {
574 m_assembler.movlMemReg(offset >> 2, base, dest);
575 return;
576 }
577
578 if ((dest == SH4Registers::r0) && (dest != base)) {
579 m_assembler.loadConstant((offset), dest);
580 m_assembler.movlR0mr(base, dest);
581 return;
582 }
583
584 RegisterID scr;
585 if (dest == base)
586 scr = claimScratch();
587 else
588 scr = dest;
589 m_assembler.loadConstant((offset), scr);
590 m_assembler.addlRegReg(base, scr);
591 m_assembler.movlMemReg(scr, dest);
592
593 if (dest == base)
594 releaseScratch(scr);
595 }
596
597 void load8(RegisterID base, int offset, RegisterID dest)
598 {
599 if (!offset) {
600 m_assembler.movbMemReg(base, dest);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000601 m_assembler.extub(dest, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000602 return;
603 }
604
605 if ((offset > 0) && (offset < 64) && (dest == SH4Registers::r0)) {
606 m_assembler.movbMemReg(offset, base, dest);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000607 m_assembler.extub(dest, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000608 return;
609 }
610
611 if (base != dest) {
612 m_assembler.loadConstant((offset), dest);
613 m_assembler.addlRegReg(base, dest);
614 m_assembler.movbMemReg(dest, dest);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000615 m_assembler.extub(dest, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000616 return;
617 }
618
619 RegisterID scr = claimScratch();
620 m_assembler.loadConstant((offset), scr);
621 m_assembler.addlRegReg(base, scr);
622 m_assembler.movbMemReg(scr, dest);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000623 m_assembler.extub(dest, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000624 releaseScratch(scr);
625 }
626
627 void load32(RegisterID r0, RegisterID src, RegisterID dst)
628 {
629 ASSERT(r0 == SH4Registers::r0);
630 m_assembler.movlR0mr(src, dst);
631 }
632
633 void load32(RegisterID src, RegisterID dst)
634 {
635 m_assembler.movlMemReg(src, dst);
636 }
637
638 void load16(ImplicitAddress address, RegisterID dest)
639 {
640 if (!address.offset) {
641 m_assembler.movwMemReg(address.base, dest);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000642 extuw(dest, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000643 return;
644 }
645
646 if ((address.offset > 0) && (address.offset < 64) && (dest == SH4Registers::r0)) {
647 m_assembler.movwMemReg(address.offset, address.base, dest);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000648 extuw(dest, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000649 return;
650 }
651
652 if (address.base != dest) {
653 m_assembler.loadConstant((address.offset), dest);
654 m_assembler.addlRegReg(address.base, dest);
655 m_assembler.movwMemReg(dest, dest);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000656 extuw(dest, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000657 return;
658 }
659
660 RegisterID scr = claimScratch();
661 m_assembler.loadConstant((address.offset), scr);
662 m_assembler.addlRegReg(address.base, scr);
663 m_assembler.movwMemReg(scr, dest);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000664 extuw(dest, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000665 releaseScratch(scr);
666 }
667
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000668 void load16Unaligned(BaseIndex address, RegisterID dest)
669 {
670
671 RegisterID scr = claimScratch();
672 RegisterID scr1 = claimScratch();
673
674 move(address.index, scr);
675 lshift32(TrustedImm32(address.scale), scr);
676
677 if (address.offset)
678 add32(TrustedImm32(address.offset), scr);
679
680 add32(address.base, scr);
681 load8(scr, scr1);
682 add32(TrustedImm32(1), scr);
683 load8(scr, dest);
684 move(TrustedImm32(8), scr);
685 m_assembler.shllRegReg(dest, scr);
686 or32(scr1, dest);
687
688 releaseScratch(scr);
689 releaseScratch(scr1);
690 }
691
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000692 void load16(RegisterID src, RegisterID dest)
693 {
694 m_assembler.movwMemReg(src, dest);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000695 extuw(dest, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000696 }
697
698 void load16(RegisterID r0, RegisterID src, RegisterID dest)
699 {
700 ASSERT(r0 == SH4Registers::r0);
701 m_assembler.movwR0mr(src, dest);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000702 extuw(dest, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000703 }
704
705 void load16(BaseIndex address, RegisterID dest)
706 {
707 RegisterID scr = claimScratch();
708
709 move(address.index, scr);
710 lshift32(TrustedImm32(address.scale), scr);
711
712 if (address.offset)
713 add32(TrustedImm32(address.offset), scr);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000714 if (address.base == SH4Registers::r0)
715 load16(address.base, scr, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000716 else {
717 add32(address.base, scr);
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +0000718 load16(scr, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000719 }
720
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000721 releaseScratch(scr);
722 }
723
724 void store32(RegisterID src, ImplicitAddress address)
725 {
726 RegisterID scr = claimScratch();
727 store32(src, address.offset, address.base, scr);
728 releaseScratch(scr);
729 }
730
731 void store32(RegisterID src, int offset, RegisterID base, RegisterID scr)
732 {
733 if (!offset) {
734 m_assembler.movlRegMem(src, base);
735 return;
736 }
737
738 if ((offset >=0) && (offset < 64)) {
739 m_assembler.movlRegMem(src, offset >> 2, base);
740 return;
741 }
742
743 m_assembler.loadConstant((offset), scr);
744 if (scr == SH4Registers::r0) {
745 m_assembler.movlRegMemr0(src, base);
746 return;
747 }
748
749 m_assembler.addlRegReg(base, scr);
750 m_assembler.movlRegMem(src, scr);
751 }
752
753 void store32(RegisterID src, RegisterID offset, RegisterID base)
754 {
755 ASSERT(offset == SH4Registers::r0);
756 m_assembler.movlRegMemr0(src, base);
757 }
758
759 void store32(RegisterID src, RegisterID dst)
760 {
761 m_assembler.movlRegMem(src, dst);
762 }
763
764 void store32(TrustedImm32 imm, ImplicitAddress address)
765 {
766 RegisterID scr = claimScratch();
767 RegisterID scr1 = claimScratch();
768 m_assembler.loadConstant((imm.m_value), scr);
769 store32(scr, address.offset, address.base, scr1);
770 releaseScratch(scr);
771 releaseScratch(scr1);
772 }
773
774 void store32(RegisterID src, BaseIndex address)
775 {
776 RegisterID scr = claimScratch();
777
778 move(address.index, scr);
779 lshift32(TrustedImm32(address.scale), scr);
780 add32(address.base, scr);
781 store32(src, Address(scr, address.offset));
782
783 releaseScratch(scr);
784 }
785
786 void store32(TrustedImm32 imm, void* address)
787 {
788 RegisterID scr = claimScratch();
789 RegisterID scr1 = claimScratch();
790 m_assembler.loadConstant((imm.m_value), scr);
791 m_assembler.loadConstant(reinterpret_cast<uint32_t>(address), scr1);
commit-queue@webkit.org44334562011-08-18 02:56:13 +0000792 m_assembler.movlRegMem(scr, scr1);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000793 releaseScratch(scr);
794 releaseScratch(scr1);
795 }
796
797 void store32(RegisterID src, void* address)
798 {
799 RegisterID scr = claimScratch();
800 m_assembler.loadConstant(reinterpret_cast<uint32_t>(address), scr);
commit-queue@webkit.org44334562011-08-18 02:56:13 +0000801 m_assembler.movlRegMem(src, scr);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000802 releaseScratch(scr);
803 }
804
805 DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
806 {
807 RegisterID scr = claimScratch();
808 DataLabel32 label(this);
809 m_assembler.loadConstantUnReusable(address.offset, scr);
810 m_assembler.addlRegReg(address.base, scr);
811 m_assembler.movlMemReg(scr, dest);
812 releaseScratch(scr);
813 return label;
814 }
oliver@apple.com2c012fa2011-05-17 20:02:41 +0000815
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000816 DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
817 {
818 RegisterID scr = claimScratch();
819 DataLabel32 label(this);
820 m_assembler.loadConstantUnReusable(address.offset, scr);
821 m_assembler.addlRegReg(address.base, scr);
822 m_assembler.movlRegMem(src, scr);
823 releaseScratch(scr);
824 return label;
825 }
826
commit-queue@webkit.org44334562011-08-18 02:56:13 +0000827 DataLabelCompact load32WithCompactAddressOffsetPatch(Address address, RegisterID dest)
828 {
829 DataLabelCompact dataLabel(this);
830 ASSERT(address.offset <= MaximumCompactPtrAlignedAddressOffset);
831 ASSERT(address.offset >= 0);
832 m_assembler.movlMemRegCompact(address.offset >> 2, address.base, dest);
833 return dataLabel;
834 }
835
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000836 // Floating-point operations
837
barraclough@apple.com2326f422011-11-09 20:01:24 +0000838 static bool supportsFloatingPoint() { return true; }
839 static bool supportsFloatingPointTruncate() { return true; }
840 static bool supportsFloatingPointSqrt() { return true; }
841 static bool supportsFloatingPointAbs() { return false; }
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000842
843 void loadDouble(ImplicitAddress address, FPRegisterID dest)
844 {
845 RegisterID scr = claimScratch();
846
847 m_assembler.loadConstant(address.offset, scr);
848 if (address.base == SH4Registers::r0) {
849 m_assembler.fmovsReadr0r(scr, (FPRegisterID)(dest + 1));
850 m_assembler.addlImm8r(4, scr);
851 m_assembler.fmovsReadr0r(scr, dest);
852 releaseScratch(scr);
853 return;
854 }
855
856 m_assembler.addlRegReg(address.base, scr);
857 m_assembler.fmovsReadrminc(scr, (FPRegisterID)(dest + 1));
858 m_assembler.fmovsReadrm(scr, dest);
859 releaseScratch(scr);
860 }
861
862 void loadDouble(const void* address, FPRegisterID dest)
863 {
864 RegisterID scr = claimScratch();
865 m_assembler.loadConstant(reinterpret_cast<uint32_t>(address), scr);
866 m_assembler.fmovsReadrminc(scr, (FPRegisterID)(dest + 1));
867 m_assembler.fmovsReadrm(scr, dest);
868 releaseScratch(scr);
869 }
870
871 void storeDouble(FPRegisterID src, ImplicitAddress address)
872 {
873 RegisterID scr = claimScratch();
874 m_assembler.loadConstant(address.offset, scr);
875 m_assembler.addlRegReg(address.base, scr);
876 m_assembler.fmovsWriterm((FPRegisterID)(src + 1), scr);
877 m_assembler.addlImm8r(4, scr);
878 m_assembler.fmovsWriterm(src, scr);
879 releaseScratch(scr);
880 }
881
882 void addDouble(FPRegisterID src, FPRegisterID dest)
883 {
884 m_assembler.daddRegReg(src, dest);
885 }
886
887 void addDouble(Address address, FPRegisterID dest)
888 {
889 loadDouble(address, fscratch);
890 addDouble(fscratch, dest);
891 }
892
893 void subDouble(FPRegisterID src, FPRegisterID dest)
894 {
895 m_assembler.dsubRegReg(src, dest);
896 }
897
898 void subDouble(Address address, FPRegisterID dest)
899 {
900 loadDouble(address, fscratch);
901 subDouble(fscratch, dest);
902 }
903
904 void mulDouble(FPRegisterID src, FPRegisterID dest)
905 {
906 m_assembler.dmulRegReg(src, dest);
907 }
908
909 void mulDouble(Address address, FPRegisterID dest)
910 {
911 loadDouble(address, fscratch);
912 mulDouble(fscratch, dest);
913 }
914
915 void divDouble(FPRegisterID src, FPRegisterID dest)
916 {
917 m_assembler.ddivRegReg(src, dest);
918 }
919
920 void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
921 {
922 m_assembler.ldsrmfpul(src);
923 m_assembler.floatfpulDreg(dest);
924 }
925
926 void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
927 {
928 RegisterID scr = claimScratch();
929 m_assembler.loadConstant(reinterpret_cast<uint32_t>(src.m_ptr), scr);
930 convertInt32ToDouble(scr, dest);
931 releaseScratch(scr);
932 }
933
934 void convertInt32ToDouble(Address src, FPRegisterID dest)
935 {
936 RegisterID scr = claimScratch();
937 load32(src, scr);
938 convertInt32ToDouble(scr, dest);
939 releaseScratch(scr);
940 }
941
942 void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
943 {
944 RegisterID scr = claimScratch();
945
946 move(address.index, scr);
947 lshift32(TrustedImm32(address.scale), scr);
948 add32(address.base, scr);
949
950 if (address.offset)
951 add32(TrustedImm32(address.offset), scr);
952
953 RegisterID scr1 = claimScratch();
954 load16(scr, scr1);
955 add32(TrustedImm32(2), scr);
956 load16(scr, dest);
957 move(TrustedImm32(16), scr);
958 m_assembler.shllRegReg(dest, scr);
959 or32(scr1, dest);
960
961 releaseScratch(scr);
962 releaseScratch(scr1);
963 }
964
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000965 Jump branch32WithUnalignedHalfWords(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000966 {
967 RegisterID scr = scratchReg3;
968 load32WithUnalignedHalfWords(left, scr);
969 if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
970 m_assembler.testlRegReg(scr, scr);
971 else
972 compare32(right.m_value, scr, cond);
973
974 if (cond == NotEqual)
975 return branchFalse();
976 return branchTrue();
977 }
978
979 Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID scratch)
980 {
981 m_assembler.movImm8(0, scratchReg3);
982 convertInt32ToDouble(scratchReg3, scratch);
983 return branchDouble(DoubleNotEqual, reg, scratch);
984 }
985
986 Jump branchDoubleZeroOrNaN(FPRegisterID reg, FPRegisterID scratch)
987 {
988 m_assembler.movImm8(0, scratchReg3);
989 convertInt32ToDouble(scratchReg3, scratch);
990 return branchDouble(DoubleEqualOrUnordered, reg, scratch);
991 }
992
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +0000993 Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +0000994 {
995 if (cond == DoubleEqual) {
996 m_assembler.dcmppeq(right, left);
997 return branchTrue();
998 }
999
1000 if (cond == DoubleNotEqual) {
1001 RegisterID scr = claimScratch();
1002 m_assembler.loadConstant(0x7fbfffff, scratchReg3);
1003 m_assembler.dcnvds(right);
1004 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001005 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001006 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
1007 m_assembler.branch(BT_OPCODE, 8);
1008 m_assembler.dcnvds(left);
1009 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001010 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001011 m_assembler.branch(BT_OPCODE, 4);
1012 m_assembler.dcmppeq(right, left);
1013 releaseScratch(scr);
1014 return branchFalse();
1015 }
1016
1017 if (cond == DoubleGreaterThan) {
1018 m_assembler.dcmppgt(right, left);
1019 return branchTrue();
1020 }
1021
1022 if (cond == DoubleGreaterThanOrEqual) {
1023 m_assembler.dcmppgt(left, right);
1024 return branchFalse();
1025 }
1026
1027 if (cond == DoubleLessThan) {
1028 m_assembler.dcmppgt(left, right);
1029 return branchTrue();
1030 }
1031
1032 if (cond == DoubleLessThanOrEqual) {
1033 m_assembler.dcmppgt(right, left);
1034 return branchFalse();
1035 }
1036
1037 if (cond == DoubleEqualOrUnordered) {
1038 RegisterID scr = claimScratch();
1039 m_assembler.loadConstant(0x7fbfffff, scratchReg3);
1040 m_assembler.dcnvds(right);
1041 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001042 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001043 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
1044 m_assembler.branch(BT_OPCODE, 5);
1045 m_assembler.dcnvds(left);
1046 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001047 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001048 m_assembler.branch(BT_OPCODE, 1);
1049 m_assembler.dcmppeq(left, right);
1050 releaseScratch(scr);
1051 return branchTrue();
1052 }
1053
1054 if (cond == DoubleGreaterThanOrUnordered) {
1055 RegisterID scr = claimScratch();
1056 m_assembler.loadConstant(0x7fbfffff, scratchReg3);
1057 m_assembler.dcnvds(right);
1058 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001059 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001060 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
1061 m_assembler.branch(BT_OPCODE, 5);
1062 m_assembler.dcnvds(left);
1063 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001064 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001065 m_assembler.branch(BT_OPCODE, 1);
1066 m_assembler.dcmppgt(right, left);
1067 releaseScratch(scr);
1068 return branchTrue();
1069 }
1070
1071 if (cond == DoubleGreaterThanOrEqualOrUnordered) {
1072 RegisterID scr = claimScratch();
1073 m_assembler.loadConstant(0x7fbfffff, scratchReg3);
1074 m_assembler.dcnvds(right);
1075 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001076 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001077 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
1078 m_assembler.branch(BT_OPCODE, 5);
1079 m_assembler.dcnvds(left);
1080 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001081 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001082 m_assembler.branch(BT_OPCODE, 1);
1083 m_assembler.dcmppgt(left, right);
1084 releaseScratch(scr);
1085 return branchFalse();
1086 }
1087
1088 if (cond == DoubleLessThanOrUnordered) {
1089 RegisterID scr = claimScratch();
1090 m_assembler.loadConstant(0x7fbfffff, scratchReg3);
1091 m_assembler.dcnvds(right);
1092 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001093 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001094 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
1095 m_assembler.branch(BT_OPCODE, 5);
1096 m_assembler.dcnvds(left);
1097 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001098 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001099 m_assembler.branch(BT_OPCODE, 1);
1100 m_assembler.dcmppgt(left, right);
1101 releaseScratch(scr);
1102 return branchTrue();
1103 }
1104
1105 if (cond == DoubleLessThanOrEqualOrUnordered) {
1106 RegisterID scr = claimScratch();
1107 m_assembler.loadConstant(0x7fbfffff, scratchReg3);
1108 m_assembler.dcnvds(right);
1109 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001110 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001111 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
1112 m_assembler.branch(BT_OPCODE, 5);
1113 m_assembler.dcnvds(left);
1114 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001115 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001116 m_assembler.branch(BT_OPCODE, 1);
1117 m_assembler.dcmppgt(right, left);
1118 releaseScratch(scr);
1119 return branchFalse();
1120 }
1121
1122 ASSERT(cond == DoubleNotEqualOrUnordered);
1123 RegisterID scr = claimScratch();
1124 m_assembler.loadConstant(0x7fbfffff, scratchReg3);
1125 m_assembler.dcnvds(right);
1126 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001127 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001128 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
1129 m_assembler.branch(BT_OPCODE, 5);
1130 m_assembler.dcnvds(left);
1131 m_assembler.stsfpulReg(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001132 m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001133 m_assembler.branch(BT_OPCODE, 1);
1134 m_assembler.dcmppeq(right, left);
1135 releaseScratch(scr);
1136 return branchFalse();
1137 }
1138
1139 Jump branchTrue()
1140 {
1141 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 6, sizeof(uint32_t));
1142 Jump m_jump = Jump(m_assembler.je());
1143 m_assembler.loadConstantUnReusable(0x0, scratchReg3);
1144 m_assembler.nop();
1145 m_assembler.nop();
1146 return m_jump;
1147 }
1148
1149 Jump branchFalse()
1150 {
1151 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 6, sizeof(uint32_t));
1152 Jump m_jump = Jump(m_assembler.jne());
1153 m_assembler.loadConstantUnReusable(0x0, scratchReg3);
1154 m_assembler.nop();
1155 m_assembler.nop();
1156 return m_jump;
1157 }
1158
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001159 Jump branch32(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001160 {
1161 RegisterID scr = claimScratch();
1162 move(left.index, scr);
1163 lshift32(TrustedImm32(left.scale), scr);
1164 add32(left.base, scr);
1165 load32(scr, left.offset, scr);
1166 compare32(right.m_value, scr, cond);
1167 releaseScratch(scr);
1168
1169 if (cond == NotEqual)
1170 return branchFalse();
1171 return branchTrue();
1172 }
1173
1174 void sqrtDouble(FPRegisterID src, FPRegisterID dest)
1175 {
1176 if (dest != src)
1177 m_assembler.dmovRegReg(src, dest);
1178 m_assembler.dsqrt(dest);
1179 }
oliver@apple.com5b6a0d32011-07-01 16:33:46 +00001180
barraclough@apple.com8306fdb2011-11-09 23:05:03 +00001181 void absDouble(FPRegisterID, FPRegisterID)
oliver@apple.com5b6a0d32011-07-01 16:33:46 +00001182 {
1183 ASSERT_NOT_REACHED();
1184 }
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001185
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001186 Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001187 {
1188 RegisterID addressTempRegister = claimScratch();
1189 load8(address, addressTempRegister);
1190 Jump jmp = branchTest32(cond, addressTempRegister, mask);
1191 releaseScratch(addressTempRegister);
1192 return jmp;
1193 }
1194
1195 void signExtend32ToPtr(RegisterID src, RegisterID dest)
1196 {
1197 if (src != dest)
1198 move(src, dest);
1199 }
1200
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001201 Jump branch8(RelationalCondition cond, Address left, TrustedImm32 right)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001202 {
1203 RegisterID addressTempRegister = claimScratch();
1204 load8(left, addressTempRegister);
1205 Jump jmp = branch32(cond, addressTempRegister, right);
1206 releaseScratch(addressTempRegister);
1207 return jmp;
1208 }
1209
1210 Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
1211 {
1212 m_assembler.ftrcdrmfpul(src);
1213 m_assembler.stsfpulReg(dest);
1214 m_assembler.loadConstant(0x7fffffff, scratchReg3);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001215 m_assembler.cmplRegReg(dest, scratchReg3, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001216 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 14, sizeof(uint32_t));
1217 m_assembler.branch(BT_OPCODE, 2);
1218 m_assembler.addlImm8r(1, scratchReg3);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001219 m_assembler.cmplRegReg(dest, scratchReg3, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001220 return branchTrue();
1221 }
1222
1223 // Stack manipulation operations
1224
1225 void pop(RegisterID dest)
1226 {
1227 m_assembler.popReg(dest);
1228 }
1229
1230 void push(RegisterID src)
1231 {
1232 m_assembler.pushReg(src);
1233 }
1234
1235 void push(Address address)
1236 {
1237 if (!address.offset) {
1238 push(address.base);
1239 return;
1240 }
1241
1242 if ((address.offset < 0) || (address.offset >= 64)) {
1243 RegisterID scr = claimScratch();
1244 m_assembler.loadConstant(address.offset, scr);
1245 m_assembler.addlRegReg(address.base, scr);
1246 m_assembler.movlMemReg(scr, SH4Registers::sp);
1247 m_assembler.addlImm8r(-4, SH4Registers::sp);
1248 releaseScratch(scr);
1249 return;
1250 }
1251
1252 m_assembler.movlMemReg(address.offset >> 2, address.base, SH4Registers::sp);
1253 m_assembler.addlImm8r(-4, SH4Registers::sp);
1254 }
1255
1256 void push(TrustedImm32 imm)
1257 {
1258 RegisterID scr = claimScratch();
1259 m_assembler.loadConstant(imm.m_value, scr);
1260 push(scr);
1261 releaseScratch(scr);
1262 }
1263
1264 // Register move operations
1265
1266 void move(TrustedImm32 imm, RegisterID dest)
1267 {
1268 m_assembler.loadConstant(imm.m_value, dest);
1269 }
1270
1271 DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
1272 {
commit-queue@webkit.org44334562011-08-18 02:56:13 +00001273 m_assembler.ensureSpace(m_assembler.maxInstructionSize, sizeof(uint32_t));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001274 DataLabelPtr dataLabel(this);
commit-queue@webkit.org44334562011-08-18 02:56:13 +00001275 m_assembler.loadConstantUnReusable(reinterpret_cast<uint32_t>(initialValue.m_value), dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001276 return dataLabel;
1277 }
1278
1279 void move(RegisterID src, RegisterID dest)
1280 {
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +00001281 if (src != dest)
1282 m_assembler.movlRegReg(src, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001283 }
1284
1285 void move(TrustedImmPtr imm, RegisterID dest)
1286 {
1287 m_assembler.loadConstant(imm.asIntptr(), dest);
1288 }
1289
1290 void extuw(RegisterID src, RegisterID dst)
1291 {
1292 m_assembler.extuw(src, dst);
1293 }
1294
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001295 void compare32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001296 {
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001297 m_assembler.cmplRegReg(right, left, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001298 if (cond != NotEqual) {
1299 m_assembler.movt(dest);
1300 return;
1301 }
1302
1303 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 4);
1304 m_assembler.movImm8(0, dest);
1305 m_assembler.branch(BT_OPCODE, 0);
1306 m_assembler.movImm8(1, dest);
1307 }
1308
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001309 void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001310 {
1311 if (left != dest) {
1312 move(right, dest);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001313 compare32(cond, left, dest, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001314 return;
1315 }
1316
1317 RegisterID scr = claimScratch();
1318 move(right, scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001319 compare32(cond, left, scr, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001320 releaseScratch(scr);
1321 }
1322
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001323 void test8(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001324 {
1325 ASSERT((cond == Zero) || (cond == NonZero));
1326
1327 load8(address, dest);
1328 if (mask.m_value == -1)
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001329 compare32(0, dest, static_cast<RelationalCondition>(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001330 else
1331 testlImm(mask.m_value, dest);
1332 if (cond != NonZero) {
1333 m_assembler.movt(dest);
1334 return;
1335 }
1336
1337 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 4);
1338 m_assembler.movImm8(0, dest);
1339 m_assembler.branch(BT_OPCODE, 0);
1340 m_assembler.movImm8(1, dest);
1341 }
1342
1343 void loadPtrLinkReg(ImplicitAddress address)
1344 {
1345 RegisterID scr = claimScratch();
1346 load32(address, scr);
1347 m_assembler.ldspr(scr);
1348 releaseScratch(scr);
1349 }
1350
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001351 Jump branch32(RelationalCondition cond, RegisterID left, RegisterID right)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001352 {
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001353 m_assembler.cmplRegReg(right, left, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001354 /* BT label => BF off
1355 nop LDR reg
1356 nop braf @reg
1357 nop nop
1358 */
1359 if (cond == NotEqual)
1360 return branchFalse();
1361 return branchTrue();
1362 }
1363
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001364 Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001365 {
1366 if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
1367 m_assembler.testlRegReg(left, left);
1368 else
1369 compare32(right.m_value, left, cond);
1370
1371 if (cond == NotEqual)
1372 return branchFalse();
1373 return branchTrue();
1374 }
1375
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001376 Jump branch32(RelationalCondition cond, RegisterID left, Address right)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001377 {
1378 compare32(right.offset, right.base, left, cond);
1379 if (cond == NotEqual)
1380 return branchFalse();
1381 return branchTrue();
1382 }
1383
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001384 Jump branch32(RelationalCondition cond, Address left, RegisterID right)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001385 {
1386 compare32(right, left.offset, left.base, cond);
1387 if (cond == NotEqual)
1388 return branchFalse();
1389 return branchTrue();
1390 }
1391
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001392 Jump branch32(RelationalCondition cond, Address left, TrustedImm32 right)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001393 {
1394 compare32(right.m_value, left.offset, left.base, cond);
1395 if (cond == NotEqual)
1396 return branchFalse();
1397 return branchTrue();
1398 }
1399
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001400 Jump branch32(RelationalCondition cond, AbsoluteAddress left, RegisterID right)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001401 {
1402 RegisterID scr = claimScratch();
1403
1404 move(TrustedImm32(reinterpret_cast<uint32_t>(left.m_ptr)), scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001405 m_assembler.cmplRegReg(right, scr, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001406 releaseScratch(scr);
1407
1408 if (cond == NotEqual)
1409 return branchFalse();
1410 return branchTrue();
1411 }
1412
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001413 Jump branch32(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001414 {
1415 RegisterID addressTempRegister = claimScratch();
1416
1417 m_assembler.loadConstant(reinterpret_cast<uint32_t>(left.m_ptr), addressTempRegister);
1418 m_assembler.movlMemReg(addressTempRegister, addressTempRegister);
1419 compare32(right.m_value, addressTempRegister, cond);
1420 releaseScratch(addressTempRegister);
1421
1422 if (cond == NotEqual)
1423 return branchFalse();
1424 return branchTrue();
1425 }
1426
msaboff@apple.com2cc41502011-09-12 22:17:53 +00001427 Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
1428 {
1429 ASSERT(!(right.m_value & 0xFFFFFF00));
1430 RegisterID scr = claimScratch();
1431
1432 move(left.index, scr);
1433 lshift32(TrustedImm32(left.scale), scr);
1434
1435 if (left.offset)
1436 add32(TrustedImm32(left.offset), scr);
1437 add32(left.base, scr);
1438 load8(scr, scr);
msaboff@apple.com2cc41502011-09-12 22:17:53 +00001439 RegisterID scr1 = claimScratch();
1440 m_assembler.loadConstant(right.m_value, scr1);
1441 releaseScratch(scr);
1442 releaseScratch(scr1);
1443
1444 return branch32(cond, scr, scr1);
1445 }
1446
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001447 Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001448 {
1449 ASSERT((cond == Zero) || (cond == NonZero));
1450
1451 m_assembler.testlRegReg(reg, mask);
1452
1453 if (cond == NotEqual)
1454 return branchFalse();
1455 return branchTrue();
1456 }
1457
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001458 Jump branchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001459 {
1460 ASSERT((cond == Zero) || (cond == NonZero));
1461
1462 if (mask.m_value == -1)
1463 m_assembler.testlRegReg(reg, reg);
1464 else
1465 testlImm(mask.m_value, reg);
1466
1467 if (cond == NotEqual)
1468 return branchFalse();
1469 return branchTrue();
1470 }
1471
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001472 Jump branchTest32(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001473 {
1474 ASSERT((cond == Zero) || (cond == NonZero));
1475
1476 if (mask.m_value == -1)
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001477 compare32(0, address.offset, address.base, static_cast<RelationalCondition>(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001478 else
1479 testImm(mask.m_value, address.offset, address.base);
1480
1481 if (cond == NotEqual)
1482 return branchFalse();
1483 return branchTrue();
1484 }
1485
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001486 Jump branchTest32(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001487 {
1488 RegisterID scr = claimScratch();
1489
1490 move(address.index, scr);
1491 lshift32(TrustedImm32(address.scale), scr);
1492 add32(address.base, scr);
1493 load32(scr, address.offset, scr);
1494
1495 if (mask.m_value == -1)
1496 m_assembler.testlRegReg(scr, scr);
1497 else
1498 testlImm(mask.m_value, scr);
1499
1500 releaseScratch(scr);
1501
1502 if (cond == NotEqual)
1503 return branchFalse();
1504 return branchTrue();
1505 }
1506
1507 Jump jump()
1508 {
1509 return Jump(m_assembler.jmp());
1510 }
1511
1512 void jump(RegisterID target)
1513 {
1514 m_assembler.jmpReg(target);
1515 }
1516
1517 void jump(Address address)
1518 {
1519 RegisterID scr = claimScratch();
1520
1521 if ((address.offset < 0) || (address.offset >= 64)) {
1522 m_assembler.loadConstant(address.offset, scr);
1523 m_assembler.addlRegReg(address.base, scr);
1524 m_assembler.movlMemReg(scr, scr);
1525 } else if (address.offset)
1526 m_assembler.movlMemReg(address.offset >> 2, address.base, scr);
1527 else
1528 m_assembler.movlMemReg(address.base, scr);
1529 m_assembler.jmpReg(scr);
1530
1531 releaseScratch(scr);
1532 }
1533
1534 // Arithmetic control flow operations
1535
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001536 Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001537 {
1538 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
1539
1540 if (cond == Overflow) {
1541 m_assembler.addvlRegReg(src, dest);
1542 return branchTrue();
1543 }
1544
1545 if (cond == Signed) {
1546 m_assembler.addlRegReg(src, dest);
1547 // Check if dest is negative
1548 m_assembler.cmppz(dest);
1549 return branchFalse();
1550 }
1551
1552 m_assembler.addlRegReg(src, dest);
1553 compare32(0, dest, Equal);
1554
1555 if (cond == NotEqual)
1556 return branchFalse();
1557 return branchTrue();
1558 }
1559
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001560 Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001561 {
1562 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
1563
1564 move(imm, scratchReg3);
1565 return branchAdd32(cond, scratchReg3, dest);
1566 }
1567
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001568 Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001569 {
1570 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
1571
1572 if (cond == Overflow) {
1573 RegisterID scr1 = claimScratch();
1574 RegisterID scr = claimScratch();
1575 m_assembler.dmullRegReg(src, dest);
1576 m_assembler.stsmacl(dest);
1577 m_assembler.movImm8(-31, scr);
1578 m_assembler.movlRegReg(dest, scr1);
1579 m_assembler.shaRegReg(scr1, scr);
1580 m_assembler.stsmach(scr);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001581 m_assembler.cmplRegReg(scr, scr1, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001582 releaseScratch(scr1);
1583 releaseScratch(scr);
1584 return branchFalse();
1585 }
1586
1587 m_assembler.imullRegReg(src, dest);
1588 m_assembler.stsmacl(dest);
1589 if (cond == Signed) {
1590 // Check if dest is negative
1591 m_assembler.cmppz(dest);
1592 return branchFalse();
1593 }
1594
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001595 compare32(0, dest, static_cast<RelationalCondition>(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001596
1597 if (cond == NotEqual)
1598 return branchFalse();
1599 return branchTrue();
1600 }
1601
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001602 Jump branchMul32(ResultCondition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001603 {
1604 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
1605
1606 move(imm, scratchReg3);
1607 if (src != dest)
1608 move(src, dest);
1609
1610 return branchMul32(cond, scratchReg3, dest);
1611 }
1612
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001613 Jump branchSub32(ResultCondition cond, RegisterID src, RegisterID dest)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001614 {
1615 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
1616
1617 if (cond == Overflow) {
1618 m_assembler.subvlRegReg(src, dest);
1619 return branchTrue();
1620 }
1621
1622 if (cond == Signed) {
1623 // Check if dest is negative
1624 m_assembler.sublRegReg(src, dest);
1625 compare32(0, dest, LessThan);
1626 return branchTrue();
1627 }
1628
1629 sub32(src, dest);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001630 compare32(0, dest, static_cast<RelationalCondition>(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001631
1632 if (cond == NotEqual)
1633 return branchFalse();
1634 return branchTrue();
1635 }
1636
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001637 Jump branchSub32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001638 {
1639 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
1640
1641 move(imm, scratchReg3);
1642 return branchSub32(cond, scratchReg3, dest);
1643 }
1644
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001645 Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest)
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001646 {
1647 ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
1648
1649 if (cond == Signed) {
1650 or32(src, dest);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001651 compare32(0, dest, static_cast<RelationalCondition>(LessThan));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001652 return branchTrue();
1653 }
1654
1655 or32(src, dest);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001656 compare32(0, dest, static_cast<RelationalCondition>(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001657
1658 if (cond == NotEqual)
1659 return branchFalse();
1660 return branchTrue();
1661 }
1662
1663 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
1664 {
1665 m_assembler.ftrcdrmfpul(src);
1666 m_assembler.stsfpulReg(dest);
1667 convertInt32ToDouble(dest, fscratch);
1668 failureCases.append(branchDouble(DoubleNotEqualOrUnordered, fscratch, src));
1669
1670 if (dest == SH4Registers::r0)
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001671 m_assembler.cmpEqImmR0(0, dest);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001672 else {
1673 m_assembler.movImm8(0, scratchReg3);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001674 m_assembler.cmplRegReg(scratchReg3, dest, SH4Condition(Equal));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001675 }
1676 failureCases.append(branchTrue());
1677 }
1678
1679 void neg32(RegisterID dst)
1680 {
1681 m_assembler.neg(dst, dst);
1682 }
1683
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001684 void urshift32(RegisterID shiftamount, RegisterID dest)
1685 {
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +00001686 if (shiftamount == SH4Registers::r0)
1687 m_assembler.andlImm8r(0x1f, shiftamount);
1688 else {
1689 RegisterID scr = claimScratch();
1690 m_assembler.loadConstant(0x1f, scr);
1691 m_assembler.andlRegReg(scr, shiftamount);
1692 releaseScratch(scr);
1693 }
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001694 m_assembler.neg(shiftamount, shiftamount);
1695 m_assembler.shllRegReg(dest, shiftamount);
1696 }
1697
1698 void urshift32(TrustedImm32 imm, RegisterID dest)
1699 {
1700 RegisterID scr = claimScratch();
commit-queue@webkit.orga7d13c82011-12-08 23:16:54 +00001701 m_assembler.loadConstant(-(imm.m_value & 0x1f), scr);
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001702 m_assembler.shaRegReg(dest, scr);
1703 releaseScratch(scr);
1704 }
1705
1706 Call call()
1707 {
1708 return Call(m_assembler.call(), Call::Linkable);
1709 }
1710
1711 Call nearCall()
1712 {
1713 return Call(m_assembler.call(), Call::LinkableNear);
1714 }
1715
1716 Call call(RegisterID target)
1717 {
1718 return Call(m_assembler.call(target), Call::None);
1719 }
1720
commit-queue@webkit.orgd5765e42011-04-11 17:11:38 +00001721 void call(Address address, RegisterID target)
1722 {
1723 load32(address.base, address.offset, target);
1724 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 2);
1725 m_assembler.branch(JSR_OPCODE, target);
1726 m_assembler.nop();
1727 }
1728
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001729 void breakpoint()
1730 {
1731 m_assembler.bkpt();
1732 m_assembler.nop();
1733 }
1734
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001735 Jump branchPtrWithPatch(RelationalCondition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001736 {
1737 RegisterID dataTempRegister = claimScratch();
1738
1739 dataLabel = moveWithPatch(initialRightValue, dataTempRegister);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001740 m_assembler.cmplRegReg(dataTempRegister, left, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001741 releaseScratch(dataTempRegister);
1742
1743 if (cond == NotEqual)
1744 return branchFalse();
1745 return branchTrue();
1746 }
1747
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001748 Jump branchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001749 {
1750 RegisterID scr = claimScratch();
1751
1752 m_assembler.loadConstant(left.offset, scr);
1753 m_assembler.addlRegReg(left.base, scr);
1754 m_assembler.movlMemReg(scr, scr);
1755 RegisterID scr1 = claimScratch();
1756 dataLabel = moveWithPatch(initialRightValue, scr1);
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001757 m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond));
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001758 releaseScratch(scr);
1759 releaseScratch(scr1);
1760
1761 if (cond == NotEqual)
1762 return branchFalse();
1763 return branchTrue();
1764 }
1765
1766 void ret()
1767 {
1768 m_assembler.ret();
1769 m_assembler.nop();
1770 }
1771
1772 DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
1773 {
1774 RegisterID scr = claimScratch();
1775 DataLabelPtr label = moveWithPatch(initialValue, scr);
1776 store32(scr, address);
1777 releaseScratch(scr);
1778 return label;
1779 }
1780
1781 DataLabelPtr storePtrWithPatch(ImplicitAddress address) { return storePtrWithPatch(TrustedImmPtr(0), address); }
1782
1783 int sizeOfConstantPool()
1784 {
1785 return m_assembler.sizeOfConstantPool();
1786 }
1787
1788 Call tailRecursiveCall()
1789 {
1790 RegisterID scr = claimScratch();
1791
1792 m_assembler.loadConstantUnReusable(0x0, scr, true);
1793 Jump m_jump = Jump(m_assembler.jmp(scr));
1794 releaseScratch(scr);
1795
1796 return Call::fromTailJump(m_jump);
1797 }
1798
1799 Call makeTailRecursiveCall(Jump oldJump)
1800 {
1801 oldJump.link(this);
1802 return tailRecursiveCall();
1803 }
oliver@apple.com31df1c82011-05-20 01:33:46 +00001804
1805 void nop()
1806 {
1807 m_assembler.nop();
1808 }
1809
ossy@webkit.orgf69ce1d2011-12-05 09:41:04 +00001810 static FunctionPtr readCallTarget(CodeLocationCall call)
1811 {
1812 return FunctionPtr(reinterpret_cast<void(*)()>(SH4Assembler::readCallTarget(call.dataLocation())));
1813 }
1814
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001815protected:
1816 SH4Assembler::Condition SH4Condition(RelationalCondition cond)
1817 {
1818 return static_cast<SH4Assembler::Condition>(cond);
1819 }
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001820
commit-queue@webkit.orgbdfbe5c2011-04-25 20:19:11 +00001821 SH4Assembler::Condition SH4Condition(ResultCondition cond)
1822 {
1823 return static_cast<SH4Assembler::Condition>(cond);
1824 }
commit-queue@webkit.orgf61bc822011-03-31 21:25:42 +00001825private:
1826 friend class LinkBuffer;
1827 friend class RepatchBuffer;
1828
1829 static void linkCall(void*, Call, FunctionPtr);
1830 static void repatchCall(CodeLocationCall, CodeLocationLabel);
1831 static void repatchCall(CodeLocationCall, FunctionPtr);
1832};
1833
1834} // namespace JSC
1835
1836#endif // ENABLE(ASSEMBLER)
1837
1838#endif // MacroAssemblerSH4_h