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