1 // Copyright 2012 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 "src/v8.h"
29 #include "test/cctest/cctest.h"
30 
31 #include "src/arm/assembler-arm-inl.h"
32 #include "src/arm/simulator-arm.h"
33 #include "src/disassembler.h"
34 #include "src/factory.h"
35 #include "src/ostreams.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 
46 
47 #define __ assm.
48 
49 TEST(0) {
50   CcTest::InitializeVM();
51   Isolate* isolate = CcTest::i_isolate();
52   HandleScope scope(isolate);
53 
54   Assembler assm(isolate, NULL, 0);
55 
56   __ add(r0, r0, Operand(r1));
57   __ mov(pc, Operand(lr));
58 
59   CodeDesc desc;
60   assm.GetCode(&desc);
61   Handle<Code> code = isolate->factory()->NewCode(
62       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
63 #ifdef DEBUG
64   OFStream os(stdout);
65   code->Print(os);
66 #endif
67   F2 f = FUNCTION_CAST<F2>(code->entry());
68   int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 3, 4, 0, 0, 0));
69   ::printf("f() = %d\n", res);
70   CHECK_EQ(7, res);
71 }
72 
73 
74 TEST(1) {
75   CcTest::InitializeVM();
76   Isolate* isolate = CcTest::i_isolate();
77   HandleScope scope(isolate);
78 
79   Assembler assm(isolate, NULL, 0);
80   Label L, C;
81 
82   __ mov(r1, Operand(r0));
83   __ mov(r0, Operand::Zero());
84   __ b(&C);
85 
86   __ bind(&L);
87   __ add(r0, r0, Operand(r1));
88   __ sub(r1, r1, Operand(1));
89 
90   __ bind(&C);
91   __ teq(r1, Operand::Zero());
92   __ b(ne, &L);
93   __ mov(pc, Operand(lr));
94 
95   CodeDesc desc;
96   assm.GetCode(&desc);
97   Handle<Code> code = isolate->factory()->NewCode(
98       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
99 #ifdef DEBUG
100   OFStream os(stdout);
101   code->Print(os);
102 #endif
103   F1 f = FUNCTION_CAST<F1>(code->entry());
104   int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 100, 0, 0, 0, 0));
105   ::printf("f() = %d\n", res);
106   CHECK_EQ(5050, res);
107 }
108 
109 
110 TEST(2) {
111   CcTest::InitializeVM();
112   Isolate* isolate = CcTest::i_isolate();
113   HandleScope scope(isolate);
114 
115   Assembler assm(isolate, NULL, 0);
116   Label L, C;
117 
118   __ mov(r1, Operand(r0));
119   __ mov(r0, Operand(1));
120   __ b(&C);
121 
122   __ bind(&L);
123   __ mul(r0, r1, r0);
124   __ sub(r1, r1, Operand(1));
125 
126   __ bind(&C);
127   __ teq(r1, Operand::Zero());
128   __ b(ne, &L);
129   __ mov(pc, Operand(lr));
130 
131   // some relocated stuff here, not executed
132   __ RecordComment("dead code, just testing relocations");
133   __ mov(r0, Operand(isolate->factory()->true_value()));
134   __ RecordComment("dead code, just testing immediate operands");
135   __ mov(r0, Operand(-1));
136   __ mov(r0, Operand(0xFF000000));
137   __ mov(r0, Operand(0xF0F0F0F0));
138   __ mov(r0, Operand(0xFFF0FFFF));
139 
140   CodeDesc desc;
141   assm.GetCode(&desc);
142   Handle<Code> code = isolate->factory()->NewCode(
143       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
144 #ifdef DEBUG
145   OFStream os(stdout);
146   code->Print(os);
147 #endif
148   F1 f = FUNCTION_CAST<F1>(code->entry());
149   int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0));
150   ::printf("f() = %d\n", res);
151   CHECK_EQ(3628800, res);
152 }
153 
154 
155 TEST(3) {
156   CcTest::InitializeVM();
157   Isolate* isolate = CcTest::i_isolate();
158   HandleScope scope(isolate);
159 
160   typedef struct {
161     int i;
162     char c;
163     int16_t s;
164   } T;
165   T t;
166 
167   Assembler assm(isolate, NULL, 0);
168   Label L, C;
169 
170   __ mov(ip, Operand(sp));
171   __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
172   __ sub(fp, ip, Operand(4));
173   __ mov(r4, Operand(r0));
174   __ ldr(r0, MemOperand(r4, OFFSET_OF(T, i)));
175   __ mov(r2, Operand(r0, ASR, 1));
176   __ str(r2, MemOperand(r4, OFFSET_OF(T, i)));
177   __ ldrsb(r2, MemOperand(r4, OFFSET_OF(T, c)));
178   __ add(r0, r2, Operand(r0));
179   __ mov(r2, Operand(r2, LSL, 2));
180   __ strb(r2, MemOperand(r4, OFFSET_OF(T, c)));
181   __ ldrsh(r2, MemOperand(r4, OFFSET_OF(T, s)));
182   __ add(r0, r2, Operand(r0));
183   __ mov(r2, Operand(r2, ASR, 3));
184   __ strh(r2, MemOperand(r4, OFFSET_OF(T, s)));
185   __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
186 
187   CodeDesc desc;
188   assm.GetCode(&desc);
189   Handle<Code> code = isolate->factory()->NewCode(
190       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
191 #ifdef DEBUG
192   OFStream os(stdout);
193   code->Print(os);
194 #endif
195   F3 f = FUNCTION_CAST<F3>(code->entry());
196   t.i = 100000;
197   t.c = 10;
198   t.s = 1000;
199   int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0));
200   ::printf("f() = %d\n", res);
201   CHECK_EQ(101010, res);
202   CHECK_EQ(100000/2, t.i);
203   CHECK_EQ(10*4, t.c);
204   CHECK_EQ(1000/8, t.s);
205 }
206 
207 
208 TEST(4) {
209   // Test the VFP floating point instructions.
210   CcTest::InitializeVM();
211   Isolate* isolate = CcTest::i_isolate();
212   HandleScope scope(isolate);
213 
214   typedef struct {
215     double a;
216     double b;
217     double c;
218     double d;
219     double e;
220     double f;
221     double g;
222     double h;
223     int i;
224     double j;
225     double m;
226     double n;
227     float x;
228     float y;
229   } T;
230   T t;
231 
232   // Create a function that accepts &t, and loads, manipulates, and stores
233   // the doubles and floats.
234   Assembler assm(isolate, NULL, 0);
235   Label L, C;
236 
237 
238   if (CpuFeatures::IsSupported(VFP3)) {
239     CpuFeatureScope scope(&assm, VFP3);
240 
241     __ mov(ip, Operand(sp));
242     __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
243     __ sub(fp, ip, Operand(4));
244 
245     __ mov(r4, Operand(r0));
246     __ vldr(d6, r4, OFFSET_OF(T, a));
247     __ vldr(d7, r4, OFFSET_OF(T, b));
248     __ vadd(d5, d6, d7);
249     __ vstr(d5, r4, OFFSET_OF(T, c));
250 
251     __ vmla(d5, d6, d7);
252     __ vmls(d5, d5, d6);
253 
254     __ vmov(r2, r3, d5);
255     __ vmov(d4, r2, r3);
256     __ vstr(d4, r4, OFFSET_OF(T, b));
257 
258     // Load t.x and t.y, switch values, and store back to the struct.
259     __ vldr(s0, r4, OFFSET_OF(T, x));
260     __ vldr(s31, r4, OFFSET_OF(T, y));
261     __ vmov(s16, s0);
262     __ vmov(s0, s31);
263     __ vmov(s31, s16);
264     __ vstr(s0, r4, OFFSET_OF(T, x));
265     __ vstr(s31, r4, OFFSET_OF(T, y));
266 
267     // Move a literal into a register that can be encoded in the instruction.
268     __ vmov(d4, 1.0);
269     __ vstr(d4, r4, OFFSET_OF(T, e));
270 
271     // Move a literal into a register that requires 64 bits to encode.
272     // 0x3ff0000010000000 = 1.000000059604644775390625
273     __ vmov(d4, 1.000000059604644775390625);
274     __ vstr(d4, r4, OFFSET_OF(T, d));
275 
276     // Convert from floating point to integer.
277     __ vmov(d4, 2.0);
278     __ vcvt_s32_f64(s31, d4);
279     __ vstr(s31, r4, OFFSET_OF(T, i));
280 
281     // Convert from integer to floating point.
282     __ mov(lr, Operand(42));
283     __ vmov(s31, lr);
284     __ vcvt_f64_s32(d4, s31);
285     __ vstr(d4, r4, OFFSET_OF(T, f));
286 
287     // Convert from fixed point to floating point.
288     __ mov(lr, Operand(2468));
289     __ vmov(s8, lr);
290     __ vcvt_f64_s32(d4, 2);
291     __ vstr(d4, r4, OFFSET_OF(T, j));
292 
293     // Test vabs.
294     __ vldr(d1, r4, OFFSET_OF(T, g));
295     __ vabs(d0, d1);
296     __ vstr(d0, r4, OFFSET_OF(T, g));
297     __ vldr(d2, r4, OFFSET_OF(T, h));
298     __ vabs(d0, d2);
299     __ vstr(d0, r4, OFFSET_OF(T, h));
300 
301     // Test vneg.
302     __ vldr(d1, r4, OFFSET_OF(T, m));
303     __ vneg(d0, d1);
304     __ vstr(d0, r4, OFFSET_OF(T, m));
305     __ vldr(d1, r4, OFFSET_OF(T, n));
306     __ vneg(d0, d1);
307     __ vstr(d0, r4, OFFSET_OF(T, n));
308 
309     __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
310 
311     CodeDesc desc;
312     assm.GetCode(&desc);
313     Handle<Code> code = isolate->factory()->NewCode(
314         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
315 #ifdef DEBUG
316     OFStream os(stdout);
317     code->Print(os);
318 #endif
319     F3 f = FUNCTION_CAST<F3>(code->entry());
320     t.a = 1.5;
321     t.b = 2.75;
322     t.c = 17.17;
323     t.d = 0.0;
324     t.e = 0.0;
325     t.f = 0.0;
326     t.g = -2718.2818;
327     t.h = 31415926.5;
328     t.i = 0;
329     t.j = 0;
330     t.m = -2718.2818;
331     t.n = 123.456;
332     t.x = 4.5;
333     t.y = 9.0;
334     Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
335     USE(dummy);
336     CHECK_EQ(4.5, t.y);
337     CHECK_EQ(9.0, t.x);
338     CHECK_EQ(-123.456, t.n);
339     CHECK_EQ(2718.2818, t.m);
340     CHECK_EQ(2, t.i);
341     CHECK_EQ(2718.2818, t.g);
342     CHECK_EQ(31415926.5, t.h);
343     CHECK_EQ(617.0, t.j);
344     CHECK_EQ(42.0, t.f);
345     CHECK_EQ(1.0, t.e);
346     CHECK_EQ(1.000000059604644775390625, t.d);
347     CHECK_EQ(4.25, t.c);
348     CHECK_EQ(-4.1875, t.b);
349     CHECK_EQ(1.5, t.a);
350   }
351 }
352 
353 
354 TEST(5) {
355   // Test the ARMv7 bitfield instructions.
356   CcTest::InitializeVM();
357   Isolate* isolate = CcTest::i_isolate();
358   HandleScope scope(isolate);
359 
360   Assembler assm(isolate, NULL, 0);
361 
362   if (CpuFeatures::IsSupported(ARMv7)) {
363     CpuFeatureScope scope(&assm, ARMv7);
364     // On entry, r0 = 0xAAAAAAAA = 0b10..10101010.
365     __ ubfx(r0, r0, 1, 12);  // 0b00..010101010101 = 0x555
366     __ sbfx(r0, r0, 0, 5);   // 0b11..111111110101 = -11
367     __ bfc(r0, 1, 3);        // 0b11..111111110001 = -15
368     __ mov(r1, Operand(7));
369     __ bfi(r0, r1, 3, 3);    // 0b11..111111111001 = -7
370     __ mov(pc, Operand(lr));
371 
372     CodeDesc desc;
373     assm.GetCode(&desc);
374     Handle<Code> code = isolate->factory()->NewCode(
375         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
376 #ifdef DEBUG
377     OFStream os(stdout);
378     code->Print(os);
379 #endif
380     F1 f = FUNCTION_CAST<F1>(code->entry());
381     int res = reinterpret_cast<int>(
382                 CALL_GENERATED_CODE(f, 0xAAAAAAAA, 0, 0, 0, 0));
383     ::printf("f() = %d\n", res);
384     CHECK_EQ(-7, res);
385   }
386 }
387 
388 
389 TEST(6) {
390   // Test saturating instructions.
391   CcTest::InitializeVM();
392   Isolate* isolate = CcTest::i_isolate();
393   HandleScope scope(isolate);
394 
395   Assembler assm(isolate, NULL, 0);
396 
397   if (CpuFeatures::IsSupported(ARMv7)) {
398     CpuFeatureScope scope(&assm, ARMv7);
399     __ usat(r1, 8, Operand(r0));           // Sat 0xFFFF to 0-255 = 0xFF.
400     __ usat(r2, 12, Operand(r0, ASR, 9));  // Sat (0xFFFF>>9) to 0-4095 = 0x7F.
401     __ usat(r3, 1, Operand(r0, LSL, 16));  // Sat (0xFFFF<<16) to 0-1 = 0x0.
402     __ add(r0, r1, Operand(r2));
403     __ add(r0, r0, Operand(r3));
404     __ mov(pc, Operand(lr));
405 
406     CodeDesc desc;
407     assm.GetCode(&desc);
408     Handle<Code> code = isolate->factory()->NewCode(
409         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
410 #ifdef DEBUG
411     OFStream os(stdout);
412     code->Print(os);
413 #endif
414     F1 f = FUNCTION_CAST<F1>(code->entry());
415     int res = reinterpret_cast<int>(
416                 CALL_GENERATED_CODE(f, 0xFFFF, 0, 0, 0, 0));
417     ::printf("f() = %d\n", res);
418     CHECK_EQ(382, res);
419   }
420 }
421 
422 
423 enum VCVTTypes {
424   s32_f64,
425   u32_f64
426 };
427 
TestRoundingMode(VCVTTypes types,VFPRoundingMode mode,double value,int expected,bool expected_exception=false)428 static void TestRoundingMode(VCVTTypes types,
429                              VFPRoundingMode mode,
430                              double value,
431                              int expected,
432                              bool expected_exception = false) {
433   Isolate* isolate = CcTest::i_isolate();
434   HandleScope scope(isolate);
435 
436   Assembler assm(isolate, NULL, 0);
437 
438   if (CpuFeatures::IsSupported(VFP3)) {
439     CpuFeatureScope scope(&assm, VFP3);
440 
441     Label wrong_exception;
442 
443     __ vmrs(r1);
444     // Set custom FPSCR.
445     __ bic(r2, r1, Operand(kVFPRoundingModeMask | kVFPExceptionMask));
446     __ orr(r2, r2, Operand(mode));
447     __ vmsr(r2);
448 
449     // Load value, convert, and move back result to r0 if everything went well.
450     __ vmov(d1, value);
451     switch (types) {
452       case s32_f64:
453         __ vcvt_s32_f64(s0, d1, kFPSCRRounding);
454         break;
455 
456       case u32_f64:
457         __ vcvt_u32_f64(s0, d1, kFPSCRRounding);
458         break;
459 
460       default:
461         UNREACHABLE();
462         break;
463     }
464     // Check for vfp exceptions
465     __ vmrs(r2);
466     __ tst(r2, Operand(kVFPExceptionMask));
467     // Check that we behaved as expected.
468     __ b(&wrong_exception,
469          expected_exception ? eq : ne);
470     // There was no exception. Retrieve the result and return.
471     __ vmov(r0, s0);
472     __ mov(pc, Operand(lr));
473 
474     // The exception behaviour is not what we expected.
475     // Load a special value and return.
476     __ bind(&wrong_exception);
477     __ mov(r0, Operand(11223344));
478     __ mov(pc, Operand(lr));
479 
480     CodeDesc desc;
481     assm.GetCode(&desc);
482     Handle<Code> code = isolate->factory()->NewCode(
483         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
484 #ifdef DEBUG
485     OFStream os(stdout);
486     code->Print(os);
487 #endif
488     F1 f = FUNCTION_CAST<F1>(code->entry());
489     int res = reinterpret_cast<int>(
490                 CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
491     ::printf("res = %d\n", res);
492     CHECK_EQ(expected, res);
493   }
494 }
495 
496 
497 TEST(7) {
498   CcTest::InitializeVM();
499   // Test vfp rounding modes.
500 
501   // s32_f64 (double to integer).
502 
503   TestRoundingMode(s32_f64, RN,  0, 0);
504   TestRoundingMode(s32_f64, RN,  0.5, 0);
505   TestRoundingMode(s32_f64, RN, -0.5, 0);
506   TestRoundingMode(s32_f64, RN,  1.5, 2);
507   TestRoundingMode(s32_f64, RN, -1.5, -2);
508   TestRoundingMode(s32_f64, RN,  123.7, 124);
509   TestRoundingMode(s32_f64, RN, -123.7, -124);
510   TestRoundingMode(s32_f64, RN,  123456.2,  123456);
511   TestRoundingMode(s32_f64, RN, -123456.2, -123456);
512   TestRoundingMode(s32_f64, RN, static_cast<double>(kMaxInt), kMaxInt);
513   TestRoundingMode(s32_f64, RN, (kMaxInt + 0.49), kMaxInt);
514   TestRoundingMode(s32_f64, RN, (kMaxInt + 1.0), kMaxInt, true);
515   TestRoundingMode(s32_f64, RN, (kMaxInt + 0.5), kMaxInt, true);
516   TestRoundingMode(s32_f64, RN, static_cast<double>(kMinInt), kMinInt);
517   TestRoundingMode(s32_f64, RN, (kMinInt - 0.5), kMinInt);
518   TestRoundingMode(s32_f64, RN, (kMinInt - 1.0), kMinInt, true);
519   TestRoundingMode(s32_f64, RN, (kMinInt - 0.51), kMinInt, true);
520 
521   TestRoundingMode(s32_f64, RM,  0, 0);
522   TestRoundingMode(s32_f64, RM,  0.5, 0);
523   TestRoundingMode(s32_f64, RM, -0.5, -1);
524   TestRoundingMode(s32_f64, RM,  123.7, 123);
525   TestRoundingMode(s32_f64, RM, -123.7, -124);
526   TestRoundingMode(s32_f64, RM,  123456.2,  123456);
527   TestRoundingMode(s32_f64, RM, -123456.2, -123457);
528   TestRoundingMode(s32_f64, RM, static_cast<double>(kMaxInt), kMaxInt);
529   TestRoundingMode(s32_f64, RM, (kMaxInt + 0.5), kMaxInt);
530   TestRoundingMode(s32_f64, RM, (kMaxInt + 1.0), kMaxInt, true);
531   TestRoundingMode(s32_f64, RM, static_cast<double>(kMinInt), kMinInt);
532   TestRoundingMode(s32_f64, RM, (kMinInt - 0.5), kMinInt, true);
533   TestRoundingMode(s32_f64, RM, (kMinInt + 0.5), kMinInt);
534 
535   TestRoundingMode(s32_f64, RZ,  0, 0);
536   TestRoundingMode(s32_f64, RZ,  0.5, 0);
537   TestRoundingMode(s32_f64, RZ, -0.5, 0);
538   TestRoundingMode(s32_f64, RZ,  123.7,  123);
539   TestRoundingMode(s32_f64, RZ, -123.7, -123);
540   TestRoundingMode(s32_f64, RZ,  123456.2,  123456);
541   TestRoundingMode(s32_f64, RZ, -123456.2, -123456);
542   TestRoundingMode(s32_f64, RZ, static_cast<double>(kMaxInt), kMaxInt);
543   TestRoundingMode(s32_f64, RZ, (kMaxInt + 0.5), kMaxInt);
544   TestRoundingMode(s32_f64, RZ, (kMaxInt + 1.0), kMaxInt, true);
545   TestRoundingMode(s32_f64, RZ, static_cast<double>(kMinInt), kMinInt);
546   TestRoundingMode(s32_f64, RZ, (kMinInt - 0.5), kMinInt);
547   TestRoundingMode(s32_f64, RZ, (kMinInt - 1.0), kMinInt, true);
548 
549 
550   // u32_f64 (double to integer).
551 
552   // Negative values.
553   TestRoundingMode(u32_f64, RN, -0.5, 0);
554   TestRoundingMode(u32_f64, RN, -123456.7, 0, true);
555   TestRoundingMode(u32_f64, RN, static_cast<double>(kMinInt), 0, true);
556   TestRoundingMode(u32_f64, RN, kMinInt - 1.0, 0, true);
557 
558   TestRoundingMode(u32_f64, RM, -0.5, 0, true);
559   TestRoundingMode(u32_f64, RM, -123456.7, 0, true);
560   TestRoundingMode(u32_f64, RM, static_cast<double>(kMinInt), 0, true);
561   TestRoundingMode(u32_f64, RM, kMinInt - 1.0, 0, true);
562 
563   TestRoundingMode(u32_f64, RZ, -0.5, 0);
564   TestRoundingMode(u32_f64, RZ, -123456.7, 0, true);
565   TestRoundingMode(u32_f64, RZ, static_cast<double>(kMinInt), 0, true);
566   TestRoundingMode(u32_f64, RZ, kMinInt - 1.0, 0, true);
567 
568   // Positive values.
569   // kMaxInt is the maximum *signed* integer: 0x7fffffff.
570   static const uint32_t kMaxUInt = 0xffffffffu;
571   TestRoundingMode(u32_f64, RZ,  0, 0);
572   TestRoundingMode(u32_f64, RZ,  0.5, 0);
573   TestRoundingMode(u32_f64, RZ,  123.7,  123);
574   TestRoundingMode(u32_f64, RZ,  123456.2,  123456);
575   TestRoundingMode(u32_f64, RZ, static_cast<double>(kMaxInt), kMaxInt);
576   TestRoundingMode(u32_f64, RZ, (kMaxInt + 0.5), kMaxInt);
577   TestRoundingMode(u32_f64, RZ, (kMaxInt + 1.0),
578                                 static_cast<uint32_t>(kMaxInt) + 1);
579   TestRoundingMode(u32_f64, RZ, (kMaxUInt + 0.5), kMaxUInt);
580   TestRoundingMode(u32_f64, RZ, (kMaxUInt + 1.0), kMaxUInt, true);
581 
582   TestRoundingMode(u32_f64, RM,  0, 0);
583   TestRoundingMode(u32_f64, RM,  0.5, 0);
584   TestRoundingMode(u32_f64, RM,  123.7, 123);
585   TestRoundingMode(u32_f64, RM,  123456.2,  123456);
586   TestRoundingMode(u32_f64, RM, static_cast<double>(kMaxInt), kMaxInt);
587   TestRoundingMode(u32_f64, RM, (kMaxInt + 0.5), kMaxInt);
588   TestRoundingMode(u32_f64, RM, (kMaxInt + 1.0),
589                                 static_cast<uint32_t>(kMaxInt) + 1);
590   TestRoundingMode(u32_f64, RM, (kMaxUInt + 0.5), kMaxUInt);
591   TestRoundingMode(u32_f64, RM, (kMaxUInt + 1.0), kMaxUInt, true);
592 
593   TestRoundingMode(u32_f64, RN,  0, 0);
594   TestRoundingMode(u32_f64, RN,  0.5, 0);
595   TestRoundingMode(u32_f64, RN,  1.5, 2);
596   TestRoundingMode(u32_f64, RN,  123.7, 124);
597   TestRoundingMode(u32_f64, RN,  123456.2,  123456);
598   TestRoundingMode(u32_f64, RN, static_cast<double>(kMaxInt), kMaxInt);
599   TestRoundingMode(u32_f64, RN, (kMaxInt + 0.49), kMaxInt);
600   TestRoundingMode(u32_f64, RN, (kMaxInt + 0.5),
601                                 static_cast<uint32_t>(kMaxInt) + 1);
602   TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.49), kMaxUInt);
603   TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.5), kMaxUInt, true);
604   TestRoundingMode(u32_f64, RN, (kMaxUInt + 1.0), kMaxUInt, true);
605 }
606 
607 
608 TEST(8) {
609   // Test VFP multi load/store with ia_w.
610   CcTest::InitializeVM();
611   Isolate* isolate = CcTest::i_isolate();
612   HandleScope scope(isolate);
613 
614   typedef struct {
615     double a;
616     double b;
617     double c;
618     double d;
619     double e;
620     double f;
621     double g;
622     double h;
623   } D;
624   D d;
625 
626   typedef struct {
627     float a;
628     float b;
629     float c;
630     float d;
631     float e;
632     float f;
633     float g;
634     float h;
635   } F;
636   F f;
637 
638   // Create a function that uses vldm/vstm to move some double and
639   // single precision values around in memory.
640   Assembler assm(isolate, NULL, 0);
641 
642   __ mov(ip, Operand(sp));
643   __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
644   __ sub(fp, ip, Operand(4));
645 
646   __ add(r4, r0, Operand(OFFSET_OF(D, a)));
647   __ vldm(ia_w, r4, d0, d3);
648   __ vldm(ia_w, r4, d4, d7);
649 
650   __ add(r4, r0, Operand(OFFSET_OF(D, a)));
651   __ vstm(ia_w, r4, d6, d7);
652   __ vstm(ia_w, r4, d0, d5);
653 
654   __ add(r4, r1, Operand(OFFSET_OF(F, a)));
655   __ vldm(ia_w, r4, s0, s3);
656   __ vldm(ia_w, r4, s4, s7);
657 
658   __ add(r4, r1, Operand(OFFSET_OF(F, a)));
659   __ vstm(ia_w, r4, s6, s7);
660   __ vstm(ia_w, r4, s0, s5);
661 
662   __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
663 
664   CodeDesc desc;
665   assm.GetCode(&desc);
666   Handle<Code> code = isolate->factory()->NewCode(
667       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
668 #ifdef DEBUG
669   OFStream os(stdout);
670   code->Print(os);
671 #endif
672   F4 fn = FUNCTION_CAST<F4>(code->entry());
673   d.a = 1.1;
674   d.b = 2.2;
675   d.c = 3.3;
676   d.d = 4.4;
677   d.e = 5.5;
678   d.f = 6.6;
679   d.g = 7.7;
680   d.h = 8.8;
681 
682   f.a = 1.0;
683   f.b = 2.0;
684   f.c = 3.0;
685   f.d = 4.0;
686   f.e = 5.0;
687   f.f = 6.0;
688   f.g = 7.0;
689   f.h = 8.0;
690 
691   Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
692   USE(dummy);
693 
694   CHECK_EQ(7.7, d.a);
695   CHECK_EQ(8.8, d.b);
696   CHECK_EQ(1.1, d.c);
697   CHECK_EQ(2.2, d.d);
698   CHECK_EQ(3.3, d.e);
699   CHECK_EQ(4.4, d.f);
700   CHECK_EQ(5.5, d.g);
701   CHECK_EQ(6.6, d.h);
702 
703   CHECK_EQ(7.0, f.a);
704   CHECK_EQ(8.0, f.b);
705   CHECK_EQ(1.0, f.c);
706   CHECK_EQ(2.0, f.d);
707   CHECK_EQ(3.0, f.e);
708   CHECK_EQ(4.0, f.f);
709   CHECK_EQ(5.0, f.g);
710   CHECK_EQ(6.0, f.h);
711 }
712 
713 
714 TEST(9) {
715   // Test VFP multi load/store with ia.
716   CcTest::InitializeVM();
717   Isolate* isolate = CcTest::i_isolate();
718   HandleScope scope(isolate);
719 
720   typedef struct {
721     double a;
722     double b;
723     double c;
724     double d;
725     double e;
726     double f;
727     double g;
728     double h;
729   } D;
730   D d;
731 
732   typedef struct {
733     float a;
734     float b;
735     float c;
736     float d;
737     float e;
738     float f;
739     float g;
740     float h;
741   } F;
742   F f;
743 
744   // Create a function that uses vldm/vstm to move some double and
745   // single precision values around in memory.
746   Assembler assm(isolate, NULL, 0);
747 
748   __ mov(ip, Operand(sp));
749   __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
750   __ sub(fp, ip, Operand(4));
751 
752   __ add(r4, r0, Operand(OFFSET_OF(D, a)));
753   __ vldm(ia, r4, d0, d3);
754   __ add(r4, r4, Operand(4 * 8));
755   __ vldm(ia, r4, d4, d7);
756 
757   __ add(r4, r0, Operand(OFFSET_OF(D, a)));
758   __ vstm(ia, r4, d6, d7);
759   __ add(r4, r4, Operand(2 * 8));
760   __ vstm(ia, r4, d0, d5);
761 
762   __ add(r4, r1, Operand(OFFSET_OF(F, a)));
763   __ vldm(ia, r4, s0, s3);
764   __ add(r4, r4, Operand(4 * 4));
765   __ vldm(ia, r4, s4, s7);
766 
767   __ add(r4, r1, Operand(OFFSET_OF(F, a)));
768   __ vstm(ia, r4, s6, s7);
769   __ add(r4, r4, Operand(2 * 4));
770   __ vstm(ia, r4, s0, s5);
771 
772   __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
773 
774   CodeDesc desc;
775   assm.GetCode(&desc);
776   Handle<Code> code = isolate->factory()->NewCode(
777       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
778 #ifdef DEBUG
779   OFStream os(stdout);
780   code->Print(os);
781 #endif
782   F4 fn = FUNCTION_CAST<F4>(code->entry());
783   d.a = 1.1;
784   d.b = 2.2;
785   d.c = 3.3;
786   d.d = 4.4;
787   d.e = 5.5;
788   d.f = 6.6;
789   d.g = 7.7;
790   d.h = 8.8;
791 
792   f.a = 1.0;
793   f.b = 2.0;
794   f.c = 3.0;
795   f.d = 4.0;
796   f.e = 5.0;
797   f.f = 6.0;
798   f.g = 7.0;
799   f.h = 8.0;
800 
801   Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
802   USE(dummy);
803 
804   CHECK_EQ(7.7, d.a);
805   CHECK_EQ(8.8, d.b);
806   CHECK_EQ(1.1, d.c);
807   CHECK_EQ(2.2, d.d);
808   CHECK_EQ(3.3, d.e);
809   CHECK_EQ(4.4, d.f);
810   CHECK_EQ(5.5, d.g);
811   CHECK_EQ(6.6, d.h);
812 
813   CHECK_EQ(7.0, f.a);
814   CHECK_EQ(8.0, f.b);
815   CHECK_EQ(1.0, f.c);
816   CHECK_EQ(2.0, f.d);
817   CHECK_EQ(3.0, f.e);
818   CHECK_EQ(4.0, f.f);
819   CHECK_EQ(5.0, f.g);
820   CHECK_EQ(6.0, f.h);
821 }
822 
823 
824 TEST(10) {
825   // Test VFP multi load/store with db_w.
826   CcTest::InitializeVM();
827   Isolate* isolate = CcTest::i_isolate();
828   HandleScope scope(isolate);
829 
830   typedef struct {
831     double a;
832     double b;
833     double c;
834     double d;
835     double e;
836     double f;
837     double g;
838     double h;
839   } D;
840   D d;
841 
842   typedef struct {
843     float a;
844     float b;
845     float c;
846     float d;
847     float e;
848     float f;
849     float g;
850     float h;
851   } F;
852   F f;
853 
854   // Create a function that uses vldm/vstm to move some double and
855   // single precision values around in memory.
856   Assembler assm(isolate, NULL, 0);
857 
858   __ mov(ip, Operand(sp));
859   __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
860   __ sub(fp, ip, Operand(4));
861 
862   __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
863   __ vldm(db_w, r4, d4, d7);
864   __ vldm(db_w, r4, d0, d3);
865 
866   __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
867   __ vstm(db_w, r4, d0, d5);
868   __ vstm(db_w, r4, d6, d7);
869 
870   __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
871   __ vldm(db_w, r4, s4, s7);
872   __ vldm(db_w, r4, s0, s3);
873 
874   __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
875   __ vstm(db_w, r4, s0, s5);
876   __ vstm(db_w, r4, s6, s7);
877 
878   __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
879 
880   CodeDesc desc;
881   assm.GetCode(&desc);
882   Handle<Code> code = isolate->factory()->NewCode(
883       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
884 #ifdef DEBUG
885   OFStream os(stdout);
886   code->Print(os);
887 #endif
888   F4 fn = FUNCTION_CAST<F4>(code->entry());
889   d.a = 1.1;
890   d.b = 2.2;
891   d.c = 3.3;
892   d.d = 4.4;
893   d.e = 5.5;
894   d.f = 6.6;
895   d.g = 7.7;
896   d.h = 8.8;
897 
898   f.a = 1.0;
899   f.b = 2.0;
900   f.c = 3.0;
901   f.d = 4.0;
902   f.e = 5.0;
903   f.f = 6.0;
904   f.g = 7.0;
905   f.h = 8.0;
906 
907   Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0);
908   USE(dummy);
909 
910   CHECK_EQ(7.7, d.a);
911   CHECK_EQ(8.8, d.b);
912   CHECK_EQ(1.1, d.c);
913   CHECK_EQ(2.2, d.d);
914   CHECK_EQ(3.3, d.e);
915   CHECK_EQ(4.4, d.f);
916   CHECK_EQ(5.5, d.g);
917   CHECK_EQ(6.6, d.h);
918 
919   CHECK_EQ(7.0, f.a);
920   CHECK_EQ(8.0, f.b);
921   CHECK_EQ(1.0, f.c);
922   CHECK_EQ(2.0, f.d);
923   CHECK_EQ(3.0, f.e);
924   CHECK_EQ(4.0, f.f);
925   CHECK_EQ(5.0, f.g);
926   CHECK_EQ(6.0, f.h);
927 }
928 
929 
930 TEST(11) {
931   // Test instructions using the carry flag.
932   CcTest::InitializeVM();
933   Isolate* isolate = CcTest::i_isolate();
934   HandleScope scope(isolate);
935 
936   typedef struct {
937     int32_t a;
938     int32_t b;
939     int32_t c;
940     int32_t d;
941   } I;
942   I i;
943 
944   i.a = 0xabcd0001;
945   i.b = 0xabcd0000;
946 
947   Assembler assm(isolate, NULL, 0);
948 
949   // Test HeapObject untagging.
950   __ ldr(r1, MemOperand(r0, OFFSET_OF(I, a)));
951   __ mov(r1, Operand(r1, ASR, 1), SetCC);
952   __ adc(r1, r1, Operand(r1), LeaveCC, cs);
953   __ str(r1, MemOperand(r0, OFFSET_OF(I, a)));
954 
955   __ ldr(r2, MemOperand(r0, OFFSET_OF(I, b)));
956   __ mov(r2, Operand(r2, ASR, 1), SetCC);
957   __ adc(r2, r2, Operand(r2), LeaveCC, cs);
958   __ str(r2, MemOperand(r0, OFFSET_OF(I, b)));
959 
960   // Test corner cases.
961   __ mov(r1, Operand(0xffffffff));
962   __ mov(r2, Operand::Zero());
963   __ mov(r3, Operand(r1, ASR, 1), SetCC);  // Set the carry.
964   __ adc(r3, r1, Operand(r2));
965   __ str(r3, MemOperand(r0, OFFSET_OF(I, c)));
966 
967   __ mov(r1, Operand(0xffffffff));
968   __ mov(r2, Operand::Zero());
969   __ mov(r3, Operand(r2, ASR, 1), SetCC);  // Unset the carry.
970   __ adc(r3, r1, Operand(r2));
971   __ str(r3, MemOperand(r0, OFFSET_OF(I, d)));
972 
973   __ mov(pc, Operand(lr));
974 
975   CodeDesc desc;
976   assm.GetCode(&desc);
977   Handle<Code> code = isolate->factory()->NewCode(
978       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
979 #ifdef DEBUG
980   OFStream os(stdout);
981   code->Print(os);
982 #endif
983   F3 f = FUNCTION_CAST<F3>(code->entry());
984   Object* dummy = CALL_GENERATED_CODE(f, &i, 0, 0, 0, 0);
985   USE(dummy);
986 
987   CHECK_EQ(0xabcd0001, i.a);
988   CHECK_EQ(static_cast<int32_t>(0xabcd0000) >> 1, i.b);
989   CHECK_EQ(0x00000000, i.c);
990   CHECK_EQ(0xffffffff, i.d);
991 }
992 
993 
994 TEST(12) {
995   // Test chaining of label usages within instructions (issue 1644).
996   CcTest::InitializeVM();
997   Isolate* isolate = CcTest::i_isolate();
998   HandleScope scope(isolate);
999 
1000   Assembler assm(isolate, NULL, 0);
1001   Label target;
1002   __ b(eq, &target);
1003   __ b(ne, &target);
1004   __ bind(&target);
1005   __ nop();
1006 }
1007 
1008 
1009 TEST(13) {
1010   // Test VFP instructions using registers d16-d31.
1011   CcTest::InitializeVM();
1012   Isolate* isolate = CcTest::i_isolate();
1013   HandleScope scope(isolate);
1014 
1015   if (!CpuFeatures::IsSupported(VFP32DREGS)) {
1016     return;
1017   }
1018 
1019   typedef struct {
1020     double a;
1021     double b;
1022     double c;
1023     double x;
1024     double y;
1025     double z;
1026     double i;
1027     double j;
1028     double k;
1029     uint32_t low;
1030     uint32_t high;
1031   } T;
1032   T t;
1033 
1034   // Create a function that accepts &t, and loads, manipulates, and stores
1035   // the doubles and floats.
1036   Assembler assm(isolate, NULL, 0);
1037   Label L, C;
1038 
1039 
1040   if (CpuFeatures::IsSupported(VFP3)) {
1041     CpuFeatureScope scope(&assm, VFP3);
1042 
1043     __ stm(db_w, sp, r4.bit() | lr.bit());
1044 
1045     // Load a, b, c into d16, d17, d18.
1046     __ mov(r4, Operand(r0));
1047     __ vldr(d16, r4, OFFSET_OF(T, a));
1048     __ vldr(d17, r4, OFFSET_OF(T, b));
1049     __ vldr(d18, r4, OFFSET_OF(T, c));
1050 
1051     __ vneg(d25, d16);
1052     __ vadd(d25, d25, d17);
1053     __ vsub(d25, d25, d18);
1054     __ vmul(d25, d25, d25);
1055     __ vdiv(d25, d25, d18);
1056 
1057     __ vmov(d16, d25);
1058     __ vsqrt(d17, d25);
1059     __ vneg(d17, d17);
1060     __ vabs(d17, d17);
1061     __ vmla(d18, d16, d17);
1062 
1063     // Store d16, d17, d18 into a, b, c.
1064     __ mov(r4, Operand(r0));
1065     __ vstr(d16, r4, OFFSET_OF(T, a));
1066     __ vstr(d17, r4, OFFSET_OF(T, b));
1067     __ vstr(d18, r4, OFFSET_OF(T, c));
1068 
1069     // Load x, y, z into d29-d31.
1070     __ add(r4, r0, Operand(OFFSET_OF(T, x)));
1071     __ vldm(ia_w, r4, d29, d31);
1072 
1073     // Swap d29 and d30 via r registers.
1074     __ vmov(r1, r2, d29);
1075     __ vmov(d29, d30);
1076     __ vmov(d30, r1, r2);
1077 
1078     // Convert to and from integer.
1079     __ vcvt_s32_f64(s1, d31);
1080     __ vcvt_f64_u32(d31, s1);
1081 
1082     // Store d29-d31 into x, y, z.
1083     __ add(r4, r0, Operand(OFFSET_OF(T, x)));
1084     __ vstm(ia_w, r4, d29, d31);
1085 
1086     // Move constants into d20, d21, d22 and store into i, j, k.
1087     __ vmov(d20, 14.7610017472335499);
1088     __ vmov(d21, 16.0);
1089     __ mov(r1, Operand(372106121));
1090     __ mov(r2, Operand(1079146608));
1091     __ vmov(d22, VmovIndexLo, r1);
1092     __ vmov(d22, VmovIndexHi, r2);
1093     __ add(r4, r0, Operand(OFFSET_OF(T, i)));
1094     __ vstm(ia_w, r4, d20, d22);
1095     // Move d22 into low and high.
1096     __ vmov(r4, VmovIndexLo, d22);
1097     __ str(r4, MemOperand(r0, OFFSET_OF(T, low)));
1098     __ vmov(r4, VmovIndexHi, d22);
1099     __ str(r4, MemOperand(r0, OFFSET_OF(T, high)));
1100 
1101     __ ldm(ia_w, sp, r4.bit() | pc.bit());
1102 
1103     CodeDesc desc;
1104     assm.GetCode(&desc);
1105     Handle<Code> code = isolate->factory()->NewCode(
1106         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
1107 #ifdef DEBUG
1108     OFStream os(stdout);
1109     code->Print(os);
1110 #endif
1111     F3 f = FUNCTION_CAST<F3>(code->entry());
1112     t.a = 1.5;
1113     t.b = 2.75;
1114     t.c = 17.17;
1115     t.x = 1.5;
1116     t.y = 2.75;
1117     t.z = 17.17;
1118     Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
1119     USE(dummy);
1120     CHECK_EQ(14.7610017472335499, t.a);
1121     CHECK_EQ(3.84200491244266251, t.b);
1122     CHECK_EQ(73.8818412254460241, t.c);
1123     CHECK_EQ(2.75, t.x);
1124     CHECK_EQ(1.5, t.y);
1125     CHECK_EQ(17.0, t.z);
1126     CHECK_EQ(14.7610017472335499, t.i);
1127     CHECK_EQ(16.0, t.j);
1128     CHECK_EQ(73.8818412254460241, t.k);
1129     CHECK_EQ(372106121, t.low);
1130     CHECK_EQ(1079146608, t.high);
1131   }
1132 }
1133 
1134 
1135 TEST(14) {
1136   // Test the VFP Canonicalized Nan mode.
1137   CcTest::InitializeVM();
1138   Isolate* isolate = CcTest::i_isolate();
1139   HandleScope scope(isolate);
1140 
1141   typedef struct {
1142     double left;
1143     double right;
1144     double add_result;
1145     double sub_result;
1146     double mul_result;
1147     double div_result;
1148   } T;
1149   T t;
1150 
1151   // Create a function that makes the four basic operations.
1152   Assembler assm(isolate, NULL, 0);
1153 
1154   // Ensure FPSCR state (as JSEntryStub does).
1155   Label fpscr_done;
1156   __ vmrs(r1);
1157   __ tst(r1, Operand(kVFPDefaultNaNModeControlBit));
1158   __ b(ne, &fpscr_done);
1159   __ orr(r1, r1, Operand(kVFPDefaultNaNModeControlBit));
1160   __ vmsr(r1);
1161   __ bind(&fpscr_done);
1162 
1163   __ vldr(d0, r0, OFFSET_OF(T, left));
1164   __ vldr(d1, r0, OFFSET_OF(T, right));
1165   __ vadd(d2, d0, d1);
1166   __ vstr(d2, r0, OFFSET_OF(T, add_result));
1167   __ vsub(d2, d0, d1);
1168   __ vstr(d2, r0, OFFSET_OF(T, sub_result));
1169   __ vmul(d2, d0, d1);
1170   __ vstr(d2, r0, OFFSET_OF(T, mul_result));
1171   __ vdiv(d2, d0, d1);
1172   __ vstr(d2, r0, OFFSET_OF(T, div_result));
1173 
1174   __ mov(pc, Operand(lr));
1175 
1176   CodeDesc desc;
1177   assm.GetCode(&desc);
1178   Handle<Code> code = isolate->factory()->NewCode(
1179       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
1180 #ifdef DEBUG
1181   OFStream os(stdout);
1182   code->Print(os);
1183 #endif
1184   F3 f = FUNCTION_CAST<F3>(code->entry());
1185   t.left = bit_cast<double>(kHoleNanInt64);
1186   t.right = 1;
1187   t.add_result = 0;
1188   t.sub_result = 0;
1189   t.mul_result = 0;
1190   t.div_result = 0;
1191   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
1192   USE(dummy);
1193   const uint32_t kArmNanUpper32 = 0x7ff80000;
1194   const uint32_t kArmNanLower32 = 0x00000000;
1195 #ifdef DEBUG
1196   const uint64_t kArmNanInt64 =
1197       (static_cast<uint64_t>(kArmNanUpper32) << 32) | kArmNanLower32;
1198   DCHECK(kArmNanInt64 != kHoleNanInt64);
1199 #endif
1200   // With VFP2 the sign of the canonicalized Nan is undefined. So
1201   // we remove the sign bit for the upper tests.
1202   CHECK_EQ(kArmNanUpper32,
1203            (bit_cast<int64_t>(t.add_result) >> 32) & 0x7fffffff);
1204   CHECK_EQ(kArmNanLower32, bit_cast<int64_t>(t.add_result) & 0xffffffffu);
1205   CHECK_EQ(kArmNanUpper32,
1206            (bit_cast<int64_t>(t.sub_result) >> 32) & 0x7fffffff);
1207   CHECK_EQ(kArmNanLower32, bit_cast<int64_t>(t.sub_result) & 0xffffffffu);
1208   CHECK_EQ(kArmNanUpper32,
1209            (bit_cast<int64_t>(t.mul_result) >> 32) & 0x7fffffff);
1210   CHECK_EQ(kArmNanLower32, bit_cast<int64_t>(t.mul_result) & 0xffffffffu);
1211   CHECK_EQ(kArmNanUpper32,
1212            (bit_cast<int64_t>(t.div_result) >> 32) & 0x7fffffff);
1213   CHECK_EQ(kArmNanLower32, bit_cast<int64_t>(t.div_result) & 0xffffffffu);
1214 }
1215 
1216 
1217 TEST(15) {
1218   // Test the Neon instructions.
1219   CcTest::InitializeVM();
1220   Isolate* isolate = CcTest::i_isolate();
1221   HandleScope scope(isolate);
1222 
1223   typedef struct {
1224     uint32_t src0;
1225     uint32_t src1;
1226     uint32_t src2;
1227     uint32_t src3;
1228     uint32_t src4;
1229     uint32_t src5;
1230     uint32_t src6;
1231     uint32_t src7;
1232     uint32_t dst0;
1233     uint32_t dst1;
1234     uint32_t dst2;
1235     uint32_t dst3;
1236     uint32_t dst4;
1237     uint32_t dst5;
1238     uint32_t dst6;
1239     uint32_t dst7;
1240     uint32_t srcA0;
1241     uint32_t srcA1;
1242     uint32_t dstA0;
1243     uint32_t dstA1;
1244     uint32_t dstA2;
1245     uint32_t dstA3;
1246     uint32_t dstA4;
1247     uint32_t dstA5;
1248     uint32_t dstA6;
1249     uint32_t dstA7;
1250   } T;
1251   T t;
1252 
1253   // Create a function that accepts &t, and loads, manipulates, and stores
1254   // the doubles and floats.
1255   Assembler assm(isolate, NULL, 0);
1256 
1257 
1258   if (CpuFeatures::IsSupported(NEON)) {
1259     CpuFeatureScope scope(&assm, NEON);
1260 
1261     __ stm(db_w, sp, r4.bit() | lr.bit());
1262     // Move 32 bytes with neon.
1263     __ add(r4, r0, Operand(OFFSET_OF(T, src0)));
1264     __ vld1(Neon8, NeonListOperand(d0, 4), NeonMemOperand(r4));
1265     __ add(r4, r0, Operand(OFFSET_OF(T, dst0)));
1266     __ vst1(Neon8, NeonListOperand(d0, 4), NeonMemOperand(r4));
1267 
1268     // Expand 8 bytes into 8 words(16 bits).
1269     __ add(r4, r0, Operand(OFFSET_OF(T, srcA0)));
1270     __ vld1(Neon8, NeonListOperand(d0), NeonMemOperand(r4));
1271     __ vmovl(NeonU8, q0, d0);
1272     __ add(r4, r0, Operand(OFFSET_OF(T, dstA0)));
1273     __ vst1(Neon8, NeonListOperand(d0, 2), NeonMemOperand(r4));
1274 
1275     // The same expansion, but with different source and destination registers.
1276     __ add(r4, r0, Operand(OFFSET_OF(T, srcA0)));
1277     __ vld1(Neon8, NeonListOperand(d1), NeonMemOperand(r4));
1278     __ vmovl(NeonU8, q1, d1);
1279     __ add(r4, r0, Operand(OFFSET_OF(T, dstA4)));
1280     __ vst1(Neon8, NeonListOperand(d2, 2), NeonMemOperand(r4));
1281 
1282     __ ldm(ia_w, sp, r4.bit() | pc.bit());
1283 
1284     CodeDesc desc;
1285     assm.GetCode(&desc);
1286     Handle<Code> code = isolate->factory()->NewCode(
1287         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
1288 #ifdef DEBUG
1289     OFStream os(stdout);
1290     code->Print(os);
1291 #endif
1292     F3 f = FUNCTION_CAST<F3>(code->entry());
1293     t.src0 = 0x01020304;
1294     t.src1 = 0x11121314;
1295     t.src2 = 0x21222324;
1296     t.src3 = 0x31323334;
1297     t.src4 = 0x41424344;
1298     t.src5 = 0x51525354;
1299     t.src6 = 0x61626364;
1300     t.src7 = 0x71727374;
1301     t.dst0 = 0;
1302     t.dst1 = 0;
1303     t.dst2 = 0;
1304     t.dst3 = 0;
1305     t.dst4 = 0;
1306     t.dst5 = 0;
1307     t.dst6 = 0;
1308     t.dst7 = 0;
1309     t.srcA0 = 0x41424344;
1310     t.srcA1 = 0x81828384;
1311     t.dstA0 = 0;
1312     t.dstA1 = 0;
1313     t.dstA2 = 0;
1314     t.dstA3 = 0;
1315     t.dstA4 = 0;
1316     t.dstA5 = 0;
1317     t.dstA6 = 0;
1318     t.dstA7 = 0;
1319     Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
1320     USE(dummy);
1321     CHECK_EQ(0x01020304, t.dst0);
1322     CHECK_EQ(0x11121314, t.dst1);
1323     CHECK_EQ(0x21222324, t.dst2);
1324     CHECK_EQ(0x31323334, t.dst3);
1325     CHECK_EQ(0x41424344, t.dst4);
1326     CHECK_EQ(0x51525354, t.dst5);
1327     CHECK_EQ(0x61626364, t.dst6);
1328     CHECK_EQ(0x71727374, t.dst7);
1329     CHECK_EQ(0x00430044, t.dstA0);
1330     CHECK_EQ(0x00410042, t.dstA1);
1331     CHECK_EQ(0x00830084, t.dstA2);
1332     CHECK_EQ(0x00810082, t.dstA3);
1333     CHECK_EQ(0x00430044, t.dstA4);
1334     CHECK_EQ(0x00410042, t.dstA5);
1335     CHECK_EQ(0x00830084, t.dstA6);
1336     CHECK_EQ(0x00810082, t.dstA7);
1337   }
1338 }
1339 
1340 
1341 TEST(16) {
1342   // Test the pkh, uxtb, uxtab and uxtb16 instructions.
1343   CcTest::InitializeVM();
1344   Isolate* isolate = CcTest::i_isolate();
1345   HandleScope scope(isolate);
1346 
1347   typedef struct {
1348     uint32_t src0;
1349     uint32_t src1;
1350     uint32_t src2;
1351     uint32_t dst0;
1352     uint32_t dst1;
1353     uint32_t dst2;
1354     uint32_t dst3;
1355     uint32_t dst4;
1356   } T;
1357   T t;
1358 
1359   // Create a function that accepts &t, and loads, manipulates, and stores
1360   // the doubles and floats.
1361   Assembler assm(isolate, NULL, 0);
1362 
1363   __ stm(db_w, sp, r4.bit() | lr.bit());
1364 
1365   __ mov(r4, Operand(r0));
1366   __ ldr(r0, MemOperand(r4, OFFSET_OF(T, src0)));
1367   __ ldr(r1, MemOperand(r4, OFFSET_OF(T, src1)));
1368 
1369   __ pkhbt(r2, r0, Operand(r1, LSL, 8));
1370   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst0)));
1371 
1372   __ pkhtb(r2, r0, Operand(r1, ASR, 8));
1373   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst1)));
1374 
1375   __ uxtb16(r2, Operand(r0, ROR, 8));
1376   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst2)));
1377 
1378   __ uxtb(r2, Operand(r0, ROR, 8));
1379   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst3)));
1380 
1381   __ ldr(r0, MemOperand(r4, OFFSET_OF(T, src2)));
1382   __ uxtab(r2, r0, Operand(r1, ROR, 8));
1383   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst4)));
1384 
1385   __ ldm(ia_w, sp, r4.bit() | pc.bit());
1386 
1387   CodeDesc desc;
1388   assm.GetCode(&desc);
1389   Handle<Code> code = isolate->factory()->NewCode(
1390       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
1391 #ifdef DEBUG
1392   OFStream os(stdout);
1393   code->Print(os);
1394 #endif
1395   F3 f = FUNCTION_CAST<F3>(code->entry());
1396   t.src0 = 0x01020304;
1397   t.src1 = 0x11121314;
1398   t.src2 = 0x11121300;
1399   t.dst0 = 0;
1400   t.dst1 = 0;
1401   t.dst2 = 0;
1402   t.dst3 = 0;
1403   t.dst4 = 0;
1404   Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
1405   USE(dummy);
1406   CHECK_EQ(0x12130304, t.dst0);
1407   CHECK_EQ(0x01021213, t.dst1);
1408   CHECK_EQ(0x00010003, t.dst2);
1409   CHECK_EQ(0x00000003, t.dst3);
1410   CHECK_EQ(0x11121313, t.dst4);
1411 }
1412 
1413 
1414 TEST(17) {
1415   // Test generating labels at high addresses.
1416   // Should not assert.
1417   CcTest::InitializeVM();
1418   Isolate* isolate = CcTest::i_isolate();
1419   HandleScope scope(isolate);
1420 
1421   // Generate a code segment that will be longer than 2^24 bytes.
1422   Assembler assm(isolate, NULL, 0);
1423   for (size_t i = 0; i < 1 << 23 ; ++i) {  // 2^23
1424     __ nop();
1425   }
1426 
1427   Label target;
1428   __ b(eq, &target);
1429   __ bind(&target);
1430   __ nop();
1431 }
1432 
1433 
1434 #define TEST_SDIV(expected_, dividend_, divisor_) \
1435     t.dividend = dividend_; \
1436     t.divisor = divisor_; \
1437     t.result = 0; \
1438     dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); \
1439     CHECK_EQ(expected_, t.result);
1440 
1441 
1442 TEST(18) {
1443   // Test the sdiv.
1444   CcTest::InitializeVM();
1445   Isolate* isolate = CcTest::i_isolate();
1446   HandleScope scope(isolate);
1447 
1448   typedef struct {
1449     uint32_t dividend;
1450     uint32_t divisor;
1451     uint32_t result;
1452   } T;
1453   T t;
1454 
1455   Assembler assm(isolate, NULL, 0);
1456 
1457   if (CpuFeatures::IsSupported(SUDIV)) {
1458     CpuFeatureScope scope(&assm, SUDIV);
1459 
1460     __ mov(r3, Operand(r0));
1461 
1462     __ ldr(r0, MemOperand(r3, OFFSET_OF(T, dividend)));
1463     __ ldr(r1, MemOperand(r3, OFFSET_OF(T, divisor)));
1464 
1465     __ sdiv(r2, r0, r1);
1466     __ str(r2, MemOperand(r3, OFFSET_OF(T, result)));
1467 
1468   __ bx(lr);
1469 
1470     CodeDesc desc;
1471     assm.GetCode(&desc);
1472     Handle<Code> code = isolate->factory()->NewCode(
1473         desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
1474 #ifdef DEBUG
1475     OFStream os(stdout);
1476     code->Print(os);
1477 #endif
1478     F3 f = FUNCTION_CAST<F3>(code->entry());
1479     Object* dummy;
1480     TEST_SDIV(1073741824, kMinInt, -2);
1481     TEST_SDIV(kMinInt, kMinInt, -1);
1482     TEST_SDIV(5, 10, 2);
1483     TEST_SDIV(3, 10, 3);
1484     TEST_SDIV(-5, 10, -2);
1485     TEST_SDIV(-3, 10, -3);
1486     TEST_SDIV(-5, -10, 2);
1487     TEST_SDIV(-3, -10, 3);
1488     TEST_SDIV(5, -10, -2);
1489     TEST_SDIV(3, -10, -3);
1490     USE(dummy);
1491   }
1492 }
1493 
1494 
1495 #undef TEST_SDIV
1496 
1497 
TEST(code_relative_offset)1498 TEST(code_relative_offset) {
1499   // Test extracting the offset of a label from the beginning of the code
1500   // in a register.
1501   CcTest::InitializeVM();
1502   Isolate* isolate = CcTest::i_isolate();
1503   HandleScope scope(isolate);
1504   // Initialize a code object that will contain the code.
1505   Handle<Object> code_object(isolate->heap()->undefined_value(), isolate);
1506 
1507   Assembler assm(isolate, NULL, 0);
1508 
1509   Label start, target_away, target_faraway;
1510 
1511   __ stm(db_w, sp, r4.bit() | r5.bit() | lr.bit());
1512 
1513   // r3 is used as the address zero, the test will crash when we load it.
1514   __ mov(r3, Operand::Zero());
1515 
1516   // r5 will be a pointer to the start of the code.
1517   __ mov(r5, Operand(code_object));
1518   __ mov_label_offset(r4, &start);
1519 
1520   __ mov_label_offset(r1, &target_faraway);
1521   __ str(r1, MemOperand(sp, kPointerSize, NegPreIndex));
1522 
1523   __ mov_label_offset(r1, &target_away);
1524 
1525   // Jump straight to 'target_away' the first time and use the relative
1526   // position the second time. This covers the case when extracting the
1527   // position of a label which is linked.
1528   __ mov(r2, Operand::Zero());
1529   __ bind(&start);
1530   __ cmp(r2, Operand::Zero());
1531   __ b(eq, &target_away);
1532   __ add(pc, r5, r1);
1533   // Emit invalid instructions to push the label between 2^8 and 2^16
1534   // instructions away. The test will crash if they are reached.
1535   for (int i = 0; i < (1 << 10); i++) {
1536     __ ldr(r3, MemOperand(r3));
1537   }
1538   __ bind(&target_away);
1539   // This will be hit twice: r0 = r0 + 5 + 5.
1540   __ add(r0, r0, Operand(5));
1541 
1542   __ ldr(r1, MemOperand(sp, kPointerSize, PostIndex), ne);
1543   __ add(pc, r5, r4, LeaveCC, ne);
1544 
1545   __ mov(r2, Operand(1));
1546   __ b(&start);
1547   // Emit invalid instructions to push the label between 2^16 and 2^24
1548   // instructions away. The test will crash if they are reached.
1549   for (int i = 0; i < (1 << 21); i++) {
1550     __ ldr(r3, MemOperand(r3));
1551   }
1552   __ bind(&target_faraway);
1553   // r0 = r0 + 5 + 5 + 11
1554   __ add(r0, r0, Operand(11));
1555 
1556   __ ldm(ia_w, sp, r4.bit() | r5.bit() | pc.bit());
1557 
1558   CodeDesc desc;
1559   assm.GetCode(&desc);
1560   Handle<Code> code = isolate->factory()->NewCode(
1561       desc, Code::ComputeFlags(Code::STUB), code_object);
1562   F1 f = FUNCTION_CAST<F1>(code->entry());
1563   int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 21, 0, 0, 0, 0));
1564   ::printf("f() = %d\n", res);
1565   CHECK_EQ(42, res);
1566 }
1567 
1568 #undef __
1569