• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013, ARM Limited
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <math.h>
31 #include <float.h>
32 
33 #include "cctest.h"
34 #include "test-utils-a64.h"
35 #include "a64/macro-assembler-a64.h"
36 #include "a64/simulator-a64.h"
37 #include "a64/debugger-a64.h"
38 #include "a64/disasm-a64.h"
39 #include "a64/cpu-a64.h"
40 
41 namespace vixl {
42 
43 // Test infrastructure.
44 //
45 // Tests are functions which accept no parameters and have no return values.
46 // The testing code should not perform an explicit return once completed. For
47 // example to test the mov immediate instruction a very simple test would be:
48 //
49 //   TEST(mov_x0_one) {
50 //     SETUP();
51 //
52 //     START();
53 //     __ mov(x0, Operand(1));
54 //     END();
55 //
56 //     RUN();
57 //
58 //     ASSERT_EQUAL_64(1, x0);
59 //
60 //     TEARDOWN();
61 //   }
62 //
63 // Within a START ... END block all registers but sp can be modified. sp has to
64 // be explicitly saved/restored. The END() macro replaces the function return
65 // so it may appear multiple times in a test if the test has multiple exit
66 // points.
67 //
68 // Once the test has been run all integer and floating point registers as well
69 // as flags are accessible through a RegisterDump instance, see
70 // utils-a64.cc for more info on RegisterDump.
71 //
72 // We provide some helper assert to handle common cases:
73 //
74 //   ASSERT_EQUAL_32(int32_t, int_32t)
75 //   ASSERT_EQUAL_FP32(float, float)
76 //   ASSERT_EQUAL_32(int32_t, W register)
77 //   ASSERT_EQUAL_FP32(float, S register)
78 //   ASSERT_EQUAL_64(int64_t, int_64t)
79 //   ASSERT_EQUAL_FP64(double, double)
80 //   ASSERT_EQUAL_64(int64_t, X register)
81 //   ASSERT_EQUAL_64(X register, X register)
82 //   ASSERT_EQUAL_FP64(double, D register)
83 //
84 // e.g. ASSERT_EQUAL_64(0.5, d30);
85 //
86 // If more advanced computation is required before the assert then access the
87 // RegisterDump named core directly:
88 //
89 //   ASSERT_EQUAL_64(0x1234, core->reg_x0() & 0xffff);
90 
91 
92 #define __ masm.
93 #define TEST(name)  TEST_(ASM_##name)
94 
95 #define BUF_SIZE (4096)
96 
97 #define SETUP() SETUP_SIZE(BUF_SIZE)
98 
99 #ifdef USE_SIMULATOR
100 
101 // Run tests with the simulator.
102 #define SETUP_SIZE(buf_size)                                                   \
103   byte* buf = new byte[buf_size];                                              \
104   MacroAssembler masm(buf, buf_size);                                          \
105   Decoder decoder;                                                             \
106   Simulator* simulator = NULL;                                                 \
107   if (Cctest::run_debugger()) {                                                \
108     simulator = new Debugger(&decoder);                                        \
109   } else {                                                                     \
110     simulator = new Simulator(&decoder);                                       \
111     simulator->set_disasm_trace(Cctest::trace_sim());                          \
112   }                                                                            \
113   simulator->set_coloured_trace(Cctest::coloured_trace());                     \
114   simulator->set_instruction_stats(Cctest::instruction_stats());               \
115   RegisterDump core
116 
117 #define START()                                                                \
118   masm.Reset();                                                                \
119   simulator->ResetState();                                                     \
120   __ PushCalleeSavedRegisters();                                               \
121   if (Cctest::run_debugger()) {                                                \
122     if (Cctest::trace_reg()) {                                                 \
123       __ Trace(LOG_STATE, TRACE_ENABLE);                                       \
124     }                                                                          \
125     if (Cctest::trace_sim()) {                                                 \
126       __ Trace(LOG_DISASM, TRACE_ENABLE);                                      \
127     }                                                                          \
128   }                                                                            \
129   if (Cctest::instruction_stats()) {                                           \
130     __ EnableInstrumentation();                                                \
131   }
132 
133 #define END()                                                                  \
134   if (Cctest::instruction_stats()) {                                           \
135     __ DisableInstrumentation();                                               \
136   }                                                                            \
137   if (Cctest::run_debugger()) {                                                \
138     __ Trace(LOG_ALL, TRACE_DISABLE);                                          \
139   }                                                                            \
140   core.Dump(&masm);                                                            \
141   __ PopCalleeSavedRegisters();                                                \
142   __ Ret();                                                                    \
143   masm.FinalizeCode()
144 
145 #define RUN()                                                                  \
146   simulator->RunFrom(reinterpret_cast<Instruction*>(buf))
147 
148 #define TEARDOWN()                                                             \
149   delete simulator;                                                            \
150   delete[] buf;
151 
152 #else  // ifdef USE_SIMULATOR.
153 // Run the test on real hardware or models.
154 #define SETUP_SIZE(size)                                                       \
155   size_t buf_size = size;                                                      \
156   byte* buf = new byte[buf_size];                                              \
157   MacroAssembler masm(buf, buf_size);                                          \
158   RegisterDump core;                                                           \
159   CPU::SetUp()
160 
161 #define START()                                                                \
162   masm.Reset();                                                                \
163   __ PushCalleeSavedRegisters()
164 
165 #define END()                                                                  \
166   core.Dump(&masm);                                                            \
167   __ PopCalleeSavedRegisters();                                                \
168   __ Ret();                                                                    \
169   masm.FinalizeCode()
170 
171 #define RUN()                                                                  \
172   CPU::EnsureIAndDCacheCoherency(buf, buf_size);                               \
173   {                                                                            \
174     void (*test_function)(void);                                               \
175     VIXL_ASSERT(sizeof(buf) == sizeof(test_function));                         \
176     memcpy(&test_function, &buf, sizeof(buf));                                 \
177     test_function();                                                           \
178   }
179 
180 #define TEARDOWN()                                                             \
181   delete[] buf;
182 
183 #endif  // ifdef USE_SIMULATOR.
184 
185 #define ASSERT_EQUAL_NZCV(expected)                                            \
186   assert(EqualNzcv(expected, core.flags_nzcv()))
187 
188 #define ASSERT_EQUAL_REGISTERS(expected)                                       \
189   assert(EqualRegisters(&expected, &core))
190 
191 #define ASSERT_EQUAL_32(expected, result)                                      \
192   assert(Equal32(static_cast<uint32_t>(expected), &core, result))
193 
194 #define ASSERT_EQUAL_FP32(expected, result)                                    \
195   assert(EqualFP32(expected, &core, result))
196 
197 #define ASSERT_EQUAL_64(expected, result)                                      \
198   assert(Equal64(expected, &core, result))
199 
200 #define ASSERT_EQUAL_FP64(expected, result)                                    \
201   assert(EqualFP64(expected, &core, result))
202 
203 #define ASSERT_LITERAL_POOL_SIZE(expected)                                     \
204   assert((expected) == (__ LiteralPoolSize()))
205 
206 
TEST(stack_ops)207 TEST(stack_ops) {
208   SETUP();
209 
210   START();
211   // save sp.
212   __ Mov(x29, sp);
213 
214   // Set the sp to a known value.
215   __ Mov(sp, 0x1004);
216   __ Mov(x0, sp);
217 
218   // Add immediate to the sp, and move the result to a normal register.
219   __ Add(sp, sp, 0x50);
220   __ Mov(x1, sp);
221 
222   // Add extended to the sp, and move the result to a normal register.
223   __ Mov(x17, 0xfff);
224   __ Add(sp, sp, Operand(x17, SXTB));
225   __ Mov(x2, sp);
226 
227   // Create an sp using a logical instruction, and move to normal register.
228   __ Orr(sp, xzr, 0x1fff);
229   __ Mov(x3, sp);
230 
231   // Write wsp using a logical instruction.
232   __ Orr(wsp, wzr, 0xfffffff8);
233   __ Mov(x4, sp);
234 
235   // Write sp, and read back wsp.
236   __ Orr(sp, xzr, 0xfffffff8);
237   __ Mov(w5, wsp);
238 
239   //  restore sp.
240   __ Mov(sp, x29);
241   END();
242 
243   RUN();
244 
245   ASSERT_EQUAL_64(0x1004, x0);
246   ASSERT_EQUAL_64(0x1054, x1);
247   ASSERT_EQUAL_64(0x1053, x2);
248   ASSERT_EQUAL_64(0x1fff, x3);
249   ASSERT_EQUAL_64(0xfffffff8, x4);
250   ASSERT_EQUAL_64(0xfffffff8, x5);
251 
252   TEARDOWN();
253 }
254 
255 
TEST(mvn)256 TEST(mvn) {
257   SETUP();
258 
259   START();
260   __ Mvn(w0, 0xfff);
261   __ Mvn(x1, 0xfff);
262   __ Mvn(w2, Operand(w0, LSL, 1));
263   __ Mvn(x3, Operand(x1, LSL, 2));
264   __ Mvn(w4, Operand(w0, LSR, 3));
265   __ Mvn(x5, Operand(x1, LSR, 4));
266   __ Mvn(w6, Operand(w0, ASR, 11));
267   __ Mvn(x7, Operand(x1, ASR, 12));
268   __ Mvn(w8, Operand(w0, ROR, 13));
269   __ Mvn(x9, Operand(x1, ROR, 14));
270   __ Mvn(w10, Operand(w2, UXTB));
271   __ Mvn(x11, Operand(x2, SXTB, 1));
272   __ Mvn(w12, Operand(w2, UXTH, 2));
273   __ Mvn(x13, Operand(x2, SXTH, 3));
274   __ Mvn(x14, Operand(w2, UXTW, 4));
275   __ Mvn(x15, Operand(w2, SXTW, 4));
276   END();
277 
278   RUN();
279 
280   ASSERT_EQUAL_64(0xfffff000, x0);
281   ASSERT_EQUAL_64(0xfffffffffffff000, x1);
282   ASSERT_EQUAL_64(0x00001fff, x2);
283   ASSERT_EQUAL_64(0x0000000000003fff, x3);
284   ASSERT_EQUAL_64(0xe00001ff, x4);
285   ASSERT_EQUAL_64(0xf0000000000000ff, x5);
286   ASSERT_EQUAL_64(0x00000001, x6);
287   ASSERT_EQUAL_64(0x0000000000000000, x7);
288   ASSERT_EQUAL_64(0x7ff80000, x8);
289   ASSERT_EQUAL_64(0x3ffc000000000000, x9);
290   ASSERT_EQUAL_64(0xffffff00, x10);
291   ASSERT_EQUAL_64(0x0000000000000001, x11);
292   ASSERT_EQUAL_64(0xffff8003, x12);
293   ASSERT_EQUAL_64(0xffffffffffff0007, x13);
294   ASSERT_EQUAL_64(0xfffffffffffe000f, x14);
295   ASSERT_EQUAL_64(0xfffffffffffe000f, x15);
296 
297   TEARDOWN();
298 }
299 
300 
TEST(mov_imm_w)301 TEST(mov_imm_w) {
302   SETUP();
303 
304   START();
305   __ Mov(w0, 0xffffffff);
306   __ Mov(w1, 0xffff1234);
307   __ Mov(w2, 0x1234ffff);
308   __ Mov(w3, 0x00000000);
309   __ Mov(w4, 0x00001234);
310   __ Mov(w5, 0x12340000);
311   __ Mov(w6, 0x12345678);
312   END();
313 
314   RUN();
315 
316   ASSERT_EQUAL_64(0xffffffff, x0);
317   ASSERT_EQUAL_64(0xffff1234, x1);
318   ASSERT_EQUAL_64(0x1234ffff, x2);
319   ASSERT_EQUAL_64(0x00000000, x3);
320   ASSERT_EQUAL_64(0x00001234, x4);
321   ASSERT_EQUAL_64(0x12340000, x5);
322   ASSERT_EQUAL_64(0x12345678, x6);
323 
324   TEARDOWN();
325 }
326 
327 
TEST(mov_imm_x)328 TEST(mov_imm_x) {
329   SETUP();
330 
331   START();
332   __ Mov(x0, 0xffffffffffffffff);
333   __ Mov(x1, 0xffffffffffff1234);
334   __ Mov(x2, 0xffffffff12345678);
335   __ Mov(x3, 0xffff1234ffff5678);
336   __ Mov(x4, 0x1234ffffffff5678);
337   __ Mov(x5, 0x1234ffff5678ffff);
338   __ Mov(x6, 0x12345678ffffffff);
339   __ Mov(x7, 0x1234ffffffffffff);
340   __ Mov(x8, 0x123456789abcffff);
341   __ Mov(x9, 0x12345678ffff9abc);
342   __ Mov(x10, 0x1234ffff56789abc);
343   __ Mov(x11, 0xffff123456789abc);
344   __ Mov(x12, 0x0000000000000000);
345   __ Mov(x13, 0x0000000000001234);
346   __ Mov(x14, 0x0000000012345678);
347   __ Mov(x15, 0x0000123400005678);
348   __ Mov(x18, 0x1234000000005678);
349   __ Mov(x19, 0x1234000056780000);
350   __ Mov(x20, 0x1234567800000000);
351   __ Mov(x21, 0x1234000000000000);
352   __ Mov(x22, 0x123456789abc0000);
353   __ Mov(x23, 0x1234567800009abc);
354   __ Mov(x24, 0x1234000056789abc);
355   __ Mov(x25, 0x0000123456789abc);
356   __ Mov(x26, 0x123456789abcdef0);
357   __ Mov(x27, 0xffff000000000001);
358   __ Mov(x28, 0x8000ffff00000000);
359   END();
360 
361   RUN();
362 
363   ASSERT_EQUAL_64(0xffffffffffff1234, x1);
364   ASSERT_EQUAL_64(0xffffffff12345678, x2);
365   ASSERT_EQUAL_64(0xffff1234ffff5678, x3);
366   ASSERT_EQUAL_64(0x1234ffffffff5678, x4);
367   ASSERT_EQUAL_64(0x1234ffff5678ffff, x5);
368   ASSERT_EQUAL_64(0x12345678ffffffff, x6);
369   ASSERT_EQUAL_64(0x1234ffffffffffff, x7);
370   ASSERT_EQUAL_64(0x123456789abcffff, x8);
371   ASSERT_EQUAL_64(0x12345678ffff9abc, x9);
372   ASSERT_EQUAL_64(0x1234ffff56789abc, x10);
373   ASSERT_EQUAL_64(0xffff123456789abc, x11);
374   ASSERT_EQUAL_64(0x0000000000000000, x12);
375   ASSERT_EQUAL_64(0x0000000000001234, x13);
376   ASSERT_EQUAL_64(0x0000000012345678, x14);
377   ASSERT_EQUAL_64(0x0000123400005678, x15);
378   ASSERT_EQUAL_64(0x1234000000005678, x18);
379   ASSERT_EQUAL_64(0x1234000056780000, x19);
380   ASSERT_EQUAL_64(0x1234567800000000, x20);
381   ASSERT_EQUAL_64(0x1234000000000000, x21);
382   ASSERT_EQUAL_64(0x123456789abc0000, x22);
383   ASSERT_EQUAL_64(0x1234567800009abc, x23);
384   ASSERT_EQUAL_64(0x1234000056789abc, x24);
385   ASSERT_EQUAL_64(0x0000123456789abc, x25);
386   ASSERT_EQUAL_64(0x123456789abcdef0, x26);
387   ASSERT_EQUAL_64(0xffff000000000001, x27);
388   ASSERT_EQUAL_64(0x8000ffff00000000, x28);
389 
390 
391   TEARDOWN();
392 }
393 
394 
TEST(mov)395 TEST(mov) {
396   SETUP();
397 
398   START();
399   __ Mov(x0, 0xffffffffffffffff);
400   __ Mov(x1, 0xffffffffffffffff);
401   __ Mov(x2, 0xffffffffffffffff);
402   __ Mov(x3, 0xffffffffffffffff);
403 
404   __ Mov(x0, 0x0123456789abcdef);
405 
406   __ movz(x1, UINT64_C(0xabcd) << 16);
407   __ movk(x2, UINT64_C(0xabcd) << 32);
408   __ movn(x3, UINT64_C(0xabcd) << 48);
409 
410   __ Mov(x4, 0x0123456789abcdef);
411   __ Mov(x5, x4);
412 
413   __ Mov(w6, -1);
414 
415   // Test that moves back to the same register have the desired effect. This
416   // is a no-op for X registers, and a truncation for W registers.
417   __ Mov(x7, 0x0123456789abcdef);
418   __ Mov(x7, x7);
419   __ Mov(x8, 0x0123456789abcdef);
420   __ Mov(w8, w8);
421   __ Mov(x9, 0x0123456789abcdef);
422   __ Mov(x9, Operand(x9));
423   __ Mov(x10, 0x0123456789abcdef);
424   __ Mov(w10, Operand(w10));
425 
426   __ Mov(w11, 0xfff);
427   __ Mov(x12, 0xfff);
428   __ Mov(w13, Operand(w11, LSL, 1));
429   __ Mov(x14, Operand(x12, LSL, 2));
430   __ Mov(w15, Operand(w11, LSR, 3));
431   __ Mov(x18, Operand(x12, LSR, 4));
432   __ Mov(w19, Operand(w11, ASR, 11));
433   __ Mov(x20, Operand(x12, ASR, 12));
434   __ Mov(w21, Operand(w11, ROR, 13));
435   __ Mov(x22, Operand(x12, ROR, 14));
436   __ Mov(w23, Operand(w13, UXTB));
437   __ Mov(x24, Operand(x13, SXTB, 1));
438   __ Mov(w25, Operand(w13, UXTH, 2));
439   __ Mov(x26, Operand(x13, SXTH, 3));
440   __ Mov(x27, Operand(w13, UXTW, 4));
441 
442   __ Mov(x28, 0x0123456789abcdef);
443   __ Mov(w28, w28, kDiscardForSameWReg);
444   END();
445 
446   RUN();
447 
448   ASSERT_EQUAL_64(0x0123456789abcdef, x0);
449   ASSERT_EQUAL_64(0x00000000abcd0000, x1);
450   ASSERT_EQUAL_64(0xffffabcdffffffff, x2);
451   ASSERT_EQUAL_64(0x5432ffffffffffff, x3);
452   ASSERT_EQUAL_64(x4, x5);
453   ASSERT_EQUAL_32(-1, w6);
454   ASSERT_EQUAL_64(0x0123456789abcdef, x7);
455   ASSERT_EQUAL_32(0x89abcdef, w8);
456   ASSERT_EQUAL_64(0x0123456789abcdef, x9);
457   ASSERT_EQUAL_32(0x89abcdef, w10);
458   ASSERT_EQUAL_64(0x00000fff, x11);
459   ASSERT_EQUAL_64(0x0000000000000fff, x12);
460   ASSERT_EQUAL_64(0x00001ffe, x13);
461   ASSERT_EQUAL_64(0x0000000000003ffc, x14);
462   ASSERT_EQUAL_64(0x000001ff, x15);
463   ASSERT_EQUAL_64(0x00000000000000ff, x18);
464   ASSERT_EQUAL_64(0x00000001, x19);
465   ASSERT_EQUAL_64(0x0000000000000000, x20);
466   ASSERT_EQUAL_64(0x7ff80000, x21);
467   ASSERT_EQUAL_64(0x3ffc000000000000, x22);
468   ASSERT_EQUAL_64(0x000000fe, x23);
469   ASSERT_EQUAL_64(0xfffffffffffffffc, x24);
470   ASSERT_EQUAL_64(0x00007ff8, x25);
471   ASSERT_EQUAL_64(0x000000000000fff0, x26);
472   ASSERT_EQUAL_64(0x000000000001ffe0, x27);
473   ASSERT_EQUAL_64(0x0123456789abcdef, x28);
474 
475   TEARDOWN();
476 }
477 
478 
TEST(orr)479 TEST(orr) {
480   SETUP();
481 
482   START();
483   __ Mov(x0, 0xf0f0);
484   __ Mov(x1, 0xf00000ff);
485 
486   __ Orr(x2, x0, Operand(x1));
487   __ Orr(w3, w0, Operand(w1, LSL, 28));
488   __ Orr(x4, x0, Operand(x1, LSL, 32));
489   __ Orr(x5, x0, Operand(x1, LSR, 4));
490   __ Orr(w6, w0, Operand(w1, ASR, 4));
491   __ Orr(x7, x0, Operand(x1, ASR, 4));
492   __ Orr(w8, w0, Operand(w1, ROR, 12));
493   __ Orr(x9, x0, Operand(x1, ROR, 12));
494   __ Orr(w10, w0, 0xf);
495   __ Orr(x11, x0, 0xf0000000f0000000);
496   END();
497 
498   RUN();
499 
500   ASSERT_EQUAL_64(0x00000000f000f0ff, x2);
501   ASSERT_EQUAL_64(0xf000f0f0, x3);
502   ASSERT_EQUAL_64(0xf00000ff0000f0f0, x4);
503   ASSERT_EQUAL_64(0x000000000f00f0ff, x5);
504   ASSERT_EQUAL_64(0xff00f0ff, x6);
505   ASSERT_EQUAL_64(0x000000000f00f0ff, x7);
506   ASSERT_EQUAL_64(0x0ffff0f0, x8);
507   ASSERT_EQUAL_64(0x0ff00000000ff0f0, x9);
508   ASSERT_EQUAL_64(0x0000f0ff, x10);
509   ASSERT_EQUAL_64(0xf0000000f000f0f0, x11);
510 
511   TEARDOWN();
512 }
513 
514 
TEST(orr_extend)515 TEST(orr_extend) {
516   SETUP();
517 
518   START();
519   __ Mov(x0, 1);
520   __ Mov(x1, 0x8000000080008080);
521   __ Orr(w6, w0, Operand(w1, UXTB));
522   __ Orr(x7, x0, Operand(x1, UXTH, 1));
523   __ Orr(w8, w0, Operand(w1, UXTW, 2));
524   __ Orr(x9, x0, Operand(x1, UXTX, 3));
525   __ Orr(w10, w0, Operand(w1, SXTB));
526   __ Orr(x11, x0, Operand(x1, SXTH, 1));
527   __ Orr(x12, x0, Operand(x1, SXTW, 2));
528   __ Orr(x13, x0, Operand(x1, SXTX, 3));
529   END();
530 
531   RUN();
532 
533   ASSERT_EQUAL_64(0x00000081, x6);
534   ASSERT_EQUAL_64(0x0000000000010101, x7);
535   ASSERT_EQUAL_64(0x00020201, x8);
536   ASSERT_EQUAL_64(0x0000000400040401, x9);
537   ASSERT_EQUAL_64(0xffffff81, x10);
538   ASSERT_EQUAL_64(0xffffffffffff0101, x11);
539   ASSERT_EQUAL_64(0xfffffffe00020201, x12);
540   ASSERT_EQUAL_64(0x0000000400040401, x13);
541 
542   TEARDOWN();
543 }
544 
545 
TEST(bitwise_wide_imm)546 TEST(bitwise_wide_imm) {
547   SETUP();
548 
549   START();
550   __ Mov(x0, 0);
551   __ Mov(x1, 0xf0f0f0f0f0f0f0f0);
552 
553   __ Orr(x10, x0, 0x1234567890abcdef);
554   __ Orr(w11, w1, 0x90abcdef);
555   END();
556 
557   RUN();
558 
559   ASSERT_EQUAL_64(0, x0);
560   ASSERT_EQUAL_64(0xf0f0f0f0f0f0f0f0, x1);
561   ASSERT_EQUAL_64(0x1234567890abcdef, x10);
562   ASSERT_EQUAL_64(0x00000000f0fbfdff, x11);
563 
564   TEARDOWN();
565 }
566 
567 
TEST(orn)568 TEST(orn) {
569   SETUP();
570 
571   START();
572   __ Mov(x0, 0xf0f0);
573   __ Mov(x1, 0xf00000ff);
574 
575   __ Orn(x2, x0, Operand(x1));
576   __ Orn(w3, w0, Operand(w1, LSL, 4));
577   __ Orn(x4, x0, Operand(x1, LSL, 4));
578   __ Orn(x5, x0, Operand(x1, LSR, 1));
579   __ Orn(w6, w0, Operand(w1, ASR, 1));
580   __ Orn(x7, x0, Operand(x1, ASR, 1));
581   __ Orn(w8, w0, Operand(w1, ROR, 16));
582   __ Orn(x9, x0, Operand(x1, ROR, 16));
583   __ Orn(w10, w0, 0x0000ffff);
584   __ Orn(x11, x0, 0x0000ffff0000ffff);
585   END();
586 
587   RUN();
588 
589   ASSERT_EQUAL_64(0xffffffff0ffffff0, x2);
590   ASSERT_EQUAL_64(0xfffff0ff, x3);
591   ASSERT_EQUAL_64(0xfffffff0fffff0ff, x4);
592   ASSERT_EQUAL_64(0xffffffff87fffff0, x5);
593   ASSERT_EQUAL_64(0x07fffff0, x6);
594   ASSERT_EQUAL_64(0xffffffff87fffff0, x7);
595   ASSERT_EQUAL_64(0xff00ffff, x8);
596   ASSERT_EQUAL_64(0xff00ffffffffffff, x9);
597   ASSERT_EQUAL_64(0xfffff0f0, x10);
598   ASSERT_EQUAL_64(0xffff0000fffff0f0, x11);
599 
600   TEARDOWN();
601 }
602 
603 
TEST(orn_extend)604 TEST(orn_extend) {
605   SETUP();
606 
607   START();
608   __ Mov(x0, 1);
609   __ Mov(x1, 0x8000000080008081);
610   __ Orn(w6, w0, Operand(w1, UXTB));
611   __ Orn(x7, x0, Operand(x1, UXTH, 1));
612   __ Orn(w8, w0, Operand(w1, UXTW, 2));
613   __ Orn(x9, x0, Operand(x1, UXTX, 3));
614   __ Orn(w10, w0, Operand(w1, SXTB));
615   __ Orn(x11, x0, Operand(x1, SXTH, 1));
616   __ Orn(x12, x0, Operand(x1, SXTW, 2));
617   __ Orn(x13, x0, Operand(x1, SXTX, 3));
618   END();
619 
620   RUN();
621 
622   ASSERT_EQUAL_64(0xffffff7f, x6);
623   ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
624   ASSERT_EQUAL_64(0xfffdfdfb, x8);
625   ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
626   ASSERT_EQUAL_64(0x0000007f, x10);
627   ASSERT_EQUAL_64(0x000000000000fefd, x11);
628   ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
629   ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
630 
631   TEARDOWN();
632 }
633 
634 
TEST(and_)635 TEST(and_) {
636   SETUP();
637 
638   START();
639   __ Mov(x0, 0xfff0);
640   __ Mov(x1, 0xf00000ff);
641 
642   __ And(x2, x0, Operand(x1));
643   __ And(w3, w0, Operand(w1, LSL, 4));
644   __ And(x4, x0, Operand(x1, LSL, 4));
645   __ And(x5, x0, Operand(x1, LSR, 1));
646   __ And(w6, w0, Operand(w1, ASR, 20));
647   __ And(x7, x0, Operand(x1, ASR, 20));
648   __ And(w8, w0, Operand(w1, ROR, 28));
649   __ And(x9, x0, Operand(x1, ROR, 28));
650   __ And(w10, w0, Operand(0xff00));
651   __ And(x11, x0, Operand(0xff));
652   END();
653 
654   RUN();
655 
656   ASSERT_EQUAL_64(0x000000f0, x2);
657   ASSERT_EQUAL_64(0x00000ff0, x3);
658   ASSERT_EQUAL_64(0x00000ff0, x4);
659   ASSERT_EQUAL_64(0x00000070, x5);
660   ASSERT_EQUAL_64(0x0000ff00, x6);
661   ASSERT_EQUAL_64(0x00000f00, x7);
662   ASSERT_EQUAL_64(0x00000ff0, x8);
663   ASSERT_EQUAL_64(0x00000000, x9);
664   ASSERT_EQUAL_64(0x0000ff00, x10);
665   ASSERT_EQUAL_64(0x000000f0, x11);
666 
667   TEARDOWN();
668 }
669 
670 
TEST(and_extend)671 TEST(and_extend) {
672   SETUP();
673 
674   START();
675   __ Mov(x0, 0xffffffffffffffff);
676   __ Mov(x1, 0x8000000080008081);
677   __ And(w6, w0, Operand(w1, UXTB));
678   __ And(x7, x0, Operand(x1, UXTH, 1));
679   __ And(w8, w0, Operand(w1, UXTW, 2));
680   __ And(x9, x0, Operand(x1, UXTX, 3));
681   __ And(w10, w0, Operand(w1, SXTB));
682   __ And(x11, x0, Operand(x1, SXTH, 1));
683   __ And(x12, x0, Operand(x1, SXTW, 2));
684   __ And(x13, x0, Operand(x1, SXTX, 3));
685   END();
686 
687   RUN();
688 
689   ASSERT_EQUAL_64(0x00000081, x6);
690   ASSERT_EQUAL_64(0x0000000000010102, x7);
691   ASSERT_EQUAL_64(0x00020204, x8);
692   ASSERT_EQUAL_64(0x0000000400040408, x9);
693   ASSERT_EQUAL_64(0xffffff81, x10);
694   ASSERT_EQUAL_64(0xffffffffffff0102, x11);
695   ASSERT_EQUAL_64(0xfffffffe00020204, x12);
696   ASSERT_EQUAL_64(0x0000000400040408, x13);
697 
698   TEARDOWN();
699 }
700 
701 
TEST(ands)702 TEST(ands) {
703   SETUP();
704 
705   START();
706   __ Mov(x1, 0xf00000ff);
707   __ Ands(w0, w1, Operand(w1));
708   END();
709 
710   RUN();
711 
712   ASSERT_EQUAL_NZCV(NFlag);
713   ASSERT_EQUAL_64(0xf00000ff, x0);
714 
715   START();
716   __ Mov(x0, 0xfff0);
717   __ Mov(x1, 0xf00000ff);
718   __ Ands(w0, w0, Operand(w1, LSR, 4));
719   END();
720 
721   RUN();
722 
723   ASSERT_EQUAL_NZCV(ZFlag);
724   ASSERT_EQUAL_64(0x00000000, x0);
725 
726   START();
727   __ Mov(x0, 0x8000000000000000);
728   __ Mov(x1, 0x00000001);
729   __ Ands(x0, x0, Operand(x1, ROR, 1));
730   END();
731 
732   RUN();
733 
734   ASSERT_EQUAL_NZCV(NFlag);
735   ASSERT_EQUAL_64(0x8000000000000000, x0);
736 
737   START();
738   __ Mov(x0, 0xfff0);
739   __ Ands(w0, w0, Operand(0xf));
740   END();
741 
742   RUN();
743 
744   ASSERT_EQUAL_NZCV(ZFlag);
745   ASSERT_EQUAL_64(0x00000000, x0);
746 
747   START();
748   __ Mov(x0, 0xff000000);
749   __ Ands(w0, w0, Operand(0x80000000));
750   END();
751 
752   RUN();
753 
754   ASSERT_EQUAL_NZCV(NFlag);
755   ASSERT_EQUAL_64(0x80000000, x0);
756 
757   TEARDOWN();
758 }
759 
760 
TEST(bic)761 TEST(bic) {
762   SETUP();
763 
764   START();
765   __ Mov(x0, 0xfff0);
766   __ Mov(x1, 0xf00000ff);
767 
768   __ Bic(x2, x0, Operand(x1));
769   __ Bic(w3, w0, Operand(w1, LSL, 4));
770   __ Bic(x4, x0, Operand(x1, LSL, 4));
771   __ Bic(x5, x0, Operand(x1, LSR, 1));
772   __ Bic(w6, w0, Operand(w1, ASR, 20));
773   __ Bic(x7, x0, Operand(x1, ASR, 20));
774   __ Bic(w8, w0, Operand(w1, ROR, 28));
775   __ Bic(x9, x0, Operand(x1, ROR, 24));
776   __ Bic(x10, x0, Operand(0x1f));
777   __ Bic(x11, x0, Operand(0x100));
778 
779   // Test bic into sp when the constant cannot be encoded in the immediate
780   // field.
781   // Use x20 to preserve sp. We check for the result via x21 because the
782   // test infrastructure requires that sp be restored to its original value.
783   __ Mov(x20, sp);
784   __ Mov(x0, 0xffffff);
785   __ Bic(sp, x0, Operand(0xabcdef));
786   __ Mov(x21, sp);
787   __ Mov(sp, x20);
788   END();
789 
790   RUN();
791 
792   ASSERT_EQUAL_64(0x0000ff00, x2);
793   ASSERT_EQUAL_64(0x0000f000, x3);
794   ASSERT_EQUAL_64(0x0000f000, x4);
795   ASSERT_EQUAL_64(0x0000ff80, x5);
796   ASSERT_EQUAL_64(0x000000f0, x6);
797   ASSERT_EQUAL_64(0x0000f0f0, x7);
798   ASSERT_EQUAL_64(0x0000f000, x8);
799   ASSERT_EQUAL_64(0x0000ff00, x9);
800   ASSERT_EQUAL_64(0x0000ffe0, x10);
801   ASSERT_EQUAL_64(0x0000fef0, x11);
802 
803   ASSERT_EQUAL_64(0x543210, x21);
804 
805   TEARDOWN();
806 }
807 
808 
TEST(bic_extend)809 TEST(bic_extend) {
810   SETUP();
811 
812   START();
813   __ Mov(x0, 0xffffffffffffffff);
814   __ Mov(x1, 0x8000000080008081);
815   __ Bic(w6, w0, Operand(w1, UXTB));
816   __ Bic(x7, x0, Operand(x1, UXTH, 1));
817   __ Bic(w8, w0, Operand(w1, UXTW, 2));
818   __ Bic(x9, x0, Operand(x1, UXTX, 3));
819   __ Bic(w10, w0, Operand(w1, SXTB));
820   __ Bic(x11, x0, Operand(x1, SXTH, 1));
821   __ Bic(x12, x0, Operand(x1, SXTW, 2));
822   __ Bic(x13, x0, Operand(x1, SXTX, 3));
823   END();
824 
825   RUN();
826 
827   ASSERT_EQUAL_64(0xffffff7e, x6);
828   ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
829   ASSERT_EQUAL_64(0xfffdfdfb, x8);
830   ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
831   ASSERT_EQUAL_64(0x0000007e, x10);
832   ASSERT_EQUAL_64(0x000000000000fefd, x11);
833   ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
834   ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
835 
836   TEARDOWN();
837 }
838 
839 
TEST(bics)840 TEST(bics) {
841   SETUP();
842 
843   START();
844   __ Mov(x1, 0xffff);
845   __ Bics(w0, w1, Operand(w1));
846   END();
847 
848   RUN();
849 
850   ASSERT_EQUAL_NZCV(ZFlag);
851   ASSERT_EQUAL_64(0x00000000, x0);
852 
853   START();
854   __ Mov(x0, 0xffffffff);
855   __ Bics(w0, w0, Operand(w0, LSR, 1));
856   END();
857 
858   RUN();
859 
860   ASSERT_EQUAL_NZCV(NFlag);
861   ASSERT_EQUAL_64(0x80000000, x0);
862 
863   START();
864   __ Mov(x0, 0x8000000000000000);
865   __ Mov(x1, 0x00000001);
866   __ Bics(x0, x0, Operand(x1, ROR, 1));
867   END();
868 
869   RUN();
870 
871   ASSERT_EQUAL_NZCV(ZFlag);
872   ASSERT_EQUAL_64(0x00000000, x0);
873 
874   START();
875   __ Mov(x0, 0xffffffffffffffff);
876   __ Bics(x0, x0, 0x7fffffffffffffff);
877   END();
878 
879   RUN();
880 
881   ASSERT_EQUAL_NZCV(NFlag);
882   ASSERT_EQUAL_64(0x8000000000000000, x0);
883 
884   START();
885   __ Mov(w0, 0xffff0000);
886   __ Bics(w0, w0, 0xfffffff0);
887   END();
888 
889   RUN();
890 
891   ASSERT_EQUAL_NZCV(ZFlag);
892   ASSERT_EQUAL_64(0x00000000, x0);
893 
894   TEARDOWN();
895 }
896 
897 
TEST(eor)898 TEST(eor) {
899   SETUP();
900 
901   START();
902   __ Mov(x0, 0xfff0);
903   __ Mov(x1, 0xf00000ff);
904 
905   __ Eor(x2, x0, Operand(x1));
906   __ Eor(w3, w0, Operand(w1, LSL, 4));
907   __ Eor(x4, x0, Operand(x1, LSL, 4));
908   __ Eor(x5, x0, Operand(x1, LSR, 1));
909   __ Eor(w6, w0, Operand(w1, ASR, 20));
910   __ Eor(x7, x0, Operand(x1, ASR, 20));
911   __ Eor(w8, w0, Operand(w1, ROR, 28));
912   __ Eor(x9, x0, Operand(x1, ROR, 28));
913   __ Eor(w10, w0, 0xff00ff00);
914   __ Eor(x11, x0, 0xff00ff00ff00ff00);
915   END();
916 
917   RUN();
918 
919   ASSERT_EQUAL_64(0x00000000f000ff0f, x2);
920   ASSERT_EQUAL_64(0x0000f000, x3);
921   ASSERT_EQUAL_64(0x0000000f0000f000, x4);
922   ASSERT_EQUAL_64(0x000000007800ff8f, x5);
923   ASSERT_EQUAL_64(0xffff00f0, x6);
924   ASSERT_EQUAL_64(0x000000000000f0f0, x7);
925   ASSERT_EQUAL_64(0x0000f00f, x8);
926   ASSERT_EQUAL_64(0x00000ff00000ffff, x9);
927   ASSERT_EQUAL_64(0xff0000f0, x10);
928   ASSERT_EQUAL_64(0xff00ff00ff0000f0, x11);
929 
930   TEARDOWN();
931 }
932 
TEST(eor_extend)933 TEST(eor_extend) {
934   SETUP();
935 
936   START();
937   __ Mov(x0, 0x1111111111111111);
938   __ Mov(x1, 0x8000000080008081);
939   __ Eor(w6, w0, Operand(w1, UXTB));
940   __ Eor(x7, x0, Operand(x1, UXTH, 1));
941   __ Eor(w8, w0, Operand(w1, UXTW, 2));
942   __ Eor(x9, x0, Operand(x1, UXTX, 3));
943   __ Eor(w10, w0, Operand(w1, SXTB));
944   __ Eor(x11, x0, Operand(x1, SXTH, 1));
945   __ Eor(x12, x0, Operand(x1, SXTW, 2));
946   __ Eor(x13, x0, Operand(x1, SXTX, 3));
947   END();
948 
949   RUN();
950 
951   ASSERT_EQUAL_64(0x11111190, x6);
952   ASSERT_EQUAL_64(0x1111111111101013, x7);
953   ASSERT_EQUAL_64(0x11131315, x8);
954   ASSERT_EQUAL_64(0x1111111511151519, x9);
955   ASSERT_EQUAL_64(0xeeeeee90, x10);
956   ASSERT_EQUAL_64(0xeeeeeeeeeeee1013, x11);
957   ASSERT_EQUAL_64(0xeeeeeeef11131315, x12);
958   ASSERT_EQUAL_64(0x1111111511151519, x13);
959 
960   TEARDOWN();
961 }
962 
963 
TEST(eon)964 TEST(eon) {
965   SETUP();
966 
967   START();
968   __ Mov(x0, 0xfff0);
969   __ Mov(x1, 0xf00000ff);
970 
971   __ Eon(x2, x0, Operand(x1));
972   __ Eon(w3, w0, Operand(w1, LSL, 4));
973   __ Eon(x4, x0, Operand(x1, LSL, 4));
974   __ Eon(x5, x0, Operand(x1, LSR, 1));
975   __ Eon(w6, w0, Operand(w1, ASR, 20));
976   __ Eon(x7, x0, Operand(x1, ASR, 20));
977   __ Eon(w8, w0, Operand(w1, ROR, 28));
978   __ Eon(x9, x0, Operand(x1, ROR, 28));
979   __ Eon(w10, w0, 0x03c003c0);
980   __ Eon(x11, x0, 0x0000100000001000);
981   END();
982 
983   RUN();
984 
985   ASSERT_EQUAL_64(0xffffffff0fff00f0, x2);
986   ASSERT_EQUAL_64(0xffff0fff, x3);
987   ASSERT_EQUAL_64(0xfffffff0ffff0fff, x4);
988   ASSERT_EQUAL_64(0xffffffff87ff0070, x5);
989   ASSERT_EQUAL_64(0x0000ff0f, x6);
990   ASSERT_EQUAL_64(0xffffffffffff0f0f, x7);
991   ASSERT_EQUAL_64(0xffff0ff0, x8);
992   ASSERT_EQUAL_64(0xfffff00fffff0000, x9);
993   ASSERT_EQUAL_64(0xfc3f03cf, x10);
994   ASSERT_EQUAL_64(0xffffefffffff100f, x11);
995 
996   TEARDOWN();
997 }
998 
999 
TEST(eon_extend)1000 TEST(eon_extend) {
1001   SETUP();
1002 
1003   START();
1004   __ Mov(x0, 0x1111111111111111);
1005   __ Mov(x1, 0x8000000080008081);
1006   __ Eon(w6, w0, Operand(w1, UXTB));
1007   __ Eon(x7, x0, Operand(x1, UXTH, 1));
1008   __ Eon(w8, w0, Operand(w1, UXTW, 2));
1009   __ Eon(x9, x0, Operand(x1, UXTX, 3));
1010   __ Eon(w10, w0, Operand(w1, SXTB));
1011   __ Eon(x11, x0, Operand(x1, SXTH, 1));
1012   __ Eon(x12, x0, Operand(x1, SXTW, 2));
1013   __ Eon(x13, x0, Operand(x1, SXTX, 3));
1014   END();
1015 
1016   RUN();
1017 
1018   ASSERT_EQUAL_64(0xeeeeee6f, x6);
1019   ASSERT_EQUAL_64(0xeeeeeeeeeeefefec, x7);
1020   ASSERT_EQUAL_64(0xeeececea, x8);
1021   ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x9);
1022   ASSERT_EQUAL_64(0x1111116f, x10);
1023   ASSERT_EQUAL_64(0x111111111111efec, x11);
1024   ASSERT_EQUAL_64(0x11111110eeececea, x12);
1025   ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x13);
1026 
1027   TEARDOWN();
1028 }
1029 
1030 
TEST(mul)1031 TEST(mul) {
1032   SETUP();
1033 
1034   START();
1035   __ Mov(x16, 0);
1036   __ Mov(x17, 1);
1037   __ Mov(x18, 0xffffffff);
1038   __ Mov(x19, 0xffffffffffffffff);
1039 
1040   __ Mul(w0, w16, w16);
1041   __ Mul(w1, w16, w17);
1042   __ Mul(w2, w17, w18);
1043   __ Mul(w3, w18, w19);
1044   __ Mul(x4, x16, x16);
1045   __ Mul(x5, x17, x18);
1046   __ Mul(x6, x18, x19);
1047   __ Mul(x7, x19, x19);
1048   __ Smull(x8, w17, w18);
1049   __ Smull(x9, w18, w18);
1050   __ Smull(x10, w19, w19);
1051   __ Mneg(w11, w16, w16);
1052   __ Mneg(w12, w16, w17);
1053   __ Mneg(w13, w17, w18);
1054   __ Mneg(w14, w18, w19);
1055   __ Mneg(x20, x16, x16);
1056   __ Mneg(x21, x17, x18);
1057   __ Mneg(x22, x18, x19);
1058   __ Mneg(x23, x19, x19);
1059   END();
1060 
1061   RUN();
1062 
1063   ASSERT_EQUAL_64(0, x0);
1064   ASSERT_EQUAL_64(0, x1);
1065   ASSERT_EQUAL_64(0xffffffff, x2);
1066   ASSERT_EQUAL_64(1, x3);
1067   ASSERT_EQUAL_64(0, x4);
1068   ASSERT_EQUAL_64(0xffffffff, x5);
1069   ASSERT_EQUAL_64(0xffffffff00000001, x6);
1070   ASSERT_EQUAL_64(1, x7);
1071   ASSERT_EQUAL_64(0xffffffffffffffff, x8);
1072   ASSERT_EQUAL_64(1, x9);
1073   ASSERT_EQUAL_64(1, x10);
1074   ASSERT_EQUAL_64(0, x11);
1075   ASSERT_EQUAL_64(0, x12);
1076   ASSERT_EQUAL_64(1, x13);
1077   ASSERT_EQUAL_64(0xffffffff, x14);
1078   ASSERT_EQUAL_64(0, x20);
1079   ASSERT_EQUAL_64(0xffffffff00000001, x21);
1080   ASSERT_EQUAL_64(0xffffffff, x22);
1081   ASSERT_EQUAL_64(0xffffffffffffffff, x23);
1082 
1083   TEARDOWN();
1084 }
1085 
1086 
SmullHelper(int64_t expected,int64_t a,int64_t b)1087 static void SmullHelper(int64_t expected, int64_t a, int64_t b) {
1088   SETUP();
1089   START();
1090   __ Mov(w0, a);
1091   __ Mov(w1, b);
1092   __ Smull(x2, w0, w1);
1093   END();
1094   RUN();
1095   ASSERT_EQUAL_64(expected, x2);
1096   TEARDOWN();
1097 }
1098 
1099 
TEST(smull)1100 TEST(smull) {
1101   SmullHelper(0, 0, 0);
1102   SmullHelper(1, 1, 1);
1103   SmullHelper(-1, -1, 1);
1104   SmullHelper(1, -1, -1);
1105   SmullHelper(0xffffffff80000000, 0x80000000, 1);
1106   SmullHelper(0x0000000080000000, 0x00010000, 0x00008000);
1107 }
1108 
1109 
TEST(madd)1110 TEST(madd) {
1111   SETUP();
1112 
1113   START();
1114   __ Mov(x16, 0);
1115   __ Mov(x17, 1);
1116   __ Mov(x18, 0xffffffff);
1117   __ Mov(x19, 0xffffffffffffffff);
1118 
1119   __ Madd(w0, w16, w16, w16);
1120   __ Madd(w1, w16, w16, w17);
1121   __ Madd(w2, w16, w16, w18);
1122   __ Madd(w3, w16, w16, w19);
1123   __ Madd(w4, w16, w17, w17);
1124   __ Madd(w5, w17, w17, w18);
1125   __ Madd(w6, w17, w17, w19);
1126   __ Madd(w7, w17, w18, w16);
1127   __ Madd(w8, w17, w18, w18);
1128   __ Madd(w9, w18, w18, w17);
1129   __ Madd(w10, w18, w19, w18);
1130   __ Madd(w11, w19, w19, w19);
1131 
1132   __ Madd(x12, x16, x16, x16);
1133   __ Madd(x13, x16, x16, x17);
1134   __ Madd(x14, x16, x16, x18);
1135   __ Madd(x15, x16, x16, x19);
1136   __ Madd(x20, x16, x17, x17);
1137   __ Madd(x21, x17, x17, x18);
1138   __ Madd(x22, x17, x17, x19);
1139   __ Madd(x23, x17, x18, x16);
1140   __ Madd(x24, x17, x18, x18);
1141   __ Madd(x25, x18, x18, x17);
1142   __ Madd(x26, x18, x19, x18);
1143   __ Madd(x27, x19, x19, x19);
1144 
1145   END();
1146 
1147   RUN();
1148 
1149   ASSERT_EQUAL_64(0, x0);
1150   ASSERT_EQUAL_64(1, x1);
1151   ASSERT_EQUAL_64(0xffffffff, x2);
1152   ASSERT_EQUAL_64(0xffffffff, x3);
1153   ASSERT_EQUAL_64(1, x4);
1154   ASSERT_EQUAL_64(0, x5);
1155   ASSERT_EQUAL_64(0, x6);
1156   ASSERT_EQUAL_64(0xffffffff, x7);
1157   ASSERT_EQUAL_64(0xfffffffe, x8);
1158   ASSERT_EQUAL_64(2, x9);
1159   ASSERT_EQUAL_64(0, x10);
1160   ASSERT_EQUAL_64(0, x11);
1161 
1162   ASSERT_EQUAL_64(0, x12);
1163   ASSERT_EQUAL_64(1, x13);
1164   ASSERT_EQUAL_64(0x00000000ffffffff, x14);
1165   ASSERT_EQUAL_64(0xffffffffffffffff, x15);
1166   ASSERT_EQUAL_64(1, x20);
1167   ASSERT_EQUAL_64(0x0000000100000000, x21);
1168   ASSERT_EQUAL_64(0, x22);
1169   ASSERT_EQUAL_64(0x00000000ffffffff, x23);
1170   ASSERT_EQUAL_64(0x00000001fffffffe, x24);
1171   ASSERT_EQUAL_64(0xfffffffe00000002, x25);
1172   ASSERT_EQUAL_64(0, x26);
1173   ASSERT_EQUAL_64(0, x27);
1174 
1175   TEARDOWN();
1176 }
1177 
1178 
TEST(msub)1179 TEST(msub) {
1180   SETUP();
1181 
1182   START();
1183   __ Mov(x16, 0);
1184   __ Mov(x17, 1);
1185   __ Mov(x18, 0xffffffff);
1186   __ Mov(x19, 0xffffffffffffffff);
1187 
1188   __ Msub(w0, w16, w16, w16);
1189   __ Msub(w1, w16, w16, w17);
1190   __ Msub(w2, w16, w16, w18);
1191   __ Msub(w3, w16, w16, w19);
1192   __ Msub(w4, w16, w17, w17);
1193   __ Msub(w5, w17, w17, w18);
1194   __ Msub(w6, w17, w17, w19);
1195   __ Msub(w7, w17, w18, w16);
1196   __ Msub(w8, w17, w18, w18);
1197   __ Msub(w9, w18, w18, w17);
1198   __ Msub(w10, w18, w19, w18);
1199   __ Msub(w11, w19, w19, w19);
1200 
1201   __ Msub(x12, x16, x16, x16);
1202   __ Msub(x13, x16, x16, x17);
1203   __ Msub(x14, x16, x16, x18);
1204   __ Msub(x15, x16, x16, x19);
1205   __ Msub(x20, x16, x17, x17);
1206   __ Msub(x21, x17, x17, x18);
1207   __ Msub(x22, x17, x17, x19);
1208   __ Msub(x23, x17, x18, x16);
1209   __ Msub(x24, x17, x18, x18);
1210   __ Msub(x25, x18, x18, x17);
1211   __ Msub(x26, x18, x19, x18);
1212   __ Msub(x27, x19, x19, x19);
1213 
1214   END();
1215 
1216   RUN();
1217 
1218   ASSERT_EQUAL_64(0, x0);
1219   ASSERT_EQUAL_64(1, x1);
1220   ASSERT_EQUAL_64(0xffffffff, x2);
1221   ASSERT_EQUAL_64(0xffffffff, x3);
1222   ASSERT_EQUAL_64(1, x4);
1223   ASSERT_EQUAL_64(0xfffffffe, x5);
1224   ASSERT_EQUAL_64(0xfffffffe, x6);
1225   ASSERT_EQUAL_64(1, x7);
1226   ASSERT_EQUAL_64(0, x8);
1227   ASSERT_EQUAL_64(0, x9);
1228   ASSERT_EQUAL_64(0xfffffffe, x10);
1229   ASSERT_EQUAL_64(0xfffffffe, x11);
1230 
1231   ASSERT_EQUAL_64(0, x12);
1232   ASSERT_EQUAL_64(1, x13);
1233   ASSERT_EQUAL_64(0x00000000ffffffff, x14);
1234   ASSERT_EQUAL_64(0xffffffffffffffff, x15);
1235   ASSERT_EQUAL_64(1, x20);
1236   ASSERT_EQUAL_64(0x00000000fffffffe, x21);
1237   ASSERT_EQUAL_64(0xfffffffffffffffe, x22);
1238   ASSERT_EQUAL_64(0xffffffff00000001, x23);
1239   ASSERT_EQUAL_64(0, x24);
1240   ASSERT_EQUAL_64(0x0000000200000000, x25);
1241   ASSERT_EQUAL_64(0x00000001fffffffe, x26);
1242   ASSERT_EQUAL_64(0xfffffffffffffffe, x27);
1243 
1244   TEARDOWN();
1245 }
1246 
1247 
TEST(smulh)1248 TEST(smulh) {
1249   SETUP();
1250 
1251   START();
1252   __ Mov(x20, 0);
1253   __ Mov(x21, 1);
1254   __ Mov(x22, 0x0000000100000000);
1255   __ Mov(x23, 0x0000000012345678);
1256   __ Mov(x24, 0x0123456789abcdef);
1257   __ Mov(x25, 0x0000000200000000);
1258   __ Mov(x26, 0x8000000000000000);
1259   __ Mov(x27, 0xffffffffffffffff);
1260   __ Mov(x28, 0x5555555555555555);
1261   __ Mov(x29, 0xaaaaaaaaaaaaaaaa);
1262 
1263   __ Smulh(x0, x20, x24);
1264   __ Smulh(x1, x21, x24);
1265   __ Smulh(x2, x22, x23);
1266   __ Smulh(x3, x22, x24);
1267   __ Smulh(x4, x24, x25);
1268   __ Smulh(x5, x23, x27);
1269   __ Smulh(x6, x26, x26);
1270   __ Smulh(x7, x26, x27);
1271   __ Smulh(x8, x27, x27);
1272   __ Smulh(x9, x28, x28);
1273   __ Smulh(x10, x28, x29);
1274   __ Smulh(x11, x29, x29);
1275   END();
1276 
1277   RUN();
1278 
1279   ASSERT_EQUAL_64(0, x0);
1280   ASSERT_EQUAL_64(0, x1);
1281   ASSERT_EQUAL_64(0, x2);
1282   ASSERT_EQUAL_64(0x0000000001234567, x3);
1283   ASSERT_EQUAL_64(0x0000000002468acf, x4);
1284   ASSERT_EQUAL_64(0xffffffffffffffff, x5);
1285   ASSERT_EQUAL_64(0x4000000000000000, x6);
1286   ASSERT_EQUAL_64(0, x7);
1287   ASSERT_EQUAL_64(0, x8);
1288   ASSERT_EQUAL_64(0x1c71c71c71c71c71, x9);
1289   ASSERT_EQUAL_64(0xe38e38e38e38e38e, x10);
1290   ASSERT_EQUAL_64(0x1c71c71c71c71c72, x11);
1291 
1292   TEARDOWN();
1293 }
1294 
1295 
TEST(smaddl_umaddl)1296 TEST(smaddl_umaddl) {
1297   SETUP();
1298 
1299   START();
1300   __ Mov(x17, 1);
1301   __ Mov(x18, 0x00000000ffffffff);
1302   __ Mov(x19, 0xffffffffffffffff);
1303   __ Mov(x20, 4);
1304   __ Mov(x21, 0x0000000200000000);
1305 
1306   __ Smaddl(x9, w17, w18, x20);
1307   __ Smaddl(x10, w18, w18, x20);
1308   __ Smaddl(x11, w19, w19, x20);
1309   __ Smaddl(x12, w19, w19, x21);
1310   __ Umaddl(x13, w17, w18, x20);
1311   __ Umaddl(x14, w18, w18, x20);
1312   __ Umaddl(x15, w19, w19, x20);
1313   __ Umaddl(x22, w19, w19, x21);
1314   END();
1315 
1316   RUN();
1317 
1318   ASSERT_EQUAL_64(3, x9);
1319   ASSERT_EQUAL_64(5, x10);
1320   ASSERT_EQUAL_64(5, x11);
1321   ASSERT_EQUAL_64(0x0000000200000001, x12);
1322   ASSERT_EQUAL_64(0x0000000100000003, x13);
1323   ASSERT_EQUAL_64(0xfffffffe00000005, x14);
1324   ASSERT_EQUAL_64(0xfffffffe00000005, x15);
1325   ASSERT_EQUAL_64(1, x22);
1326 
1327   TEARDOWN();
1328 }
1329 
1330 
TEST(smsubl_umsubl)1331 TEST(smsubl_umsubl) {
1332   SETUP();
1333 
1334   START();
1335   __ Mov(x17, 1);
1336   __ Mov(x18, 0x00000000ffffffff);
1337   __ Mov(x19, 0xffffffffffffffff);
1338   __ Mov(x20, 4);
1339   __ Mov(x21, 0x0000000200000000);
1340 
1341   __ Smsubl(x9, w17, w18, x20);
1342   __ Smsubl(x10, w18, w18, x20);
1343   __ Smsubl(x11, w19, w19, x20);
1344   __ Smsubl(x12, w19, w19, x21);
1345   __ Umsubl(x13, w17, w18, x20);
1346   __ Umsubl(x14, w18, w18, x20);
1347   __ Umsubl(x15, w19, w19, x20);
1348   __ Umsubl(x22, w19, w19, x21);
1349   END();
1350 
1351   RUN();
1352 
1353   ASSERT_EQUAL_64(5, x9);
1354   ASSERT_EQUAL_64(3, x10);
1355   ASSERT_EQUAL_64(3, x11);
1356   ASSERT_EQUAL_64(0x00000001ffffffff, x12);
1357   ASSERT_EQUAL_64(0xffffffff00000005, x13);
1358   ASSERT_EQUAL_64(0x0000000200000003, x14);
1359   ASSERT_EQUAL_64(0x0000000200000003, x15);
1360   ASSERT_EQUAL_64(0x00000003ffffffff, x22);
1361 
1362   TEARDOWN();
1363 }
1364 
1365 
TEST(div)1366 TEST(div) {
1367   SETUP();
1368 
1369   START();
1370   __ Mov(x16, 1);
1371   __ Mov(x17, 0xffffffff);
1372   __ Mov(x18, 0xffffffffffffffff);
1373   __ Mov(x19, 0x80000000);
1374   __ Mov(x20, 0x8000000000000000);
1375   __ Mov(x21, 2);
1376 
1377   __ Udiv(w0, w16, w16);
1378   __ Udiv(w1, w17, w16);
1379   __ Sdiv(w2, w16, w16);
1380   __ Sdiv(w3, w16, w17);
1381   __ Sdiv(w4, w17, w18);
1382 
1383   __ Udiv(x5, x16, x16);
1384   __ Udiv(x6, x17, x18);
1385   __ Sdiv(x7, x16, x16);
1386   __ Sdiv(x8, x16, x17);
1387   __ Sdiv(x9, x17, x18);
1388 
1389   __ Udiv(w10, w19, w21);
1390   __ Sdiv(w11, w19, w21);
1391   __ Udiv(x12, x19, x21);
1392   __ Sdiv(x13, x19, x21);
1393   __ Udiv(x14, x20, x21);
1394   __ Sdiv(x15, x20, x21);
1395 
1396   __ Udiv(w22, w19, w17);
1397   __ Sdiv(w23, w19, w17);
1398   __ Udiv(x24, x20, x18);
1399   __ Sdiv(x25, x20, x18);
1400 
1401   __ Udiv(x26, x16, x21);
1402   __ Sdiv(x27, x16, x21);
1403   __ Udiv(x28, x18, x21);
1404   __ Sdiv(x29, x18, x21);
1405 
1406   __ Mov(x17, 0);
1407   __ Udiv(w18, w16, w17);
1408   __ Sdiv(w19, w16, w17);
1409   __ Udiv(x20, x16, x17);
1410   __ Sdiv(x21, x16, x17);
1411   END();
1412 
1413   RUN();
1414 
1415   ASSERT_EQUAL_64(1, x0);
1416   ASSERT_EQUAL_64(0xffffffff, x1);
1417   ASSERT_EQUAL_64(1, x2);
1418   ASSERT_EQUAL_64(0xffffffff, x3);
1419   ASSERT_EQUAL_64(1, x4);
1420   ASSERT_EQUAL_64(1, x5);
1421   ASSERT_EQUAL_64(0, x6);
1422   ASSERT_EQUAL_64(1, x7);
1423   ASSERT_EQUAL_64(0, x8);
1424   ASSERT_EQUAL_64(0xffffffff00000001, x9);
1425   ASSERT_EQUAL_64(0x40000000, x10);
1426   ASSERT_EQUAL_64(0xC0000000, x11);
1427   ASSERT_EQUAL_64(0x0000000040000000, x12);
1428   ASSERT_EQUAL_64(0x0000000040000000, x13);
1429   ASSERT_EQUAL_64(0x4000000000000000, x14);
1430   ASSERT_EQUAL_64(0xC000000000000000, x15);
1431   ASSERT_EQUAL_64(0, x22);
1432   ASSERT_EQUAL_64(0x80000000, x23);
1433   ASSERT_EQUAL_64(0, x24);
1434   ASSERT_EQUAL_64(0x8000000000000000, x25);
1435   ASSERT_EQUAL_64(0, x26);
1436   ASSERT_EQUAL_64(0, x27);
1437   ASSERT_EQUAL_64(0x7fffffffffffffff, x28);
1438   ASSERT_EQUAL_64(0, x29);
1439   ASSERT_EQUAL_64(0, x18);
1440   ASSERT_EQUAL_64(0, x19);
1441   ASSERT_EQUAL_64(0, x20);
1442   ASSERT_EQUAL_64(0, x21);
1443 
1444   TEARDOWN();
1445 }
1446 
1447 
TEST(rbit_rev)1448 TEST(rbit_rev) {
1449   SETUP();
1450 
1451   START();
1452   __ Mov(x24, 0xfedcba9876543210);
1453   __ Rbit(w0, w24);
1454   __ Rbit(x1, x24);
1455   __ Rev16(w2, w24);
1456   __ Rev16(x3, x24);
1457   __ Rev(w4, w24);
1458   __ Rev32(x5, x24);
1459   __ Rev(x6, x24);
1460   END();
1461 
1462   RUN();
1463 
1464   ASSERT_EQUAL_64(0x084c2a6e, x0);
1465   ASSERT_EQUAL_64(0x084c2a6e195d3b7f, x1);
1466   ASSERT_EQUAL_64(0x54761032, x2);
1467   ASSERT_EQUAL_64(0xdcfe98ba54761032, x3);
1468   ASSERT_EQUAL_64(0x10325476, x4);
1469   ASSERT_EQUAL_64(0x98badcfe10325476, x5);
1470   ASSERT_EQUAL_64(0x1032547698badcfe, x6);
1471 
1472   TEARDOWN();
1473 }
1474 
1475 
TEST(clz_cls)1476 TEST(clz_cls) {
1477   SETUP();
1478 
1479   START();
1480   __ Mov(x24, 0x0008000000800000);
1481   __ Mov(x25, 0xff800000fff80000);
1482   __ Mov(x26, 0);
1483   __ Clz(w0, w24);
1484   __ Clz(x1, x24);
1485   __ Clz(w2, w25);
1486   __ Clz(x3, x25);
1487   __ Clz(w4, w26);
1488   __ Clz(x5, x26);
1489   __ Cls(w6, w24);
1490   __ Cls(x7, x24);
1491   __ Cls(w8, w25);
1492   __ Cls(x9, x25);
1493   __ Cls(w10, w26);
1494   __ Cls(x11, x26);
1495   END();
1496 
1497   RUN();
1498 
1499   ASSERT_EQUAL_64(8, x0);
1500   ASSERT_EQUAL_64(12, x1);
1501   ASSERT_EQUAL_64(0, x2);
1502   ASSERT_EQUAL_64(0, x3);
1503   ASSERT_EQUAL_64(32, x4);
1504   ASSERT_EQUAL_64(64, x5);
1505   ASSERT_EQUAL_64(7, x6);
1506   ASSERT_EQUAL_64(11, x7);
1507   ASSERT_EQUAL_64(12, x8);
1508   ASSERT_EQUAL_64(8, x9);
1509   ASSERT_EQUAL_64(31, x10);
1510   ASSERT_EQUAL_64(63, x11);
1511 
1512   TEARDOWN();
1513 }
1514 
1515 
TEST(label)1516 TEST(label) {
1517   SETUP();
1518 
1519   Label label_1, label_2, label_3, label_4;
1520 
1521   START();
1522   __ Mov(x0, 0x1);
1523   __ Mov(x1, 0x0);
1524   __ Mov(x22, lr);    // Save lr.
1525 
1526   __ B(&label_1);
1527   __ B(&label_1);
1528   __ B(&label_1);     // Multiple branches to the same label.
1529   __ Mov(x0, 0x0);
1530   __ Bind(&label_2);
1531   __ B(&label_3);     // Forward branch.
1532   __ Mov(x0, 0x0);
1533   __ Bind(&label_1);
1534   __ B(&label_2);     // Backward branch.
1535   __ Mov(x0, 0x0);
1536   __ Bind(&label_3);
1537   __ Bl(&label_4);
1538   END();
1539 
1540   __ Bind(&label_4);
1541   __ Mov(x1, 0x1);
1542   __ Mov(lr, x22);
1543   END();
1544 
1545   RUN();
1546 
1547   ASSERT_EQUAL_64(0x1, x0);
1548   ASSERT_EQUAL_64(0x1, x1);
1549 
1550   TEARDOWN();
1551 }
1552 
1553 
TEST(adr)1554 TEST(adr) {
1555   SETUP();
1556 
1557   Label label_1, label_2, label_3, label_4;
1558 
1559   START();
1560   __ Mov(x0, 0x0);        // Set to non-zero to indicate failure.
1561   __ Adr(x1, &label_3);   // Set to zero to indicate success.
1562 
1563   __ Adr(x2, &label_1);   // Multiple forward references to the same label.
1564   __ Adr(x3, &label_1);
1565   __ Adr(x4, &label_1);
1566 
1567   __ Bind(&label_2);
1568   __ Eor(x5, x2, Operand(x3));  // Ensure that x2,x3 and x4 are identical.
1569   __ Eor(x6, x2, Operand(x4));
1570   __ Orr(x0, x0, Operand(x5));
1571   __ Orr(x0, x0, Operand(x6));
1572   __ Br(x2);  // label_1, label_3
1573 
1574   __ Bind(&label_3);
1575   __ Adr(x2, &label_3);   // Self-reference (offset 0).
1576   __ Eor(x1, x1, Operand(x2));
1577   __ Adr(x2, &label_4);   // Simple forward reference.
1578   __ Br(x2);  // label_4
1579 
1580   __ Bind(&label_1);
1581   __ Adr(x2, &label_3);   // Multiple reverse references to the same label.
1582   __ Adr(x3, &label_3);
1583   __ Adr(x4, &label_3);
1584   __ Adr(x5, &label_2);   // Simple reverse reference.
1585   __ Br(x5);  // label_2
1586 
1587   __ Bind(&label_4);
1588   END();
1589 
1590   RUN();
1591 
1592   ASSERT_EQUAL_64(0x0, x0);
1593   ASSERT_EQUAL_64(0x0, x1);
1594 
1595   TEARDOWN();
1596 }
1597 
1598 
TEST(branch_cond)1599 TEST(branch_cond) {
1600   SETUP();
1601 
1602   Label wrong;
1603 
1604   START();
1605   __ Mov(x0, 0x1);
1606   __ Mov(x1, 0x1);
1607   __ Mov(x2, 0x8000000000000000);
1608 
1609   // For each 'cmp' instruction below, condition codes other than the ones
1610   // following it would branch.
1611 
1612   __ Cmp(x1, 0);
1613   __ B(&wrong, eq);
1614   __ B(&wrong, lo);
1615   __ B(&wrong, mi);
1616   __ B(&wrong, vs);
1617   __ B(&wrong, ls);
1618   __ B(&wrong, lt);
1619   __ B(&wrong, le);
1620   Label ok_1;
1621   __ B(&ok_1, ne);
1622   __ Mov(x0, 0x0);
1623   __ Bind(&ok_1);
1624 
1625   __ Cmp(x1, 1);
1626   __ B(&wrong, ne);
1627   __ B(&wrong, lo);
1628   __ B(&wrong, mi);
1629   __ B(&wrong, vs);
1630   __ B(&wrong, hi);
1631   __ B(&wrong, lt);
1632   __ B(&wrong, gt);
1633   Label ok_2;
1634   __ B(&ok_2, pl);
1635   __ Mov(x0, 0x0);
1636   __ Bind(&ok_2);
1637 
1638   __ Cmp(x1, 2);
1639   __ B(&wrong, eq);
1640   __ B(&wrong, hs);
1641   __ B(&wrong, pl);
1642   __ B(&wrong, vs);
1643   __ B(&wrong, hi);
1644   __ B(&wrong, ge);
1645   __ B(&wrong, gt);
1646   Label ok_3;
1647   __ B(&ok_3, vc);
1648   __ Mov(x0, 0x0);
1649   __ Bind(&ok_3);
1650 
1651   __ Cmp(x2, 1);
1652   __ B(&wrong, eq);
1653   __ B(&wrong, lo);
1654   __ B(&wrong, mi);
1655   __ B(&wrong, vc);
1656   __ B(&wrong, ls);
1657   __ B(&wrong, ge);
1658   __ B(&wrong, gt);
1659   Label ok_4;
1660   __ B(&ok_4, le);
1661   __ Mov(x0, 0x0);
1662   __ Bind(&ok_4);
1663 
1664   Label ok_5;
1665   __ b(&ok_5, al);
1666   __ Mov(x0, 0x0);
1667   __ Bind(&ok_5);
1668 
1669   Label ok_6;
1670   __ b(&ok_6, nv);
1671   __ Mov(x0, 0x0);
1672   __ Bind(&ok_6);
1673 
1674   END();
1675 
1676   __ Bind(&wrong);
1677   __ Mov(x0, 0x0);
1678   END();
1679 
1680   RUN();
1681 
1682   ASSERT_EQUAL_64(0x1, x0);
1683 
1684   TEARDOWN();
1685 }
1686 
1687 
TEST(branch_to_reg)1688 TEST(branch_to_reg) {
1689   SETUP();
1690 
1691   // Test br.
1692   Label fn1, after_fn1;
1693 
1694   START();
1695   __ Mov(x29, lr);
1696 
1697   __ Mov(x1, 0);
1698   __ B(&after_fn1);
1699 
1700   __ Bind(&fn1);
1701   __ Mov(x0, lr);
1702   __ Mov(x1, 42);
1703   __ Br(x0);
1704 
1705   __ Bind(&after_fn1);
1706   __ Bl(&fn1);
1707 
1708   // Test blr.
1709   Label fn2, after_fn2;
1710 
1711   __ Mov(x2, 0);
1712   __ B(&after_fn2);
1713 
1714   __ Bind(&fn2);
1715   __ Mov(x0, lr);
1716   __ Mov(x2, 84);
1717   __ Blr(x0);
1718 
1719   __ Bind(&after_fn2);
1720   __ Bl(&fn2);
1721   __ Mov(x3, lr);
1722 
1723   __ Mov(lr, x29);
1724   END();
1725 
1726   RUN();
1727 
1728   ASSERT_EQUAL_64(core.xreg(3) + kInstructionSize, x0);
1729   ASSERT_EQUAL_64(42, x1);
1730   ASSERT_EQUAL_64(84, x2);
1731 
1732   TEARDOWN();
1733 }
1734 
1735 
TEST(compare_branch)1736 TEST(compare_branch) {
1737   SETUP();
1738 
1739   START();
1740   __ Mov(x0, 0);
1741   __ Mov(x1, 0);
1742   __ Mov(x2, 0);
1743   __ Mov(x3, 0);
1744   __ Mov(x4, 0);
1745   __ Mov(x5, 0);
1746   __ Mov(x16, 0);
1747   __ Mov(x17, 42);
1748 
1749   Label zt, zt_end;
1750   __ Cbz(w16, &zt);
1751   __ B(&zt_end);
1752   __ Bind(&zt);
1753   __ Mov(x0, 1);
1754   __ Bind(&zt_end);
1755 
1756   Label zf, zf_end;
1757   __ Cbz(x17, &zf);
1758   __ B(&zf_end);
1759   __ Bind(&zf);
1760   __ Mov(x1, 1);
1761   __ Bind(&zf_end);
1762 
1763   Label nzt, nzt_end;
1764   __ Cbnz(w17, &nzt);
1765   __ B(&nzt_end);
1766   __ Bind(&nzt);
1767   __ Mov(x2, 1);
1768   __ Bind(&nzt_end);
1769 
1770   Label nzf, nzf_end;
1771   __ Cbnz(x16, &nzf);
1772   __ B(&nzf_end);
1773   __ Bind(&nzf);
1774   __ Mov(x3, 1);
1775   __ Bind(&nzf_end);
1776 
1777   __ Mov(x18, 0xffffffff00000000);
1778 
1779   Label a, a_end;
1780   __ Cbz(w18, &a);
1781   __ B(&a_end);
1782   __ Bind(&a);
1783   __ Mov(x4, 1);
1784   __ Bind(&a_end);
1785 
1786   Label b, b_end;
1787   __ Cbnz(w18, &b);
1788   __ B(&b_end);
1789   __ Bind(&b);
1790   __ Mov(x5, 1);
1791   __ Bind(&b_end);
1792 
1793   END();
1794 
1795   RUN();
1796 
1797   ASSERT_EQUAL_64(1, x0);
1798   ASSERT_EQUAL_64(0, x1);
1799   ASSERT_EQUAL_64(1, x2);
1800   ASSERT_EQUAL_64(0, x3);
1801   ASSERT_EQUAL_64(1, x4);
1802   ASSERT_EQUAL_64(0, x5);
1803 
1804   TEARDOWN();
1805 }
1806 
1807 
TEST(test_branch)1808 TEST(test_branch) {
1809   SETUP();
1810 
1811   START();
1812   __ Mov(x0, 0);
1813   __ Mov(x1, 0);
1814   __ Mov(x2, 0);
1815   __ Mov(x3, 0);
1816   __ Mov(x16, 0xaaaaaaaaaaaaaaaa);
1817 
1818   Label bz, bz_end;
1819   __ Tbz(w16, 0, &bz);
1820   __ B(&bz_end);
1821   __ Bind(&bz);
1822   __ Mov(x0, 1);
1823   __ Bind(&bz_end);
1824 
1825   Label bo, bo_end;
1826   __ Tbz(x16, 63, &bo);
1827   __ B(&bo_end);
1828   __ Bind(&bo);
1829   __ Mov(x1, 1);
1830   __ Bind(&bo_end);
1831 
1832   Label nbz, nbz_end;
1833   __ Tbnz(x16, 61, &nbz);
1834   __ B(&nbz_end);
1835   __ Bind(&nbz);
1836   __ Mov(x2, 1);
1837   __ Bind(&nbz_end);
1838 
1839   Label nbo, nbo_end;
1840   __ Tbnz(w16, 2, &nbo);
1841   __ B(&nbo_end);
1842   __ Bind(&nbo);
1843   __ Mov(x3, 1);
1844   __ Bind(&nbo_end);
1845   END();
1846 
1847   RUN();
1848 
1849   ASSERT_EQUAL_64(1, x0);
1850   ASSERT_EQUAL_64(0, x1);
1851   ASSERT_EQUAL_64(1, x2);
1852   ASSERT_EQUAL_64(0, x3);
1853 
1854   TEARDOWN();
1855 }
1856 
1857 
TEST(branch_type)1858 TEST(branch_type) {
1859   SETUP();
1860 
1861   Label fail, done;
1862 
1863   START();
1864   __ Mov(x0, 0x0);
1865   __ Mov(x10, 0x7);
1866   __ Mov(x11, 0x0);
1867 
1868   // Test non taken branches.
1869   __ Cmp(x10, 0x7);
1870   __ B(&fail, ne);
1871   __ B(&fail, never);
1872   __ B(&fail, reg_zero, x10);
1873   __ B(&fail, reg_not_zero, x11);
1874   __ B(&fail, reg_bit_clear, x10, 0);
1875   __ B(&fail, reg_bit_set, x10, 3);
1876 
1877   // Test taken branches.
1878   Label l1, l2, l3, l4, l5;
1879   __ Cmp(x10, 0x7);
1880   __ B(&l1, eq);
1881   __ B(&fail);
1882   __ Bind(&l1);
1883   __ B(&l2, always);
1884   __ B(&fail);
1885   __ Bind(&l2);
1886   __ B(&l3, reg_not_zero, x10);
1887   __ B(&fail);
1888   __ Bind(&l3);
1889   __ B(&l4, reg_bit_clear, x10, 15);
1890   __ B(&fail);
1891   __ Bind(&l4);
1892   __ B(&l5, reg_bit_set, x10, 1);
1893   __ B(&fail);
1894   __ Bind(&l5);
1895 
1896   __ B(&done);
1897 
1898   __ Bind(&fail);
1899   __ Mov(x0, 0x1);
1900 
1901   __ Bind(&done);
1902 
1903   END();
1904 
1905   RUN();
1906 
1907   ASSERT_EQUAL_64(0x0, x0);
1908 
1909   TEARDOWN();
1910 }
1911 
1912 
TEST(ldr_str_offset)1913 TEST(ldr_str_offset) {
1914   SETUP();
1915 
1916   uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
1917   uint64_t dst[5] = {0, 0, 0, 0, 0};
1918   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
1919   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
1920 
1921   START();
1922   __ Mov(x17, src_base);
1923   __ Mov(x18, dst_base);
1924   __ Ldr(w0, MemOperand(x17));
1925   __ Str(w0, MemOperand(x18));
1926   __ Ldr(w1, MemOperand(x17, 4));
1927   __ Str(w1, MemOperand(x18, 12));
1928   __ Ldr(x2, MemOperand(x17, 8));
1929   __ Str(x2, MemOperand(x18, 16));
1930   __ Ldrb(w3, MemOperand(x17, 1));
1931   __ Strb(w3, MemOperand(x18, 25));
1932   __ Ldrh(w4, MemOperand(x17, 2));
1933   __ Strh(w4, MemOperand(x18, 33));
1934   END();
1935 
1936   RUN();
1937 
1938   ASSERT_EQUAL_64(0x76543210, x0);
1939   ASSERT_EQUAL_64(0x76543210, dst[0]);
1940   ASSERT_EQUAL_64(0xfedcba98, x1);
1941   ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
1942   ASSERT_EQUAL_64(0x0123456789abcdef, x2);
1943   ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
1944   ASSERT_EQUAL_64(0x32, x3);
1945   ASSERT_EQUAL_64(0x3200, dst[3]);
1946   ASSERT_EQUAL_64(0x7654, x4);
1947   ASSERT_EQUAL_64(0x765400, dst[4]);
1948   ASSERT_EQUAL_64(src_base, x17);
1949   ASSERT_EQUAL_64(dst_base, x18);
1950 
1951   TEARDOWN();
1952 }
1953 
1954 
TEST(ldr_str_wide)1955 TEST(ldr_str_wide) {
1956   SETUP();
1957 
1958   uint32_t src[8192];
1959   uint32_t dst[8192];
1960   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
1961   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
1962   memset(src, 0xaa, 8192 * sizeof(src[0]));
1963   memset(dst, 0xaa, 8192 * sizeof(dst[0]));
1964   src[0] = 0;
1965   src[6144] = 6144;
1966   src[8191] = 8191;
1967 
1968   START();
1969   __ Mov(x22, src_base);
1970   __ Mov(x23, dst_base);
1971   __ Mov(x24, src_base);
1972   __ Mov(x25, dst_base);
1973   __ Mov(x26, src_base);
1974   __ Mov(x27, dst_base);
1975 
1976   __ Ldr(w0, MemOperand(x22, 8191 * sizeof(src[0])));
1977   __ Str(w0, MemOperand(x23, 8191 * sizeof(dst[0])));
1978   __ Ldr(w1, MemOperand(x24, 4096 * sizeof(src[0]), PostIndex));
1979   __ Str(w1, MemOperand(x25, 4096 * sizeof(dst[0]), PostIndex));
1980   __ Ldr(w2, MemOperand(x26, 6144 * sizeof(src[0]), PreIndex));
1981   __ Str(w2, MemOperand(x27, 6144 * sizeof(dst[0]), PreIndex));
1982   END();
1983 
1984   RUN();
1985 
1986   ASSERT_EQUAL_32(8191, w0);
1987   ASSERT_EQUAL_32(8191, dst[8191]);
1988   ASSERT_EQUAL_64(src_base, x22);
1989   ASSERT_EQUAL_64(dst_base, x23);
1990   ASSERT_EQUAL_32(0, w1);
1991   ASSERT_EQUAL_32(0, dst[0]);
1992   ASSERT_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24);
1993   ASSERT_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25);
1994   ASSERT_EQUAL_32(6144, w2);
1995   ASSERT_EQUAL_32(6144, dst[6144]);
1996   ASSERT_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26);
1997   ASSERT_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27);
1998 
1999   TEARDOWN();
2000 }
2001 
2002 
TEST(ldr_str_preindex)2003 TEST(ldr_str_preindex) {
2004   SETUP();
2005 
2006   uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
2007   uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2008   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2009   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2010 
2011   START();
2012   __ Mov(x17, src_base);
2013   __ Mov(x18, dst_base);
2014   __ Mov(x19, src_base);
2015   __ Mov(x20, dst_base);
2016   __ Mov(x21, src_base + 16);
2017   __ Mov(x22, dst_base + 40);
2018   __ Mov(x23, src_base);
2019   __ Mov(x24, dst_base);
2020   __ Mov(x25, src_base);
2021   __ Mov(x26, dst_base);
2022   __ Ldr(w0, MemOperand(x17, 4, PreIndex));
2023   __ Str(w0, MemOperand(x18, 12, PreIndex));
2024   __ Ldr(x1, MemOperand(x19, 8, PreIndex));
2025   __ Str(x1, MemOperand(x20, 16, PreIndex));
2026   __ Ldr(w2, MemOperand(x21, -4, PreIndex));
2027   __ Str(w2, MemOperand(x22, -4, PreIndex));
2028   __ Ldrb(w3, MemOperand(x23, 1, PreIndex));
2029   __ Strb(w3, MemOperand(x24, 25, PreIndex));
2030   __ Ldrh(w4, MemOperand(x25, 3, PreIndex));
2031   __ Strh(w4, MemOperand(x26, 41, PreIndex));
2032   END();
2033 
2034   RUN();
2035 
2036   ASSERT_EQUAL_64(0xfedcba98, x0);
2037   ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2038   ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2039   ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
2040   ASSERT_EQUAL_64(0x01234567, x2);
2041   ASSERT_EQUAL_64(0x0123456700000000, dst[4]);
2042   ASSERT_EQUAL_64(0x32, x3);
2043   ASSERT_EQUAL_64(0x3200, dst[3]);
2044   ASSERT_EQUAL_64(0x9876, x4);
2045   ASSERT_EQUAL_64(0x987600, dst[5]);
2046   ASSERT_EQUAL_64(src_base + 4, x17);
2047   ASSERT_EQUAL_64(dst_base + 12, x18);
2048   ASSERT_EQUAL_64(src_base + 8, x19);
2049   ASSERT_EQUAL_64(dst_base + 16, x20);
2050   ASSERT_EQUAL_64(src_base + 12, x21);
2051   ASSERT_EQUAL_64(dst_base + 36, x22);
2052   ASSERT_EQUAL_64(src_base + 1, x23);
2053   ASSERT_EQUAL_64(dst_base + 25, x24);
2054   ASSERT_EQUAL_64(src_base + 3, x25);
2055   ASSERT_EQUAL_64(dst_base + 41, x26);
2056 
2057   TEARDOWN();
2058 }
2059 
2060 
TEST(ldr_str_postindex)2061 TEST(ldr_str_postindex) {
2062   SETUP();
2063 
2064   uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
2065   uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2066   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2067   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2068 
2069   START();
2070   __ Mov(x17, src_base + 4);
2071   __ Mov(x18, dst_base + 12);
2072   __ Mov(x19, src_base + 8);
2073   __ Mov(x20, dst_base + 16);
2074   __ Mov(x21, src_base + 8);
2075   __ Mov(x22, dst_base + 32);
2076   __ Mov(x23, src_base + 1);
2077   __ Mov(x24, dst_base + 25);
2078   __ Mov(x25, src_base + 3);
2079   __ Mov(x26, dst_base + 41);
2080   __ Ldr(w0, MemOperand(x17, 4, PostIndex));
2081   __ Str(w0, MemOperand(x18, 12, PostIndex));
2082   __ Ldr(x1, MemOperand(x19, 8, PostIndex));
2083   __ Str(x1, MemOperand(x20, 16, PostIndex));
2084   __ Ldr(x2, MemOperand(x21, -8, PostIndex));
2085   __ Str(x2, MemOperand(x22, -32, PostIndex));
2086   __ Ldrb(w3, MemOperand(x23, 1, PostIndex));
2087   __ Strb(w3, MemOperand(x24, 5, PostIndex));
2088   __ Ldrh(w4, MemOperand(x25, -3, PostIndex));
2089   __ Strh(w4, MemOperand(x26, -41, PostIndex));
2090   END();
2091 
2092   RUN();
2093 
2094   ASSERT_EQUAL_64(0xfedcba98, x0);
2095   ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2096   ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2097   ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
2098   ASSERT_EQUAL_64(0x0123456789abcdef, x2);
2099   ASSERT_EQUAL_64(0x0123456789abcdef, dst[4]);
2100   ASSERT_EQUAL_64(0x32, x3);
2101   ASSERT_EQUAL_64(0x3200, dst[3]);
2102   ASSERT_EQUAL_64(0x9876, x4);
2103   ASSERT_EQUAL_64(0x987600, dst[5]);
2104   ASSERT_EQUAL_64(src_base + 8, x17);
2105   ASSERT_EQUAL_64(dst_base + 24, x18);
2106   ASSERT_EQUAL_64(src_base + 16, x19);
2107   ASSERT_EQUAL_64(dst_base + 32, x20);
2108   ASSERT_EQUAL_64(src_base, x21);
2109   ASSERT_EQUAL_64(dst_base, x22);
2110   ASSERT_EQUAL_64(src_base + 2, x23);
2111   ASSERT_EQUAL_64(dst_base + 30, x24);
2112   ASSERT_EQUAL_64(src_base, x25);
2113   ASSERT_EQUAL_64(dst_base, x26);
2114 
2115   TEARDOWN();
2116 }
2117 
2118 
TEST(ldr_str_largeindex)2119 TEST(ldr_str_largeindex) {
2120   SETUP();
2121 
2122   // This value won't fit in the immediate offset field of ldr/str instructions.
2123   int largeoffset = 0xabcdef;
2124 
2125   int64_t data[3] = { 0x1122334455667788, 0, 0 };
2126   uint64_t base_addr = reinterpret_cast<uintptr_t>(data);
2127   uint64_t drifted_addr = base_addr - largeoffset;
2128 
2129   // This test checks that we we can use large immediate offsets when
2130   // using PreIndex or PostIndex addressing mode of the MacroAssembler
2131   // Ldr/Str instructions.
2132 
2133   START();
2134   __ Mov(x19, drifted_addr);
2135   __ Ldr(x0, MemOperand(x19, largeoffset, PreIndex));
2136 
2137   __ Mov(x20, base_addr);
2138   __ Ldr(x1, MemOperand(x20, largeoffset, PostIndex));
2139 
2140   __ Mov(x21, drifted_addr);
2141   __ Str(x0, MemOperand(x21, largeoffset + 8, PreIndex));
2142 
2143   __ Mov(x22, base_addr + 16);
2144   __ Str(x0, MemOperand(x22, largeoffset, PostIndex));
2145   END();
2146 
2147   RUN();
2148 
2149   ASSERT_EQUAL_64(0x1122334455667788, data[0]);
2150   ASSERT_EQUAL_64(0x1122334455667788, data[1]);
2151   ASSERT_EQUAL_64(0x1122334455667788, data[2]);
2152   ASSERT_EQUAL_64(0x1122334455667788, x0);
2153   ASSERT_EQUAL_64(0x1122334455667788, x1);
2154 
2155   ASSERT_EQUAL_64(base_addr, x19);
2156   ASSERT_EQUAL_64(base_addr + largeoffset, x20);
2157   ASSERT_EQUAL_64(base_addr + 8, x21);
2158   ASSERT_EQUAL_64(base_addr + 16 + largeoffset, x22);
2159 
2160   TEARDOWN();
2161 }
2162 
2163 
TEST(load_signed)2164 TEST(load_signed) {
2165   SETUP();
2166 
2167   uint32_t src[2] = {0x80008080, 0x7fff7f7f};
2168   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2169 
2170   START();
2171   __ Mov(x24, src_base);
2172   __ Ldrsb(w0, MemOperand(x24));
2173   __ Ldrsb(w1, MemOperand(x24, 4));
2174   __ Ldrsh(w2, MemOperand(x24));
2175   __ Ldrsh(w3, MemOperand(x24, 4));
2176   __ Ldrsb(x4, MemOperand(x24));
2177   __ Ldrsb(x5, MemOperand(x24, 4));
2178   __ Ldrsh(x6, MemOperand(x24));
2179   __ Ldrsh(x7, MemOperand(x24, 4));
2180   __ Ldrsw(x8, MemOperand(x24));
2181   __ Ldrsw(x9, MemOperand(x24, 4));
2182   END();
2183 
2184   RUN();
2185 
2186   ASSERT_EQUAL_64(0xffffff80, x0);
2187   ASSERT_EQUAL_64(0x0000007f, x1);
2188   ASSERT_EQUAL_64(0xffff8080, x2);
2189   ASSERT_EQUAL_64(0x00007f7f, x3);
2190   ASSERT_EQUAL_64(0xffffffffffffff80, x4);
2191   ASSERT_EQUAL_64(0x000000000000007f, x5);
2192   ASSERT_EQUAL_64(0xffffffffffff8080, x6);
2193   ASSERT_EQUAL_64(0x0000000000007f7f, x7);
2194   ASSERT_EQUAL_64(0xffffffff80008080, x8);
2195   ASSERT_EQUAL_64(0x000000007fff7f7f, x9);
2196 
2197   TEARDOWN();
2198 }
2199 
2200 
TEST(load_store_regoffset)2201 TEST(load_store_regoffset) {
2202   SETUP();
2203 
2204   uint32_t src[3] = {1, 2, 3};
2205   uint32_t dst[4] = {0, 0, 0, 0};
2206   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2207   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2208 
2209   START();
2210   __ Mov(x16, src_base);
2211   __ Mov(x17, dst_base);
2212   __ Mov(x18, src_base + 3 * sizeof(src[0]));
2213   __ Mov(x19, dst_base + 3 * sizeof(dst[0]));
2214   __ Mov(x20, dst_base + 4 * sizeof(dst[0]));
2215   __ Mov(x24, 0);
2216   __ Mov(x25, 4);
2217   __ Mov(x26, -4);
2218   __ Mov(x27, 0xfffffffc);  // 32-bit -4.
2219   __ Mov(x28, 0xfffffffe);  // 32-bit -2.
2220   __ Mov(x29, 0xffffffff);  // 32-bit -1.
2221 
2222   __ Ldr(w0, MemOperand(x16, x24));
2223   __ Ldr(x1, MemOperand(x16, x25));
2224   __ Ldr(w2, MemOperand(x18, x26));
2225   __ Ldr(w3, MemOperand(x18, x27, SXTW));
2226   __ Ldr(w4, MemOperand(x18, x28, SXTW, 2));
2227   __ Str(w0, MemOperand(x17, x24));
2228   __ Str(x1, MemOperand(x17, x25));
2229   __ Str(w2, MemOperand(x20, x29, SXTW, 2));
2230   END();
2231 
2232   RUN();
2233 
2234   ASSERT_EQUAL_64(1, x0);
2235   ASSERT_EQUAL_64(0x0000000300000002, x1);
2236   ASSERT_EQUAL_64(3, x2);
2237   ASSERT_EQUAL_64(3, x3);
2238   ASSERT_EQUAL_64(2, x4);
2239   ASSERT_EQUAL_32(1, dst[0]);
2240   ASSERT_EQUAL_32(2, dst[1]);
2241   ASSERT_EQUAL_32(3, dst[2]);
2242   ASSERT_EQUAL_32(3, dst[3]);
2243 
2244   TEARDOWN();
2245 }
2246 
2247 
TEST(load_store_float)2248 TEST(load_store_float) {
2249   SETUP();
2250 
2251   float src[3] = {1.0, 2.0, 3.0};
2252   float dst[3] = {0.0, 0.0, 0.0};
2253   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2254   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2255 
2256   START();
2257   __ Mov(x17, src_base);
2258   __ Mov(x18, dst_base);
2259   __ Mov(x19, src_base);
2260   __ Mov(x20, dst_base);
2261   __ Mov(x21, src_base);
2262   __ Mov(x22, dst_base);
2263   __ Ldr(s0, MemOperand(x17, sizeof(src[0])));
2264   __ Str(s0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2265   __ Ldr(s1, MemOperand(x19, sizeof(src[0]), PostIndex));
2266   __ Str(s1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2267   __ Ldr(s2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2268   __ Str(s2, MemOperand(x22, sizeof(dst[0])));
2269   END();
2270 
2271   RUN();
2272 
2273   ASSERT_EQUAL_FP32(2.0, s0);
2274   ASSERT_EQUAL_FP32(2.0, dst[0]);
2275   ASSERT_EQUAL_FP32(1.0, s1);
2276   ASSERT_EQUAL_FP32(1.0, dst[2]);
2277   ASSERT_EQUAL_FP32(3.0, s2);
2278   ASSERT_EQUAL_FP32(3.0, dst[1]);
2279   ASSERT_EQUAL_64(src_base, x17);
2280   ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2281   ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2282   ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2283   ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2284   ASSERT_EQUAL_64(dst_base, x22);
2285 
2286   TEARDOWN();
2287 }
2288 
2289 
TEST(load_store_double)2290 TEST(load_store_double) {
2291   SETUP();
2292 
2293   double src[3] = {1.0, 2.0, 3.0};
2294   double dst[3] = {0.0, 0.0, 0.0};
2295   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2296   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2297 
2298   START();
2299   __ Mov(x17, src_base);
2300   __ Mov(x18, dst_base);
2301   __ Mov(x19, src_base);
2302   __ Mov(x20, dst_base);
2303   __ Mov(x21, src_base);
2304   __ Mov(x22, dst_base);
2305   __ Ldr(d0, MemOperand(x17, sizeof(src[0])));
2306   __ Str(d0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2307   __ Ldr(d1, MemOperand(x19, sizeof(src[0]), PostIndex));
2308   __ Str(d1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2309   __ Ldr(d2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2310   __ Str(d2, MemOperand(x22, sizeof(dst[0])));
2311   END();
2312 
2313   RUN();
2314 
2315   ASSERT_EQUAL_FP64(2.0, d0);
2316   ASSERT_EQUAL_FP64(2.0, dst[0]);
2317   ASSERT_EQUAL_FP64(1.0, d1);
2318   ASSERT_EQUAL_FP64(1.0, dst[2]);
2319   ASSERT_EQUAL_FP64(3.0, d2);
2320   ASSERT_EQUAL_FP64(3.0, dst[1]);
2321   ASSERT_EQUAL_64(src_base, x17);
2322   ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2323   ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2324   ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2325   ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2326   ASSERT_EQUAL_64(dst_base, x22);
2327 
2328   TEARDOWN();
2329 }
2330 
2331 
TEST(ldp_stp_float)2332 TEST(ldp_stp_float) {
2333   SETUP();
2334 
2335   float src[2] = {1.0, 2.0};
2336   float dst[3] = {0.0, 0.0, 0.0};
2337   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2338   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2339 
2340   START();
2341   __ Mov(x16, src_base);
2342   __ Mov(x17, dst_base);
2343   __ Ldp(s31, s0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
2344   __ Stp(s0, s31, MemOperand(x17, sizeof(dst[1]), PreIndex));
2345   END();
2346 
2347   RUN();
2348 
2349   ASSERT_EQUAL_FP32(1.0, s31);
2350   ASSERT_EQUAL_FP32(2.0, s0);
2351   ASSERT_EQUAL_FP32(0.0, dst[0]);
2352   ASSERT_EQUAL_FP32(2.0, dst[1]);
2353   ASSERT_EQUAL_FP32(1.0, dst[2]);
2354   ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
2355   ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
2356 
2357   TEARDOWN();
2358 }
2359 
2360 
TEST(ldp_stp_double)2361 TEST(ldp_stp_double) {
2362   SETUP();
2363 
2364   double src[2] = {1.0, 2.0};
2365   double dst[3] = {0.0, 0.0, 0.0};
2366   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2367   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2368 
2369   START();
2370   __ Mov(x16, src_base);
2371   __ Mov(x17, dst_base);
2372   __ Ldp(d31, d0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
2373   __ Stp(d0, d31, MemOperand(x17, sizeof(dst[1]), PreIndex));
2374   END();
2375 
2376   RUN();
2377 
2378   ASSERT_EQUAL_FP64(1.0, d31);
2379   ASSERT_EQUAL_FP64(2.0, d0);
2380   ASSERT_EQUAL_FP64(0.0, dst[0]);
2381   ASSERT_EQUAL_FP64(2.0, dst[1]);
2382   ASSERT_EQUAL_FP64(1.0, dst[2]);
2383   ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
2384   ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
2385 
2386   TEARDOWN();
2387 }
2388 
2389 
TEST(ldp_stp_offset)2390 TEST(ldp_stp_offset) {
2391   SETUP();
2392 
2393   uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
2394                      0xffeeddccbbaa9988};
2395   uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
2396   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2397   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2398 
2399   START();
2400   __ Mov(x16, src_base);
2401   __ Mov(x17, dst_base);
2402   __ Mov(x18, src_base + 24);
2403   __ Mov(x19, dst_base + 56);
2404   __ Ldp(w0, w1, MemOperand(x16));
2405   __ Ldp(w2, w3, MemOperand(x16, 4));
2406   __ Ldp(x4, x5, MemOperand(x16, 8));
2407   __ Ldp(w6, w7, MemOperand(x18, -12));
2408   __ Ldp(x8, x9, MemOperand(x18, -16));
2409   __ Stp(w0, w1, MemOperand(x17));
2410   __ Stp(w2, w3, MemOperand(x17, 8));
2411   __ Stp(x4, x5, MemOperand(x17, 16));
2412   __ Stp(w6, w7, MemOperand(x19, -24));
2413   __ Stp(x8, x9, MemOperand(x19, -16));
2414   END();
2415 
2416   RUN();
2417 
2418   ASSERT_EQUAL_64(0x44556677, x0);
2419   ASSERT_EQUAL_64(0x00112233, x1);
2420   ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
2421   ASSERT_EQUAL_64(0x00112233, x2);
2422   ASSERT_EQUAL_64(0xccddeeff, x3);
2423   ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
2424   ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
2425   ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
2426   ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
2427   ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
2428   ASSERT_EQUAL_64(0x8899aabb, x6);
2429   ASSERT_EQUAL_64(0xbbaa9988, x7);
2430   ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
2431   ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
2432   ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
2433   ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
2434   ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
2435   ASSERT_EQUAL_64(src_base, x16);
2436   ASSERT_EQUAL_64(dst_base, x17);
2437   ASSERT_EQUAL_64(src_base + 24, x18);
2438   ASSERT_EQUAL_64(dst_base + 56, x19);
2439 
2440   TEARDOWN();
2441 }
2442 
2443 
TEST(ldnp_stnp_offset)2444 TEST(ldnp_stnp_offset) {
2445   SETUP();
2446 
2447   uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
2448                      0xffeeddccbbaa9988};
2449   uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
2450   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2451   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2452 
2453   START();
2454   __ Mov(x16, src_base);
2455   __ Mov(x17, dst_base);
2456   __ Mov(x18, src_base + 24);
2457   __ Mov(x19, dst_base + 56);
2458   __ Ldnp(w0, w1, MemOperand(x16));
2459   __ Ldnp(w2, w3, MemOperand(x16, 4));
2460   __ Ldnp(x4, x5, MemOperand(x16, 8));
2461   __ Ldnp(w6, w7, MemOperand(x18, -12));
2462   __ Ldnp(x8, x9, MemOperand(x18, -16));
2463   __ Stnp(w0, w1, MemOperand(x17));
2464   __ Stnp(w2, w3, MemOperand(x17, 8));
2465   __ Stnp(x4, x5, MemOperand(x17, 16));
2466   __ Stnp(w6, w7, MemOperand(x19, -24));
2467   __ Stnp(x8, x9, MemOperand(x19, -16));
2468   END();
2469 
2470   RUN();
2471 
2472   ASSERT_EQUAL_64(0x44556677, x0);
2473   ASSERT_EQUAL_64(0x00112233, x1);
2474   ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
2475   ASSERT_EQUAL_64(0x00112233, x2);
2476   ASSERT_EQUAL_64(0xccddeeff, x3);
2477   ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
2478   ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
2479   ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
2480   ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
2481   ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
2482   ASSERT_EQUAL_64(0x8899aabb, x6);
2483   ASSERT_EQUAL_64(0xbbaa9988, x7);
2484   ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
2485   ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
2486   ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
2487   ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
2488   ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
2489   ASSERT_EQUAL_64(src_base, x16);
2490   ASSERT_EQUAL_64(dst_base, x17);
2491   ASSERT_EQUAL_64(src_base + 24, x18);
2492   ASSERT_EQUAL_64(dst_base + 56, x19);
2493 
2494   TEARDOWN();
2495 }
2496 
2497 
TEST(ldp_stp_preindex)2498 TEST(ldp_stp_preindex) {
2499   SETUP();
2500 
2501   uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
2502                      0xffeeddccbbaa9988};
2503   uint64_t dst[5] = {0, 0, 0, 0, 0};
2504   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2505   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2506 
2507   START();
2508   __ Mov(x16, src_base);
2509   __ Mov(x17, dst_base);
2510   __ Mov(x18, dst_base + 16);
2511   __ Ldp(w0, w1, MemOperand(x16, 4, PreIndex));
2512   __ Mov(x19, x16);
2513   __ Ldp(w2, w3, MemOperand(x16, -4, PreIndex));
2514   __ Stp(w2, w3, MemOperand(x17, 4, PreIndex));
2515   __ Mov(x20, x17);
2516   __ Stp(w0, w1, MemOperand(x17, -4, PreIndex));
2517   __ Ldp(x4, x5, MemOperand(x16, 8, PreIndex));
2518   __ Mov(x21, x16);
2519   __ Ldp(x6, x7, MemOperand(x16, -8, PreIndex));
2520   __ Stp(x7, x6, MemOperand(x18, 8, PreIndex));
2521   __ Mov(x22, x18);
2522   __ Stp(x5, x4, MemOperand(x18, -8, PreIndex));
2523   END();
2524 
2525   RUN();
2526 
2527   ASSERT_EQUAL_64(0x00112233, x0);
2528   ASSERT_EQUAL_64(0xccddeeff, x1);
2529   ASSERT_EQUAL_64(0x44556677, x2);
2530   ASSERT_EQUAL_64(0x00112233, x3);
2531   ASSERT_EQUAL_64(0xccddeeff00112233, dst[0]);
2532   ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
2533   ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
2534   ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
2535   ASSERT_EQUAL_64(0x0011223344556677, x6);
2536   ASSERT_EQUAL_64(0x8899aabbccddeeff, x7);
2537   ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
2538   ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
2539   ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
2540   ASSERT_EQUAL_64(src_base, x16);
2541   ASSERT_EQUAL_64(dst_base, x17);
2542   ASSERT_EQUAL_64(dst_base + 16, x18);
2543   ASSERT_EQUAL_64(src_base + 4, x19);
2544   ASSERT_EQUAL_64(dst_base + 4, x20);
2545   ASSERT_EQUAL_64(src_base + 8, x21);
2546   ASSERT_EQUAL_64(dst_base + 24, x22);
2547 
2548   TEARDOWN();
2549 }
2550 
2551 
TEST(ldp_stp_postindex)2552 TEST(ldp_stp_postindex) {
2553   SETUP();
2554 
2555   uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
2556                      0xffeeddccbbaa9988, 0x7766554433221100};
2557   uint64_t dst[5] = {0, 0, 0, 0, 0};
2558   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2559   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2560 
2561   START();
2562   __ Mov(x16, src_base);
2563   __ Mov(x17, dst_base);
2564   __ Mov(x18, dst_base + 16);
2565   __ Ldp(w0, w1, MemOperand(x16, 4, PostIndex));
2566   __ Mov(x19, x16);
2567   __ Ldp(w2, w3, MemOperand(x16, -4, PostIndex));
2568   __ Stp(w2, w3, MemOperand(x17, 4, PostIndex));
2569   __ Mov(x20, x17);
2570   __ Stp(w0, w1, MemOperand(x17, -4, PostIndex));
2571   __ Ldp(x4, x5, MemOperand(x16, 8, PostIndex));
2572   __ Mov(x21, x16);
2573   __ Ldp(x6, x7, MemOperand(x16, -8, PostIndex));
2574   __ Stp(x7, x6, MemOperand(x18, 8, PostIndex));
2575   __ Mov(x22, x18);
2576   __ Stp(x5, x4, MemOperand(x18, -8, PostIndex));
2577   END();
2578 
2579   RUN();
2580 
2581   ASSERT_EQUAL_64(0x44556677, x0);
2582   ASSERT_EQUAL_64(0x00112233, x1);
2583   ASSERT_EQUAL_64(0x00112233, x2);
2584   ASSERT_EQUAL_64(0xccddeeff, x3);
2585   ASSERT_EQUAL_64(0x4455667700112233, dst[0]);
2586   ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
2587   ASSERT_EQUAL_64(0x0011223344556677, x4);
2588   ASSERT_EQUAL_64(0x8899aabbccddeeff, x5);
2589   ASSERT_EQUAL_64(0x8899aabbccddeeff, x6);
2590   ASSERT_EQUAL_64(0xffeeddccbbaa9988, x7);
2591   ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
2592   ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
2593   ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
2594   ASSERT_EQUAL_64(src_base, x16);
2595   ASSERT_EQUAL_64(dst_base, x17);
2596   ASSERT_EQUAL_64(dst_base + 16, x18);
2597   ASSERT_EQUAL_64(src_base + 4, x19);
2598   ASSERT_EQUAL_64(dst_base + 4, x20);
2599   ASSERT_EQUAL_64(src_base + 8, x21);
2600   ASSERT_EQUAL_64(dst_base + 24, x22);
2601 
2602   TEARDOWN();
2603 }
2604 
2605 
TEST(ldp_sign_extend)2606 TEST(ldp_sign_extend) {
2607   SETUP();
2608 
2609   uint32_t src[2] = {0x80000000, 0x7fffffff};
2610   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2611 
2612   START();
2613   __ Mov(x24, src_base);
2614   __ Ldpsw(x0, x1, MemOperand(x24));
2615   END();
2616 
2617   RUN();
2618 
2619   ASSERT_EQUAL_64(0xffffffff80000000, x0);
2620   ASSERT_EQUAL_64(0x000000007fffffff, x1);
2621 
2622   TEARDOWN();
2623 }
2624 
2625 
TEST(ldur_stur)2626 TEST(ldur_stur) {
2627   SETUP();
2628 
2629   int64_t src[2] = {0x0123456789abcdef, 0x0123456789abcdef};
2630   int64_t dst[5] = {0, 0, 0, 0, 0};
2631   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2632   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2633 
2634   START();
2635   __ Mov(x17, src_base);
2636   __ Mov(x18, dst_base);
2637   __ Mov(x19, src_base + 16);
2638   __ Mov(x20, dst_base + 32);
2639   __ Mov(x21, dst_base + 40);
2640   __ Ldr(w0, MemOperand(x17, 1));
2641   __ Str(w0, MemOperand(x18, 2));
2642   __ Ldr(x1, MemOperand(x17, 3));
2643   __ Str(x1, MemOperand(x18, 9));
2644   __ Ldr(w2, MemOperand(x19, -9));
2645   __ Str(w2, MemOperand(x20, -5));
2646   __ Ldrb(w3, MemOperand(x19, -1));
2647   __ Strb(w3, MemOperand(x21, -1));
2648   END();
2649 
2650   RUN();
2651 
2652   ASSERT_EQUAL_64(0x6789abcd, x0);
2653   ASSERT_EQUAL_64(0x00006789abcd0000, dst[0]);
2654   ASSERT_EQUAL_64(0xabcdef0123456789, x1);
2655   ASSERT_EQUAL_64(0xcdef012345678900, dst[1]);
2656   ASSERT_EQUAL_64(0x000000ab, dst[2]);
2657   ASSERT_EQUAL_64(0xabcdef01, x2);
2658   ASSERT_EQUAL_64(0x00abcdef01000000, dst[3]);
2659   ASSERT_EQUAL_64(0x00000001, x3);
2660   ASSERT_EQUAL_64(0x0100000000000000, dst[4]);
2661   ASSERT_EQUAL_64(src_base, x17);
2662   ASSERT_EQUAL_64(dst_base, x18);
2663   ASSERT_EQUAL_64(src_base + 16, x19);
2664   ASSERT_EQUAL_64(dst_base + 32, x20);
2665 
2666   TEARDOWN();
2667 }
2668 
2669 
TEST(ldr_literal)2670 TEST(ldr_literal) {
2671   SETUP();
2672 
2673   START();
2674   __ Ldr(x2, 0x1234567890abcdef);
2675   __ Ldr(w3, 0xfedcba09);
2676   __ Ldr(d13, 1.234);
2677   __ Ldr(s25, 2.5);
2678   END();
2679 
2680   RUN();
2681 
2682   ASSERT_EQUAL_64(0x1234567890abcdef, x2);
2683   ASSERT_EQUAL_64(0xfedcba09, x3);
2684   ASSERT_EQUAL_FP64(1.234, d13);
2685   ASSERT_EQUAL_FP32(2.5, s25);
2686 
2687   TEARDOWN();
2688 }
2689 
2690 
LdrLiteralRangeHelper(ptrdiff_t range_,LiteralPoolEmitOption option,bool expect_dump)2691 static void LdrLiteralRangeHelper(ptrdiff_t range_,
2692                                   LiteralPoolEmitOption option,
2693                                   bool expect_dump) {
2694   VIXL_ASSERT(range_ > 0);
2695   SETUP_SIZE(range_ + 1024);
2696 
2697   Label label_1, label_2;
2698 
2699   size_t range = static_cast<size_t>(range_);
2700   size_t code_size = 0;
2701   size_t pool_guard_size;
2702 
2703   if (option == NoJumpRequired) {
2704     // Space for an explicit branch.
2705     pool_guard_size = sizeof(Instr);
2706   } else {
2707     pool_guard_size = 0;
2708   }
2709 
2710   START();
2711   // Force a pool dump so the pool starts off empty.
2712   __ EmitLiteralPool(JumpRequired);
2713   ASSERT_LITERAL_POOL_SIZE(0);
2714 
2715   __ Ldr(x0, 0x1234567890abcdef);
2716   __ Ldr(w1, 0xfedcba09);
2717   __ Ldr(d0, 1.234);
2718   __ Ldr(s1, 2.5);
2719   ASSERT_LITERAL_POOL_SIZE(24);
2720 
2721   code_size += 4 * sizeof(Instr);
2722 
2723   // Check that the requested range (allowing space for a branch over the pool)
2724   // can be handled by this test.
2725   VIXL_ASSERT((code_size + pool_guard_size) <= range);
2726 
2727   // Emit NOPs up to 'range', leaving space for the pool guard.
2728   while ((code_size + pool_guard_size) < range) {
2729     __ Nop();
2730     code_size += sizeof(Instr);
2731   }
2732 
2733   // Emit the guard sequence before the literal pool.
2734   if (option == NoJumpRequired) {
2735     __ B(&label_1);
2736     code_size += sizeof(Instr);
2737   }
2738 
2739   VIXL_ASSERT(code_size == range);
2740   ASSERT_LITERAL_POOL_SIZE(24);
2741 
2742   // Possibly generate a literal pool.
2743   __ CheckLiteralPool(option);
2744   __ Bind(&label_1);
2745   if (expect_dump) {
2746     ASSERT_LITERAL_POOL_SIZE(0);
2747   } else {
2748     ASSERT_LITERAL_POOL_SIZE(24);
2749   }
2750 
2751   // Force a pool flush to check that a second pool functions correctly.
2752   __ EmitLiteralPool(JumpRequired);
2753   ASSERT_LITERAL_POOL_SIZE(0);
2754 
2755   // These loads should be after the pool (and will require a new one).
2756   __ Ldr(x4, 0x34567890abcdef12);
2757   __ Ldr(w5, 0xdcba09fe);
2758   __ Ldr(d4, 123.4);
2759   __ Ldr(s5, 250.0);
2760   ASSERT_LITERAL_POOL_SIZE(24);
2761   END();
2762 
2763   RUN();
2764 
2765   // Check that the literals loaded correctly.
2766   ASSERT_EQUAL_64(0x1234567890abcdef, x0);
2767   ASSERT_EQUAL_64(0xfedcba09, x1);
2768   ASSERT_EQUAL_FP64(1.234, d0);
2769   ASSERT_EQUAL_FP32(2.5, s1);
2770   ASSERT_EQUAL_64(0x34567890abcdef12, x4);
2771   ASSERT_EQUAL_64(0xdcba09fe, x5);
2772   ASSERT_EQUAL_FP64(123.4, d4);
2773   ASSERT_EQUAL_FP32(250.0, s5);
2774 
2775   TEARDOWN();
2776 }
2777 
2778 
TEST(ldr_literal_range_1)2779 TEST(ldr_literal_range_1) {
2780   LdrLiteralRangeHelper(kRecommendedLiteralPoolRange,
2781                         NoJumpRequired,
2782                         true);
2783 }
2784 
2785 
TEST(ldr_literal_range_2)2786 TEST(ldr_literal_range_2) {
2787   LdrLiteralRangeHelper(kRecommendedLiteralPoolRange-sizeof(Instr),
2788                         NoJumpRequired,
2789                         false);
2790 }
2791 
2792 
TEST(ldr_literal_range_3)2793 TEST(ldr_literal_range_3) {
2794   LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange,
2795                         JumpRequired,
2796                         true);
2797 }
2798 
2799 
TEST(ldr_literal_range_4)2800 TEST(ldr_literal_range_4) {
2801   LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange-sizeof(Instr),
2802                         JumpRequired,
2803                         false);
2804 }
2805 
2806 
TEST(ldr_literal_range_5)2807 TEST(ldr_literal_range_5) {
2808   LdrLiteralRangeHelper(kLiteralPoolCheckInterval,
2809                         JumpRequired,
2810                         false);
2811 }
2812 
2813 
TEST(ldr_literal_range_6)2814 TEST(ldr_literal_range_6) {
2815   LdrLiteralRangeHelper(kLiteralPoolCheckInterval-sizeof(Instr),
2816                         JumpRequired,
2817                         false);
2818 }
2819 
2820 
TEST(add_sub_imm)2821 TEST(add_sub_imm) {
2822   SETUP();
2823 
2824   START();
2825   __ Mov(x0, 0x0);
2826   __ Mov(x1, 0x1111);
2827   __ Mov(x2, 0xffffffffffffffff);
2828   __ Mov(x3, 0x8000000000000000);
2829 
2830   __ Add(x10, x0, Operand(0x123));
2831   __ Add(x11, x1, Operand(0x122000));
2832   __ Add(x12, x0, Operand(0xabc << 12));
2833   __ Add(x13, x2, Operand(1));
2834 
2835   __ Add(w14, w0, Operand(0x123));
2836   __ Add(w15, w1, Operand(0x122000));
2837   __ Add(w16, w0, Operand(0xabc << 12));
2838   __ Add(w17, w2, Operand(1));
2839 
2840   __ Sub(x20, x0, Operand(0x1));
2841   __ Sub(x21, x1, Operand(0x111));
2842   __ Sub(x22, x1, Operand(0x1 << 12));
2843   __ Sub(x23, x3, Operand(1));
2844 
2845   __ Sub(w24, w0, Operand(0x1));
2846   __ Sub(w25, w1, Operand(0x111));
2847   __ Sub(w26, w1, Operand(0x1 << 12));
2848   __ Sub(w27, w3, Operand(1));
2849   END();
2850 
2851   RUN();
2852 
2853   ASSERT_EQUAL_64(0x123, x10);
2854   ASSERT_EQUAL_64(0x123111, x11);
2855   ASSERT_EQUAL_64(0xabc000, x12);
2856   ASSERT_EQUAL_64(0x0, x13);
2857 
2858   ASSERT_EQUAL_32(0x123, w14);
2859   ASSERT_EQUAL_32(0x123111, w15);
2860   ASSERT_EQUAL_32(0xabc000, w16);
2861   ASSERT_EQUAL_32(0x0, w17);
2862 
2863   ASSERT_EQUAL_64(0xffffffffffffffff, x20);
2864   ASSERT_EQUAL_64(0x1000, x21);
2865   ASSERT_EQUAL_64(0x111, x22);
2866   ASSERT_EQUAL_64(0x7fffffffffffffff, x23);
2867 
2868   ASSERT_EQUAL_32(0xffffffff, w24);
2869   ASSERT_EQUAL_32(0x1000, w25);
2870   ASSERT_EQUAL_32(0x111, w26);
2871   ASSERT_EQUAL_32(0xffffffff, w27);
2872 
2873   TEARDOWN();
2874 }
2875 
2876 
TEST(add_sub_wide_imm)2877 TEST(add_sub_wide_imm) {
2878   SETUP();
2879 
2880   START();
2881   __ Mov(x0, 0x0);
2882   __ Mov(x1, 0x1);
2883 
2884   __ Add(x10, x0, Operand(0x1234567890abcdef));
2885   __ Add(x11, x1, Operand(0xffffffff));
2886 
2887   __ Add(w12, w0, Operand(0x12345678));
2888   __ Add(w13, w1, Operand(0xffffffff));
2889 
2890   __ Sub(x20, x0, Operand(0x1234567890abcdef));
2891 
2892   __ Sub(w21, w0, Operand(0x12345678));
2893   END();
2894 
2895   RUN();
2896 
2897   ASSERT_EQUAL_64(0x1234567890abcdef, x10);
2898   ASSERT_EQUAL_64(0x100000000, x11);
2899 
2900   ASSERT_EQUAL_32(0x12345678, w12);
2901   ASSERT_EQUAL_64(0x0, x13);
2902 
2903   ASSERT_EQUAL_64(-0x1234567890abcdef, x20);
2904 
2905   ASSERT_EQUAL_32(-0x12345678, w21);
2906 
2907   TEARDOWN();
2908 }
2909 
2910 
TEST(add_sub_shifted)2911 TEST(add_sub_shifted) {
2912   SETUP();
2913 
2914   START();
2915   __ Mov(x0, 0);
2916   __ Mov(x1, 0x0123456789abcdef);
2917   __ Mov(x2, 0xfedcba9876543210);
2918   __ Mov(x3, 0xffffffffffffffff);
2919 
2920   __ Add(x10, x1, Operand(x2));
2921   __ Add(x11, x0, Operand(x1, LSL, 8));
2922   __ Add(x12, x0, Operand(x1, LSR, 8));
2923   __ Add(x13, x0, Operand(x1, ASR, 8));
2924   __ Add(x14, x0, Operand(x2, ASR, 8));
2925   __ Add(w15, w0, Operand(w1, ASR, 8));
2926   __ Add(w18, w3, Operand(w1, ROR, 8));
2927   __ Add(x19, x3, Operand(x1, ROR, 8));
2928 
2929   __ Sub(x20, x3, Operand(x2));
2930   __ Sub(x21, x3, Operand(x1, LSL, 8));
2931   __ Sub(x22, x3, Operand(x1, LSR, 8));
2932   __ Sub(x23, x3, Operand(x1, ASR, 8));
2933   __ Sub(x24, x3, Operand(x2, ASR, 8));
2934   __ Sub(w25, w3, Operand(w1, ASR, 8));
2935   __ Sub(w26, w3, Operand(w1, ROR, 8));
2936   __ Sub(x27, x3, Operand(x1, ROR, 8));
2937   END();
2938 
2939   RUN();
2940 
2941   ASSERT_EQUAL_64(0xffffffffffffffff, x10);
2942   ASSERT_EQUAL_64(0x23456789abcdef00, x11);
2943   ASSERT_EQUAL_64(0x000123456789abcd, x12);
2944   ASSERT_EQUAL_64(0x000123456789abcd, x13);
2945   ASSERT_EQUAL_64(0xfffedcba98765432, x14);
2946   ASSERT_EQUAL_64(0xff89abcd, x15);
2947   ASSERT_EQUAL_64(0xef89abcc, x18);
2948   ASSERT_EQUAL_64(0xef0123456789abcc, x19);
2949 
2950   ASSERT_EQUAL_64(0x0123456789abcdef, x20);
2951   ASSERT_EQUAL_64(0xdcba9876543210ff, x21);
2952   ASSERT_EQUAL_64(0xfffedcba98765432, x22);
2953   ASSERT_EQUAL_64(0xfffedcba98765432, x23);
2954   ASSERT_EQUAL_64(0x000123456789abcd, x24);
2955   ASSERT_EQUAL_64(0x00765432, x25);
2956   ASSERT_EQUAL_64(0x10765432, x26);
2957   ASSERT_EQUAL_64(0x10fedcba98765432, x27);
2958 
2959   TEARDOWN();
2960 }
2961 
2962 
TEST(add_sub_extended)2963 TEST(add_sub_extended) {
2964   SETUP();
2965 
2966   START();
2967   __ Mov(x0, 0);
2968   __ Mov(x1, 0x0123456789abcdef);
2969   __ Mov(x2, 0xfedcba9876543210);
2970   __ Mov(w3, 0x80);
2971 
2972   __ Add(x10, x0, Operand(x1, UXTB, 0));
2973   __ Add(x11, x0, Operand(x1, UXTB, 1));
2974   __ Add(x12, x0, Operand(x1, UXTH, 2));
2975   __ Add(x13, x0, Operand(x1, UXTW, 4));
2976 
2977   __ Add(x14, x0, Operand(x1, SXTB, 0));
2978   __ Add(x15, x0, Operand(x1, SXTB, 1));
2979   __ Add(x16, x0, Operand(x1, SXTH, 2));
2980   __ Add(x17, x0, Operand(x1, SXTW, 3));
2981   __ Add(x18, x0, Operand(x2, SXTB, 0));
2982   __ Add(x19, x0, Operand(x2, SXTB, 1));
2983   __ Add(x20, x0, Operand(x2, SXTH, 2));
2984   __ Add(x21, x0, Operand(x2, SXTW, 3));
2985 
2986   __ Add(x22, x1, Operand(x2, SXTB, 1));
2987   __ Sub(x23, x1, Operand(x2, SXTB, 1));
2988 
2989   __ Add(w24, w1, Operand(w2, UXTB, 2));
2990   __ Add(w25, w0, Operand(w1, SXTB, 0));
2991   __ Add(w26, w0, Operand(w1, SXTB, 1));
2992   __ Add(w27, w2, Operand(w1, SXTW, 3));
2993 
2994   __ Add(w28, w0, Operand(w1, SXTW, 3));
2995   __ Add(x29, x0, Operand(w1, SXTW, 3));
2996 
2997   __ Sub(x30, x0, Operand(w3, SXTB, 1));
2998   END();
2999 
3000   RUN();
3001 
3002   ASSERT_EQUAL_64(0xef, x10);
3003   ASSERT_EQUAL_64(0x1de, x11);
3004   ASSERT_EQUAL_64(0x337bc, x12);
3005   ASSERT_EQUAL_64(0x89abcdef0, x13);
3006 
3007   ASSERT_EQUAL_64(0xffffffffffffffef, x14);
3008   ASSERT_EQUAL_64(0xffffffffffffffde, x15);
3009   ASSERT_EQUAL_64(0xffffffffffff37bc, x16);
3010   ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x17);
3011   ASSERT_EQUAL_64(0x10, x18);
3012   ASSERT_EQUAL_64(0x20, x19);
3013   ASSERT_EQUAL_64(0xc840, x20);
3014   ASSERT_EQUAL_64(0x3b2a19080, x21);
3015 
3016   ASSERT_EQUAL_64(0x0123456789abce0f, x22);
3017   ASSERT_EQUAL_64(0x0123456789abcdcf, x23);
3018 
3019   ASSERT_EQUAL_32(0x89abce2f, w24);
3020   ASSERT_EQUAL_32(0xffffffef, w25);
3021   ASSERT_EQUAL_32(0xffffffde, w26);
3022   ASSERT_EQUAL_32(0xc3b2a188, w27);
3023 
3024   ASSERT_EQUAL_32(0x4d5e6f78, w28);
3025   ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x29);
3026 
3027   ASSERT_EQUAL_64(256, x30);
3028 
3029   TEARDOWN();
3030 }
3031 
3032 
TEST(add_sub_negative)3033 TEST(add_sub_negative) {
3034   SETUP();
3035 
3036   START();
3037   __ Mov(x0, 0);
3038   __ Mov(x1, 4687);
3039   __ Mov(x2, 0x1122334455667788);
3040   __ Mov(w3, 0x11223344);
3041   __ Mov(w4, 400000);
3042 
3043   __ Add(x10, x0, -42);
3044   __ Add(x11, x1, -687);
3045   __ Add(x12, x2, -0x88);
3046 
3047   __ Sub(x13, x0, -600);
3048   __ Sub(x14, x1, -313);
3049   __ Sub(x15, x2, -0x555);
3050 
3051   __ Add(w19, w3, -0x344);
3052   __ Add(w20, w4, -2000);
3053 
3054   __ Sub(w21, w3, -0xbc);
3055   __ Sub(w22, w4, -2000);
3056   END();
3057 
3058   RUN();
3059 
3060   ASSERT_EQUAL_64(-42, x10);
3061   ASSERT_EQUAL_64(4000, x11);
3062   ASSERT_EQUAL_64(0x1122334455667700, x12);
3063 
3064   ASSERT_EQUAL_64(600, x13);
3065   ASSERT_EQUAL_64(5000, x14);
3066   ASSERT_EQUAL_64(0x1122334455667cdd, x15);
3067 
3068   ASSERT_EQUAL_32(0x11223000, w19);
3069   ASSERT_EQUAL_32(398000, w20);
3070 
3071   ASSERT_EQUAL_32(0x11223400, w21);
3072   ASSERT_EQUAL_32(402000, w22);
3073 
3074   TEARDOWN();
3075 }
3076 
3077 
TEST(add_sub_zero)3078 TEST(add_sub_zero) {
3079   SETUP();
3080 
3081   START();
3082   __ Mov(x0, 0);
3083   __ Mov(x1, 0);
3084   __ Mov(x2, 0);
3085 
3086   Label blob1;
3087   __ Bind(&blob1);
3088   __ Add(x0, x0, 0);
3089   __ Sub(x1, x1, 0);
3090   __ Sub(x2, x2, xzr);
3091   VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob1) == 0);
3092 
3093   Label blob2;
3094   __ Bind(&blob2);
3095   __ Add(w3, w3, 0);
3096   VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob2) != 0);
3097 
3098   Label blob3;
3099   __ Bind(&blob3);
3100   __ Sub(w3, w3, wzr);
3101   VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob3) != 0);
3102 
3103   END();
3104 
3105   RUN();
3106 
3107   ASSERT_EQUAL_64(0, x0);
3108   ASSERT_EQUAL_64(0, x1);
3109   ASSERT_EQUAL_64(0, x2);
3110 
3111   TEARDOWN();
3112 }
3113 
3114 
TEST(claim_drop_zero)3115 TEST(claim_drop_zero) {
3116   SETUP();
3117 
3118   START();
3119 
3120   Label start;
3121   __ Bind(&start);
3122   __ Claim(Operand(0));
3123   __ Drop(Operand(0));
3124   __ Claim(Operand(xzr));
3125   __ Drop(Operand(xzr));
3126   VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
3127 
3128   END();
3129 
3130   RUN();
3131 
3132   TEARDOWN();
3133 }
3134 
3135 
TEST(neg)3136 TEST(neg) {
3137   SETUP();
3138 
3139   START();
3140   __ Mov(x0, 0xf123456789abcdef);
3141 
3142   // Immediate.
3143   __ Neg(x1, 0x123);
3144   __ Neg(w2, 0x123);
3145 
3146   // Shifted.
3147   __ Neg(x3, Operand(x0, LSL, 1));
3148   __ Neg(w4, Operand(w0, LSL, 2));
3149   __ Neg(x5, Operand(x0, LSR, 3));
3150   __ Neg(w6, Operand(w0, LSR, 4));
3151   __ Neg(x7, Operand(x0, ASR, 5));
3152   __ Neg(w8, Operand(w0, ASR, 6));
3153 
3154   // Extended.
3155   __ Neg(w9, Operand(w0, UXTB));
3156   __ Neg(x10, Operand(x0, SXTB, 1));
3157   __ Neg(w11, Operand(w0, UXTH, 2));
3158   __ Neg(x12, Operand(x0, SXTH, 3));
3159   __ Neg(w13, Operand(w0, UXTW, 4));
3160   __ Neg(x14, Operand(x0, SXTW, 4));
3161   END();
3162 
3163   RUN();
3164 
3165   ASSERT_EQUAL_64(0xfffffffffffffedd, x1);
3166   ASSERT_EQUAL_64(0xfffffedd, x2);
3167   ASSERT_EQUAL_64(0x1db97530eca86422, x3);
3168   ASSERT_EQUAL_64(0xd950c844, x4);
3169   ASSERT_EQUAL_64(0xe1db97530eca8643, x5);
3170   ASSERT_EQUAL_64(0xf7654322, x6);
3171   ASSERT_EQUAL_64(0x0076e5d4c3b2a191, x7);
3172   ASSERT_EQUAL_64(0x01d950c9, x8);
3173   ASSERT_EQUAL_64(0xffffff11, x9);
3174   ASSERT_EQUAL_64(0x0000000000000022, x10);
3175   ASSERT_EQUAL_64(0xfffcc844, x11);
3176   ASSERT_EQUAL_64(0x0000000000019088, x12);
3177   ASSERT_EQUAL_64(0x65432110, x13);
3178   ASSERT_EQUAL_64(0x0000000765432110, x14);
3179 
3180   TEARDOWN();
3181 }
3182 
3183 
TEST(adc_sbc_shift)3184 TEST(adc_sbc_shift) {
3185   SETUP();
3186 
3187   START();
3188   __ Mov(x0, 0);
3189   __ Mov(x1, 1);
3190   __ Mov(x2, 0x0123456789abcdef);
3191   __ Mov(x3, 0xfedcba9876543210);
3192   __ Mov(x4, 0xffffffffffffffff);
3193 
3194   // Clear the C flag.
3195   __ Adds(x0, x0, Operand(0));
3196 
3197   __ Adc(x5, x2, Operand(x3));
3198   __ Adc(x6, x0, Operand(x1, LSL, 60));
3199   __ Sbc(x7, x4, Operand(x3, LSR, 4));
3200   __ Adc(x8, x2, Operand(x3, ASR, 4));
3201   __ Adc(x9, x2, Operand(x3, ROR, 8));
3202 
3203   __ Adc(w10, w2, Operand(w3));
3204   __ Adc(w11, w0, Operand(w1, LSL, 30));
3205   __ Sbc(w12, w4, Operand(w3, LSR, 4));
3206   __ Adc(w13, w2, Operand(w3, ASR, 4));
3207   __ Adc(w14, w2, Operand(w3, ROR, 8));
3208 
3209   // Set the C flag.
3210   __ Cmp(w0, Operand(w0));
3211 
3212   __ Adc(x18, x2, Operand(x3));
3213   __ Adc(x19, x0, Operand(x1, LSL, 60));
3214   __ Sbc(x20, x4, Operand(x3, LSR, 4));
3215   __ Adc(x21, x2, Operand(x3, ASR, 4));
3216   __ Adc(x22, x2, Operand(x3, ROR, 8));
3217 
3218   __ Adc(w23, w2, Operand(w3));
3219   __ Adc(w24, w0, Operand(w1, LSL, 30));
3220   __ Sbc(w25, w4, Operand(w3, LSR, 4));
3221   __ Adc(w26, w2, Operand(w3, ASR, 4));
3222   __ Adc(w27, w2, Operand(w3, ROR, 8));
3223   END();
3224 
3225   RUN();
3226 
3227   ASSERT_EQUAL_64(0xffffffffffffffff, x5);
3228   ASSERT_EQUAL_64(INT64_C(1) << 60, x6);
3229   ASSERT_EQUAL_64(0xf0123456789abcdd, x7);
3230   ASSERT_EQUAL_64(0x0111111111111110, x8);
3231   ASSERT_EQUAL_64(0x1222222222222221, x9);
3232 
3233   ASSERT_EQUAL_32(0xffffffff, w10);
3234   ASSERT_EQUAL_32(INT32_C(1) << 30, w11);
3235   ASSERT_EQUAL_32(0xf89abcdd, w12);
3236   ASSERT_EQUAL_32(0x91111110, w13);
3237   ASSERT_EQUAL_32(0x9a222221, w14);
3238 
3239   ASSERT_EQUAL_64(0xffffffffffffffff + 1, x18);
3240   ASSERT_EQUAL_64((INT64_C(1) << 60) + 1, x19);
3241   ASSERT_EQUAL_64(0xf0123456789abcdd + 1, x20);
3242   ASSERT_EQUAL_64(0x0111111111111110 + 1, x21);
3243   ASSERT_EQUAL_64(0x1222222222222221 + 1, x22);
3244 
3245   ASSERT_EQUAL_32(0xffffffff + 1, w23);
3246   ASSERT_EQUAL_32((INT32_C(1) << 30) + 1, w24);
3247   ASSERT_EQUAL_32(0xf89abcdd + 1, w25);
3248   ASSERT_EQUAL_32(0x91111110 + 1, w26);
3249   ASSERT_EQUAL_32(0x9a222221 + 1, w27);
3250 
3251   // Check that adc correctly sets the condition flags.
3252   START();
3253   __ Mov(x0, 1);
3254   __ Mov(x1, 0xffffffffffffffff);
3255   // Clear the C flag.
3256   __ Adds(x0, x0, Operand(0));
3257   __ Adcs(x10, x0, Operand(x1));
3258   END();
3259 
3260   RUN();
3261 
3262   ASSERT_EQUAL_NZCV(ZCFlag);
3263   ASSERT_EQUAL_64(0, x10);
3264 
3265   START();
3266   __ Mov(x0, 1);
3267   __ Mov(x1, 0x8000000000000000);
3268   // Clear the C flag.
3269   __ Adds(x0, x0, Operand(0));
3270   __ Adcs(x10, x0, Operand(x1, ASR, 63));
3271   END();
3272 
3273   RUN();
3274 
3275   ASSERT_EQUAL_NZCV(ZCFlag);
3276   ASSERT_EQUAL_64(0, x10);
3277 
3278   START();
3279   __ Mov(x0, 0x10);
3280   __ Mov(x1, 0x07ffffffffffffff);
3281   // Clear the C flag.
3282   __ Adds(x0, x0, Operand(0));
3283   __ Adcs(x10, x0, Operand(x1, LSL, 4));
3284   END();
3285 
3286   RUN();
3287 
3288   ASSERT_EQUAL_NZCV(NVFlag);
3289   ASSERT_EQUAL_64(0x8000000000000000, x10);
3290 
3291   // Check that sbc correctly sets the condition flags.
3292   START();
3293   __ Mov(x0, 0);
3294   __ Mov(x1, 0xffffffffffffffff);
3295   // Clear the C flag.
3296   __ Adds(x0, x0, Operand(0));
3297   __ Sbcs(x10, x0, Operand(x1));
3298   END();
3299 
3300   RUN();
3301 
3302   ASSERT_EQUAL_NZCV(ZFlag);
3303   ASSERT_EQUAL_64(0, x10);
3304 
3305   START();
3306   __ Mov(x0, 1);
3307   __ Mov(x1, 0xffffffffffffffff);
3308   // Clear the C flag.
3309   __ Adds(x0, x0, Operand(0));
3310   __ Sbcs(x10, x0, Operand(x1, LSR, 1));
3311   END();
3312 
3313   RUN();
3314 
3315   ASSERT_EQUAL_NZCV(NFlag);
3316   ASSERT_EQUAL_64(0x8000000000000001, x10);
3317 
3318   START();
3319   __ Mov(x0, 0);
3320   // Clear the C flag.
3321   __ Adds(x0, x0, Operand(0));
3322   __ Sbcs(x10, x0, Operand(0xffffffffffffffff));
3323   END();
3324 
3325   RUN();
3326 
3327   ASSERT_EQUAL_NZCV(ZFlag);
3328   ASSERT_EQUAL_64(0, x10);
3329 
3330   START();
3331   __ Mov(w0, 0x7fffffff);
3332   // Clear the C flag.
3333   __ Adds(x0, x0, Operand(0));
3334   __ Ngcs(w10, w0);
3335   END();
3336 
3337   RUN();
3338 
3339   ASSERT_EQUAL_NZCV(NFlag);
3340   ASSERT_EQUAL_64(0x80000000, x10);
3341 
3342   START();
3343   // Clear the C flag.
3344   __ Adds(x0, x0, Operand(0));
3345   __ Ngcs(x10, 0x7fffffffffffffff);
3346   END();
3347 
3348   RUN();
3349 
3350   ASSERT_EQUAL_NZCV(NFlag);
3351   ASSERT_EQUAL_64(0x8000000000000000, x10);
3352 
3353   START();
3354   __ Mov(x0, 0);
3355   // Set the C flag.
3356   __ Cmp(x0, Operand(x0));
3357   __ Sbcs(x10, x0, Operand(1));
3358   END();
3359 
3360   RUN();
3361 
3362   ASSERT_EQUAL_NZCV(NFlag);
3363   ASSERT_EQUAL_64(0xffffffffffffffff, x10);
3364 
3365   START();
3366   __ Mov(x0, 0);
3367   // Set the C flag.
3368   __ Cmp(x0, Operand(x0));
3369   __ Ngcs(x10, 0x7fffffffffffffff);
3370   END();
3371 
3372   RUN();
3373 
3374   ASSERT_EQUAL_NZCV(NFlag);
3375   ASSERT_EQUAL_64(0x8000000000000001, x10);
3376 
3377   TEARDOWN();
3378 }
3379 
3380 
TEST(adc_sbc_extend)3381 TEST(adc_sbc_extend) {
3382   SETUP();
3383 
3384   START();
3385   // Clear the C flag.
3386   __ Adds(x0, x0, Operand(0));
3387 
3388   __ Mov(x0, 0);
3389   __ Mov(x1, 1);
3390   __ Mov(x2, 0x0123456789abcdef);
3391 
3392   __ Adc(x10, x1, Operand(w2, UXTB, 1));
3393   __ Adc(x11, x1, Operand(x2, SXTH, 2));
3394   __ Sbc(x12, x1, Operand(w2, UXTW, 4));
3395   __ Adc(x13, x1, Operand(x2, UXTX, 4));
3396 
3397   __ Adc(w14, w1, Operand(w2, UXTB, 1));
3398   __ Adc(w15, w1, Operand(w2, SXTH, 2));
3399   __ Adc(w9, w1, Operand(w2, UXTW, 4));
3400 
3401   // Set the C flag.
3402   __ Cmp(w0, Operand(w0));
3403 
3404   __ Adc(x20, x1, Operand(w2, UXTB, 1));
3405   __ Adc(x21, x1, Operand(x2, SXTH, 2));
3406   __ Sbc(x22, x1, Operand(w2, UXTW, 4));
3407   __ Adc(x23, x1, Operand(x2, UXTX, 4));
3408 
3409   __ Adc(w24, w1, Operand(w2, UXTB, 1));
3410   __ Adc(w25, w1, Operand(w2, SXTH, 2));
3411   __ Adc(w26, w1, Operand(w2, UXTW, 4));
3412   END();
3413 
3414   RUN();
3415 
3416   ASSERT_EQUAL_64(0x1df, x10);
3417   ASSERT_EQUAL_64(0xffffffffffff37bd, x11);
3418   ASSERT_EQUAL_64(0xfffffff765432110, x12);
3419   ASSERT_EQUAL_64(0x123456789abcdef1, x13);
3420 
3421   ASSERT_EQUAL_32(0x1df, w14);
3422   ASSERT_EQUAL_32(0xffff37bd, w15);
3423   ASSERT_EQUAL_32(0x9abcdef1, w9);
3424 
3425   ASSERT_EQUAL_64(0x1df + 1, x20);
3426   ASSERT_EQUAL_64(0xffffffffffff37bd + 1, x21);
3427   ASSERT_EQUAL_64(0xfffffff765432110 + 1, x22);
3428   ASSERT_EQUAL_64(0x123456789abcdef1 + 1, x23);
3429 
3430   ASSERT_EQUAL_32(0x1df + 1, w24);
3431   ASSERT_EQUAL_32(0xffff37bd + 1, w25);
3432   ASSERT_EQUAL_32(0x9abcdef1 + 1, w26);
3433 
3434   // Check that adc correctly sets the condition flags.
3435   START();
3436   __ Mov(x0, 0xff);
3437   __ Mov(x1, 0xffffffffffffffff);
3438   // Clear the C flag.
3439   __ Adds(x0, x0, Operand(0));
3440   __ Adcs(x10, x0, Operand(x1, SXTX, 1));
3441   END();
3442 
3443   RUN();
3444 
3445   ASSERT_EQUAL_NZCV(CFlag);
3446 
3447   START();
3448   __ Mov(x0, 0x7fffffffffffffff);
3449   __ Mov(x1, 1);
3450   // Clear the C flag.
3451   __ Adds(x0, x0, Operand(0));
3452   __ Adcs(x10, x0, Operand(x1, UXTB, 2));
3453   END();
3454 
3455   RUN();
3456 
3457   ASSERT_EQUAL_NZCV(NVFlag);
3458 
3459   START();
3460   __ Mov(x0, 0x7fffffffffffffff);
3461   // Clear the C flag.
3462   __ Adds(x0, x0, Operand(0));
3463   __ Adcs(x10, x0, Operand(1));
3464   END();
3465 
3466   RUN();
3467 
3468   ASSERT_EQUAL_NZCV(NVFlag);
3469 
3470   TEARDOWN();
3471 }
3472 
3473 
TEST(adc_sbc_wide_imm)3474 TEST(adc_sbc_wide_imm) {
3475   SETUP();
3476 
3477   START();
3478   __ Mov(x0, 0);
3479 
3480   // Clear the C flag.
3481   __ Adds(x0, x0, Operand(0));
3482 
3483   __ Adc(x7, x0, Operand(0x1234567890abcdef));
3484   __ Adc(w8, w0, Operand(0xffffffff));
3485   __ Sbc(x9, x0, Operand(0x1234567890abcdef));
3486   __ Sbc(w10, w0, Operand(0xffffffff));
3487   __ Ngc(x11, Operand(0xffffffff00000000));
3488   __ Ngc(w12, Operand(0xffff0000));
3489 
3490   // Set the C flag.
3491   __ Cmp(w0, Operand(w0));
3492 
3493   __ Adc(x18, x0, Operand(0x1234567890abcdef));
3494   __ Adc(w19, w0, Operand(0xffffffff));
3495   __ Sbc(x20, x0, Operand(0x1234567890abcdef));
3496   __ Sbc(w21, w0, Operand(0xffffffff));
3497   __ Ngc(x22, Operand(0xffffffff00000000));
3498   __ Ngc(w23, Operand(0xffff0000));
3499   END();
3500 
3501   RUN();
3502 
3503   ASSERT_EQUAL_64(0x1234567890abcdef, x7);
3504   ASSERT_EQUAL_64(0xffffffff, x8);
3505   ASSERT_EQUAL_64(0xedcba9876f543210, x9);
3506   ASSERT_EQUAL_64(0, x10);
3507   ASSERT_EQUAL_64(0xffffffff, x11);
3508   ASSERT_EQUAL_64(0xffff, x12);
3509 
3510   ASSERT_EQUAL_64(0x1234567890abcdef + 1, x18);
3511   ASSERT_EQUAL_64(0, x19);
3512   ASSERT_EQUAL_64(0xedcba9876f543211, x20);
3513   ASSERT_EQUAL_64(1, x21);
3514   ASSERT_EQUAL_64(0x0000000100000000, x22);
3515   ASSERT_EQUAL_64(0x0000000000010000, x23);
3516 
3517   TEARDOWN();
3518 }
3519 
TEST(flags)3520 TEST(flags) {
3521   SETUP();
3522 
3523   START();
3524   __ Mov(x0, 0);
3525   __ Mov(x1, 0x1111111111111111);
3526   __ Neg(x10, Operand(x0));
3527   __ Neg(x11, Operand(x1));
3528   __ Neg(w12, Operand(w1));
3529   // Clear the C flag.
3530   __ Adds(x0, x0, Operand(0));
3531   __ Ngc(x13, Operand(x0));
3532   // Set the C flag.
3533   __ Cmp(x0, Operand(x0));
3534   __ Ngc(w14, Operand(w0));
3535   END();
3536 
3537   RUN();
3538 
3539   ASSERT_EQUAL_64(0, x10);
3540   ASSERT_EQUAL_64(-0x1111111111111111, x11);
3541   ASSERT_EQUAL_32(-0x11111111, w12);
3542   ASSERT_EQUAL_64(-1, x13);
3543   ASSERT_EQUAL_32(0, w14);
3544 
3545   START();
3546   __ Mov(x0, 0);
3547   __ Cmp(x0, Operand(x0));
3548   END();
3549 
3550   RUN();
3551 
3552   ASSERT_EQUAL_NZCV(ZCFlag);
3553 
3554   START();
3555   __ Mov(w0, 0);
3556   __ Cmp(w0, Operand(w0));
3557   END();
3558 
3559   RUN();
3560 
3561   ASSERT_EQUAL_NZCV(ZCFlag);
3562 
3563   START();
3564   __ Mov(x0, 0);
3565   __ Mov(x1, 0x1111111111111111);
3566   __ Cmp(x0, Operand(x1));
3567   END();
3568 
3569   RUN();
3570 
3571   ASSERT_EQUAL_NZCV(NFlag);
3572 
3573   START();
3574   __ Mov(w0, 0);
3575   __ Mov(w1, 0x11111111);
3576   __ Cmp(w0, Operand(w1));
3577   END();
3578 
3579   RUN();
3580 
3581   ASSERT_EQUAL_NZCV(NFlag);
3582 
3583   START();
3584   __ Mov(x1, 0x1111111111111111);
3585   __ Cmp(x1, Operand(0));
3586   END();
3587 
3588   RUN();
3589 
3590   ASSERT_EQUAL_NZCV(CFlag);
3591 
3592   START();
3593   __ Mov(w1, 0x11111111);
3594   __ Cmp(w1, Operand(0));
3595   END();
3596 
3597   RUN();
3598 
3599   ASSERT_EQUAL_NZCV(CFlag);
3600 
3601   START();
3602   __ Mov(x0, 1);
3603   __ Mov(x1, 0x7fffffffffffffff);
3604   __ Cmn(x1, Operand(x0));
3605   END();
3606 
3607   RUN();
3608 
3609   ASSERT_EQUAL_NZCV(NVFlag);
3610 
3611   START();
3612   __ Mov(w0, 1);
3613   __ Mov(w1, 0x7fffffff);
3614   __ Cmn(w1, Operand(w0));
3615   END();
3616 
3617   RUN();
3618 
3619   ASSERT_EQUAL_NZCV(NVFlag);
3620 
3621   START();
3622   __ Mov(x0, 1);
3623   __ Mov(x1, 0xffffffffffffffff);
3624   __ Cmn(x1, Operand(x0));
3625   END();
3626 
3627   RUN();
3628 
3629   ASSERT_EQUAL_NZCV(ZCFlag);
3630 
3631   START();
3632   __ Mov(w0, 1);
3633   __ Mov(w1, 0xffffffff);
3634   __ Cmn(w1, Operand(w0));
3635   END();
3636 
3637   RUN();
3638 
3639   ASSERT_EQUAL_NZCV(ZCFlag);
3640 
3641   START();
3642   __ Mov(w0, 0);
3643   __ Mov(w1, 1);
3644   // Clear the C flag.
3645   __ Adds(w0, w0, Operand(0));
3646   __ Ngcs(w0, Operand(w1));
3647   END();
3648 
3649   RUN();
3650 
3651   ASSERT_EQUAL_NZCV(NFlag);
3652 
3653   START();
3654   __ Mov(w0, 0);
3655   __ Mov(w1, 0);
3656   // Set the C flag.
3657   __ Cmp(w0, Operand(w0));
3658   __ Ngcs(w0, Operand(w1));
3659   END();
3660 
3661   RUN();
3662 
3663   ASSERT_EQUAL_NZCV(ZCFlag);
3664 
3665   TEARDOWN();
3666 }
3667 
3668 
TEST(cmp_shift)3669 TEST(cmp_shift) {
3670   SETUP();
3671 
3672   START();
3673   __ Mov(x18, 0xf0000000);
3674   __ Mov(x19, 0xf000000010000000);
3675   __ Mov(x20, 0xf0000000f0000000);
3676   __ Mov(x21, 0x7800000078000000);
3677   __ Mov(x22, 0x3c0000003c000000);
3678   __ Mov(x23, 0x8000000780000000);
3679   __ Mov(x24, 0x0000000f00000000);
3680   __ Mov(x25, 0x00000003c0000000);
3681   __ Mov(x26, 0x8000000780000000);
3682   __ Mov(x27, 0xc0000003);
3683 
3684   __ Cmp(w20, Operand(w21, LSL, 1));
3685   __ Mrs(x0, NZCV);
3686 
3687   __ Cmp(x20, Operand(x22, LSL, 2));
3688   __ Mrs(x1, NZCV);
3689 
3690   __ Cmp(w19, Operand(w23, LSR, 3));
3691   __ Mrs(x2, NZCV);
3692 
3693   __ Cmp(x18, Operand(x24, LSR, 4));
3694   __ Mrs(x3, NZCV);
3695 
3696   __ Cmp(w20, Operand(w25, ASR, 2));
3697   __ Mrs(x4, NZCV);
3698 
3699   __ Cmp(x20, Operand(x26, ASR, 3));
3700   __ Mrs(x5, NZCV);
3701 
3702   __ Cmp(w27, Operand(w22, ROR, 28));
3703   __ Mrs(x6, NZCV);
3704 
3705   __ Cmp(x20, Operand(x21, ROR, 31));
3706   __ Mrs(x7, NZCV);
3707   END();
3708 
3709   RUN();
3710 
3711   ASSERT_EQUAL_32(ZCFlag, w0);
3712   ASSERT_EQUAL_32(ZCFlag, w1);
3713   ASSERT_EQUAL_32(ZCFlag, w2);
3714   ASSERT_EQUAL_32(ZCFlag, w3);
3715   ASSERT_EQUAL_32(ZCFlag, w4);
3716   ASSERT_EQUAL_32(ZCFlag, w5);
3717   ASSERT_EQUAL_32(ZCFlag, w6);
3718   ASSERT_EQUAL_32(ZCFlag, w7);
3719 
3720   TEARDOWN();
3721 }
3722 
3723 
TEST(cmp_extend)3724 TEST(cmp_extend) {
3725   SETUP();
3726 
3727   START();
3728   __ Mov(w20, 0x2);
3729   __ Mov(w21, 0x1);
3730   __ Mov(x22, 0xffffffffffffffff);
3731   __ Mov(x23, 0xff);
3732   __ Mov(x24, 0xfffffffffffffffe);
3733   __ Mov(x25, 0xffff);
3734   __ Mov(x26, 0xffffffff);
3735 
3736   __ Cmp(w20, Operand(w21, LSL, 1));
3737   __ Mrs(x0, NZCV);
3738 
3739   __ Cmp(x22, Operand(x23, SXTB, 0));
3740   __ Mrs(x1, NZCV);
3741 
3742   __ Cmp(x24, Operand(x23, SXTB, 1));
3743   __ Mrs(x2, NZCV);
3744 
3745   __ Cmp(x24, Operand(x23, UXTB, 1));
3746   __ Mrs(x3, NZCV);
3747 
3748   __ Cmp(w22, Operand(w25, UXTH));
3749   __ Mrs(x4, NZCV);
3750 
3751   __ Cmp(x22, Operand(x25, SXTH));
3752   __ Mrs(x5, NZCV);
3753 
3754   __ Cmp(x22, Operand(x26, UXTW));
3755   __ Mrs(x6, NZCV);
3756 
3757   __ Cmp(x24, Operand(x26, SXTW, 1));
3758   __ Mrs(x7, NZCV);
3759   END();
3760 
3761   RUN();
3762 
3763   ASSERT_EQUAL_32(ZCFlag, w0);
3764   ASSERT_EQUAL_32(ZCFlag, w1);
3765   ASSERT_EQUAL_32(ZCFlag, w2);
3766   ASSERT_EQUAL_32(NCFlag, w3);
3767   ASSERT_EQUAL_32(NCFlag, w4);
3768   ASSERT_EQUAL_32(ZCFlag, w5);
3769   ASSERT_EQUAL_32(NCFlag, w6);
3770   ASSERT_EQUAL_32(ZCFlag, w7);
3771 
3772   TEARDOWN();
3773 }
3774 
3775 
TEST(ccmp)3776 TEST(ccmp) {
3777   SETUP();
3778 
3779   START();
3780   __ Mov(w16, 0);
3781   __ Mov(w17, 1);
3782   __ Cmp(w16, w16);
3783   __ Ccmp(w16, w17, NCFlag, eq);
3784   __ Mrs(x0, NZCV);
3785 
3786   __ Cmp(w16, w16);
3787   __ Ccmp(w16, w17, NCFlag, ne);
3788   __ Mrs(x1, NZCV);
3789 
3790   __ Cmp(x16, x16);
3791   __ Ccmn(x16, 2, NZCVFlag, eq);
3792   __ Mrs(x2, NZCV);
3793 
3794   __ Cmp(x16, x16);
3795   __ Ccmn(x16, 2, NZCVFlag, ne);
3796   __ Mrs(x3, NZCV);
3797 
3798   __ ccmp(x16, x16, NZCVFlag, al);
3799   __ Mrs(x4, NZCV);
3800 
3801   __ ccmp(x16, x16, NZCVFlag, nv);
3802   __ Mrs(x5, NZCV);
3803 
3804   END();
3805 
3806   RUN();
3807 
3808   ASSERT_EQUAL_32(NFlag, w0);
3809   ASSERT_EQUAL_32(NCFlag, w1);
3810   ASSERT_EQUAL_32(NoFlag, w2);
3811   ASSERT_EQUAL_32(NZCVFlag, w3);
3812   ASSERT_EQUAL_32(ZCFlag, w4);
3813   ASSERT_EQUAL_32(ZCFlag, w5);
3814 
3815   TEARDOWN();
3816 }
3817 
3818 
TEST(ccmp_wide_imm)3819 TEST(ccmp_wide_imm) {
3820   SETUP();
3821 
3822   START();
3823   __ Mov(w20, 0);
3824 
3825   __ Cmp(w20, Operand(w20));
3826   __ Ccmp(w20, Operand(0x12345678), NZCVFlag, eq);
3827   __ Mrs(x0, NZCV);
3828 
3829   __ Cmp(w20, Operand(w20));
3830   __ Ccmp(x20, Operand(0xffffffffffffffff), NZCVFlag, eq);
3831   __ Mrs(x1, NZCV);
3832   END();
3833 
3834   RUN();
3835 
3836   ASSERT_EQUAL_32(NFlag, w0);
3837   ASSERT_EQUAL_32(NoFlag, w1);
3838 
3839   TEARDOWN();
3840 }
3841 
3842 
TEST(ccmp_shift_extend)3843 TEST(ccmp_shift_extend) {
3844   SETUP();
3845 
3846   START();
3847   __ Mov(w20, 0x2);
3848   __ Mov(w21, 0x1);
3849   __ Mov(x22, 0xffffffffffffffff);
3850   __ Mov(x23, 0xff);
3851   __ Mov(x24, 0xfffffffffffffffe);
3852 
3853   __ Cmp(w20, Operand(w20));
3854   __ Ccmp(w20, Operand(w21, LSL, 1), NZCVFlag, eq);
3855   __ Mrs(x0, NZCV);
3856 
3857   __ Cmp(w20, Operand(w20));
3858   __ Ccmp(x22, Operand(x23, SXTB, 0), NZCVFlag, eq);
3859   __ Mrs(x1, NZCV);
3860 
3861   __ Cmp(w20, Operand(w20));
3862   __ Ccmp(x24, Operand(x23, SXTB, 1), NZCVFlag, eq);
3863   __ Mrs(x2, NZCV);
3864 
3865   __ Cmp(w20, Operand(w20));
3866   __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, eq);
3867   __ Mrs(x3, NZCV);
3868 
3869   __ Cmp(w20, Operand(w20));
3870   __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, ne);
3871   __ Mrs(x4, NZCV);
3872   END();
3873 
3874   RUN();
3875 
3876   ASSERT_EQUAL_32(ZCFlag, w0);
3877   ASSERT_EQUAL_32(ZCFlag, w1);
3878   ASSERT_EQUAL_32(ZCFlag, w2);
3879   ASSERT_EQUAL_32(NCFlag, w3);
3880   ASSERT_EQUAL_32(NZCVFlag, w4);
3881 
3882   TEARDOWN();
3883 }
3884 
3885 
TEST(csel)3886 TEST(csel) {
3887   SETUP();
3888 
3889   START();
3890   __ Mov(x16, 0);
3891   __ Mov(x24, 0x0000000f0000000f);
3892   __ Mov(x25, 0x0000001f0000001f);
3893 
3894   __ Cmp(w16, Operand(0));
3895   __ Csel(w0, w24, w25, eq);
3896   __ Csel(w1, w24, w25, ne);
3897   __ Csinc(w2, w24, w25, mi);
3898   __ Csinc(w3, w24, w25, pl);
3899 
3900   __ csel(w13, w24, w25, al);
3901   __ csel(x14, x24, x25, nv);
3902 
3903   __ Cmp(x16, Operand(1));
3904   __ Csinv(x4, x24, x25, gt);
3905   __ Csinv(x5, x24, x25, le);
3906   __ Csneg(x6, x24, x25, hs);
3907   __ Csneg(x7, x24, x25, lo);
3908 
3909   __ Cset(w8, ne);
3910   __ Csetm(w9, ne);
3911   __ Cinc(x10, x25, ne);
3912   __ Cinv(x11, x24, ne);
3913   __ Cneg(x12, x24, ne);
3914 
3915   __ csel(w15, w24, w25, al);
3916   __ csel(x17, x24, x25, nv);
3917 
3918   END();
3919 
3920   RUN();
3921 
3922   ASSERT_EQUAL_64(0x0000000f, x0);
3923   ASSERT_EQUAL_64(0x0000001f, x1);
3924   ASSERT_EQUAL_64(0x00000020, x2);
3925   ASSERT_EQUAL_64(0x0000000f, x3);
3926   ASSERT_EQUAL_64(0xffffffe0ffffffe0, x4);
3927   ASSERT_EQUAL_64(0x0000000f0000000f, x5);
3928   ASSERT_EQUAL_64(0xffffffe0ffffffe1, x6);
3929   ASSERT_EQUAL_64(0x0000000f0000000f, x7);
3930   ASSERT_EQUAL_64(0x00000001, x8);
3931   ASSERT_EQUAL_64(0xffffffff, x9);
3932   ASSERT_EQUAL_64(0x0000001f00000020, x10);
3933   ASSERT_EQUAL_64(0xfffffff0fffffff0, x11);
3934   ASSERT_EQUAL_64(0xfffffff0fffffff1, x12);
3935   ASSERT_EQUAL_64(0x0000000f, x13);
3936   ASSERT_EQUAL_64(0x0000000f0000000f, x14);
3937   ASSERT_EQUAL_64(0x0000000f, x15);
3938   ASSERT_EQUAL_64(0x0000000f0000000f, x17);
3939 
3940   TEARDOWN();
3941 }
3942 
3943 
TEST(csel_imm)3944 TEST(csel_imm) {
3945   SETUP();
3946 
3947   START();
3948   __ Mov(x18, 0);
3949   __ Mov(x19, 0x80000000);
3950   __ Mov(x20, 0x8000000000000000);
3951 
3952   __ Cmp(x18, Operand(0));
3953   __ Csel(w0, w19, -2, ne);
3954   __ Csel(w1, w19, -1, ne);
3955   __ Csel(w2, w19, 0, ne);
3956   __ Csel(w3, w19, 1, ne);
3957   __ Csel(w4, w19, 2, ne);
3958   __ Csel(w5, w19, Operand(w19, ASR, 31), ne);
3959   __ Csel(w6, w19, Operand(w19, ROR, 1), ne);
3960   __ Csel(w7, w19, 3, eq);
3961 
3962   __ Csel(x8, x20, -2, ne);
3963   __ Csel(x9, x20, -1, ne);
3964   __ Csel(x10, x20, 0, ne);
3965   __ Csel(x11, x20, 1, ne);
3966   __ Csel(x12, x20, 2, ne);
3967   __ Csel(x13, x20, Operand(x20, ASR, 63), ne);
3968   __ Csel(x14, x20, Operand(x20, ROR, 1), ne);
3969   __ Csel(x15, x20, 3, eq);
3970 
3971   END();
3972 
3973   RUN();
3974 
3975   ASSERT_EQUAL_32(-2, w0);
3976   ASSERT_EQUAL_32(-1, w1);
3977   ASSERT_EQUAL_32(0, w2);
3978   ASSERT_EQUAL_32(1, w3);
3979   ASSERT_EQUAL_32(2, w4);
3980   ASSERT_EQUAL_32(-1, w5);
3981   ASSERT_EQUAL_32(0x40000000, w6);
3982   ASSERT_EQUAL_32(0x80000000, w7);
3983 
3984   ASSERT_EQUAL_64(-2, x8);
3985   ASSERT_EQUAL_64(-1, x9);
3986   ASSERT_EQUAL_64(0, x10);
3987   ASSERT_EQUAL_64(1, x11);
3988   ASSERT_EQUAL_64(2, x12);
3989   ASSERT_EQUAL_64(-1, x13);
3990   ASSERT_EQUAL_64(0x4000000000000000, x14);
3991   ASSERT_EQUAL_64(0x8000000000000000, x15);
3992 
3993   TEARDOWN();
3994 }
3995 
3996 
TEST(lslv)3997 TEST(lslv) {
3998   SETUP();
3999 
4000   uint64_t value = 0x0123456789abcdef;
4001   int shift[] = {1, 3, 5, 9, 17, 33};
4002 
4003   START();
4004   __ Mov(x0, value);
4005   __ Mov(w1, shift[0]);
4006   __ Mov(w2, shift[1]);
4007   __ Mov(w3, shift[2]);
4008   __ Mov(w4, shift[3]);
4009   __ Mov(w5, shift[4]);
4010   __ Mov(w6, shift[5]);
4011 
4012   __ lslv(x0, x0, xzr);
4013 
4014   __ Lsl(x16, x0, x1);
4015   __ Lsl(x17, x0, x2);
4016   __ Lsl(x18, x0, x3);
4017   __ Lsl(x19, x0, x4);
4018   __ Lsl(x20, x0, x5);
4019   __ Lsl(x21, x0, x6);
4020 
4021   __ Lsl(w22, w0, w1);
4022   __ Lsl(w23, w0, w2);
4023   __ Lsl(w24, w0, w3);
4024   __ Lsl(w25, w0, w4);
4025   __ Lsl(w26, w0, w5);
4026   __ Lsl(w27, w0, w6);
4027   END();
4028 
4029   RUN();
4030 
4031   ASSERT_EQUAL_64(value, x0);
4032   ASSERT_EQUAL_64(value << (shift[0] & 63), x16);
4033   ASSERT_EQUAL_64(value << (shift[1] & 63), x17);
4034   ASSERT_EQUAL_64(value << (shift[2] & 63), x18);
4035   ASSERT_EQUAL_64(value << (shift[3] & 63), x19);
4036   ASSERT_EQUAL_64(value << (shift[4] & 63), x20);
4037   ASSERT_EQUAL_64(value << (shift[5] & 63), x21);
4038   ASSERT_EQUAL_32(value << (shift[0] & 31), w22);
4039   ASSERT_EQUAL_32(value << (shift[1] & 31), w23);
4040   ASSERT_EQUAL_32(value << (shift[2] & 31), w24);
4041   ASSERT_EQUAL_32(value << (shift[3] & 31), w25);
4042   ASSERT_EQUAL_32(value << (shift[4] & 31), w26);
4043   ASSERT_EQUAL_32(value << (shift[5] & 31), w27);
4044 
4045   TEARDOWN();
4046 }
4047 
4048 
TEST(lsrv)4049 TEST(lsrv) {
4050   SETUP();
4051 
4052   uint64_t value = 0x0123456789abcdef;
4053   int shift[] = {1, 3, 5, 9, 17, 33};
4054 
4055   START();
4056   __ Mov(x0, value);
4057   __ Mov(w1, shift[0]);
4058   __ Mov(w2, shift[1]);
4059   __ Mov(w3, shift[2]);
4060   __ Mov(w4, shift[3]);
4061   __ Mov(w5, shift[4]);
4062   __ Mov(w6, shift[5]);
4063 
4064   __ lsrv(x0, x0, xzr);
4065 
4066   __ Lsr(x16, x0, x1);
4067   __ Lsr(x17, x0, x2);
4068   __ Lsr(x18, x0, x3);
4069   __ Lsr(x19, x0, x4);
4070   __ Lsr(x20, x0, x5);
4071   __ Lsr(x21, x0, x6);
4072 
4073   __ Lsr(w22, w0, w1);
4074   __ Lsr(w23, w0, w2);
4075   __ Lsr(w24, w0, w3);
4076   __ Lsr(w25, w0, w4);
4077   __ Lsr(w26, w0, w5);
4078   __ Lsr(w27, w0, w6);
4079   END();
4080 
4081   RUN();
4082 
4083   ASSERT_EQUAL_64(value, x0);
4084   ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
4085   ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
4086   ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
4087   ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
4088   ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
4089   ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
4090 
4091   value &= 0xffffffff;
4092   ASSERT_EQUAL_32(value >> (shift[0] & 31), w22);
4093   ASSERT_EQUAL_32(value >> (shift[1] & 31), w23);
4094   ASSERT_EQUAL_32(value >> (shift[2] & 31), w24);
4095   ASSERT_EQUAL_32(value >> (shift[3] & 31), w25);
4096   ASSERT_EQUAL_32(value >> (shift[4] & 31), w26);
4097   ASSERT_EQUAL_32(value >> (shift[5] & 31), w27);
4098 
4099   TEARDOWN();
4100 }
4101 
4102 
TEST(asrv)4103 TEST(asrv) {
4104   SETUP();
4105 
4106   int64_t value = 0xfedcba98fedcba98;
4107   int shift[] = {1, 3, 5, 9, 17, 33};
4108 
4109   START();
4110   __ Mov(x0, value);
4111   __ Mov(w1, shift[0]);
4112   __ Mov(w2, shift[1]);
4113   __ Mov(w3, shift[2]);
4114   __ Mov(w4, shift[3]);
4115   __ Mov(w5, shift[4]);
4116   __ Mov(w6, shift[5]);
4117 
4118   __ asrv(x0, x0, xzr);
4119 
4120   __ Asr(x16, x0, x1);
4121   __ Asr(x17, x0, x2);
4122   __ Asr(x18, x0, x3);
4123   __ Asr(x19, x0, x4);
4124   __ Asr(x20, x0, x5);
4125   __ Asr(x21, x0, x6);
4126 
4127   __ Asr(w22, w0, w1);
4128   __ Asr(w23, w0, w2);
4129   __ Asr(w24, w0, w3);
4130   __ Asr(w25, w0, w4);
4131   __ Asr(w26, w0, w5);
4132   __ Asr(w27, w0, w6);
4133   END();
4134 
4135   RUN();
4136 
4137   ASSERT_EQUAL_64(value, x0);
4138   ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
4139   ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
4140   ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
4141   ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
4142   ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
4143   ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
4144 
4145   int32_t value32 = static_cast<int32_t>(value & 0xffffffff);
4146   ASSERT_EQUAL_32(value32 >> (shift[0] & 31), w22);
4147   ASSERT_EQUAL_32(value32 >> (shift[1] & 31), w23);
4148   ASSERT_EQUAL_32(value32 >> (shift[2] & 31), w24);
4149   ASSERT_EQUAL_32(value32 >> (shift[3] & 31), w25);
4150   ASSERT_EQUAL_32(value32 >> (shift[4] & 31), w26);
4151   ASSERT_EQUAL_32(value32 >> (shift[5] & 31), w27);
4152 
4153   TEARDOWN();
4154 }
4155 
4156 
TEST(rorv)4157 TEST(rorv) {
4158   SETUP();
4159 
4160   uint64_t value = 0x0123456789abcdef;
4161   int shift[] = {4, 8, 12, 16, 24, 36};
4162 
4163   START();
4164   __ Mov(x0, value);
4165   __ Mov(w1, shift[0]);
4166   __ Mov(w2, shift[1]);
4167   __ Mov(w3, shift[2]);
4168   __ Mov(w4, shift[3]);
4169   __ Mov(w5, shift[4]);
4170   __ Mov(w6, shift[5]);
4171 
4172   __ rorv(x0, x0, xzr);
4173 
4174   __ Ror(x16, x0, x1);
4175   __ Ror(x17, x0, x2);
4176   __ Ror(x18, x0, x3);
4177   __ Ror(x19, x0, x4);
4178   __ Ror(x20, x0, x5);
4179   __ Ror(x21, x0, x6);
4180 
4181   __ Ror(w22, w0, w1);
4182   __ Ror(w23, w0, w2);
4183   __ Ror(w24, w0, w3);
4184   __ Ror(w25, w0, w4);
4185   __ Ror(w26, w0, w5);
4186   __ Ror(w27, w0, w6);
4187   END();
4188 
4189   RUN();
4190 
4191   ASSERT_EQUAL_64(value, x0);
4192   ASSERT_EQUAL_64(0xf0123456789abcde, x16);
4193   ASSERT_EQUAL_64(0xef0123456789abcd, x17);
4194   ASSERT_EQUAL_64(0xdef0123456789abc, x18);
4195   ASSERT_EQUAL_64(0xcdef0123456789ab, x19);
4196   ASSERT_EQUAL_64(0xabcdef0123456789, x20);
4197   ASSERT_EQUAL_64(0x789abcdef0123456, x21);
4198   ASSERT_EQUAL_32(0xf89abcde, w22);
4199   ASSERT_EQUAL_32(0xef89abcd, w23);
4200   ASSERT_EQUAL_32(0xdef89abc, w24);
4201   ASSERT_EQUAL_32(0xcdef89ab, w25);
4202   ASSERT_EQUAL_32(0xabcdef89, w26);
4203   ASSERT_EQUAL_32(0xf89abcde, w27);
4204 
4205   TEARDOWN();
4206 }
4207 
4208 
TEST(bfm)4209 TEST(bfm) {
4210   SETUP();
4211 
4212   START();
4213   __ Mov(x1, 0x0123456789abcdef);
4214 
4215   __ Mov(x10, 0x8888888888888888);
4216   __ Mov(x11, 0x8888888888888888);
4217   __ Mov(x12, 0x8888888888888888);
4218   __ Mov(x13, 0x8888888888888888);
4219   __ Mov(w20, 0x88888888);
4220   __ Mov(w21, 0x88888888);
4221 
4222   __ bfm(x10, x1, 16, 31);
4223   __ bfm(x11, x1, 32, 15);
4224 
4225   __ bfm(w20, w1, 16, 23);
4226   __ bfm(w21, w1, 24, 15);
4227 
4228   // Aliases.
4229   __ Bfi(x12, x1, 16, 8);
4230   __ Bfxil(x13, x1, 16, 8);
4231   END();
4232 
4233   RUN();
4234 
4235 
4236   ASSERT_EQUAL_64(0x88888888888889ab, x10);
4237   ASSERT_EQUAL_64(0x8888cdef88888888, x11);
4238 
4239   ASSERT_EQUAL_32(0x888888ab, w20);
4240   ASSERT_EQUAL_32(0x88cdef88, w21);
4241 
4242   ASSERT_EQUAL_64(0x8888888888ef8888, x12);
4243   ASSERT_EQUAL_64(0x88888888888888ab, x13);
4244 
4245   TEARDOWN();
4246 }
4247 
4248 
TEST(sbfm)4249 TEST(sbfm) {
4250   SETUP();
4251 
4252   START();
4253   __ Mov(x1, 0x0123456789abcdef);
4254   __ Mov(x2, 0xfedcba9876543210);
4255 
4256   __ sbfm(x10, x1, 16, 31);
4257   __ sbfm(x11, x1, 32, 15);
4258   __ sbfm(x12, x1, 32, 47);
4259   __ sbfm(x13, x1, 48, 35);
4260 
4261   __ sbfm(w14, w1, 16, 23);
4262   __ sbfm(w15, w1, 24, 15);
4263   __ sbfm(w16, w2, 16, 23);
4264   __ sbfm(w17, w2, 24, 15);
4265 
4266   // Aliases.
4267   __ Asr(x18, x1, 32);
4268   __ Asr(x19, x2, 32);
4269   __ Sbfiz(x20, x1, 8, 16);
4270   __ Sbfiz(x21, x2, 8, 16);
4271   __ Sbfx(x22, x1, 8, 16);
4272   __ Sbfx(x23, x2, 8, 16);
4273   __ Sxtb(x24, w1);
4274   __ Sxtb(x25, x2);
4275   __ Sxth(x26, w1);
4276   __ Sxth(x27, x2);
4277   __ Sxtw(x28, w1);
4278   __ Sxtw(x29, x2);
4279   END();
4280 
4281   RUN();
4282 
4283 
4284   ASSERT_EQUAL_64(0xffffffffffff89ab, x10);
4285   ASSERT_EQUAL_64(0xffffcdef00000000, x11);
4286   ASSERT_EQUAL_64(0x0000000000004567, x12);
4287   ASSERT_EQUAL_64(0x000789abcdef0000, x13);
4288 
4289   ASSERT_EQUAL_32(0xffffffab, w14);
4290   ASSERT_EQUAL_32(0xffcdef00, w15);
4291   ASSERT_EQUAL_32(0x00000054, w16);
4292   ASSERT_EQUAL_32(0x00321000, w17);
4293 
4294   ASSERT_EQUAL_64(0x0000000001234567, x18);
4295   ASSERT_EQUAL_64(0xfffffffffedcba98, x19);
4296   ASSERT_EQUAL_64(0xffffffffffcdef00, x20);
4297   ASSERT_EQUAL_64(0x0000000000321000, x21);
4298   ASSERT_EQUAL_64(0xffffffffffffabcd, x22);
4299   ASSERT_EQUAL_64(0x0000000000005432, x23);
4300   ASSERT_EQUAL_64(0xffffffffffffffef, x24);
4301   ASSERT_EQUAL_64(0x0000000000000010, x25);
4302   ASSERT_EQUAL_64(0xffffffffffffcdef, x26);
4303   ASSERT_EQUAL_64(0x0000000000003210, x27);
4304   ASSERT_EQUAL_64(0xffffffff89abcdef, x28);
4305   ASSERT_EQUAL_64(0x0000000076543210, x29);
4306 
4307   TEARDOWN();
4308 }
4309 
4310 
TEST(ubfm)4311 TEST(ubfm) {
4312   SETUP();
4313 
4314   START();
4315   __ Mov(x1, 0x0123456789abcdef);
4316   __ Mov(x2, 0xfedcba9876543210);
4317 
4318   __ Mov(x10, 0x8888888888888888);
4319   __ Mov(x11, 0x8888888888888888);
4320 
4321   __ ubfm(x10, x1, 16, 31);
4322   __ ubfm(x11, x1, 32, 15);
4323   __ ubfm(x12, x1, 32, 47);
4324   __ ubfm(x13, x1, 48, 35);
4325 
4326   __ ubfm(w25, w1, 16, 23);
4327   __ ubfm(w26, w1, 24, 15);
4328   __ ubfm(w27, w2, 16, 23);
4329   __ ubfm(w28, w2, 24, 15);
4330 
4331   // Aliases
4332   __ Lsl(x15, x1, 63);
4333   __ Lsl(x16, x1, 0);
4334   __ Lsr(x17, x1, 32);
4335   __ Ubfiz(x18, x1, 8, 16);
4336   __ Ubfx(x19, x1, 8, 16);
4337   __ Uxtb(x20, x1);
4338   __ Uxth(x21, x1);
4339   __ Uxtw(x22, x1);
4340   END();
4341 
4342   RUN();
4343 
4344   ASSERT_EQUAL_64(0x00000000000089ab, x10);
4345   ASSERT_EQUAL_64(0x0000cdef00000000, x11);
4346   ASSERT_EQUAL_64(0x0000000000004567, x12);
4347   ASSERT_EQUAL_64(0x000789abcdef0000, x13);
4348 
4349   ASSERT_EQUAL_32(0x000000ab, w25);
4350   ASSERT_EQUAL_32(0x00cdef00, w26);
4351   ASSERT_EQUAL_32(0x00000054, w27);
4352   ASSERT_EQUAL_32(0x00321000, w28);
4353 
4354   ASSERT_EQUAL_64(0x8000000000000000, x15);
4355   ASSERT_EQUAL_64(0x0123456789abcdef, x16);
4356   ASSERT_EQUAL_64(0x0000000001234567, x17);
4357   ASSERT_EQUAL_64(0x0000000000cdef00, x18);
4358   ASSERT_EQUAL_64(0x000000000000abcd, x19);
4359   ASSERT_EQUAL_64(0x00000000000000ef, x20);
4360   ASSERT_EQUAL_64(0x000000000000cdef, x21);
4361   ASSERT_EQUAL_64(0x0000000089abcdef, x22);
4362 
4363   TEARDOWN();
4364 }
4365 
4366 
TEST(extr)4367 TEST(extr) {
4368   SETUP();
4369 
4370   START();
4371   __ Mov(x1, 0x0123456789abcdef);
4372   __ Mov(x2, 0xfedcba9876543210);
4373 
4374   __ Extr(w10, w1, w2, 0);
4375   __ Extr(w11, w1, w2, 1);
4376   __ Extr(x12, x2, x1, 2);
4377 
4378   __ Ror(w13, w1, 0);
4379   __ Ror(w14, w2, 17);
4380   __ Ror(w15, w1, 31);
4381   __ Ror(x18, x2, 1);
4382   __ Ror(x19, x1, 63);
4383   END();
4384 
4385   RUN();
4386 
4387   ASSERT_EQUAL_64(0x76543210, x10);
4388   ASSERT_EQUAL_64(0xbb2a1908, x11);
4389   ASSERT_EQUAL_64(0x0048d159e26af37b, x12);
4390   ASSERT_EQUAL_64(0x89abcdef, x13);
4391   ASSERT_EQUAL_64(0x19083b2a, x14);
4392   ASSERT_EQUAL_64(0x13579bdf, x15);
4393   ASSERT_EQUAL_64(0x7f6e5d4c3b2a1908, x18);
4394   ASSERT_EQUAL_64(0x02468acf13579bde, x19);
4395 
4396   TEARDOWN();
4397 }
4398 
4399 
TEST(fmov_imm)4400 TEST(fmov_imm) {
4401   SETUP();
4402 
4403   START();
4404   __ Fmov(s11, 1.0);
4405   __ Fmov(d22, -13.0);
4406   __ Fmov(s1, 255.0);
4407   __ Fmov(d2, 12.34567);
4408   __ Fmov(s3, 0.0);
4409   __ Fmov(d4, 0.0);
4410   __ Fmov(s5, kFP32PositiveInfinity);
4411   __ Fmov(d6, kFP64NegativeInfinity);
4412   END();
4413 
4414   RUN();
4415 
4416   ASSERT_EQUAL_FP32(1.0, s11);
4417   ASSERT_EQUAL_FP64(-13.0, d22);
4418   ASSERT_EQUAL_FP32(255.0, s1);
4419   ASSERT_EQUAL_FP64(12.34567, d2);
4420   ASSERT_EQUAL_FP32(0.0, s3);
4421   ASSERT_EQUAL_FP64(0.0, d4);
4422   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
4423   ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d6);
4424 
4425   TEARDOWN();
4426 }
4427 
4428 
TEST(fmov_reg)4429 TEST(fmov_reg) {
4430   SETUP();
4431 
4432   START();
4433   __ Fmov(s20, 1.0);
4434   __ Fmov(w10, s20);
4435   __ Fmov(s30, w10);
4436   __ Fmov(s5, s20);
4437   __ Fmov(d1, -13.0);
4438   __ Fmov(x1, d1);
4439   __ Fmov(d2, x1);
4440   __ Fmov(d4, d1);
4441   __ Fmov(d6, rawbits_to_double(0x0123456789abcdef));
4442   __ Fmov(s6, s6);
4443   END();
4444 
4445   RUN();
4446 
4447   ASSERT_EQUAL_32(float_to_rawbits(1.0), w10);
4448   ASSERT_EQUAL_FP32(1.0, s30);
4449   ASSERT_EQUAL_FP32(1.0, s5);
4450   ASSERT_EQUAL_64(double_to_rawbits(-13.0), x1);
4451   ASSERT_EQUAL_FP64(-13.0, d2);
4452   ASSERT_EQUAL_FP64(-13.0, d4);
4453   ASSERT_EQUAL_FP32(rawbits_to_float(0x89abcdef), s6);
4454 
4455   TEARDOWN();
4456 }
4457 
4458 
TEST(fadd)4459 TEST(fadd) {
4460   SETUP();
4461 
4462   START();
4463   __ Fmov(s14, -0.0f);
4464   __ Fmov(s15, kFP32PositiveInfinity);
4465   __ Fmov(s16, kFP32NegativeInfinity);
4466   __ Fmov(s17, 3.25f);
4467   __ Fmov(s18, 1.0f);
4468   __ Fmov(s19, 0.0f);
4469 
4470   __ Fmov(d26, -0.0);
4471   __ Fmov(d27, kFP64PositiveInfinity);
4472   __ Fmov(d28, kFP64NegativeInfinity);
4473   __ Fmov(d29, 0.0);
4474   __ Fmov(d30, -2.0);
4475   __ Fmov(d31, 2.25);
4476 
4477   __ Fadd(s0, s17, s18);
4478   __ Fadd(s1, s18, s19);
4479   __ Fadd(s2, s14, s18);
4480   __ Fadd(s3, s15, s18);
4481   __ Fadd(s4, s16, s18);
4482   __ Fadd(s5, s15, s16);
4483   __ Fadd(s6, s16, s15);
4484 
4485   __ Fadd(d7, d30, d31);
4486   __ Fadd(d8, d29, d31);
4487   __ Fadd(d9, d26, d31);
4488   __ Fadd(d10, d27, d31);
4489   __ Fadd(d11, d28, d31);
4490   __ Fadd(d12, d27, d28);
4491   __ Fadd(d13, d28, d27);
4492   END();
4493 
4494   RUN();
4495 
4496   ASSERT_EQUAL_FP32(4.25, s0);
4497   ASSERT_EQUAL_FP32(1.0, s1);
4498   ASSERT_EQUAL_FP32(1.0, s2);
4499   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
4500   ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
4501   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
4502   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
4503   ASSERT_EQUAL_FP64(0.25, d7);
4504   ASSERT_EQUAL_FP64(2.25, d8);
4505   ASSERT_EQUAL_FP64(2.25, d9);
4506   ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d10);
4507   ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d11);
4508   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
4509   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
4510 
4511   TEARDOWN();
4512 }
4513 
4514 
TEST(fsub)4515 TEST(fsub) {
4516   SETUP();
4517 
4518   START();
4519   __ Fmov(s14, -0.0f);
4520   __ Fmov(s15, kFP32PositiveInfinity);
4521   __ Fmov(s16, kFP32NegativeInfinity);
4522   __ Fmov(s17, 3.25f);
4523   __ Fmov(s18, 1.0f);
4524   __ Fmov(s19, 0.0f);
4525 
4526   __ Fmov(d26, -0.0);
4527   __ Fmov(d27, kFP64PositiveInfinity);
4528   __ Fmov(d28, kFP64NegativeInfinity);
4529   __ Fmov(d29, 0.0);
4530   __ Fmov(d30, -2.0);
4531   __ Fmov(d31, 2.25);
4532 
4533   __ Fsub(s0, s17, s18);
4534   __ Fsub(s1, s18, s19);
4535   __ Fsub(s2, s14, s18);
4536   __ Fsub(s3, s18, s15);
4537   __ Fsub(s4, s18, s16);
4538   __ Fsub(s5, s15, s15);
4539   __ Fsub(s6, s16, s16);
4540 
4541   __ Fsub(d7, d30, d31);
4542   __ Fsub(d8, d29, d31);
4543   __ Fsub(d9, d26, d31);
4544   __ Fsub(d10, d31, d27);
4545   __ Fsub(d11, d31, d28);
4546   __ Fsub(d12, d27, d27);
4547   __ Fsub(d13, d28, d28);
4548   END();
4549 
4550   RUN();
4551 
4552   ASSERT_EQUAL_FP32(2.25, s0);
4553   ASSERT_EQUAL_FP32(1.0, s1);
4554   ASSERT_EQUAL_FP32(-1.0, s2);
4555   ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
4556   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
4557   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
4558   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
4559   ASSERT_EQUAL_FP64(-4.25, d7);
4560   ASSERT_EQUAL_FP64(-2.25, d8);
4561   ASSERT_EQUAL_FP64(-2.25, d9);
4562   ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
4563   ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
4564   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
4565   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
4566 
4567   TEARDOWN();
4568 }
4569 
4570 
TEST(fmul)4571 TEST(fmul) {
4572   SETUP();
4573 
4574   START();
4575   __ Fmov(s14, -0.0f);
4576   __ Fmov(s15, kFP32PositiveInfinity);
4577   __ Fmov(s16, kFP32NegativeInfinity);
4578   __ Fmov(s17, 3.25f);
4579   __ Fmov(s18, 2.0f);
4580   __ Fmov(s19, 0.0f);
4581   __ Fmov(s20, -2.0f);
4582 
4583   __ Fmov(d26, -0.0);
4584   __ Fmov(d27, kFP64PositiveInfinity);
4585   __ Fmov(d28, kFP64NegativeInfinity);
4586   __ Fmov(d29, 0.0);
4587   __ Fmov(d30, -2.0);
4588   __ Fmov(d31, 2.25);
4589 
4590   __ Fmul(s0, s17, s18);
4591   __ Fmul(s1, s18, s19);
4592   __ Fmul(s2, s14, s14);
4593   __ Fmul(s3, s15, s20);
4594   __ Fmul(s4, s16, s20);
4595   __ Fmul(s5, s15, s19);
4596   __ Fmul(s6, s19, s16);
4597 
4598   __ Fmul(d7, d30, d31);
4599   __ Fmul(d8, d29, d31);
4600   __ Fmul(d9, d26, d26);
4601   __ Fmul(d10, d27, d30);
4602   __ Fmul(d11, d28, d30);
4603   __ Fmul(d12, d27, d29);
4604   __ Fmul(d13, d29, d28);
4605   END();
4606 
4607   RUN();
4608 
4609   ASSERT_EQUAL_FP32(6.5, s0);
4610   ASSERT_EQUAL_FP32(0.0, s1);
4611   ASSERT_EQUAL_FP32(0.0, s2);
4612   ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
4613   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
4614   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
4615   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
4616   ASSERT_EQUAL_FP64(-4.5, d7);
4617   ASSERT_EQUAL_FP64(0.0, d8);
4618   ASSERT_EQUAL_FP64(0.0, d9);
4619   ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
4620   ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
4621   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
4622   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
4623 
4624   TEARDOWN();
4625 }
4626 
4627 
FmaddFmsubHelper(double n,double m,double a,double fmadd,double fmsub,double fnmadd,double fnmsub)4628 static void FmaddFmsubHelper(double n, double m, double a,
4629                              double fmadd, double fmsub,
4630                              double fnmadd, double fnmsub) {
4631   SETUP();
4632   START();
4633 
4634   __ Fmov(d0, n);
4635   __ Fmov(d1, m);
4636   __ Fmov(d2, a);
4637   __ Fmadd(d28, d0, d1, d2);
4638   __ Fmsub(d29, d0, d1, d2);
4639   __ Fnmadd(d30, d0, d1, d2);
4640   __ Fnmsub(d31, d0, d1, d2);
4641 
4642   END();
4643   RUN();
4644 
4645   ASSERT_EQUAL_FP64(fmadd, d28);
4646   ASSERT_EQUAL_FP64(fmsub, d29);
4647   ASSERT_EQUAL_FP64(fnmadd, d30);
4648   ASSERT_EQUAL_FP64(fnmsub, d31);
4649 
4650   TEARDOWN();
4651 }
4652 
4653 
TEST(fmadd_fmsub_double)4654 TEST(fmadd_fmsub_double) {
4655   // It's hard to check the result of fused operations because the only way to
4656   // calculate the result is using fma, which is what the simulator uses anyway.
4657   // TODO(jbramley): Add tests to check behaviour against a hardware trace.
4658 
4659   // Basic operation.
4660   FmaddFmsubHelper(1.0, 2.0, 3.0, 5.0, 1.0, -5.0, -1.0);
4661   FmaddFmsubHelper(-1.0, 2.0, 3.0, 1.0, 5.0, -1.0, -5.0);
4662 
4663   // Check the sign of exact zeroes.
4664   //               n     m     a     fmadd  fmsub  fnmadd fnmsub
4665   FmaddFmsubHelper(-0.0, +0.0, -0.0, -0.0,  +0.0,  +0.0,  +0.0);
4666   FmaddFmsubHelper(+0.0, +0.0, -0.0, +0.0,  -0.0,  +0.0,  +0.0);
4667   FmaddFmsubHelper(+0.0, +0.0, +0.0, +0.0,  +0.0,  -0.0,  +0.0);
4668   FmaddFmsubHelper(-0.0, +0.0, +0.0, +0.0,  +0.0,  +0.0,  -0.0);
4669   FmaddFmsubHelper(+0.0, -0.0, -0.0, -0.0,  +0.0,  +0.0,  +0.0);
4670   FmaddFmsubHelper(-0.0, -0.0, -0.0, +0.0,  -0.0,  +0.0,  +0.0);
4671   FmaddFmsubHelper(-0.0, -0.0, +0.0, +0.0,  +0.0,  -0.0,  +0.0);
4672   FmaddFmsubHelper(+0.0, -0.0, +0.0, +0.0,  +0.0,  +0.0,  -0.0);
4673 
4674   // Check NaN generation.
4675   FmaddFmsubHelper(kFP64PositiveInfinity, 0.0, 42.0,
4676                    kFP64DefaultNaN, kFP64DefaultNaN,
4677                    kFP64DefaultNaN, kFP64DefaultNaN);
4678   FmaddFmsubHelper(0.0, kFP64PositiveInfinity, 42.0,
4679                    kFP64DefaultNaN, kFP64DefaultNaN,
4680                    kFP64DefaultNaN, kFP64DefaultNaN);
4681   FmaddFmsubHelper(kFP64PositiveInfinity, 1.0, kFP64PositiveInfinity,
4682                    kFP64PositiveInfinity,   //  inf + ( inf * 1) = inf
4683                    kFP64DefaultNaN,         //  inf + (-inf * 1) = NaN
4684                    kFP64NegativeInfinity,   // -inf + (-inf * 1) = -inf
4685                    kFP64DefaultNaN);        // -inf + ( inf * 1) = NaN
4686   FmaddFmsubHelper(kFP64NegativeInfinity, 1.0, kFP64PositiveInfinity,
4687                    kFP64DefaultNaN,         //  inf + (-inf * 1) = NaN
4688                    kFP64PositiveInfinity,   //  inf + ( inf * 1) = inf
4689                    kFP64DefaultNaN,         // -inf + ( inf * 1) = NaN
4690                    kFP64NegativeInfinity);  // -inf + (-inf * 1) = -inf
4691 }
4692 
4693 
FmaddFmsubHelper(float n,float m,float a,float fmadd,float fmsub,float fnmadd,float fnmsub)4694 static void FmaddFmsubHelper(float n, float m, float a,
4695                              float fmadd, float fmsub,
4696                              float fnmadd, float fnmsub) {
4697   SETUP();
4698   START();
4699 
4700   __ Fmov(s0, n);
4701   __ Fmov(s1, m);
4702   __ Fmov(s2, a);
4703   __ Fmadd(s28, s0, s1, s2);
4704   __ Fmsub(s29, s0, s1, s2);
4705   __ Fnmadd(s30, s0, s1, s2);
4706   __ Fnmsub(s31, s0, s1, s2);
4707 
4708   END();
4709   RUN();
4710 
4711   ASSERT_EQUAL_FP32(fmadd, s28);
4712   ASSERT_EQUAL_FP32(fmsub, s29);
4713   ASSERT_EQUAL_FP32(fnmadd, s30);
4714   ASSERT_EQUAL_FP32(fnmsub, s31);
4715 
4716   TEARDOWN();
4717 }
4718 
4719 
TEST(fmadd_fmsub_float)4720 TEST(fmadd_fmsub_float) {
4721   // It's hard to check the result of fused operations because the only way to
4722   // calculate the result is using fma, which is what the simulator uses anyway.
4723   // TODO(jbramley): Add tests to check behaviour against a hardware trace.
4724 
4725   // Basic operation.
4726   FmaddFmsubHelper(1.0f, 2.0f, 3.0f, 5.0f, 1.0f, -5.0f, -1.0f);
4727   FmaddFmsubHelper(-1.0f, 2.0f, 3.0f, 1.0f, 5.0f, -1.0f, -5.0f);
4728 
4729   // Check the sign of exact zeroes.
4730   //               n      m      a      fmadd  fmsub  fnmadd fnmsub
4731   FmaddFmsubHelper(-0.0f, +0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
4732   FmaddFmsubHelper(+0.0f, +0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
4733   FmaddFmsubHelper(+0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
4734   FmaddFmsubHelper(-0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
4735   FmaddFmsubHelper(+0.0f, -0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
4736   FmaddFmsubHelper(-0.0f, -0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
4737   FmaddFmsubHelper(-0.0f, -0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
4738   FmaddFmsubHelper(+0.0f, -0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
4739 
4740   // Check NaN generation.
4741   FmaddFmsubHelper(kFP32PositiveInfinity, 0.0f, 42.0f,
4742                    kFP32DefaultNaN, kFP32DefaultNaN,
4743                    kFP32DefaultNaN, kFP32DefaultNaN);
4744   FmaddFmsubHelper(0.0f, kFP32PositiveInfinity, 42.0f,
4745                    kFP32DefaultNaN, kFP32DefaultNaN,
4746                    kFP32DefaultNaN, kFP32DefaultNaN);
4747   FmaddFmsubHelper(kFP32PositiveInfinity, 1.0f, kFP32PositiveInfinity,
4748                    kFP32PositiveInfinity,   //  inf + ( inf * 1) = inf
4749                    kFP32DefaultNaN,         //  inf + (-inf * 1) = NaN
4750                    kFP32NegativeInfinity,   // -inf + (-inf * 1) = -inf
4751                    kFP32DefaultNaN);        // -inf + ( inf * 1) = NaN
4752   FmaddFmsubHelper(kFP32NegativeInfinity, 1.0f, kFP32PositiveInfinity,
4753                    kFP32DefaultNaN,         //  inf + (-inf * 1) = NaN
4754                    kFP32PositiveInfinity,   //  inf + ( inf * 1) = inf
4755                    kFP32DefaultNaN,         // -inf + ( inf * 1) = NaN
4756                    kFP32NegativeInfinity);  // -inf + (-inf * 1) = -inf
4757 }
4758 
4759 
TEST(fmadd_fmsub_double_nans)4760 TEST(fmadd_fmsub_double_nans) {
4761   // Make sure that NaN propagation works correctly.
4762   double s1 = rawbits_to_double(0x7ff5555511111111);
4763   double s2 = rawbits_to_double(0x7ff5555522222222);
4764   double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
4765   double q1 = rawbits_to_double(0x7ffaaaaa11111111);
4766   double q2 = rawbits_to_double(0x7ffaaaaa22222222);
4767   double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
4768   VIXL_ASSERT(IsSignallingNaN(s1));
4769   VIXL_ASSERT(IsSignallingNaN(s2));
4770   VIXL_ASSERT(IsSignallingNaN(sa));
4771   VIXL_ASSERT(IsQuietNaN(q1));
4772   VIXL_ASSERT(IsQuietNaN(q2));
4773   VIXL_ASSERT(IsQuietNaN(qa));
4774 
4775   // The input NaNs after passing through ProcessNaN.
4776   double s1_proc = rawbits_to_double(0x7ffd555511111111);
4777   double s2_proc = rawbits_to_double(0x7ffd555522222222);
4778   double sa_proc = rawbits_to_double(0x7ffd5555aaaaaaaa);
4779   double q1_proc = q1;
4780   double q2_proc = q2;
4781   double qa_proc = qa;
4782   VIXL_ASSERT(IsQuietNaN(s1_proc));
4783   VIXL_ASSERT(IsQuietNaN(s2_proc));
4784   VIXL_ASSERT(IsQuietNaN(sa_proc));
4785   VIXL_ASSERT(IsQuietNaN(q1_proc));
4786   VIXL_ASSERT(IsQuietNaN(q2_proc));
4787   VIXL_ASSERT(IsQuietNaN(qa_proc));
4788 
4789   // Negated NaNs as it would be done on ARMv8 hardware.
4790   double s1_proc_neg = rawbits_to_double(0xfffd555511111111);
4791   double sa_proc_neg = rawbits_to_double(0xfffd5555aaaaaaaa);
4792   double q1_proc_neg = rawbits_to_double(0xfffaaaaa11111111);
4793   double qa_proc_neg = rawbits_to_double(0xfffaaaaaaaaaaaaa);
4794   VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
4795   VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
4796   VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
4797   VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
4798 
4799   // Quiet NaNs are propagated.
4800   FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
4801   FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
4802   FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4803   FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
4804   FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4805   FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4806   FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4807 
4808   // Signalling NaNs are propagated, and made quiet.
4809   FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4810   FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
4811   FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4812   FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4813   FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4814   FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4815   FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4816 
4817   // Signalling NaNs take precedence over quiet NaNs.
4818   FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4819   FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
4820   FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4821   FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4822   FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4823   FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4824   FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4825 
4826   // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
4827   FmaddFmsubHelper(0, kFP64PositiveInfinity, qa,
4828                    kFP64DefaultNaN, kFP64DefaultNaN,
4829                    kFP64DefaultNaN, kFP64DefaultNaN);
4830   FmaddFmsubHelper(kFP64PositiveInfinity, 0, qa,
4831                    kFP64DefaultNaN, kFP64DefaultNaN,
4832                    kFP64DefaultNaN, kFP64DefaultNaN);
4833   FmaddFmsubHelper(0, kFP64NegativeInfinity, qa,
4834                    kFP64DefaultNaN, kFP64DefaultNaN,
4835                    kFP64DefaultNaN, kFP64DefaultNaN);
4836   FmaddFmsubHelper(kFP64NegativeInfinity, 0, qa,
4837                    kFP64DefaultNaN, kFP64DefaultNaN,
4838                    kFP64DefaultNaN, kFP64DefaultNaN);
4839 }
4840 
4841 
TEST(fmadd_fmsub_float_nans)4842 TEST(fmadd_fmsub_float_nans) {
4843   // Make sure that NaN propagation works correctly.
4844   float s1 = rawbits_to_float(0x7f951111);
4845   float s2 = rawbits_to_float(0x7f952222);
4846   float sa = rawbits_to_float(0x7f95aaaa);
4847   float q1 = rawbits_to_float(0x7fea1111);
4848   float q2 = rawbits_to_float(0x7fea2222);
4849   float qa = rawbits_to_float(0x7feaaaaa);
4850   VIXL_ASSERT(IsSignallingNaN(s1));
4851   VIXL_ASSERT(IsSignallingNaN(s2));
4852   VIXL_ASSERT(IsSignallingNaN(sa));
4853   VIXL_ASSERT(IsQuietNaN(q1));
4854   VIXL_ASSERT(IsQuietNaN(q2));
4855   VIXL_ASSERT(IsQuietNaN(qa));
4856 
4857   // The input NaNs after passing through ProcessNaN.
4858   float s1_proc = rawbits_to_float(0x7fd51111);
4859   float s2_proc = rawbits_to_float(0x7fd52222);
4860   float sa_proc = rawbits_to_float(0x7fd5aaaa);
4861   float q1_proc = q1;
4862   float q2_proc = q2;
4863   float qa_proc = qa;
4864   VIXL_ASSERT(IsQuietNaN(s1_proc));
4865   VIXL_ASSERT(IsQuietNaN(s2_proc));
4866   VIXL_ASSERT(IsQuietNaN(sa_proc));
4867   VIXL_ASSERT(IsQuietNaN(q1_proc));
4868   VIXL_ASSERT(IsQuietNaN(q2_proc));
4869   VIXL_ASSERT(IsQuietNaN(qa_proc));
4870 
4871   // Negated NaNs as it would be done on ARMv8 hardware.
4872   float s1_proc_neg = rawbits_to_float(0xffd51111);
4873   float sa_proc_neg = rawbits_to_float(0xffd5aaaa);
4874   float q1_proc_neg = rawbits_to_float(0xffea1111);
4875   float qa_proc_neg = rawbits_to_float(0xffeaaaaa);
4876   VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
4877   VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
4878   VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
4879   VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
4880 
4881   // Quiet NaNs are propagated.
4882   FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
4883   FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
4884   FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4885   FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
4886   FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4887   FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4888   FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
4889 
4890   // Signalling NaNs are propagated, and made quiet.
4891   FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4892   FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
4893   FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4894   FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4895   FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4896   FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4897   FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4898 
4899   // Signalling NaNs take precedence over quiet NaNs.
4900   FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4901   FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
4902   FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4903   FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
4904   FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4905   FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4906   FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
4907 
4908   // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
4909   FmaddFmsubHelper(0, kFP32PositiveInfinity, qa,
4910                    kFP32DefaultNaN, kFP32DefaultNaN,
4911                    kFP32DefaultNaN, kFP32DefaultNaN);
4912   FmaddFmsubHelper(kFP32PositiveInfinity, 0, qa,
4913                    kFP32DefaultNaN, kFP32DefaultNaN,
4914                    kFP32DefaultNaN, kFP32DefaultNaN);
4915   FmaddFmsubHelper(0, kFP32NegativeInfinity, qa,
4916                    kFP32DefaultNaN, kFP32DefaultNaN,
4917                    kFP32DefaultNaN, kFP32DefaultNaN);
4918   FmaddFmsubHelper(kFP32NegativeInfinity, 0, qa,
4919                    kFP32DefaultNaN, kFP32DefaultNaN,
4920                    kFP32DefaultNaN, kFP32DefaultNaN);
4921 }
4922 
4923 
TEST(fdiv)4924 TEST(fdiv) {
4925   SETUP();
4926 
4927   START();
4928   __ Fmov(s14, -0.0f);
4929   __ Fmov(s15, kFP32PositiveInfinity);
4930   __ Fmov(s16, kFP32NegativeInfinity);
4931   __ Fmov(s17, 3.25f);
4932   __ Fmov(s18, 2.0f);
4933   __ Fmov(s19, 2.0f);
4934   __ Fmov(s20, -2.0f);
4935 
4936   __ Fmov(d26, -0.0);
4937   __ Fmov(d27, kFP64PositiveInfinity);
4938   __ Fmov(d28, kFP64NegativeInfinity);
4939   __ Fmov(d29, 0.0);
4940   __ Fmov(d30, -2.0);
4941   __ Fmov(d31, 2.25);
4942 
4943   __ Fdiv(s0, s17, s18);
4944   __ Fdiv(s1, s18, s19);
4945   __ Fdiv(s2, s14, s18);
4946   __ Fdiv(s3, s18, s15);
4947   __ Fdiv(s4, s18, s16);
4948   __ Fdiv(s5, s15, s16);
4949   __ Fdiv(s6, s14, s14);
4950 
4951   __ Fdiv(d7, d31, d30);
4952   __ Fdiv(d8, d29, d31);
4953   __ Fdiv(d9, d26, d31);
4954   __ Fdiv(d10, d31, d27);
4955   __ Fdiv(d11, d31, d28);
4956   __ Fdiv(d12, d28, d27);
4957   __ Fdiv(d13, d29, d29);
4958   END();
4959 
4960   RUN();
4961 
4962   ASSERT_EQUAL_FP32(1.625f, s0);
4963   ASSERT_EQUAL_FP32(1.0f, s1);
4964   ASSERT_EQUAL_FP32(-0.0f, s2);
4965   ASSERT_EQUAL_FP32(0.0f, s3);
4966   ASSERT_EQUAL_FP32(-0.0f, s4);
4967   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
4968   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
4969   ASSERT_EQUAL_FP64(-1.125, d7);
4970   ASSERT_EQUAL_FP64(0.0, d8);
4971   ASSERT_EQUAL_FP64(-0.0, d9);
4972   ASSERT_EQUAL_FP64(0.0, d10);
4973   ASSERT_EQUAL_FP64(-0.0, d11);
4974   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
4975   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
4976 
4977   TEARDOWN();
4978 }
4979 
4980 
MinMaxHelper(float n,float m,bool min,float quiet_nan_substitute=0.0)4981 static float MinMaxHelper(float n,
4982                           float m,
4983                           bool min,
4984                           float quiet_nan_substitute = 0.0) {
4985   const uint64_t kFP32QuietNaNMask = 0x00400000;
4986   uint32_t raw_n = float_to_rawbits(n);
4987   uint32_t raw_m = float_to_rawbits(m);
4988 
4989   if (isnan(n) && ((raw_n & kFP32QuietNaNMask) == 0)) {
4990     // n is signalling NaN.
4991     return rawbits_to_float(raw_n | kFP32QuietNaNMask);
4992   } else if (isnan(m) && ((raw_m & kFP32QuietNaNMask) == 0)) {
4993     // m is signalling NaN.
4994     return rawbits_to_float(raw_m | kFP32QuietNaNMask);
4995   } else if (quiet_nan_substitute == 0.0) {
4996     if (isnan(n)) {
4997       // n is quiet NaN.
4998       return n;
4999     } else if (isnan(m)) {
5000       // m is quiet NaN.
5001       return m;
5002     }
5003   } else {
5004     // Substitute n or m if one is quiet, but not both.
5005     if (isnan(n) && !isnan(m)) {
5006       // n is quiet NaN: replace with substitute.
5007       n = quiet_nan_substitute;
5008     } else if (!isnan(n) && isnan(m)) {
5009       // m is quiet NaN: replace with substitute.
5010       m = quiet_nan_substitute;
5011     }
5012   }
5013 
5014   if ((n == 0.0) && (m == 0.0) &&
5015       (copysign(1.0, n) != copysign(1.0, m))) {
5016     return min ? -0.0 : 0.0;
5017   }
5018 
5019   return min ? fminf(n, m) : fmaxf(n, m);
5020 }
5021 
5022 
MinMaxHelper(double n,double m,bool min,double quiet_nan_substitute=0.0)5023 static double MinMaxHelper(double n,
5024                            double m,
5025                            bool min,
5026                            double quiet_nan_substitute = 0.0) {
5027   const uint64_t kFP64QuietNaNMask = 0x0008000000000000;
5028   uint64_t raw_n = double_to_rawbits(n);
5029   uint64_t raw_m = double_to_rawbits(m);
5030 
5031   if (isnan(n) && ((raw_n & kFP64QuietNaNMask) == 0)) {
5032     // n is signalling NaN.
5033     return rawbits_to_double(raw_n | kFP64QuietNaNMask);
5034   } else if (isnan(m) && ((raw_m & kFP64QuietNaNMask) == 0)) {
5035     // m is signalling NaN.
5036     return rawbits_to_double(raw_m | kFP64QuietNaNMask);
5037   } else if (quiet_nan_substitute == 0.0) {
5038     if (isnan(n)) {
5039       // n is quiet NaN.
5040       return n;
5041     } else if (isnan(m)) {
5042       // m is quiet NaN.
5043       return m;
5044     }
5045   } else {
5046     // Substitute n or m if one is quiet, but not both.
5047     if (isnan(n) && !isnan(m)) {
5048       // n is quiet NaN: replace with substitute.
5049       n = quiet_nan_substitute;
5050     } else if (!isnan(n) && isnan(m)) {
5051       // m is quiet NaN: replace with substitute.
5052       m = quiet_nan_substitute;
5053     }
5054   }
5055 
5056   if ((n == 0.0) && (m == 0.0) &&
5057       (copysign(1.0, n) != copysign(1.0, m))) {
5058     return min ? -0.0 : 0.0;
5059   }
5060 
5061   return min ? fmin(n, m) : fmax(n, m);
5062 }
5063 
5064 
FminFmaxDoubleHelper(double n,double m,double min,double max,double minnm,double maxnm)5065 static void FminFmaxDoubleHelper(double n, double m, double min, double max,
5066                                  double minnm, double maxnm) {
5067   SETUP();
5068 
5069   START();
5070   __ Fmov(d0, n);
5071   __ Fmov(d1, m);
5072   __ Fmin(d28, d0, d1);
5073   __ Fmax(d29, d0, d1);
5074   __ Fminnm(d30, d0, d1);
5075   __ Fmaxnm(d31, d0, d1);
5076   END();
5077 
5078   RUN();
5079 
5080   ASSERT_EQUAL_FP64(min, d28);
5081   ASSERT_EQUAL_FP64(max, d29);
5082   ASSERT_EQUAL_FP64(minnm, d30);
5083   ASSERT_EQUAL_FP64(maxnm, d31);
5084 
5085   TEARDOWN();
5086 }
5087 
5088 
TEST(fmax_fmin_d)5089 TEST(fmax_fmin_d) {
5090   // Use non-standard NaNs to check that the payload bits are preserved.
5091   double snan = rawbits_to_double(0x7ff5555512345678);
5092   double qnan = rawbits_to_double(0x7ffaaaaa87654321);
5093 
5094   double snan_processed = rawbits_to_double(0x7ffd555512345678);
5095   double qnan_processed = qnan;
5096 
5097   VIXL_ASSERT(IsSignallingNaN(snan));
5098   VIXL_ASSERT(IsQuietNaN(qnan));
5099   VIXL_ASSERT(IsQuietNaN(snan_processed));
5100   VIXL_ASSERT(IsQuietNaN(qnan_processed));
5101 
5102   // Bootstrap tests.
5103   FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0);
5104   FminFmaxDoubleHelper(0, 1, 0, 1, 0, 1);
5105   FminFmaxDoubleHelper(kFP64PositiveInfinity, kFP64NegativeInfinity,
5106                        kFP64NegativeInfinity, kFP64PositiveInfinity,
5107                        kFP64NegativeInfinity, kFP64PositiveInfinity);
5108   FminFmaxDoubleHelper(snan, 0,
5109                        snan_processed, snan_processed,
5110                        snan_processed, snan_processed);
5111   FminFmaxDoubleHelper(0, snan,
5112                        snan_processed, snan_processed,
5113                        snan_processed, snan_processed);
5114   FminFmaxDoubleHelper(qnan, 0,
5115                        qnan_processed, qnan_processed,
5116                        0, 0);
5117   FminFmaxDoubleHelper(0, qnan,
5118                        qnan_processed, qnan_processed,
5119                        0, 0);
5120   FminFmaxDoubleHelper(qnan, snan,
5121                        snan_processed, snan_processed,
5122                        snan_processed, snan_processed);
5123   FminFmaxDoubleHelper(snan, qnan,
5124                        snan_processed, snan_processed,
5125                        snan_processed, snan_processed);
5126 
5127   // Iterate over all combinations of inputs.
5128   double inputs[] = { DBL_MAX, DBL_MIN, 1.0, 0.0,
5129                       -DBL_MAX, -DBL_MIN, -1.0, -0.0,
5130                       kFP64PositiveInfinity, kFP64NegativeInfinity,
5131                       kFP64QuietNaN, kFP64SignallingNaN };
5132 
5133   const int count = sizeof(inputs) / sizeof(inputs[0]);
5134 
5135   for (int in = 0; in < count; in++) {
5136     double n = inputs[in];
5137     for (int im = 0; im < count; im++) {
5138       double m = inputs[im];
5139       FminFmaxDoubleHelper(n, m,
5140                            MinMaxHelper(n, m, true),
5141                            MinMaxHelper(n, m, false),
5142                            MinMaxHelper(n, m, true, kFP64PositiveInfinity),
5143                            MinMaxHelper(n, m, false, kFP64NegativeInfinity));
5144     }
5145   }
5146 }
5147 
5148 
FminFmaxFloatHelper(float n,float m,float min,float max,float minnm,float maxnm)5149 static void FminFmaxFloatHelper(float n, float m, float min, float max,
5150                                 float minnm, float maxnm) {
5151   SETUP();
5152 
5153   START();
5154   __ Fmov(s0, n);
5155   __ Fmov(s1, m);
5156   __ Fmin(s28, s0, s1);
5157   __ Fmax(s29, s0, s1);
5158   __ Fminnm(s30, s0, s1);
5159   __ Fmaxnm(s31, s0, s1);
5160   END();
5161 
5162   RUN();
5163 
5164   ASSERT_EQUAL_FP32(min, s28);
5165   ASSERT_EQUAL_FP32(max, s29);
5166   ASSERT_EQUAL_FP32(minnm, s30);
5167   ASSERT_EQUAL_FP32(maxnm, s31);
5168 
5169   TEARDOWN();
5170 }
5171 
5172 
TEST(fmax_fmin_s)5173 TEST(fmax_fmin_s) {
5174   // Use non-standard NaNs to check that the payload bits are preserved.
5175   float snan = rawbits_to_float(0x7f951234);
5176   float qnan = rawbits_to_float(0x7fea8765);
5177 
5178   float snan_processed = rawbits_to_float(0x7fd51234);
5179   float qnan_processed = qnan;
5180 
5181   VIXL_ASSERT(IsSignallingNaN(snan));
5182   VIXL_ASSERT(IsQuietNaN(qnan));
5183   VIXL_ASSERT(IsQuietNaN(snan_processed));
5184   VIXL_ASSERT(IsQuietNaN(qnan_processed));
5185 
5186   // Bootstrap tests.
5187   FminFmaxFloatHelper(0, 0, 0, 0, 0, 0);
5188   FminFmaxFloatHelper(0, 1, 0, 1, 0, 1);
5189   FminFmaxFloatHelper(kFP32PositiveInfinity, kFP32NegativeInfinity,
5190                       kFP32NegativeInfinity, kFP32PositiveInfinity,
5191                       kFP32NegativeInfinity, kFP32PositiveInfinity);
5192   FminFmaxFloatHelper(snan, 0,
5193                       snan_processed, snan_processed,
5194                       snan_processed, snan_processed);
5195   FminFmaxFloatHelper(0, snan,
5196                       snan_processed, snan_processed,
5197                       snan_processed, snan_processed);
5198   FminFmaxFloatHelper(qnan, 0,
5199                       qnan_processed, qnan_processed,
5200                       0, 0);
5201   FminFmaxFloatHelper(0, qnan,
5202                       qnan_processed, qnan_processed,
5203                       0, 0);
5204   FminFmaxFloatHelper(qnan, snan,
5205                       snan_processed, snan_processed,
5206                       snan_processed, snan_processed);
5207   FminFmaxFloatHelper(snan, qnan,
5208                       snan_processed, snan_processed,
5209                       snan_processed, snan_processed);
5210 
5211   // Iterate over all combinations of inputs.
5212   float inputs[] = { FLT_MAX, FLT_MIN, 1.0, 0.0,
5213                      -FLT_MAX, -FLT_MIN, -1.0, -0.0,
5214                      kFP32PositiveInfinity, kFP32NegativeInfinity,
5215                      kFP32QuietNaN, kFP32SignallingNaN };
5216 
5217   const int count = sizeof(inputs) / sizeof(inputs[0]);
5218 
5219   for (int in = 0; in < count; in++) {
5220     float n = inputs[in];
5221     for (int im = 0; im < count; im++) {
5222       float m = inputs[im];
5223       FminFmaxFloatHelper(n, m,
5224                           MinMaxHelper(n, m, true),
5225                           MinMaxHelper(n, m, false),
5226                           MinMaxHelper(n, m, true, kFP32PositiveInfinity),
5227                           MinMaxHelper(n, m, false, kFP32NegativeInfinity));
5228     }
5229   }
5230 }
5231 
5232 
TEST(fccmp)5233 TEST(fccmp) {
5234   SETUP();
5235 
5236   START();
5237   __ Fmov(s16, 0.0);
5238   __ Fmov(s17, 0.5);
5239   __ Fmov(d18, -0.5);
5240   __ Fmov(d19, -1.0);
5241   __ Mov(x20, 0);
5242 
5243   __ Cmp(x20, 0);
5244   __ Fccmp(s16, s16, NoFlag, eq);
5245   __ Mrs(x0, NZCV);
5246 
5247   __ Cmp(x20, 0);
5248   __ Fccmp(s16, s16, VFlag, ne);
5249   __ Mrs(x1, NZCV);
5250 
5251   __ Cmp(x20, 0);
5252   __ Fccmp(s16, s17, CFlag, ge);
5253   __ Mrs(x2, NZCV);
5254 
5255   __ Cmp(x20, 0);
5256   __ Fccmp(s16, s17, CVFlag, lt);
5257   __ Mrs(x3, NZCV);
5258 
5259   __ Cmp(x20, 0);
5260   __ Fccmp(d18, d18, ZFlag, le);
5261   __ Mrs(x4, NZCV);
5262 
5263   __ Cmp(x20, 0);
5264   __ Fccmp(d18, d18, ZVFlag, gt);
5265   __ Mrs(x5, NZCV);
5266 
5267   __ Cmp(x20, 0);
5268   __ Fccmp(d18, d19, ZCVFlag, ls);
5269   __ Mrs(x6, NZCV);
5270 
5271   __ Cmp(x20, 0);
5272   __ Fccmp(d18, d19, NFlag, hi);
5273   __ Mrs(x7, NZCV);
5274 
5275   __ fccmp(s16, s16, NFlag, al);
5276   __ Mrs(x8, NZCV);
5277 
5278   __ fccmp(d18, d18, NFlag, nv);
5279   __ Mrs(x9, NZCV);
5280   END();
5281 
5282   RUN();
5283 
5284   ASSERT_EQUAL_32(ZCFlag, w0);
5285   ASSERT_EQUAL_32(VFlag, w1);
5286   ASSERT_EQUAL_32(NFlag, w2);
5287   ASSERT_EQUAL_32(CVFlag, w3);
5288   ASSERT_EQUAL_32(ZCFlag, w4);
5289   ASSERT_EQUAL_32(ZVFlag, w5);
5290   ASSERT_EQUAL_32(CFlag, w6);
5291   ASSERT_EQUAL_32(NFlag, w7);
5292   ASSERT_EQUAL_32(ZCFlag, w8);
5293   ASSERT_EQUAL_32(ZCFlag, w9);
5294 
5295   TEARDOWN();
5296 }
5297 
5298 
TEST(fcmp)5299 TEST(fcmp) {
5300   SETUP();
5301 
5302   START();
5303 
5304   // Some of these tests require a floating-point scratch register assigned to
5305   // the macro assembler, but most do not.
5306   {
5307     UseScratchRegisterScope temps(&masm);
5308     temps.ExcludeAll();
5309     temps.Include(ip0, ip1);
5310 
5311     __ Fmov(s8, 0.0);
5312     __ Fmov(s9, 0.5);
5313     __ Mov(w18, 0x7f800001);  // Single precision NaN.
5314     __ Fmov(s18, w18);
5315 
5316     __ Fcmp(s8, s8);
5317     __ Mrs(x0, NZCV);
5318     __ Fcmp(s8, s9);
5319     __ Mrs(x1, NZCV);
5320     __ Fcmp(s9, s8);
5321     __ Mrs(x2, NZCV);
5322     __ Fcmp(s8, s18);
5323     __ Mrs(x3, NZCV);
5324     __ Fcmp(s18, s18);
5325     __ Mrs(x4, NZCV);
5326     __ Fcmp(s8, 0.0);
5327     __ Mrs(x5, NZCV);
5328     temps.Include(d0);
5329     __ Fcmp(s8, 255.0);
5330     temps.Exclude(d0);
5331     __ Mrs(x6, NZCV);
5332 
5333     __ Fmov(d19, 0.0);
5334     __ Fmov(d20, 0.5);
5335     __ Mov(x21, 0x7ff0000000000001);  // Double precision NaN.
5336     __ Fmov(d21, x21);
5337 
5338     __ Fcmp(d19, d19);
5339     __ Mrs(x10, NZCV);
5340     __ Fcmp(d19, d20);
5341     __ Mrs(x11, NZCV);
5342     __ Fcmp(d20, d19);
5343     __ Mrs(x12, NZCV);
5344     __ Fcmp(d19, d21);
5345     __ Mrs(x13, NZCV);
5346     __ Fcmp(d21, d21);
5347     __ Mrs(x14, NZCV);
5348     __ Fcmp(d19, 0.0);
5349     __ Mrs(x15, NZCV);
5350     temps.Include(d0);
5351     __ Fcmp(d19, 12.3456);
5352     temps.Exclude(d0);
5353     __ Mrs(x16, NZCV);
5354   }
5355 
5356   END();
5357 
5358   RUN();
5359 
5360   ASSERT_EQUAL_32(ZCFlag, w0);
5361   ASSERT_EQUAL_32(NFlag, w1);
5362   ASSERT_EQUAL_32(CFlag, w2);
5363   ASSERT_EQUAL_32(CVFlag, w3);
5364   ASSERT_EQUAL_32(CVFlag, w4);
5365   ASSERT_EQUAL_32(ZCFlag, w5);
5366   ASSERT_EQUAL_32(NFlag, w6);
5367   ASSERT_EQUAL_32(ZCFlag, w10);
5368   ASSERT_EQUAL_32(NFlag, w11);
5369   ASSERT_EQUAL_32(CFlag, w12);
5370   ASSERT_EQUAL_32(CVFlag, w13);
5371   ASSERT_EQUAL_32(CVFlag, w14);
5372   ASSERT_EQUAL_32(ZCFlag, w15);
5373   ASSERT_EQUAL_32(NFlag, w16);
5374 
5375   TEARDOWN();
5376 }
5377 
5378 
TEST(fcsel)5379 TEST(fcsel) {
5380   SETUP();
5381 
5382   START();
5383   __ Mov(x16, 0);
5384   __ Fmov(s16, 1.0);
5385   __ Fmov(s17, 2.0);
5386   __ Fmov(d18, 3.0);
5387   __ Fmov(d19, 4.0);
5388 
5389   __ Cmp(x16, 0);
5390   __ Fcsel(s0, s16, s17, eq);
5391   __ Fcsel(s1, s16, s17, ne);
5392   __ Fcsel(d2, d18, d19, eq);
5393   __ Fcsel(d3, d18, d19, ne);
5394   __ fcsel(s4, s16, s17, al);
5395   __ fcsel(d5, d18, d19, nv);
5396   END();
5397 
5398   RUN();
5399 
5400   ASSERT_EQUAL_FP32(1.0, s0);
5401   ASSERT_EQUAL_FP32(2.0, s1);
5402   ASSERT_EQUAL_FP64(3.0, d2);
5403   ASSERT_EQUAL_FP64(4.0, d3);
5404   ASSERT_EQUAL_FP32(1.0, s4);
5405   ASSERT_EQUAL_FP64(3.0, d5);
5406 
5407   TEARDOWN();
5408 }
5409 
5410 
TEST(fneg)5411 TEST(fneg) {
5412   SETUP();
5413 
5414   START();
5415   __ Fmov(s16, 1.0);
5416   __ Fmov(s17, 0.0);
5417   __ Fmov(s18, kFP32PositiveInfinity);
5418   __ Fmov(d19, 1.0);
5419   __ Fmov(d20, 0.0);
5420   __ Fmov(d21, kFP64PositiveInfinity);
5421 
5422   __ Fneg(s0, s16);
5423   __ Fneg(s1, s0);
5424   __ Fneg(s2, s17);
5425   __ Fneg(s3, s2);
5426   __ Fneg(s4, s18);
5427   __ Fneg(s5, s4);
5428   __ Fneg(d6, d19);
5429   __ Fneg(d7, d6);
5430   __ Fneg(d8, d20);
5431   __ Fneg(d9, d8);
5432   __ Fneg(d10, d21);
5433   __ Fneg(d11, d10);
5434   END();
5435 
5436   RUN();
5437 
5438   ASSERT_EQUAL_FP32(-1.0, s0);
5439   ASSERT_EQUAL_FP32(1.0, s1);
5440   ASSERT_EQUAL_FP32(-0.0, s2);
5441   ASSERT_EQUAL_FP32(0.0, s3);
5442   ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
5443   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
5444   ASSERT_EQUAL_FP64(-1.0, d6);
5445   ASSERT_EQUAL_FP64(1.0, d7);
5446   ASSERT_EQUAL_FP64(-0.0, d8);
5447   ASSERT_EQUAL_FP64(0.0, d9);
5448   ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
5449   ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
5450 
5451   TEARDOWN();
5452 }
5453 
5454 
TEST(fabs)5455 TEST(fabs) {
5456   SETUP();
5457 
5458   START();
5459   __ Fmov(s16, -1.0);
5460   __ Fmov(s17, -0.0);
5461   __ Fmov(s18, kFP32NegativeInfinity);
5462   __ Fmov(d19, -1.0);
5463   __ Fmov(d20, -0.0);
5464   __ Fmov(d21, kFP64NegativeInfinity);
5465 
5466   __ Fabs(s0, s16);
5467   __ Fabs(s1, s0);
5468   __ Fabs(s2, s17);
5469   __ Fabs(s3, s18);
5470   __ Fabs(d4, d19);
5471   __ Fabs(d5, d4);
5472   __ Fabs(d6, d20);
5473   __ Fabs(d7, d21);
5474   END();
5475 
5476   RUN();
5477 
5478   ASSERT_EQUAL_FP32(1.0, s0);
5479   ASSERT_EQUAL_FP32(1.0, s1);
5480   ASSERT_EQUAL_FP32(0.0, s2);
5481   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
5482   ASSERT_EQUAL_FP64(1.0, d4);
5483   ASSERT_EQUAL_FP64(1.0, d5);
5484   ASSERT_EQUAL_FP64(0.0, d6);
5485   ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
5486 
5487   TEARDOWN();
5488 }
5489 
5490 
TEST(fsqrt)5491 TEST(fsqrt) {
5492   SETUP();
5493 
5494   START();
5495   __ Fmov(s16, 0.0);
5496   __ Fmov(s17, 1.0);
5497   __ Fmov(s18, 0.25);
5498   __ Fmov(s19, 65536.0);
5499   __ Fmov(s20, -0.0);
5500   __ Fmov(s21, kFP32PositiveInfinity);
5501   __ Fmov(s22, -1.0);
5502   __ Fmov(d23, 0.0);
5503   __ Fmov(d24, 1.0);
5504   __ Fmov(d25, 0.25);
5505   __ Fmov(d26, 4294967296.0);
5506   __ Fmov(d27, -0.0);
5507   __ Fmov(d28, kFP64PositiveInfinity);
5508   __ Fmov(d29, -1.0);
5509 
5510   __ Fsqrt(s0, s16);
5511   __ Fsqrt(s1, s17);
5512   __ Fsqrt(s2, s18);
5513   __ Fsqrt(s3, s19);
5514   __ Fsqrt(s4, s20);
5515   __ Fsqrt(s5, s21);
5516   __ Fsqrt(s6, s22);
5517   __ Fsqrt(d7, d23);
5518   __ Fsqrt(d8, d24);
5519   __ Fsqrt(d9, d25);
5520   __ Fsqrt(d10, d26);
5521   __ Fsqrt(d11, d27);
5522   __ Fsqrt(d12, d28);
5523   __ Fsqrt(d13, d29);
5524   END();
5525 
5526   RUN();
5527 
5528   ASSERT_EQUAL_FP32(0.0, s0);
5529   ASSERT_EQUAL_FP32(1.0, s1);
5530   ASSERT_EQUAL_FP32(0.5, s2);
5531   ASSERT_EQUAL_FP32(256.0, s3);
5532   ASSERT_EQUAL_FP32(-0.0, s4);
5533   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
5534   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
5535   ASSERT_EQUAL_FP64(0.0, d7);
5536   ASSERT_EQUAL_FP64(1.0, d8);
5537   ASSERT_EQUAL_FP64(0.5, d9);
5538   ASSERT_EQUAL_FP64(65536.0, d10);
5539   ASSERT_EQUAL_FP64(-0.0, d11);
5540   ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d12);
5541   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
5542 
5543   TEARDOWN();
5544 }
5545 
5546 
TEST(frinta)5547 TEST(frinta) {
5548   SETUP();
5549 
5550   START();
5551   __ Fmov(s16, 1.0);
5552   __ Fmov(s17, 1.1);
5553   __ Fmov(s18, 1.5);
5554   __ Fmov(s19, 1.9);
5555   __ Fmov(s20, 2.5);
5556   __ Fmov(s21, -1.5);
5557   __ Fmov(s22, -2.5);
5558   __ Fmov(s23, kFP32PositiveInfinity);
5559   __ Fmov(s24, kFP32NegativeInfinity);
5560   __ Fmov(s25, 0.0);
5561   __ Fmov(s26, -0.0);
5562   __ Fmov(s27, -0.2);
5563 
5564   __ Frinta(s0, s16);
5565   __ Frinta(s1, s17);
5566   __ Frinta(s2, s18);
5567   __ Frinta(s3, s19);
5568   __ Frinta(s4, s20);
5569   __ Frinta(s5, s21);
5570   __ Frinta(s6, s22);
5571   __ Frinta(s7, s23);
5572   __ Frinta(s8, s24);
5573   __ Frinta(s9, s25);
5574   __ Frinta(s10, s26);
5575   __ Frinta(s11, s27);
5576 
5577   __ Fmov(d16, 1.0);
5578   __ Fmov(d17, 1.1);
5579   __ Fmov(d18, 1.5);
5580   __ Fmov(d19, 1.9);
5581   __ Fmov(d20, 2.5);
5582   __ Fmov(d21, -1.5);
5583   __ Fmov(d22, -2.5);
5584   __ Fmov(d23, kFP32PositiveInfinity);
5585   __ Fmov(d24, kFP32NegativeInfinity);
5586   __ Fmov(d25, 0.0);
5587   __ Fmov(d26, -0.0);
5588   __ Fmov(d27, -0.2);
5589 
5590   __ Frinta(d12, d16);
5591   __ Frinta(d13, d17);
5592   __ Frinta(d14, d18);
5593   __ Frinta(d15, d19);
5594   __ Frinta(d16, d20);
5595   __ Frinta(d17, d21);
5596   __ Frinta(d18, d22);
5597   __ Frinta(d19, d23);
5598   __ Frinta(d20, d24);
5599   __ Frinta(d21, d25);
5600   __ Frinta(d22, d26);
5601   __ Frinta(d23, d27);
5602   END();
5603 
5604   RUN();
5605 
5606   ASSERT_EQUAL_FP32(1.0, s0);
5607   ASSERT_EQUAL_FP32(1.0, s1);
5608   ASSERT_EQUAL_FP32(2.0, s2);
5609   ASSERT_EQUAL_FP32(2.0, s3);
5610   ASSERT_EQUAL_FP32(3.0, s4);
5611   ASSERT_EQUAL_FP32(-2.0, s5);
5612   ASSERT_EQUAL_FP32(-3.0, s6);
5613   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
5614   ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
5615   ASSERT_EQUAL_FP32(0.0, s9);
5616   ASSERT_EQUAL_FP32(-0.0, s10);
5617   ASSERT_EQUAL_FP32(-0.0, s11);
5618   ASSERT_EQUAL_FP64(1.0, d12);
5619   ASSERT_EQUAL_FP64(1.0, d13);
5620   ASSERT_EQUAL_FP64(2.0, d14);
5621   ASSERT_EQUAL_FP64(2.0, d15);
5622   ASSERT_EQUAL_FP64(3.0, d16);
5623   ASSERT_EQUAL_FP64(-2.0, d17);
5624   ASSERT_EQUAL_FP64(-3.0, d18);
5625   ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
5626   ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
5627   ASSERT_EQUAL_FP64(0.0, d21);
5628   ASSERT_EQUAL_FP64(-0.0, d22);
5629   ASSERT_EQUAL_FP64(-0.0, d23);
5630 
5631   TEARDOWN();
5632 }
5633 
5634 
TEST(frintm)5635 TEST(frintm) {
5636   SETUP();
5637 
5638   START();
5639   __ Fmov(s16, 1.0);
5640   __ Fmov(s17, 1.1);
5641   __ Fmov(s18, 1.5);
5642   __ Fmov(s19, 1.9);
5643   __ Fmov(s20, 2.5);
5644   __ Fmov(s21, -1.5);
5645   __ Fmov(s22, -2.5);
5646   __ Fmov(s23, kFP32PositiveInfinity);
5647   __ Fmov(s24, kFP32NegativeInfinity);
5648   __ Fmov(s25, 0.0);
5649   __ Fmov(s26, -0.0);
5650   __ Fmov(s27, -0.2);
5651 
5652   __ Frintm(s0, s16);
5653   __ Frintm(s1, s17);
5654   __ Frintm(s2, s18);
5655   __ Frintm(s3, s19);
5656   __ Frintm(s4, s20);
5657   __ Frintm(s5, s21);
5658   __ Frintm(s6, s22);
5659   __ Frintm(s7, s23);
5660   __ Frintm(s8, s24);
5661   __ Frintm(s9, s25);
5662   __ Frintm(s10, s26);
5663   __ Frintm(s11, s27);
5664 
5665   __ Fmov(d16, 1.0);
5666   __ Fmov(d17, 1.1);
5667   __ Fmov(d18, 1.5);
5668   __ Fmov(d19, 1.9);
5669   __ Fmov(d20, 2.5);
5670   __ Fmov(d21, -1.5);
5671   __ Fmov(d22, -2.5);
5672   __ Fmov(d23, kFP32PositiveInfinity);
5673   __ Fmov(d24, kFP32NegativeInfinity);
5674   __ Fmov(d25, 0.0);
5675   __ Fmov(d26, -0.0);
5676   __ Fmov(d27, -0.2);
5677 
5678   __ Frintm(d12, d16);
5679   __ Frintm(d13, d17);
5680   __ Frintm(d14, d18);
5681   __ Frintm(d15, d19);
5682   __ Frintm(d16, d20);
5683   __ Frintm(d17, d21);
5684   __ Frintm(d18, d22);
5685   __ Frintm(d19, d23);
5686   __ Frintm(d20, d24);
5687   __ Frintm(d21, d25);
5688   __ Frintm(d22, d26);
5689   __ Frintm(d23, d27);
5690   END();
5691 
5692   RUN();
5693 
5694   ASSERT_EQUAL_FP32(1.0, s0);
5695   ASSERT_EQUAL_FP32(1.0, s1);
5696   ASSERT_EQUAL_FP32(1.0, s2);
5697   ASSERT_EQUAL_FP32(1.0, s3);
5698   ASSERT_EQUAL_FP32(2.0, s4);
5699   ASSERT_EQUAL_FP32(-2.0, s5);
5700   ASSERT_EQUAL_FP32(-3.0, s6);
5701   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
5702   ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
5703   ASSERT_EQUAL_FP32(0.0, s9);
5704   ASSERT_EQUAL_FP32(-0.0, s10);
5705   ASSERT_EQUAL_FP32(-1.0, s11);
5706   ASSERT_EQUAL_FP64(1.0, d12);
5707   ASSERT_EQUAL_FP64(1.0, d13);
5708   ASSERT_EQUAL_FP64(1.0, d14);
5709   ASSERT_EQUAL_FP64(1.0, d15);
5710   ASSERT_EQUAL_FP64(2.0, d16);
5711   ASSERT_EQUAL_FP64(-2.0, d17);
5712   ASSERT_EQUAL_FP64(-3.0, d18);
5713   ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
5714   ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
5715   ASSERT_EQUAL_FP64(0.0, d21);
5716   ASSERT_EQUAL_FP64(-0.0, d22);
5717   ASSERT_EQUAL_FP64(-1.0, d23);
5718 
5719   TEARDOWN();
5720 }
5721 
5722 
TEST(frintn)5723 TEST(frintn) {
5724   SETUP();
5725 
5726   START();
5727   __ Fmov(s16, 1.0);
5728   __ Fmov(s17, 1.1);
5729   __ Fmov(s18, 1.5);
5730   __ Fmov(s19, 1.9);
5731   __ Fmov(s20, 2.5);
5732   __ Fmov(s21, -1.5);
5733   __ Fmov(s22, -2.5);
5734   __ Fmov(s23, kFP32PositiveInfinity);
5735   __ Fmov(s24, kFP32NegativeInfinity);
5736   __ Fmov(s25, 0.0);
5737   __ Fmov(s26, -0.0);
5738   __ Fmov(s27, -0.2);
5739 
5740   __ Frintn(s0, s16);
5741   __ Frintn(s1, s17);
5742   __ Frintn(s2, s18);
5743   __ Frintn(s3, s19);
5744   __ Frintn(s4, s20);
5745   __ Frintn(s5, s21);
5746   __ Frintn(s6, s22);
5747   __ Frintn(s7, s23);
5748   __ Frintn(s8, s24);
5749   __ Frintn(s9, s25);
5750   __ Frintn(s10, s26);
5751   __ Frintn(s11, s27);
5752 
5753   __ Fmov(d16, 1.0);
5754   __ Fmov(d17, 1.1);
5755   __ Fmov(d18, 1.5);
5756   __ Fmov(d19, 1.9);
5757   __ Fmov(d20, 2.5);
5758   __ Fmov(d21, -1.5);
5759   __ Fmov(d22, -2.5);
5760   __ Fmov(d23, kFP32PositiveInfinity);
5761   __ Fmov(d24, kFP32NegativeInfinity);
5762   __ Fmov(d25, 0.0);
5763   __ Fmov(d26, -0.0);
5764   __ Fmov(d27, -0.2);
5765 
5766   __ Frintn(d12, d16);
5767   __ Frintn(d13, d17);
5768   __ Frintn(d14, d18);
5769   __ Frintn(d15, d19);
5770   __ Frintn(d16, d20);
5771   __ Frintn(d17, d21);
5772   __ Frintn(d18, d22);
5773   __ Frintn(d19, d23);
5774   __ Frintn(d20, d24);
5775   __ Frintn(d21, d25);
5776   __ Frintn(d22, d26);
5777   __ Frintn(d23, d27);
5778   END();
5779 
5780   RUN();
5781 
5782   ASSERT_EQUAL_FP32(1.0, s0);
5783   ASSERT_EQUAL_FP32(1.0, s1);
5784   ASSERT_EQUAL_FP32(2.0, s2);
5785   ASSERT_EQUAL_FP32(2.0, s3);
5786   ASSERT_EQUAL_FP32(2.0, s4);
5787   ASSERT_EQUAL_FP32(-2.0, s5);
5788   ASSERT_EQUAL_FP32(-2.0, s6);
5789   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
5790   ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
5791   ASSERT_EQUAL_FP32(0.0, s9);
5792   ASSERT_EQUAL_FP32(-0.0, s10);
5793   ASSERT_EQUAL_FP32(-0.0, s11);
5794   ASSERT_EQUAL_FP64(1.0, d12);
5795   ASSERT_EQUAL_FP64(1.0, d13);
5796   ASSERT_EQUAL_FP64(2.0, d14);
5797   ASSERT_EQUAL_FP64(2.0, d15);
5798   ASSERT_EQUAL_FP64(2.0, d16);
5799   ASSERT_EQUAL_FP64(-2.0, d17);
5800   ASSERT_EQUAL_FP64(-2.0, d18);
5801   ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
5802   ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
5803   ASSERT_EQUAL_FP64(0.0, d21);
5804   ASSERT_EQUAL_FP64(-0.0, d22);
5805   ASSERT_EQUAL_FP64(-0.0, d23);
5806 
5807   TEARDOWN();
5808 }
5809 
5810 
TEST(frintz)5811 TEST(frintz) {
5812   SETUP();
5813 
5814   START();
5815   __ Fmov(s16, 1.0);
5816   __ Fmov(s17, 1.1);
5817   __ Fmov(s18, 1.5);
5818   __ Fmov(s19, 1.9);
5819   __ Fmov(s20, 2.5);
5820   __ Fmov(s21, -1.5);
5821   __ Fmov(s22, -2.5);
5822   __ Fmov(s23, kFP32PositiveInfinity);
5823   __ Fmov(s24, kFP32NegativeInfinity);
5824   __ Fmov(s25, 0.0);
5825   __ Fmov(s26, -0.0);
5826 
5827   __ Frintz(s0, s16);
5828   __ Frintz(s1, s17);
5829   __ Frintz(s2, s18);
5830   __ Frintz(s3, s19);
5831   __ Frintz(s4, s20);
5832   __ Frintz(s5, s21);
5833   __ Frintz(s6, s22);
5834   __ Frintz(s7, s23);
5835   __ Frintz(s8, s24);
5836   __ Frintz(s9, s25);
5837   __ Frintz(s10, s26);
5838 
5839   __ Fmov(d16, 1.0);
5840   __ Fmov(d17, 1.1);
5841   __ Fmov(d18, 1.5);
5842   __ Fmov(d19, 1.9);
5843   __ Fmov(d20, 2.5);
5844   __ Fmov(d21, -1.5);
5845   __ Fmov(d22, -2.5);
5846   __ Fmov(d23, kFP32PositiveInfinity);
5847   __ Fmov(d24, kFP32NegativeInfinity);
5848   __ Fmov(d25, 0.0);
5849   __ Fmov(d26, -0.0);
5850 
5851   __ Frintz(d11, d16);
5852   __ Frintz(d12, d17);
5853   __ Frintz(d13, d18);
5854   __ Frintz(d14, d19);
5855   __ Frintz(d15, d20);
5856   __ Frintz(d16, d21);
5857   __ Frintz(d17, d22);
5858   __ Frintz(d18, d23);
5859   __ Frintz(d19, d24);
5860   __ Frintz(d20, d25);
5861   __ Frintz(d21, d26);
5862   END();
5863 
5864   RUN();
5865 
5866   ASSERT_EQUAL_FP32(1.0, s0);
5867   ASSERT_EQUAL_FP32(1.0, s1);
5868   ASSERT_EQUAL_FP32(1.0, s2);
5869   ASSERT_EQUAL_FP32(1.0, s3);
5870   ASSERT_EQUAL_FP32(2.0, s4);
5871   ASSERT_EQUAL_FP32(-1.0, s5);
5872   ASSERT_EQUAL_FP32(-2.0, s6);
5873   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
5874   ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
5875   ASSERT_EQUAL_FP32(0.0, s9);
5876   ASSERT_EQUAL_FP32(-0.0, s10);
5877   ASSERT_EQUAL_FP64(1.0, d11);
5878   ASSERT_EQUAL_FP64(1.0, d12);
5879   ASSERT_EQUAL_FP64(1.0, d13);
5880   ASSERT_EQUAL_FP64(1.0, d14);
5881   ASSERT_EQUAL_FP64(2.0, d15);
5882   ASSERT_EQUAL_FP64(-1.0, d16);
5883   ASSERT_EQUAL_FP64(-2.0, d17);
5884   ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
5885   ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
5886   ASSERT_EQUAL_FP64(0.0, d20);
5887   ASSERT_EQUAL_FP64(-0.0, d21);
5888 
5889   TEARDOWN();
5890 }
5891 
5892 
TEST(fcvt_ds)5893 TEST(fcvt_ds) {
5894   SETUP();
5895 
5896   START();
5897   __ Fmov(s16, 1.0);
5898   __ Fmov(s17, 1.1);
5899   __ Fmov(s18, 1.5);
5900   __ Fmov(s19, 1.9);
5901   __ Fmov(s20, 2.5);
5902   __ Fmov(s21, -1.5);
5903   __ Fmov(s22, -2.5);
5904   __ Fmov(s23, kFP32PositiveInfinity);
5905   __ Fmov(s24, kFP32NegativeInfinity);
5906   __ Fmov(s25, 0.0);
5907   __ Fmov(s26, -0.0);
5908   __ Fmov(s27, FLT_MAX);
5909   __ Fmov(s28, FLT_MIN);
5910   __ Fmov(s29, rawbits_to_float(0x7fc12345));   // Quiet NaN.
5911   __ Fmov(s30, rawbits_to_float(0x7f812345));   // Signalling NaN.
5912 
5913   __ Fcvt(d0, s16);
5914   __ Fcvt(d1, s17);
5915   __ Fcvt(d2, s18);
5916   __ Fcvt(d3, s19);
5917   __ Fcvt(d4, s20);
5918   __ Fcvt(d5, s21);
5919   __ Fcvt(d6, s22);
5920   __ Fcvt(d7, s23);
5921   __ Fcvt(d8, s24);
5922   __ Fcvt(d9, s25);
5923   __ Fcvt(d10, s26);
5924   __ Fcvt(d11, s27);
5925   __ Fcvt(d12, s28);
5926   __ Fcvt(d13, s29);
5927   __ Fcvt(d14, s30);
5928   END();
5929 
5930   RUN();
5931 
5932   ASSERT_EQUAL_FP64(1.0f, d0);
5933   ASSERT_EQUAL_FP64(1.1f, d1);
5934   ASSERT_EQUAL_FP64(1.5f, d2);
5935   ASSERT_EQUAL_FP64(1.9f, d3);
5936   ASSERT_EQUAL_FP64(2.5f, d4);
5937   ASSERT_EQUAL_FP64(-1.5f, d5);
5938   ASSERT_EQUAL_FP64(-2.5f, d6);
5939   ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
5940   ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8);
5941   ASSERT_EQUAL_FP64(0.0f, d9);
5942   ASSERT_EQUAL_FP64(-0.0f, d10);
5943   ASSERT_EQUAL_FP64(FLT_MAX, d11);
5944   ASSERT_EQUAL_FP64(FLT_MIN, d12);
5945 
5946   // Check that the NaN payload is preserved according to A64 conversion rules:
5947   //  - The sign bit is preserved.
5948   //  - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
5949   //  - The remaining mantissa bits are copied until they run out.
5950   //  - The low-order bits that haven't already been assigned are set to 0.
5951   ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d13);
5952   ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d14);
5953 
5954   TEARDOWN();
5955 }
5956 
5957 
TEST(fcvt_sd)5958 TEST(fcvt_sd) {
5959   // Test simple conversions here. Complex behaviour (such as rounding
5960   // specifics) are tested in the simulator tests.
5961 
5962   SETUP();
5963 
5964   START();
5965   __ Fmov(d16, 1.0);
5966   __ Fmov(d17, 1.1);
5967   __ Fmov(d18, 1.5);
5968   __ Fmov(d19, 1.9);
5969   __ Fmov(d20, 2.5);
5970   __ Fmov(d21, -1.5);
5971   __ Fmov(d22, -2.5);
5972   __ Fmov(d23, kFP32PositiveInfinity);
5973   __ Fmov(d24, kFP32NegativeInfinity);
5974   __ Fmov(d25, 0.0);
5975   __ Fmov(d26, -0.0);
5976   __ Fmov(d27, FLT_MAX);
5977   __ Fmov(d28, FLT_MIN);
5978   __ Fmov(d29, rawbits_to_double(0x7ff82468a0000000));   // Quiet NaN.
5979   __ Fmov(d30, rawbits_to_double(0x7ff02468a0000000));   // Signalling NaN.
5980 
5981   __ Fcvt(s0, d16);
5982   __ Fcvt(s1, d17);
5983   __ Fcvt(s2, d18);
5984   __ Fcvt(s3, d19);
5985   __ Fcvt(s4, d20);
5986   __ Fcvt(s5, d21);
5987   __ Fcvt(s6, d22);
5988   __ Fcvt(s7, d23);
5989   __ Fcvt(s8, d24);
5990   __ Fcvt(s9, d25);
5991   __ Fcvt(s10, d26);
5992   __ Fcvt(s11, d27);
5993   __ Fcvt(s12, d28);
5994   __ Fcvt(s13, d29);
5995   __ Fcvt(s14, d30);
5996   END();
5997 
5998   RUN();
5999 
6000   ASSERT_EQUAL_FP32(1.0f, s0);
6001   ASSERT_EQUAL_FP32(1.1f, s1);
6002   ASSERT_EQUAL_FP32(1.5f, s2);
6003   ASSERT_EQUAL_FP32(1.9f, s3);
6004   ASSERT_EQUAL_FP32(2.5f, s4);
6005   ASSERT_EQUAL_FP32(-1.5f, s5);
6006   ASSERT_EQUAL_FP32(-2.5f, s6);
6007   ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
6008   ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
6009   ASSERT_EQUAL_FP32(0.0f, s9);
6010   ASSERT_EQUAL_FP32(-0.0f, s10);
6011   ASSERT_EQUAL_FP32(FLT_MAX, s11);
6012   ASSERT_EQUAL_FP32(FLT_MIN, s12);
6013 
6014   // Check that the NaN payload is preserved according to A64 conversion rules:
6015   //  - The sign bit is preserved.
6016   //  - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
6017   //  - The remaining mantissa bits are copied until they run out.
6018   //  - The low-order bits that haven't already been assigned are set to 0.
6019   ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s13);
6020   ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s14);
6021 
6022   TEARDOWN();
6023 }
6024 
6025 
TEST(fcvtas)6026 TEST(fcvtas) {
6027   SETUP();
6028 
6029   START();
6030   __ Fmov(s0, 1.0);
6031   __ Fmov(s1, 1.1);
6032   __ Fmov(s2, 2.5);
6033   __ Fmov(s3, -2.5);
6034   __ Fmov(s4, kFP32PositiveInfinity);
6035   __ Fmov(s5, kFP32NegativeInfinity);
6036   __ Fmov(s6, 0x7fffff80);  // Largest float < INT32_MAX.
6037   __ Fneg(s7, s6);          // Smallest float > INT32_MIN.
6038   __ Fmov(d8, 1.0);
6039   __ Fmov(d9, 1.1);
6040   __ Fmov(d10, 2.5);
6041   __ Fmov(d11, -2.5);
6042   __ Fmov(d12, kFP64PositiveInfinity);
6043   __ Fmov(d13, kFP64NegativeInfinity);
6044   __ Fmov(d14, kWMaxInt - 1);
6045   __ Fmov(d15, kWMinInt + 1);
6046   __ Fmov(s17, 1.1);
6047   __ Fmov(s18, 2.5);
6048   __ Fmov(s19, -2.5);
6049   __ Fmov(s20, kFP32PositiveInfinity);
6050   __ Fmov(s21, kFP32NegativeInfinity);
6051   __ Fmov(s22, 0x7fffff8000000000);     // Largest float < INT64_MAX.
6052   __ Fneg(s23, s22);                    // Smallest float > INT64_MIN.
6053   __ Fmov(d24, 1.1);
6054   __ Fmov(d25, 2.5);
6055   __ Fmov(d26, -2.5);
6056   __ Fmov(d27, kFP64PositiveInfinity);
6057   __ Fmov(d28, kFP64NegativeInfinity);
6058   __ Fmov(d29, 0x7ffffffffffffc00);     // Largest double < INT64_MAX.
6059   __ Fneg(d30, d29);                    // Smallest double > INT64_MIN.
6060 
6061   __ Fcvtas(w0, s0);
6062   __ Fcvtas(w1, s1);
6063   __ Fcvtas(w2, s2);
6064   __ Fcvtas(w3, s3);
6065   __ Fcvtas(w4, s4);
6066   __ Fcvtas(w5, s5);
6067   __ Fcvtas(w6, s6);
6068   __ Fcvtas(w7, s7);
6069   __ Fcvtas(w8, d8);
6070   __ Fcvtas(w9, d9);
6071   __ Fcvtas(w10, d10);
6072   __ Fcvtas(w11, d11);
6073   __ Fcvtas(w12, d12);
6074   __ Fcvtas(w13, d13);
6075   __ Fcvtas(w14, d14);
6076   __ Fcvtas(w15, d15);
6077   __ Fcvtas(x17, s17);
6078   __ Fcvtas(x18, s18);
6079   __ Fcvtas(x19, s19);
6080   __ Fcvtas(x20, s20);
6081   __ Fcvtas(x21, s21);
6082   __ Fcvtas(x22, s22);
6083   __ Fcvtas(x23, s23);
6084   __ Fcvtas(x24, d24);
6085   __ Fcvtas(x25, d25);
6086   __ Fcvtas(x26, d26);
6087   __ Fcvtas(x27, d27);
6088   __ Fcvtas(x28, d28);
6089   __ Fcvtas(x29, d29);
6090   __ Fcvtas(x30, d30);
6091   END();
6092 
6093   RUN();
6094 
6095   ASSERT_EQUAL_64(1, x0);
6096   ASSERT_EQUAL_64(1, x1);
6097   ASSERT_EQUAL_64(3, x2);
6098   ASSERT_EQUAL_64(0xfffffffd, x3);
6099   ASSERT_EQUAL_64(0x7fffffff, x4);
6100   ASSERT_EQUAL_64(0x80000000, x5);
6101   ASSERT_EQUAL_64(0x7fffff80, x6);
6102   ASSERT_EQUAL_64(0x80000080, x7);
6103   ASSERT_EQUAL_64(1, x8);
6104   ASSERT_EQUAL_64(1, x9);
6105   ASSERT_EQUAL_64(3, x10);
6106   ASSERT_EQUAL_64(0xfffffffd, x11);
6107   ASSERT_EQUAL_64(0x7fffffff, x12);
6108   ASSERT_EQUAL_64(0x80000000, x13);
6109   ASSERT_EQUAL_64(0x7ffffffe, x14);
6110   ASSERT_EQUAL_64(0x80000001, x15);
6111   ASSERT_EQUAL_64(1, x17);
6112   ASSERT_EQUAL_64(3, x18);
6113   ASSERT_EQUAL_64(0xfffffffffffffffd, x19);
6114   ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6115   ASSERT_EQUAL_64(0x8000000000000000, x21);
6116   ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6117   ASSERT_EQUAL_64(0x8000008000000000, x23);
6118   ASSERT_EQUAL_64(1, x24);
6119   ASSERT_EQUAL_64(3, x25);
6120   ASSERT_EQUAL_64(0xfffffffffffffffd, x26);
6121   ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6122   ASSERT_EQUAL_64(0x8000000000000000, x28);
6123   ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6124   ASSERT_EQUAL_64(0x8000000000000400, x30);
6125 
6126   TEARDOWN();
6127 }
6128 
6129 
TEST(fcvtau)6130 TEST(fcvtau) {
6131   SETUP();
6132 
6133   START();
6134   __ Fmov(s0, 1.0);
6135   __ Fmov(s1, 1.1);
6136   __ Fmov(s2, 2.5);
6137   __ Fmov(s3, -2.5);
6138   __ Fmov(s4, kFP32PositiveInfinity);
6139   __ Fmov(s5, kFP32NegativeInfinity);
6140   __ Fmov(s6, 0xffffff00);  // Largest float < UINT32_MAX.
6141   __ Fmov(d8, 1.0);
6142   __ Fmov(d9, 1.1);
6143   __ Fmov(d10, 2.5);
6144   __ Fmov(d11, -2.5);
6145   __ Fmov(d12, kFP64PositiveInfinity);
6146   __ Fmov(d13, kFP64NegativeInfinity);
6147   __ Fmov(d14, 0xfffffffe);
6148   __ Fmov(s16, 1.0);
6149   __ Fmov(s17, 1.1);
6150   __ Fmov(s18, 2.5);
6151   __ Fmov(s19, -2.5);
6152   __ Fmov(s20, kFP32PositiveInfinity);
6153   __ Fmov(s21, kFP32NegativeInfinity);
6154   __ Fmov(s22, 0xffffff0000000000);  // Largest float < UINT64_MAX.
6155   __ Fmov(d24, 1.1);
6156   __ Fmov(d25, 2.5);
6157   __ Fmov(d26, -2.5);
6158   __ Fmov(d27, kFP64PositiveInfinity);
6159   __ Fmov(d28, kFP64NegativeInfinity);
6160   __ Fmov(d29, 0xfffffffffffff800);  // Largest double < UINT64_MAX.
6161   __ Fmov(s30, 0x100000000);
6162 
6163   __ Fcvtau(w0, s0);
6164   __ Fcvtau(w1, s1);
6165   __ Fcvtau(w2, s2);
6166   __ Fcvtau(w3, s3);
6167   __ Fcvtau(w4, s4);
6168   __ Fcvtau(w5, s5);
6169   __ Fcvtau(w6, s6);
6170   __ Fcvtau(w8, d8);
6171   __ Fcvtau(w9, d9);
6172   __ Fcvtau(w10, d10);
6173   __ Fcvtau(w11, d11);
6174   __ Fcvtau(w12, d12);
6175   __ Fcvtau(w13, d13);
6176   __ Fcvtau(w14, d14);
6177   __ Fcvtau(w15, d15);
6178   __ Fcvtau(x16, s16);
6179   __ Fcvtau(x17, s17);
6180   __ Fcvtau(x18, s18);
6181   __ Fcvtau(x19, s19);
6182   __ Fcvtau(x20, s20);
6183   __ Fcvtau(x21, s21);
6184   __ Fcvtau(x22, s22);
6185   __ Fcvtau(x24, d24);
6186   __ Fcvtau(x25, d25);
6187   __ Fcvtau(x26, d26);
6188   __ Fcvtau(x27, d27);
6189   __ Fcvtau(x28, d28);
6190   __ Fcvtau(x29, d29);
6191   __ Fcvtau(w30, s30);
6192   END();
6193 
6194   RUN();
6195 
6196   ASSERT_EQUAL_64(1, x0);
6197   ASSERT_EQUAL_64(1, x1);
6198   ASSERT_EQUAL_64(3, x2);
6199   ASSERT_EQUAL_64(0, x3);
6200   ASSERT_EQUAL_64(0xffffffff, x4);
6201   ASSERT_EQUAL_64(0, x5);
6202   ASSERT_EQUAL_64(0xffffff00, x6);
6203   ASSERT_EQUAL_64(1, x8);
6204   ASSERT_EQUAL_64(1, x9);
6205   ASSERT_EQUAL_64(3, x10);
6206   ASSERT_EQUAL_64(0, x11);
6207   ASSERT_EQUAL_64(0xffffffff, x12);
6208   ASSERT_EQUAL_64(0, x13);
6209   ASSERT_EQUAL_64(0xfffffffe, x14);
6210   ASSERT_EQUAL_64(1, x16);
6211   ASSERT_EQUAL_64(1, x17);
6212   ASSERT_EQUAL_64(3, x18);
6213   ASSERT_EQUAL_64(0, x19);
6214   ASSERT_EQUAL_64(0xffffffffffffffff, x20);
6215   ASSERT_EQUAL_64(0, x21);
6216   ASSERT_EQUAL_64(0xffffff0000000000, x22);
6217   ASSERT_EQUAL_64(1, x24);
6218   ASSERT_EQUAL_64(3, x25);
6219   ASSERT_EQUAL_64(0, x26);
6220   ASSERT_EQUAL_64(0xffffffffffffffff, x27);
6221   ASSERT_EQUAL_64(0, x28);
6222   ASSERT_EQUAL_64(0xfffffffffffff800, x29);
6223   ASSERT_EQUAL_64(0xffffffff, x30);
6224 
6225   TEARDOWN();
6226 }
6227 
6228 
TEST(fcvtms)6229 TEST(fcvtms) {
6230   SETUP();
6231 
6232   START();
6233   __ Fmov(s0, 1.0);
6234   __ Fmov(s1, 1.1);
6235   __ Fmov(s2, 1.5);
6236   __ Fmov(s3, -1.5);
6237   __ Fmov(s4, kFP32PositiveInfinity);
6238   __ Fmov(s5, kFP32NegativeInfinity);
6239   __ Fmov(s6, 0x7fffff80);                    // Largest float < INT32_MAX.
6240   __ Fneg(s7, s6);                            // Smallest float > INT32_MIN.
6241   __ Fmov(d8, 1.0);
6242   __ Fmov(d9, 1.1);
6243   __ Fmov(d10, 1.5);
6244   __ Fmov(d11, -1.5);
6245   __ Fmov(d12, kFP64PositiveInfinity);
6246   __ Fmov(d13, kFP64NegativeInfinity);
6247   __ Fmov(d14, kWMaxInt - 1);
6248   __ Fmov(d15, kWMinInt + 1);
6249   __ Fmov(s17, 1.1);
6250   __ Fmov(s18, 1.5);
6251   __ Fmov(s19, -1.5);
6252   __ Fmov(s20, kFP32PositiveInfinity);
6253   __ Fmov(s21, kFP32NegativeInfinity);
6254   __ Fmov(s22, 0x7fffff8000000000);           // Largest float < INT64_MAX.
6255   __ Fneg(s23, s22);                          // Smallest float > INT64_MIN.
6256   __ Fmov(d24, 1.1);
6257   __ Fmov(d25, 1.5);
6258   __ Fmov(d26, -1.5);
6259   __ Fmov(d27, kFP64PositiveInfinity);
6260   __ Fmov(d28, kFP64NegativeInfinity);
6261   __ Fmov(d29, 0x7ffffffffffffc00);           // Largest double < INT64_MAX.
6262   __ Fneg(d30, d29);                          // Smallest double > INT64_MIN.
6263 
6264   __ Fcvtms(w0, s0);
6265   __ Fcvtms(w1, s1);
6266   __ Fcvtms(w2, s2);
6267   __ Fcvtms(w3, s3);
6268   __ Fcvtms(w4, s4);
6269   __ Fcvtms(w5, s5);
6270   __ Fcvtms(w6, s6);
6271   __ Fcvtms(w7, s7);
6272   __ Fcvtms(w8, d8);
6273   __ Fcvtms(w9, d9);
6274   __ Fcvtms(w10, d10);
6275   __ Fcvtms(w11, d11);
6276   __ Fcvtms(w12, d12);
6277   __ Fcvtms(w13, d13);
6278   __ Fcvtms(w14, d14);
6279   __ Fcvtms(w15, d15);
6280   __ Fcvtms(x17, s17);
6281   __ Fcvtms(x18, s18);
6282   __ Fcvtms(x19, s19);
6283   __ Fcvtms(x20, s20);
6284   __ Fcvtms(x21, s21);
6285   __ Fcvtms(x22, s22);
6286   __ Fcvtms(x23, s23);
6287   __ Fcvtms(x24, d24);
6288   __ Fcvtms(x25, d25);
6289   __ Fcvtms(x26, d26);
6290   __ Fcvtms(x27, d27);
6291   __ Fcvtms(x28, d28);
6292   __ Fcvtms(x29, d29);
6293   __ Fcvtms(x30, d30);
6294   END();
6295 
6296   RUN();
6297 
6298   ASSERT_EQUAL_64(1, x0);
6299   ASSERT_EQUAL_64(1, x1);
6300   ASSERT_EQUAL_64(1, x2);
6301   ASSERT_EQUAL_64(0xfffffffe, x3);
6302   ASSERT_EQUAL_64(0x7fffffff, x4);
6303   ASSERT_EQUAL_64(0x80000000, x5);
6304   ASSERT_EQUAL_64(0x7fffff80, x6);
6305   ASSERT_EQUAL_64(0x80000080, x7);
6306   ASSERT_EQUAL_64(1, x8);
6307   ASSERT_EQUAL_64(1, x9);
6308   ASSERT_EQUAL_64(1, x10);
6309   ASSERT_EQUAL_64(0xfffffffe, x11);
6310   ASSERT_EQUAL_64(0x7fffffff, x12);
6311   ASSERT_EQUAL_64(0x80000000, x13);
6312   ASSERT_EQUAL_64(0x7ffffffe, x14);
6313   ASSERT_EQUAL_64(0x80000001, x15);
6314   ASSERT_EQUAL_64(1, x17);
6315   ASSERT_EQUAL_64(1, x18);
6316   ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
6317   ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6318   ASSERT_EQUAL_64(0x8000000000000000, x21);
6319   ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6320   ASSERT_EQUAL_64(0x8000008000000000, x23);
6321   ASSERT_EQUAL_64(1, x24);
6322   ASSERT_EQUAL_64(1, x25);
6323   ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
6324   ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6325   ASSERT_EQUAL_64(0x8000000000000000, x28);
6326   ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6327   ASSERT_EQUAL_64(0x8000000000000400, x30);
6328 
6329   TEARDOWN();
6330 }
6331 
6332 
TEST(fcvtmu)6333 TEST(fcvtmu) {
6334   SETUP();
6335 
6336   START();
6337   __ Fmov(s0, 1.0);
6338   __ Fmov(s1, 1.1);
6339   __ Fmov(s2, 1.5);
6340   __ Fmov(s3, -1.5);
6341   __ Fmov(s4, kFP32PositiveInfinity);
6342   __ Fmov(s5, kFP32NegativeInfinity);
6343   __ Fmov(s6, 0x7fffff80);                    // Largest float < INT32_MAX.
6344   __ Fneg(s7, s6);                            // Smallest float > INT32_MIN.
6345   __ Fmov(d8, 1.0);
6346   __ Fmov(d9, 1.1);
6347   __ Fmov(d10, 1.5);
6348   __ Fmov(d11, -1.5);
6349   __ Fmov(d12, kFP64PositiveInfinity);
6350   __ Fmov(d13, kFP64NegativeInfinity);
6351   __ Fmov(d14, kWMaxInt - 1);
6352   __ Fmov(d15, kWMinInt + 1);
6353   __ Fmov(s17, 1.1);
6354   __ Fmov(s18, 1.5);
6355   __ Fmov(s19, -1.5);
6356   __ Fmov(s20, kFP32PositiveInfinity);
6357   __ Fmov(s21, kFP32NegativeInfinity);
6358   __ Fmov(s22, 0x7fffff8000000000);           // Largest float < INT64_MAX.
6359   __ Fneg(s23, s22);                          // Smallest float > INT64_MIN.
6360   __ Fmov(d24, 1.1);
6361   __ Fmov(d25, 1.5);
6362   __ Fmov(d26, -1.5);
6363   __ Fmov(d27, kFP64PositiveInfinity);
6364   __ Fmov(d28, kFP64NegativeInfinity);
6365   __ Fmov(d29, 0x7ffffffffffffc00);           // Largest double < INT64_MAX.
6366   __ Fneg(d30, d29);                          // Smallest double > INT64_MIN.
6367 
6368   __ Fcvtmu(w0, s0);
6369   __ Fcvtmu(w1, s1);
6370   __ Fcvtmu(w2, s2);
6371   __ Fcvtmu(w3, s3);
6372   __ Fcvtmu(w4, s4);
6373   __ Fcvtmu(w5, s5);
6374   __ Fcvtmu(w6, s6);
6375   __ Fcvtmu(w7, s7);
6376   __ Fcvtmu(w8, d8);
6377   __ Fcvtmu(w9, d9);
6378   __ Fcvtmu(w10, d10);
6379   __ Fcvtmu(w11, d11);
6380   __ Fcvtmu(w12, d12);
6381   __ Fcvtmu(w13, d13);
6382   __ Fcvtmu(w14, d14);
6383   __ Fcvtmu(x17, s17);
6384   __ Fcvtmu(x18, s18);
6385   __ Fcvtmu(x19, s19);
6386   __ Fcvtmu(x20, s20);
6387   __ Fcvtmu(x21, s21);
6388   __ Fcvtmu(x22, s22);
6389   __ Fcvtmu(x23, s23);
6390   __ Fcvtmu(x24, d24);
6391   __ Fcvtmu(x25, d25);
6392   __ Fcvtmu(x26, d26);
6393   __ Fcvtmu(x27, d27);
6394   __ Fcvtmu(x28, d28);
6395   __ Fcvtmu(x29, d29);
6396   __ Fcvtmu(x30, d30);
6397   END();
6398 
6399   RUN();
6400 
6401   ASSERT_EQUAL_64(1, x0);
6402   ASSERT_EQUAL_64(1, x1);
6403   ASSERT_EQUAL_64(1, x2);
6404   ASSERT_EQUAL_64(0, x3);
6405   ASSERT_EQUAL_64(0xffffffff, x4);
6406   ASSERT_EQUAL_64(0, x5);
6407   ASSERT_EQUAL_64(0x7fffff80, x6);
6408   ASSERT_EQUAL_64(0, x7);
6409   ASSERT_EQUAL_64(1, x8);
6410   ASSERT_EQUAL_64(1, x9);
6411   ASSERT_EQUAL_64(1, x10);
6412   ASSERT_EQUAL_64(0, x11);
6413   ASSERT_EQUAL_64(0xffffffff, x12);
6414   ASSERT_EQUAL_64(0, x13);
6415   ASSERT_EQUAL_64(0x7ffffffe, x14);
6416   ASSERT_EQUAL_64(1, x17);
6417   ASSERT_EQUAL_64(1, x18);
6418   ASSERT_EQUAL_64(0, x19);
6419   ASSERT_EQUAL_64(0xffffffffffffffff, x20);
6420   ASSERT_EQUAL_64(0, x21);
6421   ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6422   ASSERT_EQUAL_64(0, x23);
6423   ASSERT_EQUAL_64(1, x24);
6424   ASSERT_EQUAL_64(1, x25);
6425   ASSERT_EQUAL_64(0, x26);
6426   ASSERT_EQUAL_64(0xffffffffffffffff, x27);
6427   ASSERT_EQUAL_64(0, x28);
6428   ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6429   ASSERT_EQUAL_64(0, x30);
6430 
6431   TEARDOWN();
6432 }
6433 
6434 
TEST(fcvtns)6435 TEST(fcvtns) {
6436   SETUP();
6437 
6438   START();
6439   __ Fmov(s0, 1.0);
6440   __ Fmov(s1, 1.1);
6441   __ Fmov(s2, 1.5);
6442   __ Fmov(s3, -1.5);
6443   __ Fmov(s4, kFP32PositiveInfinity);
6444   __ Fmov(s5, kFP32NegativeInfinity);
6445   __ Fmov(s6, 0x7fffff80);                    // Largest float < INT32_MAX.
6446   __ Fneg(s7, s6);                            // Smallest float > INT32_MIN.
6447   __ Fmov(d8, 1.0);
6448   __ Fmov(d9, 1.1);
6449   __ Fmov(d10, 1.5);
6450   __ Fmov(d11, -1.5);
6451   __ Fmov(d12, kFP64PositiveInfinity);
6452   __ Fmov(d13, kFP64NegativeInfinity);
6453   __ Fmov(d14, kWMaxInt - 1);
6454   __ Fmov(d15, kWMinInt + 1);
6455   __ Fmov(s17, 1.1);
6456   __ Fmov(s18, 1.5);
6457   __ Fmov(s19, -1.5);
6458   __ Fmov(s20, kFP32PositiveInfinity);
6459   __ Fmov(s21, kFP32NegativeInfinity);
6460   __ Fmov(s22, 0x7fffff8000000000);           // Largest float < INT64_MAX.
6461   __ Fneg(s23, s22);                          // Smallest float > INT64_MIN.
6462   __ Fmov(d24, 1.1);
6463   __ Fmov(d25, 1.5);
6464   __ Fmov(d26, -1.5);
6465   __ Fmov(d27, kFP64PositiveInfinity);
6466   __ Fmov(d28, kFP64NegativeInfinity);
6467   __ Fmov(d29, 0x7ffffffffffffc00);           // Largest double < INT64_MAX.
6468   __ Fneg(d30, d29);                          // Smallest double > INT64_MIN.
6469 
6470   __ Fcvtns(w0, s0);
6471   __ Fcvtns(w1, s1);
6472   __ Fcvtns(w2, s2);
6473   __ Fcvtns(w3, s3);
6474   __ Fcvtns(w4, s4);
6475   __ Fcvtns(w5, s5);
6476   __ Fcvtns(w6, s6);
6477   __ Fcvtns(w7, s7);
6478   __ Fcvtns(w8, d8);
6479   __ Fcvtns(w9, d9);
6480   __ Fcvtns(w10, d10);
6481   __ Fcvtns(w11, d11);
6482   __ Fcvtns(w12, d12);
6483   __ Fcvtns(w13, d13);
6484   __ Fcvtns(w14, d14);
6485   __ Fcvtns(w15, d15);
6486   __ Fcvtns(x17, s17);
6487   __ Fcvtns(x18, s18);
6488   __ Fcvtns(x19, s19);
6489   __ Fcvtns(x20, s20);
6490   __ Fcvtns(x21, s21);
6491   __ Fcvtns(x22, s22);
6492   __ Fcvtns(x23, s23);
6493   __ Fcvtns(x24, d24);
6494   __ Fcvtns(x25, d25);
6495   __ Fcvtns(x26, d26);
6496   __ Fcvtns(x27, d27);
6497   __ Fcvtns(x28, d28);
6498   __ Fcvtns(x29, d29);
6499   __ Fcvtns(x30, d30);
6500   END();
6501 
6502   RUN();
6503 
6504   ASSERT_EQUAL_64(1, x0);
6505   ASSERT_EQUAL_64(1, x1);
6506   ASSERT_EQUAL_64(2, x2);
6507   ASSERT_EQUAL_64(0xfffffffe, x3);
6508   ASSERT_EQUAL_64(0x7fffffff, x4);
6509   ASSERT_EQUAL_64(0x80000000, x5);
6510   ASSERT_EQUAL_64(0x7fffff80, x6);
6511   ASSERT_EQUAL_64(0x80000080, x7);
6512   ASSERT_EQUAL_64(1, x8);
6513   ASSERT_EQUAL_64(1, x9);
6514   ASSERT_EQUAL_64(2, x10);
6515   ASSERT_EQUAL_64(0xfffffffe, x11);
6516   ASSERT_EQUAL_64(0x7fffffff, x12);
6517   ASSERT_EQUAL_64(0x80000000, x13);
6518   ASSERT_EQUAL_64(0x7ffffffe, x14);
6519   ASSERT_EQUAL_64(0x80000001, x15);
6520   ASSERT_EQUAL_64(1, x17);
6521   ASSERT_EQUAL_64(2, x18);
6522   ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
6523   ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6524   ASSERT_EQUAL_64(0x8000000000000000, x21);
6525   ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6526   ASSERT_EQUAL_64(0x8000008000000000, x23);
6527   ASSERT_EQUAL_64(1, x24);
6528   ASSERT_EQUAL_64(2, x25);
6529   ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
6530   ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6531   ASSERT_EQUAL_64(0x8000000000000000, x28);
6532   ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6533   ASSERT_EQUAL_64(0x8000000000000400, x30);
6534 
6535   TEARDOWN();
6536 }
6537 
6538 
TEST(fcvtnu)6539 TEST(fcvtnu) {
6540   SETUP();
6541 
6542   START();
6543   __ Fmov(s0, 1.0);
6544   __ Fmov(s1, 1.1);
6545   __ Fmov(s2, 1.5);
6546   __ Fmov(s3, -1.5);
6547   __ Fmov(s4, kFP32PositiveInfinity);
6548   __ Fmov(s5, kFP32NegativeInfinity);
6549   __ Fmov(s6, 0xffffff00);  // Largest float < UINT32_MAX.
6550   __ Fmov(d8, 1.0);
6551   __ Fmov(d9, 1.1);
6552   __ Fmov(d10, 1.5);
6553   __ Fmov(d11, -1.5);
6554   __ Fmov(d12, kFP64PositiveInfinity);
6555   __ Fmov(d13, kFP64NegativeInfinity);
6556   __ Fmov(d14, 0xfffffffe);
6557   __ Fmov(s16, 1.0);
6558   __ Fmov(s17, 1.1);
6559   __ Fmov(s18, 1.5);
6560   __ Fmov(s19, -1.5);
6561   __ Fmov(s20, kFP32PositiveInfinity);
6562   __ Fmov(s21, kFP32NegativeInfinity);
6563   __ Fmov(s22, 0xffffff0000000000);  // Largest float < UINT64_MAX.
6564   __ Fmov(d24, 1.1);
6565   __ Fmov(d25, 1.5);
6566   __ Fmov(d26, -1.5);
6567   __ Fmov(d27, kFP64PositiveInfinity);
6568   __ Fmov(d28, kFP64NegativeInfinity);
6569   __ Fmov(d29, 0xfffffffffffff800);  // Largest double < UINT64_MAX.
6570   __ Fmov(s30, 0x100000000);
6571 
6572   __ Fcvtnu(w0, s0);
6573   __ Fcvtnu(w1, s1);
6574   __ Fcvtnu(w2, s2);
6575   __ Fcvtnu(w3, s3);
6576   __ Fcvtnu(w4, s4);
6577   __ Fcvtnu(w5, s5);
6578   __ Fcvtnu(w6, s6);
6579   __ Fcvtnu(w8, d8);
6580   __ Fcvtnu(w9, d9);
6581   __ Fcvtnu(w10, d10);
6582   __ Fcvtnu(w11, d11);
6583   __ Fcvtnu(w12, d12);
6584   __ Fcvtnu(w13, d13);
6585   __ Fcvtnu(w14, d14);
6586   __ Fcvtnu(w15, d15);
6587   __ Fcvtnu(x16, s16);
6588   __ Fcvtnu(x17, s17);
6589   __ Fcvtnu(x18, s18);
6590   __ Fcvtnu(x19, s19);
6591   __ Fcvtnu(x20, s20);
6592   __ Fcvtnu(x21, s21);
6593   __ Fcvtnu(x22, s22);
6594   __ Fcvtnu(x24, d24);
6595   __ Fcvtnu(x25, d25);
6596   __ Fcvtnu(x26, d26);
6597   __ Fcvtnu(x27, d27);
6598   __ Fcvtnu(x28, d28);
6599   __ Fcvtnu(x29, d29);
6600   __ Fcvtnu(w30, s30);
6601   END();
6602 
6603   RUN();
6604 
6605   ASSERT_EQUAL_64(1, x0);
6606   ASSERT_EQUAL_64(1, x1);
6607   ASSERT_EQUAL_64(2, x2);
6608   ASSERT_EQUAL_64(0, x3);
6609   ASSERT_EQUAL_64(0xffffffff, x4);
6610   ASSERT_EQUAL_64(0, x5);
6611   ASSERT_EQUAL_64(0xffffff00, x6);
6612   ASSERT_EQUAL_64(1, x8);
6613   ASSERT_EQUAL_64(1, x9);
6614   ASSERT_EQUAL_64(2, x10);
6615   ASSERT_EQUAL_64(0, x11);
6616   ASSERT_EQUAL_64(0xffffffff, x12);
6617   ASSERT_EQUAL_64(0, x13);
6618   ASSERT_EQUAL_64(0xfffffffe, x14);
6619   ASSERT_EQUAL_64(1, x16);
6620   ASSERT_EQUAL_64(1, x17);
6621   ASSERT_EQUAL_64(2, x18);
6622   ASSERT_EQUAL_64(0, x19);
6623   ASSERT_EQUAL_64(0xffffffffffffffff, x20);
6624   ASSERT_EQUAL_64(0, x21);
6625   ASSERT_EQUAL_64(0xffffff0000000000, x22);
6626   ASSERT_EQUAL_64(1, x24);
6627   ASSERT_EQUAL_64(2, x25);
6628   ASSERT_EQUAL_64(0, x26);
6629   ASSERT_EQUAL_64(0xffffffffffffffff, x27);
6630   ASSERT_EQUAL_64(0, x28);
6631   ASSERT_EQUAL_64(0xfffffffffffff800, x29);
6632   ASSERT_EQUAL_64(0xffffffff, x30);
6633 
6634   TEARDOWN();
6635 }
6636 
6637 
TEST(fcvtzs)6638 TEST(fcvtzs) {
6639   SETUP();
6640 
6641   START();
6642   __ Fmov(s0, 1.0);
6643   __ Fmov(s1, 1.1);
6644   __ Fmov(s2, 1.5);
6645   __ Fmov(s3, -1.5);
6646   __ Fmov(s4, kFP32PositiveInfinity);
6647   __ Fmov(s5, kFP32NegativeInfinity);
6648   __ Fmov(s6, 0x7fffff80);                    // Largest float < INT32_MAX.
6649   __ Fneg(s7, s6);                            // Smallest float > INT32_MIN.
6650   __ Fmov(d8, 1.0);
6651   __ Fmov(d9, 1.1);
6652   __ Fmov(d10, 1.5);
6653   __ Fmov(d11, -1.5);
6654   __ Fmov(d12, kFP64PositiveInfinity);
6655   __ Fmov(d13, kFP64NegativeInfinity);
6656   __ Fmov(d14, kWMaxInt - 1);
6657   __ Fmov(d15, kWMinInt + 1);
6658   __ Fmov(s17, 1.1);
6659   __ Fmov(s18, 1.5);
6660   __ Fmov(s19, -1.5);
6661   __ Fmov(s20, kFP32PositiveInfinity);
6662   __ Fmov(s21, kFP32NegativeInfinity);
6663   __ Fmov(s22, 0x7fffff8000000000);           // Largest float < INT64_MAX.
6664   __ Fneg(s23, s22);                          // Smallest float > INT64_MIN.
6665   __ Fmov(d24, 1.1);
6666   __ Fmov(d25, 1.5);
6667   __ Fmov(d26, -1.5);
6668   __ Fmov(d27, kFP64PositiveInfinity);
6669   __ Fmov(d28, kFP64NegativeInfinity);
6670   __ Fmov(d29, 0x7ffffffffffffc00);           // Largest double < INT64_MAX.
6671   __ Fneg(d30, d29);                          // Smallest double > INT64_MIN.
6672 
6673   __ Fcvtzs(w0, s0);
6674   __ Fcvtzs(w1, s1);
6675   __ Fcvtzs(w2, s2);
6676   __ Fcvtzs(w3, s3);
6677   __ Fcvtzs(w4, s4);
6678   __ Fcvtzs(w5, s5);
6679   __ Fcvtzs(w6, s6);
6680   __ Fcvtzs(w7, s7);
6681   __ Fcvtzs(w8, d8);
6682   __ Fcvtzs(w9, d9);
6683   __ Fcvtzs(w10, d10);
6684   __ Fcvtzs(w11, d11);
6685   __ Fcvtzs(w12, d12);
6686   __ Fcvtzs(w13, d13);
6687   __ Fcvtzs(w14, d14);
6688   __ Fcvtzs(w15, d15);
6689   __ Fcvtzs(x17, s17);
6690   __ Fcvtzs(x18, s18);
6691   __ Fcvtzs(x19, s19);
6692   __ Fcvtzs(x20, s20);
6693   __ Fcvtzs(x21, s21);
6694   __ Fcvtzs(x22, s22);
6695   __ Fcvtzs(x23, s23);
6696   __ Fcvtzs(x24, d24);
6697   __ Fcvtzs(x25, d25);
6698   __ Fcvtzs(x26, d26);
6699   __ Fcvtzs(x27, d27);
6700   __ Fcvtzs(x28, d28);
6701   __ Fcvtzs(x29, d29);
6702   __ Fcvtzs(x30, d30);
6703   END();
6704 
6705   RUN();
6706 
6707   ASSERT_EQUAL_64(1, x0);
6708   ASSERT_EQUAL_64(1, x1);
6709   ASSERT_EQUAL_64(1, x2);
6710   ASSERT_EQUAL_64(0xffffffff, x3);
6711   ASSERT_EQUAL_64(0x7fffffff, x4);
6712   ASSERT_EQUAL_64(0x80000000, x5);
6713   ASSERT_EQUAL_64(0x7fffff80, x6);
6714   ASSERT_EQUAL_64(0x80000080, x7);
6715   ASSERT_EQUAL_64(1, x8);
6716   ASSERT_EQUAL_64(1, x9);
6717   ASSERT_EQUAL_64(1, x10);
6718   ASSERT_EQUAL_64(0xffffffff, x11);
6719   ASSERT_EQUAL_64(0x7fffffff, x12);
6720   ASSERT_EQUAL_64(0x80000000, x13);
6721   ASSERT_EQUAL_64(0x7ffffffe, x14);
6722   ASSERT_EQUAL_64(0x80000001, x15);
6723   ASSERT_EQUAL_64(1, x17);
6724   ASSERT_EQUAL_64(1, x18);
6725   ASSERT_EQUAL_64(0xffffffffffffffff, x19);
6726   ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6727   ASSERT_EQUAL_64(0x8000000000000000, x21);
6728   ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6729   ASSERT_EQUAL_64(0x8000008000000000, x23);
6730   ASSERT_EQUAL_64(1, x24);
6731   ASSERT_EQUAL_64(1, x25);
6732   ASSERT_EQUAL_64(0xffffffffffffffff, x26);
6733   ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6734   ASSERT_EQUAL_64(0x8000000000000000, x28);
6735   ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6736   ASSERT_EQUAL_64(0x8000000000000400, x30);
6737 
6738   TEARDOWN();
6739 }
6740 
TEST(fcvtzu)6741 TEST(fcvtzu) {
6742   SETUP();
6743 
6744   START();
6745   __ Fmov(s0, 1.0);
6746   __ Fmov(s1, 1.1);
6747   __ Fmov(s2, 1.5);
6748   __ Fmov(s3, -1.5);
6749   __ Fmov(s4, kFP32PositiveInfinity);
6750   __ Fmov(s5, kFP32NegativeInfinity);
6751   __ Fmov(s6, 0x7fffff80);                    // Largest float < INT32_MAX.
6752   __ Fneg(s7, s6);                            // Smallest float > INT32_MIN.
6753   __ Fmov(d8, 1.0);
6754   __ Fmov(d9, 1.1);
6755   __ Fmov(d10, 1.5);
6756   __ Fmov(d11, -1.5);
6757   __ Fmov(d12, kFP64PositiveInfinity);
6758   __ Fmov(d13, kFP64NegativeInfinity);
6759   __ Fmov(d14, kWMaxInt - 1);
6760   __ Fmov(d15, kWMinInt + 1);
6761   __ Fmov(s17, 1.1);
6762   __ Fmov(s18, 1.5);
6763   __ Fmov(s19, -1.5);
6764   __ Fmov(s20, kFP32PositiveInfinity);
6765   __ Fmov(s21, kFP32NegativeInfinity);
6766   __ Fmov(s22, 0x7fffff8000000000);           // Largest float < INT64_MAX.
6767   __ Fneg(s23, s22);                          // Smallest float > INT64_MIN.
6768   __ Fmov(d24, 1.1);
6769   __ Fmov(d25, 1.5);
6770   __ Fmov(d26, -1.5);
6771   __ Fmov(d27, kFP64PositiveInfinity);
6772   __ Fmov(d28, kFP64NegativeInfinity);
6773   __ Fmov(d29, 0x7ffffffffffffc00);           // Largest double < INT64_MAX.
6774   __ Fneg(d30, d29);                          // Smallest double > INT64_MIN.
6775 
6776   __ Fcvtzu(w0, s0);
6777   __ Fcvtzu(w1, s1);
6778   __ Fcvtzu(w2, s2);
6779   __ Fcvtzu(w3, s3);
6780   __ Fcvtzu(w4, s4);
6781   __ Fcvtzu(w5, s5);
6782   __ Fcvtzu(w6, s6);
6783   __ Fcvtzu(w7, s7);
6784   __ Fcvtzu(w8, d8);
6785   __ Fcvtzu(w9, d9);
6786   __ Fcvtzu(w10, d10);
6787   __ Fcvtzu(w11, d11);
6788   __ Fcvtzu(w12, d12);
6789   __ Fcvtzu(w13, d13);
6790   __ Fcvtzu(w14, d14);
6791   __ Fcvtzu(x17, s17);
6792   __ Fcvtzu(x18, s18);
6793   __ Fcvtzu(x19, s19);
6794   __ Fcvtzu(x20, s20);
6795   __ Fcvtzu(x21, s21);
6796   __ Fcvtzu(x22, s22);
6797   __ Fcvtzu(x23, s23);
6798   __ Fcvtzu(x24, d24);
6799   __ Fcvtzu(x25, d25);
6800   __ Fcvtzu(x26, d26);
6801   __ Fcvtzu(x27, d27);
6802   __ Fcvtzu(x28, d28);
6803   __ Fcvtzu(x29, d29);
6804   __ Fcvtzu(x30, d30);
6805   END();
6806 
6807   RUN();
6808 
6809   ASSERT_EQUAL_64(1, x0);
6810   ASSERT_EQUAL_64(1, x1);
6811   ASSERT_EQUAL_64(1, x2);
6812   ASSERT_EQUAL_64(0, x3);
6813   ASSERT_EQUAL_64(0xffffffff, x4);
6814   ASSERT_EQUAL_64(0, x5);
6815   ASSERT_EQUAL_64(0x7fffff80, x6);
6816   ASSERT_EQUAL_64(0, x7);
6817   ASSERT_EQUAL_64(1, x8);
6818   ASSERT_EQUAL_64(1, x9);
6819   ASSERT_EQUAL_64(1, x10);
6820   ASSERT_EQUAL_64(0, x11);
6821   ASSERT_EQUAL_64(0xffffffff, x12);
6822   ASSERT_EQUAL_64(0, x13);
6823   ASSERT_EQUAL_64(0x7ffffffe, x14);
6824   ASSERT_EQUAL_64(1, x17);
6825   ASSERT_EQUAL_64(1, x18);
6826   ASSERT_EQUAL_64(0, x19);
6827   ASSERT_EQUAL_64(0xffffffffffffffff, x20);
6828   ASSERT_EQUAL_64(0, x21);
6829   ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6830   ASSERT_EQUAL_64(0, x23);
6831   ASSERT_EQUAL_64(1, x24);
6832   ASSERT_EQUAL_64(1, x25);
6833   ASSERT_EQUAL_64(0, x26);
6834   ASSERT_EQUAL_64(0xffffffffffffffff, x27);
6835   ASSERT_EQUAL_64(0, x28);
6836   ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6837   ASSERT_EQUAL_64(0, x30);
6838 
6839   TEARDOWN();
6840 }
6841 
6842 
6843 // Test that scvtf and ucvtf can convert the 64-bit input into the expected
6844 // value. All possible values of 'fbits' are tested. The expected value is
6845 // modified accordingly in each case.
6846 //
6847 // The expected value is specified as the bit encoding of the expected double
6848 // produced by scvtf (expected_scvtf_bits) as well as ucvtf
6849 // (expected_ucvtf_bits).
6850 //
6851 // Where the input value is representable by int32_t or uint32_t, conversions
6852 // from W registers will also be tested.
TestUScvtfHelper(uint64_t in,uint64_t expected_scvtf_bits,uint64_t expected_ucvtf_bits)6853 static void TestUScvtfHelper(uint64_t in,
6854                              uint64_t expected_scvtf_bits,
6855                              uint64_t expected_ucvtf_bits) {
6856   uint64_t u64 = in;
6857   uint32_t u32 = u64 & 0xffffffff;
6858   int64_t s64 = static_cast<int64_t>(in);
6859   int32_t s32 = s64 & 0x7fffffff;
6860 
6861   bool cvtf_s32 = (s64 == s32);
6862   bool cvtf_u32 = (u64 == u32);
6863 
6864   double results_scvtf_x[65];
6865   double results_ucvtf_x[65];
6866   double results_scvtf_w[33];
6867   double results_ucvtf_w[33];
6868 
6869   SETUP();
6870   START();
6871 
6872   __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
6873   __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
6874   __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
6875   __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
6876 
6877   __ Mov(x10, s64);
6878 
6879   // Corrupt the top word, in case it is accidentally used during W-register
6880   // conversions.
6881   __ Mov(x11, 0x5555555555555555);
6882   __ Bfi(x11, x10, 0, kWRegSize);
6883 
6884   // Test integer conversions.
6885   __ Scvtf(d0, x10);
6886   __ Ucvtf(d1, x10);
6887   __ Scvtf(d2, w11);
6888   __ Ucvtf(d3, w11);
6889   __ Str(d0, MemOperand(x0));
6890   __ Str(d1, MemOperand(x1));
6891   __ Str(d2, MemOperand(x2));
6892   __ Str(d3, MemOperand(x3));
6893 
6894   // Test all possible values of fbits.
6895   for (int fbits = 1; fbits <= 32; fbits++) {
6896     __ Scvtf(d0, x10, fbits);
6897     __ Ucvtf(d1, x10, fbits);
6898     __ Scvtf(d2, w11, fbits);
6899     __ Ucvtf(d3, w11, fbits);
6900     __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
6901     __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
6902     __ Str(d2, MemOperand(x2, fbits * kDRegSizeInBytes));
6903     __ Str(d3, MemOperand(x3, fbits * kDRegSizeInBytes));
6904   }
6905 
6906   // Conversions from W registers can only handle fbits values <= 32, so just
6907   // test conversions from X registers for 32 < fbits <= 64.
6908   for (int fbits = 33; fbits <= 64; fbits++) {
6909     __ Scvtf(d0, x10, fbits);
6910     __ Ucvtf(d1, x10, fbits);
6911     __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
6912     __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
6913   }
6914 
6915   END();
6916   RUN();
6917 
6918   // Check the results.
6919   double expected_scvtf_base = rawbits_to_double(expected_scvtf_bits);
6920   double expected_ucvtf_base = rawbits_to_double(expected_ucvtf_bits);
6921 
6922   for (int fbits = 0; fbits <= 32; fbits++) {
6923     double expected_scvtf = expected_scvtf_base / pow(2, fbits);
6924     double expected_ucvtf = expected_ucvtf_base / pow(2, fbits);
6925     ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
6926     ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
6927     if (cvtf_s32) ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_w[fbits]);
6928     if (cvtf_u32) ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_w[fbits]);
6929   }
6930   for (int fbits = 33; fbits <= 64; fbits++) {
6931     double expected_scvtf = expected_scvtf_base / pow(2, fbits);
6932     double expected_ucvtf = expected_ucvtf_base / pow(2, fbits);
6933     ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
6934     ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
6935   }
6936 
6937   TEARDOWN();
6938 }
6939 
6940 
TEST(scvtf_ucvtf_double)6941 TEST(scvtf_ucvtf_double) {
6942   // Simple conversions of positive numbers which require no rounding; the
6943   // results should not depened on the rounding mode, and ucvtf and scvtf should
6944   // produce the same result.
6945   TestUScvtfHelper(0x0000000000000000, 0x0000000000000000, 0x0000000000000000);
6946   TestUScvtfHelper(0x0000000000000001, 0x3ff0000000000000, 0x3ff0000000000000);
6947   TestUScvtfHelper(0x0000000040000000, 0x41d0000000000000, 0x41d0000000000000);
6948   TestUScvtfHelper(0x0000000100000000, 0x41f0000000000000, 0x41f0000000000000);
6949   TestUScvtfHelper(0x4000000000000000, 0x43d0000000000000, 0x43d0000000000000);
6950   // Test mantissa extremities.
6951   TestUScvtfHelper(0x4000000000000400, 0x43d0000000000001, 0x43d0000000000001);
6952   // The largest int32_t that fits in a double.
6953   TestUScvtfHelper(0x000000007fffffff, 0x41dfffffffc00000, 0x41dfffffffc00000);
6954   // Values that would be negative if treated as an int32_t.
6955   TestUScvtfHelper(0x00000000ffffffff, 0x41efffffffe00000, 0x41efffffffe00000);
6956   TestUScvtfHelper(0x0000000080000000, 0x41e0000000000000, 0x41e0000000000000);
6957   TestUScvtfHelper(0x0000000080000001, 0x41e0000000200000, 0x41e0000000200000);
6958   // The largest int64_t that fits in a double.
6959   TestUScvtfHelper(0x7ffffffffffffc00, 0x43dfffffffffffff, 0x43dfffffffffffff);
6960   // Check for bit pattern reproduction.
6961   TestUScvtfHelper(0x0123456789abcde0, 0x43723456789abcde, 0x43723456789abcde);
6962   TestUScvtfHelper(0x0000000012345678, 0x41b2345678000000, 0x41b2345678000000);
6963 
6964   // Simple conversions of negative int64_t values. These require no rounding,
6965   // and the results should not depend on the rounding mode.
6966   TestUScvtfHelper(0xffffffffc0000000, 0xc1d0000000000000, 0x43effffffff80000);
6967   TestUScvtfHelper(0xffffffff00000000, 0xc1f0000000000000, 0x43efffffffe00000);
6968   TestUScvtfHelper(0xc000000000000000, 0xc3d0000000000000, 0x43e8000000000000);
6969 
6970   // Conversions which require rounding.
6971   TestUScvtfHelper(0x1000000000000000, 0x43b0000000000000, 0x43b0000000000000);
6972   TestUScvtfHelper(0x1000000000000001, 0x43b0000000000000, 0x43b0000000000000);
6973   TestUScvtfHelper(0x1000000000000080, 0x43b0000000000000, 0x43b0000000000000);
6974   TestUScvtfHelper(0x1000000000000081, 0x43b0000000000001, 0x43b0000000000001);
6975   TestUScvtfHelper(0x1000000000000100, 0x43b0000000000001, 0x43b0000000000001);
6976   TestUScvtfHelper(0x1000000000000101, 0x43b0000000000001, 0x43b0000000000001);
6977   TestUScvtfHelper(0x1000000000000180, 0x43b0000000000002, 0x43b0000000000002);
6978   TestUScvtfHelper(0x1000000000000181, 0x43b0000000000002, 0x43b0000000000002);
6979   TestUScvtfHelper(0x1000000000000200, 0x43b0000000000002, 0x43b0000000000002);
6980   TestUScvtfHelper(0x1000000000000201, 0x43b0000000000002, 0x43b0000000000002);
6981   TestUScvtfHelper(0x1000000000000280, 0x43b0000000000002, 0x43b0000000000002);
6982   TestUScvtfHelper(0x1000000000000281, 0x43b0000000000003, 0x43b0000000000003);
6983   TestUScvtfHelper(0x1000000000000300, 0x43b0000000000003, 0x43b0000000000003);
6984   // Check rounding of negative int64_t values (and large uint64_t values).
6985   TestUScvtfHelper(0x8000000000000000, 0xc3e0000000000000, 0x43e0000000000000);
6986   TestUScvtfHelper(0x8000000000000001, 0xc3e0000000000000, 0x43e0000000000000);
6987   TestUScvtfHelper(0x8000000000000200, 0xc3e0000000000000, 0x43e0000000000000);
6988   TestUScvtfHelper(0x8000000000000201, 0xc3dfffffffffffff, 0x43e0000000000000);
6989   TestUScvtfHelper(0x8000000000000400, 0xc3dfffffffffffff, 0x43e0000000000000);
6990   TestUScvtfHelper(0x8000000000000401, 0xc3dfffffffffffff, 0x43e0000000000001);
6991   TestUScvtfHelper(0x8000000000000600, 0xc3dffffffffffffe, 0x43e0000000000001);
6992   TestUScvtfHelper(0x8000000000000601, 0xc3dffffffffffffe, 0x43e0000000000001);
6993   TestUScvtfHelper(0x8000000000000800, 0xc3dffffffffffffe, 0x43e0000000000001);
6994   TestUScvtfHelper(0x8000000000000801, 0xc3dffffffffffffe, 0x43e0000000000001);
6995   TestUScvtfHelper(0x8000000000000a00, 0xc3dffffffffffffe, 0x43e0000000000001);
6996   TestUScvtfHelper(0x8000000000000a01, 0xc3dffffffffffffd, 0x43e0000000000001);
6997   TestUScvtfHelper(0x8000000000000c00, 0xc3dffffffffffffd, 0x43e0000000000002);
6998   // Round up to produce a result that's too big for the input to represent.
6999   TestUScvtfHelper(0x7ffffffffffffe00, 0x43e0000000000000, 0x43e0000000000000);
7000   TestUScvtfHelper(0x7fffffffffffffff, 0x43e0000000000000, 0x43e0000000000000);
7001   TestUScvtfHelper(0xfffffffffffffc00, 0xc090000000000000, 0x43f0000000000000);
7002   TestUScvtfHelper(0xffffffffffffffff, 0xbff0000000000000, 0x43f0000000000000);
7003 }
7004 
7005 
7006 // The same as TestUScvtfHelper, but convert to floats.
TestUScvtf32Helper(uint64_t in,uint32_t expected_scvtf_bits,uint32_t expected_ucvtf_bits)7007 static void TestUScvtf32Helper(uint64_t in,
7008                                uint32_t expected_scvtf_bits,
7009                                uint32_t expected_ucvtf_bits) {
7010   uint64_t u64 = in;
7011   uint32_t u32 = u64 & 0xffffffff;
7012   int64_t s64 = static_cast<int64_t>(in);
7013   int32_t s32 = s64 & 0x7fffffff;
7014 
7015   bool cvtf_s32 = (s64 == s32);
7016   bool cvtf_u32 = (u64 == u32);
7017 
7018   float results_scvtf_x[65];
7019   float results_ucvtf_x[65];
7020   float results_scvtf_w[33];
7021   float results_ucvtf_w[33];
7022 
7023   SETUP();
7024   START();
7025 
7026   __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
7027   __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
7028   __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
7029   __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
7030 
7031   __ Mov(x10, s64);
7032 
7033   // Corrupt the top word, in case it is accidentally used during W-register
7034   // conversions.
7035   __ Mov(x11, 0x5555555555555555);
7036   __ Bfi(x11, x10, 0, kWRegSize);
7037 
7038   // Test integer conversions.
7039   __ Scvtf(s0, x10);
7040   __ Ucvtf(s1, x10);
7041   __ Scvtf(s2, w11);
7042   __ Ucvtf(s3, w11);
7043   __ Str(s0, MemOperand(x0));
7044   __ Str(s1, MemOperand(x1));
7045   __ Str(s2, MemOperand(x2));
7046   __ Str(s3, MemOperand(x3));
7047 
7048   // Test all possible values of fbits.
7049   for (int fbits = 1; fbits <= 32; fbits++) {
7050     __ Scvtf(s0, x10, fbits);
7051     __ Ucvtf(s1, x10, fbits);
7052     __ Scvtf(s2, w11, fbits);
7053     __ Ucvtf(s3, w11, fbits);
7054     __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
7055     __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
7056     __ Str(s2, MemOperand(x2, fbits * kSRegSizeInBytes));
7057     __ Str(s3, MemOperand(x3, fbits * kSRegSizeInBytes));
7058   }
7059 
7060   // Conversions from W registers can only handle fbits values <= 32, so just
7061   // test conversions from X registers for 32 < fbits <= 64.
7062   for (int fbits = 33; fbits <= 64; fbits++) {
7063     __ Scvtf(s0, x10, fbits);
7064     __ Ucvtf(s1, x10, fbits);
7065     __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
7066     __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
7067   }
7068 
7069   END();
7070   RUN();
7071 
7072   // Check the results.
7073   float expected_scvtf_base = rawbits_to_float(expected_scvtf_bits);
7074   float expected_ucvtf_base = rawbits_to_float(expected_ucvtf_bits);
7075 
7076   for (int fbits = 0; fbits <= 32; fbits++) {
7077     float expected_scvtf = expected_scvtf_base / powf(2, fbits);
7078     float expected_ucvtf = expected_ucvtf_base / powf(2, fbits);
7079     ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
7080     ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
7081     if (cvtf_s32) ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_w[fbits]);
7082     if (cvtf_u32) ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_w[fbits]);
7083     break;
7084   }
7085   for (int fbits = 33; fbits <= 64; fbits++) {
7086     break;
7087     float expected_scvtf = expected_scvtf_base / powf(2, fbits);
7088     float expected_ucvtf = expected_ucvtf_base / powf(2, fbits);
7089     ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
7090     ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
7091   }
7092 
7093   TEARDOWN();
7094 }
7095 
7096 
TEST(scvtf_ucvtf_float)7097 TEST(scvtf_ucvtf_float) {
7098   // Simple conversions of positive numbers which require no rounding; the
7099   // results should not depened on the rounding mode, and ucvtf and scvtf should
7100   // produce the same result.
7101   TestUScvtf32Helper(0x0000000000000000, 0x00000000, 0x00000000);
7102   TestUScvtf32Helper(0x0000000000000001, 0x3f800000, 0x3f800000);
7103   TestUScvtf32Helper(0x0000000040000000, 0x4e800000, 0x4e800000);
7104   TestUScvtf32Helper(0x0000000100000000, 0x4f800000, 0x4f800000);
7105   TestUScvtf32Helper(0x4000000000000000, 0x5e800000, 0x5e800000);
7106   // Test mantissa extremities.
7107   TestUScvtf32Helper(0x0000000000800001, 0x4b000001, 0x4b000001);
7108   TestUScvtf32Helper(0x4000008000000000, 0x5e800001, 0x5e800001);
7109   // The largest int32_t that fits in a float.
7110   TestUScvtf32Helper(0x000000007fffff80, 0x4effffff, 0x4effffff);
7111   // Values that would be negative if treated as an int32_t.
7112   TestUScvtf32Helper(0x00000000ffffff00, 0x4f7fffff, 0x4f7fffff);
7113   TestUScvtf32Helper(0x0000000080000000, 0x4f000000, 0x4f000000);
7114   TestUScvtf32Helper(0x0000000080000100, 0x4f000001, 0x4f000001);
7115   // The largest int64_t that fits in a float.
7116   TestUScvtf32Helper(0x7fffff8000000000, 0x5effffff, 0x5effffff);
7117   // Check for bit pattern reproduction.
7118   TestUScvtf32Helper(0x0000000000876543, 0x4b076543, 0x4b076543);
7119 
7120   // Simple conversions of negative int64_t values. These require no rounding,
7121   // and the results should not depend on the rounding mode.
7122   TestUScvtf32Helper(0xfffffc0000000000, 0xd4800000, 0x5f7ffffc);
7123   TestUScvtf32Helper(0xc000000000000000, 0xde800000, 0x5f400000);
7124 
7125   // Conversions which require rounding.
7126   TestUScvtf32Helper(0x0000800000000000, 0x57000000, 0x57000000);
7127   TestUScvtf32Helper(0x0000800000000001, 0x57000000, 0x57000000);
7128   TestUScvtf32Helper(0x0000800000800000, 0x57000000, 0x57000000);
7129   TestUScvtf32Helper(0x0000800000800001, 0x57000001, 0x57000001);
7130   TestUScvtf32Helper(0x0000800001000000, 0x57000001, 0x57000001);
7131   TestUScvtf32Helper(0x0000800001000001, 0x57000001, 0x57000001);
7132   TestUScvtf32Helper(0x0000800001800000, 0x57000002, 0x57000002);
7133   TestUScvtf32Helper(0x0000800001800001, 0x57000002, 0x57000002);
7134   TestUScvtf32Helper(0x0000800002000000, 0x57000002, 0x57000002);
7135   TestUScvtf32Helper(0x0000800002000001, 0x57000002, 0x57000002);
7136   TestUScvtf32Helper(0x0000800002800000, 0x57000002, 0x57000002);
7137   TestUScvtf32Helper(0x0000800002800001, 0x57000003, 0x57000003);
7138   TestUScvtf32Helper(0x0000800003000000, 0x57000003, 0x57000003);
7139   // Check rounding of negative int64_t values (and large uint64_t values).
7140   TestUScvtf32Helper(0x8000000000000000, 0xdf000000, 0x5f000000);
7141   TestUScvtf32Helper(0x8000000000000001, 0xdf000000, 0x5f000000);
7142   TestUScvtf32Helper(0x8000004000000000, 0xdf000000, 0x5f000000);
7143   TestUScvtf32Helper(0x8000004000000001, 0xdeffffff, 0x5f000000);
7144   TestUScvtf32Helper(0x8000008000000000, 0xdeffffff, 0x5f000000);
7145   TestUScvtf32Helper(0x8000008000000001, 0xdeffffff, 0x5f000001);
7146   TestUScvtf32Helper(0x800000c000000000, 0xdefffffe, 0x5f000001);
7147   TestUScvtf32Helper(0x800000c000000001, 0xdefffffe, 0x5f000001);
7148   TestUScvtf32Helper(0x8000010000000000, 0xdefffffe, 0x5f000001);
7149   TestUScvtf32Helper(0x8000010000000001, 0xdefffffe, 0x5f000001);
7150   TestUScvtf32Helper(0x8000014000000000, 0xdefffffe, 0x5f000001);
7151   TestUScvtf32Helper(0x8000014000000001, 0xdefffffd, 0x5f000001);
7152   TestUScvtf32Helper(0x8000018000000000, 0xdefffffd, 0x5f000002);
7153   // Round up to produce a result that's too big for the input to represent.
7154   TestUScvtf32Helper(0x000000007fffffc0, 0x4f000000, 0x4f000000);
7155   TestUScvtf32Helper(0x000000007fffffff, 0x4f000000, 0x4f000000);
7156   TestUScvtf32Helper(0x00000000ffffff80, 0x4f800000, 0x4f800000);
7157   TestUScvtf32Helper(0x00000000ffffffff, 0x4f800000, 0x4f800000);
7158   TestUScvtf32Helper(0x7fffffc000000000, 0x5f000000, 0x5f000000);
7159   TestUScvtf32Helper(0x7fffffffffffffff, 0x5f000000, 0x5f000000);
7160   TestUScvtf32Helper(0xffffff8000000000, 0xd3000000, 0x5f800000);
7161   TestUScvtf32Helper(0xffffffffffffffff, 0xbf800000, 0x5f800000);
7162 }
7163 
7164 
TEST(system_mrs)7165 TEST(system_mrs) {
7166   SETUP();
7167 
7168   START();
7169   __ Mov(w0, 0);
7170   __ Mov(w1, 1);
7171   __ Mov(w2, 0x80000000);
7172 
7173   // Set the Z and C flags.
7174   __ Cmp(w0, w0);
7175   __ Mrs(x3, NZCV);
7176 
7177   // Set the N flag.
7178   __ Cmp(w0, w1);
7179   __ Mrs(x4, NZCV);
7180 
7181   // Set the Z, C and V flags.
7182   __ Adds(w0, w2, w2);
7183   __ Mrs(x5, NZCV);
7184 
7185   // Read the default FPCR.
7186   __ Mrs(x6, FPCR);
7187   END();
7188 
7189   RUN();
7190 
7191   // NZCV
7192   ASSERT_EQUAL_32(ZCFlag, w3);
7193   ASSERT_EQUAL_32(NFlag, w4);
7194   ASSERT_EQUAL_32(ZCVFlag, w5);
7195 
7196   // FPCR
7197   // The default FPCR on Linux-based platforms is 0.
7198   ASSERT_EQUAL_32(0, w6);
7199 
7200   TEARDOWN();
7201 }
7202 
7203 
TEST(system_msr)7204 TEST(system_msr) {
7205   // All FPCR fields that must be implemented: AHP, DN, FZ, RMode
7206   const uint64_t fpcr_core = 0x07c00000;
7207 
7208   // All FPCR fields (including fields which may be read-as-zero):
7209   //  Stride, Len
7210   //  IDE, IXE, UFE, OFE, DZE, IOE
7211   const uint64_t fpcr_all = fpcr_core | 0x00379f00;
7212 
7213   SETUP();
7214 
7215   START();
7216   __ Mov(w0, 0);
7217   __ Mov(w1, 0x7fffffff);
7218 
7219   __ Mov(x7, 0);
7220 
7221   __ Mov(x10, NVFlag);
7222   __ Cmp(w0, w0);     // Set Z and C.
7223   __ Msr(NZCV, x10);  // Set N and V.
7224   // The Msr should have overwritten every flag set by the Cmp.
7225   __ Cinc(x7, x7, mi);  // N
7226   __ Cinc(x7, x7, ne);  // !Z
7227   __ Cinc(x7, x7, lo);  // !C
7228   __ Cinc(x7, x7, vs);  // V
7229 
7230   __ Mov(x10, ZCFlag);
7231   __ Cmn(w1, w1);     // Set N and V.
7232   __ Msr(NZCV, x10);  // Set Z and C.
7233   // The Msr should have overwritten every flag set by the Cmn.
7234   __ Cinc(x7, x7, pl);  // !N
7235   __ Cinc(x7, x7, eq);  // Z
7236   __ Cinc(x7, x7, hs);  // C
7237   __ Cinc(x7, x7, vc);  // !V
7238 
7239   // All core FPCR fields must be writable.
7240   __ Mov(x8, fpcr_core);
7241   __ Msr(FPCR, x8);
7242   __ Mrs(x8, FPCR);
7243 
7244   // All FPCR fields, including optional ones. This part of the test doesn't
7245   // achieve much other than ensuring that supported fields can be cleared by
7246   // the next test.
7247   __ Mov(x9, fpcr_all);
7248   __ Msr(FPCR, x9);
7249   __ Mrs(x9, FPCR);
7250   __ And(x9, x9, fpcr_core);
7251 
7252   // The undefined bits must ignore writes.
7253   // It's conceivable that a future version of the architecture could use these
7254   // fields (making this test fail), but in the meantime this is a useful test
7255   // for the simulator.
7256   __ Mov(x10, ~fpcr_all);
7257   __ Msr(FPCR, x10);
7258   __ Mrs(x10, FPCR);
7259 
7260   END();
7261 
7262   RUN();
7263 
7264   // We should have incremented x7 (from 0) exactly 8 times.
7265   ASSERT_EQUAL_64(8, x7);
7266 
7267   ASSERT_EQUAL_64(fpcr_core, x8);
7268   ASSERT_EQUAL_64(fpcr_core, x9);
7269   ASSERT_EQUAL_64(0, x10);
7270 
7271   TEARDOWN();
7272 }
7273 
7274 
TEST(system_nop)7275 TEST(system_nop) {
7276   SETUP();
7277   RegisterDump before;
7278 
7279   START();
7280   before.Dump(&masm);
7281   __ Nop();
7282   END();
7283 
7284   RUN();
7285 
7286   ASSERT_EQUAL_REGISTERS(before);
7287   ASSERT_EQUAL_NZCV(before.flags_nzcv());
7288 
7289   TEARDOWN();
7290 }
7291 
7292 
TEST(zero_dest)7293 TEST(zero_dest) {
7294   SETUP();
7295   RegisterDump before;
7296 
7297   START();
7298   // Preserve the stack pointer, in case we clobber it.
7299   __ Mov(x30, sp);
7300   // Initialize the other registers used in this test.
7301   uint64_t literal_base = 0x0100001000100101;
7302   __ Mov(x0, 0);
7303   __ Mov(x1, literal_base);
7304   for (unsigned i = 2; i < x30.code(); i++) {
7305     __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
7306   }
7307   before.Dump(&masm);
7308 
7309   // All of these instructions should be NOPs in these forms, but have
7310   // alternate forms which can write into the stack pointer.
7311   __ add(xzr, x0, x1);
7312   __ add(xzr, x1, xzr);
7313   __ add(xzr, xzr, x1);
7314 
7315   __ and_(xzr, x0, x2);
7316   __ and_(xzr, x2, xzr);
7317   __ and_(xzr, xzr, x2);
7318 
7319   __ bic(xzr, x0, x3);
7320   __ bic(xzr, x3, xzr);
7321   __ bic(xzr, xzr, x3);
7322 
7323   __ eon(xzr, x0, x4);
7324   __ eon(xzr, x4, xzr);
7325   __ eon(xzr, xzr, x4);
7326 
7327   __ eor(xzr, x0, x5);
7328   __ eor(xzr, x5, xzr);
7329   __ eor(xzr, xzr, x5);
7330 
7331   __ orr(xzr, x0, x6);
7332   __ orr(xzr, x6, xzr);
7333   __ orr(xzr, xzr, x6);
7334 
7335   __ sub(xzr, x0, x7);
7336   __ sub(xzr, x7, xzr);
7337   __ sub(xzr, xzr, x7);
7338 
7339   // Swap the saved stack pointer with the real one. If sp was written
7340   // during the test, it will show up in x30. This is done because the test
7341   // framework assumes that sp will be valid at the end of the test.
7342   __ Mov(x29, x30);
7343   __ Mov(x30, sp);
7344   __ Mov(sp, x29);
7345   // We used x29 as a scratch register, so reset it to make sure it doesn't
7346   // trigger a test failure.
7347   __ Add(x29, x28, x1);
7348   END();
7349 
7350   RUN();
7351 
7352   ASSERT_EQUAL_REGISTERS(before);
7353   ASSERT_EQUAL_NZCV(before.flags_nzcv());
7354 
7355   TEARDOWN();
7356 }
7357 
7358 
TEST(zero_dest_setflags)7359 TEST(zero_dest_setflags) {
7360   SETUP();
7361   RegisterDump before;
7362 
7363   START();
7364   // Preserve the stack pointer, in case we clobber it.
7365   __ Mov(x30, sp);
7366   // Initialize the other registers used in this test.
7367   uint64_t literal_base = 0x0100001000100101;
7368   __ Mov(x0, 0);
7369   __ Mov(x1, literal_base);
7370   for (int i = 2; i < 30; i++) {
7371     __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
7372   }
7373   before.Dump(&masm);
7374 
7375   // All of these instructions should only write to the flags in these forms,
7376   // but have alternate forms which can write into the stack pointer.
7377   __ adds(xzr, x0, Operand(x1, UXTX));
7378   __ adds(xzr, x1, Operand(xzr, UXTX));
7379   __ adds(xzr, x1, 1234);
7380   __ adds(xzr, x0, x1);
7381   __ adds(xzr, x1, xzr);
7382   __ adds(xzr, xzr, x1);
7383 
7384   __ ands(xzr, x2, ~0xf);
7385   __ ands(xzr, xzr, ~0xf);
7386   __ ands(xzr, x0, x2);
7387   __ ands(xzr, x2, xzr);
7388   __ ands(xzr, xzr, x2);
7389 
7390   __ bics(xzr, x3, ~0xf);
7391   __ bics(xzr, xzr, ~0xf);
7392   __ bics(xzr, x0, x3);
7393   __ bics(xzr, x3, xzr);
7394   __ bics(xzr, xzr, x3);
7395 
7396   __ subs(xzr, x0, Operand(x3, UXTX));
7397   __ subs(xzr, x3, Operand(xzr, UXTX));
7398   __ subs(xzr, x3, 1234);
7399   __ subs(xzr, x0, x3);
7400   __ subs(xzr, x3, xzr);
7401   __ subs(xzr, xzr, x3);
7402 
7403   // Swap the saved stack pointer with the real one. If sp was written
7404   // during the test, it will show up in x30. This is done because the test
7405   // framework assumes that sp will be valid at the end of the test.
7406   __ Mov(x29, x30);
7407   __ Mov(x30, sp);
7408   __ Mov(sp, x29);
7409   // We used x29 as a scratch register, so reset it to make sure it doesn't
7410   // trigger a test failure.
7411   __ Add(x29, x28, x1);
7412   END();
7413 
7414   RUN();
7415 
7416   ASSERT_EQUAL_REGISTERS(before);
7417 
7418   TEARDOWN();
7419 }
7420 
7421 
TEST(register_bit)7422 TEST(register_bit) {
7423   // No code generation takes place in this test, so no need to setup and
7424   // teardown.
7425 
7426   // Simple tests.
7427   assert(x0.Bit() == (UINT64_C(1) << 0));
7428   assert(x1.Bit() == (UINT64_C(1) << 1));
7429   assert(x10.Bit() == (UINT64_C(1) << 10));
7430 
7431   // AAPCS64 definitions.
7432   assert(lr.Bit() == (UINT64_C(1) << kLinkRegCode));
7433 
7434   // Fixed (hardware) definitions.
7435   assert(xzr.Bit() == (UINT64_C(1) << kZeroRegCode));
7436 
7437   // Internal ABI definitions.
7438   assert(sp.Bit() == (UINT64_C(1) << kSPRegInternalCode));
7439   assert(sp.Bit() != xzr.Bit());
7440 
7441   // xn.Bit() == wn.Bit() at all times, for the same n.
7442   assert(x0.Bit() == w0.Bit());
7443   assert(x1.Bit() == w1.Bit());
7444   assert(x10.Bit() == w10.Bit());
7445   assert(xzr.Bit() == wzr.Bit());
7446   assert(sp.Bit() == wsp.Bit());
7447 }
7448 
7449 
TEST(stack_pointer_override)7450 TEST(stack_pointer_override) {
7451   // This test generates some stack maintenance code, but the test only checks
7452   // the reported state.
7453   SETUP();
7454   START();
7455 
7456   // The default stack pointer in VIXL is sp.
7457   assert(sp.Is(__ StackPointer()));
7458   __ SetStackPointer(x0);
7459   assert(x0.Is(__ StackPointer()));
7460   __ SetStackPointer(x28);
7461   assert(x28.Is(__ StackPointer()));
7462   __ SetStackPointer(sp);
7463   assert(sp.Is(__ StackPointer()));
7464 
7465   END();
7466   RUN();
7467   TEARDOWN();
7468 }
7469 
7470 
TEST(peek_poke_simple)7471 TEST(peek_poke_simple) {
7472   SETUP();
7473   START();
7474 
7475   static const RegList x0_to_x3 = x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit();
7476   static const RegList x10_to_x13 = x10.Bit() | x11.Bit() |
7477                                     x12.Bit() | x13.Bit();
7478 
7479   // The literal base is chosen to have two useful properties:
7480   //  * When multiplied by small values (such as a register index), this value
7481   //    is clearly readable in the result.
7482   //  * The value is not formed from repeating fixed-size smaller values, so it
7483   //    can be used to detect endianness-related errors.
7484   uint64_t literal_base = 0x0100001000100101;
7485 
7486   // Initialize the registers.
7487   __ Mov(x0, literal_base);
7488   __ Add(x1, x0, x0);
7489   __ Add(x2, x1, x0);
7490   __ Add(x3, x2, x0);
7491 
7492   __ Claim(32);
7493 
7494   // Simple exchange.
7495   //  After this test:
7496   //    x0-x3 should be unchanged.
7497   //    w10-w13 should contain the lower words of x0-x3.
7498   __ Poke(x0, 0);
7499   __ Poke(x1, 8);
7500   __ Poke(x2, 16);
7501   __ Poke(x3, 24);
7502   Clobber(&masm, x0_to_x3);
7503   __ Peek(x0, 0);
7504   __ Peek(x1, 8);
7505   __ Peek(x2, 16);
7506   __ Peek(x3, 24);
7507 
7508   __ Poke(w0, 0);
7509   __ Poke(w1, 4);
7510   __ Poke(w2, 8);
7511   __ Poke(w3, 12);
7512   Clobber(&masm, x10_to_x13);
7513   __ Peek(w10, 0);
7514   __ Peek(w11, 4);
7515   __ Peek(w12, 8);
7516   __ Peek(w13, 12);
7517 
7518   __ Drop(32);
7519 
7520   END();
7521   RUN();
7522 
7523   ASSERT_EQUAL_64(literal_base * 1, x0);
7524   ASSERT_EQUAL_64(literal_base * 2, x1);
7525   ASSERT_EQUAL_64(literal_base * 3, x2);
7526   ASSERT_EQUAL_64(literal_base * 4, x3);
7527 
7528   ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
7529   ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
7530   ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
7531   ASSERT_EQUAL_64((literal_base * 4) & 0xffffffff, x13);
7532 
7533   TEARDOWN();
7534 }
7535 
7536 
TEST(peek_poke_unaligned)7537 TEST(peek_poke_unaligned) {
7538   SETUP();
7539   START();
7540 
7541   // The literal base is chosen to have two useful properties:
7542   //  * When multiplied by small values (such as a register index), this value
7543   //    is clearly readable in the result.
7544   //  * The value is not formed from repeating fixed-size smaller values, so it
7545   //    can be used to detect endianness-related errors.
7546   uint64_t literal_base = 0x0100001000100101;
7547 
7548   // Initialize the registers.
7549   __ Mov(x0, literal_base);
7550   __ Add(x1, x0, x0);
7551   __ Add(x2, x1, x0);
7552   __ Add(x3, x2, x0);
7553   __ Add(x4, x3, x0);
7554   __ Add(x5, x4, x0);
7555   __ Add(x6, x5, x0);
7556 
7557   __ Claim(32);
7558 
7559   // Unaligned exchanges.
7560   //  After this test:
7561   //    x0-x6 should be unchanged.
7562   //    w10-w12 should contain the lower words of x0-x2.
7563   __ Poke(x0, 1);
7564   Clobber(&masm, x0.Bit());
7565   __ Peek(x0, 1);
7566   __ Poke(x1, 2);
7567   Clobber(&masm, x1.Bit());
7568   __ Peek(x1, 2);
7569   __ Poke(x2, 3);
7570   Clobber(&masm, x2.Bit());
7571   __ Peek(x2, 3);
7572   __ Poke(x3, 4);
7573   Clobber(&masm, x3.Bit());
7574   __ Peek(x3, 4);
7575   __ Poke(x4, 5);
7576   Clobber(&masm, x4.Bit());
7577   __ Peek(x4, 5);
7578   __ Poke(x5, 6);
7579   Clobber(&masm, x5.Bit());
7580   __ Peek(x5, 6);
7581   __ Poke(x6, 7);
7582   Clobber(&masm, x6.Bit());
7583   __ Peek(x6, 7);
7584 
7585   __ Poke(w0, 1);
7586   Clobber(&masm, w10.Bit());
7587   __ Peek(w10, 1);
7588   __ Poke(w1, 2);
7589   Clobber(&masm, w11.Bit());
7590   __ Peek(w11, 2);
7591   __ Poke(w2, 3);
7592   Clobber(&masm, w12.Bit());
7593   __ Peek(w12, 3);
7594 
7595   __ Drop(32);
7596 
7597   END();
7598   RUN();
7599 
7600   ASSERT_EQUAL_64(literal_base * 1, x0);
7601   ASSERT_EQUAL_64(literal_base * 2, x1);
7602   ASSERT_EQUAL_64(literal_base * 3, x2);
7603   ASSERT_EQUAL_64(literal_base * 4, x3);
7604   ASSERT_EQUAL_64(literal_base * 5, x4);
7605   ASSERT_EQUAL_64(literal_base * 6, x5);
7606   ASSERT_EQUAL_64(literal_base * 7, x6);
7607 
7608   ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
7609   ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
7610   ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
7611 
7612   TEARDOWN();
7613 }
7614 
7615 
TEST(peek_poke_endianness)7616 TEST(peek_poke_endianness) {
7617   SETUP();
7618   START();
7619 
7620   // The literal base is chosen to have two useful properties:
7621   //  * When multiplied by small values (such as a register index), this value
7622   //    is clearly readable in the result.
7623   //  * The value is not formed from repeating fixed-size smaller values, so it
7624   //    can be used to detect endianness-related errors.
7625   uint64_t literal_base = 0x0100001000100101;
7626 
7627   // Initialize the registers.
7628   __ Mov(x0, literal_base);
7629   __ Add(x1, x0, x0);
7630 
7631   __ Claim(32);
7632 
7633   // Endianness tests.
7634   //  After this section:
7635   //    x4 should match x0[31:0]:x0[63:32]
7636   //    w5 should match w1[15:0]:w1[31:16]
7637   __ Poke(x0, 0);
7638   __ Poke(x0, 8);
7639   __ Peek(x4, 4);
7640 
7641   __ Poke(w1, 0);
7642   __ Poke(w1, 4);
7643   __ Peek(w5, 2);
7644 
7645   __ Drop(32);
7646 
7647   END();
7648   RUN();
7649 
7650   uint64_t x0_expected = literal_base * 1;
7651   uint64_t x1_expected = literal_base * 2;
7652   uint64_t x4_expected = (x0_expected << 32) | (x0_expected >> 32);
7653   uint64_t x5_expected = ((x1_expected << 16) & 0xffff0000) |
7654                          ((x1_expected >> 16) & 0x0000ffff);
7655 
7656   ASSERT_EQUAL_64(x0_expected, x0);
7657   ASSERT_EQUAL_64(x1_expected, x1);
7658   ASSERT_EQUAL_64(x4_expected, x4);
7659   ASSERT_EQUAL_64(x5_expected, x5);
7660 
7661   TEARDOWN();
7662 }
7663 
7664 
TEST(peek_poke_mixed)7665 TEST(peek_poke_mixed) {
7666   SETUP();
7667   START();
7668 
7669   // The literal base is chosen to have two useful properties:
7670   //  * When multiplied by small values (such as a register index), this value
7671   //    is clearly readable in the result.
7672   //  * The value is not formed from repeating fixed-size smaller values, so it
7673   //    can be used to detect endianness-related errors.
7674   uint64_t literal_base = 0x0100001000100101;
7675 
7676   // Initialize the registers.
7677   __ Mov(x0, literal_base);
7678   __ Add(x1, x0, x0);
7679   __ Add(x2, x1, x0);
7680   __ Add(x3, x2, x0);
7681 
7682   __ Claim(32);
7683 
7684   // Mix with other stack operations.
7685   //  After this section:
7686   //    x0-x3 should be unchanged.
7687   //    x6 should match x1[31:0]:x0[63:32]
7688   //    w7 should match x1[15:0]:x0[63:48]
7689   __ Poke(x1, 8);
7690   __ Poke(x0, 0);
7691   {
7692     VIXL_ASSERT(__ StackPointer().Is(sp));
7693     __ Mov(x4, __ StackPointer());
7694     __ SetStackPointer(x4);
7695 
7696     __ Poke(wzr, 0);    // Clobber the space we're about to drop.
7697     __ Drop(4);
7698     __ Peek(x6, 0);
7699     __ Claim(8);
7700     __ Peek(w7, 10);
7701     __ Poke(x3, 28);
7702     __ Poke(xzr, 0);    // Clobber the space we're about to drop.
7703     __ Drop(8);
7704     __ Poke(x2, 12);
7705     __ Push(w0);
7706 
7707     __ Mov(sp, __ StackPointer());
7708     __ SetStackPointer(sp);
7709   }
7710 
7711   __ Pop(x0, x1, x2, x3);
7712 
7713   END();
7714   RUN();
7715 
7716   uint64_t x0_expected = literal_base * 1;
7717   uint64_t x1_expected = literal_base * 2;
7718   uint64_t x2_expected = literal_base * 3;
7719   uint64_t x3_expected = literal_base * 4;
7720   uint64_t x6_expected = (x1_expected << 32) | (x0_expected >> 32);
7721   uint64_t x7_expected = ((x1_expected << 16) & 0xffff0000) |
7722                          ((x0_expected >> 48) & 0x0000ffff);
7723 
7724   ASSERT_EQUAL_64(x0_expected, x0);
7725   ASSERT_EQUAL_64(x1_expected, x1);
7726   ASSERT_EQUAL_64(x2_expected, x2);
7727   ASSERT_EQUAL_64(x3_expected, x3);
7728   ASSERT_EQUAL_64(x6_expected, x6);
7729   ASSERT_EQUAL_64(x7_expected, x7);
7730 
7731   TEARDOWN();
7732 }
7733 
7734 
7735 // This enum is used only as an argument to the push-pop test helpers.
7736 enum PushPopMethod {
7737   // Push or Pop using the Push and Pop methods, with blocks of up to four
7738   // registers. (Smaller blocks will be used if necessary.)
7739   PushPopByFour,
7740 
7741   // Use Push<Size>RegList and Pop<Size>RegList to transfer the registers.
7742   PushPopRegList
7743 };
7744 
7745 
7746 // The maximum number of registers that can be used by the PushPopXReg* tests,
7747 // where a reg_count field is provided.
7748 static int const kPushPopXRegMaxRegCount = -1;
7749 
7750 // Test a simple push-pop pattern:
7751 //  * Claim <claim> bytes to set the stack alignment.
7752 //  * Push <reg_count> registers with size <reg_size>.
7753 //  * Clobber the register contents.
7754 //  * Pop <reg_count> registers to restore the original contents.
7755 //  * Drop <claim> bytes to restore the original stack pointer.
7756 //
7757 // Different push and pop methods can be specified independently to test for
7758 // proper word-endian behaviour.
PushPopXRegSimpleHelper(int reg_count,int claim,int reg_size,PushPopMethod push_method,PushPopMethod pop_method)7759 static void PushPopXRegSimpleHelper(int reg_count,
7760                                     int claim,
7761                                     int reg_size,
7762                                     PushPopMethod push_method,
7763                                     PushPopMethod pop_method) {
7764   SETUP();
7765 
7766   START();
7767 
7768   // Arbitrarily pick a register to use as a stack pointer.
7769   const Register& stack_pointer = x20;
7770   const RegList allowed = ~stack_pointer.Bit();
7771   if (reg_count == kPushPopXRegMaxRegCount) {
7772     reg_count = CountSetBits(allowed, kNumberOfRegisters);
7773   }
7774   // Work out which registers to use, based on reg_size.
7775   Register r[kNumberOfRegisters];
7776   Register x[kNumberOfRegisters];
7777   RegList list = PopulateRegisterArray(NULL, x, r, reg_size, reg_count,
7778                                        allowed);
7779 
7780   // The literal base is chosen to have two useful properties:
7781   //  * When multiplied by small values (such as a register index), this value
7782   //    is clearly readable in the result.
7783   //  * The value is not formed from repeating fixed-size smaller values, so it
7784   //    can be used to detect endianness-related errors.
7785   uint64_t literal_base = 0x0100001000100101;
7786 
7787   {
7788     VIXL_ASSERT(__ StackPointer().Is(sp));
7789     __ Mov(stack_pointer, __ StackPointer());
7790     __ SetStackPointer(stack_pointer);
7791 
7792     int i;
7793 
7794     // Initialize the registers.
7795     for (i = 0; i < reg_count; i++) {
7796       // Always write into the X register, to ensure that the upper word is
7797       // properly ignored by Push when testing W registers.
7798       __ Mov(x[i], literal_base * i);
7799     }
7800 
7801     // Claim memory first, as requested.
7802     __ Claim(claim);
7803 
7804     switch (push_method) {
7805       case PushPopByFour:
7806         // Push high-numbered registers first (to the highest addresses).
7807         for (i = reg_count; i >= 4; i -= 4) {
7808           __ Push(r[i-1], r[i-2], r[i-3], r[i-4]);
7809         }
7810         // Finish off the leftovers.
7811         switch (i) {
7812           case 3:  __ Push(r[2], r[1], r[0]); break;
7813           case 2:  __ Push(r[1], r[0]);       break;
7814           case 1:  __ Push(r[0]);             break;
7815           default: VIXL_ASSERT(i == 0);            break;
7816         }
7817         break;
7818       case PushPopRegList:
7819         __ PushSizeRegList(list, reg_size);
7820         break;
7821     }
7822 
7823     // Clobber all the registers, to ensure that they get repopulated by Pop.
7824     Clobber(&masm, list);
7825 
7826     switch (pop_method) {
7827       case PushPopByFour:
7828         // Pop low-numbered registers first (from the lowest addresses).
7829         for (i = 0; i <= (reg_count-4); i += 4) {
7830           __ Pop(r[i], r[i+1], r[i+2], r[i+3]);
7831         }
7832         // Finish off the leftovers.
7833         switch (reg_count - i) {
7834           case 3:  __ Pop(r[i], r[i+1], r[i+2]); break;
7835           case 2:  __ Pop(r[i], r[i+1]);         break;
7836           case 1:  __ Pop(r[i]);                 break;
7837           default: VIXL_ASSERT(i == reg_count);       break;
7838         }
7839         break;
7840       case PushPopRegList:
7841         __ PopSizeRegList(list, reg_size);
7842         break;
7843     }
7844 
7845     // Drop memory to restore stack_pointer.
7846     __ Drop(claim);
7847 
7848     __ Mov(sp, __ StackPointer());
7849     __ SetStackPointer(sp);
7850   }
7851 
7852   END();
7853 
7854   RUN();
7855 
7856   // Check that the register contents were preserved.
7857   // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
7858   // that the upper word was properly cleared by Pop.
7859   literal_base &= (0xffffffffffffffff >> (64-reg_size));
7860   for (int i = 0; i < reg_count; i++) {
7861     if (x[i].Is(xzr)) {
7862       ASSERT_EQUAL_64(0, x[i]);
7863     } else {
7864       ASSERT_EQUAL_64(literal_base * i, x[i]);
7865     }
7866   }
7867 
7868   TEARDOWN();
7869 }
7870 
7871 
TEST(push_pop_xreg_simple_32)7872 TEST(push_pop_xreg_simple_32) {
7873   for (int claim = 0; claim <= 8; claim++) {
7874     for (int count = 0; count <= 8; count++) {
7875       PushPopXRegSimpleHelper(count, claim, kWRegSize,
7876                               PushPopByFour, PushPopByFour);
7877       PushPopXRegSimpleHelper(count, claim, kWRegSize,
7878                               PushPopByFour, PushPopRegList);
7879       PushPopXRegSimpleHelper(count, claim, kWRegSize,
7880                               PushPopRegList, PushPopByFour);
7881       PushPopXRegSimpleHelper(count, claim, kWRegSize,
7882                               PushPopRegList, PushPopRegList);
7883     }
7884     // Test with the maximum number of registers.
7885     PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7886                             claim, kWRegSize, PushPopByFour, PushPopByFour);
7887     PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7888                             claim, kWRegSize, PushPopByFour, PushPopRegList);
7889     PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7890                             claim, kWRegSize, PushPopRegList, PushPopByFour);
7891     PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7892                             claim, kWRegSize, PushPopRegList, PushPopRegList);
7893   }
7894 }
7895 
7896 
TEST(push_pop_xreg_simple_64)7897 TEST(push_pop_xreg_simple_64) {
7898   for (int claim = 0; claim <= 8; claim++) {
7899     for (int count = 0; count <= 8; count++) {
7900       PushPopXRegSimpleHelper(count, claim, kXRegSize,
7901                               PushPopByFour, PushPopByFour);
7902       PushPopXRegSimpleHelper(count, claim, kXRegSize,
7903                               PushPopByFour, PushPopRegList);
7904       PushPopXRegSimpleHelper(count, claim, kXRegSize,
7905                               PushPopRegList, PushPopByFour);
7906       PushPopXRegSimpleHelper(count, claim, kXRegSize,
7907                               PushPopRegList, PushPopRegList);
7908     }
7909     // Test with the maximum number of registers.
7910     PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7911                             claim, kXRegSize, PushPopByFour, PushPopByFour);
7912     PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7913                             claim, kXRegSize, PushPopByFour, PushPopRegList);
7914     PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7915                             claim, kXRegSize, PushPopRegList, PushPopByFour);
7916     PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
7917                             claim, kXRegSize, PushPopRegList, PushPopRegList);
7918   }
7919 }
7920 
7921 
7922 // The maximum number of registers that can be used by the PushPopFPXReg* tests,
7923 // where a reg_count field is provided.
7924 static int const kPushPopFPXRegMaxRegCount = -1;
7925 
7926 // Test a simple push-pop pattern:
7927 //  * Claim <claim> bytes to set the stack alignment.
7928 //  * Push <reg_count> FP registers with size <reg_size>.
7929 //  * Clobber the register contents.
7930 //  * Pop <reg_count> FP registers to restore the original contents.
7931 //  * Drop <claim> bytes to restore the original stack pointer.
7932 //
7933 // Different push and pop methods can be specified independently to test for
7934 // proper word-endian behaviour.
PushPopFPXRegSimpleHelper(int reg_count,int claim,int reg_size,PushPopMethod push_method,PushPopMethod pop_method)7935 static void PushPopFPXRegSimpleHelper(int reg_count,
7936                                       int claim,
7937                                       int reg_size,
7938                                       PushPopMethod push_method,
7939                                       PushPopMethod pop_method) {
7940   SETUP();
7941 
7942   START();
7943 
7944   // We can use any floating-point register. None of them are reserved for
7945   // debug code, for example.
7946   static RegList const allowed = ~0;
7947   if (reg_count == kPushPopFPXRegMaxRegCount) {
7948     reg_count = CountSetBits(allowed, kNumberOfFPRegisters);
7949   }
7950   // Work out which registers to use, based on reg_size.
7951   FPRegister v[kNumberOfRegisters];
7952   FPRegister d[kNumberOfRegisters];
7953   RegList list = PopulateFPRegisterArray(NULL, d, v, reg_size, reg_count,
7954                                          allowed);
7955 
7956   // Arbitrarily pick a register to use as a stack pointer.
7957   const Register& stack_pointer = x10;
7958 
7959   // The literal base is chosen to have two useful properties:
7960   //  * When multiplied (using an integer) by small values (such as a register
7961   //    index), this value is clearly readable in the result.
7962   //  * The value is not formed from repeating fixed-size smaller values, so it
7963   //    can be used to detect endianness-related errors.
7964   //  * It is never a floating-point NaN, and will therefore always compare
7965   //    equal to itself.
7966   uint64_t literal_base = 0x0100001000100101;
7967 
7968   {
7969     VIXL_ASSERT(__ StackPointer().Is(sp));
7970     __ Mov(stack_pointer, __ StackPointer());
7971     __ SetStackPointer(stack_pointer);
7972 
7973     int i;
7974 
7975     // Initialize the registers, using X registers to load the literal.
7976     __ Mov(x0, 0);
7977     __ Mov(x1, literal_base);
7978     for (i = 0; i < reg_count; i++) {
7979       // Always write into the D register, to ensure that the upper word is
7980       // properly ignored by Push when testing S registers.
7981       __ Fmov(d[i], x0);
7982       // Calculate the next literal.
7983       __ Add(x0, x0, x1);
7984     }
7985 
7986     // Claim memory first, as requested.
7987     __ Claim(claim);
7988 
7989     switch (push_method) {
7990       case PushPopByFour:
7991         // Push high-numbered registers first (to the highest addresses).
7992         for (i = reg_count; i >= 4; i -= 4) {
7993           __ Push(v[i-1], v[i-2], v[i-3], v[i-4]);
7994         }
7995         // Finish off the leftovers.
7996         switch (i) {
7997           case 3:  __ Push(v[2], v[1], v[0]); break;
7998           case 2:  __ Push(v[1], v[0]);       break;
7999           case 1:  __ Push(v[0]);             break;
8000           default: VIXL_ASSERT(i == 0);            break;
8001         }
8002         break;
8003       case PushPopRegList:
8004         __ PushSizeRegList(list, reg_size, CPURegister::kFPRegister);
8005         break;
8006     }
8007 
8008     // Clobber all the registers, to ensure that they get repopulated by Pop.
8009     ClobberFP(&masm, list);
8010 
8011     switch (pop_method) {
8012       case PushPopByFour:
8013         // Pop low-numbered registers first (from the lowest addresses).
8014         for (i = 0; i <= (reg_count-4); i += 4) {
8015           __ Pop(v[i], v[i+1], v[i+2], v[i+3]);
8016         }
8017         // Finish off the leftovers.
8018         switch (reg_count - i) {
8019           case 3:  __ Pop(v[i], v[i+1], v[i+2]); break;
8020           case 2:  __ Pop(v[i], v[i+1]);         break;
8021           case 1:  __ Pop(v[i]);                 break;
8022           default: VIXL_ASSERT(i == reg_count);       break;
8023         }
8024         break;
8025       case PushPopRegList:
8026         __ PopSizeRegList(list, reg_size, CPURegister::kFPRegister);
8027         break;
8028     }
8029 
8030     // Drop memory to restore the stack pointer.
8031     __ Drop(claim);
8032 
8033     __ Mov(sp, __ StackPointer());
8034     __ SetStackPointer(sp);
8035   }
8036 
8037   END();
8038 
8039   RUN();
8040 
8041   // Check that the register contents were preserved.
8042   // Always use ASSERT_EQUAL_FP64, even when testing S registers, so we can
8043   // test that the upper word was properly cleared by Pop.
8044   literal_base &= (0xffffffffffffffff >> (64-reg_size));
8045   for (int i = 0; i < reg_count; i++) {
8046     uint64_t literal = literal_base * i;
8047     double expected;
8048     memcpy(&expected, &literal, sizeof(expected));
8049     ASSERT_EQUAL_FP64(expected, d[i]);
8050   }
8051 
8052   TEARDOWN();
8053 }
8054 
8055 
TEST(push_pop_fp_xreg_simple_32)8056 TEST(push_pop_fp_xreg_simple_32) {
8057   for (int claim = 0; claim <= 8; claim++) {
8058     for (int count = 0; count <= 8; count++) {
8059       PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8060                                 PushPopByFour, PushPopByFour);
8061       PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8062                                 PushPopByFour, PushPopRegList);
8063       PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8064                                 PushPopRegList, PushPopByFour);
8065       PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8066                                 PushPopRegList, PushPopRegList);
8067     }
8068     // Test with the maximum number of registers.
8069     PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8070                               PushPopByFour, PushPopByFour);
8071     PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8072                               PushPopByFour, PushPopRegList);
8073     PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8074                               PushPopRegList, PushPopByFour);
8075     PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8076                               PushPopRegList, PushPopRegList);
8077   }
8078 }
8079 
8080 
TEST(push_pop_fp_xreg_simple_64)8081 TEST(push_pop_fp_xreg_simple_64) {
8082   for (int claim = 0; claim <= 8; claim++) {
8083     for (int count = 0; count <= 8; count++) {
8084       PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8085                                 PushPopByFour, PushPopByFour);
8086       PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8087                                 PushPopByFour, PushPopRegList);
8088       PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8089                                 PushPopRegList, PushPopByFour);
8090       PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8091                                 PushPopRegList, PushPopRegList);
8092     }
8093     // Test with the maximum number of registers.
8094     PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8095                               PushPopByFour, PushPopByFour);
8096     PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8097                               PushPopByFour, PushPopRegList);
8098     PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8099                               PushPopRegList, PushPopByFour);
8100     PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8101                               PushPopRegList, PushPopRegList);
8102   }
8103 }
8104 
8105 
8106 // Push and pop data using an overlapping combination of Push/Pop and
8107 // RegList-based methods.
PushPopXRegMixedMethodsHelper(int claim,int reg_size)8108 static void PushPopXRegMixedMethodsHelper(int claim, int reg_size) {
8109   SETUP();
8110 
8111   // Arbitrarily pick a register to use as a stack pointer.
8112   const Register& stack_pointer = x5;
8113   const RegList allowed = ~stack_pointer.Bit();
8114   // Work out which registers to use, based on reg_size.
8115   Register r[10];
8116   Register x[10];
8117   PopulateRegisterArray(NULL, x, r, reg_size, 10, allowed);
8118 
8119   // Calculate some handy register lists.
8120   RegList r0_to_r3 = 0;
8121   for (int i = 0; i <= 3; i++) {
8122     r0_to_r3 |= x[i].Bit();
8123   }
8124   RegList r4_to_r5 = 0;
8125   for (int i = 4; i <= 5; i++) {
8126     r4_to_r5 |= x[i].Bit();
8127   }
8128   RegList r6_to_r9 = 0;
8129   for (int i = 6; i <= 9; i++) {
8130     r6_to_r9 |= x[i].Bit();
8131   }
8132 
8133   // The literal base is chosen to have two useful properties:
8134   //  * When multiplied by small values (such as a register index), this value
8135   //    is clearly readable in the result.
8136   //  * The value is not formed from repeating fixed-size smaller values, so it
8137   //    can be used to detect endianness-related errors.
8138   uint64_t literal_base = 0x0100001000100101;
8139 
8140   START();
8141   {
8142     VIXL_ASSERT(__ StackPointer().Is(sp));
8143     __ Mov(stack_pointer, __ StackPointer());
8144     __ SetStackPointer(stack_pointer);
8145 
8146     // Claim memory first, as requested.
8147     __ Claim(claim);
8148 
8149     __ Mov(x[3], literal_base * 3);
8150     __ Mov(x[2], literal_base * 2);
8151     __ Mov(x[1], literal_base * 1);
8152     __ Mov(x[0], literal_base * 0);
8153 
8154     __ PushSizeRegList(r0_to_r3, reg_size);
8155     __ Push(r[3], r[2]);
8156 
8157     Clobber(&masm, r0_to_r3);
8158     __ PopSizeRegList(r0_to_r3, reg_size);
8159 
8160     __ Push(r[2], r[1], r[3], r[0]);
8161 
8162     Clobber(&masm, r4_to_r5);
8163     __ Pop(r[4], r[5]);
8164     Clobber(&masm, r6_to_r9);
8165     __ Pop(r[6], r[7], r[8], r[9]);
8166 
8167     // Drop memory to restore stack_pointer.
8168     __ Drop(claim);
8169 
8170     __ Mov(sp, __ StackPointer());
8171     __ SetStackPointer(sp);
8172   }
8173 
8174   END();
8175 
8176   RUN();
8177 
8178   // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
8179   // that the upper word was properly cleared by Pop.
8180   literal_base &= (0xffffffffffffffff >> (64-reg_size));
8181 
8182   ASSERT_EQUAL_64(literal_base * 3, x[9]);
8183   ASSERT_EQUAL_64(literal_base * 2, x[8]);
8184   ASSERT_EQUAL_64(literal_base * 0, x[7]);
8185   ASSERT_EQUAL_64(literal_base * 3, x[6]);
8186   ASSERT_EQUAL_64(literal_base * 1, x[5]);
8187   ASSERT_EQUAL_64(literal_base * 2, x[4]);
8188 
8189   TEARDOWN();
8190 }
8191 
8192 
TEST(push_pop_xreg_mixed_methods_64)8193 TEST(push_pop_xreg_mixed_methods_64) {
8194   for (int claim = 0; claim <= 8; claim++) {
8195     PushPopXRegMixedMethodsHelper(claim, kXRegSize);
8196   }
8197 }
8198 
8199 
TEST(push_pop_xreg_mixed_methods_32)8200 TEST(push_pop_xreg_mixed_methods_32) {
8201   for (int claim = 0; claim <= 8; claim++) {
8202     PushPopXRegMixedMethodsHelper(claim, kWRegSize);
8203   }
8204 }
8205 
8206 
8207 // Push and pop data using overlapping X- and W-sized quantities.
PushPopXRegWXOverlapHelper(int reg_count,int claim)8208 static void PushPopXRegWXOverlapHelper(int reg_count, int claim) {
8209   SETUP();
8210 
8211   // Arbitrarily pick a register to use as a stack pointer.
8212   const Register& stack_pointer = x10;
8213   const RegList allowed = ~stack_pointer.Bit();
8214   if (reg_count == kPushPopXRegMaxRegCount) {
8215     reg_count = CountSetBits(allowed, kNumberOfRegisters);
8216   }
8217   // Work out which registers to use, based on reg_size.
8218   Register w[kNumberOfRegisters];
8219   Register x[kNumberOfRegisters];
8220   RegList list = PopulateRegisterArray(w, x, NULL, 0, reg_count, allowed);
8221 
8222   // The number of W-sized slots we expect to pop. When we pop, we alternate
8223   // between W and X registers, so we need reg_count*1.5 W-sized slots.
8224   int const requested_w_slots = reg_count + reg_count / 2;
8225 
8226   // Track what _should_ be on the stack, using W-sized slots.
8227   static int const kMaxWSlots = kNumberOfRegisters + kNumberOfRegisters / 2;
8228   uint32_t stack[kMaxWSlots];
8229   for (int i = 0; i < kMaxWSlots; i++) {
8230     stack[i] = 0xdeadbeef;
8231   }
8232 
8233   // The literal base is chosen to have two useful properties:
8234   //  * When multiplied by small values (such as a register index), this value
8235   //    is clearly readable in the result.
8236   //  * The value is not formed from repeating fixed-size smaller values, so it
8237   //    can be used to detect endianness-related errors.
8238   static uint64_t const literal_base = 0x0100001000100101;
8239   static uint64_t const literal_base_hi = literal_base >> 32;
8240   static uint64_t const literal_base_lo = literal_base & 0xffffffff;
8241   static uint64_t const literal_base_w = literal_base & 0xffffffff;
8242 
8243   START();
8244   {
8245     VIXL_ASSERT(__ StackPointer().Is(sp));
8246     __ Mov(stack_pointer, __ StackPointer());
8247     __ SetStackPointer(stack_pointer);
8248 
8249     // Initialize the registers.
8250     for (int i = 0; i < reg_count; i++) {
8251       // Always write into the X register, to ensure that the upper word is
8252       // properly ignored by Push when testing W registers.
8253       __ Mov(x[i], literal_base * i);
8254     }
8255 
8256     // Claim memory first, as requested.
8257     __ Claim(claim);
8258 
8259     // The push-pop pattern is as follows:
8260     // Push:           Pop:
8261     //  x[0](hi)   ->   w[0]
8262     //  x[0](lo)   ->   x[1](hi)
8263     //  w[1]       ->   x[1](lo)
8264     //  w[1]       ->   w[2]
8265     //  x[2](hi)   ->   x[2](hi)
8266     //  x[2](lo)   ->   x[2](lo)
8267     //  x[2](hi)   ->   w[3]
8268     //  x[2](lo)   ->   x[4](hi)
8269     //  x[2](hi)   ->   x[4](lo)
8270     //  x[2](lo)   ->   w[5]
8271     //  w[3]       ->   x[5](hi)
8272     //  w[3]       ->   x[6](lo)
8273     //  w[3]       ->   w[7]
8274     //  w[3]       ->   x[8](hi)
8275     //  x[4](hi)   ->   x[8](lo)
8276     //  x[4](lo)   ->   w[9]
8277     // ... pattern continues ...
8278     //
8279     // That is, registers are pushed starting with the lower numbers,
8280     // alternating between x and w registers, and pushing i%4+1 copies of each,
8281     // where i is the register number.
8282     // Registers are popped starting with the higher numbers one-by-one,
8283     // alternating between x and w registers, but only popping one at a time.
8284     //
8285     // This pattern provides a wide variety of alignment effects and overlaps.
8286 
8287     // ---- Push ----
8288 
8289     int active_w_slots = 0;
8290     for (int i = 0; active_w_slots < requested_w_slots; i++) {
8291       VIXL_ASSERT(i < reg_count);
8292       // In order to test various arguments to PushMultipleTimes, and to try to
8293       // exercise different alignment and overlap effects, we push each
8294       // register a different number of times.
8295       int times = i % 4 + 1;
8296       if (i & 1) {
8297         // Push odd-numbered registers as W registers.
8298         __ PushMultipleTimes(times, w[i]);
8299         // Fill in the expected stack slots.
8300         for (int j = 0; j < times; j++) {
8301           if (w[i].Is(wzr)) {
8302             // The zero register always writes zeroes.
8303             stack[active_w_slots++] = 0;
8304           } else {
8305             stack[active_w_slots++] = literal_base_w * i;
8306           }
8307         }
8308       } else {
8309         // Push even-numbered registers as X registers.
8310         __ PushMultipleTimes(times, x[i]);
8311         // Fill in the expected stack slots.
8312         for (int j = 0; j < times; j++) {
8313           if (x[i].Is(xzr)) {
8314             // The zero register always writes zeroes.
8315             stack[active_w_slots++] = 0;
8316             stack[active_w_slots++] = 0;
8317           } else {
8318             stack[active_w_slots++] = literal_base_hi * i;
8319             stack[active_w_slots++] = literal_base_lo * i;
8320           }
8321         }
8322       }
8323     }
8324     // Because we were pushing several registers at a time, we probably pushed
8325     // more than we needed to.
8326     if (active_w_slots > requested_w_slots) {
8327       __ Drop((active_w_slots - requested_w_slots) * kWRegSizeInBytes);
8328       // Bump the number of active W-sized slots back to where it should be,
8329       // and fill the empty space with a dummy value.
8330       do {
8331         stack[active_w_slots--] = 0xdeadbeef;
8332       } while (active_w_slots > requested_w_slots);
8333     }
8334 
8335     // ---- Pop ----
8336 
8337     Clobber(&masm, list);
8338 
8339     // If popping an even number of registers, the first one will be X-sized.
8340     // Otherwise, the first one will be W-sized.
8341     bool next_is_64 = !(reg_count & 1);
8342     for (int i = reg_count-1; i >= 0; i--) {
8343       if (next_is_64) {
8344         __ Pop(x[i]);
8345         active_w_slots -= 2;
8346       } else {
8347         __ Pop(w[i]);
8348         active_w_slots -= 1;
8349       }
8350       next_is_64 = !next_is_64;
8351     }
8352     VIXL_ASSERT(active_w_slots == 0);
8353 
8354     // Drop memory to restore stack_pointer.
8355     __ Drop(claim);
8356 
8357     __ Mov(sp, __ StackPointer());
8358     __ SetStackPointer(sp);
8359   }
8360 
8361   END();
8362 
8363   RUN();
8364 
8365   int slot = 0;
8366   for (int i = 0; i < reg_count; i++) {
8367     // Even-numbered registers were written as W registers.
8368     // Odd-numbered registers were written as X registers.
8369     bool expect_64 = (i & 1);
8370     uint64_t expected;
8371 
8372     if (expect_64) {
8373       uint64_t hi = stack[slot++];
8374       uint64_t lo = stack[slot++];
8375       expected = (hi << 32) | lo;
8376     } else {
8377       expected = stack[slot++];
8378     }
8379 
8380     // Always use ASSERT_EQUAL_64, even when testing W registers, so we can
8381     // test that the upper word was properly cleared by Pop.
8382     if (x[i].Is(xzr)) {
8383       ASSERT_EQUAL_64(0, x[i]);
8384     } else {
8385       ASSERT_EQUAL_64(expected, x[i]);
8386     }
8387   }
8388   VIXL_ASSERT(slot == requested_w_slots);
8389 
8390   TEARDOWN();
8391 }
8392 
8393 
TEST(push_pop_xreg_wx_overlap)8394 TEST(push_pop_xreg_wx_overlap) {
8395   for (int claim = 0; claim <= 8; claim++) {
8396     for (int count = 1; count <= 8; count++) {
8397       PushPopXRegWXOverlapHelper(count, claim);
8398     }
8399     // Test with the maximum number of registers.
8400     PushPopXRegWXOverlapHelper(kPushPopXRegMaxRegCount, claim);
8401   }
8402 }
8403 
8404 
TEST(push_pop_sp)8405 TEST(push_pop_sp) {
8406   SETUP();
8407 
8408   START();
8409 
8410   VIXL_ASSERT(sp.Is(__ StackPointer()));
8411 
8412   __ Mov(x3, 0x3333333333333333);
8413   __ Mov(x2, 0x2222222222222222);
8414   __ Mov(x1, 0x1111111111111111);
8415   __ Mov(x0, 0x0000000000000000);
8416   __ Claim(2 * kXRegSizeInBytes);
8417   __ PushXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
8418   __ Push(x3, x2);
8419   __ PopXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
8420   __ Push(x2, x1, x3, x0);
8421   __ Pop(x4, x5);
8422   __ Pop(x6, x7, x8, x9);
8423 
8424   __ Claim(2 * kXRegSizeInBytes);
8425   __ PushWRegList(w0.Bit() | w1.Bit() | w2.Bit() | w3.Bit());
8426   __ Push(w3, w1, w2, w0);
8427   __ PopWRegList(w10.Bit() | w11.Bit() | w12.Bit() | w13.Bit());
8428   __ Pop(w14, w15, w16, w17);
8429 
8430   __ Claim(2 * kXRegSizeInBytes);
8431   __ Push(w2, w2, w1, w1);
8432   __ Push(x3, x3);
8433   __ Pop(w18, w19, w20, w21);
8434   __ Pop(x22, x23);
8435 
8436   __ Claim(2 * kXRegSizeInBytes);
8437   __ PushXRegList(x1.Bit() | x22.Bit());
8438   __ PopXRegList(x24.Bit() | x26.Bit());
8439 
8440   __ Claim(2 * kXRegSizeInBytes);
8441   __ PushWRegList(w1.Bit() | w2.Bit() | w4.Bit() | w22.Bit());
8442   __ PopWRegList(w25.Bit() | w27.Bit() | w28.Bit() | w29.Bit());
8443 
8444   __ Claim(2 * kXRegSizeInBytes);
8445   __ PushXRegList(0);
8446   __ PopXRegList(0);
8447   __ PushXRegList(0xffffffff);
8448   __ PopXRegList(0xffffffff);
8449   __ Drop(12 * kXRegSizeInBytes);
8450   END();
8451 
8452   RUN();
8453 
8454   ASSERT_EQUAL_64(0x1111111111111111, x3);
8455   ASSERT_EQUAL_64(0x0000000000000000, x2);
8456   ASSERT_EQUAL_64(0x3333333333333333, x1);
8457   ASSERT_EQUAL_64(0x2222222222222222, x0);
8458   ASSERT_EQUAL_64(0x3333333333333333, x9);
8459   ASSERT_EQUAL_64(0x2222222222222222, x8);
8460   ASSERT_EQUAL_64(0x0000000000000000, x7);
8461   ASSERT_EQUAL_64(0x3333333333333333, x6);
8462   ASSERT_EQUAL_64(0x1111111111111111, x5);
8463   ASSERT_EQUAL_64(0x2222222222222222, x4);
8464 
8465   ASSERT_EQUAL_32(0x11111111U, w13);
8466   ASSERT_EQUAL_32(0x33333333U, w12);
8467   ASSERT_EQUAL_32(0x00000000U, w11);
8468   ASSERT_EQUAL_32(0x22222222U, w10);
8469   ASSERT_EQUAL_32(0x11111111U, w17);
8470   ASSERT_EQUAL_32(0x00000000U, w16);
8471   ASSERT_EQUAL_32(0x33333333U, w15);
8472   ASSERT_EQUAL_32(0x22222222U, w14);
8473 
8474   ASSERT_EQUAL_32(0x11111111U, w18);
8475   ASSERT_EQUAL_32(0x11111111U, w19);
8476   ASSERT_EQUAL_32(0x11111111U, w20);
8477   ASSERT_EQUAL_32(0x11111111U, w21);
8478   ASSERT_EQUAL_64(0x3333333333333333, x22);
8479   ASSERT_EQUAL_64(0x0000000000000000, x23);
8480 
8481   ASSERT_EQUAL_64(0x3333333333333333, x24);
8482   ASSERT_EQUAL_64(0x3333333333333333, x26);
8483 
8484   ASSERT_EQUAL_32(0x33333333U, w25);
8485   ASSERT_EQUAL_32(0x00000000U, w27);
8486   ASSERT_EQUAL_32(0x22222222U, w28);
8487   ASSERT_EQUAL_32(0x33333333U, w29);
8488   TEARDOWN();
8489 }
8490 
8491 
TEST(noreg)8492 TEST(noreg) {
8493   // This test doesn't generate any code, but it verifies some invariants
8494   // related to NoReg.
8495   VIXL_CHECK(NoReg.Is(NoFPReg));
8496   VIXL_CHECK(NoFPReg.Is(NoReg));
8497   VIXL_CHECK(NoReg.Is(NoCPUReg));
8498   VIXL_CHECK(NoCPUReg.Is(NoReg));
8499   VIXL_CHECK(NoFPReg.Is(NoCPUReg));
8500   VIXL_CHECK(NoCPUReg.Is(NoFPReg));
8501 
8502   VIXL_CHECK(NoReg.IsNone());
8503   VIXL_CHECK(NoFPReg.IsNone());
8504   VIXL_CHECK(NoCPUReg.IsNone());
8505 }
8506 
8507 
TEST(isvalid)8508 TEST(isvalid) {
8509   // This test doesn't generate any code, but it verifies some invariants
8510   // related to IsValid().
8511   VIXL_CHECK(!NoReg.IsValid());
8512   VIXL_CHECK(!NoFPReg.IsValid());
8513   VIXL_CHECK(!NoCPUReg.IsValid());
8514 
8515   VIXL_CHECK(x0.IsValid());
8516   VIXL_CHECK(w0.IsValid());
8517   VIXL_CHECK(x30.IsValid());
8518   VIXL_CHECK(w30.IsValid());
8519   VIXL_CHECK(xzr.IsValid());
8520   VIXL_CHECK(wzr.IsValid());
8521 
8522   VIXL_CHECK(sp.IsValid());
8523   VIXL_CHECK(wsp.IsValid());
8524 
8525   VIXL_CHECK(d0.IsValid());
8526   VIXL_CHECK(s0.IsValid());
8527   VIXL_CHECK(d31.IsValid());
8528   VIXL_CHECK(s31.IsValid());
8529 
8530   VIXL_CHECK(x0.IsValidRegister());
8531   VIXL_CHECK(w0.IsValidRegister());
8532   VIXL_CHECK(xzr.IsValidRegister());
8533   VIXL_CHECK(wzr.IsValidRegister());
8534   VIXL_CHECK(sp.IsValidRegister());
8535   VIXL_CHECK(wsp.IsValidRegister());
8536   VIXL_CHECK(!x0.IsValidFPRegister());
8537   VIXL_CHECK(!w0.IsValidFPRegister());
8538   VIXL_CHECK(!xzr.IsValidFPRegister());
8539   VIXL_CHECK(!wzr.IsValidFPRegister());
8540   VIXL_CHECK(!sp.IsValidFPRegister());
8541   VIXL_CHECK(!wsp.IsValidFPRegister());
8542 
8543   VIXL_CHECK(d0.IsValidFPRegister());
8544   VIXL_CHECK(s0.IsValidFPRegister());
8545   VIXL_CHECK(!d0.IsValidRegister());
8546   VIXL_CHECK(!s0.IsValidRegister());
8547 
8548   // Test the same as before, but using CPURegister types. This shouldn't make
8549   // any difference.
8550   VIXL_CHECK(static_cast<CPURegister>(x0).IsValid());
8551   VIXL_CHECK(static_cast<CPURegister>(w0).IsValid());
8552   VIXL_CHECK(static_cast<CPURegister>(x30).IsValid());
8553   VIXL_CHECK(static_cast<CPURegister>(w30).IsValid());
8554   VIXL_CHECK(static_cast<CPURegister>(xzr).IsValid());
8555   VIXL_CHECK(static_cast<CPURegister>(wzr).IsValid());
8556 
8557   VIXL_CHECK(static_cast<CPURegister>(sp).IsValid());
8558   VIXL_CHECK(static_cast<CPURegister>(wsp).IsValid());
8559 
8560   VIXL_CHECK(static_cast<CPURegister>(d0).IsValid());
8561   VIXL_CHECK(static_cast<CPURegister>(s0).IsValid());
8562   VIXL_CHECK(static_cast<CPURegister>(d31).IsValid());
8563   VIXL_CHECK(static_cast<CPURegister>(s31).IsValid());
8564 
8565   VIXL_CHECK(static_cast<CPURegister>(x0).IsValidRegister());
8566   VIXL_CHECK(static_cast<CPURegister>(w0).IsValidRegister());
8567   VIXL_CHECK(static_cast<CPURegister>(xzr).IsValidRegister());
8568   VIXL_CHECK(static_cast<CPURegister>(wzr).IsValidRegister());
8569   VIXL_CHECK(static_cast<CPURegister>(sp).IsValidRegister());
8570   VIXL_CHECK(static_cast<CPURegister>(wsp).IsValidRegister());
8571   VIXL_CHECK(!static_cast<CPURegister>(x0).IsValidFPRegister());
8572   VIXL_CHECK(!static_cast<CPURegister>(w0).IsValidFPRegister());
8573   VIXL_CHECK(!static_cast<CPURegister>(xzr).IsValidFPRegister());
8574   VIXL_CHECK(!static_cast<CPURegister>(wzr).IsValidFPRegister());
8575   VIXL_CHECK(!static_cast<CPURegister>(sp).IsValidFPRegister());
8576   VIXL_CHECK(!static_cast<CPURegister>(wsp).IsValidFPRegister());
8577 
8578   VIXL_CHECK(static_cast<CPURegister>(d0).IsValidFPRegister());
8579   VIXL_CHECK(static_cast<CPURegister>(s0).IsValidFPRegister());
8580   VIXL_CHECK(!static_cast<CPURegister>(d0).IsValidRegister());
8581   VIXL_CHECK(!static_cast<CPURegister>(s0).IsValidRegister());
8582 }
8583 
8584 
TEST(printf)8585 TEST(printf) {
8586   SETUP_SIZE(BUF_SIZE * 2);
8587   START();
8588 
8589   char const * test_plain_string = "Printf with no arguments.\n";
8590   char const * test_substring = "'This is a substring.'";
8591   RegisterDump before;
8592 
8593   // Initialize x29 to the value of the stack pointer. We will use x29 as a
8594   // temporary stack pointer later, and initializing it in this way allows the
8595   // RegisterDump check to pass.
8596   __ Mov(x29, __ StackPointer());
8597 
8598   // Test simple integer arguments.
8599   __ Mov(x0, 1234);
8600   __ Mov(x1, 0x1234);
8601 
8602   // Test simple floating-point arguments.
8603   __ Fmov(d0, 1.234);
8604 
8605   // Test pointer (string) arguments.
8606   __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
8607 
8608   // Test the maximum number of arguments, and sign extension.
8609   __ Mov(w3, 0xffffffff);
8610   __ Mov(w4, 0xffffffff);
8611   __ Mov(x5, 0xffffffffffffffff);
8612   __ Mov(x6, 0xffffffffffffffff);
8613   __ Fmov(s1, 1.234);
8614   __ Fmov(s2, 2.345);
8615   __ Fmov(d3, 3.456);
8616   __ Fmov(d4, 4.567);
8617 
8618   // Test printing callee-saved registers.
8619   __ Mov(x28, 0x123456789abcdef);
8620   __ Fmov(d10, 42.0);
8621 
8622   // Test with three arguments.
8623   __ Mov(x10, 3);
8624   __ Mov(x11, 40);
8625   __ Mov(x12, 500);
8626 
8627   // A single character.
8628   __ Mov(w13, 'x');
8629 
8630   // Check that we don't clobber any registers.
8631   before.Dump(&masm);
8632 
8633   __ Printf(test_plain_string);   // NOLINT(runtime/printf)
8634   __ Printf("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1);
8635   __ Printf("w5: %" PRId32 ", x5: %" PRId64"\n", w5, x5);
8636   __ Printf("d0: %f\n", d0);
8637   __ Printf("Test %%s: %s\n", x2);
8638   __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
8639             "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
8640             w3, w4, x5, x6);
8641   __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
8642   __ Printf("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
8643   __ Printf("%g\n", d10);
8644   __ Printf("%%%%%s%%%c%%\n", x2, w13);
8645 
8646   // Print the stack pointer (sp).
8647   __ Printf("StackPointer(sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
8648             __ StackPointer(), __ StackPointer().W());
8649 
8650   // Test with a different stack pointer.
8651   const Register old_stack_pointer = __ StackPointer();
8652   __ Mov(x29, old_stack_pointer);
8653   __ SetStackPointer(x29);
8654   // Print the stack pointer (not sp).
8655   __ Printf("StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
8656             __ StackPointer(), __ StackPointer().W());
8657   __ Mov(old_stack_pointer, __ StackPointer());
8658   __ SetStackPointer(old_stack_pointer);
8659 
8660   // Test with three arguments.
8661   __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12);
8662 
8663   // Mixed argument types.
8664   __ Printf("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
8665             w3, s1, x5, d3);
8666   __ Printf("s1: %f, d3: %f, w3: %" PRId32 ", x5: %" PRId64 "\n",
8667             s1, d3, w3, x5);
8668 
8669   END();
8670   RUN();
8671 
8672   // We cannot easily test the output of the Printf sequences, and because
8673   // Printf preserves all registers by default, we can't look at the number of
8674   // bytes that were printed. However, the printf_no_preserve test should check
8675   // that, and here we just test that we didn't clobber any registers.
8676   ASSERT_EQUAL_REGISTERS(before);
8677 
8678   TEARDOWN();
8679 }
8680 
8681 
TEST(printf_no_preserve)8682 TEST(printf_no_preserve) {
8683   SETUP();
8684   START();
8685 
8686   char const * test_plain_string = "Printf with no arguments.\n";
8687   char const * test_substring = "'This is a substring.'";
8688 
8689   __ PrintfNoPreserve(test_plain_string);
8690   __ Mov(x19, x0);
8691 
8692   // Test simple integer arguments.
8693   __ Mov(x0, 1234);
8694   __ Mov(x1, 0x1234);
8695   __ PrintfNoPreserve("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1);
8696   __ Mov(x20, x0);
8697 
8698   // Test simple floating-point arguments.
8699   __ Fmov(d0, 1.234);
8700   __ PrintfNoPreserve("d0: %f\n", d0);
8701   __ Mov(x21, x0);
8702 
8703   // Test pointer (string) arguments.
8704   __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
8705   __ PrintfNoPreserve("Test %%s: %s\n", x2);
8706   __ Mov(x22, x0);
8707 
8708   // Test the maximum number of arguments, and sign extension.
8709   __ Mov(w3, 0xffffffff);
8710   __ Mov(w4, 0xffffffff);
8711   __ Mov(x5, 0xffffffffffffffff);
8712   __ Mov(x6, 0xffffffffffffffff);
8713   __ PrintfNoPreserve("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
8714                       "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
8715                       w3, w4, x5, x6);
8716   __ Mov(x23, x0);
8717 
8718   __ Fmov(s1, 1.234);
8719   __ Fmov(s2, 2.345);
8720   __ Fmov(d3, 3.456);
8721   __ Fmov(d4, 4.567);
8722   __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
8723   __ Mov(x24, x0);
8724 
8725   // Test printing callee-saved registers.
8726   __ Mov(x28, 0x123456789abcdef);
8727   __ PrintfNoPreserve("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
8728   __ Mov(x25, x0);
8729 
8730   __ Fmov(d10, 42.0);
8731   __ PrintfNoPreserve("%g\n", d10);
8732   __ Mov(x26, x0);
8733 
8734   // Test with a different stack pointer.
8735   const Register old_stack_pointer = __ StackPointer();
8736   __ Mov(x29, old_stack_pointer);
8737   __ SetStackPointer(x29);
8738   // Print the stack pointer (not sp).
8739   __ PrintfNoPreserve(
8740       "StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
8741       __ StackPointer(), __ StackPointer().W());
8742   __ Mov(x27, x0);
8743   __ Mov(old_stack_pointer, __ StackPointer());
8744   __ SetStackPointer(old_stack_pointer);
8745 
8746   // Test with three arguments.
8747   __ Mov(x3, 3);
8748   __ Mov(x4, 40);
8749   __ Mov(x5, 500);
8750   __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5);
8751   __ Mov(x28, x0);
8752 
8753   // Mixed argument types.
8754   __ Mov(w3, 0xffffffff);
8755   __ Fmov(s1, 1.234);
8756   __ Mov(x5, 0xffffffffffffffff);
8757   __ Fmov(d3, 3.456);
8758   __ PrintfNoPreserve("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
8759                       w3, s1, x5, d3);
8760   __ Mov(x29, x0);
8761 
8762   END();
8763   RUN();
8764 
8765   // We cannot easily test the exact output of the Printf sequences, but we can
8766   // use the return code to check that the string length was correct.
8767 
8768   // Printf with no arguments.
8769   ASSERT_EQUAL_64(strlen(test_plain_string), x19);
8770   // x0: 1234, x1: 0x00001234
8771   ASSERT_EQUAL_64(25, x20);
8772   // d0: 1.234000
8773   ASSERT_EQUAL_64(13, x21);
8774   // Test %s: 'This is a substring.'
8775   ASSERT_EQUAL_64(32, x22);
8776   // w3(uint32): 4294967295
8777   // w4(int32): -1
8778   // x5(uint64): 18446744073709551615
8779   // x6(int64): -1
8780   ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23);
8781   // %f: 1.234000
8782   // %g: 2.345
8783   // %e: 3.456000e+00
8784   // %E: 4.567000E+00
8785   ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24);
8786   // 0x89abcdef, 0x123456789abcdef
8787   ASSERT_EQUAL_64(30, x25);
8788   // 42
8789   ASSERT_EQUAL_64(3, x26);
8790   // StackPointer(not sp): 0x00007fb037ae2370, 0x37ae2370
8791   // Note: This is an example value, but the field width is fixed here so the
8792   // string length is still predictable.
8793   ASSERT_EQUAL_64(53, x27);
8794   // 3=3, 4=40, 5=500
8795   ASSERT_EQUAL_64(17, x28);
8796   // w3: 4294967295, s1: 1.234000, x5: 18446744073709551615, d3: 3.456000
8797   ASSERT_EQUAL_64(69, x29);
8798 
8799   TEARDOWN();
8800 }
8801 
8802 
8803 #ifndef USE_SIMULATOR
TEST(trace)8804 TEST(trace) {
8805   // The Trace helper should not generate any code unless the simulator (or
8806   // debugger) is being used.
8807   SETUP();
8808   START();
8809 
8810   Label start;
8811   __ Bind(&start);
8812   __ Trace(LOG_ALL, TRACE_ENABLE);
8813   __ Trace(LOG_ALL, TRACE_DISABLE);
8814   VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
8815 
8816   END();
8817   TEARDOWN();
8818 }
8819 #endif
8820 
8821 
8822 #ifndef USE_SIMULATOR
TEST(log)8823 TEST(log) {
8824   // The Log helper should not generate any code unless the simulator (or
8825   // debugger) is being used.
8826   SETUP();
8827   START();
8828 
8829   Label start;
8830   __ Bind(&start);
8831   __ Log(LOG_ALL);
8832   VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
8833 
8834   END();
8835   TEARDOWN();
8836 }
8837 #endif
8838 
8839 
TEST(instruction_accurate_scope)8840 TEST(instruction_accurate_scope) {
8841   SETUP();
8842   START();
8843 
8844   // By default macro instructions are allowed.
8845   VIXL_ASSERT(masm.AllowMacroInstructions());
8846   {
8847     InstructionAccurateScope scope1(&masm);
8848     VIXL_ASSERT(!masm.AllowMacroInstructions());
8849     {
8850       InstructionAccurateScope scope2(&masm);
8851       VIXL_ASSERT(!masm.AllowMacroInstructions());
8852     }
8853     VIXL_ASSERT(!masm.AllowMacroInstructions());
8854   }
8855   VIXL_ASSERT(masm.AllowMacroInstructions());
8856 
8857   {
8858     InstructionAccurateScope scope(&masm, 2);
8859     __ add(x0, x0, x0);
8860     __ sub(x0, x0, x0);
8861   }
8862 
8863   END();
8864   RUN();
8865   TEARDOWN();
8866 }
8867 
8868 
TEST(blr_lr)8869 TEST(blr_lr) {
8870   // A simple test to check that the simulator correcty handle "blr lr".
8871   SETUP();
8872 
8873   START();
8874   Label target;
8875   Label end;
8876 
8877   __ Mov(x0, 0x0);
8878   __ Adr(lr, &target);
8879 
8880   __ Blr(lr);
8881   __ Mov(x0, 0xdeadbeef);
8882   __ B(&end);
8883 
8884   __ Bind(&target);
8885   __ Mov(x0, 0xc001c0de);
8886 
8887   __ Bind(&end);
8888   END();
8889 
8890   RUN();
8891 
8892   ASSERT_EQUAL_64(0xc001c0de, x0);
8893 
8894   TEARDOWN();
8895 }
8896 
8897 
TEST(barriers)8898 TEST(barriers) {
8899   // Generate all supported barriers, this is just a smoke test
8900   SETUP();
8901 
8902   START();
8903 
8904   // DMB
8905   __ Dmb(FullSystem, BarrierAll);
8906   __ Dmb(FullSystem, BarrierReads);
8907   __ Dmb(FullSystem, BarrierWrites);
8908   __ Dmb(FullSystem, BarrierOther);
8909 
8910   __ Dmb(InnerShareable, BarrierAll);
8911   __ Dmb(InnerShareable, BarrierReads);
8912   __ Dmb(InnerShareable, BarrierWrites);
8913   __ Dmb(InnerShareable, BarrierOther);
8914 
8915   __ Dmb(NonShareable, BarrierAll);
8916   __ Dmb(NonShareable, BarrierReads);
8917   __ Dmb(NonShareable, BarrierWrites);
8918   __ Dmb(NonShareable, BarrierOther);
8919 
8920   __ Dmb(OuterShareable, BarrierAll);
8921   __ Dmb(OuterShareable, BarrierReads);
8922   __ Dmb(OuterShareable, BarrierWrites);
8923   __ Dmb(OuterShareable, BarrierOther);
8924 
8925   // DSB
8926   __ Dsb(FullSystem, BarrierAll);
8927   __ Dsb(FullSystem, BarrierReads);
8928   __ Dsb(FullSystem, BarrierWrites);
8929   __ Dsb(FullSystem, BarrierOther);
8930 
8931   __ Dsb(InnerShareable, BarrierAll);
8932   __ Dsb(InnerShareable, BarrierReads);
8933   __ Dsb(InnerShareable, BarrierWrites);
8934   __ Dsb(InnerShareable, BarrierOther);
8935 
8936   __ Dsb(NonShareable, BarrierAll);
8937   __ Dsb(NonShareable, BarrierReads);
8938   __ Dsb(NonShareable, BarrierWrites);
8939   __ Dsb(NonShareable, BarrierOther);
8940 
8941   __ Dsb(OuterShareable, BarrierAll);
8942   __ Dsb(OuterShareable, BarrierReads);
8943   __ Dsb(OuterShareable, BarrierWrites);
8944   __ Dsb(OuterShareable, BarrierOther);
8945 
8946   // ISB
8947   __ Isb();
8948 
8949   END();
8950 
8951   RUN();
8952 
8953   TEARDOWN();
8954 }
8955 
8956 
TEST(process_nan_double)8957 TEST(process_nan_double) {
8958   // Make sure that NaN propagation works correctly.
8959   double sn = rawbits_to_double(0x7ff5555511111111);
8960   double qn = rawbits_to_double(0x7ffaaaaa11111111);
8961   VIXL_ASSERT(IsSignallingNaN(sn));
8962   VIXL_ASSERT(IsQuietNaN(qn));
8963 
8964   // The input NaNs after passing through ProcessNaN.
8965   double sn_proc = rawbits_to_double(0x7ffd555511111111);
8966   double qn_proc = qn;
8967   VIXL_ASSERT(IsQuietNaN(sn_proc));
8968   VIXL_ASSERT(IsQuietNaN(qn_proc));
8969 
8970   SETUP();
8971   START();
8972 
8973   // Execute a number of instructions which all use ProcessNaN, and check that
8974   // they all handle the NaN correctly.
8975   __ Fmov(d0, sn);
8976   __ Fmov(d10, qn);
8977 
8978   // Operations that always propagate NaNs unchanged, even signalling NaNs.
8979   //   - Signalling NaN
8980   __ Fmov(d1, d0);
8981   __ Fabs(d2, d0);
8982   __ Fneg(d3, d0);
8983   //   - Quiet NaN
8984   __ Fmov(d11, d10);
8985   __ Fabs(d12, d10);
8986   __ Fneg(d13, d10);
8987 
8988   // Operations that use ProcessNaN.
8989   //   - Signalling NaN
8990   __ Fsqrt(d4, d0);
8991   __ Frinta(d5, d0);
8992   __ Frintn(d6, d0);
8993   __ Frintz(d7, d0);
8994   //   - Quiet NaN
8995   __ Fsqrt(d14, d10);
8996   __ Frinta(d15, d10);
8997   __ Frintn(d16, d10);
8998   __ Frintz(d17, d10);
8999 
9000   // The behaviour of fcvt is checked in TEST(fcvt_sd).
9001 
9002   END();
9003   RUN();
9004 
9005   uint64_t qn_raw = double_to_rawbits(qn);
9006   uint64_t sn_raw = double_to_rawbits(sn);
9007 
9008   //   - Signalling NaN
9009   ASSERT_EQUAL_FP64(sn, d1);
9010   ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw & ~kDSignMask), d2);
9011   ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw ^ kDSignMask), d3);
9012   //   - Quiet NaN
9013   ASSERT_EQUAL_FP64(qn, d11);
9014   ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw & ~kDSignMask), d12);
9015   ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw ^ kDSignMask), d13);
9016 
9017   //   - Signalling NaN
9018   ASSERT_EQUAL_FP64(sn_proc, d4);
9019   ASSERT_EQUAL_FP64(sn_proc, d5);
9020   ASSERT_EQUAL_FP64(sn_proc, d6);
9021   ASSERT_EQUAL_FP64(sn_proc, d7);
9022   //   - Quiet NaN
9023   ASSERT_EQUAL_FP64(qn_proc, d14);
9024   ASSERT_EQUAL_FP64(qn_proc, d15);
9025   ASSERT_EQUAL_FP64(qn_proc, d16);
9026   ASSERT_EQUAL_FP64(qn_proc, d17);
9027 
9028   TEARDOWN();
9029 }
9030 
9031 
TEST(process_nan_float)9032 TEST(process_nan_float) {
9033   // Make sure that NaN propagation works correctly.
9034   float sn = rawbits_to_float(0x7f951111);
9035   float qn = rawbits_to_float(0x7fea1111);
9036   VIXL_ASSERT(IsSignallingNaN(sn));
9037   VIXL_ASSERT(IsQuietNaN(qn));
9038 
9039   // The input NaNs after passing through ProcessNaN.
9040   float sn_proc = rawbits_to_float(0x7fd51111);
9041   float qn_proc = qn;
9042   VIXL_ASSERT(IsQuietNaN(sn_proc));
9043   VIXL_ASSERT(IsQuietNaN(qn_proc));
9044 
9045   SETUP();
9046   START();
9047 
9048   // Execute a number of instructions which all use ProcessNaN, and check that
9049   // they all handle the NaN correctly.
9050   __ Fmov(s0, sn);
9051   __ Fmov(s10, qn);
9052 
9053   // Operations that always propagate NaNs unchanged, even signalling NaNs.
9054   //   - Signalling NaN
9055   __ Fmov(s1, s0);
9056   __ Fabs(s2, s0);
9057   __ Fneg(s3, s0);
9058   //   - Quiet NaN
9059   __ Fmov(s11, s10);
9060   __ Fabs(s12, s10);
9061   __ Fneg(s13, s10);
9062 
9063   // Operations that use ProcessNaN.
9064   //   - Signalling NaN
9065   __ Fsqrt(s4, s0);
9066   __ Frinta(s5, s0);
9067   __ Frintn(s6, s0);
9068   __ Frintz(s7, s0);
9069   //   - Quiet NaN
9070   __ Fsqrt(s14, s10);
9071   __ Frinta(s15, s10);
9072   __ Frintn(s16, s10);
9073   __ Frintz(s17, s10);
9074 
9075   // The behaviour of fcvt is checked in TEST(fcvt_sd).
9076 
9077   END();
9078   RUN();
9079 
9080   uint32_t qn_raw = float_to_rawbits(qn);
9081   uint32_t sn_raw = float_to_rawbits(sn);
9082 
9083   //   - Signalling NaN
9084   ASSERT_EQUAL_FP32(sn, s1);
9085   ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw & ~kSSignMask), s2);
9086   ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw ^ kSSignMask), s3);
9087   //   - Quiet NaN
9088   ASSERT_EQUAL_FP32(qn, s11);
9089   ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw & ~kSSignMask), s12);
9090   ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw ^ kSSignMask), s13);
9091 
9092   //   - Signalling NaN
9093   ASSERT_EQUAL_FP32(sn_proc, s4);
9094   ASSERT_EQUAL_FP32(sn_proc, s5);
9095   ASSERT_EQUAL_FP32(sn_proc, s6);
9096   ASSERT_EQUAL_FP32(sn_proc, s7);
9097   //   - Quiet NaN
9098   ASSERT_EQUAL_FP32(qn_proc, s14);
9099   ASSERT_EQUAL_FP32(qn_proc, s15);
9100   ASSERT_EQUAL_FP32(qn_proc, s16);
9101   ASSERT_EQUAL_FP32(qn_proc, s17);
9102 
9103   TEARDOWN();
9104 }
9105 
9106 
ProcessNaNsHelper(double n,double m,double expected)9107 static void ProcessNaNsHelper(double n, double m, double expected) {
9108   VIXL_ASSERT(isnan(n) || isnan(m));
9109   VIXL_ASSERT(isnan(expected));
9110 
9111   SETUP();
9112   START();
9113 
9114   // Execute a number of instructions which all use ProcessNaNs, and check that
9115   // they all propagate NaNs correctly.
9116   __ Fmov(d0, n);
9117   __ Fmov(d1, m);
9118 
9119   __ Fadd(d2, d0, d1);
9120   __ Fsub(d3, d0, d1);
9121   __ Fmul(d4, d0, d1);
9122   __ Fdiv(d5, d0, d1);
9123   __ Fmax(d6, d0, d1);
9124   __ Fmin(d7, d0, d1);
9125 
9126   END();
9127   RUN();
9128 
9129   ASSERT_EQUAL_FP64(expected, d2);
9130   ASSERT_EQUAL_FP64(expected, d3);
9131   ASSERT_EQUAL_FP64(expected, d4);
9132   ASSERT_EQUAL_FP64(expected, d5);
9133   ASSERT_EQUAL_FP64(expected, d6);
9134   ASSERT_EQUAL_FP64(expected, d7);
9135 
9136   TEARDOWN();
9137 }
9138 
9139 
TEST(process_nans_double)9140 TEST(process_nans_double) {
9141   // Make sure that NaN propagation works correctly.
9142   double sn = rawbits_to_double(0x7ff5555511111111);
9143   double sm = rawbits_to_double(0x7ff5555522222222);
9144   double qn = rawbits_to_double(0x7ffaaaaa11111111);
9145   double qm = rawbits_to_double(0x7ffaaaaa22222222);
9146   VIXL_ASSERT(IsSignallingNaN(sn));
9147   VIXL_ASSERT(IsSignallingNaN(sm));
9148   VIXL_ASSERT(IsQuietNaN(qn));
9149   VIXL_ASSERT(IsQuietNaN(qm));
9150 
9151   // The input NaNs after passing through ProcessNaN.
9152   double sn_proc = rawbits_to_double(0x7ffd555511111111);
9153   double sm_proc = rawbits_to_double(0x7ffd555522222222);
9154   double qn_proc = qn;
9155   double qm_proc = qm;
9156   VIXL_ASSERT(IsQuietNaN(sn_proc));
9157   VIXL_ASSERT(IsQuietNaN(sm_proc));
9158   VIXL_ASSERT(IsQuietNaN(qn_proc));
9159   VIXL_ASSERT(IsQuietNaN(qm_proc));
9160 
9161   // Quiet NaNs are propagated.
9162   ProcessNaNsHelper(qn, 0, qn_proc);
9163   ProcessNaNsHelper(0, qm, qm_proc);
9164   ProcessNaNsHelper(qn, qm, qn_proc);
9165 
9166   // Signalling NaNs are propagated, and made quiet.
9167   ProcessNaNsHelper(sn, 0, sn_proc);
9168   ProcessNaNsHelper(0, sm, sm_proc);
9169   ProcessNaNsHelper(sn, sm, sn_proc);
9170 
9171   // Signalling NaNs take precedence over quiet NaNs.
9172   ProcessNaNsHelper(sn, qm, sn_proc);
9173   ProcessNaNsHelper(qn, sm, sm_proc);
9174   ProcessNaNsHelper(sn, sm, sn_proc);
9175 }
9176 
9177 
ProcessNaNsHelper(float n,float m,float expected)9178 static void ProcessNaNsHelper(float n, float m, float expected) {
9179   VIXL_ASSERT(isnan(n) || isnan(m));
9180   VIXL_ASSERT(isnan(expected));
9181 
9182   SETUP();
9183   START();
9184 
9185   // Execute a number of instructions which all use ProcessNaNs, and check that
9186   // they all propagate NaNs correctly.
9187   __ Fmov(s0, n);
9188   __ Fmov(s1, m);
9189 
9190   __ Fadd(s2, s0, s1);
9191   __ Fsub(s3, s0, s1);
9192   __ Fmul(s4, s0, s1);
9193   __ Fdiv(s5, s0, s1);
9194   __ Fmax(s6, s0, s1);
9195   __ Fmin(s7, s0, s1);
9196 
9197   END();
9198   RUN();
9199 
9200   ASSERT_EQUAL_FP32(expected, s2);
9201   ASSERT_EQUAL_FP32(expected, s3);
9202   ASSERT_EQUAL_FP32(expected, s4);
9203   ASSERT_EQUAL_FP32(expected, s5);
9204   ASSERT_EQUAL_FP32(expected, s6);
9205   ASSERT_EQUAL_FP32(expected, s7);
9206 
9207   TEARDOWN();
9208 }
9209 
9210 
TEST(process_nans_float)9211 TEST(process_nans_float) {
9212   // Make sure that NaN propagation works correctly.
9213   float sn = rawbits_to_float(0x7f951111);
9214   float sm = rawbits_to_float(0x7f952222);
9215   float qn = rawbits_to_float(0x7fea1111);
9216   float qm = rawbits_to_float(0x7fea2222);
9217   VIXL_ASSERT(IsSignallingNaN(sn));
9218   VIXL_ASSERT(IsSignallingNaN(sm));
9219   VIXL_ASSERT(IsQuietNaN(qn));
9220   VIXL_ASSERT(IsQuietNaN(qm));
9221 
9222   // The input NaNs after passing through ProcessNaN.
9223   float sn_proc = rawbits_to_float(0x7fd51111);
9224   float sm_proc = rawbits_to_float(0x7fd52222);
9225   float qn_proc = qn;
9226   float qm_proc = qm;
9227   VIXL_ASSERT(IsQuietNaN(sn_proc));
9228   VIXL_ASSERT(IsQuietNaN(sm_proc));
9229   VIXL_ASSERT(IsQuietNaN(qn_proc));
9230   VIXL_ASSERT(IsQuietNaN(qm_proc));
9231 
9232   // Quiet NaNs are propagated.
9233   ProcessNaNsHelper(qn, 0, qn_proc);
9234   ProcessNaNsHelper(0, qm, qm_proc);
9235   ProcessNaNsHelper(qn, qm, qn_proc);
9236 
9237   // Signalling NaNs are propagated, and made quiet.
9238   ProcessNaNsHelper(sn, 0, sn_proc);
9239   ProcessNaNsHelper(0, sm, sm_proc);
9240   ProcessNaNsHelper(sn, sm, sn_proc);
9241 
9242   // Signalling NaNs take precedence over quiet NaNs.
9243   ProcessNaNsHelper(sn, qm, sn_proc);
9244   ProcessNaNsHelper(qn, sm, sm_proc);
9245   ProcessNaNsHelper(sn, sm, sn_proc);
9246 }
9247 
9248 
DefaultNaNHelper(float n,float m,float a)9249 static void DefaultNaNHelper(float n, float m, float a) {
9250   VIXL_ASSERT(isnan(n) || isnan(m) || isnan(a));
9251 
9252   bool test_1op = isnan(n);
9253   bool test_2op = isnan(n) || isnan(m);
9254 
9255   SETUP();
9256   START();
9257 
9258   // Enable Default-NaN mode in the FPCR.
9259   __ Mrs(x0, FPCR);
9260   __ Orr(x1, x0, DN_mask);
9261   __ Msr(FPCR, x1);
9262 
9263   // Execute a number of instructions which all use ProcessNaNs, and check that
9264   // they all produce the default NaN.
9265   __ Fmov(s0, n);
9266   __ Fmov(s1, m);
9267   __ Fmov(s2, a);
9268 
9269   if (test_1op) {
9270     // Operations that always propagate NaNs unchanged, even signalling NaNs.
9271     __ Fmov(s10, s0);
9272     __ Fabs(s11, s0);
9273     __ Fneg(s12, s0);
9274 
9275     // Operations that use ProcessNaN.
9276     __ Fsqrt(s13, s0);
9277     __ Frinta(s14, s0);
9278     __ Frintn(s15, s0);
9279     __ Frintz(s16, s0);
9280 
9281     // Fcvt usually has special NaN handling, but it respects default-NaN mode.
9282     __ Fcvt(d17, s0);
9283   }
9284 
9285   if (test_2op) {
9286     __ Fadd(s18, s0, s1);
9287     __ Fsub(s19, s0, s1);
9288     __ Fmul(s20, s0, s1);
9289     __ Fdiv(s21, s0, s1);
9290     __ Fmax(s22, s0, s1);
9291     __ Fmin(s23, s0, s1);
9292   }
9293 
9294   __ Fmadd(s24, s0, s1, s2);
9295   __ Fmsub(s25, s0, s1, s2);
9296   __ Fnmadd(s26, s0, s1, s2);
9297   __ Fnmsub(s27, s0, s1, s2);
9298 
9299   // Restore FPCR.
9300   __ Msr(FPCR, x0);
9301 
9302   END();
9303   RUN();
9304 
9305   if (test_1op) {
9306     uint32_t n_raw = float_to_rawbits(n);
9307     ASSERT_EQUAL_FP32(n, s10);
9308     ASSERT_EQUAL_FP32(rawbits_to_float(n_raw & ~kSSignMask), s11);
9309     ASSERT_EQUAL_FP32(rawbits_to_float(n_raw ^ kSSignMask), s12);
9310     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s13);
9311     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s14);
9312     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s15);
9313     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s16);
9314     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d17);
9315   }
9316 
9317   if (test_2op) {
9318     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s18);
9319     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s19);
9320     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s20);
9321     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s21);
9322     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s22);
9323     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s23);
9324   }
9325 
9326   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s24);
9327   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s25);
9328   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s26);
9329   ASSERT_EQUAL_FP32(kFP32DefaultNaN, s27);
9330 
9331   TEARDOWN();
9332 }
9333 
9334 
TEST(default_nan_float)9335 TEST(default_nan_float) {
9336   float sn = rawbits_to_float(0x7f951111);
9337   float sm = rawbits_to_float(0x7f952222);
9338   float sa = rawbits_to_float(0x7f95aaaa);
9339   float qn = rawbits_to_float(0x7fea1111);
9340   float qm = rawbits_to_float(0x7fea2222);
9341   float qa = rawbits_to_float(0x7feaaaaa);
9342   VIXL_ASSERT(IsSignallingNaN(sn));
9343   VIXL_ASSERT(IsSignallingNaN(sm));
9344   VIXL_ASSERT(IsSignallingNaN(sa));
9345   VIXL_ASSERT(IsQuietNaN(qn));
9346   VIXL_ASSERT(IsQuietNaN(qm));
9347   VIXL_ASSERT(IsQuietNaN(qa));
9348 
9349   //   - Signalling NaNs
9350   DefaultNaNHelper(sn, 0.0f, 0.0f);
9351   DefaultNaNHelper(0.0f, sm, 0.0f);
9352   DefaultNaNHelper(0.0f, 0.0f, sa);
9353   DefaultNaNHelper(sn, sm, 0.0f);
9354   DefaultNaNHelper(0.0f, sm, sa);
9355   DefaultNaNHelper(sn, 0.0f, sa);
9356   DefaultNaNHelper(sn, sm, sa);
9357   //   - Quiet NaNs
9358   DefaultNaNHelper(qn, 0.0f, 0.0f);
9359   DefaultNaNHelper(0.0f, qm, 0.0f);
9360   DefaultNaNHelper(0.0f, 0.0f, qa);
9361   DefaultNaNHelper(qn, qm, 0.0f);
9362   DefaultNaNHelper(0.0f, qm, qa);
9363   DefaultNaNHelper(qn, 0.0f, qa);
9364   DefaultNaNHelper(qn, qm, qa);
9365   //   - Mixed NaNs
9366   DefaultNaNHelper(qn, sm, sa);
9367   DefaultNaNHelper(sn, qm, sa);
9368   DefaultNaNHelper(sn, sm, qa);
9369   DefaultNaNHelper(qn, qm, sa);
9370   DefaultNaNHelper(sn, qm, qa);
9371   DefaultNaNHelper(qn, sm, qa);
9372   DefaultNaNHelper(qn, qm, qa);
9373 }
9374 
9375 
DefaultNaNHelper(double n,double m,double a)9376 static void DefaultNaNHelper(double n, double m, double a) {
9377   VIXL_ASSERT(isnan(n) || isnan(m) || isnan(a));
9378 
9379   bool test_1op = isnan(n);
9380   bool test_2op = isnan(n) || isnan(m);
9381 
9382   SETUP();
9383   START();
9384 
9385   // Enable Default-NaN mode in the FPCR.
9386   __ Mrs(x0, FPCR);
9387   __ Orr(x1, x0, DN_mask);
9388   __ Msr(FPCR, x1);
9389 
9390   // Execute a number of instructions which all use ProcessNaNs, and check that
9391   // they all produce the default NaN.
9392   __ Fmov(d0, n);
9393   __ Fmov(d1, m);
9394   __ Fmov(d2, a);
9395 
9396   if (test_1op) {
9397     // Operations that always propagate NaNs unchanged, even signalling NaNs.
9398     __ Fmov(d10, d0);
9399     __ Fabs(d11, d0);
9400     __ Fneg(d12, d0);
9401 
9402     // Operations that use ProcessNaN.
9403     __ Fsqrt(d13, d0);
9404     __ Frinta(d14, d0);
9405     __ Frintn(d15, d0);
9406     __ Frintz(d16, d0);
9407 
9408     // Fcvt usually has special NaN handling, but it respects default-NaN mode.
9409     __ Fcvt(s17, d0);
9410   }
9411 
9412   if (test_2op) {
9413     __ Fadd(d18, d0, d1);
9414     __ Fsub(d19, d0, d1);
9415     __ Fmul(d20, d0, d1);
9416     __ Fdiv(d21, d0, d1);
9417     __ Fmax(d22, d0, d1);
9418     __ Fmin(d23, d0, d1);
9419   }
9420 
9421   __ Fmadd(d24, d0, d1, d2);
9422   __ Fmsub(d25, d0, d1, d2);
9423   __ Fnmadd(d26, d0, d1, d2);
9424   __ Fnmsub(d27, d0, d1, d2);
9425 
9426   // Restore FPCR.
9427   __ Msr(FPCR, x0);
9428 
9429   END();
9430   RUN();
9431 
9432   if (test_1op) {
9433     uint64_t n_raw = double_to_rawbits(n);
9434     ASSERT_EQUAL_FP64(n, d10);
9435     ASSERT_EQUAL_FP64(rawbits_to_double(n_raw & ~kDSignMask), d11);
9436     ASSERT_EQUAL_FP64(rawbits_to_double(n_raw ^ kDSignMask), d12);
9437     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
9438     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d14);
9439     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d15);
9440     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d16);
9441     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s17);
9442   }
9443 
9444   if (test_2op) {
9445     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d18);
9446     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d19);
9447     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d20);
9448     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d21);
9449     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d22);
9450     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d23);
9451   }
9452 
9453   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d24);
9454   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d25);
9455   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d26);
9456   ASSERT_EQUAL_FP64(kFP64DefaultNaN, d27);
9457 
9458   TEARDOWN();
9459 }
9460 
9461 
TEST(default_nan_double)9462 TEST(default_nan_double) {
9463   double sn = rawbits_to_double(0x7ff5555511111111);
9464   double sm = rawbits_to_double(0x7ff5555522222222);
9465   double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
9466   double qn = rawbits_to_double(0x7ffaaaaa11111111);
9467   double qm = rawbits_to_double(0x7ffaaaaa22222222);
9468   double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
9469   VIXL_ASSERT(IsSignallingNaN(sn));
9470   VIXL_ASSERT(IsSignallingNaN(sm));
9471   VIXL_ASSERT(IsSignallingNaN(sa));
9472   VIXL_ASSERT(IsQuietNaN(qn));
9473   VIXL_ASSERT(IsQuietNaN(qm));
9474   VIXL_ASSERT(IsQuietNaN(qa));
9475 
9476   //   - Signalling NaNs
9477   DefaultNaNHelper(sn, 0.0, 0.0);
9478   DefaultNaNHelper(0.0, sm, 0.0);
9479   DefaultNaNHelper(0.0, 0.0, sa);
9480   DefaultNaNHelper(sn, sm, 0.0);
9481   DefaultNaNHelper(0.0, sm, sa);
9482   DefaultNaNHelper(sn, 0.0, sa);
9483   DefaultNaNHelper(sn, sm, sa);
9484   //   - Quiet NaNs
9485   DefaultNaNHelper(qn, 0.0, 0.0);
9486   DefaultNaNHelper(0.0, qm, 0.0);
9487   DefaultNaNHelper(0.0, 0.0, qa);
9488   DefaultNaNHelper(qn, qm, 0.0);
9489   DefaultNaNHelper(0.0, qm, qa);
9490   DefaultNaNHelper(qn, 0.0, qa);
9491   DefaultNaNHelper(qn, qm, qa);
9492   //   - Mixed NaNs
9493   DefaultNaNHelper(qn, sm, sa);
9494   DefaultNaNHelper(sn, qm, sa);
9495   DefaultNaNHelper(sn, sm, qa);
9496   DefaultNaNHelper(qn, qm, sa);
9497   DefaultNaNHelper(sn, qm, qa);
9498   DefaultNaNHelper(qn, sm, qa);
9499   DefaultNaNHelper(qn, qm, qa);
9500 }
9501 
9502 
9503 }  // namespace vixl
9504