]> git.saurik.com Git - apple/javascriptcore.git/blame - assembler/MacroAssemblerSH4.h
JavaScriptCore-7600.1.4.11.8.tar.gz
[apple/javascriptcore.git] / assembler / MacroAssemblerSH4.h
CommitLineData
14957cd0 1/*
93a37866 2 * Copyright (C) 2013 Cisco Systems, Inc. All rights reserved.
14957cd0
A
3 * Copyright (C) 2009-2011 STMicroelectronics. All rights reserved.
4 * Copyright (C) 2008 Apple Inc. 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 MacroAssemblerSH4_h
29#define MacroAssemblerSH4_h
30
31#if ENABLE(ASSEMBLER) && CPU(SH4)
32
14957cd0 33#include "SH4Assembler.h"
6fe7ccc8 34#include "AbstractMacroAssembler.h"
14957cd0
A
35#include <wtf/Assertions.h>
36
37namespace JSC {
38
39class MacroAssemblerSH4 : public AbstractMacroAssembler<SH4Assembler> {
40public:
41 typedef SH4Assembler::FPRegisterID FPRegisterID;
42
43 static const Scale ScalePtr = TimesFour;
81345200 44 static const FPRegisterID fscratch = SH4Registers::dr10;
14957cd0 45 static const RegisterID stackPointerRegister = SH4Registers::sp;
81345200 46 static const RegisterID framePointerRegister = SH4Registers::fp;
14957cd0
A
47 static const RegisterID linkRegister = SH4Registers::pr;
48 static const RegisterID scratchReg3 = SH4Registers::r13;
49
6fe7ccc8 50 static const int MaximumCompactPtrAlignedAddressOffset = 60;
14957cd0 51
93a37866
A
52 static bool isCompactPtrAlignedAddressOffset(ptrdiff_t value)
53 {
81345200 54 return (value >= 0) && (value <= MaximumCompactPtrAlignedAddressOffset) && (!(value & 3));
93a37866
A
55 }
56
14957cd0
A
57 enum RelationalCondition {
58 Equal = SH4Assembler::EQ,
59 NotEqual = SH4Assembler::NE,
60 Above = SH4Assembler::HI,
61 AboveOrEqual = SH4Assembler::HS,
62 Below = SH4Assembler::LI,
63 BelowOrEqual = SH4Assembler::LS,
64 GreaterThan = SH4Assembler::GT,
65 GreaterThanOrEqual = SH4Assembler::GE,
66 LessThan = SH4Assembler::LT,
67 LessThanOrEqual = SH4Assembler::LE
68 };
69
70 enum ResultCondition {
71 Overflow = SH4Assembler::OF,
72 Signed = SH4Assembler::SI,
93a37866 73 PositiveOrZero = SH4Assembler::NS,
14957cd0
A
74 Zero = SH4Assembler::EQ,
75 NonZero = SH4Assembler::NE
76 };
77
78 enum DoubleCondition {
79 // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
80 DoubleEqual = SH4Assembler::EQ,
81 DoubleNotEqual = SH4Assembler::NE,
82 DoubleGreaterThan = SH4Assembler::GT,
83 DoubleGreaterThanOrEqual = SH4Assembler::GE,
84 DoubleLessThan = SH4Assembler::LT,
85 DoubleLessThanOrEqual = SH4Assembler::LE,
86 // If either operand is NaN, these conditions always evaluate to true.
87 DoubleEqualOrUnordered = SH4Assembler::EQU,
88 DoubleNotEqualOrUnordered = SH4Assembler::NEU,
89 DoubleGreaterThanOrUnordered = SH4Assembler::GTU,
90 DoubleGreaterThanOrEqualOrUnordered = SH4Assembler::GEU,
91 DoubleLessThanOrUnordered = SH4Assembler::LTU,
92 DoubleLessThanOrEqualOrUnordered = SH4Assembler::LEU,
93 };
94
95 RegisterID claimScratch()
96 {
97 return m_assembler.claimScratch();
98 }
99
100 void releaseScratch(RegisterID reg)
101 {
102 m_assembler.releaseScratch(reg);
103 }
104
81345200
A
105 static RelationalCondition invert(RelationalCondition cond)
106 {
107 switch (cond) {
108 case Equal:
109 return NotEqual;
110 case NotEqual:
111 return Equal;
112 case Above:
113 return BelowOrEqual;
114 case AboveOrEqual:
115 return Below;
116 case Below:
117 return AboveOrEqual;
118 case BelowOrEqual:
119 return Above;
120 case GreaterThan:
121 return LessThanOrEqual;
122 case GreaterThanOrEqual:
123 return LessThan;
124 case LessThan:
125 return GreaterThanOrEqual;
126 case LessThanOrEqual:
127 return GreaterThan;
128 default:
129 RELEASE_ASSERT_NOT_REACHED();
130 }
131 }
132
14957cd0
A
133 // Integer arithmetic operations
134
135 void add32(RegisterID src, RegisterID dest)
136 {
137 m_assembler.addlRegReg(src, dest);
138 }
139
81345200
A
140 void add32(RegisterID src1, RegisterID src2, RegisterID dest)
141 {
142 if (src1 == dest)
143 add32(src2, dest);
144 else {
145 move(src2, dest);
146 add32(src1, dest);
147 }
148 }
149
14957cd0
A
150 void add32(TrustedImm32 imm, RegisterID dest)
151 {
93a37866
A
152 if (!imm.m_value)
153 return;
154
14957cd0
A
155 if (m_assembler.isImmediate(imm.m_value)) {
156 m_assembler.addlImm8r(imm.m_value, dest);
157 return;
158 }
159
160 RegisterID scr = claimScratch();
161 m_assembler.loadConstant(imm.m_value, scr);
162 m_assembler.addlRegReg(scr, dest);
163 releaseScratch(scr);
164 }
165
166 void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
167 {
81345200 168 move(src, dest);
14957cd0
A
169 add32(imm, dest);
170 }
171
172 void add32(TrustedImm32 imm, Address address)
173 {
93a37866
A
174 if (!imm.m_value)
175 return;
176
14957cd0
A
177 RegisterID scr = claimScratch();
178 load32(address, scr);
179 add32(imm, scr);
180 store32(scr, address);
181 releaseScratch(scr);
182 }
183
184 void add32(Address src, RegisterID dest)
185 {
186 RegisterID scr = claimScratch();
187 load32(src, scr);
188 m_assembler.addlRegReg(scr, dest);
189 releaseScratch(scr);
190 }
191
93a37866
A
192 void add32(AbsoluteAddress src, RegisterID dest)
193 {
194 RegisterID scr = claimScratch();
195 load32(src.m_ptr, scr);
196 m_assembler.addlRegReg(scr, dest);
197 releaseScratch(scr);
198 }
199
14957cd0
A
200 void and32(RegisterID src, RegisterID dest)
201 {
202 m_assembler.andlRegReg(src, dest);
203 }
204
81345200
A
205 void and32(RegisterID src1, RegisterID src2, RegisterID dest)
206 {
207 if (src1 == dest)
208 and32(src2, dest);
209 else {
210 move(src2, dest);
211 and32(src1, dest);
212 }
213 }
214
215 void and32(Address src, RegisterID dest)
216 {
217 RegisterID scr = claimScratch();
218 load32(src, scr);
219 and32(scr, dest);
220 releaseScratch(scr);
221 }
222
14957cd0
A
223 void and32(TrustedImm32 imm, RegisterID dest)
224 {
81345200
A
225 if (!imm.m_value) {
226 m_assembler.movImm8(0, dest);
227 return;
228 }
229
14957cd0
A
230 if ((imm.m_value <= 255) && (imm.m_value >= 0) && (dest == SH4Registers::r0)) {
231 m_assembler.andlImm8r(imm.m_value, dest);
232 return;
233 }
234
235 RegisterID scr = claimScratch();
93a37866 236 m_assembler.loadConstant(imm.m_value, scr);
14957cd0
A
237 m_assembler.andlRegReg(scr, dest);
238 releaseScratch(scr);
239 }
240
6fe7ccc8
A
241 void and32(TrustedImm32 imm, RegisterID src, RegisterID dest)
242 {
243 if (src != dest) {
244 move(imm, dest);
245 and32(src, dest);
246 return;
247 }
248
249 and32(imm, dest);
250 }
251
14957cd0
A
252 void lshift32(RegisterID shiftamount, RegisterID dest)
253 {
93a37866
A
254 RegisterID shiftTmp = claimScratch();
255 m_assembler.loadConstant(0x1f, shiftTmp);
256 m_assembler.andlRegReg(shiftamount, shiftTmp);
257 m_assembler.shldRegReg(dest, shiftTmp);
258 releaseScratch(shiftTmp);
14957cd0
A
259 }
260
81345200
A
261 void lshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
262 {
263 move(src, dest);
264 lshift32(shiftAmount, dest);
265 }
266
14957cd0
A
267 void lshift32(TrustedImm32 imm, RegisterID dest)
268 {
93a37866
A
269 int immMasked = imm.m_value & 0x1f;
270 if (!immMasked)
6fe7ccc8
A
271 return;
272
93a37866
A
273 if ((immMasked == 1) || (immMasked == 2) || (immMasked == 8) || (immMasked == 16)) {
274 m_assembler.shllImm8r(immMasked, dest);
14957cd0
A
275 return;
276 }
277
93a37866
A
278 RegisterID shiftTmp = claimScratch();
279 m_assembler.loadConstant(immMasked, shiftTmp);
280 m_assembler.shldRegReg(dest, shiftTmp);
281 releaseScratch(shiftTmp);
14957cd0
A
282 }
283
6fe7ccc8
A
284 void lshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest)
285 {
81345200 286 move(src, dest);
6fe7ccc8
A
287 lshift32(shiftamount, dest);
288 }
289
14957cd0
A
290 void mul32(RegisterID src, RegisterID dest)
291 {
81345200
A
292 mul32(src, dest, dest);
293 }
294
295 void mul32(RegisterID src1, RegisterID src2, RegisterID dest)
296 {
297 m_assembler.imullRegReg(src1, src2);
14957cd0
A
298 m_assembler.stsmacl(dest);
299 }
300
301 void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
302 {
81345200
A
303 if (src == dest) {
304 RegisterID immval = claimScratch();
305 move(imm, immval);
306 mul32(immval, dest);
307 releaseScratch(immval);
308 } else {
309 move(imm, dest);
310 mul32(src, dest);
311 }
14957cd0
A
312 }
313
14957cd0
A
314 void or32(RegisterID src, RegisterID dest)
315 {
316 m_assembler.orlRegReg(src, dest);
317 }
318
319 void or32(TrustedImm32 imm, RegisterID dest)
320 {
321 if ((imm.m_value <= 255) && (imm.m_value >= 0) && (dest == SH4Registers::r0)) {
322 m_assembler.orlImm8r(imm.m_value, dest);
323 return;
324 }
325
326 RegisterID scr = claimScratch();
327 m_assembler.loadConstant(imm.m_value, scr);
328 m_assembler.orlRegReg(scr, dest);
329 releaseScratch(scr);
330 }
331
6fe7ccc8
A
332 void or32(RegisterID op1, RegisterID op2, RegisterID dest)
333 {
334 if (op1 == op2)
335 move(op1, dest);
336 else if (op1 == dest)
337 or32(op2, dest);
338 else {
339 move(op2, dest);
340 or32(op1, dest);
341 }
342 }
343
93a37866 344 void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
6fe7ccc8 345 {
93a37866 346 if (src != dest) {
6fe7ccc8
A
347 move(imm, dest);
348 or32(src, dest);
349 return;
350 }
351
352 or32(imm, dest);
353 }
354
81345200
A
355 void or32(RegisterID src, AbsoluteAddress address)
356 {
357 RegisterID destptr = claimScratch();
358 move(TrustedImmPtr(address.m_ptr), destptr);
359 RegisterID destval = claimScratch();
360 m_assembler.movlMemReg(destptr, destval);
361 m_assembler.orlRegReg(src, destval);
362 m_assembler.movlRegMem(destval, destptr);
363 releaseScratch(destval);
364 releaseScratch(destptr);
365 }
366
6fe7ccc8
A
367 void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest)
368 {
93a37866 369 if (src != dest) {
6fe7ccc8
A
370 move(imm, dest);
371 xor32(src, dest);
372 return;
373 }
374
375 xor32(imm, dest);
376 }
377
14957cd0
A
378 void rshift32(RegisterID shiftamount, RegisterID dest)
379 {
93a37866
A
380 RegisterID shiftTmp = claimScratch();
381 m_assembler.loadConstant(0x1f, shiftTmp);
382 m_assembler.andlRegReg(shiftamount, shiftTmp);
383 m_assembler.neg(shiftTmp, shiftTmp);
384 m_assembler.shadRegReg(dest, shiftTmp);
385 releaseScratch(shiftTmp);
14957cd0
A
386 }
387
81345200
A
388 void rshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
389 {
390 move(src, dest);
391 rshift32(shiftAmount, dest);
392 }
393
14957cd0
A
394 void rshift32(TrustedImm32 imm, RegisterID dest)
395 {
93a37866
A
396 int immMasked = imm.m_value & 0x1f;
397 if (!immMasked)
398 return;
399
400 if (immMasked == 1) {
401 m_assembler.sharImm8r(immMasked, dest);
402 return;
403 }
404
405 RegisterID shiftTmp = claimScratch();
406 m_assembler.loadConstant(-immMasked, shiftTmp);
407 m_assembler.shadRegReg(dest, shiftTmp);
408 releaseScratch(shiftTmp);
14957cd0
A
409 }
410
6fe7ccc8
A
411 void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
412 {
81345200 413 move(src, dest);
6fe7ccc8
A
414 rshift32(imm, dest);
415 }
416
14957cd0
A
417 void sub32(RegisterID src, RegisterID dest)
418 {
419 m_assembler.sublRegReg(src, dest);
420 }
421
14957cd0
A
422 void sub32(TrustedImm32 imm, AbsoluteAddress address)
423 {
93a37866
A
424 if (!imm.m_value)
425 return;
426
14957cd0
A
427 RegisterID result = claimScratch();
428 RegisterID scratchReg = claimScratch();
429
81345200 430 move(TrustedImmPtr(address.m_ptr), scratchReg);
14957cd0
A
431 m_assembler.movlMemReg(scratchReg, result);
432
433 if (m_assembler.isImmediate(-imm.m_value))
434 m_assembler.addlImm8r(-imm.m_value, result);
435 else {
436 m_assembler.loadConstant(imm.m_value, scratchReg3);
437 m_assembler.sublRegReg(scratchReg3, result);
438 }
439
440 store32(result, scratchReg);
441 releaseScratch(result);
442 releaseScratch(scratchReg);
443 }
444
81345200
A
445 void sub32(TrustedImm32 imm, Address address)
446 {
447 add32(TrustedImm32(-imm.m_value), address);
448 }
449
14957cd0
A
450 void add32(TrustedImm32 imm, AbsoluteAddress address)
451 {
93a37866
A
452 if (!imm.m_value)
453 return;
454
14957cd0
A
455 RegisterID result = claimScratch();
456 RegisterID scratchReg = claimScratch();
457
81345200 458 move(TrustedImmPtr(address.m_ptr), scratchReg);
14957cd0
A
459 m_assembler.movlMemReg(scratchReg, result);
460
461 if (m_assembler.isImmediate(imm.m_value))
462 m_assembler.addlImm8r(imm.m_value, result);
463 else {
464 m_assembler.loadConstant(imm.m_value, scratchReg3);
465 m_assembler.addlRegReg(scratchReg3, result);
466 }
467
468 store32(result, scratchReg);
469 releaseScratch(result);
470 releaseScratch(scratchReg);
471 }
472
93a37866
A
473 void add64(TrustedImm32 imm, AbsoluteAddress address)
474 {
475 RegisterID scr1 = claimScratch();
476 RegisterID scr2 = claimScratch();
477
478 // Add 32-bit LSB first.
81345200
A
479 move(TrustedImmPtr(address.m_ptr), scratchReg3);
480 m_assembler.movlMemReg(scratchReg3, scr1); // scr1 = 32-bit LSB of int64 @ address
93a37866
A
481 m_assembler.loadConstant(imm.m_value, scr2);
482 m_assembler.clrt();
483 m_assembler.addclRegReg(scr1, scr2);
81345200 484 m_assembler.movlRegMem(scr2, scratchReg3); // Update address with 32-bit LSB result.
93a37866
A
485
486 // Then add 32-bit MSB.
81345200
A
487 m_assembler.addlImm8r(4, scratchReg3);
488 m_assembler.movlMemReg(scratchReg3, scr1); // scr1 = 32-bit MSB of int64 @ address
93a37866
A
489 m_assembler.movt(scr2);
490 if (imm.m_value < 0)
491 m_assembler.addlImm8r(-1, scr2); // Sign extend imm value if needed.
492 m_assembler.addvlRegReg(scr2, scr1);
81345200 493 m_assembler.movlRegMem(scr1, scratchReg3); // Update (address + 4) with 32-bit MSB result.
93a37866
A
494
495 releaseScratch(scr2);
496 releaseScratch(scr1);
497 }
498
14957cd0
A
499 void sub32(TrustedImm32 imm, RegisterID dest)
500 {
93a37866
A
501 if (!imm.m_value)
502 return;
503
14957cd0
A
504 if (m_assembler.isImmediate(-imm.m_value)) {
505 m_assembler.addlImm8r(-imm.m_value, dest);
506 return;
507 }
508
509 RegisterID scr = claimScratch();
510 m_assembler.loadConstant(imm.m_value, scr);
511 m_assembler.sublRegReg(scr, dest);
512 releaseScratch(scr);
513 }
514
515 void sub32(Address src, RegisterID dest)
516 {
517 RegisterID scr = claimScratch();
518 load32(src, scr);
519 m_assembler.sublRegReg(scr, dest);
520 releaseScratch(scr);
521 }
522
523 void xor32(RegisterID src, RegisterID dest)
524 {
525 m_assembler.xorlRegReg(src, dest);
526 }
527
81345200
A
528 void xor32(RegisterID src1, RegisterID src2, RegisterID dest)
529 {
530 if (src1 == dest)
531 xor32(src2, dest);
532 else {
533 move(src2, dest);
534 xor32(src1, dest);
535 }
536 }
537
14957cd0
A
538 void xor32(TrustedImm32 imm, RegisterID srcDest)
539 {
6fe7ccc8
A
540 if (imm.m_value == -1) {
541 m_assembler.notlReg(srcDest, srcDest);
542 return;
543 }
544
14957cd0
A
545 if ((srcDest != SH4Registers::r0) || (imm.m_value > 255) || (imm.m_value < 0)) {
546 RegisterID scr = claimScratch();
93a37866 547 m_assembler.loadConstant(imm.m_value, scr);
14957cd0
A
548 m_assembler.xorlRegReg(scr, srcDest);
549 releaseScratch(scr);
550 return;
551 }
552
553 m_assembler.xorlImm8r(imm.m_value, srcDest);
554 }
555
556 void compare32(int imm, RegisterID dst, RelationalCondition cond)
557 {
558 if (((cond == Equal) || (cond == NotEqual)) && (dst == SH4Registers::r0) && m_assembler.isImmediate(imm)) {
559 m_assembler.cmpEqImmR0(imm, dst);
560 return;
561 }
562
81345200
A
563 if (((cond == Equal) || (cond == NotEqual)) && !imm) {
564 m_assembler.testlRegReg(dst, dst);
565 return;
566 }
567
14957cd0
A
568 RegisterID scr = claimScratch();
569 m_assembler.loadConstant(imm, scr);
570 m_assembler.cmplRegReg(scr, dst, SH4Condition(cond));
571 releaseScratch(scr);
572 }
573
574 void compare32(int offset, RegisterID base, RegisterID left, RelationalCondition cond)
575 {
576 RegisterID scr = claimScratch();
577 if (!offset) {
578 m_assembler.movlMemReg(base, scr);
579 m_assembler.cmplRegReg(scr, left, SH4Condition(cond));
580 releaseScratch(scr);
581 return;
582 }
583
584 if ((offset < 0) || (offset >= 64)) {
585 m_assembler.loadConstant(offset, scr);
586 m_assembler.addlRegReg(base, scr);
587 m_assembler.movlMemReg(scr, scr);
588 m_assembler.cmplRegReg(scr, left, SH4Condition(cond));
589 releaseScratch(scr);
590 return;
591 }
592
593 m_assembler.movlMemReg(offset >> 2, base, scr);
594 m_assembler.cmplRegReg(scr, left, SH4Condition(cond));
595 releaseScratch(scr);
596 }
597
598 void testImm(int imm, int offset, RegisterID base)
599 {
600 RegisterID scr = claimScratch();
81345200 601 load32(base, offset, scr);
14957cd0 602
81345200
A
603 RegisterID scr1 = claimScratch();
604 move(TrustedImm32(imm), scr1);
14957cd0
A
605
606 m_assembler.testlRegReg(scr, scr1);
607 releaseScratch(scr);
608 releaseScratch(scr1);
609 }
610
611 void testlImm(int imm, RegisterID dst)
612 {
613 if ((dst == SH4Registers::r0) && (imm <= 255) && (imm >= 0)) {
614 m_assembler.testlImm8r(imm, dst);
615 return;
616 }
617
618 RegisterID scr = claimScratch();
619 m_assembler.loadConstant(imm, scr);
620 m_assembler.testlRegReg(scr, dst);
621 releaseScratch(scr);
622 }
623
624 void compare32(RegisterID right, int offset, RegisterID base, RelationalCondition cond)
625 {
626 if (!offset) {
627 RegisterID scr = claimScratch();
628 m_assembler.movlMemReg(base, scr);
629 m_assembler.cmplRegReg(right, scr, SH4Condition(cond));
630 releaseScratch(scr);
631 return;
632 }
633
634 if ((offset < 0) || (offset >= 64)) {
635 RegisterID scr = claimScratch();
636 m_assembler.loadConstant(offset, scr);
637 m_assembler.addlRegReg(base, scr);
638 m_assembler.movlMemReg(scr, scr);
639 m_assembler.cmplRegReg(right, scr, SH4Condition(cond));
640 releaseScratch(scr);
641 return;
642 }
643
644 RegisterID scr = claimScratch();
645 m_assembler.movlMemReg(offset >> 2, base, scr);
646 m_assembler.cmplRegReg(right, scr, SH4Condition(cond));
647 releaseScratch(scr);
648 }
649
650 void compare32(int imm, int offset, RegisterID base, RelationalCondition cond)
651 {
14957cd0 652 RegisterID scr = claimScratch();
81345200
A
653 load32(base, offset, scr);
654
14957cd0 655 RegisterID scr1 = claimScratch();
81345200
A
656 move(TrustedImm32(imm), scr1);
657
14957cd0 658 m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond));
81345200 659
14957cd0
A
660 releaseScratch(scr1);
661 releaseScratch(scr);
662 }
663
664 // Memory access operation
665
81345200
A
666 ALWAYS_INLINE void loadEffectiveAddress(BaseIndex address, RegisterID dest, int extraoffset = 0)
667 {
668 if (dest == address.base) {
669 RegisterID scaledIndex = claimScratch();
670 move(address.index, scaledIndex);
671 lshift32(TrustedImm32(address.scale), scaledIndex);
672 add32(scaledIndex, dest);
673 releaseScratch(scaledIndex);
674 } else {
675 move(address.index, dest);
676 lshift32(TrustedImm32(address.scale), dest);
677 add32(address.base, dest);
678 }
679
680 add32(TrustedImm32(address.offset + extraoffset), dest);
681 }
682
14957cd0
A
683 void load32(ImplicitAddress address, RegisterID dest)
684 {
685 load32(address.base, address.offset, dest);
686 }
687
688 void load8(ImplicitAddress address, RegisterID dest)
689 {
690 load8(address.base, address.offset, dest);
691 }
692
6fe7ccc8
A
693 void load8(BaseIndex address, RegisterID dest)
694 {
695 RegisterID scr = claimScratch();
696 move(address.index, scr);
697 lshift32(TrustedImm32(address.scale), scr);
698 add32(address.base, scr);
699 load8(scr, address.offset, dest);
700 releaseScratch(scr);
701 }
702
81345200
A
703 void load8(AbsoluteAddress address, RegisterID dest)
704 {
705 move(TrustedImmPtr(address.m_ptr), dest);
706 m_assembler.movbMemReg(dest, dest);
707 m_assembler.extub(dest, dest);
708 }
709
710 void load8(const void* address, RegisterID dest)
711 {
712 load8(AbsoluteAddress(address), dest);
713 }
714
93a37866
A
715 void load8PostInc(RegisterID base, RegisterID dest)
716 {
717 m_assembler.movbMemRegIn(base, dest);
718 m_assembler.extub(dest, dest);
719 }
720
721 void load8Signed(BaseIndex address, RegisterID dest)
722 {
723 RegisterID scr = claimScratch();
724 move(address.index, scr);
725 lshift32(TrustedImm32(address.scale), scr);
726 add32(address.base, scr);
727 load8Signed(scr, address.offset, dest);
728 releaseScratch(scr);
729 }
730
14957cd0
A
731 void load32(BaseIndex address, RegisterID dest)
732 {
733 RegisterID scr = claimScratch();
734 move(address.index, scr);
735 lshift32(TrustedImm32(address.scale), scr);
736 add32(address.base, scr);
737 load32(scr, address.offset, dest);
738 releaseScratch(scr);
739 }
740
6fe7ccc8 741 void load32(const void* address, RegisterID dest)
14957cd0 742 {
81345200 743 move(TrustedImmPtr(address), dest);
14957cd0
A
744 m_assembler.movlMemReg(dest, dest);
745 }
746
747 void load32(RegisterID base, int offset, RegisterID dest)
748 {
749 if (!offset) {
750 m_assembler.movlMemReg(base, dest);
751 return;
752 }
753
754 if ((offset >= 0) && (offset < 64)) {
755 m_assembler.movlMemReg(offset >> 2, base, dest);
756 return;
757 }
758
93a37866 759 RegisterID scr = (dest == base) ? claimScratch() : dest;
14957cd0 760
93a37866
A
761 m_assembler.loadConstant(offset, scr);
762 if (base == SH4Registers::r0)
763 m_assembler.movlR0mr(scr, dest);
764 else {
765 m_assembler.addlRegReg(base, scr);
766 m_assembler.movlMemReg(scr, dest);
767 }
14957cd0
A
768
769 if (dest == base)
770 releaseScratch(scr);
771 }
772
93a37866 773 void load8Signed(RegisterID base, int offset, RegisterID dest)
14957cd0
A
774 {
775 if (!offset) {
776 m_assembler.movbMemReg(base, dest);
777 return;
778 }
779
93a37866 780 if ((offset > 0) && (offset <= 15) && (dest == SH4Registers::r0)) {
14957cd0
A
781 m_assembler.movbMemReg(offset, base, dest);
782 return;
783 }
784
93a37866
A
785 RegisterID scr = (dest == base) ? claimScratch() : dest;
786
787 m_assembler.loadConstant(offset, scr);
788 if (base == SH4Registers::r0)
789 m_assembler.movbR0mr(scr, dest);
790 else {
791 m_assembler.addlRegReg(base, scr);
792 m_assembler.movbMemReg(scr, dest);
14957cd0
A
793 }
794
93a37866
A
795 if (dest == base)
796 releaseScratch(scr);
14957cd0
A
797 }
798
93a37866 799 void load8(RegisterID base, int offset, RegisterID dest)
14957cd0 800 {
93a37866
A
801 load8Signed(base, offset, dest);
802 m_assembler.extub(dest, dest);
14957cd0
A
803 }
804
805 void load32(RegisterID src, RegisterID dst)
806 {
807 m_assembler.movlMemReg(src, dst);
808 }
809
810 void load16(ImplicitAddress address, RegisterID dest)
811 {
812 if (!address.offset) {
813 m_assembler.movwMemReg(address.base, dest);
93a37866 814 m_assembler.extuw(dest, dest);
14957cd0
A
815 return;
816 }
817
93a37866
A
818 if ((address.offset > 0) && (address.offset <= 30) && (dest == SH4Registers::r0)) {
819 m_assembler.movwMemReg(address.offset >> 1, address.base, dest);
820 m_assembler.extuw(dest, dest);
14957cd0
A
821 return;
822 }
823
93a37866
A
824 RegisterID scr = (dest == address.base) ? claimScratch() : dest;
825
826 m_assembler.loadConstant(address.offset, scr);
827 if (address.base == SH4Registers::r0)
828 m_assembler.movwR0mr(scr, dest);
829 else {
830 m_assembler.addlRegReg(address.base, scr);
831 m_assembler.movwMemReg(scr, dest);
14957cd0 832 }
93a37866 833 m_assembler.extuw(dest, dest);
14957cd0 834
93a37866
A
835 if (dest == address.base)
836 releaseScratch(scr);
14957cd0
A
837 }
838
6fe7ccc8
A
839 void load16Unaligned(BaseIndex address, RegisterID dest)
840 {
6fe7ccc8 841 RegisterID scr = claimScratch();
6fe7ccc8 842
81345200 843 loadEffectiveAddress(address, scr);
6fe7ccc8 844
81345200 845 RegisterID scr1 = claimScratch();
93a37866 846 load8PostInc(scr, scr1);
6fe7ccc8
A
847 load8(scr, dest);
848 m_assembler.shllImm8r(8, dest);
849 or32(scr1, dest);
850
851 releaseScratch(scr);
852 releaseScratch(scr1);
853 }
854
14957cd0
A
855 void load16(RegisterID src, RegisterID dest)
856 {
857 m_assembler.movwMemReg(src, dest);
93a37866 858 m_assembler.extuw(dest, dest);
14957cd0
A
859 }
860
93a37866 861 void load16Signed(RegisterID src, RegisterID dest)
14957cd0 862 {
93a37866 863 m_assembler.movwMemReg(src, dest);
14957cd0
A
864 }
865
866 void load16(BaseIndex address, RegisterID dest)
93a37866
A
867 {
868 load16Signed(address, dest);
869 m_assembler.extuw(dest, dest);
870 }
871
872 void load16PostInc(RegisterID base, RegisterID dest)
873 {
874 m_assembler.movwMemRegIn(base, dest);
875 m_assembler.extuw(dest, dest);
876 }
877
878 void load16Signed(BaseIndex address, RegisterID dest)
14957cd0
A
879 {
880 RegisterID scr = claimScratch();
881
882 move(address.index, scr);
883 lshift32(TrustedImm32(address.scale), scr);
81345200 884 add32(TrustedImm32(address.offset), scr);
93a37866 885
6fe7ccc8 886 if (address.base == SH4Registers::r0)
93a37866 887 m_assembler.movwR0mr(scr, dest);
14957cd0
A
888 else {
889 add32(address.base, scr);
93a37866 890 load16Signed(scr, dest);
14957cd0
A
891 }
892
14957cd0
A
893 releaseScratch(scr);
894 }
895
93a37866 896 void store8(RegisterID src, BaseIndex address)
14957cd0
A
897 {
898 RegisterID scr = claimScratch();
93a37866
A
899
900 move(address.index, scr);
901 lshift32(TrustedImm32(address.scale), scr);
902 add32(TrustedImm32(address.offset), scr);
903
904 if (address.base == SH4Registers::r0)
905 m_assembler.movbRegMemr0(src, scr);
906 else {
907 add32(address.base, scr);
908 m_assembler.movbRegMem(src, scr);
909 }
910
14957cd0
A
911 releaseScratch(scr);
912 }
913
81345200
A
914 void store8(RegisterID src, void* address)
915 {
916 RegisterID destptr = claimScratch();
917 move(TrustedImmPtr(address), destptr);
918 m_assembler.movbRegMem(src, destptr);
919 releaseScratch(destptr);
920 }
921
922 void store8(TrustedImm32 imm, void* address)
923 {
924 ASSERT((imm.m_value >= -128) && (imm.m_value <= 127));
925 RegisterID dstptr = claimScratch();
926 move(TrustedImmPtr(address), dstptr);
927 RegisterID srcval = claimScratch();
928 move(imm, srcval);
929 m_assembler.movbRegMem(srcval, dstptr);
930 releaseScratch(dstptr);
931 releaseScratch(srcval);
932 }
933
93a37866 934 void store16(RegisterID src, BaseIndex address)
14957cd0 935 {
93a37866
A
936 RegisterID scr = claimScratch();
937
938 move(address.index, scr);
939 lshift32(TrustedImm32(address.scale), scr);
940 add32(TrustedImm32(address.offset), scr);
941
942 if (address.base == SH4Registers::r0)
943 m_assembler.movwRegMemr0(src, scr);
944 else {
945 add32(address.base, scr);
946 m_assembler.movwRegMem(src, scr);
14957cd0
A
947 }
948
93a37866
A
949 releaseScratch(scr);
950 }
951
952 void store32(RegisterID src, ImplicitAddress address)
953 {
954 if (!address.offset) {
955 m_assembler.movlRegMem(src, address.base);
14957cd0
A
956 return;
957 }
958
93a37866
A
959 if ((address.offset >= 0) && (address.offset < 64)) {
960 m_assembler.movlRegMem(src, address.offset >> 2, address.base);
14957cd0
A
961 return;
962 }
963
93a37866
A
964 RegisterID scr = claimScratch();
965 m_assembler.loadConstant(address.offset, scr);
966 if (address.base == SH4Registers::r0)
967 m_assembler.movlRegMemr0(src, scr);
968 else {
969 m_assembler.addlRegReg(address.base, scr);
970 m_assembler.movlRegMem(src, scr);
971 }
972 releaseScratch(scr);
14957cd0
A
973 }
974
975 void store32(RegisterID src, RegisterID dst)
976 {
977 m_assembler.movlRegMem(src, dst);
978 }
979
980 void store32(TrustedImm32 imm, ImplicitAddress address)
981 {
982 RegisterID scr = claimScratch();
93a37866
A
983 m_assembler.loadConstant(imm.m_value, scr);
984 store32(scr, address);
14957cd0 985 releaseScratch(scr);
14957cd0
A
986 }
987
988 void store32(RegisterID src, BaseIndex address)
989 {
990 RegisterID scr = claimScratch();
991
992 move(address.index, scr);
993 lshift32(TrustedImm32(address.scale), scr);
994 add32(address.base, scr);
995 store32(src, Address(scr, address.offset));
996
997 releaseScratch(scr);
998 }
999
1000 void store32(TrustedImm32 imm, void* address)
1001 {
1002 RegisterID scr = claimScratch();
1003 RegisterID scr1 = claimScratch();
93a37866 1004 m_assembler.loadConstant(imm.m_value, scr);
81345200 1005 move(TrustedImmPtr(address), scr1);
6fe7ccc8 1006 m_assembler.movlRegMem(scr, scr1);
14957cd0
A
1007 releaseScratch(scr);
1008 releaseScratch(scr1);
1009 }
1010
1011 void store32(RegisterID src, void* address)
1012 {
1013 RegisterID scr = claimScratch();
81345200 1014 move(TrustedImmPtr(address), scr);
6fe7ccc8 1015 m_assembler.movlRegMem(src, scr);
14957cd0
A
1016 releaseScratch(scr);
1017 }
1018
81345200
A
1019 void store32(TrustedImm32 imm, BaseIndex address)
1020 {
1021 RegisterID destptr = claimScratch();
1022
1023 loadEffectiveAddress(address, destptr);
1024
1025 RegisterID srcval = claimScratch();
1026 move(imm, srcval);
1027 m_assembler.movlRegMem(srcval, destptr);
1028 releaseScratch(srcval);
1029 releaseScratch(destptr);
1030 }
1031
14957cd0
A
1032 DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
1033 {
1034 RegisterID scr = claimScratch();
1035 DataLabel32 label(this);
1036 m_assembler.loadConstantUnReusable(address.offset, scr);
1037 m_assembler.addlRegReg(address.base, scr);
1038 m_assembler.movlMemReg(scr, dest);
1039 releaseScratch(scr);
1040 return label;
1041 }
1042
14957cd0
A
1043 DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
1044 {
1045 RegisterID scr = claimScratch();
1046 DataLabel32 label(this);
1047 m_assembler.loadConstantUnReusable(address.offset, scr);
1048 m_assembler.addlRegReg(address.base, scr);
1049 m_assembler.movlRegMem(src, scr);
1050 releaseScratch(scr);
1051 return label;
1052 }
1053
6fe7ccc8
A
1054 DataLabelCompact load32WithCompactAddressOffsetPatch(Address address, RegisterID dest)
1055 {
1056 DataLabelCompact dataLabel(this);
81345200 1057 ASSERT(isCompactPtrAlignedAddressOffset(address.offset));
6fe7ccc8
A
1058 m_assembler.movlMemRegCompact(address.offset >> 2, address.base, dest);
1059 return dataLabel;
1060 }
1061
93a37866
A
1062 ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest)
1063 {
1064 ConvertibleLoadLabel result(this);
1065
1066 RegisterID scr = claimScratch();
1067 m_assembler.movImm8(address.offset, scr);
1068 m_assembler.addlRegReg(address.base, scr);
1069 m_assembler.movlMemReg(scr, dest);
1070 releaseScratch(scr);
1071
1072 return result;
1073 }
1074
1075 // Floating-point operations
14957cd0 1076
6fe7ccc8
A
1077 static bool supportsFloatingPoint() { return true; }
1078 static bool supportsFloatingPointTruncate() { return true; }
1079 static bool supportsFloatingPointSqrt() { return true; }
93a37866
A
1080 static bool supportsFloatingPointAbs() { return true; }
1081
1082 void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2)
1083 {
1084 m_assembler.fldsfpul((FPRegisterID)(src + 1));
1085 m_assembler.stsfpulReg(dest1);
1086 m_assembler.fldsfpul(src);
1087 m_assembler.stsfpulReg(dest2);
1088 }
1089
81345200 1090 void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID)
93a37866 1091 {
93a37866
A
1092 m_assembler.ldsrmfpul(src1);
1093 m_assembler.fstsfpul((FPRegisterID)(dest + 1));
1094 m_assembler.ldsrmfpul(src2);
1095 m_assembler.fstsfpul(dest);
1096 }
1097
1098 void moveDouble(FPRegisterID src, FPRegisterID dest)
1099 {
1100 if (src != dest) {
1101 m_assembler.fmovsRegReg((FPRegisterID)(src + 1), (FPRegisterID)(dest + 1));
1102 m_assembler.fmovsRegReg(src, dest);
1103 }
1104 }
1105
81345200
A
1106 void swapDouble(FPRegisterID fr1, FPRegisterID fr2)
1107 {
1108 if (fr1 != fr2) {
1109 m_assembler.fldsfpul((FPRegisterID)(fr1 + 1));
1110 m_assembler.fmovsRegReg((FPRegisterID)(fr2 + 1), (FPRegisterID)(fr1 + 1));
1111 m_assembler.fstsfpul((FPRegisterID)(fr2 + 1));
1112 m_assembler.fldsfpul(fr1);
1113 m_assembler.fmovsRegReg(fr2, fr1);
1114 m_assembler.fstsfpul(fr2);
1115 }
1116 }
1117
93a37866
A
1118 void loadFloat(BaseIndex address, FPRegisterID dest)
1119 {
1120 RegisterID scr = claimScratch();
1121
81345200 1122 loadEffectiveAddress(address, scr);
93a37866
A
1123
1124 m_assembler.fmovsReadrm(scr, dest);
1125 releaseScratch(scr);
1126 }
1127
1128 void loadDouble(BaseIndex address, FPRegisterID dest)
1129 {
1130 RegisterID scr = claimScratch();
1131
81345200 1132 loadEffectiveAddress(address, scr);
93a37866
A
1133
1134 m_assembler.fmovsReadrminc(scr, (FPRegisterID)(dest + 1));
1135 m_assembler.fmovsReadrm(scr, dest);
1136 releaseScratch(scr);
1137 }
14957cd0
A
1138
1139 void loadDouble(ImplicitAddress address, FPRegisterID dest)
1140 {
1141 RegisterID scr = claimScratch();
1142
1143 m_assembler.loadConstant(address.offset, scr);
1144 if (address.base == SH4Registers::r0) {
1145 m_assembler.fmovsReadr0r(scr, (FPRegisterID)(dest + 1));
1146 m_assembler.addlImm8r(4, scr);
1147 m_assembler.fmovsReadr0r(scr, dest);
1148 releaseScratch(scr);
1149 return;
1150 }
1151
1152 m_assembler.addlRegReg(address.base, scr);
1153 m_assembler.fmovsReadrminc(scr, (FPRegisterID)(dest + 1));
1154 m_assembler.fmovsReadrm(scr, dest);
1155 releaseScratch(scr);
1156 }
1157
81345200 1158 void loadDouble(TrustedImmPtr address, FPRegisterID dest)
14957cd0
A
1159 {
1160 RegisterID scr = claimScratch();
81345200 1161 move(address, scr);
14957cd0
A
1162 m_assembler.fmovsReadrminc(scr, (FPRegisterID)(dest + 1));
1163 m_assembler.fmovsReadrm(scr, dest);
1164 releaseScratch(scr);
1165 }
1166
93a37866
A
1167 void storeFloat(FPRegisterID src, BaseIndex address)
1168 {
1169 RegisterID scr = claimScratch();
81345200 1170 loadEffectiveAddress(address, scr);
93a37866 1171 m_assembler.fmovsWriterm(src, scr);
93a37866
A
1172 releaseScratch(scr);
1173 }
1174
14957cd0
A
1175 void storeDouble(FPRegisterID src, ImplicitAddress address)
1176 {
1177 RegisterID scr = claimScratch();
93a37866 1178 m_assembler.loadConstant(address.offset + 8, scr);
14957cd0 1179 m_assembler.addlRegReg(address.base, scr);
93a37866
A
1180 m_assembler.fmovsWriterndec(src, scr);
1181 m_assembler.fmovsWriterndec((FPRegisterID)(src + 1), scr);
1182 releaseScratch(scr);
1183 }
1184
1185 void storeDouble(FPRegisterID src, BaseIndex address)
1186 {
1187 RegisterID scr = claimScratch();
1188
81345200 1189 loadEffectiveAddress(address, scr, 8);
93a37866
A
1190
1191 m_assembler.fmovsWriterndec(src, scr);
1192 m_assembler.fmovsWriterndec((FPRegisterID)(src + 1), scr);
1193
14957cd0
A
1194 releaseScratch(scr);
1195 }
1196
93a37866
A
1197 void addDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
1198 {
1199 if (op1 == dest)
1200 addDouble(op2, dest);
1201 else {
1202 moveDouble(op2, dest);
1203 addDouble(op1, dest);
1204 }
1205 }
1206
81345200
A
1207 void storeDouble(FPRegisterID src, TrustedImmPtr address)
1208 {
1209 RegisterID scr = claimScratch();
1210 m_assembler.loadConstant(reinterpret_cast<uint32_t>(const_cast<void*>(address.m_value)) + 8, scr);
1211 m_assembler.fmovsWriterndec(src, scr);
1212 m_assembler.fmovsWriterndec((FPRegisterID)(src + 1), scr);
1213 releaseScratch(scr);
1214 }
1215
14957cd0
A
1216 void addDouble(FPRegisterID src, FPRegisterID dest)
1217 {
1218 m_assembler.daddRegReg(src, dest);
1219 }
1220
93a37866
A
1221 void addDouble(AbsoluteAddress address, FPRegisterID dest)
1222 {
81345200 1223 loadDouble(TrustedImmPtr(address.m_ptr), fscratch);
93a37866
A
1224 addDouble(fscratch, dest);
1225 }
1226
14957cd0
A
1227 void addDouble(Address address, FPRegisterID dest)
1228 {
1229 loadDouble(address, fscratch);
1230 addDouble(fscratch, dest);
1231 }
1232
1233 void subDouble(FPRegisterID src, FPRegisterID dest)
1234 {
1235 m_assembler.dsubRegReg(src, dest);
1236 }
1237
81345200
A
1238 void subDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
1239 {
1240 if (op2 == dest) {
1241 moveDouble(op1, fscratch);
1242 subDouble(op2, fscratch);
1243 moveDouble(fscratch, dest);
1244 } else {
1245 moveDouble(op1, dest);
1246 subDouble(op2, dest);
1247 }
1248 }
1249
14957cd0
A
1250 void subDouble(Address address, FPRegisterID dest)
1251 {
1252 loadDouble(address, fscratch);
1253 subDouble(fscratch, dest);
1254 }
1255
1256 void mulDouble(FPRegisterID src, FPRegisterID dest)
1257 {
1258 m_assembler.dmulRegReg(src, dest);
1259 }
1260
81345200
A
1261 void mulDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
1262 {
1263 if (op1 == dest)
1264 mulDouble(op2, dest);
1265 else {
1266 moveDouble(op2, dest);
1267 mulDouble(op1, dest);
1268 }
1269 }
1270
14957cd0
A
1271 void mulDouble(Address address, FPRegisterID dest)
1272 {
1273 loadDouble(address, fscratch);
1274 mulDouble(fscratch, dest);
1275 }
1276
1277 void divDouble(FPRegisterID src, FPRegisterID dest)
1278 {
1279 m_assembler.ddivRegReg(src, dest);
1280 }
1281
81345200
A
1282 void divDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
1283 {
1284 if (op2 == dest) {
1285 moveDouble(op1, fscratch);
1286 divDouble(op2, fscratch);
1287 moveDouble(fscratch, dest);
1288 } else {
1289 moveDouble(op1, dest);
1290 divDouble(op2, dest);
1291 }
1292 }
1293
1294 void negateDouble(FPRegisterID src, FPRegisterID dest)
1295 {
1296 moveDouble(src, dest);
1297 m_assembler.dneg(dest);
1298 }
1299
93a37866
A
1300 void convertFloatToDouble(FPRegisterID src, FPRegisterID dst)
1301 {
1302 m_assembler.fldsfpul(src);
1303 m_assembler.dcnvsd(dst);
1304 }
1305
1306 void convertDoubleToFloat(FPRegisterID src, FPRegisterID dst)
1307 {
1308 m_assembler.dcnvds(src);
1309 m_assembler.fstsfpul(dst);
1310 }
1311
14957cd0
A
1312 void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
1313 {
1314 m_assembler.ldsrmfpul(src);
1315 m_assembler.floatfpulDreg(dest);
1316 }
1317
1318 void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
1319 {
1320 RegisterID scr = claimScratch();
93a37866 1321 load32(src.m_ptr, scr);
14957cd0
A
1322 convertInt32ToDouble(scr, dest);
1323 releaseScratch(scr);
1324 }
1325
1326 void convertInt32ToDouble(Address src, FPRegisterID dest)
1327 {
1328 RegisterID scr = claimScratch();
1329 load32(src, scr);
1330 convertInt32ToDouble(scr, dest);
1331 releaseScratch(scr);
1332 }
1333
1334 void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
1335 {
1336 RegisterID scr = claimScratch();
6fe7ccc8
A
1337 Jump m_jump;
1338 JumpList end;
1339
81345200
A
1340 loadEffectiveAddress(address, scr);
1341
1342 RegisterID scr1 = claimScratch();
6fe7ccc8
A
1343 if (dest != SH4Registers::r0)
1344 move(SH4Registers::r0, scr1);
14957cd0 1345
93a37866 1346 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 58, sizeof(uint32_t));
6fe7ccc8 1347 move(scr, SH4Registers::r0);
93a37866 1348 m_assembler.testlImm8r(0x3, SH4Registers::r0);
6fe7ccc8 1349 m_jump = Jump(m_assembler.jne(), SH4Assembler::JumpNear);
93a37866 1350
6fe7ccc8
A
1351 if (dest != SH4Registers::r0)
1352 move(scr1, SH4Registers::r0);
1353
1354 load32(scr, dest);
1355 end.append(Jump(m_assembler.bra(), SH4Assembler::JumpNear));
1356 m_assembler.nop();
1357 m_jump.link(this);
93a37866 1358 m_assembler.testlImm8r(0x1, SH4Registers::r0);
6fe7ccc8
A
1359
1360 if (dest != SH4Registers::r0)
1361 move(scr1, SH4Registers::r0);
1362
1363 m_jump = Jump(m_assembler.jne(), SH4Assembler::JumpNear);
93a37866 1364 load16PostInc(scr, scr1);
14957cd0 1365 load16(scr, dest);
6fe7ccc8 1366 m_assembler.shllImm8r(16, dest);
14957cd0 1367 or32(scr1, dest);
6fe7ccc8
A
1368 end.append(Jump(m_assembler.bra(), SH4Assembler::JumpNear));
1369 m_assembler.nop();
1370 m_jump.link(this);
93a37866
A
1371 load8PostInc(scr, scr1);
1372 load16PostInc(scr, dest);
6fe7ccc8
A
1373 m_assembler.shllImm8r(8, dest);
1374 or32(dest, scr1);
6fe7ccc8
A
1375 load8(scr, dest);
1376 m_assembler.shllImm8r(8, dest);
1377 m_assembler.shllImm8r(16, dest);
1378 or32(scr1, dest);
1379 end.link(this);
14957cd0
A
1380
1381 releaseScratch(scr);
1382 releaseScratch(scr1);
1383 }
1384
1385 Jump branch32WithUnalignedHalfWords(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
1386 {
1387 RegisterID scr = scratchReg3;
1388 load32WithUnalignedHalfWords(left, scr);
1389 if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
1390 m_assembler.testlRegReg(scr, scr);
1391 else
1392 compare32(right.m_value, scr, cond);
1393
1394 if (cond == NotEqual)
1395 return branchFalse();
1396 return branchTrue();
1397 }
1398
1399 Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID scratch)
1400 {
1401 m_assembler.movImm8(0, scratchReg3);
1402 convertInt32ToDouble(scratchReg3, scratch);
1403 return branchDouble(DoubleNotEqual, reg, scratch);
1404 }
1405
1406 Jump branchDoubleZeroOrNaN(FPRegisterID reg, FPRegisterID scratch)
1407 {
1408 m_assembler.movImm8(0, scratchReg3);
1409 convertInt32ToDouble(scratchReg3, scratch);
1410 return branchDouble(DoubleEqualOrUnordered, reg, scratch);
1411 }
1412
1413 Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
1414 {
1415 if (cond == DoubleEqual) {
1416 m_assembler.dcmppeq(right, left);
1417 return branchTrue();
1418 }
1419
1420 if (cond == DoubleNotEqual) {
6fe7ccc8 1421 JumpList end;
93a37866 1422 m_assembler.dcmppeq(left, left);
14957cd0 1423 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
93a37866
A
1424 end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
1425 m_assembler.dcmppeq(right, right);
1426 end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
14957cd0 1427 m_assembler.dcmppeq(right, left);
6fe7ccc8
A
1428 Jump m_jump = branchFalse();
1429 end.link(this);
1430 return m_jump;
14957cd0
A
1431 }
1432
1433 if (cond == DoubleGreaterThan) {
1434 m_assembler.dcmppgt(right, left);
1435 return branchTrue();
1436 }
1437
1438 if (cond == DoubleGreaterThanOrEqual) {
93a37866
A
1439 JumpList end;
1440 m_assembler.dcmppeq(left, left);
1441 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
1442 end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
1443 m_assembler.dcmppeq(right, right);
1444 end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
14957cd0 1445 m_assembler.dcmppgt(left, right);
93a37866
A
1446 Jump m_jump = branchFalse();
1447 end.link(this);
1448 return m_jump;
14957cd0
A
1449 }
1450
1451 if (cond == DoubleLessThan) {
1452 m_assembler.dcmppgt(left, right);
1453 return branchTrue();
1454 }
1455
1456 if (cond == DoubleLessThanOrEqual) {
93a37866
A
1457 JumpList end;
1458 m_assembler.dcmppeq(left, left);
1459 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
1460 end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
1461 m_assembler.dcmppeq(right, right);
1462 end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
14957cd0 1463 m_assembler.dcmppgt(right, left);
93a37866
A
1464 Jump m_jump = branchFalse();
1465 end.link(this);
1466 return m_jump;
14957cd0
A
1467 }
1468
1469 if (cond == DoubleEqualOrUnordered) {
93a37866
A
1470 JumpList takeBranch;
1471 m_assembler.dcmppeq(left, left);
14957cd0 1472 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
93a37866
A
1473 takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
1474 m_assembler.dcmppeq(right, right);
1475 takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
14957cd0 1476 m_assembler.dcmppeq(left, right);
81345200 1477 m_assembler.branch(BF_OPCODE, 2);
93a37866 1478 takeBranch.link(this);
81345200 1479 return Jump(m_assembler.extraInstrForBranch(scratchReg3));
14957cd0
A
1480 }
1481
1482 if (cond == DoubleGreaterThanOrUnordered) {
93a37866
A
1483 JumpList takeBranch;
1484 m_assembler.dcmppeq(left, left);
14957cd0 1485 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
93a37866
A
1486 takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
1487 m_assembler.dcmppeq(right, right);
1488 takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
14957cd0 1489 m_assembler.dcmppgt(right, left);
81345200 1490 m_assembler.branch(BF_OPCODE, 2);
93a37866 1491 takeBranch.link(this);
81345200 1492 return Jump(m_assembler.extraInstrForBranch(scratchReg3));
14957cd0
A
1493 }
1494
1495 if (cond == DoubleGreaterThanOrEqualOrUnordered) {
14957cd0 1496 m_assembler.dcmppgt(left, right);
93a37866 1497 return branchFalse();
14957cd0
A
1498 }
1499
1500 if (cond == DoubleLessThanOrUnordered) {
93a37866
A
1501 JumpList takeBranch;
1502 m_assembler.dcmppeq(left, left);
14957cd0 1503 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
93a37866
A
1504 takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
1505 m_assembler.dcmppeq(right, right);
1506 takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
14957cd0 1507 m_assembler.dcmppgt(left, right);
81345200 1508 m_assembler.branch(BF_OPCODE, 2);
93a37866 1509 takeBranch.link(this);
81345200 1510 return Jump(m_assembler.extraInstrForBranch(scratchReg3));
14957cd0
A
1511 }
1512
1513 if (cond == DoubleLessThanOrEqualOrUnordered) {
14957cd0 1514 m_assembler.dcmppgt(right, left);
93a37866 1515 return branchFalse();
14957cd0
A
1516 }
1517
1518 ASSERT(cond == DoubleNotEqualOrUnordered);
14957cd0 1519 m_assembler.dcmppeq(right, left);
93a37866 1520 return branchFalse();
14957cd0
A
1521 }
1522
1523 Jump branchTrue()
1524 {
1525 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 6, sizeof(uint32_t));
81345200
A
1526 m_assembler.branch(BF_OPCODE, 2);
1527 return Jump(m_assembler.extraInstrForBranch(scratchReg3));
14957cd0
A
1528 }
1529
1530 Jump branchFalse()
1531 {
1532 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 6, sizeof(uint32_t));
81345200
A
1533 m_assembler.branch(BT_OPCODE, 2);
1534 return Jump(m_assembler.extraInstrForBranch(scratchReg3));
14957cd0
A
1535 }
1536
1537 Jump branch32(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
1538 {
1539 RegisterID scr = claimScratch();
1540 move(left.index, scr);
1541 lshift32(TrustedImm32(left.scale), scr);
1542 add32(left.base, scr);
1543 load32(scr, left.offset, scr);
1544 compare32(right.m_value, scr, cond);
1545 releaseScratch(scr);
1546
1547 if (cond == NotEqual)
1548 return branchFalse();
1549 return branchTrue();
1550 }
1551
1552 void sqrtDouble(FPRegisterID src, FPRegisterID dest)
1553 {
93a37866 1554 moveDouble(src, dest);
14957cd0
A
1555 m_assembler.dsqrt(dest);
1556 }
6fe7ccc8 1557
93a37866 1558 void absDouble(FPRegisterID src, FPRegisterID dest)
6fe7ccc8 1559 {
93a37866
A
1560 moveDouble(src, dest);
1561 m_assembler.dabs(dest);
6fe7ccc8 1562 }
14957cd0
A
1563
1564 Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
1565 {
1566 RegisterID addressTempRegister = claimScratch();
1567 load8(address, addressTempRegister);
1568 Jump jmp = branchTest32(cond, addressTempRegister, mask);
1569 releaseScratch(addressTempRegister);
1570 return jmp;
1571 }
1572
81345200
A
1573 Jump branchTest8(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
1574 {
1575 RegisterID addressTempRegister = claimScratch();
1576 load8(address, addressTempRegister);
1577 Jump jmp = branchTest32(cond, addressTempRegister, mask);
1578 releaseScratch(addressTempRegister);
1579 return jmp;
1580 }
1581
93a37866
A
1582 Jump branchTest8(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
1583 {
1584 RegisterID addressTempRegister = claimScratch();
1585 move(TrustedImmPtr(address.m_ptr), addressTempRegister);
1586 load8(Address(addressTempRegister), addressTempRegister);
1587 Jump jmp = branchTest32(cond, addressTempRegister, mask);
1588 releaseScratch(addressTempRegister);
1589 return jmp;
1590 }
1591
14957cd0
A
1592 void signExtend32ToPtr(RegisterID src, RegisterID dest)
1593 {
81345200
A
1594 move(src, dest);
1595 }
1596
1597 void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
1598 {
1599 move(src, dest);
14957cd0
A
1600 }
1601
1602 Jump branch8(RelationalCondition cond, Address left, TrustedImm32 right)
1603 {
1604 RegisterID addressTempRegister = claimScratch();
1605 load8(left, addressTempRegister);
1606 Jump jmp = branch32(cond, addressTempRegister, right);
1607 releaseScratch(addressTempRegister);
1608 return jmp;
1609 }
1610
81345200
A
1611 Jump branch8(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right)
1612 {
1613 RegisterID addressTempRegister = claimScratch();
1614 load8(left, addressTempRegister);
1615 Jump jmp = branch32(cond, addressTempRegister, right);
1616 releaseScratch(addressTempRegister);
1617 return jmp;
1618 }
1619
6fe7ccc8
A
1620 void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest)
1621 {
1622 RegisterID addressTempRegister = claimScratch();
1623 load8(left, addressTempRegister);
1624 compare32(cond, addressTempRegister, right, dest);
1625 releaseScratch(addressTempRegister);
1626 }
1627
93a37866
A
1628 enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful };
1629 Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed)
81345200
A
1630 {
1631 Jump result;
1632 truncateDoubleToInt32(src, dest);
1633 RegisterID intscr = claimScratch();
1634 m_assembler.loadConstant(0x7fffffff, intscr);
1635 m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
1636 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 12, sizeof(uint32_t));
1637 if (branchType == BranchIfTruncateFailed) {
1638 m_assembler.branch(BT_OPCODE, 2);
1639 m_assembler.addlImm8r(1, intscr);
1640 m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
1641 result = branchTrue();
1642 } else {
1643 Jump out = Jump(m_assembler.je(), SH4Assembler::JumpNear);
1644 m_assembler.addlImm8r(1, intscr);
1645 m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
1646 result = branchFalse();
1647 out.link(this);
1648 }
1649 releaseScratch(intscr);
1650 return result;
1651 }
1652
1653 Jump branchTruncateDoubleToUint32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed)
1654 {
1655 Jump result;
1656 RegisterID intscr = claimScratch();
1657 m_assembler.loadConstant(0x80000000, intscr);
1658 convertInt32ToDouble(intscr, fscratch);
1659 addDouble(src, fscratch);
1660 truncateDoubleToInt32(fscratch, dest);
1661 m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
1662 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 16, sizeof(uint32_t));
1663 if (branchType == BranchIfTruncateFailed) {
1664 m_assembler.branch(BT_OPCODE, 4);
1665 m_assembler.addlImm8r(-1, intscr);
1666 m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
1667 m_assembler.addlImm8r(1, intscr);
1668 m_assembler.sublRegReg(intscr, dest);
1669 result = branchTrue();
1670 } else {
1671 Jump out = Jump(m_assembler.je(), SH4Assembler::JumpNear);
1672 m_assembler.addlImm8r(-1, intscr);
1673 m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
1674 m_assembler.addlImm8r(1, intscr);
1675 m_assembler.sublRegReg(intscr, dest);
1676 result = branchFalse();
1677 out.link(this);
1678 }
1679 releaseScratch(intscr);
1680 return result;
1681 }
1682
1683 void truncateDoubleToInt32(FPRegisterID src, RegisterID dest)
14957cd0
A
1684 {
1685 m_assembler.ftrcdrmfpul(src);
1686 m_assembler.stsfpulReg(dest);
81345200
A
1687 }
1688
1689 void truncateDoubleToUint32(FPRegisterID src, RegisterID dest)
1690 {
1691 RegisterID intscr = claimScratch();
1692 m_assembler.loadConstant(0x80000000, intscr);
1693 convertInt32ToDouble(intscr, fscratch);
1694 addDouble(src, fscratch);
1695 m_assembler.ftrcdrmfpul(fscratch);
1696 m_assembler.stsfpulReg(dest);
1697 m_assembler.sublRegReg(intscr, dest);
1698 releaseScratch(intscr);
14957cd0
A
1699 }
1700
1701 // Stack manipulation operations
1702
1703 void pop(RegisterID dest)
1704 {
1705 m_assembler.popReg(dest);
1706 }
1707
1708 void push(RegisterID src)
1709 {
1710 m_assembler.pushReg(src);
1711 }
1712
14957cd0
A
1713 void push(TrustedImm32 imm)
1714 {
1715 RegisterID scr = claimScratch();
1716 m_assembler.loadConstant(imm.m_value, scr);
1717 push(scr);
1718 releaseScratch(scr);
1719 }
1720
1721 // Register move operations
1722
1723 void move(TrustedImm32 imm, RegisterID dest)
1724 {
1725 m_assembler.loadConstant(imm.m_value, dest);
1726 }
1727
1728 DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
1729 {
6fe7ccc8 1730 m_assembler.ensureSpace(m_assembler.maxInstructionSize, sizeof(uint32_t));
14957cd0 1731 DataLabelPtr dataLabel(this);
6fe7ccc8 1732 m_assembler.loadConstantUnReusable(reinterpret_cast<uint32_t>(initialValue.m_value), dest);
14957cd0
A
1733 return dataLabel;
1734 }
1735
1736 void move(RegisterID src, RegisterID dest)
1737 {
6fe7ccc8
A
1738 if (src != dest)
1739 m_assembler.movlRegReg(src, dest);
14957cd0
A
1740 }
1741
1742 void move(TrustedImmPtr imm, RegisterID dest)
1743 {
1744 m_assembler.loadConstant(imm.asIntptr(), dest);
1745 }
1746
81345200
A
1747 void swap(RegisterID reg1, RegisterID reg2)
1748 {
1749 if (reg1 != reg2) {
1750 xor32(reg1, reg2);
1751 xor32(reg2, reg1);
1752 xor32(reg1, reg2);
1753 }
1754 }
1755
14957cd0
A
1756 void compare32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
1757 {
1758 m_assembler.cmplRegReg(right, left, SH4Condition(cond));
1759 if (cond != NotEqual) {
1760 m_assembler.movt(dest);
1761 return;
1762 }
1763
1764 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 4);
1765 m_assembler.movImm8(0, dest);
1766 m_assembler.branch(BT_OPCODE, 0);
1767 m_assembler.movImm8(1, dest);
1768 }
1769
1770 void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
1771 {
1772 if (left != dest) {
1773 move(right, dest);
1774 compare32(cond, left, dest, dest);
1775 return;
1776 }
1777
1778 RegisterID scr = claimScratch();
1779 move(right, scr);
1780 compare32(cond, left, scr, dest);
1781 releaseScratch(scr);
1782 }
1783
1784 void test8(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest)
1785 {
1786 ASSERT((cond == Zero) || (cond == NonZero));
1787
1788 load8(address, dest);
1789 if (mask.m_value == -1)
1790 compare32(0, dest, static_cast<RelationalCondition>(cond));
1791 else
1792 testlImm(mask.m_value, dest);
1793 if (cond != NonZero) {
1794 m_assembler.movt(dest);
1795 return;
1796 }
1797
1798 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 4);
1799 m_assembler.movImm8(0, dest);
1800 m_assembler.branch(BT_OPCODE, 0);
1801 m_assembler.movImm8(1, dest);
1802 }
1803
81345200
A
1804 void test32(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest)
1805 {
1806 ASSERT((cond == Zero) || (cond == NonZero));
1807
1808 load32(address, dest);
1809 if (mask.m_value == -1)
1810 compare32(0, dest, static_cast<RelationalCondition>(cond));
1811 else
1812 testlImm(mask.m_value, dest);
1813 if (cond != NonZero) {
1814 m_assembler.movt(dest);
1815 return;
1816 }
1817
1818 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 4);
1819 m_assembler.movImm8(0, dest);
1820 m_assembler.branch(BT_OPCODE, 0);
1821 m_assembler.movImm8(1, dest);
1822 }
1823
14957cd0
A
1824 void loadPtrLinkReg(ImplicitAddress address)
1825 {
1826 RegisterID scr = claimScratch();
1827 load32(address, scr);
1828 m_assembler.ldspr(scr);
1829 releaseScratch(scr);
1830 }
1831
1832 Jump branch32(RelationalCondition cond, RegisterID left, RegisterID right)
1833 {
1834 m_assembler.cmplRegReg(right, left, SH4Condition(cond));
1835 /* BT label => BF off
1836 nop LDR reg
1837 nop braf @reg
1838 nop nop
1839 */
1840 if (cond == NotEqual)
1841 return branchFalse();
1842 return branchTrue();
1843 }
1844
1845 Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right)
1846 {
1847 if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
1848 m_assembler.testlRegReg(left, left);
1849 else
1850 compare32(right.m_value, left, cond);
1851
1852 if (cond == NotEqual)
1853 return branchFalse();
1854 return branchTrue();
1855 }
1856
1857 Jump branch32(RelationalCondition cond, RegisterID left, Address right)
1858 {
1859 compare32(right.offset, right.base, left, cond);
1860 if (cond == NotEqual)
1861 return branchFalse();
1862 return branchTrue();
1863 }
1864
1865 Jump branch32(RelationalCondition cond, Address left, RegisterID right)
1866 {
1867 compare32(right, left.offset, left.base, cond);
1868 if (cond == NotEqual)
1869 return branchFalse();
1870 return branchTrue();
1871 }
1872
1873 Jump branch32(RelationalCondition cond, Address left, TrustedImm32 right)
1874 {
1875 compare32(right.m_value, left.offset, left.base, cond);
1876 if (cond == NotEqual)
1877 return branchFalse();
1878 return branchTrue();
1879 }
1880
1881 Jump branch32(RelationalCondition cond, AbsoluteAddress left, RegisterID right)
1882 {
1883 RegisterID scr = claimScratch();
1884
93a37866 1885 load32(left.m_ptr, scr);
14957cd0
A
1886 m_assembler.cmplRegReg(right, scr, SH4Condition(cond));
1887 releaseScratch(scr);
1888
1889 if (cond == NotEqual)
1890 return branchFalse();
1891 return branchTrue();
1892 }
1893
1894 Jump branch32(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right)
1895 {
1896 RegisterID addressTempRegister = claimScratch();
1897
81345200 1898 move(TrustedImmPtr(left.m_ptr), addressTempRegister);
14957cd0
A
1899 m_assembler.movlMemReg(addressTempRegister, addressTempRegister);
1900 compare32(right.m_value, addressTempRegister, cond);
1901 releaseScratch(addressTempRegister);
1902
1903 if (cond == NotEqual)
1904 return branchFalse();
1905 return branchTrue();
1906 }
1907
6fe7ccc8 1908 Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
14957cd0 1909 {
6fe7ccc8 1910 ASSERT(!(right.m_value & 0xFFFFFF00));
81345200 1911 RegisterID lefttmp = claimScratch();
14957cd0 1912
81345200 1913 loadEffectiveAddress(left, lefttmp);
14957cd0 1914
81345200
A
1915 load8(lefttmp, lefttmp);
1916 RegisterID righttmp = claimScratch();
1917 m_assembler.loadConstant(right.m_value, righttmp);
14957cd0 1918
81345200
A
1919 Jump result = branch32(cond, lefttmp, righttmp);
1920 releaseScratch(lefttmp);
1921 releaseScratch(righttmp);
1922 return result;
14957cd0
A
1923 }
1924
1925 Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask)
1926 {
1927 ASSERT((cond == Zero) || (cond == NonZero));
1928
1929 m_assembler.testlRegReg(reg, mask);
1930
93a37866 1931 if (cond == NonZero) // NotEqual
14957cd0
A
1932 return branchFalse();
1933 return branchTrue();
1934 }
1935
1936 Jump branchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
1937 {
1938 ASSERT((cond == Zero) || (cond == NonZero));
1939
1940 if (mask.m_value == -1)
1941 m_assembler.testlRegReg(reg, reg);
1942 else
1943 testlImm(mask.m_value, reg);
1944
93a37866 1945 if (cond == NonZero) // NotEqual
14957cd0
A
1946 return branchFalse();
1947 return branchTrue();
1948 }
1949
1950 Jump branchTest32(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
1951 {
1952 ASSERT((cond == Zero) || (cond == NonZero));
1953
1954 if (mask.m_value == -1)
1955 compare32(0, address.offset, address.base, static_cast<RelationalCondition>(cond));
1956 else
1957 testImm(mask.m_value, address.offset, address.base);
1958
93a37866 1959 if (cond == NonZero) // NotEqual
14957cd0
A
1960 return branchFalse();
1961 return branchTrue();
1962 }
1963
1964 Jump branchTest32(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
1965 {
81345200
A
1966 ASSERT((cond == Zero) || (cond == NonZero));
1967
14957cd0
A
1968 RegisterID scr = claimScratch();
1969
1970 move(address.index, scr);
1971 lshift32(TrustedImm32(address.scale), scr);
1972 add32(address.base, scr);
1973 load32(scr, address.offset, scr);
1974
1975 if (mask.m_value == -1)
1976 m_assembler.testlRegReg(scr, scr);
1977 else
1978 testlImm(mask.m_value, scr);
1979
1980 releaseScratch(scr);
1981
93a37866 1982 if (cond == NonZero) // NotEqual
14957cd0
A
1983 return branchFalse();
1984 return branchTrue();
1985 }
1986
1987 Jump jump()
1988 {
1989 return Jump(m_assembler.jmp());
1990 }
1991
1992 void jump(RegisterID target)
1993 {
1994 m_assembler.jmpReg(target);
1995 }
1996
1997 void jump(Address address)
1998 {
1999 RegisterID scr = claimScratch();
81345200 2000 load32(address, scr);
14957cd0 2001 m_assembler.jmpReg(scr);
81345200
A
2002 releaseScratch(scr);
2003 }
2004
2005 void jump(AbsoluteAddress address)
2006 {
2007 RegisterID scr = claimScratch();
14957cd0 2008
81345200
A
2009 move(TrustedImmPtr(address.m_ptr), scr);
2010 m_assembler.movlMemReg(scr, scr);
2011 m_assembler.jmpReg(scr);
14957cd0
A
2012 releaseScratch(scr);
2013 }
2014
2015 // Arithmetic control flow operations
2016
81345200
A
2017 Jump branchNeg32(ResultCondition cond, RegisterID srcDest)
2018 {
2019 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
2020
2021 if (cond == Overflow)
2022 return branchMul32(cond, TrustedImm32(-1), srcDest, srcDest);
2023
2024 neg32(srcDest);
2025
2026 if (cond == Signed) {
2027 m_assembler.cmppz(srcDest);
2028 return branchFalse();
2029 }
2030
2031 compare32(0, srcDest, Equal);
2032 return (cond == NonZero) ? branchFalse() : branchTrue();
2033 }
2034
14957cd0
A
2035 Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest)
2036 {
93a37866 2037 ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
14957cd0
A
2038
2039 if (cond == Overflow) {
2040 m_assembler.addvlRegReg(src, dest);
2041 return branchTrue();
2042 }
2043
81345200
A
2044 m_assembler.addlRegReg(src, dest);
2045
2046 if ((cond == Signed) || (cond == PositiveOrZero)) {
14957cd0 2047 m_assembler.cmppz(dest);
81345200 2048 return (cond == Signed) ? branchFalse() : branchTrue();
14957cd0
A
2049 }
2050
81345200
A
2051 compare32(0, dest, Equal);
2052 return (cond == NonZero) ? branchFalse() : branchTrue();
2053 }
2054
2055 Jump branchAdd32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest)
2056 {
2057 ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
2058
2059 if (cond == Overflow) {
2060 if (src1 == dest)
2061 m_assembler.addvlRegReg(src2, dest);
2062 else {
2063 move(src2, dest);
2064 m_assembler.addvlRegReg(src1, dest);
2065 }
93a37866
A
2066 return branchTrue();
2067 }
2068
81345200 2069 add32(src1, src2, dest);
14957cd0 2070
81345200
A
2071 if ((cond == Signed) || (cond == PositiveOrZero)) {
2072 m_assembler.cmppz(dest);
2073 return (cond == Signed) ? branchFalse() : branchTrue();
2074 }
2075
2076 compare32(0, dest, Equal);
2077 return (cond == NonZero) ? branchFalse() : branchTrue();
14957cd0
A
2078 }
2079
2080 Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
2081 {
93a37866 2082 ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
14957cd0 2083
81345200
A
2084 RegisterID immval = claimScratch();
2085 move(imm, immval);
2086 Jump result = branchAdd32(cond, immval, dest);
2087 releaseScratch(immval);
2088 return result;
14957cd0
A
2089 }
2090
6fe7ccc8
A
2091 Jump branchAdd32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
2092 {
93a37866 2093 ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
6fe7ccc8 2094
81345200 2095 move(src, dest);
6fe7ccc8
A
2096
2097 if (cond == Overflow) {
2098 move(imm, scratchReg3);
2099 m_assembler.addvlRegReg(scratchReg3, dest);
2100 return branchTrue();
2101 }
2102
2103 add32(imm, dest);
2104
81345200 2105 if ((cond == Signed) || (cond == PositiveOrZero)) {
6fe7ccc8 2106 m_assembler.cmppz(dest);
81345200 2107 return (cond == Signed) ? branchFalse() : branchTrue();
93a37866
A
2108 }
2109
6fe7ccc8 2110 compare32(0, dest, Equal);
81345200 2111 return (cond == NonZero) ? branchFalse() : branchTrue();
6fe7ccc8
A
2112 }
2113
93a37866
A
2114 Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest)
2115 {
2116 ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
2117 bool result;
2118
2119 move(imm, scratchReg3);
2120 RegisterID destptr = claimScratch();
2121 RegisterID destval = claimScratch();
81345200 2122 move(TrustedImmPtr(dest.m_ptr), destptr);
93a37866
A
2123 m_assembler.movlMemReg(destptr, destval);
2124 if (cond == Overflow) {
2125 m_assembler.addvlRegReg(scratchReg3, destval);
2126 result = true;
2127 } else {
2128 m_assembler.addlRegReg(scratchReg3, destval);
81345200 2129 if ((cond == Signed) || (cond == PositiveOrZero)) {
93a37866 2130 m_assembler.cmppz(destval);
81345200 2131 result = (cond == PositiveOrZero);
93a37866 2132 } else {
81345200
A
2133 m_assembler.testlRegReg(destval, destval);
2134 result = (cond != NonZero);
93a37866
A
2135 }
2136 }
2137 m_assembler.movlRegMem(destval, destptr);
2138 releaseScratch(destval);
2139 releaseScratch(destptr);
2140 return result ? branchTrue() : branchFalse();
2141 }
2142
14957cd0
A
2143 Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest)
2144 {
2145 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
2146
2147 if (cond == Overflow) {
93a37866
A
2148 RegisterID scrsign = claimScratch();
2149 RegisterID msbres = claimScratch();
2150 m_assembler.dmulslRegReg(src, dest);
14957cd0 2151 m_assembler.stsmacl(dest);
93a37866
A
2152 m_assembler.cmppz(dest);
2153 m_assembler.movt(scrsign);
2154 m_assembler.addlImm8r(-1, scrsign);
2155 m_assembler.stsmach(msbres);
2156 m_assembler.cmplRegReg(msbres, scrsign, SH4Condition(Equal));
2157 releaseScratch(msbres);
2158 releaseScratch(scrsign);
14957cd0
A
2159 return branchFalse();
2160 }
2161
81345200
A
2162 mul32(src, dest);
2163
14957cd0 2164 if (cond == Signed) {
14957cd0
A
2165 m_assembler.cmppz(dest);
2166 return branchFalse();
2167 }
2168
2169 compare32(0, dest, static_cast<RelationalCondition>(cond));
81345200
A
2170 return (cond == NonZero) ? branchFalse() : branchTrue();
2171 }
14957cd0 2172
81345200
A
2173 Jump branchMul32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest)
2174 {
2175 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
2176
2177 if (cond == Overflow) {
2178 RegisterID scrsign = claimScratch();
2179 RegisterID msbres = claimScratch();
2180 m_assembler.dmulslRegReg(src1, src2);
2181 m_assembler.stsmacl(dest);
2182 m_assembler.cmppz(dest);
2183 m_assembler.movt(scrsign);
2184 m_assembler.addlImm8r(-1, scrsign);
2185 m_assembler.stsmach(msbres);
2186 m_assembler.cmplRegReg(msbres, scrsign, SH4Condition(Equal));
2187 releaseScratch(msbres);
2188 releaseScratch(scrsign);
14957cd0 2189 return branchFalse();
81345200
A
2190 }
2191
2192 mul32(src1, src2, dest);
2193
2194 if (cond == Signed) {
2195 m_assembler.cmppz(dest);
2196 return branchFalse();
2197 }
2198
2199 compare32(0, dest, Equal);
2200 return (cond == NonZero) ? branchFalse() : branchTrue();
14957cd0
A
2201 }
2202
2203 Jump branchMul32(ResultCondition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
2204 {
2205 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
2206
81345200
A
2207 if (src == dest) {
2208 move(imm, scratchReg3);
2209 return branchMul32(cond, scratchReg3, dest);
2210 }
14957cd0 2211
81345200
A
2212 move(imm, dest);
2213 return branchMul32(cond, src, dest);
14957cd0
A
2214 }
2215
2216 Jump branchSub32(ResultCondition cond, RegisterID src, RegisterID dest)
2217 {
2218 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
2219
2220 if (cond == Overflow) {
2221 m_assembler.subvlRegReg(src, dest);
2222 return branchTrue();
2223 }
2224
81345200
A
2225 sub32(src, dest);
2226
14957cd0 2227 if (cond == Signed) {
81345200
A
2228 m_assembler.cmppz(dest);
2229 return branchFalse();
14957cd0
A
2230 }
2231
14957cd0 2232 compare32(0, dest, static_cast<RelationalCondition>(cond));
81345200 2233 return (cond == NonZero) ? branchFalse() : branchTrue();
14957cd0
A
2234 }
2235
2236 Jump branchSub32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
2237 {
2238 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
2239
81345200
A
2240 RegisterID immval = claimScratch();
2241 move(imm, immval);
2242 Jump result = branchSub32(cond, immval, dest);
2243 releaseScratch(immval);
2244 return result;
14957cd0
A
2245 }
2246
6fe7ccc8
A
2247 Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
2248 {
81345200
A
2249 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
2250
2251 move(src, dest);
2252 return branchSub32(cond, imm, dest);
6fe7ccc8
A
2253 }
2254
2255 Jump branchSub32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest)
2256 {
81345200
A
2257 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
2258
2259 if (src2 != dest) {
6fe7ccc8 2260 move(src1, dest);
81345200
A
2261 return branchSub32(cond, src2, dest);
2262 }
2263
2264 if (cond == Overflow) {
2265 RegisterID tmpval = claimScratch();
2266 move(src1, tmpval);
2267 m_assembler.subvlRegReg(src2, tmpval);
2268 move(tmpval, dest);
2269 releaseScratch(tmpval);
2270 return branchTrue();
2271 }
2272
2273 RegisterID tmpval = claimScratch();
2274 move(src1, tmpval);
2275 sub32(src2, tmpval);
2276 move(tmpval, dest);
2277 releaseScratch(tmpval);
2278
2279 if (cond == Signed) {
2280 m_assembler.cmppz(dest);
2281 return branchFalse();
2282 }
2283
2284 compare32(0, dest, static_cast<RelationalCondition>(cond));
2285 return (cond == NonZero) ? branchFalse() : branchTrue();
6fe7ccc8
A
2286 }
2287
14957cd0
A
2288 Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest)
2289 {
2290 ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
2291
81345200
A
2292 or32(src, dest);
2293
14957cd0 2294 if (cond == Signed) {
81345200
A
2295 m_assembler.cmppz(dest);
2296 return branchFalse();
14957cd0
A
2297 }
2298
14957cd0 2299 compare32(0, dest, static_cast<RelationalCondition>(cond));
81345200 2300 return (cond == NonZero) ? branchFalse() : branchTrue();
14957cd0
A
2301 }
2302
81345200 2303 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID, bool negZeroCheck = true)
14957cd0 2304 {
81345200 2305 truncateDoubleToInt32(src, dest);
14957cd0
A
2306 convertInt32ToDouble(dest, fscratch);
2307 failureCases.append(branchDouble(DoubleNotEqualOrUnordered, fscratch, src));
2308
81345200
A
2309 if (negZeroCheck)
2310 failureCases.append(branch32(Equal, dest, TrustedImm32(0)));
14957cd0
A
2311 }
2312
2313 void neg32(RegisterID dst)
2314 {
2315 m_assembler.neg(dst, dst);
2316 }
2317
14957cd0
A
2318 void urshift32(RegisterID shiftamount, RegisterID dest)
2319 {
93a37866
A
2320 RegisterID shiftTmp = claimScratch();
2321 m_assembler.loadConstant(0x1f, shiftTmp);
2322 m_assembler.andlRegReg(shiftamount, shiftTmp);
2323 m_assembler.neg(shiftTmp, shiftTmp);
2324 m_assembler.shldRegReg(dest, shiftTmp);
2325 releaseScratch(shiftTmp);
14957cd0
A
2326 }
2327
81345200
A
2328 void urshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
2329 {
2330 move(src, dest);
2331 urshift32(shiftAmount, dest);
2332 }
2333
14957cd0
A
2334 void urshift32(TrustedImm32 imm, RegisterID dest)
2335 {
93a37866
A
2336 int immMasked = imm.m_value & 0x1f;
2337 if (!immMasked)
2338 return;
2339
2340 if ((immMasked == 1) || (immMasked == 2) || (immMasked == 8) || (immMasked == 16)) {
2341 m_assembler.shlrImm8r(immMasked, dest);
2342 return;
2343 }
2344
2345 RegisterID shiftTmp = claimScratch();
2346 m_assembler.loadConstant(-immMasked, shiftTmp);
2347 m_assembler.shldRegReg(dest, shiftTmp);
2348 releaseScratch(shiftTmp);
14957cd0
A
2349 }
2350
6fe7ccc8
A
2351 void urshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest)
2352 {
81345200 2353 move(src, dest);
6fe7ccc8
A
2354 urshift32(shiftamount, dest);
2355 }
2356
14957cd0
A
2357 Call call()
2358 {
2359 return Call(m_assembler.call(), Call::Linkable);
2360 }
2361
2362 Call nearCall()
2363 {
2364 return Call(m_assembler.call(), Call::LinkableNear);
2365 }
2366
2367 Call call(RegisterID target)
2368 {
2369 return Call(m_assembler.call(target), Call::None);
2370 }
2371
81345200 2372 void call(Address address)
14957cd0 2373 {
81345200 2374 RegisterID target = claimScratch();
14957cd0
A
2375 load32(address.base, address.offset, target);
2376 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 2);
2377 m_assembler.branch(JSR_OPCODE, target);
2378 m_assembler.nop();
81345200 2379 releaseScratch(target);
14957cd0
A
2380 }
2381
2382 void breakpoint()
2383 {
81345200 2384 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 2);
14957cd0
A
2385 m_assembler.bkpt();
2386 m_assembler.nop();
2387 }
2388
2389 Jump branchPtrWithPatch(RelationalCondition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
2390 {
2391 RegisterID dataTempRegister = claimScratch();
2392
81345200 2393 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 10, 2 * sizeof(uint32_t));
14957cd0
A
2394 dataLabel = moveWithPatch(initialRightValue, dataTempRegister);
2395 m_assembler.cmplRegReg(dataTempRegister, left, SH4Condition(cond));
2396 releaseScratch(dataTempRegister);
2397
2398 if (cond == NotEqual)
2399 return branchFalse();
2400 return branchTrue();
2401 }
2402
2403 Jump branchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
2404 {
2405 RegisterID scr = claimScratch();
2406
2407 m_assembler.loadConstant(left.offset, scr);
2408 m_assembler.addlRegReg(left.base, scr);
2409 m_assembler.movlMemReg(scr, scr);
2410 RegisterID scr1 = claimScratch();
81345200 2411 m_assembler.ensureSpace(m_assembler.maxInstructionSize + 10, 2 * sizeof(uint32_t));
14957cd0
A
2412 dataLabel = moveWithPatch(initialRightValue, scr1);
2413 m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond));
2414 releaseScratch(scr);
2415 releaseScratch(scr1);
2416
2417 if (cond == NotEqual)
2418 return branchFalse();
2419 return branchTrue();
2420 }
2421
2422 void ret()
2423 {
2424 m_assembler.ret();
2425 m_assembler.nop();
2426 }
2427
2428 DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
2429 {
2430 RegisterID scr = claimScratch();
2431 DataLabelPtr label = moveWithPatch(initialValue, scr);
2432 store32(scr, address);
2433 releaseScratch(scr);
2434 return label;
2435 }
2436
2437 DataLabelPtr storePtrWithPatch(ImplicitAddress address) { return storePtrWithPatch(TrustedImmPtr(0), address); }
2438
2439 int sizeOfConstantPool()
2440 {
2441 return m_assembler.sizeOfConstantPool();
2442 }
2443
2444 Call tailRecursiveCall()
2445 {
2446 RegisterID scr = claimScratch();
2447
2448 m_assembler.loadConstantUnReusable(0x0, scr, true);
2449 Jump m_jump = Jump(m_assembler.jmp(scr));
2450 releaseScratch(scr);
2451
2452 return Call::fromTailJump(m_jump);
2453 }
2454
2455 Call makeTailRecursiveCall(Jump oldJump)
2456 {
2457 oldJump.link(this);
2458 return tailRecursiveCall();
2459 }
2460
2461 void nop()
2462 {
2463 m_assembler.nop();
2464 }
2465
81345200
A
2466 void memoryFence()
2467 {
2468 m_assembler.synco();
2469 }
2470
6fe7ccc8
A
2471 static FunctionPtr readCallTarget(CodeLocationCall call)
2472 {
2473 return FunctionPtr(reinterpret_cast<void(*)()>(SH4Assembler::readCallTarget(call.dataLocation())));
2474 }
2475
93a37866
A
2476 static void replaceWithJump(CodeLocationLabel instructionStart, CodeLocationLabel destination)
2477 {
2478 SH4Assembler::replaceWithJump(instructionStart.dataLocation(), destination.dataLocation());
2479 }
2480
2481 static ptrdiff_t maxJumpReplacementSize()
2482 {
2483 return SH4Assembler::maxJumpReplacementSize();
2484 }
2485
2486 static bool canJumpReplacePatchableBranchPtrWithPatch() { return false; }
2487
2488 static CodeLocationLabel startOfBranchPtrWithPatchOnRegister(CodeLocationDataLabelPtr label)
2489 {
2490 return label.labelAtOffset(0);
2491 }
2492
81345200 2493 static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID rd, void* initialValue)
93a37866 2494 {
81345200 2495 SH4Assembler::revertJumpReplacementToBranchPtrWithPatch(instructionStart.dataLocation(), rd, reinterpret_cast<int>(initialValue));
93a37866
A
2496 }
2497
2498 static CodeLocationLabel startOfPatchableBranchPtrWithPatchOnAddress(CodeLocationDataLabelPtr)
2499 {
2500 UNREACHABLE_FOR_PLATFORM();
2501 return CodeLocationLabel();
2502 }
2503
81345200 2504 static void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel, Address, void*)
93a37866
A
2505 {
2506 UNREACHABLE_FOR_PLATFORM();
2507 }
2508
14957cd0
A
2509protected:
2510 SH4Assembler::Condition SH4Condition(RelationalCondition cond)
2511 {
2512 return static_cast<SH4Assembler::Condition>(cond);
2513 }
2514
2515 SH4Assembler::Condition SH4Condition(ResultCondition cond)
2516 {
2517 return static_cast<SH4Assembler::Condition>(cond);
2518 }
2519private:
2520 friend class LinkBuffer;
2521 friend class RepatchBuffer;
2522
93a37866
A
2523 static void linkCall(void* code, Call call, FunctionPtr function)
2524 {
2525 SH4Assembler::linkCall(code, call.m_label, function.value());
2526 }
2527
2528 static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
2529 {
2530 SH4Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
2531 }
2532
2533 static void repatchCall(CodeLocationCall call, FunctionPtr destination)
2534 {
2535 SH4Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
2536 }
14957cd0
A
2537};
2538
2539} // namespace JSC
2540
2541#endif // ENABLE(ASSEMBLER)
2542
2543#endif // MacroAssemblerSH4_h