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