Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: test/cctest/test-assembler-sh4.cc

Issue 11275184: First draft of the sh4 port Base URL: http://github.com/v8/v8.git@master
Patch Set: Use GYP and fixe some typos Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/cctest/cctest.gyp ('k') | test/cctest/test-code-stub-sh4.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "v8.h"
29
30 #include "disassembler.h"
31 #include "factory.h"
32 #include "sh4/constants-sh4.h"
33 #include "sh4/simulator-sh4.h"
34 #include "sh4/assembler-sh4-inl.h"
35 #include "cctest.h"
36
37 using namespace v8::internal;
38
39
40 // Define these function prototypes to match JSEntryFunction in execution.cc.
41 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
42 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
43 typedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4);
44 typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4);
45 typedef Object* (*F5)(double x, double y, int p2, int p3, int p4);
46
47
48 static v8::Persistent<v8::Context> env;
49
50
51 static void InitializeVM() {
52 if (env.IsEmpty()) {
53 env = v8::Context::New();
54 }
55 }
56
57 #define BEGIN() \
58 /* Disable compilation of natives. */ \
59 i::FLAG_disable_native_files = true; \
60 \
61 InitializeVM(); \
62 v8::HandleScope scope; \
63 Assembler assm(Isolate::Current(), NULL, 0);
64
65 #define JIT() \
66 CodeDesc desc; \
67 assm.GetCode(&desc); \
68 Object* code = HEAP->CreateCode( \
69 desc, \
70 Code::ComputeFlags(Code::STUB), \
71 Handle<Object>(HEAP->undefined_value()))->ToObjectChecked(); \
72 CHECK(code->IsCode());
73
74 #define __ assm.
75
76 TEST(0) {
77 BEGIN();
78
79 __ add(r0, r4, r5);
80 __ rts();
81
82 JIT();
83 #ifdef DEBUG
84 Code::cast(code)->Print();
85 #endif
86
87 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
88 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 3, 4, 0, 0, 0));
89 ::printf("f() = %d\n", res);
90 CHECK_EQ(3+4, res);
91 }
92
93 TEST(1) {
94 BEGIN();
95
96 __ add(r0, r4, r5);
97 __ add(r0, r0, Operand(123456789), r4);
98 __ rts();
99
100 JIT();
101 #ifdef DEBUG
102 Code::cast(code)->Print();
103 #endif
104
105 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
106 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 1, -10, 0, 0, 0));
107 ::printf("f() = %d\n", res);
108 CHECK_EQ(1-10+123456789, res);
109 }
110
111 TEST(2) {
112 BEGIN();
113
114 __ add(r0, r4, r5);
115 __ sub(r0, r0, Operand(987654), r4);
116 __ rts();
117
118 JIT();
119 #ifdef DEBUG
120 Code::cast(code)->Print();
121 #endif
122
123 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
124 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 1, -10, 0, 0, 0));
125 ::printf("f() = %d\n", res);
126 CHECK_EQ(1-10-987654, res);
127 }
128
129 TEST(3) {
130 BEGIN();
131
132 __ rsb(r0, r4, r5);
133 __ rsb(r0, r0, Operand(5678), r4);
134 __ rts();
135
136 JIT();
137 #ifdef DEBUG
138 Code::cast(code)->Print();
139 #endif
140
141 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
142 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 5, 123, 0, 0, 0));
143 ::printf("f() = %d\n", res);
144 CHECK_EQ(5678-(123-5), res);
145 }
146
147 TEST(4) {
148 BEGIN();
149
150 __ asl(r0, r4, Operand(17), r1);
151 __ asl(r0, r0, Operand(1));
152 __ rts();
153
154 JIT();
155 #ifdef DEBUG
156 Code::cast(code)->Print();
157 #endif
158
159 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
160 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 42, 0, 0, 0, 0));
161 ::printf("f() = %d\n", res);
162 CHECK_EQ(42<<(17+1), res);
163 }
164
165 TEST(5) {
166 BEGIN();
167
168 __ asr(r1, r4, r5, false, r3);
169 __ asr(r1, r1, Operand(1), r3);
170 __ asr(r4, r4, r5, false, r3);
171 __ asr(r4, r4, Operand(2), r3);
172 __ add(r0, r4, r1);
173 __ rts();
174
175 JIT();
176 #ifdef DEBUG
177 Code::cast(code)->Print();
178 #endif
179
180 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
181 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0x7fecba98, 4,
182 0, 0, 0));
183 ::printf("f() = %d\n", res);
184 CHECK_EQ((0x7fecba98>>(4+1))+(0x7fecba98>>(4+2)), res);
185 }
186
187 TEST(5b) {
188 BEGIN();
189
190 __ asr(r0, r4, r5, false, r3);
191 __ rts();
192
193 JIT();
194 #ifdef DEBUG
195 Code::cast(code)->Print();
196 #endif
197
198 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
199 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 2,
200 0, 0, 0));
201 CHECK_EQ(0, res);
202 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 16, 2,
203 0, 0, 0));
204 CHECK_EQ(4, res);
205 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 16, 32,
206 0, 0, 0));
207 CHECK_EQ(0, res);
208 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, -16, 32,
209 0, 0, 0));
210 CHECK_EQ(-1, res);
211 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0x80000000, 33,
212 0, 0, 0));
213 CHECK_EQ(-1, res);
214 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0x7fffffff, 33,
215 0, 0, 0));
216 CHECK_EQ(0, res);
217 }
218
219 TEST(5c) {
220 BEGIN();
221
222 __ asr(r0, r4, r5, true, r3);
223 __ rts();
224
225 JIT();
226 #ifdef DEBUG
227 Code::cast(code)->Print();
228 #endif
229
230 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
231 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 2,
232 0, 0, 0));
233 CHECK_EQ(0, res);
234 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 16, 2,
235 0, 0, 0));
236 CHECK_EQ(4, res);
237 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 1, 0,
238 0, 0, 0));
239 CHECK_EQ(1, res);
240 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0x80000000, 31,
241 0, 0, 0));
242 CHECK_EQ(-1, res);
243 }
244
245 TEST(6) {
246 BEGIN();
247
248 __ lsl(r0, r4, Operand(14), r1);
249 __ lsl(r0, r0, Operand(1));
250 __ lsl(r4, r0, Operand(2));
251 __ mov(r0, Operand(0));
252 __ add(r4, r4, r0);
253 __ mov(r1, Operand(1));
254 __ lsl(r4, r4, r1);
255 __ lsl(r1, r4, r1);
256 __ mov(r0, r1);
257 __ rts();
258
259 JIT();
260 #ifdef DEBUG
261 Code::cast(code)->Print();
262 #endif
263
264 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
265 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 42, 0, 0, 0, 0));
266 ::printf("f() = %d\n", res);
267 CHECK_EQ(42<<(14+1+2+1+1), res);
268 }
269
270
271 TEST(6b) {
272 BEGIN();
273
274 __ lsl(r0, r4, r5, false, r3);
275 __ rts();
276
277 JIT();
278 #ifdef DEBUG
279 Code::cast(code)->Print();
280 #endif
281
282 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
283 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 2,
284 0, 0, 0));
285 CHECK_EQ(0, res);
286 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 16, 2,
287 0, 0, 0));
288 CHECK_EQ(64, res);
289 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 16, 32,
290 0, 0, 0));
291 CHECK_EQ(0, res);
292 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, -16, 32,
293 0, 0, 0));
294 CHECK_EQ(0, res);
295 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0x80000000, 33,
296 0, 0, 0));
297 CHECK_EQ(0, res);
298 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0x7fffffff, 33,
299 0, 0, 0));
300 CHECK_EQ(0, res);
301 }
302
303
304 TEST(6c) {
305 BEGIN();
306
307 __ lsl(r0, r4, r5, true, r3);
308 __ rts();
309
310 JIT();
311 #ifdef DEBUG
312 Code::cast(code)->Print();
313 #endif
314
315 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
316 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 2,
317 0, 0, 0));
318 CHECK_EQ(0, res);
319 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 16, 2,
320 0, 0, 0));
321 CHECK_EQ(64, res);
322 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 1, 0,
323 0, 0, 0));
324 CHECK_EQ(1, res);
325 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 1, 31,
326 0, 0, 0));
327 CHECK_EQ((1<<31), res);
328 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 1, 32,
329 0, 0, 0));
330 CHECK_EQ(1, res);
331 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 1, 33,
332 0, 0, 0));
333 CHECK_EQ(2, res);
334 }
335
336
337 TEST(7) {
338 BEGIN();
339
340 __ lsr(r0, r4, r5);
341 __ mov(r1, Operand(1));
342 __ lsr(r0, r0, r1, false, r3);
343 __ lsr(r4, r0, Operand(1));
344 __ lsr(r4, r4, Operand(2));
345 __ lsr(r0, r4, Operand(3));
346 __ rts();
347
348 JIT();
349 #ifdef DEBUG
350 Code::cast(code)->Print();
351 #endif
352
353 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
354 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0x7fecba98, 4,
355 0, 0, 0));
356 ::printf("f() = %d\n", res);
357 CHECK_EQ((uint32_t)0x7fecba98>>(4+1+1+2+3), res);
358 }
359
360 TEST(7b) {
361 BEGIN();
362
363 __ lsr(r0, r4, r5, false, r3);
364 __ rts();
365
366 JIT();
367 #ifdef DEBUG
368 Code::cast(code)->Print();
369 #endif
370
371 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
372 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 2,
373 0, 0, 0));
374 CHECK_EQ(0, res);
375 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 16, 2,
376 0, 0, 0));
377 CHECK_EQ(4, res);
378 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 16, 32,
379 0, 0, 0));
380 CHECK_EQ(0, res);
381 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, -16, 32,
382 0, 0, 0));
383 CHECK_EQ(0, res);
384 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0x80000000, 33,
385 0, 0, 0));
386 CHECK_EQ(0, res);
387 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0x7fffffff, 33,
388 0, 0, 0));
389 CHECK_EQ(0, res);
390 }
391
392 TEST(7c) {
393 BEGIN();
394
395 __ lsr(r0, r4, r5, true, r3);
396 __ rts();
397
398 JIT();
399 #ifdef DEBUG
400 Code::cast(code)->Print();
401 #endif
402
403 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
404 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 2,
405 0, 0, 0));
406 CHECK_EQ(0, res);
407 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 16, 2,
408 0, 0, 0));
409 CHECK_EQ(4, res);
410 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 1, 0,
411 0, 0, 0));
412 CHECK_EQ(1, res);
413 res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0x80000000, 31,
414 0, 0, 0));
415 CHECK_EQ(1, res);
416 }
417
418 TEST(8) {
419 BEGIN();
420
421 __ mov(r0, r4);
422 for (int i = 0; i < 10000; i++)
423 __ add(r0, r0, Operand(1));
424 __ rts();
425
426 JIT();
427 #ifdef DEBUG
428 // Code::cast(code)->Print();
429 #endif
430
431 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
432 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 12, 0, 0, 0, 0));
433 ::printf("f() = %d\n", res);
434 CHECK_EQ(10000+12, res);
435 }
436
437 TEST(9) {
438 BEGIN();
439
440 Label top, middle, bottom;
441
442 __ cmpeq(r5, Operand(12), r1);
443 __ bt(&bottom);
444 __ mov(r0, Operand(0));
445 __ rts();
446
447 __ bind(&top);
448 __ mov(r0, r4);
449 __ rts();
450
451 __ bind(&middle);
452 __ add(r4, r4, Operand(1));
453 __ jmp(&top);
454
455 __ bind(&bottom);
456 __ add(r4, r4, Operand(3));
457 __ jmp(&middle);
458
459 JIT();
460 #ifdef DEBUG
461 Code::cast(code)->Print();
462 #endif
463
464 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
465 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 42, 12, 0, 0, 0));
466 ::printf("f() = %d\n", res);
467 CHECK_EQ(42+3+1, res);
468 }
469
470 TEST(10) {
471 BEGIN();
472
473 Label end;
474 __ mov(r0, r4);
475
476 for (int i = 0; i < 2000; i++)
477 __ add(r0, r0, Operand(1));
478 __ cmpeq(r0, Operand(0), r1);
479 __ bt(&end);
480
481 for (int i = 0; i < 2000; i++)
482 __ add(r0, r0, Operand(1));
483 __ cmpeq(r0, Operand(0), r1);
484 __ bt(&end);
485
486 for (int i = 0; i < 2000; i++)
487 __ add(r0, r0, Operand(1));
488 __ cmpeq(r0, Operand(0), r1);
489 __ bf(&end);
490
491 for (int i = 0; i < 2000; i++)
492 __ add(r0, r0, Operand(1));
493
494 __ bind(&end);
495 __ rts();
496
497 JIT();
498 #ifdef DEBUG
499 // Code::cast(code)->Print();
500 #endif
501
502 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
503 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 12, 0, 0, 0, 0));
504 ::printf("f() = %d\n", res);
505 CHECK_EQ(3*2000+12, res);
506 }
507
508
509 TEST(11) {
510 BEGIN();
511
512 Label error;
513
514 __ mov(r0, Operand(0));
515 __ cmpeq(r4, Operand(-27), r1); // true
516 __ bf(&error);
517
518 __ cmpgt(r5, Operand(546), r1); // false
519 __ bt(&error);
520
521 __ cmpgt(r5, Operand(545), r1); // true
522 __ bf(&error);
523
524 __ cmphi(r4, Operand(-27), r1); // false
525 __ bt(&error);
526
527 __ cmphi(r4, Operand(-28), r1); // true
528 __ bf(&error);
529
530 __ cmpge(r5, Operand(546), r1); // true
531 __ bf(&error);
532
533 __ cmpge(r5, Operand(545), r1); // false
534 __ bt(&error);
535
536 __ cmphs(r4, Operand(-27), r1); // true
537 __ bf(&error);
538
539 __ cmphs(r4, Operand(-26), r1); // false
540 __ bt(&error);
541
542 __ mov(r0, Operand(1));
543 __ rts();
544
545 __ bind(&error);
546 __ mov(r0, Operand(1));
547 __ rts();
548
549
550 JIT();
551 #ifdef DEBUG
552 Code::cast(code)->Print();
553 #endif
554
555 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
556 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, -27, 546, 0, 0, 0));
557 ::printf("f() = %d\n", res);
558 CHECK_EQ(1, res);
559 }
560
561 TEST(12) {
562 BEGIN();
563
564 Label error;
565
566 __ pushm(r4.bit() | r5.bit() | r6.bit() | r7.bit());
567 __ popm(r0.bit() | r1.bit() | r2.bit() | r3.bit());
568
569 __ cmpeq(r0, r4);
570 __ bf(&error);
571 __ cmpeq(r1, r5);
572 __ bf(&error);
573 __ cmpeq(r2, r6);
574 __ bf(&error);
575 __ cmpeq(r3, r7);
576 __ bf(&error);
577
578 __ pushm(r4.bit() | r5.bit() | r6.bit() | r7.bit());
579 __ pop(r0);
580 __ pop(r1);
581 __ add(r0, r0, r1);
582
583 __ pop(r1);
584 __ add(r0, r0, r1);
585
586 __ pop(r1);
587 __ add(r0, r0, r1);
588
589 __ rts();
590
591
592 __ bind(&error);
593 __ mov(r0, Operand(0));
594 __ rts();
595
596 JIT();
597 #ifdef DEBUG
598 Code::cast(code)->Print();
599 #endif
600
601 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
602 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 12, 816, 53, 6543, 0));
603 ::printf("f() = %d\n", res);
604 CHECK_EQ(12+816+53+6543, res);
605 }
606
607 TEST(13) {
608 BEGIN();
609
610 Label error;
611
612 __ mov(r0, Operand(2));
613 __ push(r0);
614 __ mov(r0, Operand(3));
615 __ push(r0);
616 __ mov(r0, Operand(5));
617 __ push(r0);
618 __ mov(r0, Operand(7));
619 __ push(r0);
620
621 __ mov(r0, MemOperand(sp, 3 * sizeof(void*)));
622 __ cmpeq(r0, Operand(2), r1);
623 __ bf(&error);
624
625 __ mov(r0, MemOperand(sp, 2 * sizeof(void*)));
626 __ cmpeq(r0, Operand(3), r1);
627 __ bf(&error);
628
629 __ mov(r0, MemOperand(sp, 1 * sizeof(void*)));
630 __ cmpeq(r0, Operand(5), r1);
631 __ bf(&error);
632
633 __ mov(r0, MemOperand(sp, 0 * sizeof(void*)));
634 __ cmpeq(r0, Operand(7), r1);
635 __ bf(&error);
636
637 __ mov(r0, Operand(1));
638 __ pop(r1);
639 __ pop(r1);
640 __ pop(r1);
641 __ pop(r1);
642 __ rts();
643
644 __ bind(&error);
645 __ pop(r1);
646 __ pop(r1);
647 __ pop(r1);
648 __ pop(r1);
649 __ mov(r0, Operand(0));
650 __ rts();
651
652 JIT();
653 #ifdef DEBUG
654 Code::cast(code)->Print();
655 #endif
656
657 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
658 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
659 ::printf("f() = %d\n", res);
660 CHECK_EQ(1, res);
661 }
662
663 TEST(14) {
664 BEGIN();
665
666 Label begin, end;
667
668 __ mov(r0, Operand(0));
669 __ bind(&begin);
670 __ cmpeq(r0, Operand(0), r1);
671 __ bf(&end);
672
673 for (int i = 0; i < 10000; i++)
674 __ add(r0, r0, Operand(1), r1);
675
676 __ jmp(&begin);
677
678 __ bind(&end);
679 __ rts();
680
681 JIT();
682 #ifdef DEBUG
683 // Code::cast(code)->Print();
684 #endif
685
686 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
687 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
688 ::printf("f() = %d\n", res);
689 CHECK_EQ(10000, res);
690 }
691
692 TEST(15) {
693 BEGIN();
694
695 Label error;
696
697 __ mov(r1, Operand(1));
698 __ mov(r4, Operand(2147483647));
699 __ addv(r1, r1, r4); // set the T bit
700 __ bf(&error, r2);
701
702 __ mov(r1, Operand(1));
703 __ mov(r4, Operand(2147483647-1));
704 __ addv(r1, r4, r1); // does not set the T bit
705 __ bt(&error, r2);
706
707 __ mov(r1, Operand(1));
708 __ mov(r4, Operand(0));
709 __ addv(r0, r1, r4); // does not set the T bit
710 __ bt(&error, r2);
711
712
713 __ mov(r1, Operand(1));
714 __ mov(r4, Operand(-2147483647-1));
715 __ subv(r1, r4, r1); // set the T bit
716 __ bf(&error, r2);
717
718 __ mov(r1, Operand(1));
719 __ mov(r4, Operand(-2147483647));
720 __ subv(r1, r4, r1); // does not set the T bit
721 __ bt(&error, r2);
722
723 __ mov(r1, Operand(1));
724 __ mov(r4, Operand(0));
725 __ subv(r0, r1, r4); // does not set the T bit
726 __ bt(&error, r2);
727
728
729 __ mov(r0, Operand(1));
730 __ rts();
731
732 __ bind(&error);
733 __ mov(r0, Operand(0));
734 __ rts();
735
736 JIT();
737 #ifdef DEBUG
738 Code::cast(code)->Print();
739 #endif
740
741 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
742
743 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
744 ::printf("f() = %d\n", res);
745 CHECK_EQ(1, res);
746 }
747
748 // This macro stores in r10 the line number before branching to the error label.
749 // At the error label r10 can be moved to r0 such that return code of the
750 // function if not 0 indicates an error at the line of the branch.
751 #define B_LINE(cond, target) do { \
752 __ mov(r10, Operand(__LINE__)); \
753 __ b(cond, target); \
754 } while (0);
755
756 // Saves sh4_rtmp (r11) and sh4_ip (r10) which are calle saved
757 #define PROLOGUE() \
758 __ push(r10); __ push(r11)
759 #define EPILOGUE() \
760 __ pop(r11); __ pop(r10)
761
762 // Test logical and, or, xor
763 TEST(16) {
764 BEGIN();
765
766 Label error;
767
768 PROLOGUE();
769
770 __ mov(r1, Operand(0x00ff00ff));
771 __ land(r1, r1, Operand(0xff00ff00), r2);
772 __ cmpeq(r1, Operand(0)); // true
773 B_LINE(f, &error);
774
775 __ mov(r1, Operand(0x00ffff00));
776 __ land(r1, r1, Operand(0xff00ff00));
777 __ cmpeq(r1, Operand(0x0000ff00)); // true
778 B_LINE(f, &error);
779
780 __ mov(r0, Operand(0xff));
781 __ land(r0, r0, Operand(0x0f));
782 __ cmpeq(r0, Operand(0x0f)); // true
783 B_LINE(f, &error);
784
785 __ mov(r1, Operand(0x0f0));
786 __ mov(r2, Operand(0xfff));
787 __ land(r3, r1, r2);
788 __ cmpeq(r3, Operand(0x0f0)); // true
789 B_LINE(f, &error);
790
791 __ land(r1, r1, r2); // left auto-modifying
792 __ cmpeq(r1, Operand(0x0f0)); // true
793 B_LINE(f, &error);
794
795
796 __ mov(r1, Operand(0x0f0));
797 __ land(r1, r2, r1); // right auto-modifying
798 __ cmpeq(r1, Operand(0x0f0)); // true
799 B_LINE(f, &error);
800
801
802 __ mov(r1, Operand(0x00ff00ff));
803 __ lor(r1, r1, Operand(0xff00ff00));
804 __ cmpeq(r1, Operand(0xffffffff)); // true
805 B_LINE(f, &error);
806
807 __ mov(r1, Operand(0x00ffff00));
808 __ lor(r1, r1, Operand(0xff00ff00));
809 __ cmpeq(r1, Operand(0xffffff00)); // true
810 B_LINE(f, &error);
811
812 __ mov(r0, Operand(0xf0));
813 __ lor(r0, r0, Operand(0x0e));
814 __ cmpeq(r0, Operand(0xfe)); // true
815 B_LINE(f, &error);
816
817 __ mov(r1, Operand(0x0f0));
818 __ mov(r2, Operand(0xf12));
819 __ lor(r3, r1, r2);
820 __ cmpeq(r3, Operand(0xff2)); // true
821 B_LINE(f, &error);
822
823 __ lor(r1, r1, r2); // left auto-modifying
824 __ cmpeq(r1, Operand(0xff2)); // true
825 B_LINE(f, &error);
826
827 __ mov(r1, Operand(0x0f0));
828 __ lor(r1, r2, r1); // right auto-modifying
829 __ cmpeq(r1, Operand(0xff2)); // true
830 B_LINE(f, &error);
831
832
833 __ mov(r1, Operand(0xffffffff));
834 __ lxor(r1, r1, Operand(0xff00ff00));
835 __ cmpeq(r1, Operand(0x00ff00ff)); // true
836 B_LINE(f, &error);
837
838 __ mov(r0, Operand(0xff));
839 __ lxor(r0, r0, Operand(0x0e));
840 __ cmpeq(r0, Operand(0xf1)); // true
841 B_LINE(f, &error);
842
843 __ mov(r1, Operand(0xff));
844 __ mov(r2, Operand(0x0f));
845 __ lxor(r3, r1, r2);
846 __ cmpeq(r3, Operand(0xf0)); // true
847 B_LINE(f, &error);
848
849 __ lxor(r1, r1, r2); // left auto-modifying
850 __ cmpeq(r1, Operand(0xf0)); // true
851 B_LINE(f, &error);
852
853 __ mov(r1, Operand(0x0ff));
854 __ lxor(r1, r2, r1); // right auto-modifying
855 __ cmpeq(r1, Operand(0xf0)); // true
856 B_LINE(f, &error);
857
858 __ mov(r1, Operand(0x0ff));
859 __ mov(r2, Operand(0x040));
860 __ bic(r1, r1, r2);
861 __ cmpeq(r1, Operand(0xbf)); // true
862 B_LINE(f, &error);
863 __ bic(r0, r1, Operand(0x80));
864 __ cmpeq(r0, Operand(0x3f)); // true
865 B_LINE(f, &error);
866
867 // All ok.
868 __ mov(r0, Operand(0));
869 EPILOGUE();
870 __ rts();
871
872 __ bind(&error);
873 __ mov(r0, r10);
874 EPILOGUE();
875 __ rts();
876
877 JIT();
878 #ifdef DEBUG
879 Code::cast(code)->Print();
880 #endif
881
882 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
883
884 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
885 ::printf("f() = %d\n", res);
886 CHECK_EQ(0, res);
887 }
888
889
890 // Test conditional moves
891 TEST(17) {
892 BEGIN();
893
894 Label error;
895
896 PROLOGUE();
897 __ mov(r0, Operand(0));
898 __ mov(r1, Operand(0));
899 __ mov(r2, Operand(0));
900 __ tst(r0, r0);
901 __ mov(r1, Operand(1), eq);
902 __ mov(r2, Operand(1), ne);
903 __ cmpeq(r1, Operand(1));
904 B_LINE(f, &error);
905 __ cmpeq(r2, Operand(0));
906 B_LINE(f, &error);
907
908 __ mov(r0, Operand(1));
909 __ mov(r1, Operand(0));
910 __ mov(r2, Operand(0));
911 __ tst(r0, r0);
912 __ mov(r1, Operand(1), eq);
913 __ mov(r2, Operand(1), ne);
914 __ cmpeq(r1, Operand(0));
915 B_LINE(f, &error);
916 __ cmpeq(r2, Operand(1));
917 B_LINE(f, &error);
918
919 __ mov(r0, Operand(0));
920 __ mov(r1, Operand(0));
921 __ mov(r2, Operand(0));
922 __ tst(r0, r0);
923 __ mov(r1, Operand(0xffff), eq);
924 __ mov(r2, Operand(0xffff), ne);
925 __ cmpeq(r1, Operand(0xffff));
926 B_LINE(f, &error);
927 __ cmpeq(r2, Operand(0));
928 B_LINE(f, &error);
929
930 __ mov(r0, Operand(1));
931 __ mov(r1, Operand(0));
932 __ mov(r2, Operand(0));
933 __ tst(r0, r0);
934 __ mov(r1, Operand(0xffff), eq);
935 __ mov(r2, Operand(0xffff), ne);
936 __ cmpeq(r1, Operand(0));
937 B_LINE(f, &error);
938 __ cmpeq(r2, Operand(0xffff));
939 B_LINE(f, &error);
940
941 __ mov(r0, Operand(0));
942 __ mov(r1, Operand(0));
943 __ mov(r2, Operand(0));
944 __ mov(r3, Operand(1));
945 __ tst(r0, r0);
946 __ mov(r1, r3, eq);
947 __ mov(r2, r3, ne);
948 __ cmpeq(r1, Operand(1));
949 B_LINE(f, &error);
950 __ cmpeq(r2, Operand(0));
951 B_LINE(f, &error);
952
953 // All ok.
954 __ mov(r0, Operand(0));
955 EPILOGUE();
956 __ rts();
957
958 __ bind(&error);
959 __ mov(r0, r10);
960 EPILOGUE();
961 __ rts();
962
963 JIT();
964 #ifdef DEBUG
965 Code::cast(code)->Print();
966 #endif
967
968 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
969
970 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
971 ::printf("f() = %d\n", res);
972 CHECK_EQ(0, res);
973 }
974
975
976 // Test addc/subc
977 TEST(18) {
978 BEGIN();
979
980 Label error;
981
982 PROLOGUE();
983 __ mov(r0, Operand(0xFFFFFFFE));
984 __ mov(r1, Operand(1));
985 __ addc(r2, r0, r1);
986 B_LINE(t, &error); // check that carry is clear
987 __ cmpeq(r2, Operand(0xFFFFFFFF));
988 B_LINE(f, &error);
989
990 __ addc(r1, r1, r0); // left auto-modified
991 B_LINE(t, &error);
992 __ cmpeq(r1, Operand(0xFFFFFFFF));
993 B_LINE(f, &error);
994
995 __ mov(r1, Operand(1));
996 __ addc(r1, r0, r1); // right auto-modified
997 B_LINE(t, &error);
998 __ cmpeq(r1, Operand(0xFFFFFFFF));
999 B_LINE(f, &error);
1000
1001 __ mov(r0, Operand(0xFFFFFFFF));
1002 __ mov(r1, Operand(1));
1003 __ addc(r2, r0, r1);
1004 B_LINE(f, &error); // check that carry is set
1005 __ cmpeq(r2, Operand(0));
1006 B_LINE(f, &error);
1007
1008 __ addc(r1, r1, r0); // left auto-modified
1009 B_LINE(f, &error);
1010 __ cmpeq(r1, Operand(0));
1011 B_LINE(f, &error);
1012
1013 __ mov(r1, Operand(1));
1014 __ addc(r1, r0, r1); // right auto-modified
1015 B_LINE(f, &error);
1016 __ cmpeq(r1, Operand(0));
1017 B_LINE(f, &error);
1018
1019 __ mov(r0, Operand(1));
1020 __ mov(r1, Operand(1));
1021 __ subc(r2, r0, r1);
1022 B_LINE(t, &error); // check that carry is clear
1023 __ cmpeq(r2, Operand(0));
1024 B_LINE(f, &error);
1025
1026 __ subc(r0, r0, r1); // left auto-modified
1027 B_LINE(t, &error);
1028 __ cmpeq(r0, Operand(0));
1029 B_LINE(f, &error);
1030
1031 __ mov(r0, Operand(1));
1032 __ subc(r1, r0, r1); // right auto-modified
1033 B_LINE(t, &error);
1034 __ cmpeq(r1, Operand(0));
1035 B_LINE(f, &error);
1036
1037 __ mov(r0, Operand(0));
1038 __ mov(r1, Operand(1));
1039 __ subc(r2, r0, r1);
1040 B_LINE(f, &error); // check that carry is set
1041 __ cmpeq(r2, Operand(-1));
1042 B_LINE(f, &error);
1043
1044 __ subc(r0, r0, r1); // left auto-modified
1045 B_LINE(f, &error);
1046 __ cmpeq(r0, Operand(-1));
1047 B_LINE(f, &error);
1048
1049 __ mov(r0, Operand(0));
1050 __ subc(r1, r0, r1); // right auto-modified
1051 B_LINE(f, &error);
1052 __ cmpeq(r1, Operand(-1));
1053 B_LINE(f, &error);
1054
1055 // All ok.
1056 __ mov(r0, Operand(0));
1057 EPILOGUE();
1058 __ rts();
1059
1060 __ bind(&error);
1061 __ mov(r0, r10);
1062 EPILOGUE();
1063 __ rts();
1064
1065 JIT();
1066 #ifdef DEBUG
1067 Code::cast(code)->Print();
1068 #endif
1069
1070 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
1071
1072 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
1073 ::printf("f() = %d\n", res);
1074 CHECK_EQ(0, res);
1075 }
1076
1077 // Test addv/subv
1078 TEST(19) {
1079 BEGIN();
1080
1081 Label error;
1082
1083 PROLOGUE();
1084 __ mov(r0, Operand(0x7FFFFFFE));
1085 __ mov(r1, Operand(1));
1086 __ addv(r2, r0, r1);
1087 B_LINE(t, &error); // check that overflow is clear
1088 __ cmpeq(r2, Operand(0x7FFFFFFF));
1089 B_LINE(f, &error);
1090
1091 __ addv(r1, r1, r0); // left auto-modified
1092 B_LINE(t, &error);
1093 __ cmpeq(r1, Operand(0x7FFFFFFF));
1094 B_LINE(f, &error);
1095
1096 __ mov(r1, Operand(1));
1097 __ addv(r1, r0, r1); // right auto-modified
1098 B_LINE(t, &error);
1099 __ cmpeq(r1, Operand(0x7FFFFFFF));
1100 B_LINE(f, &error);
1101
1102 __ mov(r0, Operand(0x7FFFFFFF));
1103 __ mov(r1, Operand(1));
1104 __ addv(r2, r0, r1);
1105 B_LINE(f, &error); // check that overflow is set
1106 __ cmpeq(r2, Operand(0x80000000));
1107 B_LINE(f, &error);
1108
1109 __ addv(r1, r1, r0); // left auto-modified
1110 B_LINE(f, &error);
1111 __ cmpeq(r1, Operand(0x80000000));
1112 B_LINE(f, &error);
1113
1114 __ mov(r1, Operand(1));
1115 __ addv(r1, r0, r1); // right auto-modified
1116 B_LINE(f, &error);
1117 __ cmpeq(r1, Operand(0x80000000));
1118 B_LINE(f, &error);
1119
1120 __ mov(r0, Operand(0x80000001));
1121 __ mov(r1, Operand(1));
1122 __ subv(r2, r0, r1);
1123 B_LINE(t, &error); // check that overflow is clear
1124 __ cmpeq(r2, Operand(0x80000000));
1125 B_LINE(f, &error);
1126
1127 __ subv(r0, r0, r1); // left auto-modified
1128 B_LINE(t, &error);
1129 __ cmpeq(r0, Operand(0x80000000));
1130 B_LINE(f, &error);
1131
1132 __ mov(r0, Operand(0x80000001));
1133 __ subv(r1, r0, r1); // right auto-modified
1134 B_LINE(t, &error);
1135 __ cmpeq(r1, Operand(0x80000000));
1136 B_LINE(f, &error);
1137
1138 __ mov(r0, Operand(0x80000000));
1139 __ mov(r1, Operand(1));
1140 __ subv(r2, r0, r1);
1141 B_LINE(f, &error); // check that carry is set
1142 __ cmpeq(r2, Operand(0x7FFFFFFF));
1143 B_LINE(f, &error);
1144
1145 __ subv(r0, r0, r1); // left auto-modified
1146 B_LINE(f, &error);
1147 __ cmpeq(r0, Operand(0x7FFFFFFF));
1148 B_LINE(f, &error);
1149
1150 __ mov(r0, Operand(0x80000000));
1151 __ subv(r1, r0, r1); // right auto-modified
1152 B_LINE(f, &error);
1153 __ cmpeq(r1, Operand(0x7FFFFFFF));
1154 B_LINE(f, &error);
1155
1156 // All ok.
1157 __ mov(r0, Operand(0));
1158 EPILOGUE();
1159 __ rts();
1160
1161 __ bind(&error);
1162 __ mov(r0, r10);
1163 EPILOGUE();
1164 __ rts();
1165
1166 JIT();
1167 #ifdef DEBUG
1168 Code::cast(code)->Print();
1169 #endif
1170
1171 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
1172
1173 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
1174 ::printf("f() = %d\n", res);
1175 CHECK_EQ(0, res);
1176 }
1177
1178 TEST(20) {
1179 BEGIN();
1180
1181 Label error;
1182 Condition cond;
1183
1184 PROLOGUE();
1185 cond = eq;
1186 __ cmp(&cond, r4, Operand(0), r0);
1187 CHECK_EQ(eq, cond);
1188 B_LINE(cond, &error);
1189
1190 cond = ge;
1191 __ cmp(&cond, r4, Operand(0), r0);
1192 CHECK_EQ(eq, cond);
1193 B_LINE(f, &error);
1194
1195 cond = lt;
1196 __ cmp(&cond, r4, Operand(654), r0);
1197 CHECK_EQ(ne, cond);
1198 B_LINE(t, &error);
1199
1200 __ mov(r0, Operand(0));
1201 EPILOGUE();
1202 __ rts();
1203
1204 __ bind(&error);
1205 __ mov(r0, r10);
1206 EPILOGUE();
1207 __ rts();
1208
1209 JIT();
1210
1211 #ifdef DEBUG
1212 Code::cast(code)->Print();
1213 #endif
1214
1215 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
1216
1217 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 456, 0, 0, 0, 0));
1218 ::printf("f() = %d\n", res);
1219 CHECK_EQ(0, res);
1220 }
1221
1222 // test storing uint8 value in the cmp immediate
1223 TEST(21) {
1224 BEGIN();
1225
1226 Label top;
1227 __ bind(&top);
1228 __ cmpeq(r0, r1);
1229 __ cmpgt(r0, r1);
1230 // > 127, ie. would normally exceed signed range
1231 __ cmpeq_r0_unsigned_imm(173);
1232 __ bt(&top);
1233 __ bf(&top);
1234 __ mov(r0, Operand(12));
1235
1236 JIT();
1237 #ifdef DEBUG
1238 Code::cast(code)->Print();
1239 #endif
1240
1241 CHECK_EQ(true, __ IsCmpRegister((reinterpret_cast<Instr*>(desc.buffer)[0])));
1242 CHECK_EQ(false, __ IsCmpRegister((reinterpret_cast<Instr*>(desc.buffer)[1])));
1243
1244 CHECK_EQ(false, __ IsCmpImmediate(reinterpret_cast<Instr*>(desc.buffer)[1]));
1245 CHECK_EQ(true, __ IsCmpImmediate(reinterpret_cast<Instr*>(desc.buffer)[2]));
1246 CHECK_EQ(true, (__ GetCmpImmediateRegister(
1247 reinterpret_cast<Instr*>(desc.buffer)[2])).is(r0));
1248 CHECK_EQ(173, __ GetCmpImmediateAsUnsigned(
1249 reinterpret_cast<Instr*>(desc.buffer)[2]));
1250
1251 CHECK_EQ(true, (__ GetRn((reinterpret_cast<Instr*>(desc.buffer)[0])).is(r0)));
1252 CHECK_EQ(true, (__ GetRm((reinterpret_cast<Instr*>(desc.buffer)[0])).is(r1)));
1253
1254 // __ bt() generate bt/nop
1255 CHECK_EQ(eq, __ GetCondition((reinterpret_cast<Instr*>(desc.buffer)[3])));
1256 CHECK_EQ(ne, __ GetCondition((reinterpret_cast<Instr*>(desc.buffer)[5])));
1257
1258 CHECK_EQ(true, __ IsMovImmediate(reinterpret_cast<Instr*>(desc.buffer)[7]));
1259 }
1260
1261 TEST(22) {
1262 BEGIN();
1263
1264 Label function, end_function;
1265
1266 __ mov(r5, Operand(1));
1267 __ mov(r0, r4);
1268 __ add(r0, Operand(1), r1);
1269 __ push(pr);
1270 __ jsr(&function);
1271 __ pop(pr);
1272 __ rts();
1273
1274 __ bind(&function);
1275 __ add(r0, Operand(1), r1);
1276 __ add(r0, Operand(2), r1);
1277 __ add(r0, Operand(3), r1);
1278 __ add(r0, Operand(4), r1);
1279 __ cmpeq(r5, Operand(0), r1);
1280 __ bt(&end_function);
1281 __ mov(r5, Operand(0));
1282 __ push(pr);
1283 __ jsr(&function);
1284 __ pop(pr);
1285
1286 __ bind(&end_function);
1287 __ rts();
1288
1289 JIT();
1290
1291 #ifdef DEBUG
1292 Code::cast(code)->Print();
1293 #endif
1294
1295 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
1296
1297 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 53, 0, 0, 0, 0));
1298 ::printf("f() = %d\n", res);
1299 CHECK_EQ(53+1+(1+2+3+4)*2, res);
1300 }
1301
1302 TEST(22_bis) {
1303 BEGIN();
1304
1305 Label function, label;
1306
1307 __ mov(r0, Operand(0));
1308 __ bind(&function);
1309 __ tst(r0, r0);
1310 __ bt(&label);
1311 __ rts();
1312 __ bind(&label);
1313 for (int i = 0; i < 10000; i++)
1314 __ add(r0, r0, Operand(1), r1);
1315
1316 __ push(pr);
1317 __ jsr(&function);
1318 __ pop(pr);
1319 __ rts();
1320
1321 JIT();
1322
1323 #ifdef DEBUG
1324 // Code::cast(code)->Print();
1325 #endif
1326
1327 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
1328
1329 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
1330 ::printf("f() = %d\n", res);
1331 CHECK_EQ(10000, res);
1332 }
1333
1334 TEST(23) {
1335 BEGIN();
1336 Label error;
1337
1338 __ mov(r0, Operand(0));
1339 __ cmpeq(r0, Operand(0), r4);
1340 __ mov(r1, Operand(0x00ff00ff));
1341 __ mov(r2, Operand(0xff00ff00));
1342 __ lor(r1, r1, r2, eq);
1343 __ cmpeq(r1, Operand(0xffffffff));
1344 __ bf(&error);
1345
1346 __ cmpeq(r0, Operand(0), r4);
1347 __ mov(r1, Operand(0x0000ff00));
1348 __ mov(r2, Operand(0x000000ff));
1349 __ lor(r1, r1, r2, ne);
1350 __ cmpeq(r1, Operand(0x0000ff00), r4);
1351 __ bf(&error);
1352
1353 __ mov(r0, Operand(0));
1354 __ cmpeq(r0, Operand(0), r4);
1355 __ mov(r1, Operand(0xffff00ff));
1356 __ lor(r1, r1, Operand(0xffffeeff), eq, r2);
1357 __ cmpeq(r1, Operand(0xffffeeff), r2);
1358 __ bf(&error);
1359
1360 __ cmpeq(r0, Operand(0), r4);
1361 __ mov(r1, Operand(0x0000ff00));
1362 __ lor(r1, r1, Operand(0x000000ff), ne, r2);
1363 __ cmpeq(r1, Operand(0x0000ff00), r2);
1364 __ bf(&error);
1365
1366
1367 __ mov(r0, Operand(0));
1368 __ rts();
1369
1370 __ bind(&error);
1371 __ mov(r0, Operand(1));
1372 __ rts();
1373
1374 JIT();
1375
1376 #ifdef DEBUG
1377 Code::cast(code)->Print();
1378 #endif
1379
1380 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
1381
1382 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
1383 ::printf("f() = %d\n", res);
1384 CHECK_EQ(0, res);
1385 }
1386
1387 TEST(24) {
1388 BEGIN();
1389
1390 Label error;
1391
1392 __ dmuls(r1, r0, r4, r5);
1393 __ cmpeq(r0, r6);
1394 __ bf(&error);
1395 __ cmpeq(r1, r7);
1396 __ bf(&error);
1397
1398 __ mov(r0, Operand(0));
1399 __ rts();
1400
1401 __ bind(&error);
1402 __ mov(r0, Operand(1));
1403
1404 JIT();
1405 #ifdef DEBUG
1406 Code::cast(code)->Print();
1407 #endif
1408
1409 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
1410 CHECK_EQ(0, reinterpret_cast<int>(CALL_GENERATED_CODE(f, 2, 0, 0, 0, 0)));
1411 CHECK_EQ(0, reinterpret_cast<int>(CALL_GENERATED_CODE(f, 3, 4, 0, 12, 0)));
1412 CHECK_EQ(0, reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 45, 0, 10*45,
1413 0)));
1414 CHECK_EQ(0, reinterpret_cast<int>(
1415 CALL_GENERATED_CODE(f, 1000000000, 10000, 2328,
1416 1316134912, 0)));
1417 CHECK_EQ(0, reinterpret_cast<int>(
1418 CALL_GENERATED_CODE(f, 123465879, 123465780, 3549226,
1419 1458007724, 0)));
1420 CHECK_EQ(0, reinterpret_cast<int>(
1421 CALL_GENERATED_CODE(f, 13246579, 0, 0, 0, 0)));
1422 }
1423
1424 TEST(25) {
1425 BEGIN();
1426
1427 Label function;
1428
1429 __ mov(r0, Operand(0));
1430 __ push(pr);
1431
1432 __ call(&function);
1433 __ add(r0, r0, Operand(1), r2);
1434 __ add(r0, r0, Operand(1), r2);
1435 __ add(r0, r0, Operand(1), r2);
1436 __ add(r0, r0, Operand(1), r2);
1437
1438 __ pop(pr);
1439 __ rts();
1440
1441 __ bind(&function);
1442 // return to the second add (skiping the one just after the call)
1443 __ strpr(r1);
1444 __ add(r1, r1, Operand(10), r2);
1445 __ ldrpr(r1);
1446 __ add(r0, r0, Operand(1), r2);
1447 __ rts();
1448
1449 JIT();
1450 #ifdef DEBUG
1451 Code::cast(code)->Print();
1452 #endif
1453
1454 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
1455 CHECK_EQ(4, reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)));
1456 }
1457
1458 TEST(26) {
1459 CHECK_EQ(0, strcmp(Registers::Name(1), "r1"));
1460 CHECK_EQ(0, strcmp(Registers::Name(10), "r10"));
1461 CHECK_EQ(0, strcmp(Registers::Name(15), "r15"));
1462 CHECK_EQ(0, strcmp(Registers::Name(16), "noreg"));
1463
1464 CHECK_EQ(0, Registers::Number("r0"));
1465 CHECK_EQ(5, Registers::Number("r5"));
1466 CHECK_EQ(14, Registers::Number("r14"));
1467 CHECK_EQ(15, Registers::Number("r15"));
1468 CHECK_EQ(14, Registers::Number("fp"));
1469 CHECK_EQ(15, Registers::Number("sp"));
1470 CHECK_EQ(kNoRegister, Registers::Number("r16"));
1471 }
1472
1473
1474 // Test load/store operations
1475 TEST(27) {
1476 BEGIN();
1477
1478 Label error;
1479
1480 PROLOGUE();
1481 __ mov(r3, sp);
1482 __ sub(sp, sp, Operand(16));
1483
1484 // Test str/ldr
1485 __ mov(r1, Operand(3));
1486 __ str(r1, MemOperand(sp, 0));
1487 __ mov(r1, Operand(7));
1488 __ mov(r2, Operand(4));
1489 __ str(r1, MemOperand(sp, r2));
1490 __ mov(r1, Operand(9));
1491 __ str(r1, MemOperand(sp, 8));
1492 __ mov(r0, Operand(0xdeadbeef));
1493 __ ldr(r0, MemOperand(sp, 0));
1494 __ cmpeq(r0, Operand(3));
1495 B_LINE(f, &error);
1496 __ mov(r0, Operand(0xdeadbeef));
1497 __ ldr(r0, MemOperand(sp, r2));
1498 __ cmpeq(r0, Operand(7));
1499 B_LINE(f, &error);
1500 __ mov(r0, Operand(0xdeadbeef));
1501 __ ldr(r0, MemOperand(sp, 8));
1502 __ cmpeq(r0, Operand(9));
1503 B_LINE(f, &error);
1504
1505 // Test strh/ldrh/ldrsh
1506 __ mov(r1, Operand(3));
1507 __ strh(r1, MemOperand(sp, 0));
1508 __ mov(r1, Operand(0xff07));
1509 __ strh(r1, MemOperand(sp, 2));
1510 __ mov(r2, Operand(4));
1511 __ mov(r1, Operand(0x09));
1512 __ strh(r1, MemOperand(sp, r2));
1513 __ mov(r0, Operand(0xdeadbeef));
1514 __ ldr(r0, MemOperand(sp, 0));
1515 __ cmpeq(r0, Operand(0xff070003));
1516 B_LINE(f, &error);
1517 __ mov(r0, Operand(0xdeadbeef));
1518 __ ldrh(r0, MemOperand(sp, 0));
1519 __ cmpeq(r0, Operand(0x03));
1520 B_LINE(f, &error);
1521 __ mov(r0, Operand(0xdeadbeef));
1522 __ ldrh(r0, MemOperand(sp, 2));
1523 __ cmpeq(r0, Operand(0xff07));
1524 B_LINE(f, &error);
1525 __ mov(r0, Operand(0xdeadbeef));
1526 __ ldrh(r0, MemOperand(sp, r2));
1527 __ cmpeq(r0, Operand(0x09));
1528 B_LINE(f, &error);
1529 __ mov(r0, Operand(0xdeadbeef));
1530 __ ldrsh(r0, MemOperand(sp, 2));
1531 __ cmpeq(r0, Operand(0xffffff07));
1532 B_LINE(f, &error);
1533
1534 // Test strb/ldrb
1535 __ mov(r1, Operand(3));
1536 __ strb(r1, MemOperand(sp, 0));
1537 __ mov(r1, Operand(0xf7));
1538 __ mov(r2, Operand(1));
1539 __ strb(r1, MemOperand(sp, r2));
1540 __ mov(r1, Operand(5));
1541 __ strb(r1, MemOperand(sp, 2));
1542 __ mov(r1, Operand(1));
1543 __ strb(r1, MemOperand(sp, 3));
1544 __ mov(r0, Operand(0xdeadbeef));
1545 __ ldr(r0, MemOperand(sp, 0));
1546 __ cmpeq(r0, Operand(0x0105f703));
1547 B_LINE(f, &error);
1548 __ mov(r0, Operand(0xdeadbeef));
1549 __ ldrb(r0, MemOperand(sp, 0));
1550 __ cmpeq(r0, Operand(0x03));
1551 B_LINE(f, &error);
1552 __ mov(r0, Operand(0xdeadbeef));
1553 __ ldrb(r0, MemOperand(sp, r2));
1554 __ cmpeq(r0, Operand(0xf7));
1555 B_LINE(f, &error);
1556 __ mov(r0, Operand(0xdeadbeef));
1557 __ ldrb(r0, MemOperand(sp, 2));
1558 __ cmpeq(r0, Operand(0x05));
1559 B_LINE(f, &error);
1560 __ mov(r0, Operand(0xdeadbeef));
1561 __ ldrsb(r0, MemOperand(sp, 1));
1562 __ cmpeq(r0, Operand(0xfffffff7));
1563 B_LINE(f, &error);
1564
1565
1566 // Test ldr/str with Pre/post Index
1567 __ mov(r1, Operand(3));
1568 __ str(r1, MemOperand(sp, 0));
1569 __ mov(r1, Operand(7));
1570 __ str(r1, MemOperand(sp, 4));
1571 __ mov(r1, Operand(9));
1572 __ str(r1, MemOperand(sp, 8));
1573
1574 __ mov(r2, sp);
1575 __ ldr(r0, MemOperand(r2, 0, PostIndex));
1576 __ cmpeq(r0, Operand(3));
1577 B_LINE(f, &error);
1578 __ cmpeq(r2, sp);
1579 B_LINE(f, &error);
1580
1581 __ ldr(r0, MemOperand(r2, 4, PostIndex));
1582 __ cmpeq(r0, Operand(3));
1583 B_LINE(f, &error);
1584 __ add(r1, sp, Operand(4));
1585 __ cmpeq(r1, r2);
1586 B_LINE(f, &error);
1587
1588 __ ldr(r0, MemOperand(r2, 4, PostIndex));
1589 __ cmpeq(r0, Operand(7));
1590 B_LINE(f, &error);
1591 __ add(r1, sp, Operand(8));
1592 __ cmpeq(r1, r2);
1593 B_LINE(f, &error);
1594
1595 __ ldr(r0, MemOperand(r2, 4, PostIndex));
1596 __ cmpeq(r0, Operand(9));
1597 B_LINE(f, &error);
1598 __ add(r1, sp, Operand(12));
1599 __ cmpeq(r1, r2);
1600 B_LINE(f, &error);
1601
1602 __ sub(r2, sp, Operand(4));
1603 __ ldr(r0, MemOperand(r2, 4, PreIndex));
1604 __ cmpeq(r0, Operand(3));
1605 B_LINE(f, &error);
1606 __ cmpeq(sp, r2);
1607 B_LINE(f, &error);
1608
1609 __ ldr(r0, MemOperand(r2, 4, PreIndex));
1610 __ cmpeq(r0, Operand(7));
1611 B_LINE(f, &error);
1612 __ add(r1, sp, Operand(4));
1613 __ cmpeq(r1, r2);
1614 B_LINE(f, &error);
1615
1616 __ ldr(r0, MemOperand(r2, 4, PreIndex));
1617 __ cmpeq(r0, Operand(9));
1618 B_LINE(f, &error);
1619 __ add(r1, sp, Operand(8));
1620 __ cmpeq(r1, r2);
1621 B_LINE(f, &error);
1622
1623
1624 __ mov(r2, sp);
1625 __ mov(r1, Operand(4212));
1626 __ str(r1, MemOperand(r2, 4, PostIndex));
1627 __ mov(r1, Operand(1234));
1628 __ str(r1, MemOperand(r2, 4, PostIndex));
1629 __ add(r1, sp, Operand(8));
1630 __ cmpeq(r1, r2);
1631 B_LINE(f, &error);
1632
1633 __ mov(r2, sp);
1634 __ ldr(r1, MemOperand(r2, 4, PostIndex));
1635 __ cmpeq(r1, Operand(4212));
1636 B_LINE(f, &error);
1637 __ ldr(r1, MemOperand(r2, 4, PostIndex));
1638 __ cmpeq(r1, Operand(1234));
1639 B_LINE(f, &error);
1640 __ add(r1, sp, Operand(8));
1641 __ cmpeq(r1, r2);
1642 B_LINE(f, &error);
1643
1644 __ mov(r2, sp);
1645 __ mov(r1, Operand(98765));
1646 __ str(r1, MemOperand(r2, 4, PreIndex));
1647 __ mov(r1, Operand(0));
1648 __ str(r1, MemOperand(r2, 4, PreIndex));
1649 __ add(r1, sp, Operand(8));
1650 __ cmpeq(r1, r2);
1651 B_LINE(f, &error);
1652
1653 __ mov(r2, sp);
1654 __ ldr(r1, MemOperand(r2));
1655 __ cmpeq(r1, Operand(4212));
1656 B_LINE(f, &error);
1657 __ ldr(r1, MemOperand(r2, 4, PreIndex));
1658 __ cmpeq(r1, Operand(98765));
1659 B_LINE(f, &error);
1660 __ ldr(r1, MemOperand(r2, 4, PreIndex));
1661 __ cmpeq(r1, Operand(0));
1662 B_LINE(f, &error);
1663 __ add(r1, sp, Operand(8));
1664 __ cmpeq(r1, r2);
1665 B_LINE(f, &error);
1666
1667
1668 // All ok.
1669 __ mov(sp, r3);
1670 __ mov(r0, Operand(0));
1671 EPILOGUE();
1672 __ rts();
1673
1674 __ bind(&error);
1675 __ mov(sp, r3);
1676 __ mov(r0, r10);
1677 EPILOGUE();
1678 __ rts();
1679
1680 JIT();
1681 #ifdef DEBUG
1682 Code::cast(code)->Print();
1683 #endif
1684
1685 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
1686
1687 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
1688 ::printf("f() = %d\n", res);
1689 CHECK_EQ(0, res);
1690 }
1691
1692 // Test near labels
1693 TEST(28) {
1694 BEGIN();
1695
1696 Label l1, l2, l3, l4;
1697
1698 PROLOGUE();
1699
1700 __ mov(r0, Operand(0));
1701 __ cmpeq(r4, r5);
1702 __ bf_near(&l1);
1703 __ bf_near(&l1);
1704 __ bf_near(&l1);
1705
1706 __ add(r0, Operand(1));
1707 __ bind(&l1);
1708 __ cmpeq(r4, r5);
1709 __ bt_near(&l2);
1710 __ bt_near(&l2);
1711 __ bt_near(&l2);
1712 __ bt_near(&l2);
1713
1714 __ sub(r0, r0, Operand(1));
1715 __ sub(r0, r0, Operand(1));
1716 __ sub(r0, r0, Operand(1));
1717 __ sub(r0, r0, Operand(1));
1718 __ bind(&l2);
1719 __ add(r0, Operand(1));
1720 __ add(r0, Operand(1));
1721 __ add(r0, Operand(1));
1722 __ add(r0, Operand(1));
1723
1724 __ bind(&l3);
1725 __ add(r4, Operand(1));
1726 __ cmpeq(r4, Operand(2));
1727 __ bf_near(&l3);
1728
1729 __ jmp_near(&l4);
1730 __ jmp_near(&l4);
1731 __ add(r0, Operand(1));
1732 __ bind(&l4);
1733
1734 EPILOGUE();
1735 __ rts();
1736
1737 JIT();
1738 #ifdef DEBUG
1739 Code::cast(code)->Print();
1740 #endif
1741
1742 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
1743
1744 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0, 1, 0, 0, 0));
1745 ::printf("f() = %d\n", res);
1746 CHECK_EQ(0, res);
1747 }
1748
1749 TEST(29) {
1750 BEGIN();
1751
1752 Label l1;
1753
1754 PROLOGUE();
1755
1756 __ mov(r0, Operand(0));
1757
1758 __ cmpeq(r4, r5);
1759 __ bf_near(&l1);
1760 for (int i = 0; i < 50; i++)
1761 __ nop();
1762 __ add(r0, Operand(1));
1763 __ bind(&l1);
1764 __ add(r0, Operand(2));
1765
1766 EPILOGUE();
1767 __ rts();
1768
1769 JIT();
1770 #ifdef DEBUG
1771 // Code::cast(code)->Print();
1772 #endif
1773
1774 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
1775 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 12, 0, 0, 0, 0));
1776 ::printf("f() = %d\n", res);
1777 CHECK_EQ(2, res);
1778 }
1779
1780
1781 TEST(30) {
1782 typedef struct {
1783 double a;
1784 double b;
1785 } T;
1786 T t;
1787 t.a = 12345.012456021864;
1788 t.b = 0.1348714347684218;
1789
1790 BEGIN();
1791 PROLOGUE();
1792 __ dldr(dr0, MemOperand(r4, OFFSET_OF(T, a)), r6);
1793 __ dldr(dr2, MemOperand(r4, OFFSET_OF(T, b)), r6);
1794
1795 __ dstr(dr0, MemOperand(r4, OFFSET_OF(T, b)), r6);
1796 __ dstr(dr2, MemOperand(r4, OFFSET_OF(T, a)), r6);
1797
1798 __ mov(r0, r5);
1799 EPILOGUE();
1800 __ rts();
1801
1802 JIT();
1803 #ifdef DEBUG
1804 Code::cast(code)->Print();
1805 #endif
1806
1807 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
1808 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, &t, 123156, 0, 0, 0));
1809 ::printf("f() = %d\n", res);
1810 CHECK_EQ(123156, res);
1811 CHECK_EQ(t.a, 0.1348714347684218);
1812 CHECK_EQ(t.b, 12345.012456021864);
1813 }
1814
1815
1816 TEST(31) {
1817 Label end;
1818
1819 BEGIN();
1820 PROLOGUE();
1821 __ dfloat(dr0, Operand(123));
1822 __ mov(r0, Operand(0));
1823
1824 __ dcmpeq(dr0, dr4);
1825 __ bt(&end);
1826
1827 __ mov(r0, Operand(1));
1828 EPILOGUE();
1829 __ rts();
1830
1831 __ bind(&end);
1832 EPILOGUE();
1833 __ rts();
1834
1835 JIT();
1836 #ifdef DEBUG
1837 Code::cast(code)->Print();
1838 #endif
1839
1840 F5 f = FUNCTION_CAST<F5>(Code::cast(code)->entry());
1841 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 123, 0, 0, 0, 0));
1842 CHECK_EQ(0, res);
1843 }
1844
1845
1846 TEST(32) {
1847 BEGIN();
1848
1849 Label error;
1850 PROLOGUE();
1851
1852 __ dfloat(dr0, Operand(34));
1853 __ fadd(dr0, dr4);
1854 __ dfloat(dr2, Operand(456 + 34));
1855 __ dcmpeq(dr2, dr0);
1856 B_LINE(f, &error);
1857
1858 __ dfloat(dr2, Operand(56));
1859 __ fsub(dr0, dr2);
1860 __ dfloat(dr2, Operand(456 + 34 - 56));
1861 __ dcmpeq(dr2, dr0);
1862 B_LINE(f, &error);
1863
1864 __ dfloat(dr2, Operand(7));
1865 __ fmul(dr0, dr2);
1866 __ dfloat(dr2, Operand((456 + 34 - 56) * 7));
1867 __ dcmpeq(dr2, dr0);
1868 B_LINE(f, &error);
1869
1870 __ dfloat(dr2, Operand(2));
1871 __ fdiv(dr0, dr2);
1872 __ dfloat(dr2, Operand(((456 + 34 - 56) * 7) / 2));
1873 __ dcmpeq(dr2, dr0);
1874 B_LINE(f, &error);
1875
1876 // All ok
1877 __ mov(r0, Operand(0));
1878 EPILOGUE();
1879 __ rts();
1880
1881 __ bind(&error);
1882 __ mov(r0, r10);
1883 EPILOGUE();
1884 __ rts();
1885
1886 JIT();
1887 #ifdef DEBUG
1888 Code::cast(code)->Print();
1889 #endif
1890
1891 F5 f = FUNCTION_CAST<F5>(Code::cast(code)->entry());
1892 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 456, 0, 0, 0, 0));
1893 CHECK_EQ(0, res);
1894 }
1895
1896
1897 TEST(33) {
1898 BEGIN();
1899
1900 Label error;
1901 PROLOGUE();
1902
1903 __ idouble(r1, dr4);
1904 __ cmpeq(r1, Operand(4212));
1905 B_LINE(f, &error);
1906
1907 __ dfloat(dr2, Operand(343575789));
1908 __ idouble(r3, dr2);
1909 __ cmpeq(r3, Operand(343575789));
1910 B_LINE(f, &error);
1911
1912 // All ok
1913 EPILOGUE();
1914 __ mov(r0, Operand(0));
1915 __ rts();
1916
1917 __ bind(&error);
1918 __ mov(r0, r10);
1919 EPILOGUE();
1920 __ rts();
1921
1922 JIT();
1923 #ifdef DEBUG
1924 Code::cast(code)->Print();
1925 #endif
1926
1927 F5 f = FUNCTION_CAST<F5>(Code::cast(code)->entry());
1928 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 4212, 0, 0, 0, 0));
1929 CHECK_EQ(0, res);
1930 }
1931
1932
1933 // These test case are taken from the arm ones
1934 TEST(from_arm_2) {
1935 BEGIN();
1936 Label L, C;
1937
1938 PROLOGUE();
1939 __ mov(r1, r4);
1940 __ mov(r0, Operand(1));
1941 __ b(&C);
1942
1943 __ bind(&L);
1944 __ mul(r0, r1, r0);
1945 __ sub(r1, r1, Operand(1));
1946
1947 __ bind(&C);
1948 __ teq(r1, Operand(0, RelocInfo::NONE));
1949 __ b(ne, &L);
1950 EPILOGUE();
1951 __ rts();
1952
1953 // some relocated stuff here, not executed
1954 __ RecordComment("dead code, just testing relocations");
1955 __ mov(r0, Operand(FACTORY->true_value()));
1956 __ RecordComment("dead code, just testing immediate operands");
1957 __ mov(r0, Operand(-1));
1958 __ mov(r0, Operand(0xFF000000));
1959 __ mov(r0, Operand(0xF0F0F0F0));
1960 __ mov(r0, Operand(0xFFF0FFFF));
1961
1962 JIT();
1963 #ifdef DEBUG
1964 Code::cast(code)->Print();
1965 #endif
1966 F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
1967 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0));
1968 ::printf("f() = %d\n", res);
1969 CHECK_EQ(3628800, res);
1970 }
1971
1972
1973 TEST(from_arm_3) {
1974 BEGIN();
1975
1976 typedef struct {
1977 int i;
1978 char c;
1979 int16_t s;
1980 } T;
1981 T t;
1982
1983 Label L, C;
1984 PROLOGUE();
1985 __ mov(r0, r4);
1986 __ push(pr);
1987 __ push(fp);
1988 __ sub(fp, sp, Operand(4));
1989
1990 __ ldr(r0, MemOperand(r4, OFFSET_OF(T, i)), r5);
1991 __ asr(r2, r0, Operand(1), r5);
1992 __ str(r2, MemOperand(r4, OFFSET_OF(T, i)), r5);
1993
1994 __ ldrsb(r2, MemOperand(r4, OFFSET_OF(T, c)));
1995 __ add(r0, r2, r0);
1996 __ lsl(r2, r2, Operand(2));
1997 __ strb(r2, MemOperand(r4, OFFSET_OF(T, c)), r5);
1998
1999 __ ldrsh(r2, MemOperand(r4, OFFSET_OF(T, s)), r5);
2000 __ add(r0, r2, r0);
2001 __ asr(r2, r2, Operand(3));
2002 __ strh(r2, MemOperand(r4, OFFSET_OF(T, s)), r5);
2003
2004 __ pop(fp);
2005 __ pop(pr);
2006 EPILOGUE();
2007 __ rts();
2008
2009 JIT();
2010 #ifdef DEBUG
2011 Code::cast(code)->Print();
2012 #endif
2013 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
2014 t.i = 100000;
2015 t.c = 10;
2016 t.s = 1000;
2017 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0));
2018 ::printf("f() = %d\n", res);
2019 CHECK_EQ(101010, res);
2020 CHECK_EQ(100000/2, t.i);
2021 CHECK_EQ(10*4, t.c);
2022 CHECK_EQ(1000/8, t.s);
2023 }
2024
2025
2026 TEST(from_arm_4) {
2027 // Test the FPU floating point instructions.
2028 BEGIN();
2029
2030 typedef struct {
2031 double a;
2032 double b;
2033 double c;
2034 double d;
2035 double e;
2036 double f;
2037 double g;
2038 double h;
2039 int i;
2040 float x;
2041 float y;
2042 } T;
2043 T t;
2044
2045 Label L, C;
2046 PROLOGUE();
2047 __ mov(r0, sp);
2048 __ push(pr);
2049 __ push(fp);
2050 __ push(r4);
2051 __ sub(fp, r0, Operand(4));
2052
2053 __ dldr(dr0, MemOperand(r4, OFFSET_OF(T, a)));
2054 __ dldr(dr2, MemOperand(r4, OFFSET_OF(T, b)));
2055 __ fadd(dr0, dr2);
2056 __ dstr(dr0, MemOperand(r4, OFFSET_OF(T, c)));
2057
2058 __ movd(r2, r3, dr0);
2059 __ movd(dr0, r2, r3);
2060 __ dstr(dr0, MemOperand(r4, OFFSET_OF(T, b)));
2061
2062 // Load t.x and t.y, switch values, and store back to the struct.
2063 __ fldr(fr0, MemOperand(r4, OFFSET_OF(T, x)));
2064 __ fldr(fr1, MemOperand(r4, OFFSET_OF(T, y)));
2065 __ fstr(fr1, MemOperand(r4, OFFSET_OF(T, x)));
2066 __ fstr(fr0, MemOperand(r4, OFFSET_OF(T, y)));
2067
2068 // Load a double and store it as an integer
2069 __ dldr(dr0, MemOperand(r4, OFFSET_OF(T, d)));
2070 __ idouble(r0, dr0);
2071 __ str(r0, MemOperand(r4, OFFSET_OF(T, i)));
2072
2073 // Divisions and multiplications
2074 __ dldr(dr0, MemOperand(r4, OFFSET_OF(T, e)));
2075 __ dldr(dr2, MemOperand(r4, OFFSET_OF(T, f)));
2076 __ fmul(dr2, dr0);
2077 __ dstr(dr2, MemOperand(r4, OFFSET_OF(T, e)));
2078
2079 __ dldr(dr2, MemOperand(r4, OFFSET_OF(T, f)));
2080 __ fdiv(dr2, dr0);
2081 __ dstr(dr2, MemOperand(r4, OFFSET_OF(T, f)));
2082
2083 __ dldr(dr4, MemOperand(r4, OFFSET_OF(T, g)));
2084 __ dldr(dr6, MemOperand(r4, OFFSET_OF(T, h)));
2085 __ fsub(dr4, dr6);
2086 __ dstr(dr4, MemOperand(r4, OFFSET_OF(T, g)));
2087
2088 __ pop(r4);
2089 __ pop(fp);
2090 __ pop(pr);
2091 EPILOGUE();
2092 __ rts();
2093
2094 JIT();
2095 #ifdef DEBUG
2096 Code::cast(code)->Print();
2097 #endif
2098 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
2099 t.a = 1.5;
2100 t.b = 2.75;
2101 t.c = 17.17;
2102 t.d = 17.17;
2103 t.e = 1234.56;
2104 t.f = 12.1;
2105 t.g = 2718.2818;
2106 t.h = 31415926.5;
2107 t.i = 0;
2108 t.x = 4.5;
2109 t.y = 9.0;
2110 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
2111 USE(dummy);
2112 CHECK_EQ(1.5, t.a);
2113 CHECK_EQ(1.5+2.75, t.b);
2114 CHECK_EQ(1.5+2.75, t.c);
2115 CHECK_EQ(4.5, t.y);
2116 CHECK_EQ(9.0, t.x);
2117 CHECK_EQ(17, t.i);
2118 CHECK_EQ(1234.56*12.1, t.e);
2119 CHECK_EQ(12.1/1234.56, t.f);
2120 CHECK_EQ(2718.2818-31415926.5, t.g);
2121 CHECK_EQ(31415926.5, t.h);
2122 }
2123
2124 TEST(from_arm_12) {
2125 // Test chaining of label usages within instructions (issue 1644).
2126 BEGIN();
2127
2128 Label target;
2129 __ b(eq, &target);
2130 __ b(ne, &target);
2131 __ bind(&target);
2132 __ nop();
2133 }
2134
2135 TEST(memcpy) {
2136 BEGIN();
2137 PROLOGUE();
2138 __ memcpy(r4, r5, r6, r1, r2, r3, r7);
2139 __ mov(r0, Operand(0));
2140 EPILOGUE();
2141 __ rts();
2142
2143 JIT();
2144 #ifdef DEBUG
2145 Code::cast(code)->Print();
2146 #endif
2147
2148 const char *psz_buffer = "this string will be copied to the second buffer";
2149 char psz_dest[47 + 1] = { 0 };
2150
2151 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
2152 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, (int)psz_dest,
2153 (int)psz_buffer, 47 + 1, 0, 0));
2154 ::printf("f() = %d\n", res);
2155 CHECK_EQ(0, res);
2156 CHECK_EQ(0, strcmp(psz_buffer, psz_dest));
2157 }
OLDNEW
« no previous file with comments | « test/cctest/cctest.gyp ('k') | test/cctest/test-code-stub-sh4.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698