blob: 55e42abc6777805cc8c15821f0745fbc5bec3f34 [file] [log] [blame]
armvixl5289c592015-03-02 13:52:04 +00001// Copyright 2015, ARM Limited
armvixlad96eda2013-06-14 11:42:37 +01002// 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>
armvixlf37fdc02014-02-05 13:22:16 +000028#include <stdlib.h>
armvixlad96eda2013-06-14 11:42:37 +010029#include <string.h>
armvixl578645f2013-08-15 17:21:42 +010030#include <float.h>
armvixl6e2c8272015-03-31 11:04:14 +010031#include <cmath>
armvixlad96eda2013-06-14 11:42:37 +010032
armvixl330dc712014-11-25 10:38:32 +000033#include "test-runner.h"
armvixlad96eda2013-06-14 11:42:37 +010034#include "test-utils-a64.h"
armvixl6e2c8272015-03-31 11:04:14 +010035#include "vixl/a64/macro-assembler-a64.h"
36#include "vixl/a64/simulator-a64.h"
37#include "vixl/a64/debugger-a64.h"
38#include "vixl/a64/disasm-a64.h"
39#include "vixl/a64/cpu-a64.h"
armvixlad96eda2013-06-14 11:42:37 +010040
41namespace 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//
armvixl578645f2013-08-15 17:21:42 +010086// If more advanced computation is required before the assert then access the
armvixlad96eda2013-06-14 11:42:37 +010087// 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
armvixlad96eda2013-06-14 11:42:37 +010097#ifdef USE_SIMULATOR
armvixlad96eda2013-06-14 11:42:37 +010098// Run tests with the simulator.
armvixlc68cb642014-09-25 18:49:30 +010099
100#define SETUP() \
101 MacroAssembler masm(BUF_SIZE); \
102 SETUP_COMMON()
103
104#define SETUP_CUSTOM(size, pic) \
105 byte* buf = new byte[size + BUF_SIZE]; \
106 MacroAssembler masm(buf, size + BUF_SIZE, pic); \
107 SETUP_COMMON()
108
109#define SETUP_COMMON() \
armvixlad96eda2013-06-14 11:42:37 +0100110 Decoder decoder; \
armvixl330dc712014-11-25 10:38:32 +0000111 Simulator* simulator = Test::run_debugger() ? new Debugger(&decoder) \
112 : new Simulator(&decoder); \
113 simulator->set_coloured_trace(Test::coloured_trace()); \
114 simulator->set_instruction_stats(Test::instruction_stats()); \
armvixlad96eda2013-06-14 11:42:37 +0100115 RegisterDump core
116
armvixlc68cb642014-09-25 18:49:30 +0100117// This is a convenience macro to avoid creating a scope for every assembler
118// function called. It will still assert the buffer hasn't been exceeded.
119#define ALLOW_ASM() \
120 CodeBufferCheckScope guard(&masm, masm.BufferCapacity())
121
armvixlad96eda2013-06-14 11:42:37 +0100122#define START() \
123 masm.Reset(); \
124 simulator->ResetState(); \
125 __ PushCalleeSavedRegisters(); \
armvixl330dc712014-11-25 10:38:32 +0000126 if (Test::trace_reg()) { \
127 __ Trace(LOG_STATE, TRACE_ENABLE); \
armvixl578645f2013-08-15 17:21:42 +0100128 } \
armvixl330dc712014-11-25 10:38:32 +0000129 if (Test::trace_write()) { \
130 __ Trace(LOG_WRITE, TRACE_ENABLE); \
131 } \
132 if (Test::trace_sim()) { \
133 __ Trace(LOG_DISASM, TRACE_ENABLE); \
134 } \
135 if (Test::instruction_stats()) { \
armvixl578645f2013-08-15 17:21:42 +0100136 __ EnableInstrumentation(); \
armvixlad96eda2013-06-14 11:42:37 +0100137 }
138
139#define END() \
armvixl330dc712014-11-25 10:38:32 +0000140 if (Test::instruction_stats()) { \
armvixl578645f2013-08-15 17:21:42 +0100141 __ DisableInstrumentation(); \
142 } \
armvixl330dc712014-11-25 10:38:32 +0000143 __ Trace(LOG_ALL, TRACE_DISABLE); \
armvixlad96eda2013-06-14 11:42:37 +0100144 core.Dump(&masm); \
145 __ PopCalleeSavedRegisters(); \
146 __ Ret(); \
147 masm.FinalizeCode()
148
149#define RUN() \
armvixlc68cb642014-09-25 18:49:30 +0100150 simulator->RunFrom(masm.GetStartAddress<Instruction*>())
armvixlad96eda2013-06-14 11:42:37 +0100151
armvixlc68cb642014-09-25 18:49:30 +0100152#define TEARDOWN() TEARDOWN_COMMON()
153
154#define TEARDOWN_CUSTOM() \
155 delete[] buf; \
156 TEARDOWN_COMMON()
157
158#define TEARDOWN_COMMON() \
159 delete simulator;
armvixlad96eda2013-06-14 11:42:37 +0100160
161#else // ifdef USE_SIMULATOR.
162// Run the test on real hardware or models.
armvixlc68cb642014-09-25 18:49:30 +0100163#define SETUP() \
164 MacroAssembler masm(BUF_SIZE); \
165 SETUP_COMMON()
166
167#define SETUP_CUSTOM(size, pic) \
168 byte* buf = new byte[size + BUF_SIZE]; \
169 MacroAssembler masm(buf, size + BUF_SIZE, pic); \
170 SETUP_COMMON()
171
172#define SETUP_COMMON() \
armvixlad96eda2013-06-14 11:42:37 +0100173 RegisterDump core; \
174 CPU::SetUp()
175
armvixlc68cb642014-09-25 18:49:30 +0100176// This is a convenience macro to avoid creating a scope for every assembler
177// function called. It will still assert the buffer hasn't been exceeded.
178#define ALLOW_ASM() \
179 CodeBufferCheckScope guard(&masm, masm.BufferCapacity())
180
armvixlad96eda2013-06-14 11:42:37 +0100181#define START() \
182 masm.Reset(); \
183 __ PushCalleeSavedRegisters()
184
185#define END() \
186 core.Dump(&masm); \
187 __ PopCalleeSavedRegisters(); \
188 __ Ret(); \
189 masm.FinalizeCode()
190
191#define RUN() \
armvixlad96eda2013-06-14 11:42:37 +0100192 { \
armvixlc68cb642014-09-25 18:49:30 +0100193 byte* buffer_start = masm.GetStartAddress<byte*>(); \
194 size_t buffer_length = masm.CursorOffset(); \
armvixlad96eda2013-06-14 11:42:37 +0100195 void (*test_function)(void); \
armvixlc68cb642014-09-25 18:49:30 +0100196 \
197 CPU::EnsureIAndDCacheCoherency(buffer_start, buffer_length); \
198 VIXL_STATIC_ASSERT(sizeof(buffer_start) == sizeof(test_function)); \
199 memcpy(&test_function, &buffer_start, sizeof(buffer_start)); \
armvixlad96eda2013-06-14 11:42:37 +0100200 test_function(); \
201 }
202
armvixlc68cb642014-09-25 18:49:30 +0100203#define TEARDOWN()
204
205#define TEARDOWN_CUSTOM() \
206 delete[] buf; \
armvixlad96eda2013-06-14 11:42:37 +0100207
208#endif // ifdef USE_SIMULATOR.
209
210#define ASSERT_EQUAL_NZCV(expected) \
211 assert(EqualNzcv(expected, core.flags_nzcv()))
212
213#define ASSERT_EQUAL_REGISTERS(expected) \
214 assert(EqualRegisters(&expected, &core))
215
216#define ASSERT_EQUAL_32(expected, result) \
217 assert(Equal32(static_cast<uint32_t>(expected), &core, result))
218
219#define ASSERT_EQUAL_FP32(expected, result) \
220 assert(EqualFP32(expected, &core, result))
221
222#define ASSERT_EQUAL_64(expected, result) \
223 assert(Equal64(expected, &core, result))
224
225#define ASSERT_EQUAL_FP64(expected, result) \
226 assert(EqualFP64(expected, &core, result))
227
armvixl5289c592015-03-02 13:52:04 +0000228#define ASSERT_EQUAL_128(expected_h, expected_l, result) \
229 assert(Equal128(expected_h, expected_l, &core, result))
230
armvixlad96eda2013-06-14 11:42:37 +0100231#define ASSERT_LITERAL_POOL_SIZE(expected) \
armvixl5289c592015-03-02 13:52:04 +0000232 assert((expected + kInstructionSize) == (masm.LiteralPoolSize()))
armvixlad96eda2013-06-14 11:42:37 +0100233
234
235TEST(stack_ops) {
236 SETUP();
237
238 START();
239 // save sp.
240 __ Mov(x29, sp);
241
242 // Set the sp to a known value.
243 __ Mov(sp, 0x1004);
244 __ Mov(x0, sp);
245
246 // Add immediate to the sp, and move the result to a normal register.
armvixlb0c8ae22014-03-21 14:03:59 +0000247 __ Add(sp, sp, 0x50);
armvixlad96eda2013-06-14 11:42:37 +0100248 __ Mov(x1, sp);
249
250 // Add extended to the sp, and move the result to a normal register.
251 __ Mov(x17, 0xfff);
252 __ Add(sp, sp, Operand(x17, SXTB));
253 __ Mov(x2, sp);
254
255 // Create an sp using a logical instruction, and move to normal register.
armvixlb0c8ae22014-03-21 14:03:59 +0000256 __ Orr(sp, xzr, 0x1fff);
armvixlad96eda2013-06-14 11:42:37 +0100257 __ Mov(x3, sp);
258
259 // Write wsp using a logical instruction.
armvixlb0c8ae22014-03-21 14:03:59 +0000260 __ Orr(wsp, wzr, 0xfffffff8);
armvixlad96eda2013-06-14 11:42:37 +0100261 __ Mov(x4, sp);
262
263 // Write sp, and read back wsp.
armvixlb0c8ae22014-03-21 14:03:59 +0000264 __ Orr(sp, xzr, 0xfffffff8);
armvixlad96eda2013-06-14 11:42:37 +0100265 __ Mov(w5, wsp);
266
267 // restore sp.
268 __ Mov(sp, x29);
269 END();
270
271 RUN();
272
273 ASSERT_EQUAL_64(0x1004, x0);
274 ASSERT_EQUAL_64(0x1054, x1);
275 ASSERT_EQUAL_64(0x1053, x2);
276 ASSERT_EQUAL_64(0x1fff, x3);
277 ASSERT_EQUAL_64(0xfffffff8, x4);
278 ASSERT_EQUAL_64(0xfffffff8, x5);
279
280 TEARDOWN();
281}
282
283
284TEST(mvn) {
285 SETUP();
286
287 START();
288 __ Mvn(w0, 0xfff);
289 __ Mvn(x1, 0xfff);
290 __ Mvn(w2, Operand(w0, LSL, 1));
291 __ Mvn(x3, Operand(x1, LSL, 2));
292 __ Mvn(w4, Operand(w0, LSR, 3));
293 __ Mvn(x5, Operand(x1, LSR, 4));
294 __ Mvn(w6, Operand(w0, ASR, 11));
295 __ Mvn(x7, Operand(x1, ASR, 12));
296 __ Mvn(w8, Operand(w0, ROR, 13));
297 __ Mvn(x9, Operand(x1, ROR, 14));
298 __ Mvn(w10, Operand(w2, UXTB));
299 __ Mvn(x11, Operand(x2, SXTB, 1));
300 __ Mvn(w12, Operand(w2, UXTH, 2));
301 __ Mvn(x13, Operand(x2, SXTH, 3));
302 __ Mvn(x14, Operand(w2, UXTW, 4));
303 __ Mvn(x15, Operand(w2, SXTW, 4));
304 END();
305
306 RUN();
307
308 ASSERT_EQUAL_64(0xfffff000, x0);
armvixlb0c8ae22014-03-21 14:03:59 +0000309 ASSERT_EQUAL_64(0xfffffffffffff000, x1);
armvixlad96eda2013-06-14 11:42:37 +0100310 ASSERT_EQUAL_64(0x00001fff, x2);
armvixlb0c8ae22014-03-21 14:03:59 +0000311 ASSERT_EQUAL_64(0x0000000000003fff, x3);
armvixlad96eda2013-06-14 11:42:37 +0100312 ASSERT_EQUAL_64(0xe00001ff, x4);
armvixlb0c8ae22014-03-21 14:03:59 +0000313 ASSERT_EQUAL_64(0xf0000000000000ff, x5);
armvixlad96eda2013-06-14 11:42:37 +0100314 ASSERT_EQUAL_64(0x00000001, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000315 ASSERT_EQUAL_64(0x0000000000000000, x7);
armvixlad96eda2013-06-14 11:42:37 +0100316 ASSERT_EQUAL_64(0x7ff80000, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000317 ASSERT_EQUAL_64(0x3ffc000000000000, x9);
armvixlad96eda2013-06-14 11:42:37 +0100318 ASSERT_EQUAL_64(0xffffff00, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000319 ASSERT_EQUAL_64(0x0000000000000001, x11);
armvixlad96eda2013-06-14 11:42:37 +0100320 ASSERT_EQUAL_64(0xffff8003, x12);
armvixlb0c8ae22014-03-21 14:03:59 +0000321 ASSERT_EQUAL_64(0xffffffffffff0007, x13);
322 ASSERT_EQUAL_64(0xfffffffffffe000f, x14);
323 ASSERT_EQUAL_64(0xfffffffffffe000f, x15);
armvixlad96eda2013-06-14 11:42:37 +0100324
325 TEARDOWN();
326}
327
328
armvixlf37fdc02014-02-05 13:22:16 +0000329TEST(mov_imm_w) {
330 SETUP();
331
332 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000333 __ Mov(w0, 0xffffffff);
334 __ Mov(w1, 0xffff1234);
335 __ Mov(w2, 0x1234ffff);
336 __ Mov(w3, 0x00000000);
337 __ Mov(w4, 0x00001234);
338 __ Mov(w5, 0x12340000);
339 __ Mov(w6, 0x12345678);
armvixl4a102ba2014-07-14 09:02:40 +0100340 __ Mov(w7, (int32_t)0x80000000);
341 __ Mov(w8, (int32_t)0xffff0000);
342 __ Mov(w9, kWMinInt);
armvixlf37fdc02014-02-05 13:22:16 +0000343 END();
344
345 RUN();
346
armvixlb0c8ae22014-03-21 14:03:59 +0000347 ASSERT_EQUAL_64(0xffffffff, x0);
348 ASSERT_EQUAL_64(0xffff1234, x1);
349 ASSERT_EQUAL_64(0x1234ffff, x2);
350 ASSERT_EQUAL_64(0x00000000, x3);
351 ASSERT_EQUAL_64(0x00001234, x4);
352 ASSERT_EQUAL_64(0x12340000, x5);
353 ASSERT_EQUAL_64(0x12345678, x6);
armvixl4a102ba2014-07-14 09:02:40 +0100354 ASSERT_EQUAL_64(0x80000000, x7);
355 ASSERT_EQUAL_64(0xffff0000, x8);
356 ASSERT_EQUAL_32(kWMinInt, w9);
armvixlf37fdc02014-02-05 13:22:16 +0000357
358 TEARDOWN();
359}
360
361
362TEST(mov_imm_x) {
363 SETUP();
364
365 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000366 __ Mov(x0, 0xffffffffffffffff);
367 __ Mov(x1, 0xffffffffffff1234);
368 __ Mov(x2, 0xffffffff12345678);
369 __ Mov(x3, 0xffff1234ffff5678);
370 __ Mov(x4, 0x1234ffffffff5678);
371 __ Mov(x5, 0x1234ffff5678ffff);
372 __ Mov(x6, 0x12345678ffffffff);
373 __ Mov(x7, 0x1234ffffffffffff);
374 __ Mov(x8, 0x123456789abcffff);
375 __ Mov(x9, 0x12345678ffff9abc);
376 __ Mov(x10, 0x1234ffff56789abc);
377 __ Mov(x11, 0xffff123456789abc);
378 __ Mov(x12, 0x0000000000000000);
379 __ Mov(x13, 0x0000000000001234);
380 __ Mov(x14, 0x0000000012345678);
381 __ Mov(x15, 0x0000123400005678);
382 __ Mov(x18, 0x1234000000005678);
383 __ Mov(x19, 0x1234000056780000);
384 __ Mov(x20, 0x1234567800000000);
385 __ Mov(x21, 0x1234000000000000);
386 __ Mov(x22, 0x123456789abc0000);
387 __ Mov(x23, 0x1234567800009abc);
388 __ Mov(x24, 0x1234000056789abc);
389 __ Mov(x25, 0x0000123456789abc);
390 __ Mov(x26, 0x123456789abcdef0);
391 __ Mov(x27, 0xffff000000000001);
392 __ Mov(x28, 0x8000ffff00000000);
armvixlf37fdc02014-02-05 13:22:16 +0000393 END();
394
395 RUN();
396
armvixlb0c8ae22014-03-21 14:03:59 +0000397 ASSERT_EQUAL_64(0xffffffffffff1234, x1);
398 ASSERT_EQUAL_64(0xffffffff12345678, x2);
399 ASSERT_EQUAL_64(0xffff1234ffff5678, x3);
400 ASSERT_EQUAL_64(0x1234ffffffff5678, x4);
401 ASSERT_EQUAL_64(0x1234ffff5678ffff, x5);
402 ASSERT_EQUAL_64(0x12345678ffffffff, x6);
403 ASSERT_EQUAL_64(0x1234ffffffffffff, x7);
404 ASSERT_EQUAL_64(0x123456789abcffff, x8);
405 ASSERT_EQUAL_64(0x12345678ffff9abc, x9);
406 ASSERT_EQUAL_64(0x1234ffff56789abc, x10);
407 ASSERT_EQUAL_64(0xffff123456789abc, x11);
408 ASSERT_EQUAL_64(0x0000000000000000, x12);
409 ASSERT_EQUAL_64(0x0000000000001234, x13);
410 ASSERT_EQUAL_64(0x0000000012345678, x14);
411 ASSERT_EQUAL_64(0x0000123400005678, x15);
412 ASSERT_EQUAL_64(0x1234000000005678, x18);
413 ASSERT_EQUAL_64(0x1234000056780000, x19);
414 ASSERT_EQUAL_64(0x1234567800000000, x20);
415 ASSERT_EQUAL_64(0x1234000000000000, x21);
416 ASSERT_EQUAL_64(0x123456789abc0000, x22);
417 ASSERT_EQUAL_64(0x1234567800009abc, x23);
418 ASSERT_EQUAL_64(0x1234000056789abc, x24);
419 ASSERT_EQUAL_64(0x0000123456789abc, x25);
420 ASSERT_EQUAL_64(0x123456789abcdef0, x26);
421 ASSERT_EQUAL_64(0xffff000000000001, x27);
422 ASSERT_EQUAL_64(0x8000ffff00000000, x28);
armvixlf37fdc02014-02-05 13:22:16 +0000423
424
425 TEARDOWN();
426}
427
428
armvixlad96eda2013-06-14 11:42:37 +0100429TEST(mov) {
430 SETUP();
armvixlc68cb642014-09-25 18:49:30 +0100431 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +0100432
433 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000434 __ Mov(x0, 0xffffffffffffffff);
435 __ Mov(x1, 0xffffffffffffffff);
436 __ Mov(x2, 0xffffffffffffffff);
437 __ Mov(x3, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +0100438
armvixlb0c8ae22014-03-21 14:03:59 +0000439 __ Mov(x0, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100440
armvixlb0c8ae22014-03-21 14:03:59 +0000441 __ movz(x1, UINT64_C(0xabcd) << 16);
442 __ movk(x2, UINT64_C(0xabcd) << 32);
443 __ movn(x3, UINT64_C(0xabcd) << 48);
armvixlad96eda2013-06-14 11:42:37 +0100444
armvixlb0c8ae22014-03-21 14:03:59 +0000445 __ Mov(x4, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100446 __ Mov(x5, x4);
447
448 __ Mov(w6, -1);
449
450 // Test that moves back to the same register have the desired effect. This
451 // is a no-op for X registers, and a truncation for W registers.
armvixlb0c8ae22014-03-21 14:03:59 +0000452 __ Mov(x7, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100453 __ Mov(x7, x7);
armvixlb0c8ae22014-03-21 14:03:59 +0000454 __ Mov(x8, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100455 __ Mov(w8, w8);
armvixlb0c8ae22014-03-21 14:03:59 +0000456 __ Mov(x9, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100457 __ Mov(x9, Operand(x9));
armvixlb0c8ae22014-03-21 14:03:59 +0000458 __ Mov(x10, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100459 __ Mov(w10, Operand(w10));
460
461 __ Mov(w11, 0xfff);
462 __ Mov(x12, 0xfff);
463 __ Mov(w13, Operand(w11, LSL, 1));
464 __ Mov(x14, Operand(x12, LSL, 2));
465 __ Mov(w15, Operand(w11, LSR, 3));
466 __ Mov(x18, Operand(x12, LSR, 4));
467 __ Mov(w19, Operand(w11, ASR, 11));
468 __ Mov(x20, Operand(x12, ASR, 12));
469 __ Mov(w21, Operand(w11, ROR, 13));
470 __ Mov(x22, Operand(x12, ROR, 14));
471 __ Mov(w23, Operand(w13, UXTB));
472 __ Mov(x24, Operand(x13, SXTB, 1));
473 __ Mov(w25, Operand(w13, UXTH, 2));
474 __ Mov(x26, Operand(x13, SXTH, 3));
475 __ Mov(x27, Operand(w13, UXTW, 4));
armvixlf37fdc02014-02-05 13:22:16 +0000476
armvixlb0c8ae22014-03-21 14:03:59 +0000477 __ Mov(x28, 0x0123456789abcdef);
armvixlf37fdc02014-02-05 13:22:16 +0000478 __ Mov(w28, w28, kDiscardForSameWReg);
armvixlad96eda2013-06-14 11:42:37 +0100479 END();
480
481 RUN();
482
armvixlb0c8ae22014-03-21 14:03:59 +0000483 ASSERT_EQUAL_64(0x0123456789abcdef, x0);
484 ASSERT_EQUAL_64(0x00000000abcd0000, x1);
485 ASSERT_EQUAL_64(0xffffabcdffffffff, x2);
486 ASSERT_EQUAL_64(0x5432ffffffffffff, x3);
armvixlad96eda2013-06-14 11:42:37 +0100487 ASSERT_EQUAL_64(x4, x5);
488 ASSERT_EQUAL_32(-1, w6);
armvixlb0c8ae22014-03-21 14:03:59 +0000489 ASSERT_EQUAL_64(0x0123456789abcdef, x7);
490 ASSERT_EQUAL_32(0x89abcdef, w8);
491 ASSERT_EQUAL_64(0x0123456789abcdef, x9);
492 ASSERT_EQUAL_32(0x89abcdef, w10);
armvixlad96eda2013-06-14 11:42:37 +0100493 ASSERT_EQUAL_64(0x00000fff, x11);
armvixlb0c8ae22014-03-21 14:03:59 +0000494 ASSERT_EQUAL_64(0x0000000000000fff, x12);
armvixlad96eda2013-06-14 11:42:37 +0100495 ASSERT_EQUAL_64(0x00001ffe, x13);
armvixlb0c8ae22014-03-21 14:03:59 +0000496 ASSERT_EQUAL_64(0x0000000000003ffc, x14);
armvixlad96eda2013-06-14 11:42:37 +0100497 ASSERT_EQUAL_64(0x000001ff, x15);
armvixlb0c8ae22014-03-21 14:03:59 +0000498 ASSERT_EQUAL_64(0x00000000000000ff, x18);
armvixlad96eda2013-06-14 11:42:37 +0100499 ASSERT_EQUAL_64(0x00000001, x19);
armvixlb0c8ae22014-03-21 14:03:59 +0000500 ASSERT_EQUAL_64(0x0000000000000000, x20);
armvixlad96eda2013-06-14 11:42:37 +0100501 ASSERT_EQUAL_64(0x7ff80000, x21);
armvixlb0c8ae22014-03-21 14:03:59 +0000502 ASSERT_EQUAL_64(0x3ffc000000000000, x22);
armvixlad96eda2013-06-14 11:42:37 +0100503 ASSERT_EQUAL_64(0x000000fe, x23);
armvixlb0c8ae22014-03-21 14:03:59 +0000504 ASSERT_EQUAL_64(0xfffffffffffffffc, x24);
armvixlad96eda2013-06-14 11:42:37 +0100505 ASSERT_EQUAL_64(0x00007ff8, x25);
armvixlb0c8ae22014-03-21 14:03:59 +0000506 ASSERT_EQUAL_64(0x000000000000fff0, x26);
507 ASSERT_EQUAL_64(0x000000000001ffe0, x27);
508 ASSERT_EQUAL_64(0x0123456789abcdef, x28);
armvixlad96eda2013-06-14 11:42:37 +0100509
510 TEARDOWN();
511}
512
513
514TEST(orr) {
515 SETUP();
516
517 START();
518 __ Mov(x0, 0xf0f0);
519 __ Mov(x1, 0xf00000ff);
520
521 __ Orr(x2, x0, Operand(x1));
522 __ Orr(w3, w0, Operand(w1, LSL, 28));
523 __ Orr(x4, x0, Operand(x1, LSL, 32));
524 __ Orr(x5, x0, Operand(x1, LSR, 4));
525 __ Orr(w6, w0, Operand(w1, ASR, 4));
526 __ Orr(x7, x0, Operand(x1, ASR, 4));
527 __ Orr(w8, w0, Operand(w1, ROR, 12));
528 __ Orr(x9, x0, Operand(x1, ROR, 12));
armvixlb0c8ae22014-03-21 14:03:59 +0000529 __ Orr(w10, w0, 0xf);
530 __ Orr(x11, x0, 0xf0000000f0000000);
armvixlad96eda2013-06-14 11:42:37 +0100531 END();
532
533 RUN();
534
armvixlb0c8ae22014-03-21 14:03:59 +0000535 ASSERT_EQUAL_64(0x00000000f000f0ff, x2);
armvixlad96eda2013-06-14 11:42:37 +0100536 ASSERT_EQUAL_64(0xf000f0f0, x3);
armvixlb0c8ae22014-03-21 14:03:59 +0000537 ASSERT_EQUAL_64(0xf00000ff0000f0f0, x4);
538 ASSERT_EQUAL_64(0x000000000f00f0ff, x5);
armvixlad96eda2013-06-14 11:42:37 +0100539 ASSERT_EQUAL_64(0xff00f0ff, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000540 ASSERT_EQUAL_64(0x000000000f00f0ff, x7);
armvixlad96eda2013-06-14 11:42:37 +0100541 ASSERT_EQUAL_64(0x0ffff0f0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000542 ASSERT_EQUAL_64(0x0ff00000000ff0f0, x9);
543 ASSERT_EQUAL_64(0x0000f0ff, x10);
544 ASSERT_EQUAL_64(0xf0000000f000f0f0, x11);
armvixlad96eda2013-06-14 11:42:37 +0100545
546 TEARDOWN();
547}
548
549
550TEST(orr_extend) {
551 SETUP();
552
553 START();
554 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +0000555 __ Mov(x1, 0x8000000080008080);
armvixlad96eda2013-06-14 11:42:37 +0100556 __ Orr(w6, w0, Operand(w1, UXTB));
557 __ Orr(x7, x0, Operand(x1, UXTH, 1));
558 __ Orr(w8, w0, Operand(w1, UXTW, 2));
559 __ Orr(x9, x0, Operand(x1, UXTX, 3));
560 __ Orr(w10, w0, Operand(w1, SXTB));
561 __ Orr(x11, x0, Operand(x1, SXTH, 1));
562 __ Orr(x12, x0, Operand(x1, SXTW, 2));
563 __ Orr(x13, x0, Operand(x1, SXTX, 3));
564 END();
565
566 RUN();
567
568 ASSERT_EQUAL_64(0x00000081, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000569 ASSERT_EQUAL_64(0x0000000000010101, x7);
armvixlad96eda2013-06-14 11:42:37 +0100570 ASSERT_EQUAL_64(0x00020201, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000571 ASSERT_EQUAL_64(0x0000000400040401, x9);
572 ASSERT_EQUAL_64(0xffffff81, x10);
573 ASSERT_EQUAL_64(0xffffffffffff0101, x11);
574 ASSERT_EQUAL_64(0xfffffffe00020201, x12);
575 ASSERT_EQUAL_64(0x0000000400040401, x13);
armvixlad96eda2013-06-14 11:42:37 +0100576
577 TEARDOWN();
578}
579
580
581TEST(bitwise_wide_imm) {
582 SETUP();
583
584 START();
585 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +0000586 __ Mov(x1, 0xf0f0f0f0f0f0f0f0);
armvixlad96eda2013-06-14 11:42:37 +0100587
armvixlb0c8ae22014-03-21 14:03:59 +0000588 __ Orr(x10, x0, 0x1234567890abcdef);
589 __ Orr(w11, w1, 0x90abcdef);
armvixl4a102ba2014-07-14 09:02:40 +0100590
591 __ Orr(w12, w0, kWMinInt);
592 __ Eor(w13, w0, kWMinInt);
armvixlad96eda2013-06-14 11:42:37 +0100593 END();
594
595 RUN();
596
597 ASSERT_EQUAL_64(0, x0);
armvixlb0c8ae22014-03-21 14:03:59 +0000598 ASSERT_EQUAL_64(0xf0f0f0f0f0f0f0f0, x1);
599 ASSERT_EQUAL_64(0x1234567890abcdef, x10);
600 ASSERT_EQUAL_64(0x00000000f0fbfdff, x11);
armvixl4a102ba2014-07-14 09:02:40 +0100601 ASSERT_EQUAL_32(kWMinInt, w12);
602 ASSERT_EQUAL_32(kWMinInt, w13);
armvixlad96eda2013-06-14 11:42:37 +0100603
604 TEARDOWN();
605}
606
607
608TEST(orn) {
609 SETUP();
610
611 START();
612 __ Mov(x0, 0xf0f0);
613 __ Mov(x1, 0xf00000ff);
614
615 __ Orn(x2, x0, Operand(x1));
616 __ Orn(w3, w0, Operand(w1, LSL, 4));
617 __ Orn(x4, x0, Operand(x1, LSL, 4));
618 __ Orn(x5, x0, Operand(x1, LSR, 1));
619 __ Orn(w6, w0, Operand(w1, ASR, 1));
620 __ Orn(x7, x0, Operand(x1, ASR, 1));
621 __ Orn(w8, w0, Operand(w1, ROR, 16));
622 __ Orn(x9, x0, Operand(x1, ROR, 16));
armvixlb0c8ae22014-03-21 14:03:59 +0000623 __ Orn(w10, w0, 0x0000ffff);
624 __ Orn(x11, x0, 0x0000ffff0000ffff);
armvixlad96eda2013-06-14 11:42:37 +0100625 END();
626
627 RUN();
628
armvixlb0c8ae22014-03-21 14:03:59 +0000629 ASSERT_EQUAL_64(0xffffffff0ffffff0, x2);
armvixlad96eda2013-06-14 11:42:37 +0100630 ASSERT_EQUAL_64(0xfffff0ff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +0000631 ASSERT_EQUAL_64(0xfffffff0fffff0ff, x4);
632 ASSERT_EQUAL_64(0xffffffff87fffff0, x5);
armvixlad96eda2013-06-14 11:42:37 +0100633 ASSERT_EQUAL_64(0x07fffff0, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000634 ASSERT_EQUAL_64(0xffffffff87fffff0, x7);
armvixlad96eda2013-06-14 11:42:37 +0100635 ASSERT_EQUAL_64(0xff00ffff, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000636 ASSERT_EQUAL_64(0xff00ffffffffffff, x9);
armvixlad96eda2013-06-14 11:42:37 +0100637 ASSERT_EQUAL_64(0xfffff0f0, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000638 ASSERT_EQUAL_64(0xffff0000fffff0f0, x11);
armvixlad96eda2013-06-14 11:42:37 +0100639
640 TEARDOWN();
641}
642
643
644TEST(orn_extend) {
645 SETUP();
646
647 START();
648 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +0000649 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100650 __ Orn(w6, w0, Operand(w1, UXTB));
651 __ Orn(x7, x0, Operand(x1, UXTH, 1));
652 __ Orn(w8, w0, Operand(w1, UXTW, 2));
653 __ Orn(x9, x0, Operand(x1, UXTX, 3));
654 __ Orn(w10, w0, Operand(w1, SXTB));
655 __ Orn(x11, x0, Operand(x1, SXTH, 1));
656 __ Orn(x12, x0, Operand(x1, SXTW, 2));
657 __ Orn(x13, x0, Operand(x1, SXTX, 3));
658 END();
659
660 RUN();
661
662 ASSERT_EQUAL_64(0xffffff7f, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000663 ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
armvixlad96eda2013-06-14 11:42:37 +0100664 ASSERT_EQUAL_64(0xfffdfdfb, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000665 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
armvixlad96eda2013-06-14 11:42:37 +0100666 ASSERT_EQUAL_64(0x0000007f, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000667 ASSERT_EQUAL_64(0x000000000000fefd, x11);
668 ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
669 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
armvixlad96eda2013-06-14 11:42:37 +0100670
671 TEARDOWN();
672}
673
674
675TEST(and_) {
676 SETUP();
677
678 START();
679 __ Mov(x0, 0xfff0);
680 __ Mov(x1, 0xf00000ff);
681
682 __ And(x2, x0, Operand(x1));
683 __ And(w3, w0, Operand(w1, LSL, 4));
684 __ And(x4, x0, Operand(x1, LSL, 4));
685 __ And(x5, x0, Operand(x1, LSR, 1));
686 __ And(w6, w0, Operand(w1, ASR, 20));
687 __ And(x7, x0, Operand(x1, ASR, 20));
688 __ And(w8, w0, Operand(w1, ROR, 28));
689 __ And(x9, x0, Operand(x1, ROR, 28));
690 __ And(w10, w0, Operand(0xff00));
691 __ And(x11, x0, Operand(0xff));
692 END();
693
694 RUN();
695
696 ASSERT_EQUAL_64(0x000000f0, x2);
697 ASSERT_EQUAL_64(0x00000ff0, x3);
698 ASSERT_EQUAL_64(0x00000ff0, x4);
699 ASSERT_EQUAL_64(0x00000070, x5);
700 ASSERT_EQUAL_64(0x0000ff00, x6);
701 ASSERT_EQUAL_64(0x00000f00, x7);
702 ASSERT_EQUAL_64(0x00000ff0, x8);
703 ASSERT_EQUAL_64(0x00000000, x9);
704 ASSERT_EQUAL_64(0x0000ff00, x10);
705 ASSERT_EQUAL_64(0x000000f0, x11);
706
707 TEARDOWN();
708}
709
710
711TEST(and_extend) {
712 SETUP();
713
714 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000715 __ Mov(x0, 0xffffffffffffffff);
716 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100717 __ And(w6, w0, Operand(w1, UXTB));
718 __ And(x7, x0, Operand(x1, UXTH, 1));
719 __ And(w8, w0, Operand(w1, UXTW, 2));
720 __ And(x9, x0, Operand(x1, UXTX, 3));
721 __ And(w10, w0, Operand(w1, SXTB));
722 __ And(x11, x0, Operand(x1, SXTH, 1));
723 __ And(x12, x0, Operand(x1, SXTW, 2));
724 __ And(x13, x0, Operand(x1, SXTX, 3));
725 END();
726
727 RUN();
728
729 ASSERT_EQUAL_64(0x00000081, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000730 ASSERT_EQUAL_64(0x0000000000010102, x7);
armvixlad96eda2013-06-14 11:42:37 +0100731 ASSERT_EQUAL_64(0x00020204, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000732 ASSERT_EQUAL_64(0x0000000400040408, x9);
armvixlad96eda2013-06-14 11:42:37 +0100733 ASSERT_EQUAL_64(0xffffff81, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000734 ASSERT_EQUAL_64(0xffffffffffff0102, x11);
735 ASSERT_EQUAL_64(0xfffffffe00020204, x12);
736 ASSERT_EQUAL_64(0x0000000400040408, x13);
armvixlad96eda2013-06-14 11:42:37 +0100737
738 TEARDOWN();
739}
740
741
742TEST(ands) {
743 SETUP();
744
745 START();
746 __ Mov(x1, 0xf00000ff);
armvixlf37fdc02014-02-05 13:22:16 +0000747 __ Ands(w0, w1, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +0100748 END();
749
750 RUN();
751
752 ASSERT_EQUAL_NZCV(NFlag);
753 ASSERT_EQUAL_64(0xf00000ff, x0);
754
755 START();
756 __ Mov(x0, 0xfff0);
757 __ Mov(x1, 0xf00000ff);
armvixlf37fdc02014-02-05 13:22:16 +0000758 __ Ands(w0, w0, Operand(w1, LSR, 4));
armvixlad96eda2013-06-14 11:42:37 +0100759 END();
760
761 RUN();
762
763 ASSERT_EQUAL_NZCV(ZFlag);
764 ASSERT_EQUAL_64(0x00000000, x0);
765
766 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000767 __ Mov(x0, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +0100768 __ Mov(x1, 0x00000001);
armvixlf37fdc02014-02-05 13:22:16 +0000769 __ Ands(x0, x0, Operand(x1, ROR, 1));
armvixlad96eda2013-06-14 11:42:37 +0100770 END();
771
772 RUN();
773
774 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +0000775 ASSERT_EQUAL_64(0x8000000000000000, x0);
armvixlad96eda2013-06-14 11:42:37 +0100776
777 START();
778 __ Mov(x0, 0xfff0);
armvixlf37fdc02014-02-05 13:22:16 +0000779 __ Ands(w0, w0, Operand(0xf));
armvixlad96eda2013-06-14 11:42:37 +0100780 END();
781
782 RUN();
783
784 ASSERT_EQUAL_NZCV(ZFlag);
785 ASSERT_EQUAL_64(0x00000000, x0);
786
787 START();
788 __ Mov(x0, 0xff000000);
armvixlf37fdc02014-02-05 13:22:16 +0000789 __ Ands(w0, w0, Operand(0x80000000));
armvixlad96eda2013-06-14 11:42:37 +0100790 END();
791
792 RUN();
793
794 ASSERT_EQUAL_NZCV(NFlag);
795 ASSERT_EQUAL_64(0x80000000, x0);
796
797 TEARDOWN();
798}
799
800
801TEST(bic) {
802 SETUP();
803
804 START();
805 __ Mov(x0, 0xfff0);
806 __ Mov(x1, 0xf00000ff);
807
808 __ Bic(x2, x0, Operand(x1));
809 __ Bic(w3, w0, Operand(w1, LSL, 4));
810 __ Bic(x4, x0, Operand(x1, LSL, 4));
811 __ Bic(x5, x0, Operand(x1, LSR, 1));
812 __ Bic(w6, w0, Operand(w1, ASR, 20));
813 __ Bic(x7, x0, Operand(x1, ASR, 20));
814 __ Bic(w8, w0, Operand(w1, ROR, 28));
815 __ Bic(x9, x0, Operand(x1, ROR, 24));
816 __ Bic(x10, x0, Operand(0x1f));
817 __ Bic(x11, x0, Operand(0x100));
818
819 // Test bic into sp when the constant cannot be encoded in the immediate
820 // field.
821 // Use x20 to preserve sp. We check for the result via x21 because the
822 // test infrastructure requires that sp be restored to its original value.
823 __ Mov(x20, sp);
824 __ Mov(x0, 0xffffff);
825 __ Bic(sp, x0, Operand(0xabcdef));
826 __ Mov(x21, sp);
827 __ Mov(sp, x20);
828 END();
829
830 RUN();
831
832 ASSERT_EQUAL_64(0x0000ff00, x2);
833 ASSERT_EQUAL_64(0x0000f000, x3);
834 ASSERT_EQUAL_64(0x0000f000, x4);
835 ASSERT_EQUAL_64(0x0000ff80, x5);
836 ASSERT_EQUAL_64(0x000000f0, x6);
837 ASSERT_EQUAL_64(0x0000f0f0, x7);
838 ASSERT_EQUAL_64(0x0000f000, x8);
839 ASSERT_EQUAL_64(0x0000ff00, x9);
840 ASSERT_EQUAL_64(0x0000ffe0, x10);
841 ASSERT_EQUAL_64(0x0000fef0, x11);
842
843 ASSERT_EQUAL_64(0x543210, x21);
844
845 TEARDOWN();
846}
847
848
849TEST(bic_extend) {
850 SETUP();
851
852 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000853 __ Mov(x0, 0xffffffffffffffff);
854 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100855 __ Bic(w6, w0, Operand(w1, UXTB));
856 __ Bic(x7, x0, Operand(x1, UXTH, 1));
857 __ Bic(w8, w0, Operand(w1, UXTW, 2));
858 __ Bic(x9, x0, Operand(x1, UXTX, 3));
859 __ Bic(w10, w0, Operand(w1, SXTB));
860 __ Bic(x11, x0, Operand(x1, SXTH, 1));
861 __ Bic(x12, x0, Operand(x1, SXTW, 2));
862 __ Bic(x13, x0, Operand(x1, SXTX, 3));
863 END();
864
865 RUN();
866
867 ASSERT_EQUAL_64(0xffffff7e, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000868 ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
armvixlad96eda2013-06-14 11:42:37 +0100869 ASSERT_EQUAL_64(0xfffdfdfb, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000870 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
armvixlad96eda2013-06-14 11:42:37 +0100871 ASSERT_EQUAL_64(0x0000007e, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000872 ASSERT_EQUAL_64(0x000000000000fefd, x11);
873 ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
874 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
armvixlad96eda2013-06-14 11:42:37 +0100875
876 TEARDOWN();
877}
878
879
880TEST(bics) {
881 SETUP();
882
883 START();
884 __ Mov(x1, 0xffff);
armvixlf37fdc02014-02-05 13:22:16 +0000885 __ Bics(w0, w1, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +0100886 END();
887
888 RUN();
889
890 ASSERT_EQUAL_NZCV(ZFlag);
891 ASSERT_EQUAL_64(0x00000000, x0);
892
893 START();
894 __ Mov(x0, 0xffffffff);
armvixlf37fdc02014-02-05 13:22:16 +0000895 __ Bics(w0, w0, Operand(w0, LSR, 1));
armvixlad96eda2013-06-14 11:42:37 +0100896 END();
897
898 RUN();
899
900 ASSERT_EQUAL_NZCV(NFlag);
901 ASSERT_EQUAL_64(0x80000000, x0);
902
903 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000904 __ Mov(x0, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +0100905 __ Mov(x1, 0x00000001);
armvixlf37fdc02014-02-05 13:22:16 +0000906 __ Bics(x0, x0, Operand(x1, ROR, 1));
armvixlad96eda2013-06-14 11:42:37 +0100907 END();
908
909 RUN();
910
911 ASSERT_EQUAL_NZCV(ZFlag);
912 ASSERT_EQUAL_64(0x00000000, x0);
913
914 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000915 __ Mov(x0, 0xffffffffffffffff);
916 __ Bics(x0, x0, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +0100917 END();
918
919 RUN();
920
921 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +0000922 ASSERT_EQUAL_64(0x8000000000000000, x0);
armvixlad96eda2013-06-14 11:42:37 +0100923
924 START();
925 __ Mov(w0, 0xffff0000);
armvixlb0c8ae22014-03-21 14:03:59 +0000926 __ Bics(w0, w0, 0xfffffff0);
armvixlad96eda2013-06-14 11:42:37 +0100927 END();
928
929 RUN();
930
931 ASSERT_EQUAL_NZCV(ZFlag);
932 ASSERT_EQUAL_64(0x00000000, x0);
933
934 TEARDOWN();
935}
936
937
938TEST(eor) {
939 SETUP();
940
941 START();
942 __ Mov(x0, 0xfff0);
943 __ Mov(x1, 0xf00000ff);
944
945 __ Eor(x2, x0, Operand(x1));
946 __ Eor(w3, w0, Operand(w1, LSL, 4));
947 __ Eor(x4, x0, Operand(x1, LSL, 4));
948 __ Eor(x5, x0, Operand(x1, LSR, 1));
949 __ Eor(w6, w0, Operand(w1, ASR, 20));
950 __ Eor(x7, x0, Operand(x1, ASR, 20));
951 __ Eor(w8, w0, Operand(w1, ROR, 28));
952 __ Eor(x9, x0, Operand(x1, ROR, 28));
armvixlb0c8ae22014-03-21 14:03:59 +0000953 __ Eor(w10, w0, 0xff00ff00);
954 __ Eor(x11, x0, 0xff00ff00ff00ff00);
armvixlad96eda2013-06-14 11:42:37 +0100955 END();
956
957 RUN();
958
armvixlb0c8ae22014-03-21 14:03:59 +0000959 ASSERT_EQUAL_64(0x00000000f000ff0f, x2);
armvixlad96eda2013-06-14 11:42:37 +0100960 ASSERT_EQUAL_64(0x0000f000, x3);
armvixlb0c8ae22014-03-21 14:03:59 +0000961 ASSERT_EQUAL_64(0x0000000f0000f000, x4);
962 ASSERT_EQUAL_64(0x000000007800ff8f, x5);
armvixlad96eda2013-06-14 11:42:37 +0100963 ASSERT_EQUAL_64(0xffff00f0, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000964 ASSERT_EQUAL_64(0x000000000000f0f0, x7);
armvixlad96eda2013-06-14 11:42:37 +0100965 ASSERT_EQUAL_64(0x0000f00f, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000966 ASSERT_EQUAL_64(0x00000ff00000ffff, x9);
armvixlad96eda2013-06-14 11:42:37 +0100967 ASSERT_EQUAL_64(0xff0000f0, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000968 ASSERT_EQUAL_64(0xff00ff00ff0000f0, x11);
armvixlad96eda2013-06-14 11:42:37 +0100969
970 TEARDOWN();
971}
972
973TEST(eor_extend) {
974 SETUP();
975
976 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000977 __ Mov(x0, 0x1111111111111111);
978 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100979 __ Eor(w6, w0, Operand(w1, UXTB));
980 __ Eor(x7, x0, Operand(x1, UXTH, 1));
981 __ Eor(w8, w0, Operand(w1, UXTW, 2));
982 __ Eor(x9, x0, Operand(x1, UXTX, 3));
983 __ Eor(w10, w0, Operand(w1, SXTB));
984 __ Eor(x11, x0, Operand(x1, SXTH, 1));
985 __ Eor(x12, x0, Operand(x1, SXTW, 2));
986 __ Eor(x13, x0, Operand(x1, SXTX, 3));
987 END();
988
989 RUN();
990
991 ASSERT_EQUAL_64(0x11111190, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000992 ASSERT_EQUAL_64(0x1111111111101013, x7);
armvixlad96eda2013-06-14 11:42:37 +0100993 ASSERT_EQUAL_64(0x11131315, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000994 ASSERT_EQUAL_64(0x1111111511151519, x9);
armvixlad96eda2013-06-14 11:42:37 +0100995 ASSERT_EQUAL_64(0xeeeeee90, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000996 ASSERT_EQUAL_64(0xeeeeeeeeeeee1013, x11);
997 ASSERT_EQUAL_64(0xeeeeeeef11131315, x12);
998 ASSERT_EQUAL_64(0x1111111511151519, x13);
armvixlad96eda2013-06-14 11:42:37 +0100999
1000 TEARDOWN();
1001}
1002
1003
1004TEST(eon) {
1005 SETUP();
1006
1007 START();
1008 __ Mov(x0, 0xfff0);
1009 __ Mov(x1, 0xf00000ff);
1010
1011 __ Eon(x2, x0, Operand(x1));
1012 __ Eon(w3, w0, Operand(w1, LSL, 4));
1013 __ Eon(x4, x0, Operand(x1, LSL, 4));
1014 __ Eon(x5, x0, Operand(x1, LSR, 1));
1015 __ Eon(w6, w0, Operand(w1, ASR, 20));
1016 __ Eon(x7, x0, Operand(x1, ASR, 20));
1017 __ Eon(w8, w0, Operand(w1, ROR, 28));
1018 __ Eon(x9, x0, Operand(x1, ROR, 28));
armvixlb0c8ae22014-03-21 14:03:59 +00001019 __ Eon(w10, w0, 0x03c003c0);
1020 __ Eon(x11, x0, 0x0000100000001000);
armvixlad96eda2013-06-14 11:42:37 +01001021 END();
1022
1023 RUN();
1024
armvixlb0c8ae22014-03-21 14:03:59 +00001025 ASSERT_EQUAL_64(0xffffffff0fff00f0, x2);
armvixlad96eda2013-06-14 11:42:37 +01001026 ASSERT_EQUAL_64(0xffff0fff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00001027 ASSERT_EQUAL_64(0xfffffff0ffff0fff, x4);
1028 ASSERT_EQUAL_64(0xffffffff87ff0070, x5);
armvixlad96eda2013-06-14 11:42:37 +01001029 ASSERT_EQUAL_64(0x0000ff0f, x6);
armvixlb0c8ae22014-03-21 14:03:59 +00001030 ASSERT_EQUAL_64(0xffffffffffff0f0f, x7);
armvixlad96eda2013-06-14 11:42:37 +01001031 ASSERT_EQUAL_64(0xffff0ff0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001032 ASSERT_EQUAL_64(0xfffff00fffff0000, x9);
armvixlad96eda2013-06-14 11:42:37 +01001033 ASSERT_EQUAL_64(0xfc3f03cf, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00001034 ASSERT_EQUAL_64(0xffffefffffff100f, x11);
armvixlad96eda2013-06-14 11:42:37 +01001035
1036 TEARDOWN();
1037}
1038
1039
1040TEST(eon_extend) {
1041 SETUP();
1042
1043 START();
armvixlb0c8ae22014-03-21 14:03:59 +00001044 __ Mov(x0, 0x1111111111111111);
1045 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +01001046 __ Eon(w6, w0, Operand(w1, UXTB));
1047 __ Eon(x7, x0, Operand(x1, UXTH, 1));
1048 __ Eon(w8, w0, Operand(w1, UXTW, 2));
1049 __ Eon(x9, x0, Operand(x1, UXTX, 3));
1050 __ Eon(w10, w0, Operand(w1, SXTB));
1051 __ Eon(x11, x0, Operand(x1, SXTH, 1));
1052 __ Eon(x12, x0, Operand(x1, SXTW, 2));
1053 __ Eon(x13, x0, Operand(x1, SXTX, 3));
1054 END();
1055
1056 RUN();
1057
1058 ASSERT_EQUAL_64(0xeeeeee6f, x6);
armvixlb0c8ae22014-03-21 14:03:59 +00001059 ASSERT_EQUAL_64(0xeeeeeeeeeeefefec, x7);
armvixlad96eda2013-06-14 11:42:37 +01001060 ASSERT_EQUAL_64(0xeeececea, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001061 ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x9);
armvixlad96eda2013-06-14 11:42:37 +01001062 ASSERT_EQUAL_64(0x1111116f, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00001063 ASSERT_EQUAL_64(0x111111111111efec, x11);
1064 ASSERT_EQUAL_64(0x11111110eeececea, x12);
1065 ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x13);
armvixlad96eda2013-06-14 11:42:37 +01001066
1067 TEARDOWN();
1068}
1069
1070
1071TEST(mul) {
1072 SETUP();
1073
1074 START();
armvixl6e2c8272015-03-31 11:04:14 +01001075 __ Mov(x25, 0);
1076 __ Mov(x26, 1);
armvixlad96eda2013-06-14 11:42:37 +01001077 __ Mov(x18, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001078 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001079
armvixl6e2c8272015-03-31 11:04:14 +01001080 __ Mul(w0, w25, w25);
1081 __ Mul(w1, w25, w26);
1082 __ Mul(w2, w26, w18);
armvixlad96eda2013-06-14 11:42:37 +01001083 __ Mul(w3, w18, w19);
armvixl6e2c8272015-03-31 11:04:14 +01001084 __ Mul(x4, x25, x25);
1085 __ Mul(x5, x26, x18);
armvixlad96eda2013-06-14 11:42:37 +01001086 __ Mul(x6, x18, x19);
1087 __ Mul(x7, x19, x19);
armvixl6e2c8272015-03-31 11:04:14 +01001088 __ Smull(x8, w26, w18);
armvixlad96eda2013-06-14 11:42:37 +01001089 __ Smull(x9, w18, w18);
1090 __ Smull(x10, w19, w19);
armvixl6e2c8272015-03-31 11:04:14 +01001091 __ Mneg(w11, w25, w25);
1092 __ Mneg(w12, w25, w26);
1093 __ Mneg(w13, w26, w18);
armvixlad96eda2013-06-14 11:42:37 +01001094 __ Mneg(w14, w18, w19);
armvixl6e2c8272015-03-31 11:04:14 +01001095 __ Mneg(x20, x25, x25);
1096 __ Mneg(x21, x26, x18);
armvixlad96eda2013-06-14 11:42:37 +01001097 __ Mneg(x22, x18, x19);
1098 __ Mneg(x23, x19, x19);
1099 END();
1100
1101 RUN();
1102
1103 ASSERT_EQUAL_64(0, x0);
1104 ASSERT_EQUAL_64(0, x1);
1105 ASSERT_EQUAL_64(0xffffffff, x2);
1106 ASSERT_EQUAL_64(1, x3);
1107 ASSERT_EQUAL_64(0, x4);
1108 ASSERT_EQUAL_64(0xffffffff, x5);
armvixlb0c8ae22014-03-21 14:03:59 +00001109 ASSERT_EQUAL_64(0xffffffff00000001, x6);
armvixlad96eda2013-06-14 11:42:37 +01001110 ASSERT_EQUAL_64(1, x7);
armvixlb0c8ae22014-03-21 14:03:59 +00001111 ASSERT_EQUAL_64(0xffffffffffffffff, x8);
armvixlad96eda2013-06-14 11:42:37 +01001112 ASSERT_EQUAL_64(1, x9);
1113 ASSERT_EQUAL_64(1, x10);
1114 ASSERT_EQUAL_64(0, x11);
1115 ASSERT_EQUAL_64(0, x12);
1116 ASSERT_EQUAL_64(1, x13);
1117 ASSERT_EQUAL_64(0xffffffff, x14);
1118 ASSERT_EQUAL_64(0, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00001119 ASSERT_EQUAL_64(0xffffffff00000001, x21);
armvixlad96eda2013-06-14 11:42:37 +01001120 ASSERT_EQUAL_64(0xffffffff, x22);
armvixlb0c8ae22014-03-21 14:03:59 +00001121 ASSERT_EQUAL_64(0xffffffffffffffff, x23);
armvixlad96eda2013-06-14 11:42:37 +01001122
1123 TEARDOWN();
1124}
1125
1126
armvixlf37fdc02014-02-05 13:22:16 +00001127static void SmullHelper(int64_t expected, int64_t a, int64_t b) {
1128 SETUP();
1129 START();
1130 __ Mov(w0, a);
1131 __ Mov(w1, b);
1132 __ Smull(x2, w0, w1);
1133 END();
1134 RUN();
1135 ASSERT_EQUAL_64(expected, x2);
1136 TEARDOWN();
1137}
1138
1139
1140TEST(smull) {
1141 SmullHelper(0, 0, 0);
1142 SmullHelper(1, 1, 1);
1143 SmullHelper(-1, -1, 1);
1144 SmullHelper(1, -1, -1);
1145 SmullHelper(0xffffffff80000000, 0x80000000, 1);
1146 SmullHelper(0x0000000080000000, 0x00010000, 0x00008000);
1147}
1148
1149
armvixlad96eda2013-06-14 11:42:37 +01001150TEST(madd) {
1151 SETUP();
1152
1153 START();
1154 __ Mov(x16, 0);
1155 __ Mov(x17, 1);
1156 __ Mov(x18, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001157 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001158
1159 __ Madd(w0, w16, w16, w16);
1160 __ Madd(w1, w16, w16, w17);
1161 __ Madd(w2, w16, w16, w18);
1162 __ Madd(w3, w16, w16, w19);
1163 __ Madd(w4, w16, w17, w17);
1164 __ Madd(w5, w17, w17, w18);
1165 __ Madd(w6, w17, w17, w19);
1166 __ Madd(w7, w17, w18, w16);
1167 __ Madd(w8, w17, w18, w18);
1168 __ Madd(w9, w18, w18, w17);
1169 __ Madd(w10, w18, w19, w18);
1170 __ Madd(w11, w19, w19, w19);
1171
1172 __ Madd(x12, x16, x16, x16);
1173 __ Madd(x13, x16, x16, x17);
1174 __ Madd(x14, x16, x16, x18);
1175 __ Madd(x15, x16, x16, x19);
1176 __ Madd(x20, x16, x17, x17);
1177 __ Madd(x21, x17, x17, x18);
1178 __ Madd(x22, x17, x17, x19);
1179 __ Madd(x23, x17, x18, x16);
1180 __ Madd(x24, x17, x18, x18);
1181 __ Madd(x25, x18, x18, x17);
1182 __ Madd(x26, x18, x19, x18);
1183 __ Madd(x27, x19, x19, x19);
1184
1185 END();
1186
1187 RUN();
1188
1189 ASSERT_EQUAL_64(0, x0);
1190 ASSERT_EQUAL_64(1, x1);
1191 ASSERT_EQUAL_64(0xffffffff, x2);
1192 ASSERT_EQUAL_64(0xffffffff, x3);
1193 ASSERT_EQUAL_64(1, x4);
1194 ASSERT_EQUAL_64(0, x5);
1195 ASSERT_EQUAL_64(0, x6);
1196 ASSERT_EQUAL_64(0xffffffff, x7);
1197 ASSERT_EQUAL_64(0xfffffffe, x8);
1198 ASSERT_EQUAL_64(2, x9);
1199 ASSERT_EQUAL_64(0, x10);
1200 ASSERT_EQUAL_64(0, x11);
1201
1202 ASSERT_EQUAL_64(0, x12);
1203 ASSERT_EQUAL_64(1, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00001204 ASSERT_EQUAL_64(0x00000000ffffffff, x14);
armvixlad96eda2013-06-14 11:42:37 +01001205 ASSERT_EQUAL_64(0xffffffffffffffff, x15);
1206 ASSERT_EQUAL_64(1, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00001207 ASSERT_EQUAL_64(0x0000000100000000, x21);
armvixlad96eda2013-06-14 11:42:37 +01001208 ASSERT_EQUAL_64(0, x22);
armvixlb0c8ae22014-03-21 14:03:59 +00001209 ASSERT_EQUAL_64(0x00000000ffffffff, x23);
1210 ASSERT_EQUAL_64(0x00000001fffffffe, x24);
1211 ASSERT_EQUAL_64(0xfffffffe00000002, x25);
armvixlad96eda2013-06-14 11:42:37 +01001212 ASSERT_EQUAL_64(0, x26);
1213 ASSERT_EQUAL_64(0, x27);
1214
1215 TEARDOWN();
1216}
1217
1218
1219TEST(msub) {
1220 SETUP();
1221
1222 START();
1223 __ Mov(x16, 0);
1224 __ Mov(x17, 1);
1225 __ Mov(x18, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001226 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001227
1228 __ Msub(w0, w16, w16, w16);
1229 __ Msub(w1, w16, w16, w17);
1230 __ Msub(w2, w16, w16, w18);
1231 __ Msub(w3, w16, w16, w19);
1232 __ Msub(w4, w16, w17, w17);
1233 __ Msub(w5, w17, w17, w18);
1234 __ Msub(w6, w17, w17, w19);
1235 __ Msub(w7, w17, w18, w16);
1236 __ Msub(w8, w17, w18, w18);
1237 __ Msub(w9, w18, w18, w17);
1238 __ Msub(w10, w18, w19, w18);
1239 __ Msub(w11, w19, w19, w19);
1240
1241 __ Msub(x12, x16, x16, x16);
1242 __ Msub(x13, x16, x16, x17);
1243 __ Msub(x14, x16, x16, x18);
1244 __ Msub(x15, x16, x16, x19);
1245 __ Msub(x20, x16, x17, x17);
1246 __ Msub(x21, x17, x17, x18);
1247 __ Msub(x22, x17, x17, x19);
1248 __ Msub(x23, x17, x18, x16);
1249 __ Msub(x24, x17, x18, x18);
1250 __ Msub(x25, x18, x18, x17);
1251 __ Msub(x26, x18, x19, x18);
1252 __ Msub(x27, x19, x19, x19);
1253
1254 END();
1255
1256 RUN();
1257
1258 ASSERT_EQUAL_64(0, x0);
1259 ASSERT_EQUAL_64(1, x1);
1260 ASSERT_EQUAL_64(0xffffffff, x2);
1261 ASSERT_EQUAL_64(0xffffffff, x3);
1262 ASSERT_EQUAL_64(1, x4);
1263 ASSERT_EQUAL_64(0xfffffffe, x5);
1264 ASSERT_EQUAL_64(0xfffffffe, x6);
1265 ASSERT_EQUAL_64(1, x7);
1266 ASSERT_EQUAL_64(0, x8);
1267 ASSERT_EQUAL_64(0, x9);
1268 ASSERT_EQUAL_64(0xfffffffe, x10);
1269 ASSERT_EQUAL_64(0xfffffffe, x11);
1270
1271 ASSERT_EQUAL_64(0, x12);
1272 ASSERT_EQUAL_64(1, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00001273 ASSERT_EQUAL_64(0x00000000ffffffff, x14);
1274 ASSERT_EQUAL_64(0xffffffffffffffff, x15);
armvixlad96eda2013-06-14 11:42:37 +01001275 ASSERT_EQUAL_64(1, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00001276 ASSERT_EQUAL_64(0x00000000fffffffe, x21);
1277 ASSERT_EQUAL_64(0xfffffffffffffffe, x22);
1278 ASSERT_EQUAL_64(0xffffffff00000001, x23);
armvixlad96eda2013-06-14 11:42:37 +01001279 ASSERT_EQUAL_64(0, x24);
armvixlb0c8ae22014-03-21 14:03:59 +00001280 ASSERT_EQUAL_64(0x0000000200000000, x25);
1281 ASSERT_EQUAL_64(0x00000001fffffffe, x26);
1282 ASSERT_EQUAL_64(0xfffffffffffffffe, x27);
armvixlad96eda2013-06-14 11:42:37 +01001283
1284 TEARDOWN();
1285}
1286
1287
1288TEST(smulh) {
1289 SETUP();
1290
1291 START();
1292 __ Mov(x20, 0);
1293 __ Mov(x21, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00001294 __ Mov(x22, 0x0000000100000000);
1295 __ Mov(x23, 0x0000000012345678);
1296 __ Mov(x24, 0x0123456789abcdef);
1297 __ Mov(x25, 0x0000000200000000);
1298 __ Mov(x26, 0x8000000000000000);
1299 __ Mov(x27, 0xffffffffffffffff);
1300 __ Mov(x28, 0x5555555555555555);
1301 __ Mov(x29, 0xaaaaaaaaaaaaaaaa);
armvixlad96eda2013-06-14 11:42:37 +01001302
1303 __ Smulh(x0, x20, x24);
1304 __ Smulh(x1, x21, x24);
1305 __ Smulh(x2, x22, x23);
1306 __ Smulh(x3, x22, x24);
1307 __ Smulh(x4, x24, x25);
1308 __ Smulh(x5, x23, x27);
1309 __ Smulh(x6, x26, x26);
1310 __ Smulh(x7, x26, x27);
1311 __ Smulh(x8, x27, x27);
1312 __ Smulh(x9, x28, x28);
1313 __ Smulh(x10, x28, x29);
1314 __ Smulh(x11, x29, x29);
1315 END();
1316
1317 RUN();
1318
1319 ASSERT_EQUAL_64(0, x0);
1320 ASSERT_EQUAL_64(0, x1);
1321 ASSERT_EQUAL_64(0, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00001322 ASSERT_EQUAL_64(0x0000000001234567, x3);
1323 ASSERT_EQUAL_64(0x0000000002468acf, x4);
1324 ASSERT_EQUAL_64(0xffffffffffffffff, x5);
1325 ASSERT_EQUAL_64(0x4000000000000000, x6);
armvixlad96eda2013-06-14 11:42:37 +01001326 ASSERT_EQUAL_64(0, x7);
1327 ASSERT_EQUAL_64(0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001328 ASSERT_EQUAL_64(0x1c71c71c71c71c71, x9);
1329 ASSERT_EQUAL_64(0xe38e38e38e38e38e, x10);
1330 ASSERT_EQUAL_64(0x1c71c71c71c71c72, x11);
armvixlad96eda2013-06-14 11:42:37 +01001331
1332 TEARDOWN();
1333}
1334
1335
armvixl6e2c8272015-03-31 11:04:14 +01001336TEST(umulh) {
1337 SETUP();
1338
1339 START();
1340 __ Mov(x20, 0);
1341 __ Mov(x21, 1);
1342 __ Mov(x22, 0x0000000100000000);
1343 __ Mov(x23, 0x0000000012345678);
1344 __ Mov(x24, 0x0123456789abcdef);
1345 __ Mov(x25, 0x0000000200000000);
1346 __ Mov(x26, 0x8000000000000000);
1347 __ Mov(x27, 0xffffffffffffffff);
1348 __ Mov(x28, 0x5555555555555555);
1349 __ Mov(x29, 0xaaaaaaaaaaaaaaaa);
1350
1351 __ Umulh(x0, x20, x24);
1352 __ Umulh(x1, x21, x24);
1353 __ Umulh(x2, x22, x23);
1354 __ Umulh(x3, x22, x24);
1355 __ Umulh(x4, x24, x25);
1356 __ Umulh(x5, x23, x27);
1357 __ Umulh(x6, x26, x26);
1358 __ Umulh(x7, x26, x27);
1359 __ Umulh(x8, x27, x27);
1360 __ Umulh(x9, x28, x28);
1361 __ Umulh(x10, x28, x29);
1362 __ Umulh(x11, x29, x29);
1363 END();
1364
1365 RUN();
1366
1367 ASSERT_EQUAL_64(0, x0);
1368 ASSERT_EQUAL_64(0, x1);
1369 ASSERT_EQUAL_64(0, x2);
1370 ASSERT_EQUAL_64(0x0000000001234567, x3);
1371 ASSERT_EQUAL_64(0x0000000002468acf, x4);
1372 ASSERT_EQUAL_64(0x0000000012345677, x5);
1373 ASSERT_EQUAL_64(0x4000000000000000, x6);
1374 ASSERT_EQUAL_64(0x7fffffffffffffff, x7);
1375 ASSERT_EQUAL_64(0xfffffffffffffffe, x8);
1376 ASSERT_EQUAL_64(0x1c71c71c71c71c71, x9);
1377 ASSERT_EQUAL_64(0x38e38e38e38e38e3, x10);
1378 ASSERT_EQUAL_64(0x71c71c71c71c71c6, x11);
1379
1380 TEARDOWN();
1381}
1382
1383
armvixl5289c592015-03-02 13:52:04 +00001384TEST(smaddl_umaddl_umull) {
armvixlad96eda2013-06-14 11:42:37 +01001385 SETUP();
1386
1387 START();
1388 __ Mov(x17, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00001389 __ Mov(x18, 0x00000000ffffffff);
1390 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001391 __ Mov(x20, 4);
armvixlb0c8ae22014-03-21 14:03:59 +00001392 __ Mov(x21, 0x0000000200000000);
armvixlad96eda2013-06-14 11:42:37 +01001393
1394 __ Smaddl(x9, w17, w18, x20);
1395 __ Smaddl(x10, w18, w18, x20);
1396 __ Smaddl(x11, w19, w19, x20);
1397 __ Smaddl(x12, w19, w19, x21);
1398 __ Umaddl(x13, w17, w18, x20);
1399 __ Umaddl(x14, w18, w18, x20);
1400 __ Umaddl(x15, w19, w19, x20);
1401 __ Umaddl(x22, w19, w19, x21);
armvixl5289c592015-03-02 13:52:04 +00001402 __ Umull(x24, w19, w19);
1403 __ Umull(x25, w17, w18);
armvixlad96eda2013-06-14 11:42:37 +01001404 END();
1405
1406 RUN();
1407
1408 ASSERT_EQUAL_64(3, x9);
1409 ASSERT_EQUAL_64(5, x10);
1410 ASSERT_EQUAL_64(5, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00001411 ASSERT_EQUAL_64(0x0000000200000001, x12);
1412 ASSERT_EQUAL_64(0x0000000100000003, x13);
1413 ASSERT_EQUAL_64(0xfffffffe00000005, x14);
1414 ASSERT_EQUAL_64(0xfffffffe00000005, x15);
1415 ASSERT_EQUAL_64(1, x22);
armvixl5289c592015-03-02 13:52:04 +00001416 ASSERT_EQUAL_64(0xfffffffe00000001, x24);
1417 ASSERT_EQUAL_64(0x00000000ffffffff, x25);
armvixlad96eda2013-06-14 11:42:37 +01001418
1419 TEARDOWN();
1420}
1421
1422
1423TEST(smsubl_umsubl) {
1424 SETUP();
1425
1426 START();
1427 __ Mov(x17, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00001428 __ Mov(x18, 0x00000000ffffffff);
1429 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001430 __ Mov(x20, 4);
armvixlb0c8ae22014-03-21 14:03:59 +00001431 __ Mov(x21, 0x0000000200000000);
armvixlad96eda2013-06-14 11:42:37 +01001432
1433 __ Smsubl(x9, w17, w18, x20);
1434 __ Smsubl(x10, w18, w18, x20);
1435 __ Smsubl(x11, w19, w19, x20);
1436 __ Smsubl(x12, w19, w19, x21);
1437 __ Umsubl(x13, w17, w18, x20);
1438 __ Umsubl(x14, w18, w18, x20);
1439 __ Umsubl(x15, w19, w19, x20);
1440 __ Umsubl(x22, w19, w19, x21);
1441 END();
1442
1443 RUN();
1444
1445 ASSERT_EQUAL_64(5, x9);
1446 ASSERT_EQUAL_64(3, x10);
1447 ASSERT_EQUAL_64(3, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00001448 ASSERT_EQUAL_64(0x00000001ffffffff, x12);
1449 ASSERT_EQUAL_64(0xffffffff00000005, x13);
1450 ASSERT_EQUAL_64(0x0000000200000003, x14);
1451 ASSERT_EQUAL_64(0x0000000200000003, x15);
1452 ASSERT_EQUAL_64(0x00000003ffffffff, x22);
armvixlad96eda2013-06-14 11:42:37 +01001453
1454 TEARDOWN();
1455}
1456
1457
1458TEST(div) {
1459 SETUP();
1460
1461 START();
1462 __ Mov(x16, 1);
1463 __ Mov(x17, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001464 __ Mov(x18, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001465 __ Mov(x19, 0x80000000);
armvixlb0c8ae22014-03-21 14:03:59 +00001466 __ Mov(x20, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01001467 __ Mov(x21, 2);
1468
1469 __ Udiv(w0, w16, w16);
1470 __ Udiv(w1, w17, w16);
1471 __ Sdiv(w2, w16, w16);
1472 __ Sdiv(w3, w16, w17);
1473 __ Sdiv(w4, w17, w18);
1474
1475 __ Udiv(x5, x16, x16);
1476 __ Udiv(x6, x17, x18);
1477 __ Sdiv(x7, x16, x16);
1478 __ Sdiv(x8, x16, x17);
1479 __ Sdiv(x9, x17, x18);
1480
1481 __ Udiv(w10, w19, w21);
1482 __ Sdiv(w11, w19, w21);
1483 __ Udiv(x12, x19, x21);
1484 __ Sdiv(x13, x19, x21);
1485 __ Udiv(x14, x20, x21);
1486 __ Sdiv(x15, x20, x21);
armvixlf37fdc02014-02-05 13:22:16 +00001487
1488 __ Udiv(w22, w19, w17);
1489 __ Sdiv(w23, w19, w17);
1490 __ Udiv(x24, x20, x18);
1491 __ Sdiv(x25, x20, x18);
1492
1493 __ Udiv(x26, x16, x21);
1494 __ Sdiv(x27, x16, x21);
1495 __ Udiv(x28, x18, x21);
1496 __ Sdiv(x29, x18, x21);
1497
1498 __ Mov(x17, 0);
1499 __ Udiv(w18, w16, w17);
1500 __ Sdiv(w19, w16, w17);
1501 __ Udiv(x20, x16, x17);
1502 __ Sdiv(x21, x16, x17);
armvixlad96eda2013-06-14 11:42:37 +01001503 END();
1504
1505 RUN();
1506
1507 ASSERT_EQUAL_64(1, x0);
1508 ASSERT_EQUAL_64(0xffffffff, x1);
1509 ASSERT_EQUAL_64(1, x2);
1510 ASSERT_EQUAL_64(0xffffffff, x3);
1511 ASSERT_EQUAL_64(1, x4);
1512 ASSERT_EQUAL_64(1, x5);
1513 ASSERT_EQUAL_64(0, x6);
1514 ASSERT_EQUAL_64(1, x7);
1515 ASSERT_EQUAL_64(0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001516 ASSERT_EQUAL_64(0xffffffff00000001, x9);
armvixlad96eda2013-06-14 11:42:37 +01001517 ASSERT_EQUAL_64(0x40000000, x10);
armvixl5289c592015-03-02 13:52:04 +00001518 ASSERT_EQUAL_64(0xc0000000, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00001519 ASSERT_EQUAL_64(0x0000000040000000, x12);
1520 ASSERT_EQUAL_64(0x0000000040000000, x13);
1521 ASSERT_EQUAL_64(0x4000000000000000, x14);
armvixl5289c592015-03-02 13:52:04 +00001522 ASSERT_EQUAL_64(0xc000000000000000, x15);
armvixlf37fdc02014-02-05 13:22:16 +00001523 ASSERT_EQUAL_64(0, x22);
1524 ASSERT_EQUAL_64(0x80000000, x23);
1525 ASSERT_EQUAL_64(0, x24);
armvixlb0c8ae22014-03-21 14:03:59 +00001526 ASSERT_EQUAL_64(0x8000000000000000, x25);
armvixlf37fdc02014-02-05 13:22:16 +00001527 ASSERT_EQUAL_64(0, x26);
1528 ASSERT_EQUAL_64(0, x27);
armvixlb0c8ae22014-03-21 14:03:59 +00001529 ASSERT_EQUAL_64(0x7fffffffffffffff, x28);
armvixlf37fdc02014-02-05 13:22:16 +00001530 ASSERT_EQUAL_64(0, x29);
1531 ASSERT_EQUAL_64(0, x18);
1532 ASSERT_EQUAL_64(0, x19);
1533 ASSERT_EQUAL_64(0, x20);
1534 ASSERT_EQUAL_64(0, x21);
armvixlad96eda2013-06-14 11:42:37 +01001535
1536 TEARDOWN();
1537}
1538
1539
1540TEST(rbit_rev) {
1541 SETUP();
1542
1543 START();
armvixlb0c8ae22014-03-21 14:03:59 +00001544 __ Mov(x24, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01001545 __ Rbit(w0, w24);
1546 __ Rbit(x1, x24);
1547 __ Rev16(w2, w24);
1548 __ Rev16(x3, x24);
1549 __ Rev(w4, w24);
1550 __ Rev32(x5, x24);
1551 __ Rev(x6, x24);
1552 END();
1553
1554 RUN();
1555
1556 ASSERT_EQUAL_64(0x084c2a6e, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00001557 ASSERT_EQUAL_64(0x084c2a6e195d3b7f, x1);
armvixlad96eda2013-06-14 11:42:37 +01001558 ASSERT_EQUAL_64(0x54761032, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00001559 ASSERT_EQUAL_64(0xdcfe98ba54761032, x3);
armvixlad96eda2013-06-14 11:42:37 +01001560 ASSERT_EQUAL_64(0x10325476, x4);
armvixlb0c8ae22014-03-21 14:03:59 +00001561 ASSERT_EQUAL_64(0x98badcfe10325476, x5);
1562 ASSERT_EQUAL_64(0x1032547698badcfe, x6);
armvixlad96eda2013-06-14 11:42:37 +01001563
1564 TEARDOWN();
1565}
1566
1567
1568TEST(clz_cls) {
1569 SETUP();
1570
1571 START();
armvixlb0c8ae22014-03-21 14:03:59 +00001572 __ Mov(x24, 0x0008000000800000);
1573 __ Mov(x25, 0xff800000fff80000);
armvixlad96eda2013-06-14 11:42:37 +01001574 __ Mov(x26, 0);
1575 __ Clz(w0, w24);
1576 __ Clz(x1, x24);
1577 __ Clz(w2, w25);
1578 __ Clz(x3, x25);
1579 __ Clz(w4, w26);
1580 __ Clz(x5, x26);
1581 __ Cls(w6, w24);
1582 __ Cls(x7, x24);
1583 __ Cls(w8, w25);
1584 __ Cls(x9, x25);
1585 __ Cls(w10, w26);
1586 __ Cls(x11, x26);
1587 END();
1588
1589 RUN();
1590
1591 ASSERT_EQUAL_64(8, x0);
1592 ASSERT_EQUAL_64(12, x1);
1593 ASSERT_EQUAL_64(0, x2);
1594 ASSERT_EQUAL_64(0, x3);
1595 ASSERT_EQUAL_64(32, x4);
1596 ASSERT_EQUAL_64(64, x5);
1597 ASSERT_EQUAL_64(7, x6);
1598 ASSERT_EQUAL_64(11, x7);
1599 ASSERT_EQUAL_64(12, x8);
1600 ASSERT_EQUAL_64(8, x9);
1601 ASSERT_EQUAL_64(31, x10);
1602 ASSERT_EQUAL_64(63, x11);
1603
1604 TEARDOWN();
1605}
1606
1607
1608TEST(label) {
1609 SETUP();
1610
1611 Label label_1, label_2, label_3, label_4;
1612
1613 START();
1614 __ Mov(x0, 0x1);
1615 __ Mov(x1, 0x0);
1616 __ Mov(x22, lr); // Save lr.
1617
1618 __ B(&label_1);
1619 __ B(&label_1);
1620 __ B(&label_1); // Multiple branches to the same label.
1621 __ Mov(x0, 0x0);
1622 __ Bind(&label_2);
1623 __ B(&label_3); // Forward branch.
1624 __ Mov(x0, 0x0);
1625 __ Bind(&label_1);
1626 __ B(&label_2); // Backward branch.
1627 __ Mov(x0, 0x0);
1628 __ Bind(&label_3);
1629 __ Bl(&label_4);
1630 END();
1631
1632 __ Bind(&label_4);
1633 __ Mov(x1, 0x1);
1634 __ Mov(lr, x22);
1635 END();
1636
1637 RUN();
1638
1639 ASSERT_EQUAL_64(0x1, x0);
1640 ASSERT_EQUAL_64(0x1, x1);
1641
1642 TEARDOWN();
1643}
1644
1645
armvixlc68cb642014-09-25 18:49:30 +01001646TEST(label_2) {
1647 SETUP();
1648
1649 Label label_1, label_2, label_3;
1650 Label first_jump_to_3;
1651
1652 START();
1653 __ Mov(x0, 0x0);
1654
1655 __ B(&label_1);
1656 ptrdiff_t offset_2 = masm.CursorOffset();
1657 __ Orr(x0, x0, 1 << 1);
1658 __ B(&label_3);
1659 ptrdiff_t offset_1 = masm.CursorOffset();
1660 __ Orr(x0, x0, 1 << 0);
1661 __ B(&label_2);
1662 ptrdiff_t offset_3 = masm.CursorOffset();
1663 __ Tbz(x0, 2, &first_jump_to_3);
1664 __ Orr(x0, x0, 1 << 3);
1665 __ Bind(&first_jump_to_3);
1666 __ Orr(x0, x0, 1 << 2);
1667 __ Tbz(x0, 3, &label_3);
1668
1669 // Labels 1, 2, and 3 are bound before the current buffer offset. Branches to
1670 // label_1 and label_2 branch respectively forward and backward. Branches to
1671 // label 3 include both forward and backward branches.
1672 masm.BindToOffset(&label_1, offset_1);
1673 masm.BindToOffset(&label_2, offset_2);
1674 masm.BindToOffset(&label_3, offset_3);
1675
1676 END();
1677
1678 RUN();
1679
1680 ASSERT_EQUAL_64(0xf, x0);
1681
1682 TEARDOWN();
1683}
1684
1685
armvixlad96eda2013-06-14 11:42:37 +01001686TEST(adr) {
1687 SETUP();
1688
1689 Label label_1, label_2, label_3, label_4;
1690
1691 START();
1692 __ Mov(x0, 0x0); // Set to non-zero to indicate failure.
1693 __ Adr(x1, &label_3); // Set to zero to indicate success.
1694
1695 __ Adr(x2, &label_1); // Multiple forward references to the same label.
1696 __ Adr(x3, &label_1);
1697 __ Adr(x4, &label_1);
1698
1699 __ Bind(&label_2);
1700 __ Eor(x5, x2, Operand(x3)); // Ensure that x2,x3 and x4 are identical.
1701 __ Eor(x6, x2, Operand(x4));
1702 __ Orr(x0, x0, Operand(x5));
1703 __ Orr(x0, x0, Operand(x6));
1704 __ Br(x2); // label_1, label_3
1705
1706 __ Bind(&label_3);
1707 __ Adr(x2, &label_3); // Self-reference (offset 0).
1708 __ Eor(x1, x1, Operand(x2));
1709 __ Adr(x2, &label_4); // Simple forward reference.
1710 __ Br(x2); // label_4
1711
1712 __ Bind(&label_1);
1713 __ Adr(x2, &label_3); // Multiple reverse references to the same label.
1714 __ Adr(x3, &label_3);
1715 __ Adr(x4, &label_3);
1716 __ Adr(x5, &label_2); // Simple reverse reference.
1717 __ Br(x5); // label_2
1718
1719 __ Bind(&label_4);
1720 END();
1721
1722 RUN();
1723
1724 ASSERT_EQUAL_64(0x0, x0);
1725 ASSERT_EQUAL_64(0x0, x1);
1726
1727 TEARDOWN();
1728}
1729
1730
armvixl4a102ba2014-07-14 09:02:40 +01001731// Simple adrp tests: check that labels are linked and handled properly.
1732// This is similar to the adr test, but all the adrp instructions are put on the
1733// same page so that they return the same value.
1734TEST(adrp) {
1735 Label start;
1736 Label label_1, label_2, label_3;
1737
1738 SETUP_CUSTOM(2 * kPageSize, PageOffsetDependentCode);
1739 START();
1740
1741 // Waste space until the start of a page.
armvixlc68cb642014-09-25 18:49:30 +01001742 {
1743 InstructionAccurateScope scope(&masm,
1744 kPageSize / kInstructionSize,
1745 InstructionAccurateScope::kMaximumSize);
armvixl4a102ba2014-07-14 09:02:40 +01001746 const uintptr_t kPageOffsetMask = kPageSize - 1;
armvixlc68cb642014-09-25 18:49:30 +01001747 while ((masm.GetCursorAddress<uintptr_t>() & kPageOffsetMask) != 0) {
armvixl4a102ba2014-07-14 09:02:40 +01001748 __ b(&start);
1749 }
1750 __ bind(&start);
1751 }
1752
1753 // Simple forward reference.
1754 __ Adrp(x0, &label_2);
1755
1756 __ Bind(&label_1);
1757
1758 // Multiple forward references to the same label.
1759 __ Adrp(x1, &label_3);
1760 __ Adrp(x2, &label_3);
1761 __ Adrp(x3, &label_3);
1762
1763 __ Bind(&label_2);
1764
1765 // Self-reference (offset 0).
1766 __ Adrp(x4, &label_2);
1767
1768 __ Bind(&label_3);
1769
1770 // Simple reverse reference.
1771 __ Adrp(x5, &label_1);
1772
1773 // Multiple reverse references to the same label.
1774 __ Adrp(x6, &label_2);
1775 __ Adrp(x7, &label_2);
1776 __ Adrp(x8, &label_2);
1777
1778 VIXL_ASSERT(masm.SizeOfCodeGeneratedSince(&start) < kPageSize);
1779 END();
1780 RUN();
1781
1782 uint64_t expected = reinterpret_cast<uint64_t>(
1783 AlignDown(masm.GetLabelAddress<uint64_t*>(&start), kPageSize));
1784 ASSERT_EQUAL_64(expected, x0);
1785 ASSERT_EQUAL_64(expected, x1);
1786 ASSERT_EQUAL_64(expected, x2);
1787 ASSERT_EQUAL_64(expected, x3);
1788 ASSERT_EQUAL_64(expected, x4);
1789 ASSERT_EQUAL_64(expected, x5);
1790 ASSERT_EQUAL_64(expected, x6);
1791 ASSERT_EQUAL_64(expected, x7);
1792 ASSERT_EQUAL_64(expected, x8);
1793
armvixlc68cb642014-09-25 18:49:30 +01001794 TEARDOWN_CUSTOM();
armvixl4a102ba2014-07-14 09:02:40 +01001795}
1796
1797
1798static void AdrpPageBoundaryHelper(unsigned offset_into_page) {
1799 VIXL_ASSERT(offset_into_page < kPageSize);
1800 VIXL_ASSERT((offset_into_page % kInstructionSize) == 0);
1801
1802 const uintptr_t kPageOffsetMask = kPageSize - 1;
1803
1804 // The test label is always bound on page 0. Adrp instructions are generated
1805 // on pages from kStartPage to kEndPage (inclusive).
1806 const int kStartPage = -16;
1807 const int kEndPage = 16;
armvixlc68cb642014-09-25 18:49:30 +01001808 const int kMaxCodeSize = (kEndPage - kStartPage + 2) * kPageSize;
armvixl4a102ba2014-07-14 09:02:40 +01001809
armvixlc68cb642014-09-25 18:49:30 +01001810 SETUP_CUSTOM(kMaxCodeSize, PageOffsetDependentCode);
armvixl4a102ba2014-07-14 09:02:40 +01001811 START();
1812
armvixl4a102ba2014-07-14 09:02:40 +01001813 Label test;
armvixlc68cb642014-09-25 18:49:30 +01001814 Label start;
armvixl4a102ba2014-07-14 09:02:40 +01001815
armvixlc68cb642014-09-25 18:49:30 +01001816 {
1817 InstructionAccurateScope scope(&masm,
1818 kMaxCodeSize / kInstructionSize,
1819 InstructionAccurateScope::kMaximumSize);
1820 // Initialize NZCV with `eq` flags.
1821 __ cmp(wzr, wzr);
armvixl4a102ba2014-07-14 09:02:40 +01001822 // Waste space until the start of a page.
armvixlc68cb642014-09-25 18:49:30 +01001823 while ((masm.GetCursorAddress<uintptr_t>() & kPageOffsetMask) != 0) {
armvixl4a102ba2014-07-14 09:02:40 +01001824 __ b(&start);
1825 }
1826
1827 // The first page.
1828 VIXL_STATIC_ASSERT(kStartPage < 0);
armvixlc68cb642014-09-25 18:49:30 +01001829 {
1830 InstructionAccurateScope scope_page(&masm, kPageSize / kInstructionSize);
armvixl4a102ba2014-07-14 09:02:40 +01001831 __ bind(&start);
1832 __ adrp(x0, &test);
1833 __ adrp(x1, &test);
1834 for (size_t i = 2; i < (kPageSize / kInstructionSize); i += 2) {
1835 __ ccmp(x0, x1, NoFlag, eq);
1836 __ adrp(x1, &test);
1837 }
1838 }
1839
1840 // Subsequent pages.
1841 VIXL_STATIC_ASSERT(kEndPage >= 0);
1842 for (int page = (kStartPage + 1); page <= kEndPage; page++) {
1843 InstructionAccurateScope scope_page(&masm, kPageSize / kInstructionSize);
1844 if (page == 0) {
1845 for (size_t i = 0; i < (kPageSize / kInstructionSize);) {
1846 if (i++ == (offset_into_page / kInstructionSize)) __ bind(&test);
1847 __ ccmp(x0, x1, NoFlag, eq);
1848 if (i++ == (offset_into_page / kInstructionSize)) __ bind(&test);
1849 __ adrp(x1, &test);
1850 }
1851 } else {
1852 for (size_t i = 0; i < (kPageSize / kInstructionSize); i += 2) {
1853 __ ccmp(x0, x1, NoFlag, eq);
1854 __ adrp(x1, &test);
1855 }
1856 }
1857 }
armvixl4a102ba2014-07-14 09:02:40 +01001858 }
1859
armvixlc68cb642014-09-25 18:49:30 +01001860 // Every adrp instruction pointed to the same label (`test`), so they should
1861 // all have produced the same result.
1862
armvixl4a102ba2014-07-14 09:02:40 +01001863 END();
1864 RUN();
1865
1866 uintptr_t expected =
1867 AlignDown(masm.GetLabelAddress<uintptr_t>(&test), kPageSize);
1868 ASSERT_EQUAL_64(expected, x0);
1869 ASSERT_EQUAL_64(expected, x1);
1870 ASSERT_EQUAL_NZCV(ZCFlag);
1871
armvixlc68cb642014-09-25 18:49:30 +01001872 TEARDOWN_CUSTOM();
armvixl4a102ba2014-07-14 09:02:40 +01001873}
1874
1875
1876// Test that labels are correctly referenced by adrp across page boundaries.
1877TEST(adrp_page_boundaries) {
1878 VIXL_STATIC_ASSERT(kPageSize == 4096);
1879 AdrpPageBoundaryHelper(kInstructionSize * 0);
1880 AdrpPageBoundaryHelper(kInstructionSize * 1);
1881 AdrpPageBoundaryHelper(kInstructionSize * 512);
1882 AdrpPageBoundaryHelper(kInstructionSize * 1022);
1883 AdrpPageBoundaryHelper(kInstructionSize * 1023);
1884}
1885
1886
1887static void AdrpOffsetHelper(int64_t imm21) {
1888 const size_t kPageOffsetMask = kPageSize - 1;
armvixlc68cb642014-09-25 18:49:30 +01001889 const int kMaxCodeSize = 2 * kPageSize;
armvixl4a102ba2014-07-14 09:02:40 +01001890
armvixlc68cb642014-09-25 18:49:30 +01001891 SETUP_CUSTOM(kMaxCodeSize, PageOffsetDependentCode);
armvixl4a102ba2014-07-14 09:02:40 +01001892 START();
1893
armvixl4a102ba2014-07-14 09:02:40 +01001894 Label page;
armvixlc68cb642014-09-25 18:49:30 +01001895
1896 {
1897 InstructionAccurateScope scope(&masm,
1898 kMaxCodeSize / kInstructionSize,
1899 InstructionAccurateScope::kMaximumSize);
1900 // Initialize NZCV with `eq` flags.
1901 __ cmp(wzr, wzr);
armvixl4a102ba2014-07-14 09:02:40 +01001902 // Waste space until the start of a page.
armvixlc68cb642014-09-25 18:49:30 +01001903 while ((masm.GetCursorAddress<uintptr_t>() & kPageOffsetMask) != 0) {
armvixl4a102ba2014-07-14 09:02:40 +01001904 __ b(&page);
1905 }
1906 __ bind(&page);
1907
armvixlc68cb642014-09-25 18:49:30 +01001908 {
1909 InstructionAccurateScope scope_page(&masm, kPageSize / kInstructionSize);
armvixl4a102ba2014-07-14 09:02:40 +01001910 // Every adrp instruction on this page should return the same value.
1911 __ adrp(x0, imm21);
1912 __ adrp(x1, imm21);
1913 for (size_t i = 2; i < kPageSize / kInstructionSize; i += 2) {
1914 __ ccmp(x0, x1, NoFlag, eq);
1915 __ adrp(x1, imm21);
1916 }
1917 }
1918 }
1919
1920 END();
1921 RUN();
1922
1923 uintptr_t expected =
1924 masm.GetLabelAddress<uintptr_t>(&page) + (kPageSize * imm21);
1925 ASSERT_EQUAL_64(expected, x0);
1926 ASSERT_EQUAL_64(expected, x1);
1927 ASSERT_EQUAL_NZCV(ZCFlag);
1928
armvixlc68cb642014-09-25 18:49:30 +01001929 TEARDOWN_CUSTOM();
armvixl4a102ba2014-07-14 09:02:40 +01001930}
1931
1932
1933// Check that adrp produces the correct result for a specific offset.
1934TEST(adrp_offset) {
1935 AdrpOffsetHelper(0);
1936 AdrpOffsetHelper(1);
1937 AdrpOffsetHelper(-1);
1938 AdrpOffsetHelper(4);
1939 AdrpOffsetHelper(-4);
1940 AdrpOffsetHelper(0x000fffff);
1941 AdrpOffsetHelper(-0x000fffff);
1942 AdrpOffsetHelper(-0x00100000);
1943}
1944
1945
armvixlad96eda2013-06-14 11:42:37 +01001946TEST(branch_cond) {
1947 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01001948 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01001949
armvixl5289c592015-03-02 13:52:04 +00001950 Label done, wrong;
armvixlad96eda2013-06-14 11:42:37 +01001951
1952 START();
1953 __ Mov(x0, 0x1);
1954 __ Mov(x1, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00001955 __ Mov(x2, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01001956
1957 // For each 'cmp' instruction below, condition codes other than the ones
1958 // following it would branch.
1959
armvixl578645f2013-08-15 17:21:42 +01001960 __ Cmp(x1, 0);
armvixlad96eda2013-06-14 11:42:37 +01001961 __ B(&wrong, eq);
1962 __ B(&wrong, lo);
1963 __ B(&wrong, mi);
1964 __ B(&wrong, vs);
1965 __ B(&wrong, ls);
1966 __ B(&wrong, lt);
1967 __ B(&wrong, le);
1968 Label ok_1;
1969 __ B(&ok_1, ne);
1970 __ Mov(x0, 0x0);
1971 __ Bind(&ok_1);
1972
armvixl578645f2013-08-15 17:21:42 +01001973 __ Cmp(x1, 1);
armvixlad96eda2013-06-14 11:42:37 +01001974 __ B(&wrong, ne);
1975 __ B(&wrong, lo);
1976 __ B(&wrong, mi);
1977 __ B(&wrong, vs);
1978 __ B(&wrong, hi);
1979 __ B(&wrong, lt);
1980 __ B(&wrong, gt);
1981 Label ok_2;
1982 __ B(&ok_2, pl);
1983 __ Mov(x0, 0x0);
1984 __ Bind(&ok_2);
1985
armvixl578645f2013-08-15 17:21:42 +01001986 __ Cmp(x1, 2);
armvixlad96eda2013-06-14 11:42:37 +01001987 __ B(&wrong, eq);
1988 __ B(&wrong, hs);
1989 __ B(&wrong, pl);
1990 __ B(&wrong, vs);
1991 __ B(&wrong, hi);
1992 __ B(&wrong, ge);
1993 __ B(&wrong, gt);
1994 Label ok_3;
1995 __ B(&ok_3, vc);
1996 __ Mov(x0, 0x0);
1997 __ Bind(&ok_3);
1998
armvixl578645f2013-08-15 17:21:42 +01001999 __ Cmp(x2, 1);
armvixlad96eda2013-06-14 11:42:37 +01002000 __ B(&wrong, eq);
2001 __ B(&wrong, lo);
2002 __ B(&wrong, mi);
2003 __ B(&wrong, vc);
2004 __ B(&wrong, ls);
2005 __ B(&wrong, ge);
2006 __ B(&wrong, gt);
2007 Label ok_4;
2008 __ B(&ok_4, le);
2009 __ Mov(x0, 0x0);
2010 __ Bind(&ok_4);
armvixl578645f2013-08-15 17:21:42 +01002011
armvixlc68cb642014-09-25 18:49:30 +01002012 // The MacroAssembler does not allow al as a branch condition.
armvixl578645f2013-08-15 17:21:42 +01002013 Label ok_5;
2014 __ b(&ok_5, al);
2015 __ Mov(x0, 0x0);
2016 __ Bind(&ok_5);
2017
armvixlc68cb642014-09-25 18:49:30 +01002018 // The MacroAssembler does not allow nv as a branch condition.
armvixl578645f2013-08-15 17:21:42 +01002019 Label ok_6;
2020 __ b(&ok_6, nv);
2021 __ Mov(x0, 0x0);
2022 __ Bind(&ok_6);
2023
armvixl5289c592015-03-02 13:52:04 +00002024 __ B(&done);
armvixlad96eda2013-06-14 11:42:37 +01002025
2026 __ Bind(&wrong);
2027 __ Mov(x0, 0x0);
armvixl5289c592015-03-02 13:52:04 +00002028
2029 __ Bind(&done);
armvixlad96eda2013-06-14 11:42:37 +01002030 END();
2031
2032 RUN();
2033
2034 ASSERT_EQUAL_64(0x1, x0);
2035
2036 TEARDOWN();
2037}
2038
2039
2040TEST(branch_to_reg) {
2041 SETUP();
2042
2043 // Test br.
2044 Label fn1, after_fn1;
2045
2046 START();
2047 __ Mov(x29, lr);
2048
2049 __ Mov(x1, 0);
2050 __ B(&after_fn1);
2051
2052 __ Bind(&fn1);
2053 __ Mov(x0, lr);
2054 __ Mov(x1, 42);
2055 __ Br(x0);
2056
2057 __ Bind(&after_fn1);
2058 __ Bl(&fn1);
2059
2060 // Test blr.
2061 Label fn2, after_fn2;
2062
2063 __ Mov(x2, 0);
2064 __ B(&after_fn2);
2065
2066 __ Bind(&fn2);
2067 __ Mov(x0, lr);
2068 __ Mov(x2, 84);
2069 __ Blr(x0);
2070
2071 __ Bind(&after_fn2);
2072 __ Bl(&fn2);
2073 __ Mov(x3, lr);
2074
2075 __ Mov(lr, x29);
2076 END();
2077
2078 RUN();
2079
2080 ASSERT_EQUAL_64(core.xreg(3) + kInstructionSize, x0);
2081 ASSERT_EQUAL_64(42, x1);
2082 ASSERT_EQUAL_64(84, x2);
2083
2084 TEARDOWN();
2085}
2086
2087
2088TEST(compare_branch) {
2089 SETUP();
2090
2091 START();
2092 __ Mov(x0, 0);
2093 __ Mov(x1, 0);
2094 __ Mov(x2, 0);
2095 __ Mov(x3, 0);
2096 __ Mov(x4, 0);
2097 __ Mov(x5, 0);
2098 __ Mov(x16, 0);
2099 __ Mov(x17, 42);
2100
2101 Label zt, zt_end;
2102 __ Cbz(w16, &zt);
2103 __ B(&zt_end);
2104 __ Bind(&zt);
2105 __ Mov(x0, 1);
2106 __ Bind(&zt_end);
2107
2108 Label zf, zf_end;
2109 __ Cbz(x17, &zf);
2110 __ B(&zf_end);
2111 __ Bind(&zf);
2112 __ Mov(x1, 1);
2113 __ Bind(&zf_end);
2114
2115 Label nzt, nzt_end;
2116 __ Cbnz(w17, &nzt);
2117 __ B(&nzt_end);
2118 __ Bind(&nzt);
2119 __ Mov(x2, 1);
2120 __ Bind(&nzt_end);
2121
2122 Label nzf, nzf_end;
2123 __ Cbnz(x16, &nzf);
2124 __ B(&nzf_end);
2125 __ Bind(&nzf);
2126 __ Mov(x3, 1);
2127 __ Bind(&nzf_end);
2128
armvixlb0c8ae22014-03-21 14:03:59 +00002129 __ Mov(x18, 0xffffffff00000000);
armvixlad96eda2013-06-14 11:42:37 +01002130
2131 Label a, a_end;
2132 __ Cbz(w18, &a);
2133 __ B(&a_end);
2134 __ Bind(&a);
2135 __ Mov(x4, 1);
2136 __ Bind(&a_end);
2137
2138 Label b, b_end;
2139 __ Cbnz(w18, &b);
2140 __ B(&b_end);
2141 __ Bind(&b);
2142 __ Mov(x5, 1);
2143 __ Bind(&b_end);
2144
2145 END();
2146
2147 RUN();
2148
2149 ASSERT_EQUAL_64(1, x0);
2150 ASSERT_EQUAL_64(0, x1);
2151 ASSERT_EQUAL_64(1, x2);
2152 ASSERT_EQUAL_64(0, x3);
2153 ASSERT_EQUAL_64(1, x4);
2154 ASSERT_EQUAL_64(0, x5);
2155
2156 TEARDOWN();
2157}
2158
2159
2160TEST(test_branch) {
2161 SETUP();
2162
2163 START();
2164 __ Mov(x0, 0);
2165 __ Mov(x1, 0);
2166 __ Mov(x2, 0);
2167 __ Mov(x3, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00002168 __ Mov(x16, 0xaaaaaaaaaaaaaaaa);
armvixlad96eda2013-06-14 11:42:37 +01002169
2170 Label bz, bz_end;
armvixlf37fdc02014-02-05 13:22:16 +00002171 __ Tbz(w16, 0, &bz);
armvixlad96eda2013-06-14 11:42:37 +01002172 __ B(&bz_end);
2173 __ Bind(&bz);
2174 __ Mov(x0, 1);
2175 __ Bind(&bz_end);
2176
2177 Label bo, bo_end;
2178 __ Tbz(x16, 63, &bo);
2179 __ B(&bo_end);
2180 __ Bind(&bo);
2181 __ Mov(x1, 1);
2182 __ Bind(&bo_end);
2183
2184 Label nbz, nbz_end;
2185 __ Tbnz(x16, 61, &nbz);
2186 __ B(&nbz_end);
2187 __ Bind(&nbz);
2188 __ Mov(x2, 1);
2189 __ Bind(&nbz_end);
2190
2191 Label nbo, nbo_end;
armvixlf37fdc02014-02-05 13:22:16 +00002192 __ Tbnz(w16, 2, &nbo);
armvixlad96eda2013-06-14 11:42:37 +01002193 __ B(&nbo_end);
2194 __ Bind(&nbo);
2195 __ Mov(x3, 1);
2196 __ Bind(&nbo_end);
2197 END();
2198
2199 RUN();
2200
2201 ASSERT_EQUAL_64(1, x0);
2202 ASSERT_EQUAL_64(0, x1);
2203 ASSERT_EQUAL_64(1, x2);
2204 ASSERT_EQUAL_64(0, x3);
2205
2206 TEARDOWN();
2207}
2208
2209
armvixlb0c8ae22014-03-21 14:03:59 +00002210TEST(branch_type) {
2211 SETUP();
2212
2213 Label fail, done;
2214
2215 START();
2216 __ Mov(x0, 0x0);
2217 __ Mov(x10, 0x7);
2218 __ Mov(x11, 0x0);
2219
2220 // Test non taken branches.
2221 __ Cmp(x10, 0x7);
2222 __ B(&fail, ne);
2223 __ B(&fail, never);
2224 __ B(&fail, reg_zero, x10);
2225 __ B(&fail, reg_not_zero, x11);
2226 __ B(&fail, reg_bit_clear, x10, 0);
2227 __ B(&fail, reg_bit_set, x10, 3);
2228
2229 // Test taken branches.
2230 Label l1, l2, l3, l4, l5;
2231 __ Cmp(x10, 0x7);
2232 __ B(&l1, eq);
2233 __ B(&fail);
2234 __ Bind(&l1);
2235 __ B(&l2, always);
2236 __ B(&fail);
2237 __ Bind(&l2);
2238 __ B(&l3, reg_not_zero, x10);
2239 __ B(&fail);
2240 __ Bind(&l3);
2241 __ B(&l4, reg_bit_clear, x10, 15);
2242 __ B(&fail);
2243 __ Bind(&l4);
2244 __ B(&l5, reg_bit_set, x10, 1);
2245 __ B(&fail);
2246 __ Bind(&l5);
2247
2248 __ B(&done);
2249
2250 __ Bind(&fail);
2251 __ Mov(x0, 0x1);
2252
2253 __ Bind(&done);
2254
2255 END();
2256
2257 RUN();
2258
2259 ASSERT_EQUAL_64(0x0, x0);
2260
2261 TEARDOWN();
2262}
2263
2264
armvixlad96eda2013-06-14 11:42:37 +01002265TEST(ldr_str_offset) {
2266 SETUP();
2267
armvixlb0c8ae22014-03-21 14:03:59 +00002268 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002269 uint64_t dst[5] = {0, 0, 0, 0, 0};
2270 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2271 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2272
2273 START();
2274 __ Mov(x17, src_base);
2275 __ Mov(x18, dst_base);
2276 __ Ldr(w0, MemOperand(x17));
2277 __ Str(w0, MemOperand(x18));
2278 __ Ldr(w1, MemOperand(x17, 4));
2279 __ Str(w1, MemOperand(x18, 12));
2280 __ Ldr(x2, MemOperand(x17, 8));
2281 __ Str(x2, MemOperand(x18, 16));
2282 __ Ldrb(w3, MemOperand(x17, 1));
2283 __ Strb(w3, MemOperand(x18, 25));
2284 __ Ldrh(w4, MemOperand(x17, 2));
2285 __ Strh(w4, MemOperand(x18, 33));
2286 END();
2287
2288 RUN();
2289
2290 ASSERT_EQUAL_64(0x76543210, x0);
2291 ASSERT_EQUAL_64(0x76543210, dst[0]);
2292 ASSERT_EQUAL_64(0xfedcba98, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00002293 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2294 ASSERT_EQUAL_64(0x0123456789abcdef, x2);
2295 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
armvixlad96eda2013-06-14 11:42:37 +01002296 ASSERT_EQUAL_64(0x32, x3);
2297 ASSERT_EQUAL_64(0x3200, dst[3]);
2298 ASSERT_EQUAL_64(0x7654, x4);
2299 ASSERT_EQUAL_64(0x765400, dst[4]);
2300 ASSERT_EQUAL_64(src_base, x17);
2301 ASSERT_EQUAL_64(dst_base, x18);
2302
2303 TEARDOWN();
2304}
2305
2306
2307TEST(ldr_str_wide) {
2308 SETUP();
2309
2310 uint32_t src[8192];
2311 uint32_t dst[8192];
2312 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2313 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2314 memset(src, 0xaa, 8192 * sizeof(src[0]));
2315 memset(dst, 0xaa, 8192 * sizeof(dst[0]));
2316 src[0] = 0;
2317 src[6144] = 6144;
2318 src[8191] = 8191;
2319
2320 START();
2321 __ Mov(x22, src_base);
2322 __ Mov(x23, dst_base);
2323 __ Mov(x24, src_base);
2324 __ Mov(x25, dst_base);
2325 __ Mov(x26, src_base);
2326 __ Mov(x27, dst_base);
2327
2328 __ Ldr(w0, MemOperand(x22, 8191 * sizeof(src[0])));
2329 __ Str(w0, MemOperand(x23, 8191 * sizeof(dst[0])));
2330 __ Ldr(w1, MemOperand(x24, 4096 * sizeof(src[0]), PostIndex));
2331 __ Str(w1, MemOperand(x25, 4096 * sizeof(dst[0]), PostIndex));
2332 __ Ldr(w2, MemOperand(x26, 6144 * sizeof(src[0]), PreIndex));
2333 __ Str(w2, MemOperand(x27, 6144 * sizeof(dst[0]), PreIndex));
2334 END();
2335
2336 RUN();
2337
2338 ASSERT_EQUAL_32(8191, w0);
2339 ASSERT_EQUAL_32(8191, dst[8191]);
2340 ASSERT_EQUAL_64(src_base, x22);
2341 ASSERT_EQUAL_64(dst_base, x23);
2342 ASSERT_EQUAL_32(0, w1);
2343 ASSERT_EQUAL_32(0, dst[0]);
2344 ASSERT_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24);
2345 ASSERT_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25);
2346 ASSERT_EQUAL_32(6144, w2);
2347 ASSERT_EQUAL_32(6144, dst[6144]);
2348 ASSERT_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26);
2349 ASSERT_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27);
2350
2351 TEARDOWN();
2352}
2353
2354
2355TEST(ldr_str_preindex) {
2356 SETUP();
2357
armvixlb0c8ae22014-03-21 14:03:59 +00002358 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002359 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2360 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2361 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2362
2363 START();
2364 __ Mov(x17, src_base);
2365 __ Mov(x18, dst_base);
2366 __ Mov(x19, src_base);
2367 __ Mov(x20, dst_base);
2368 __ Mov(x21, src_base + 16);
2369 __ Mov(x22, dst_base + 40);
2370 __ Mov(x23, src_base);
2371 __ Mov(x24, dst_base);
2372 __ Mov(x25, src_base);
2373 __ Mov(x26, dst_base);
2374 __ Ldr(w0, MemOperand(x17, 4, PreIndex));
2375 __ Str(w0, MemOperand(x18, 12, PreIndex));
2376 __ Ldr(x1, MemOperand(x19, 8, PreIndex));
2377 __ Str(x1, MemOperand(x20, 16, PreIndex));
2378 __ Ldr(w2, MemOperand(x21, -4, PreIndex));
2379 __ Str(w2, MemOperand(x22, -4, PreIndex));
2380 __ Ldrb(w3, MemOperand(x23, 1, PreIndex));
2381 __ Strb(w3, MemOperand(x24, 25, PreIndex));
2382 __ Ldrh(w4, MemOperand(x25, 3, PreIndex));
2383 __ Strh(w4, MemOperand(x26, 41, PreIndex));
2384 END();
2385
2386 RUN();
2387
2388 ASSERT_EQUAL_64(0xfedcba98, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002389 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2390 ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2391 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
armvixlad96eda2013-06-14 11:42:37 +01002392 ASSERT_EQUAL_64(0x01234567, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00002393 ASSERT_EQUAL_64(0x0123456700000000, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01002394 ASSERT_EQUAL_64(0x32, x3);
2395 ASSERT_EQUAL_64(0x3200, dst[3]);
2396 ASSERT_EQUAL_64(0x9876, x4);
2397 ASSERT_EQUAL_64(0x987600, dst[5]);
2398 ASSERT_EQUAL_64(src_base + 4, x17);
2399 ASSERT_EQUAL_64(dst_base + 12, x18);
2400 ASSERT_EQUAL_64(src_base + 8, x19);
2401 ASSERT_EQUAL_64(dst_base + 16, x20);
2402 ASSERT_EQUAL_64(src_base + 12, x21);
2403 ASSERT_EQUAL_64(dst_base + 36, x22);
2404 ASSERT_EQUAL_64(src_base + 1, x23);
2405 ASSERT_EQUAL_64(dst_base + 25, x24);
2406 ASSERT_EQUAL_64(src_base + 3, x25);
2407 ASSERT_EQUAL_64(dst_base + 41, x26);
2408
2409 TEARDOWN();
2410}
2411
2412
2413TEST(ldr_str_postindex) {
2414 SETUP();
2415
armvixlb0c8ae22014-03-21 14:03:59 +00002416 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002417 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2418 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2419 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2420
2421 START();
2422 __ Mov(x17, src_base + 4);
2423 __ Mov(x18, dst_base + 12);
2424 __ Mov(x19, src_base + 8);
2425 __ Mov(x20, dst_base + 16);
2426 __ Mov(x21, src_base + 8);
2427 __ Mov(x22, dst_base + 32);
2428 __ Mov(x23, src_base + 1);
2429 __ Mov(x24, dst_base + 25);
2430 __ Mov(x25, src_base + 3);
2431 __ Mov(x26, dst_base + 41);
2432 __ Ldr(w0, MemOperand(x17, 4, PostIndex));
2433 __ Str(w0, MemOperand(x18, 12, PostIndex));
2434 __ Ldr(x1, MemOperand(x19, 8, PostIndex));
2435 __ Str(x1, MemOperand(x20, 16, PostIndex));
2436 __ Ldr(x2, MemOperand(x21, -8, PostIndex));
2437 __ Str(x2, MemOperand(x22, -32, PostIndex));
2438 __ Ldrb(w3, MemOperand(x23, 1, PostIndex));
2439 __ Strb(w3, MemOperand(x24, 5, PostIndex));
2440 __ Ldrh(w4, MemOperand(x25, -3, PostIndex));
2441 __ Strh(w4, MemOperand(x26, -41, PostIndex));
2442 END();
2443
2444 RUN();
2445
2446 ASSERT_EQUAL_64(0xfedcba98, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002447 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2448 ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2449 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
2450 ASSERT_EQUAL_64(0x0123456789abcdef, x2);
2451 ASSERT_EQUAL_64(0x0123456789abcdef, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01002452 ASSERT_EQUAL_64(0x32, x3);
2453 ASSERT_EQUAL_64(0x3200, dst[3]);
2454 ASSERT_EQUAL_64(0x9876, x4);
2455 ASSERT_EQUAL_64(0x987600, dst[5]);
2456 ASSERT_EQUAL_64(src_base + 8, x17);
2457 ASSERT_EQUAL_64(dst_base + 24, x18);
2458 ASSERT_EQUAL_64(src_base + 16, x19);
2459 ASSERT_EQUAL_64(dst_base + 32, x20);
2460 ASSERT_EQUAL_64(src_base, x21);
2461 ASSERT_EQUAL_64(dst_base, x22);
2462 ASSERT_EQUAL_64(src_base + 2, x23);
2463 ASSERT_EQUAL_64(dst_base + 30, x24);
2464 ASSERT_EQUAL_64(src_base, x25);
2465 ASSERT_EQUAL_64(dst_base, x26);
2466
2467 TEARDOWN();
2468}
2469
2470
2471TEST(ldr_str_largeindex) {
2472 SETUP();
2473
2474 // This value won't fit in the immediate offset field of ldr/str instructions.
2475 int largeoffset = 0xabcdef;
2476
2477 int64_t data[3] = { 0x1122334455667788, 0, 0 };
armvixlb0c8ae22014-03-21 14:03:59 +00002478 uint64_t base_addr = reinterpret_cast<uintptr_t>(data);
2479 uint64_t drifted_addr = base_addr - largeoffset;
armvixlad96eda2013-06-14 11:42:37 +01002480
2481 // This test checks that we we can use large immediate offsets when
2482 // using PreIndex or PostIndex addressing mode of the MacroAssembler
2483 // Ldr/Str instructions.
2484
2485 START();
armvixlad96eda2013-06-14 11:42:37 +01002486 __ Mov(x19, drifted_addr);
armvixlb0c8ae22014-03-21 14:03:59 +00002487 __ Ldr(x0, MemOperand(x19, largeoffset, PreIndex));
armvixlad96eda2013-06-14 11:42:37 +01002488
armvixlb0c8ae22014-03-21 14:03:59 +00002489 __ Mov(x20, base_addr);
2490 __ Ldr(x1, MemOperand(x20, largeoffset, PostIndex));
2491
2492 __ Mov(x21, drifted_addr);
2493 __ Str(x0, MemOperand(x21, largeoffset + 8, PreIndex));
2494
2495 __ Mov(x22, base_addr + 16);
2496 __ Str(x0, MemOperand(x22, largeoffset, PostIndex));
armvixlad96eda2013-06-14 11:42:37 +01002497 END();
2498
2499 RUN();
2500
2501 ASSERT_EQUAL_64(0x1122334455667788, data[0]);
2502 ASSERT_EQUAL_64(0x1122334455667788, data[1]);
2503 ASSERT_EQUAL_64(0x1122334455667788, data[2]);
2504 ASSERT_EQUAL_64(0x1122334455667788, x0);
2505 ASSERT_EQUAL_64(0x1122334455667788, x1);
2506
armvixlb0c8ae22014-03-21 14:03:59 +00002507 ASSERT_EQUAL_64(base_addr, x19);
2508 ASSERT_EQUAL_64(base_addr + largeoffset, x20);
2509 ASSERT_EQUAL_64(base_addr + 8, x21);
2510 ASSERT_EQUAL_64(base_addr + 16 + largeoffset, x22);
armvixlad96eda2013-06-14 11:42:37 +01002511
2512 TEARDOWN();
2513}
2514
2515
2516TEST(load_signed) {
2517 SETUP();
2518
2519 uint32_t src[2] = {0x80008080, 0x7fff7f7f};
2520 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2521
2522 START();
2523 __ Mov(x24, src_base);
2524 __ Ldrsb(w0, MemOperand(x24));
2525 __ Ldrsb(w1, MemOperand(x24, 4));
2526 __ Ldrsh(w2, MemOperand(x24));
2527 __ Ldrsh(w3, MemOperand(x24, 4));
2528 __ Ldrsb(x4, MemOperand(x24));
2529 __ Ldrsb(x5, MemOperand(x24, 4));
2530 __ Ldrsh(x6, MemOperand(x24));
2531 __ Ldrsh(x7, MemOperand(x24, 4));
2532 __ Ldrsw(x8, MemOperand(x24));
2533 __ Ldrsw(x9, MemOperand(x24, 4));
2534 END();
2535
2536 RUN();
2537
2538 ASSERT_EQUAL_64(0xffffff80, x0);
2539 ASSERT_EQUAL_64(0x0000007f, x1);
2540 ASSERT_EQUAL_64(0xffff8080, x2);
2541 ASSERT_EQUAL_64(0x00007f7f, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00002542 ASSERT_EQUAL_64(0xffffffffffffff80, x4);
2543 ASSERT_EQUAL_64(0x000000000000007f, x5);
2544 ASSERT_EQUAL_64(0xffffffffffff8080, x6);
2545 ASSERT_EQUAL_64(0x0000000000007f7f, x7);
2546 ASSERT_EQUAL_64(0xffffffff80008080, x8);
2547 ASSERT_EQUAL_64(0x000000007fff7f7f, x9);
armvixlad96eda2013-06-14 11:42:37 +01002548
2549 TEARDOWN();
2550}
2551
2552
2553TEST(load_store_regoffset) {
2554 SETUP();
2555
2556 uint32_t src[3] = {1, 2, 3};
2557 uint32_t dst[4] = {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, src_base + 3 * sizeof(src[0]));
2565 __ Mov(x19, dst_base + 3 * sizeof(dst[0]));
2566 __ Mov(x20, dst_base + 4 * sizeof(dst[0]));
2567 __ Mov(x24, 0);
2568 __ Mov(x25, 4);
2569 __ Mov(x26, -4);
2570 __ Mov(x27, 0xfffffffc); // 32-bit -4.
2571 __ Mov(x28, 0xfffffffe); // 32-bit -2.
2572 __ Mov(x29, 0xffffffff); // 32-bit -1.
2573
2574 __ Ldr(w0, MemOperand(x16, x24));
2575 __ Ldr(x1, MemOperand(x16, x25));
2576 __ Ldr(w2, MemOperand(x18, x26));
2577 __ Ldr(w3, MemOperand(x18, x27, SXTW));
2578 __ Ldr(w4, MemOperand(x18, x28, SXTW, 2));
2579 __ Str(w0, MemOperand(x17, x24));
2580 __ Str(x1, MemOperand(x17, x25));
2581 __ Str(w2, MemOperand(x20, x29, SXTW, 2));
2582 END();
2583
2584 RUN();
2585
2586 ASSERT_EQUAL_64(1, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002587 ASSERT_EQUAL_64(0x0000000300000002, x1);
armvixlad96eda2013-06-14 11:42:37 +01002588 ASSERT_EQUAL_64(3, x2);
2589 ASSERT_EQUAL_64(3, x3);
2590 ASSERT_EQUAL_64(2, x4);
2591 ASSERT_EQUAL_32(1, dst[0]);
2592 ASSERT_EQUAL_32(2, dst[1]);
2593 ASSERT_EQUAL_32(3, dst[2]);
2594 ASSERT_EQUAL_32(3, dst[3]);
2595
2596 TEARDOWN();
2597}
2598
2599
2600TEST(load_store_float) {
2601 SETUP();
2602
2603 float src[3] = {1.0, 2.0, 3.0};
2604 float dst[3] = {0.0, 0.0, 0.0};
2605 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2606 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2607
2608 START();
2609 __ Mov(x17, src_base);
2610 __ Mov(x18, dst_base);
2611 __ Mov(x19, src_base);
2612 __ Mov(x20, dst_base);
2613 __ Mov(x21, src_base);
2614 __ Mov(x22, dst_base);
2615 __ Ldr(s0, MemOperand(x17, sizeof(src[0])));
2616 __ Str(s0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2617 __ Ldr(s1, MemOperand(x19, sizeof(src[0]), PostIndex));
2618 __ Str(s1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2619 __ Ldr(s2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2620 __ Str(s2, MemOperand(x22, sizeof(dst[0])));
2621 END();
2622
2623 RUN();
2624
2625 ASSERT_EQUAL_FP32(2.0, s0);
2626 ASSERT_EQUAL_FP32(2.0, dst[0]);
2627 ASSERT_EQUAL_FP32(1.0, s1);
2628 ASSERT_EQUAL_FP32(1.0, dst[2]);
2629 ASSERT_EQUAL_FP32(3.0, s2);
2630 ASSERT_EQUAL_FP32(3.0, dst[1]);
2631 ASSERT_EQUAL_64(src_base, x17);
2632 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2633 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2634 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2635 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2636 ASSERT_EQUAL_64(dst_base, x22);
2637
2638 TEARDOWN();
2639}
2640
2641
2642TEST(load_store_double) {
2643 SETUP();
2644
2645 double src[3] = {1.0, 2.0, 3.0};
2646 double dst[3] = {0.0, 0.0, 0.0};
2647 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2648 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2649
2650 START();
2651 __ Mov(x17, src_base);
2652 __ Mov(x18, dst_base);
2653 __ Mov(x19, src_base);
2654 __ Mov(x20, dst_base);
2655 __ Mov(x21, src_base);
2656 __ Mov(x22, dst_base);
2657 __ Ldr(d0, MemOperand(x17, sizeof(src[0])));
2658 __ Str(d0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2659 __ Ldr(d1, MemOperand(x19, sizeof(src[0]), PostIndex));
2660 __ Str(d1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2661 __ Ldr(d2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2662 __ Str(d2, MemOperand(x22, sizeof(dst[0])));
2663 END();
2664
2665 RUN();
2666
2667 ASSERT_EQUAL_FP64(2.0, d0);
2668 ASSERT_EQUAL_FP64(2.0, dst[0]);
2669 ASSERT_EQUAL_FP64(1.0, d1);
2670 ASSERT_EQUAL_FP64(1.0, dst[2]);
2671 ASSERT_EQUAL_FP64(3.0, d2);
2672 ASSERT_EQUAL_FP64(3.0, dst[1]);
2673 ASSERT_EQUAL_64(src_base, x17);
2674 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2675 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2676 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2677 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2678 ASSERT_EQUAL_64(dst_base, x22);
2679
2680 TEARDOWN();
2681}
2682
2683
armvixl5289c592015-03-02 13:52:04 +00002684TEST(load_store_b) {
2685 SETUP();
2686
2687 uint8_t src[3] = {0x12, 0x23, 0x34};
2688 uint8_t dst[3] = {0, 0, 0};
2689 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2690 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2691
2692 START();
2693 __ Mov(x17, src_base);
2694 __ Mov(x18, dst_base);
2695 __ Mov(x19, src_base);
2696 __ Mov(x20, dst_base);
2697 __ Mov(x21, src_base);
2698 __ Mov(x22, dst_base);
2699 __ Ldr(b0, MemOperand(x17, sizeof(src[0])));
2700 __ Str(b0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2701 __ Ldr(b1, MemOperand(x19, sizeof(src[0]), PostIndex));
2702 __ Str(b1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2703 __ Ldr(b2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2704 __ Str(b2, MemOperand(x22, sizeof(dst[0])));
2705 END();
2706
2707 RUN();
2708
2709 ASSERT_EQUAL_128(0, 0x23, q0);
2710 ASSERT_EQUAL_64(0x23, dst[0]);
2711 ASSERT_EQUAL_128(0, 0x12, q1);
2712 ASSERT_EQUAL_64(0x12, dst[2]);
2713 ASSERT_EQUAL_128(0, 0x34, q2);
2714 ASSERT_EQUAL_64(0x34, dst[1]);
2715 ASSERT_EQUAL_64(src_base, x17);
2716 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2717 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2718 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2719 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2720 ASSERT_EQUAL_64(dst_base, x22);
2721
2722 TEARDOWN();
2723}
2724
2725
2726TEST(load_store_h) {
2727 SETUP();
2728
2729 uint16_t src[3] = {0x1234, 0x2345, 0x3456};
2730 uint16_t dst[3] = {0, 0, 0};
2731 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2732 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2733
2734 START();
2735 __ Mov(x17, src_base);
2736 __ Mov(x18, dst_base);
2737 __ Mov(x19, src_base);
2738 __ Mov(x20, dst_base);
2739 __ Mov(x21, src_base);
2740 __ Mov(x22, dst_base);
2741 __ Ldr(h0, MemOperand(x17, sizeof(src[0])));
2742 __ Str(h0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2743 __ Ldr(h1, MemOperand(x19, sizeof(src[0]), PostIndex));
2744 __ Str(h1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2745 __ Ldr(h2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2746 __ Str(h2, MemOperand(x22, sizeof(dst[0])));
2747 END();
2748
2749 RUN();
2750
2751 ASSERT_EQUAL_128(0, 0x2345, q0);
2752 ASSERT_EQUAL_64(0x2345, dst[0]);
2753 ASSERT_EQUAL_128(0, 0x1234, q1);
2754 ASSERT_EQUAL_64(0x1234, dst[2]);
2755 ASSERT_EQUAL_128(0, 0x3456, q2);
2756 ASSERT_EQUAL_64(0x3456, dst[1]);
2757 ASSERT_EQUAL_64(src_base, x17);
2758 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2759 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2760 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2761 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2762 ASSERT_EQUAL_64(dst_base, x22);
2763
2764 TEARDOWN();
2765}
2766
2767
2768TEST(load_store_q) {
2769 SETUP();
2770
2771 uint8_t src[48] = {0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe,
2772 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
2773 0x21, 0x43, 0x65, 0x87, 0xa9, 0xcb, 0xed, 0x0f,
2774 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
2775 0x24, 0x46, 0x68, 0x8a, 0xac, 0xce, 0xe0, 0x02,
2776 0x42, 0x64, 0x86, 0xa8, 0xca, 0xec, 0x0e, 0x20};
2777
2778 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2779 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2780 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2781
2782 START();
2783 __ Mov(x17, src_base);
2784 __ Mov(x18, dst_base);
2785 __ Mov(x19, src_base);
2786 __ Mov(x20, dst_base);
2787 __ Mov(x21, src_base);
2788 __ Mov(x22, dst_base);
2789 __ Ldr(q0, MemOperand(x17, 16));
2790 __ Str(q0, MemOperand(x18, 16, PostIndex));
2791 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
2792 __ Str(q1, MemOperand(x20, 32, PreIndex));
2793 __ Ldr(q2, MemOperand(x21, 32, PreIndex));
2794 __ Str(q2, MemOperand(x22, 16));
2795 END();
2796
2797 RUN();
2798
2799 ASSERT_EQUAL_128(0xf0debc9a78563412, 0x0fedcba987654321, q0);
2800 ASSERT_EQUAL_64(0x0fedcba987654321, dst[0]);
2801 ASSERT_EQUAL_64(0xf0debc9a78563412, dst[1]);
2802 ASSERT_EQUAL_128(0xefcdab8967452301, 0xfedcba9876543210, q1);
2803 ASSERT_EQUAL_64(0xfedcba9876543210, dst[4]);
2804 ASSERT_EQUAL_64(0xefcdab8967452301, dst[5]);
2805 ASSERT_EQUAL_128(0x200eeccaa8866442, 0x02e0ceac8a684624, q2);
2806 ASSERT_EQUAL_64(0x02e0ceac8a684624, dst[2]);
2807 ASSERT_EQUAL_64(0x200eeccaa8866442, dst[3]);
2808 ASSERT_EQUAL_64(src_base, x17);
2809 ASSERT_EQUAL_64(dst_base + 16, x18);
2810 ASSERT_EQUAL_64(src_base + 16, x19);
2811 ASSERT_EQUAL_64(dst_base + 32, x20);
2812 ASSERT_EQUAL_64(src_base + 32, x21);
2813 ASSERT_EQUAL_64(dst_base, x22);
2814
2815 TEARDOWN();
2816}
2817
2818
2819TEST(load_store_v_regoffset) {
2820 SETUP();
2821
2822 uint8_t src[64];
2823 for (unsigned i = 0; i < sizeof(src); i++) {
2824 src[i] = i;
2825 }
2826 uint8_t dst[64];
2827 memset(dst, 0, sizeof(dst));
2828
2829 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2830 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2831
2832 START();
2833 __ Mov(x17, src_base + 16);
2834 __ Mov(x18, 1);
2835 __ Mov(w19, -1);
2836 __ Mov(x20, dst_base - 1);
2837
2838 __ Ldr(b0, MemOperand(x17, x18));
2839 __ Ldr(b1, MemOperand(x17, x19, SXTW));
2840
2841 __ Ldr(h2, MemOperand(x17, x18));
2842 __ Ldr(h3, MemOperand(x17, x18, UXTW, 1));
2843 __ Ldr(h4, MemOperand(x17, x19, SXTW, 1));
2844 __ Ldr(h5, MemOperand(x17, x18, LSL, 1));
2845
2846 __ Ldr(s16, MemOperand(x17, x18));
2847 __ Ldr(s17, MemOperand(x17, x18, UXTW, 2));
2848 __ Ldr(s18, MemOperand(x17, x19, SXTW, 2));
2849 __ Ldr(s19, MemOperand(x17, x18, LSL, 2));
2850
2851 __ Ldr(d20, MemOperand(x17, x18));
2852 __ Ldr(d21, MemOperand(x17, x18, UXTW, 3));
2853 __ Ldr(d22, MemOperand(x17, x19, SXTW, 3));
2854 __ Ldr(d23, MemOperand(x17, x18, LSL, 3));
2855
2856 __ Ldr(q24, MemOperand(x17, x18));
2857 __ Ldr(q25, MemOperand(x17, x18, UXTW, 4));
2858 __ Ldr(q26, MemOperand(x17, x19, SXTW, 4));
2859 __ Ldr(q27, MemOperand(x17, x18, LSL, 4));
2860
2861 // Store [bhsdq]27 to adjacent memory locations, then load again to check.
2862 __ Str(b27, MemOperand(x20, x18));
2863 __ Str(h27, MemOperand(x20, x18, UXTW, 1));
2864 __ Add(x20, x20, 8);
2865 __ Str(s27, MemOperand(x20, x19, SXTW, 2));
2866 __ Sub(x20, x20, 8);
2867 __ Str(d27, MemOperand(x20, x18, LSL, 3));
2868 __ Add(x20, x20, 32);
2869 __ Str(q27, MemOperand(x20, x19, SXTW, 4));
2870
2871 __ Sub(x20, x20, 32);
2872 __ Ldr(q6, MemOperand(x20, x18));
2873 __ Ldr(q7, MemOperand(x20, x18, LSL, 4));
2874
2875 END();
2876
2877 RUN();
2878
2879 ASSERT_EQUAL_128(0, 0x11, q0);
2880 ASSERT_EQUAL_128(0, 0x0f, q1);
2881 ASSERT_EQUAL_128(0, 0x1211, q2);
2882 ASSERT_EQUAL_128(0, 0x1312, q3);
2883 ASSERT_EQUAL_128(0, 0x0f0e, q4);
2884 ASSERT_EQUAL_128(0, 0x1312, q5);
2885 ASSERT_EQUAL_128(0, 0x14131211, q16);
2886 ASSERT_EQUAL_128(0, 0x17161514, q17);
2887 ASSERT_EQUAL_128(0, 0x0f0e0d0c, q18);
2888 ASSERT_EQUAL_128(0, 0x17161514, q19);
2889 ASSERT_EQUAL_128(0, 0x1817161514131211, q20);
2890 ASSERT_EQUAL_128(0, 0x1f1e1d1c1b1a1918, q21);
2891 ASSERT_EQUAL_128(0, 0x0f0e0d0c0b0a0908, q22);
2892 ASSERT_EQUAL_128(0, 0x1f1e1d1c1b1a1918, q23);
2893 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x1817161514131211, q24);
2894 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q25);
2895 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q26);
2896 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q27);
2897 ASSERT_EQUAL_128(0x2027262524232221, 0x2023222120212020, q6);
2898 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q7);
2899
2900 TEARDOWN();
2901}
2902
2903
2904TEST(neon_ld1_d) {
2905 SETUP();
2906
2907 uint8_t src[32 + 5];
2908 for (unsigned i = 0; i < sizeof(src); i++) {
2909 src[i] = i;
2910 }
2911 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2912
2913 START();
2914 __ Mov(x17, src_base);
2915 __ Ldr(q2, MemOperand(x17)); // Initialise top 64-bits of Q register.
2916 __ Ld1(v2.V8B(), MemOperand(x17));
2917 __ Add(x17, x17, 1);
2918 __ Ld1(v3.V8B(), v4.V8B(), MemOperand(x17));
2919 __ Add(x17, x17, 1);
2920 __ Ld1(v5.V4H(), v6.V4H(), v7.V4H(), MemOperand(x17));
2921 __ Add(x17, x17, 1);
2922 __ Ld1(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(), MemOperand(x17));
2923 __ Add(x17, x17, 1);
2924 __ Ld1(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x17));
2925 __ Add(x17, x17, 1);
2926 __ Ld1(v20.V1D(), v21.V1D(), v22.V1D(), v23.V1D(), MemOperand(x17));
2927 END();
2928
2929 RUN();
2930
2931 ASSERT_EQUAL_128(0, 0x0706050403020100, q2);
2932 ASSERT_EQUAL_128(0, 0x0807060504030201, q3);
2933 ASSERT_EQUAL_128(0, 0x100f0e0d0c0b0a09, q4);
2934 ASSERT_EQUAL_128(0, 0x0908070605040302, q5);
2935 ASSERT_EQUAL_128(0, 0x11100f0e0d0c0b0a, q6);
2936 ASSERT_EQUAL_128(0, 0x1918171615141312, q7);
2937 ASSERT_EQUAL_128(0, 0x0a09080706050403, q16);
2938 ASSERT_EQUAL_128(0, 0x1211100f0e0d0c0b, q17);
2939 ASSERT_EQUAL_128(0, 0x1a19181716151413, q18);
2940 ASSERT_EQUAL_128(0, 0x2221201f1e1d1c1b, q19);
2941 ASSERT_EQUAL_128(0, 0x0b0a090807060504, q30);
2942 ASSERT_EQUAL_128(0, 0x131211100f0e0d0c, q31);
2943 ASSERT_EQUAL_128(0, 0x1b1a191817161514, q0);
2944 ASSERT_EQUAL_128(0, 0x232221201f1e1d1c, q1);
2945 ASSERT_EQUAL_128(0, 0x0c0b0a0908070605, q20);
2946 ASSERT_EQUAL_128(0, 0x14131211100f0e0d, q21);
2947 ASSERT_EQUAL_128(0, 0x1c1b1a1918171615, q22);
2948 ASSERT_EQUAL_128(0, 0x24232221201f1e1d, q23);
2949
2950 TEARDOWN();
2951}
2952
2953
2954TEST(neon_ld1_d_postindex) {
2955 SETUP();
2956
2957 uint8_t src[32 + 5];
2958 for (unsigned i = 0; i < sizeof(src); i++) {
2959 src[i] = i;
2960 }
2961 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2962
2963 START();
2964 __ Mov(x17, src_base);
2965 __ Mov(x18, src_base + 1);
2966 __ Mov(x19, src_base + 2);
2967 __ Mov(x20, src_base + 3);
2968 __ Mov(x21, src_base + 4);
2969 __ Mov(x22, src_base + 5);
2970 __ Mov(x23, 1);
2971 __ Ldr(q2, MemOperand(x17)); // Initialise top 64-bits of Q register.
2972 __ Ld1(v2.V8B(), MemOperand(x17, x23, PostIndex));
2973 __ Ld1(v3.V8B(), v4.V8B(), MemOperand(x18, 16, PostIndex));
2974 __ Ld1(v5.V4H(), v6.V4H(), v7.V4H(), MemOperand(x19, 24, PostIndex));
2975 __ Ld1(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(),
2976 MemOperand(x20, 32, PostIndex));
2977 __ Ld1(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(),
2978 MemOperand(x21, 32, PostIndex));
2979 __ Ld1(v20.V1D(), v21.V1D(), v22.V1D(), v23.V1D(),
2980 MemOperand(x22, 32, PostIndex));
2981 END();
2982
2983 RUN();
2984
2985 ASSERT_EQUAL_128(0, 0x0706050403020100, q2);
2986 ASSERT_EQUAL_128(0, 0x0807060504030201, q3);
2987 ASSERT_EQUAL_128(0, 0x100f0e0d0c0b0a09, q4);
2988 ASSERT_EQUAL_128(0, 0x0908070605040302, q5);
2989 ASSERT_EQUAL_128(0, 0x11100f0e0d0c0b0a, q6);
2990 ASSERT_EQUAL_128(0, 0x1918171615141312, q7);
2991 ASSERT_EQUAL_128(0, 0x0a09080706050403, q16);
2992 ASSERT_EQUAL_128(0, 0x1211100f0e0d0c0b, q17);
2993 ASSERT_EQUAL_128(0, 0x1a19181716151413, q18);
2994 ASSERT_EQUAL_128(0, 0x2221201f1e1d1c1b, q19);
2995 ASSERT_EQUAL_128(0, 0x0b0a090807060504, q30);
2996 ASSERT_EQUAL_128(0, 0x131211100f0e0d0c, q31);
2997 ASSERT_EQUAL_128(0, 0x1b1a191817161514, q0);
2998 ASSERT_EQUAL_128(0, 0x232221201f1e1d1c, q1);
2999 ASSERT_EQUAL_128(0, 0x0c0b0a0908070605, q20);
3000 ASSERT_EQUAL_128(0, 0x14131211100f0e0d, q21);
3001 ASSERT_EQUAL_128(0, 0x1c1b1a1918171615, q22);
3002 ASSERT_EQUAL_128(0, 0x24232221201f1e1d, q23);
3003 ASSERT_EQUAL_64(src_base + 1, x17);
3004 ASSERT_EQUAL_64(src_base + 1 + 16, x18);
3005 ASSERT_EQUAL_64(src_base + 2 + 24, x19);
3006 ASSERT_EQUAL_64(src_base + 3 + 32, x20);
3007 ASSERT_EQUAL_64(src_base + 4 + 32, x21);
3008 ASSERT_EQUAL_64(src_base + 5 + 32, x22);
3009
3010 TEARDOWN();
3011}
3012
3013
3014TEST(neon_ld1_q) {
3015 SETUP();
3016
3017 uint8_t src[64 + 4];
3018 for (unsigned i = 0; i < sizeof(src); i++) {
3019 src[i] = i;
3020 }
3021 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3022
3023 START();
3024 __ Mov(x17, src_base);
3025 __ Ld1(v2.V16B(), MemOperand(x17));
3026 __ Add(x17, x17, 1);
3027 __ Ld1(v3.V16B(), v4.V16B(), MemOperand(x17));
3028 __ Add(x17, x17, 1);
3029 __ Ld1(v5.V8H(), v6.V8H(), v7.V8H(), MemOperand(x17));
3030 __ Add(x17, x17, 1);
3031 __ Ld1(v16.V4S(), v17.V4S(), v18.V4S(), v19.V4S(), MemOperand(x17));
3032 __ Add(x17, x17, 1);
3033 __ Ld1(v30.V2D(), v31.V2D(), v0.V2D(), v1.V2D(), MemOperand(x17));
3034 END();
3035
3036 RUN();
3037
3038 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q2);
3039 ASSERT_EQUAL_128(0x100f0e0d0c0b0a09, 0x0807060504030201, q3);
3040 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x1817161514131211, q4);
3041 ASSERT_EQUAL_128(0x11100f0e0d0c0b0a, 0x0908070605040302, q5);
3042 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x1918171615141312, q6);
3043 ASSERT_EQUAL_128(0x31302f2e2d2c2b2a, 0x2928272625242322, q7);
3044 ASSERT_EQUAL_128(0x1211100f0e0d0c0b, 0x0a09080706050403, q16);
3045 ASSERT_EQUAL_128(0x2221201f1e1d1c1b, 0x1a19181716151413, q17);
3046 ASSERT_EQUAL_128(0x3231302f2e2d2c2b, 0x2a29282726252423, q18);
3047 ASSERT_EQUAL_128(0x4241403f3e3d3c3b, 0x3a39383736353433, q19);
3048 ASSERT_EQUAL_128(0x131211100f0e0d0c, 0x0b0a090807060504, q30);
3049 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x1b1a191817161514, q31);
3050 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x2b2a292827262524, q0);
3051 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x3b3a393837363534, q1);
3052
3053 TEARDOWN();
3054}
3055
3056
3057TEST(neon_ld1_q_postindex) {
3058 SETUP();
3059
3060 uint8_t src[64 + 4];
3061 for (unsigned i = 0; i < sizeof(src); i++) {
3062 src[i] = i;
3063 }
3064 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3065
3066 START();
3067 __ Mov(x17, src_base);
3068 __ Mov(x18, src_base + 1);
3069 __ Mov(x19, src_base + 2);
3070 __ Mov(x20, src_base + 3);
3071 __ Mov(x21, src_base + 4);
3072 __ Mov(x22, 1);
3073 __ Ld1(v2.V16B(), MemOperand(x17, x22, PostIndex));
3074 __ Ld1(v3.V16B(), v4.V16B(), MemOperand(x18, 32, PostIndex));
3075 __ Ld1(v5.V8H(), v6.V8H(), v7.V8H(), MemOperand(x19, 48, PostIndex));
3076 __ Ld1(v16.V4S(), v17.V4S(), v18.V4S(), v19.V4S(),
3077 MemOperand(x20, 64, PostIndex));
3078 __ Ld1(v30.V2D(), v31.V2D(), v0.V2D(), v1.V2D(),
3079 MemOperand(x21, 64, PostIndex));
3080 END();
3081
3082 RUN();
3083
3084 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q2);
3085 ASSERT_EQUAL_128(0x100f0e0d0c0b0a09, 0x0807060504030201, q3);
3086 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x1817161514131211, q4);
3087 ASSERT_EQUAL_128(0x11100f0e0d0c0b0a, 0x0908070605040302, q5);
3088 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x1918171615141312, q6);
3089 ASSERT_EQUAL_128(0x31302f2e2d2c2b2a, 0x2928272625242322, q7);
3090 ASSERT_EQUAL_128(0x1211100f0e0d0c0b, 0x0a09080706050403, q16);
3091 ASSERT_EQUAL_128(0x2221201f1e1d1c1b, 0x1a19181716151413, q17);
3092 ASSERT_EQUAL_128(0x3231302f2e2d2c2b, 0x2a29282726252423, q18);
3093 ASSERT_EQUAL_128(0x4241403f3e3d3c3b, 0x3a39383736353433, q19);
3094 ASSERT_EQUAL_128(0x131211100f0e0d0c, 0x0b0a090807060504, q30);
3095 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x1b1a191817161514, q31);
3096 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x2b2a292827262524, q0);
3097 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x3b3a393837363534, q1);
3098 ASSERT_EQUAL_64(src_base + 1, x17);
3099 ASSERT_EQUAL_64(src_base + 1 + 32, x18);
3100 ASSERT_EQUAL_64(src_base + 2 + 48, x19);
3101 ASSERT_EQUAL_64(src_base + 3 + 64, x20);
3102 ASSERT_EQUAL_64(src_base + 4 + 64, x21);
3103
3104 TEARDOWN();
3105}
3106
3107
3108TEST(neon_ld1_lane) {
3109 SETUP();
3110
3111 uint8_t src[64];
3112 for (unsigned i = 0; i < sizeof(src); i++) {
3113 src[i] = i;
3114 }
3115 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3116
3117 START();
3118
3119 // Test loading whole register by element.
3120 __ Mov(x17, src_base);
3121 for (int i = 15; i >= 0; i--) {
3122 __ Ld1(v0.B(), i, MemOperand(x17));
3123 __ Add(x17, x17, 1);
3124 }
3125
3126 __ Mov(x17, src_base);
3127 for (int i = 7; i >= 0; i--) {
3128 __ Ld1(v1.H(), i, MemOperand(x17));
3129 __ Add(x17, x17, 1);
3130 }
3131
3132 __ Mov(x17, src_base);
3133 for (int i = 3; i >= 0; i--) {
3134 __ Ld1(v2.S(), i, MemOperand(x17));
3135 __ Add(x17, x17, 1);
3136 }
3137
3138 __ Mov(x17, src_base);
3139 for (int i = 1; i >= 0; i--) {
3140 __ Ld1(v3.D(), i, MemOperand(x17));
3141 __ Add(x17, x17, 1);
3142 }
3143
3144 // Test loading a single element into an initialised register.
3145 __ Mov(x17, src_base);
3146 __ Ldr(q4, MemOperand(x17));
3147 __ Ld1(v4.B(), 4, MemOperand(x17));
3148 __ Ldr(q5, MemOperand(x17));
3149 __ Ld1(v5.H(), 3, MemOperand(x17));
3150 __ Ldr(q6, MemOperand(x17));
3151 __ Ld1(v6.S(), 2, MemOperand(x17));
3152 __ Ldr(q7, MemOperand(x17));
3153 __ Ld1(v7.D(), 1, MemOperand(x17));
3154
3155 END();
3156
3157 RUN();
3158
3159 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
3160 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q1);
3161 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q2);
3162 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q3);
3163 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q4);
3164 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q5);
3165 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q6);
3166 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q7);
3167
3168 TEARDOWN();
3169}
3170
3171TEST(neon_ld2_d) {
3172 SETUP();
3173
3174 uint8_t src[64 + 4];
3175 for (unsigned i = 0; i < sizeof(src); i++) {
3176 src[i] = i;
3177 }
3178 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3179
3180 START();
3181 __ Mov(x17, src_base);
3182 __ Ld2(v2.V8B(), v3.V8B(), MemOperand(x17));
3183 __ Add(x17, x17, 1);
3184 __ Ld2(v4.V8B(), v5.V8B(), MemOperand(x17));
3185 __ Add(x17, x17, 1);
3186 __ Ld2(v6.V4H(), v7.V4H(), MemOperand(x17));
3187 __ Add(x17, x17, 1);
3188 __ Ld2(v31.V2S(), v0.V2S(), MemOperand(x17));
3189 END();
3190
3191 RUN();
3192
3193 ASSERT_EQUAL_128(0, 0x0e0c0a0806040200, q2);
3194 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q3);
3195 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q4);
3196 ASSERT_EQUAL_128(0, 0x100e0c0a08060402, q5);
3197 ASSERT_EQUAL_128(0, 0x0f0e0b0a07060302, q6);
3198 ASSERT_EQUAL_128(0, 0x11100d0c09080504, q7);
3199 ASSERT_EQUAL_128(0, 0x0e0d0c0b06050403, q31);
3200 ASSERT_EQUAL_128(0, 0x1211100f0a090807, q0);
3201
3202 TEARDOWN();
3203}
3204
3205TEST(neon_ld2_d_postindex) {
3206 SETUP();
3207
3208 uint8_t src[32 + 4];
3209 for (unsigned i = 0; i < sizeof(src); i++) {
3210 src[i] = i;
3211 }
3212 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3213
3214 START();
3215 __ Mov(x17, src_base);
3216 __ Mov(x18, src_base + 1);
3217 __ Mov(x19, src_base + 2);
3218 __ Mov(x20, src_base + 3);
3219 __ Mov(x21, src_base + 4);
3220 __ Mov(x22, 1);
3221 __ Ld2(v2.V8B(), v3.V8B(), MemOperand(x17, x22, PostIndex));
3222 __ Ld2(v4.V8B(), v5.V8B(), MemOperand(x18, 16, PostIndex));
3223 __ Ld2(v5.V4H(), v6.V4H(), MemOperand(x19, 16, PostIndex));
3224 __ Ld2(v16.V2S(), v17.V2S(), MemOperand(x20, 16, PostIndex));
3225 __ Ld2(v31.V2S(), v0.V2S(), MemOperand(x21, 16, PostIndex));
3226 END();
3227
3228 RUN();
3229
3230 ASSERT_EQUAL_128(0, 0x0e0c0a0806040200, q2);
3231 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q3);
3232 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q4);
3233 ASSERT_EQUAL_128(0, 0x0f0e0b0a07060302, q5);
3234 ASSERT_EQUAL_128(0, 0x11100d0c09080504, q6);
3235 ASSERT_EQUAL_128(0, 0x0e0d0c0b06050403, q16);
3236 ASSERT_EQUAL_128(0, 0x1211100f0a090807, q17);
3237 ASSERT_EQUAL_128(0, 0x0f0e0d0c07060504, q31);
3238 ASSERT_EQUAL_128(0, 0x131211100b0a0908, q0);
3239
3240 ASSERT_EQUAL_64(src_base + 1, x17);
3241 ASSERT_EQUAL_64(src_base + 1 + 16, x18);
3242 ASSERT_EQUAL_64(src_base + 2 + 16, x19);
3243 ASSERT_EQUAL_64(src_base + 3 + 16, x20);
3244 ASSERT_EQUAL_64(src_base + 4 + 16, x21);
3245
3246 TEARDOWN();
3247}
3248
3249
3250TEST(neon_ld2_q) {
3251 SETUP();
3252
3253 uint8_t src[64 + 4];
3254 for (unsigned i = 0; i < sizeof(src); i++) {
3255 src[i] = i;
3256 }
3257 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3258
3259 START();
3260 __ Mov(x17, src_base);
3261 __ Ld2(v2.V16B(), v3.V16B(), MemOperand(x17));
3262 __ Add(x17, x17, 1);
3263 __ Ld2(v4.V16B(), v5.V16B(), MemOperand(x17));
3264 __ Add(x17, x17, 1);
3265 __ Ld2(v6.V8H(), v7.V8H(), MemOperand(x17));
3266 __ Add(x17, x17, 1);
3267 __ Ld2(v16.V4S(), v17.V4S(), MemOperand(x17));
3268 __ Add(x17, x17, 1);
3269 __ Ld2(v31.V2D(), v0.V2D(), MemOperand(x17));
3270 END();
3271
3272 RUN();
3273
3274 ASSERT_EQUAL_128(0x1e1c1a1816141210, 0x0e0c0a0806040200, q2);
3275 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q3);
3276 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q4);
3277 ASSERT_EQUAL_128(0x201e1c1a18161412, 0x100e0c0a08060402, q5);
3278 ASSERT_EQUAL_128(0x1f1e1b1a17161312, 0x0f0e0b0a07060302, q6);
3279 ASSERT_EQUAL_128(0x21201d1c19181514, 0x11100d0c09080504, q7);
3280 ASSERT_EQUAL_128(0x1e1d1c1b16151413, 0x0e0d0c0b06050403, q16);
3281 ASSERT_EQUAL_128(0x2221201f1a191817, 0x1211100f0a090807, q17);
3282 ASSERT_EQUAL_128(0x1b1a191817161514, 0x0b0a090807060504, q31);
3283 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x131211100f0e0d0c, q0);
3284
3285 TEARDOWN();
3286}
3287
3288
3289TEST(neon_ld2_q_postindex) {
3290 SETUP();
3291
3292 uint8_t src[64 + 4];
3293 for (unsigned i = 0; i < sizeof(src); i++) {
3294 src[i] = i;
3295 }
3296 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3297
3298 START();
3299 __ Mov(x17, src_base);
3300 __ Mov(x18, src_base + 1);
3301 __ Mov(x19, src_base + 2);
3302 __ Mov(x20, src_base + 3);
3303 __ Mov(x21, src_base + 4);
3304 __ Mov(x22, 1);
3305 __ Ld2(v2.V16B(), v3.V16B(), MemOperand(x17, x22, PostIndex));
3306 __ Ld2(v4.V16B(), v5.V16B(), MemOperand(x18, 32, PostIndex));
3307 __ Ld2(v6.V8H(), v7.V8H(), MemOperand(x19, 32, PostIndex));
3308 __ Ld2(v16.V4S(), v17.V4S(), MemOperand(x20, 32, PostIndex));
3309 __ Ld2(v31.V2D(), v0.V2D(), MemOperand(x21, 32, PostIndex));
3310 END();
3311
3312 RUN();
3313
3314 ASSERT_EQUAL_128(0x1e1c1a1816141210, 0x0e0c0a0806040200, q2);
3315 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q3);
3316 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q4);
3317 ASSERT_EQUAL_128(0x201e1c1a18161412, 0x100e0c0a08060402, q5);
3318 ASSERT_EQUAL_128(0x1f1e1b1a17161312, 0x0f0e0b0a07060302, q6);
3319 ASSERT_EQUAL_128(0x21201d1c19181514, 0x11100d0c09080504, q7);
3320 ASSERT_EQUAL_128(0x1e1d1c1b16151413, 0x0e0d0c0b06050403, q16);
3321 ASSERT_EQUAL_128(0x2221201f1a191817, 0x1211100f0a090807, q17);
3322 ASSERT_EQUAL_128(0x1b1a191817161514, 0x0b0a090807060504, q31);
3323 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x131211100f0e0d0c, q0);
3324
3325
3326
3327 ASSERT_EQUAL_64(src_base + 1, x17);
3328 ASSERT_EQUAL_64(src_base + 1 + 32, x18);
3329 ASSERT_EQUAL_64(src_base + 2 + 32, x19);
3330 ASSERT_EQUAL_64(src_base + 3 + 32, x20);
3331 ASSERT_EQUAL_64(src_base + 4 + 32, x21);
3332
3333 TEARDOWN();
3334}
3335
3336
3337TEST(neon_ld2_lane) {
3338 SETUP();
3339
3340 uint8_t src[64];
3341 for (unsigned i = 0; i < sizeof(src); i++) {
3342 src[i] = i;
3343 }
3344 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3345
3346 START();
3347
3348 // Test loading whole register by element.
3349 __ Mov(x17, src_base);
3350 for (int i = 15; i >= 0; i--) {
3351 __ Ld2(v0.B(), v1.B(), i, MemOperand(x17));
3352 __ Add(x17, x17, 1);
3353 }
3354
3355 __ Mov(x17, src_base);
3356 for (int i = 7; i >= 0; i--) {
3357 __ Ld2(v2.H(), v3.H(), i, MemOperand(x17));
3358 __ Add(x17, x17, 1);
3359 }
3360
3361 __ Mov(x17, src_base);
3362 for (int i = 3; i >= 0; i--) {
3363 __ Ld2(v4.S(), v5.S(), i, MemOperand(x17));
3364 __ Add(x17, x17, 1);
3365 }
3366
3367 __ Mov(x17, src_base);
3368 for (int i = 1; i >= 0; i--) {
3369 __ Ld2(v6.D(), v7.D(), i, MemOperand(x17));
3370 __ Add(x17, x17, 1);
3371 }
3372
3373 // Test loading a single element into an initialised register.
3374 __ Mov(x17, src_base);
3375 __ Mov(x4, x17);
3376 __ Ldr(q8, MemOperand(x4, 16, PostIndex));
3377 __ Ldr(q9, MemOperand(x4));
3378 __ Ld2(v8.B(), v9.B(), 4, MemOperand(x17));
3379 __ Mov(x5, x17);
3380 __ Ldr(q10, MemOperand(x5, 16, PostIndex));
3381 __ Ldr(q11, MemOperand(x5));
3382 __ Ld2(v10.H(), v11.H(), 3, MemOperand(x17));
3383 __ Mov(x6, x17);
3384 __ Ldr(q12, MemOperand(x6, 16, PostIndex));
3385 __ Ldr(q13, MemOperand(x6));
3386 __ Ld2(v12.S(), v13.S(), 2, MemOperand(x17));
3387 __ Mov(x7, x17);
3388 __ Ldr(q14, MemOperand(x7, 16, PostIndex));
3389 __ Ldr(q15, MemOperand(x7));
3390 __ Ld2(v14.D(), v15.D(), 1, MemOperand(x17));
3391
3392 END();
3393
3394 RUN();
3395
3396 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
3397 ASSERT_EQUAL_128(0x0102030405060708, 0x090a0b0c0d0e0f10, q1);
3398 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q2);
3399 ASSERT_EQUAL_128(0x0302040305040605, 0x0706080709080a09, q3);
3400 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q4);
3401 ASSERT_EQUAL_128(0x0706050408070605, 0x090807060a090807, q5);
3402 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q6);
3403 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x100f0e0d0c0b0a09, q7);
3404 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q8);
3405 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q9);
3406 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q10);
3407 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q11);
3408 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q12);
3409 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q13);
3410 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q14);
3411 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q15);
3412
3413 TEARDOWN();
3414}
3415
3416
3417TEST(neon_ld2_lane_postindex) {
3418 SETUP();
3419
3420 uint8_t src[64];
3421 for (unsigned i = 0; i < sizeof(src); i++) {
3422 src[i] = i;
3423 }
3424 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3425
3426 START();
3427 __ Mov(x17, src_base);
3428 __ Mov(x18, src_base);
3429 __ Mov(x19, src_base);
3430 __ Mov(x20, src_base);
3431 __ Mov(x21, src_base);
3432 __ Mov(x22, src_base);
3433 __ Mov(x23, src_base);
3434 __ Mov(x24, src_base);
3435
3436 // Test loading whole register by element.
3437 for (int i = 15; i >= 0; i--) {
3438 __ Ld2(v0.B(), v1.B(), i, MemOperand(x17, 2, PostIndex));
3439 }
3440
3441 for (int i = 7; i >= 0; i--) {
3442 __ Ld2(v2.H(), v3.H(), i, MemOperand(x18, 4, PostIndex));
3443 }
3444
3445 for (int i = 3; i >= 0; i--) {
3446 __ Ld2(v4.S(), v5.S(), i, MemOperand(x19, 8, PostIndex));
3447 }
3448
3449 for (int i = 1; i >= 0; i--) {
3450 __ Ld2(v6.D(), v7.D(), i, MemOperand(x20, 16, PostIndex));
3451 }
3452
3453 // Test loading a single element into an initialised register.
3454 __ Mov(x25, 1);
3455 __ Mov(x4, x21);
3456 __ Ldr(q8, MemOperand(x4, 16, PostIndex));
3457 __ Ldr(q9, MemOperand(x4));
3458 __ Ld2(v8.B(), v9.B(), 4, MemOperand(x21, x25, PostIndex));
3459 __ Add(x25, x25, 1);
3460
3461 __ Mov(x5, x22);
3462 __ Ldr(q10, MemOperand(x5, 16, PostIndex));
3463 __ Ldr(q11, MemOperand(x5));
3464 __ Ld2(v10.H(), v11.H(), 3, MemOperand(x22, x25, PostIndex));
3465 __ Add(x25, x25, 1);
3466
3467 __ Mov(x6, x23);
3468 __ Ldr(q12, MemOperand(x6, 16, PostIndex));
3469 __ Ldr(q13, MemOperand(x6));
3470 __ Ld2(v12.S(), v13.S(), 2, MemOperand(x23, x25, PostIndex));
3471 __ Add(x25, x25, 1);
3472
3473 __ Mov(x7, x24);
3474 __ Ldr(q14, MemOperand(x7, 16, PostIndex));
3475 __ Ldr(q15, MemOperand(x7));
3476 __ Ld2(v14.D(), v15.D(), 1, MemOperand(x24, x25, PostIndex));
3477
3478 END();
3479
3480 RUN();
3481
3482 ASSERT_EQUAL_128(0x00020406080a0c0e, 0x10121416181a1c1e, q0);
3483 ASSERT_EQUAL_128(0x01030507090b0d0f, 0x11131517191b1d1f, q1);
3484 ASSERT_EQUAL_128(0x0100050409080d0c, 0x1110151419181d1c, q2);
3485 ASSERT_EQUAL_128(0x030207060b0a0f0e, 0x131217161b1a1f1e, q3);
3486 ASSERT_EQUAL_128(0x030201000b0a0908, 0x131211101b1a1918, q4);
3487 ASSERT_EQUAL_128(0x070605040f0e0d0c, 0x171615141f1e1d1c, q5);
3488 ASSERT_EQUAL_128(0x0706050403020100, 0x1716151413121110, q6);
3489 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1f1e1d1c1b1a1918, q7);
3490 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q8);
3491 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q9);
3492 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q10);
3493 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q11);
3494 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q12);
3495 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q13);
3496 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q14);
3497 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q15);
3498
3499
3500
3501
3502 ASSERT_EQUAL_64(src_base + 32, x17);
3503 ASSERT_EQUAL_64(src_base + 32, x18);
3504 ASSERT_EQUAL_64(src_base + 32, x19);
3505 ASSERT_EQUAL_64(src_base + 32, x20);
3506 ASSERT_EQUAL_64(src_base + 1, x21);
3507 ASSERT_EQUAL_64(src_base + 2, x22);
3508 ASSERT_EQUAL_64(src_base + 3, x23);
3509 ASSERT_EQUAL_64(src_base + 4, x24);
3510
3511 TEARDOWN();
3512}
3513
3514
3515TEST(neon_ld2_alllanes) {
3516 SETUP();
3517
3518 uint8_t src[64];
3519 for (unsigned i = 0; i < sizeof(src); i++) {
3520 src[i] = i;
3521 }
3522 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3523
3524 START();
3525 __ Mov(x17, src_base + 1);
3526 __ Mov(x18, 1);
3527 __ Ld2r(v0.V8B(), v1.V8B(), MemOperand(x17));
3528 __ Add(x17, x17, 2);
3529 __ Ld2r(v2.V16B(), v3.V16B(), MemOperand(x17));
3530 __ Add(x17, x17, 1);
3531 __ Ld2r(v4.V4H(), v5.V4H(), MemOperand(x17));
3532 __ Add(x17, x17, 1);
3533 __ Ld2r(v6.V8H(), v7.V8H(), MemOperand(x17));
3534 __ Add(x17, x17, 4);
3535 __ Ld2r(v8.V2S(), v9.V2S(), MemOperand(x17));
3536 __ Add(x17, x17, 1);
3537 __ Ld2r(v10.V4S(), v11.V4S(), MemOperand(x17));
3538 __ Add(x17, x17, 8);
3539 __ Ld2r(v12.V2D(), v13.V2D(), MemOperand(x17));
3540 END();
3541
3542 RUN();
3543
3544 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
3545 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
3546 ASSERT_EQUAL_128(0x0303030303030303, 0x0303030303030303, q2);
3547 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
3548 ASSERT_EQUAL_128(0x0000000000000000, 0x0504050405040504, q4);
3549 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q5);
3550 ASSERT_EQUAL_128(0x0605060506050605, 0x0605060506050605, q6);
3551 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q7);
3552 ASSERT_EQUAL_128(0x0000000000000000, 0x0c0b0a090c0b0a09, q8);
3553 ASSERT_EQUAL_128(0x0000000000000000, 0x100f0e0d100f0e0d, q9);
3554 ASSERT_EQUAL_128(0x0d0c0b0a0d0c0b0a, 0x0d0c0b0a0d0c0b0a, q10);
3555 ASSERT_EQUAL_128(0x11100f0e11100f0e, 0x11100f0e11100f0e, q11);
3556 ASSERT_EQUAL_128(0x1918171615141312, 0x1918171615141312, q12);
3557 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x21201f1e1d1c1b1a, q13);
3558
3559 TEARDOWN();
3560}
3561
3562
3563TEST(neon_ld2_alllanes_postindex) {
3564 SETUP();
3565
3566 uint8_t src[64];
3567 for (unsigned i = 0; i < sizeof(src); i++) {
3568 src[i] = i;
3569 }
3570 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3571
3572 START();
3573 __ Mov(x17, src_base + 1);
3574 __ Mov(x18, 1);
3575 __ Ld2r(v0.V8B(), v1.V8B(), MemOperand(x17, 2, PostIndex));
3576 __ Ld2r(v2.V16B(), v3.V16B(), MemOperand(x17, x18, PostIndex));
3577 __ Ld2r(v4.V4H(), v5.V4H(), MemOperand(x17, x18, PostIndex));
3578 __ Ld2r(v6.V8H(), v7.V8H(), MemOperand(x17, 4, PostIndex));
3579 __ Ld2r(v8.V2S(), v9.V2S(), MemOperand(x17, x18, PostIndex));
3580 __ Ld2r(v10.V4S(), v11.V4S(), MemOperand(x17, 8, PostIndex));
3581 __ Ld2r(v12.V2D(), v13.V2D(), MemOperand(x17, 16, PostIndex));
3582 END();
3583
3584 RUN();
3585
3586 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
3587 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
3588 ASSERT_EQUAL_128(0x0303030303030303, 0x0303030303030303, q2);
3589 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
3590 ASSERT_EQUAL_128(0x0000000000000000, 0x0504050405040504, q4);
3591 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q5);
3592 ASSERT_EQUAL_128(0x0605060506050605, 0x0605060506050605, q6);
3593 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q7);
3594 ASSERT_EQUAL_128(0x0000000000000000, 0x0c0b0a090c0b0a09, q8);
3595 ASSERT_EQUAL_128(0x0000000000000000, 0x100f0e0d100f0e0d, q9);
3596 ASSERT_EQUAL_128(0x0d0c0b0a0d0c0b0a, 0x0d0c0b0a0d0c0b0a, q10);
3597 ASSERT_EQUAL_128(0x11100f0e11100f0e, 0x11100f0e11100f0e, q11);
3598 ASSERT_EQUAL_128(0x1918171615141312, 0x1918171615141312, q12);
3599 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x21201f1e1d1c1b1a, q13);
3600 ASSERT_EQUAL_64(src_base + 34, x17);
3601
3602 TEARDOWN();
3603}
3604
3605
3606TEST(neon_ld3_d) {
3607 SETUP();
3608
3609 uint8_t src[64 + 4];
3610 for (unsigned i = 0; i < sizeof(src); i++) {
3611 src[i] = i;
3612 }
3613 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3614
3615 START();
3616 __ Mov(x17, src_base);
3617 __ Ld3(v2.V8B(), v3.V8B(), v4.V8B(), MemOperand(x17));
3618 __ Add(x17, x17, 1);
3619 __ Ld3(v5.V8B(), v6.V8B(), v7.V8B(), MemOperand(x17));
3620 __ Add(x17, x17, 1);
3621 __ Ld3(v8.V4H(), v9.V4H(), v10.V4H(), MemOperand(x17));
3622 __ Add(x17, x17, 1);
3623 __ Ld3(v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x17));
3624 END();
3625
3626 RUN();
3627
3628 ASSERT_EQUAL_128(0, 0x15120f0c09060300, q2);
3629 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q3);
3630 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q4);
3631 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q5);
3632 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q6);
3633 ASSERT_EQUAL_128(0, 0x1815120f0c090603, q7);
3634 ASSERT_EQUAL_128(0, 0x15140f0e09080302, q8);
3635 ASSERT_EQUAL_128(0, 0x171611100b0a0504, q9);
3636 ASSERT_EQUAL_128(0, 0x191813120d0c0706, q10);
3637 ASSERT_EQUAL_128(0, 0x1211100f06050403, q31);
3638 ASSERT_EQUAL_128(0, 0x161514130a090807, q0);
3639 ASSERT_EQUAL_128(0, 0x1a1918170e0d0c0b, q1);
3640
3641 TEARDOWN();
3642}
3643
3644
3645TEST(neon_ld3_d_postindex) {
3646 SETUP();
3647
3648 uint8_t src[32 + 4];
3649 for (unsigned i = 0; i < sizeof(src); i++) {
3650 src[i] = i;
3651 }
3652 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3653
3654 START();
3655 __ Mov(x17, src_base);
3656 __ Mov(x18, src_base + 1);
3657 __ Mov(x19, src_base + 2);
3658 __ Mov(x20, src_base + 3);
3659 __ Mov(x21, src_base + 4);
3660 __ Mov(x22, 1);
3661 __ Ld3(v2.V8B(), v3.V8B(), v4.V8B(), MemOperand(x17, x22, PostIndex));
3662 __ Ld3(v5.V8B(), v6.V8B(), v7.V8B(), MemOperand(x18, 24, PostIndex));
3663 __ Ld3(v8.V4H(), v9.V4H(), v10.V4H(), MemOperand(x19, 24, PostIndex));
3664 __ Ld3(v11.V2S(), v12.V2S(), v13.V2S(), MemOperand(x20, 24, PostIndex));
3665 __ Ld3(v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x21, 24, PostIndex));
3666 END();
3667
3668 RUN();
3669
3670 ASSERT_EQUAL_128(0, 0x15120f0c09060300, q2);
3671 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q3);
3672 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q4);
3673 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q5);
3674 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q6);
3675 ASSERT_EQUAL_128(0, 0x1815120f0c090603, q7);
3676 ASSERT_EQUAL_128(0, 0x15140f0e09080302, q8);
3677 ASSERT_EQUAL_128(0, 0x171611100b0a0504, q9);
3678 ASSERT_EQUAL_128(0, 0x191813120d0c0706, q10);
3679 ASSERT_EQUAL_128(0, 0x1211100f06050403, q11);
3680 ASSERT_EQUAL_128(0, 0x161514130a090807, q12);
3681 ASSERT_EQUAL_128(0, 0x1a1918170e0d0c0b, q13);
3682 ASSERT_EQUAL_128(0, 0x1312111007060504, q31);
3683 ASSERT_EQUAL_128(0, 0x171615140b0a0908, q0);
3684 ASSERT_EQUAL_128(0, 0x1b1a19180f0e0d0c, q1);
3685
3686 ASSERT_EQUAL_64(src_base + 1, x17);
3687 ASSERT_EQUAL_64(src_base + 1 + 24, x18);
3688 ASSERT_EQUAL_64(src_base + 2 + 24, x19);
3689 ASSERT_EQUAL_64(src_base + 3 + 24, x20);
3690 ASSERT_EQUAL_64(src_base + 4 + 24, x21);
3691
3692 TEARDOWN();
3693}
3694
3695
3696TEST(neon_ld3_q) {
3697 SETUP();
3698
3699 uint8_t src[64 + 4];
3700 for (unsigned i = 0; i < sizeof(src); i++) {
3701 src[i] = i;
3702 }
3703 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3704
3705 START();
3706 __ Mov(x17, src_base);
3707 __ Ld3(v2.V16B(), v3.V16B(), v4.V16B(), MemOperand(x17));
3708 __ Add(x17, x17, 1);
3709 __ Ld3(v5.V16B(), v6.V16B(), v7.V16B(), MemOperand(x17));
3710 __ Add(x17, x17, 1);
3711 __ Ld3(v8.V8H(), v9.V8H(), v10.V8H(), MemOperand(x17));
3712 __ Add(x17, x17, 1);
3713 __ Ld3(v11.V4S(), v12.V4S(), v13.V4S(), MemOperand(x17));
3714 __ Add(x17, x17, 1);
3715 __ Ld3(v31.V2D(), v0.V2D(), v1.V2D(), MemOperand(x17));
3716 END();
3717
3718 RUN();
3719
3720 ASSERT_EQUAL_128(0x2d2a2724211e1b18, 0x15120f0c09060300, q2);
3721 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q3);
3722 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q4);
3723 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q5);
3724 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q6);
3725 ASSERT_EQUAL_128(0x302d2a2724211e1b, 0x1815120f0c090603, q7);
3726 ASSERT_EQUAL_128(0x2d2c272621201b1a, 0x15140f0e09080302, q8);
3727 ASSERT_EQUAL_128(0x2f2e292823221d1c, 0x171611100b0a0504, q9);
3728 ASSERT_EQUAL_128(0x31302b2a25241f1e, 0x191813120d0c0706, q10);
3729 ASSERT_EQUAL_128(0x2a2928271e1d1c1b, 0x1211100f06050403, q11);
3730 ASSERT_EQUAL_128(0x2e2d2c2b2221201f, 0x161514130a090807, q12);
3731 ASSERT_EQUAL_128(0x3231302f26252423, 0x1a1918170e0d0c0b, q13);
3732 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x0b0a090807060504, q31);
3733 ASSERT_EQUAL_128(0x2b2a292827262524, 0x131211100f0e0d0c, q0);
3734 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x1b1a191817161514, q1);
3735
3736 TEARDOWN();
3737}
3738
3739
3740TEST(neon_ld3_q_postindex) {
3741 SETUP();
3742
3743 uint8_t src[64 + 4];
3744 for (unsigned i = 0; i < sizeof(src); i++) {
3745 src[i] = i;
3746 }
3747 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3748
3749 START();
3750 __ Mov(x17, src_base);
3751 __ Mov(x18, src_base + 1);
3752 __ Mov(x19, src_base + 2);
3753 __ Mov(x20, src_base + 3);
3754 __ Mov(x21, src_base + 4);
3755 __ Mov(x22, 1);
3756
3757 __ Ld3(v2.V16B(), v3.V16B(), v4.V16B(), MemOperand(x17, x22, PostIndex));
3758 __ Ld3(v5.V16B(), v6.V16B(), v7.V16B(), MemOperand(x18, 48, PostIndex));
3759 __ Ld3(v8.V8H(), v9.V8H(), v10.V8H(), MemOperand(x19, 48, PostIndex));
3760 __ Ld3(v11.V4S(), v12.V4S(), v13.V4S(), MemOperand(x20, 48, PostIndex));
3761 __ Ld3(v31.V2D(), v0.V2D(), v1.V2D(), MemOperand(x21, 48, PostIndex));
3762 END();
3763
3764 RUN();
3765
3766 ASSERT_EQUAL_128(0x2d2a2724211e1b18, 0x15120f0c09060300, q2);
3767 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q3);
3768 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q4);
3769 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q5);
3770 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q6);
3771 ASSERT_EQUAL_128(0x302d2a2724211e1b, 0x1815120f0c090603, q7);
3772 ASSERT_EQUAL_128(0x2d2c272621201b1a, 0x15140f0e09080302, q8);
3773 ASSERT_EQUAL_128(0x2f2e292823221d1c, 0x171611100b0a0504, q9);
3774 ASSERT_EQUAL_128(0x31302b2a25241f1e, 0x191813120d0c0706, q10);
3775 ASSERT_EQUAL_128(0x2a2928271e1d1c1b, 0x1211100f06050403, q11);
3776 ASSERT_EQUAL_128(0x2e2d2c2b2221201f, 0x161514130a090807, q12);
3777 ASSERT_EQUAL_128(0x3231302f26252423, 0x1a1918170e0d0c0b, q13);
3778 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x0b0a090807060504, q31);
3779 ASSERT_EQUAL_128(0x2b2a292827262524, 0x131211100f0e0d0c, q0);
3780 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x1b1a191817161514, q1);
3781
3782 ASSERT_EQUAL_64(src_base + 1, x17);
3783 ASSERT_EQUAL_64(src_base + 1 + 48, x18);
3784 ASSERT_EQUAL_64(src_base + 2 + 48, x19);
3785 ASSERT_EQUAL_64(src_base + 3 + 48, x20);
3786 ASSERT_EQUAL_64(src_base + 4 + 48, x21);
3787
3788 TEARDOWN();
3789}
3790
3791
3792TEST(neon_ld3_lane) {
3793 SETUP();
3794
3795 uint8_t src[64];
3796 for (unsigned i = 0; i < sizeof(src); i++) {
3797 src[i] = i;
3798 }
3799 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3800
3801 START();
3802
3803 // Test loading whole register by element.
3804 __ Mov(x17, src_base);
3805 for (int i = 15; i >= 0; i--) {
3806 __ Ld3(v0.B(), v1.B(), v2.B(), i, MemOperand(x17));
3807 __ Add(x17, x17, 1);
3808 }
3809
3810 __ Mov(x17, src_base);
3811 for (int i = 7; i >= 0; i--) {
3812 __ Ld3(v3.H(), v4.H(), v5.H(), i, MemOperand(x17));
3813 __ Add(x17, x17, 1);
3814 }
3815
3816 __ Mov(x17, src_base);
3817 for (int i = 3; i >= 0; i--) {
3818 __ Ld3(v6.S(), v7.S(), v8.S(), i, MemOperand(x17));
3819 __ Add(x17, x17, 1);
3820 }
3821
3822 __ Mov(x17, src_base);
3823 for (int i = 1; i >= 0; i--) {
3824 __ Ld3(v9.D(), v10.D(), v11.D(), i, MemOperand(x17));
3825 __ Add(x17, x17, 1);
3826 }
3827
3828 // Test loading a single element into an initialised register.
3829 __ Mov(x17, src_base);
3830 __ Mov(x4, x17);
3831 __ Ldr(q12, MemOperand(x4, 16, PostIndex));
3832 __ Ldr(q13, MemOperand(x4, 16, PostIndex));
3833 __ Ldr(q14, MemOperand(x4));
3834 __ Ld3(v12.B(), v13.B(), v14.B(), 4, MemOperand(x17));
3835 __ Mov(x5, x17);
3836 __ Ldr(q15, MemOperand(x5, 16, PostIndex));
3837 __ Ldr(q16, MemOperand(x5, 16, PostIndex));
3838 __ Ldr(q17, MemOperand(x5));
3839 __ Ld3(v15.H(), v16.H(), v17.H(), 3, MemOperand(x17));
3840 __ Mov(x6, x17);
3841 __ Ldr(q18, MemOperand(x6, 16, PostIndex));
3842 __ Ldr(q19, MemOperand(x6, 16, PostIndex));
3843 __ Ldr(q20, MemOperand(x6));
3844 __ Ld3(v18.S(), v19.S(), v20.S(), 2, MemOperand(x17));
3845 __ Mov(x7, x17);
3846 __ Ldr(q21, MemOperand(x7, 16, PostIndex));
3847 __ Ldr(q22, MemOperand(x7, 16, PostIndex));
3848 __ Ldr(q23, MemOperand(x7));
3849 __ Ld3(v21.D(), v22.D(), v23.D(), 1, MemOperand(x17));
3850
3851 END();
3852
3853 RUN();
3854
3855 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
3856 ASSERT_EQUAL_128(0x0102030405060708, 0x090a0b0c0d0e0f10, q1);
3857 ASSERT_EQUAL_128(0x0203040506070809, 0x0a0b0c0d0e0f1011, q2);
3858 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q3);
3859 ASSERT_EQUAL_128(0x0302040305040605, 0x0706080709080a09, q4);
3860 ASSERT_EQUAL_128(0x0504060507060807, 0x09080a090b0a0c0b, q5);
3861 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q6);
3862 ASSERT_EQUAL_128(0x0706050408070605, 0x090807060a090807, q7);
3863 ASSERT_EQUAL_128(0x0b0a09080c0b0a09, 0x0d0c0b0a0e0d0c0b, q8);
3864 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q9);
3865 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x100f0e0d0c0b0a09, q10);
3866 ASSERT_EQUAL_128(0x1716151413121110, 0x1817161514131211, q11);
3867 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q12);
3868 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q13);
3869 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q14);
3870 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q15);
3871 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q16);
3872 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q17);
3873
3874 TEARDOWN();
3875}
3876
3877
3878TEST(neon_ld3_lane_postindex) {
3879 SETUP();
3880
3881 uint8_t src[64];
3882 for (unsigned i = 0; i < sizeof(src); i++) {
3883 src[i] = i;
3884 }
3885 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3886
3887 START();
3888
3889 // Test loading whole register by element.
3890 __ Mov(x17, src_base);
3891 __ Mov(x18, src_base);
3892 __ Mov(x19, src_base);
3893 __ Mov(x20, src_base);
3894 __ Mov(x21, src_base);
3895 __ Mov(x22, src_base);
3896 __ Mov(x23, src_base);
3897 __ Mov(x24, src_base);
3898 for (int i = 15; i >= 0; i--) {
3899 __ Ld3(v0.B(), v1.B(), v2.B(), i, MemOperand(x17, 3, PostIndex));
3900 }
3901
3902 for (int i = 7; i >= 0; i--) {
3903 __ Ld3(v3.H(), v4.H(), v5.H(), i, MemOperand(x18, 6, PostIndex));
3904 }
3905
3906 for (int i = 3; i >= 0; i--) {
3907 __ Ld3(v6.S(), v7.S(), v8.S(), i, MemOperand(x19, 12, PostIndex));
3908 }
3909
3910 for (int i = 1; i >= 0; i--) {
3911 __ Ld3(v9.D(), v10.D(), v11.D(), i, MemOperand(x20, 24, PostIndex));
3912 }
3913
3914
3915 // Test loading a single element into an initialised register.
3916 __ Mov(x25, 1);
3917 __ Mov(x4, x21);
3918 __ Ldr(q12, MemOperand(x4, 16, PostIndex));
3919 __ Ldr(q13, MemOperand(x4, 16, PostIndex));
3920 __ Ldr(q14, MemOperand(x4));
3921 __ Ld3(v12.B(), v13.B(), v14.B(), 4, MemOperand(x21, x25, PostIndex));
3922 __ Add(x25, x25, 1);
3923
3924 __ Mov(x5, x22);
3925 __ Ldr(q15, MemOperand(x5, 16, PostIndex));
3926 __ Ldr(q16, MemOperand(x5, 16, PostIndex));
3927 __ Ldr(q17, MemOperand(x5));
3928 __ Ld3(v15.H(), v16.H(), v17.H(), 3, MemOperand(x22, x25, PostIndex));
3929 __ Add(x25, x25, 1);
3930
3931 __ Mov(x6, x23);
3932 __ Ldr(q18, MemOperand(x6, 16, PostIndex));
3933 __ Ldr(q19, MemOperand(x6, 16, PostIndex));
3934 __ Ldr(q20, MemOperand(x6));
3935 __ Ld3(v18.S(), v19.S(), v20.S(), 2, MemOperand(x23, x25, PostIndex));
3936 __ Add(x25, x25, 1);
3937
3938 __ Mov(x7, x24);
3939 __ Ldr(q21, MemOperand(x7, 16, PostIndex));
3940 __ Ldr(q22, MemOperand(x7, 16, PostIndex));
3941 __ Ldr(q23, MemOperand(x7));
3942 __ Ld3(v21.D(), v22.D(), v23.D(), 1, MemOperand(x24, x25, PostIndex));
3943
3944 END();
3945
3946 RUN();
3947
3948 ASSERT_EQUAL_128(0x000306090c0f1215, 0x181b1e2124272a2d, q0);
3949 ASSERT_EQUAL_128(0x0104070a0d101316, 0x191c1f2225282b2e, q1);
3950 ASSERT_EQUAL_128(0x0205080b0e111417, 0x1a1d202326292c2f, q2);
3951 ASSERT_EQUAL_128(0x010007060d0c1312, 0x19181f1e25242b2a, q3);
3952 ASSERT_EQUAL_128(0x030209080f0e1514, 0x1b1a212027262d2c, q4);
3953 ASSERT_EQUAL_128(0x05040b0a11101716, 0x1d1c232229282f2e, q5);
3954 ASSERT_EQUAL_128(0x030201000f0e0d0c, 0x1b1a191827262524, q6);
3955 ASSERT_EQUAL_128(0x0706050413121110, 0x1f1e1d1c2b2a2928, q7);
3956 ASSERT_EQUAL_128(0x0b0a090817161514, 0x232221202f2e2d2c, q8);
3957 ASSERT_EQUAL_128(0x0706050403020100, 0x1f1e1d1c1b1a1918, q9);
3958 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x2726252423222120, q10);
3959 ASSERT_EQUAL_128(0x1716151413121110, 0x2f2e2d2c2b2a2928, q11);
3960 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q12);
3961 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q13);
3962 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q14);
3963 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q15);
3964 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q16);
3965 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q17);
3966 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q18);
3967 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q19);
3968 ASSERT_EQUAL_128(0x2f2e2d2c0b0a0908, 0x2726252423222120, q20);
3969 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q21);
3970 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q22);
3971 ASSERT_EQUAL_128(0x1716151413121110, 0x2726252423222120, q23);
3972
3973 ASSERT_EQUAL_64(src_base + 48, x17);
3974 ASSERT_EQUAL_64(src_base + 48, x18);
3975 ASSERT_EQUAL_64(src_base + 48, x19);
3976 ASSERT_EQUAL_64(src_base + 48, x20);
3977 ASSERT_EQUAL_64(src_base + 1, x21);
3978 ASSERT_EQUAL_64(src_base + 2, x22);
3979 ASSERT_EQUAL_64(src_base + 3, x23);
3980 ASSERT_EQUAL_64(src_base + 4, x24);
3981
3982 TEARDOWN();
3983}
3984
3985
3986TEST(neon_ld3_alllanes) {
3987 SETUP();
3988
3989 uint8_t src[64];
3990 for (unsigned i = 0; i < sizeof(src); i++) {
3991 src[i] = i;
3992 }
3993 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3994
3995 START();
3996 __ Mov(x17, src_base + 1);
3997 __ Mov(x18, 1);
3998 __ Ld3r(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x17));
3999 __ Add(x17, x17, 3);
4000 __ Ld3r(v3.V16B(), v4.V16B(), v5.V16B(), MemOperand(x17));
4001 __ Add(x17, x17, 1);
4002 __ Ld3r(v6.V4H(), v7.V4H(), v8.V4H(), MemOperand(x17));
4003 __ Add(x17, x17, 1);
4004 __ Ld3r(v9.V8H(), v10.V8H(), v11.V8H(), MemOperand(x17));
4005 __ Add(x17, x17, 6);
4006 __ Ld3r(v12.V2S(), v13.V2S(), v14.V2S(), MemOperand(x17));
4007 __ Add(x17, x17, 1);
4008 __ Ld3r(v15.V4S(), v16.V4S(), v17.V4S(), MemOperand(x17));
4009 __ Add(x17, x17, 12);
4010 __ Ld3r(v18.V2D(), v19.V2D(), v20.V2D(), MemOperand(x17));
4011 END();
4012
4013 RUN();
4014
4015 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4016 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4017 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4018 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
4019 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4020 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4021 ASSERT_EQUAL_128(0x0000000000000000, 0x0605060506050605, q6);
4022 ASSERT_EQUAL_128(0x0000000000000000, 0x0807080708070807, q7);
4023 ASSERT_EQUAL_128(0x0000000000000000, 0x0a090a090a090a09, q8);
4024 ASSERT_EQUAL_128(0x0706070607060706, 0x0706070607060706, q9);
4025 ASSERT_EQUAL_128(0x0908090809080908, 0x0908090809080908, q10);
4026 ASSERT_EQUAL_128(0x0b0a0b0a0b0a0b0a, 0x0b0a0b0a0b0a0b0a, q11);
4027 ASSERT_EQUAL_128(0x0000000000000000, 0x0f0e0d0c0f0e0d0c, q12);
4028 ASSERT_EQUAL_128(0x0000000000000000, 0x1312111013121110, q13);
4029 ASSERT_EQUAL_128(0x0000000000000000, 0x1716151417161514, q14);
4030 ASSERT_EQUAL_128(0x100f0e0d100f0e0d, 0x100f0e0d100f0e0d, q15);
4031 ASSERT_EQUAL_128(0x1413121114131211, 0x1413121114131211, q16);
4032 ASSERT_EQUAL_128(0x1817161518171615, 0x1817161518171615, q17);
4033 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x201f1e1d1c1b1a19, q18);
4034 ASSERT_EQUAL_128(0x2827262524232221, 0x2827262524232221, q19);
4035 ASSERT_EQUAL_128(0x302f2e2d2c2b2a29, 0x302f2e2d2c2b2a29, q20);
4036
4037 TEARDOWN();
4038}
4039
4040
4041TEST(neon_ld3_alllanes_postindex) {
4042 SETUP();
4043
4044 uint8_t src[64];
4045 for (unsigned i = 0; i < sizeof(src); i++) {
4046 src[i] = i;
4047 }
4048 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4049 __ Mov(x17, src_base + 1);
4050 __ Mov(x18, 1);
4051
4052 START();
4053 __ Mov(x17, src_base + 1);
4054 __ Mov(x18, 1);
4055 __ Ld3r(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x17, 3, PostIndex));
4056 __ Ld3r(v3.V16B(), v4.V16B(), v5.V16B(), MemOperand(x17, x18, PostIndex));
4057 __ Ld3r(v6.V4H(), v7.V4H(), v8.V4H(), MemOperand(x17, x18, PostIndex));
4058 __ Ld3r(v9.V8H(), v10.V8H(), v11.V8H(), MemOperand(x17, 6, PostIndex));
4059 __ Ld3r(v12.V2S(), v13.V2S(), v14.V2S(), MemOperand(x17, x18, PostIndex));
4060 __ Ld3r(v15.V4S(), v16.V4S(), v17.V4S(), MemOperand(x17, 12, PostIndex));
4061 __ Ld3r(v18.V2D(), v19.V2D(), v20.V2D(), MemOperand(x17, 24, PostIndex));
4062 END();
4063
4064 RUN();
4065
4066 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4067 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4068 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4069 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
4070 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4071 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4072 ASSERT_EQUAL_128(0x0000000000000000, 0x0605060506050605, q6);
4073 ASSERT_EQUAL_128(0x0000000000000000, 0x0807080708070807, q7);
4074 ASSERT_EQUAL_128(0x0000000000000000, 0x0a090a090a090a09, q8);
4075 ASSERT_EQUAL_128(0x0706070607060706, 0x0706070607060706, q9);
4076 ASSERT_EQUAL_128(0x0908090809080908, 0x0908090809080908, q10);
4077 ASSERT_EQUAL_128(0x0b0a0b0a0b0a0b0a, 0x0b0a0b0a0b0a0b0a, q11);
4078 ASSERT_EQUAL_128(0x0000000000000000, 0x0f0e0d0c0f0e0d0c, q12);
4079 ASSERT_EQUAL_128(0x0000000000000000, 0x1312111013121110, q13);
4080 ASSERT_EQUAL_128(0x0000000000000000, 0x1716151417161514, q14);
4081 ASSERT_EQUAL_128(0x100f0e0d100f0e0d, 0x100f0e0d100f0e0d, q15);
4082 ASSERT_EQUAL_128(0x1413121114131211, 0x1413121114131211, q16);
4083 ASSERT_EQUAL_128(0x1817161518171615, 0x1817161518171615, q17);
4084 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x201f1e1d1c1b1a19, q18);
4085 ASSERT_EQUAL_128(0x2827262524232221, 0x2827262524232221, q19);
4086 ASSERT_EQUAL_128(0x302f2e2d2c2b2a29, 0x302f2e2d2c2b2a29, q20);
4087
4088 TEARDOWN();
4089}
4090
4091
4092TEST(neon_ld4_d) {
4093 SETUP();
4094
4095 uint8_t src[64 + 4];
4096 for (unsigned i = 0; i < sizeof(src); i++) {
4097 src[i] = i;
4098 }
4099 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4100
4101 START();
4102 __ Mov(x17, src_base);
4103 __ Ld4(v2.V8B(), v3.V8B(), v4.V8B(), v5.V8B(), MemOperand(x17));
4104 __ Add(x17, x17, 1);
4105 __ Ld4(v6.V8B(), v7.V8B(), v8.V8B(), v9.V8B(), MemOperand(x17));
4106 __ Add(x17, x17, 1);
4107 __ Ld4(v10.V4H(), v11.V4H(), v12.V4H(), v13.V4H(), MemOperand(x17));
4108 __ Add(x17, x17, 1);
4109 __ Ld4(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x17));
4110 END();
4111
4112 RUN();
4113
4114 ASSERT_EQUAL_128(0, 0x1c1814100c080400, q2);
4115 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q3);
4116 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q4);
4117 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q5);
4118 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q6);
4119 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q7);
4120 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q8);
4121 ASSERT_EQUAL_128(0, 0x201c1814100c0804, q9);
4122 ASSERT_EQUAL_128(0, 0x1b1a13120b0a0302, q10);
4123 ASSERT_EQUAL_128(0, 0x1d1c15140d0c0504, q11);
4124 ASSERT_EQUAL_128(0, 0x1f1e17160f0e0706, q12);
4125 ASSERT_EQUAL_128(0, 0x2120191811100908, q13);
4126 ASSERT_EQUAL_128(0, 0x1615141306050403, q30);
4127 ASSERT_EQUAL_128(0, 0x1a1918170a090807, q31);
4128 ASSERT_EQUAL_128(0, 0x1e1d1c1b0e0d0c0b, q0);
4129 ASSERT_EQUAL_128(0, 0x2221201f1211100f, q1);
4130
4131 TEARDOWN();
4132}
4133
4134
4135TEST(neon_ld4_d_postindex) {
4136 SETUP();
4137
4138 uint8_t src[32 + 4];
4139 for (unsigned i = 0; i < sizeof(src); i++) {
4140 src[i] = i;
4141 }
4142 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4143
4144 START();
4145 __ Mov(x17, src_base);
4146 __ Mov(x18, src_base + 1);
4147 __ Mov(x19, src_base + 2);
4148 __ Mov(x20, src_base + 3);
4149 __ Mov(x21, src_base + 4);
4150 __ Mov(x22, 1);
4151 __ Ld4(v2.V8B(), v3.V8B(), v4.V8B(), v5.V8B(),
4152 MemOperand(x17, x22, PostIndex));
4153 __ Ld4(v6.V8B(), v7.V8B(), v8.V8B(), v9.V8B(),
4154 MemOperand(x18, 32, PostIndex));
4155 __ Ld4(v10.V4H(), v11.V4H(), v12.V4H(), v13.V4H(),
4156 MemOperand(x19, 32, PostIndex));
4157 __ Ld4(v14.V2S(), v15.V2S(), v16.V2S(), v17.V2S(),
4158 MemOperand(x20, 32, PostIndex));
4159 __ Ld4(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(),
4160 MemOperand(x21, 32, PostIndex));
4161 END();
4162
4163 RUN();
4164
4165 ASSERT_EQUAL_128(0, 0x1c1814100c080400, q2);
4166 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q3);
4167 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q4);
4168 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q5);
4169 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q6);
4170 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q7);
4171 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q8);
4172 ASSERT_EQUAL_128(0, 0x201c1814100c0804, q9);
4173 ASSERT_EQUAL_128(0, 0x1b1a13120b0a0302, q10);
4174 ASSERT_EQUAL_128(0, 0x1d1c15140d0c0504, q11);
4175 ASSERT_EQUAL_128(0, 0x1f1e17160f0e0706, q12);
4176 ASSERT_EQUAL_128(0, 0x2120191811100908, q13);
4177 ASSERT_EQUAL_128(0, 0x1615141306050403, q14);
4178 ASSERT_EQUAL_128(0, 0x1a1918170a090807, q15);
4179 ASSERT_EQUAL_128(0, 0x1e1d1c1b0e0d0c0b, q16);
4180 ASSERT_EQUAL_128(0, 0x2221201f1211100f, q17);
4181 ASSERT_EQUAL_128(0, 0x1716151407060504, q30);
4182 ASSERT_EQUAL_128(0, 0x1b1a19180b0a0908, q31);
4183 ASSERT_EQUAL_128(0, 0x1f1e1d1c0f0e0d0c, q0);
4184 ASSERT_EQUAL_128(0, 0x2322212013121110, q1);
4185
4186
4187 ASSERT_EQUAL_64(src_base + 1, x17);
4188 ASSERT_EQUAL_64(src_base + 1 + 32, x18);
4189 ASSERT_EQUAL_64(src_base + 2 + 32, x19);
4190 ASSERT_EQUAL_64(src_base + 3 + 32, x20);
4191 ASSERT_EQUAL_64(src_base + 4 + 32, x21);
4192 TEARDOWN();
4193}
4194
4195
4196TEST(neon_ld4_q) {
4197 SETUP();
4198
4199 uint8_t src[64 + 4];
4200 for (unsigned i = 0; i < sizeof(src); i++) {
4201 src[i] = i;
4202 }
4203 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4204
4205 START();
4206 __ Mov(x17, src_base);
4207 __ Ld4(v2.V16B(), v3.V16B(), v4.V16B(), v5.V16B(), MemOperand(x17));
4208 __ Add(x17, x17, 1);
4209 __ Ld4(v6.V16B(), v7.V16B(), v8.V16B(), v9.V16B(), MemOperand(x17));
4210 __ Add(x17, x17, 1);
4211 __ Ld4(v10.V8H(), v11.V8H(), v12.V8H(), v13.V8H(), MemOperand(x17));
4212 __ Add(x17, x17, 1);
4213 __ Ld4(v14.V4S(), v15.V4S(), v16.V4S(), v17.V4S(), MemOperand(x17));
4214 __ Add(x17, x17, 1);
4215 __ Ld4(v18.V2D(), v19.V2D(), v20.V2D(), v21.V2D(), MemOperand(x17));
4216 END();
4217
4218 RUN();
4219
4220 ASSERT_EQUAL_128(0x3c3834302c282420, 0x1c1814100c080400, q2);
4221 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q3);
4222 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q4);
4223 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q5);
4224 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q6);
4225 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q7);
4226 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q8);
4227 ASSERT_EQUAL_128(0x403c3834302c2824, 0x201c1814100c0804, q9);
4228 ASSERT_EQUAL_128(0x3b3a33322b2a2322, 0x1b1a13120b0a0302, q10);
4229 ASSERT_EQUAL_128(0x3d3c35342d2c2524, 0x1d1c15140d0c0504, q11);
4230 ASSERT_EQUAL_128(0x3f3e37362f2e2726, 0x1f1e17160f0e0706, q12);
4231 ASSERT_EQUAL_128(0x4140393831302928, 0x2120191811100908, q13);
4232 ASSERT_EQUAL_128(0x3635343326252423, 0x1615141306050403, q14);
4233 ASSERT_EQUAL_128(0x3a3938372a292827, 0x1a1918170a090807, q15);
4234 ASSERT_EQUAL_128(0x3e3d3c3b2e2d2c2b, 0x1e1d1c1b0e0d0c0b, q16);
4235 ASSERT_EQUAL_128(0x4241403f3231302f, 0x2221201f1211100f, q17);
4236 ASSERT_EQUAL_128(0x2b2a292827262524, 0x0b0a090807060504, q18);
4237 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x131211100f0e0d0c, q19);
4238 ASSERT_EQUAL_128(0x3b3a393837363534, 0x1b1a191817161514, q20);
4239 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x232221201f1e1d1c, q21);
4240 TEARDOWN();
4241}
4242
4243
4244TEST(neon_ld4_q_postindex) {
4245 SETUP();
4246
4247 uint8_t src[64 + 4];
4248 for (unsigned i = 0; i < sizeof(src); i++) {
4249 src[i] = i;
4250 }
4251 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4252
4253 START();
4254 __ Mov(x17, src_base);
4255 __ Mov(x18, src_base + 1);
4256 __ Mov(x19, src_base + 2);
4257 __ Mov(x20, src_base + 3);
4258 __ Mov(x21, src_base + 4);
4259 __ Mov(x22, 1);
4260
4261 __ Ld4(v2.V16B(), v3.V16B(), v4.V16B(), v5.V16B(),
4262 MemOperand(x17, x22, PostIndex));
4263 __ Ld4(v6.V16B(), v7.V16B(), v8.V16B(), v9.V16B(),
4264 MemOperand(x18, 64, PostIndex));
4265 __ Ld4(v10.V8H(), v11.V8H(), v12.V8H(), v13.V8H(),
4266 MemOperand(x19, 64, PostIndex));
4267 __ Ld4(v14.V4S(), v15.V4S(), v16.V4S(), v17.V4S(),
4268 MemOperand(x20, 64, PostIndex));
4269 __ Ld4(v30.V2D(), v31.V2D(), v0.V2D(), v1.V2D(),
4270 MemOperand(x21, 64, PostIndex));
4271 END();
4272
4273 RUN();
4274
4275 ASSERT_EQUAL_128(0x3c3834302c282420, 0x1c1814100c080400, q2);
4276 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q3);
4277 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q4);
4278 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q5);
4279 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q6);
4280 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q7);
4281 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q8);
4282 ASSERT_EQUAL_128(0x403c3834302c2824, 0x201c1814100c0804, q9);
4283 ASSERT_EQUAL_128(0x3b3a33322b2a2322, 0x1b1a13120b0a0302, q10);
4284 ASSERT_EQUAL_128(0x3d3c35342d2c2524, 0x1d1c15140d0c0504, q11);
4285 ASSERT_EQUAL_128(0x3f3e37362f2e2726, 0x1f1e17160f0e0706, q12);
4286 ASSERT_EQUAL_128(0x4140393831302928, 0x2120191811100908, q13);
4287 ASSERT_EQUAL_128(0x3635343326252423, 0x1615141306050403, q14);
4288 ASSERT_EQUAL_128(0x3a3938372a292827, 0x1a1918170a090807, q15);
4289 ASSERT_EQUAL_128(0x3e3d3c3b2e2d2c2b, 0x1e1d1c1b0e0d0c0b, q16);
4290 ASSERT_EQUAL_128(0x4241403f3231302f, 0x2221201f1211100f, q17);
4291 ASSERT_EQUAL_128(0x2b2a292827262524, 0x0b0a090807060504, q30);
4292 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x131211100f0e0d0c, q31);
4293 ASSERT_EQUAL_128(0x3b3a393837363534, 0x1b1a191817161514, q0);
4294 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x232221201f1e1d1c, q1);
4295
4296
4297
4298 ASSERT_EQUAL_64(src_base + 1, x17);
4299 ASSERT_EQUAL_64(src_base + 1 + 64, x18);
4300 ASSERT_EQUAL_64(src_base + 2 + 64, x19);
4301 ASSERT_EQUAL_64(src_base + 3 + 64, x20);
4302 ASSERT_EQUAL_64(src_base + 4 + 64, x21);
4303
4304 TEARDOWN();
4305}
4306
4307
4308TEST(neon_ld4_lane) {
4309 SETUP();
4310
4311 uint8_t src[64];
4312 for (unsigned i = 0; i < sizeof(src); i++) {
4313 src[i] = i;
4314 }
4315 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4316
4317 START();
4318
4319 // Test loading whole register by element.
4320 __ Mov(x17, src_base);
4321 for (int i = 15; i >= 0; i--) {
4322 __ Ld4(v0.B(), v1.B(), v2.B(), v3.B(), i, MemOperand(x17));
4323 __ Add(x17, x17, 1);
4324 }
4325
4326 __ Mov(x17, src_base);
4327 for (int i = 7; i >= 0; i--) {
4328 __ Ld4(v4.H(), v5.H(), v6.H(), v7.H(), i, MemOperand(x17));
4329 __ Add(x17, x17, 1);
4330 }
4331
4332 __ Mov(x17, src_base);
4333 for (int i = 3; i >= 0; i--) {
4334 __ Ld4(v8.S(), v9.S(), v10.S(), v11.S(), i, MemOperand(x17));
4335 __ Add(x17, x17, 1);
4336 }
4337
4338 __ Mov(x17, src_base);
4339 for (int i = 1; i >= 0; i--) {
4340 __ Ld4(v12.D(), v13.D(), v14.D(), v15.D(), i, MemOperand(x17));
4341 __ Add(x17, x17, 1);
4342 }
4343
4344 // Test loading a single element into an initialised register.
4345 __ Mov(x17, src_base);
4346 __ Mov(x4, x17);
4347 __ Ldr(q16, MemOperand(x4, 16, PostIndex));
4348 __ Ldr(q17, MemOperand(x4, 16, PostIndex));
4349 __ Ldr(q18, MemOperand(x4, 16, PostIndex));
4350 __ Ldr(q19, MemOperand(x4));
4351 __ Ld4(v16.B(), v17.B(), v18.B(), v19.B(), 4, MemOperand(x17));
4352
4353 __ Mov(x5, x17);
4354 __ Ldr(q20, MemOperand(x5, 16, PostIndex));
4355 __ Ldr(q21, MemOperand(x5, 16, PostIndex));
4356 __ Ldr(q22, MemOperand(x5, 16, PostIndex));
4357 __ Ldr(q23, MemOperand(x5));
4358 __ Ld4(v20.H(), v21.H(), v22.H(), v23.H(), 3, MemOperand(x17));
4359
4360 __ Mov(x6, x17);
4361 __ Ldr(q24, MemOperand(x6, 16, PostIndex));
4362 __ Ldr(q25, MemOperand(x6, 16, PostIndex));
4363 __ Ldr(q26, MemOperand(x6, 16, PostIndex));
4364 __ Ldr(q27, MemOperand(x6));
4365 __ Ld4(v24.S(), v25.S(), v26.S(), v27.S(), 2, MemOperand(x17));
4366
4367 __ Mov(x7, x17);
4368 __ Ldr(q28, MemOperand(x7, 16, PostIndex));
4369 __ Ldr(q29, MemOperand(x7, 16, PostIndex));
4370 __ Ldr(q30, MemOperand(x7, 16, PostIndex));
4371 __ Ldr(q31, MemOperand(x7));
4372 __ Ld4(v28.D(), v29.D(), v30.D(), v31.D(), 1, MemOperand(x17));
4373
4374 END();
4375
4376 RUN();
4377
4378 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
4379 ASSERT_EQUAL_128(0x0102030405060708, 0x090a0b0c0d0e0f10, q1);
4380 ASSERT_EQUAL_128(0x0203040506070809, 0x0a0b0c0d0e0f1011, q2);
4381 ASSERT_EQUAL_128(0x030405060708090a, 0x0b0c0d0e0f101112, q3);
4382 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q4);
4383 ASSERT_EQUAL_128(0x0302040305040605, 0x0706080709080a09, q5);
4384 ASSERT_EQUAL_128(0x0504060507060807, 0x09080a090b0a0c0b, q6);
4385 ASSERT_EQUAL_128(0x0706080709080a09, 0x0b0a0c0b0d0c0e0d, q7);
4386 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q8);
4387 ASSERT_EQUAL_128(0x0706050408070605, 0x090807060a090807, q9);
4388 ASSERT_EQUAL_128(0x0b0a09080c0b0a09, 0x0d0c0b0a0e0d0c0b, q10);
4389 ASSERT_EQUAL_128(0x0f0e0d0c100f0e0d, 0x11100f0e1211100f, q11);
4390 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q12);
4391 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x100f0e0d0c0b0a09, q13);
4392 ASSERT_EQUAL_128(0x1716151413121110, 0x1817161514131211, q14);
4393 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x201f1e1d1c1b1a19, q15);
4394 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q16);
4395 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q17);
4396 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q18);
4397 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736350333323130, q19);
4398 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q20);
4399 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q21);
4400 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q22);
4401 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x0706353433323130, q23);
4402 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q24);
4403 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q25);
4404 ASSERT_EQUAL_128(0x2f2e2d2c0b0a0908, 0x2726252423222120, q26);
4405 ASSERT_EQUAL_128(0x3f3e3d3c0f0e0d0c, 0x3736353433323130, q27);
4406 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q28);
4407 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q29);
4408 ASSERT_EQUAL_128(0x1716151413121110, 0x2726252423222120, q30);
4409 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x3736353433323130, q31);
4410
4411 TEARDOWN();
4412}
4413
4414
4415
4416TEST(neon_ld4_lane_postindex) {
4417 SETUP();
4418
4419 uint8_t src[64];
4420 for (unsigned i = 0; i < sizeof(src); i++) {
4421 src[i] = i;
4422 }
4423 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4424
4425 START();
4426
4427 // Test loading whole register by element.
4428 __ Mov(x17, src_base);
4429 for (int i = 15; i >= 0; i--) {
4430 __ Ld4(v0.B(), v1.B(), v2.B(), v3.B(), i,
4431 MemOperand(x17, 4, PostIndex));
4432 }
4433
4434 __ Mov(x18, src_base);
4435 for (int i = 7; i >= 0; i--) {
4436 __ Ld4(v4.H(), v5.H(), v6.H(), v7.H(), i,
4437 MemOperand(x18, 8, PostIndex));
4438 }
4439
4440 __ Mov(x19, src_base);
4441 for (int i = 3; i >= 0; i--) {
4442 __ Ld4(v8.S(), v9.S(), v10.S(), v11.S(), i,
4443 MemOperand(x19, 16, PostIndex));
4444 }
4445
4446 __ Mov(x20, src_base);
4447 for (int i = 1; i >= 0; i--) {
4448 __ Ld4(v12.D(), v13.D(), v14.D(), v15.D(), i,
4449 MemOperand(x20, 32, PostIndex));
4450 }
4451
4452 // Test loading a single element into an initialised register.
4453 __ Mov(x25, 1);
4454 __ Mov(x21, src_base);
4455 __ Mov(x22, src_base);
4456 __ Mov(x23, src_base);
4457 __ Mov(x24, src_base);
4458
4459 __ Mov(x4, x21);
4460 __ Ldr(q16, MemOperand(x4, 16, PostIndex));
4461 __ Ldr(q17, MemOperand(x4, 16, PostIndex));
4462 __ Ldr(q18, MemOperand(x4, 16, PostIndex));
4463 __ Ldr(q19, MemOperand(x4));
4464 __ Ld4(v16.B(), v17.B(), v18.B(), v19.B(), 4,
4465 MemOperand(x21, x25, PostIndex));
4466 __ Add(x25, x25, 1);
4467
4468 __ Mov(x5, x22);
4469 __ Ldr(q20, MemOperand(x5, 16, PostIndex));
4470 __ Ldr(q21, MemOperand(x5, 16, PostIndex));
4471 __ Ldr(q22, MemOperand(x5, 16, PostIndex));
4472 __ Ldr(q23, MemOperand(x5));
4473 __ Ld4(v20.H(), v21.H(), v22.H(), v23.H(), 3,
4474 MemOperand(x22, x25, PostIndex));
4475 __ Add(x25, x25, 1);
4476
4477 __ Mov(x6, x23);
4478 __ Ldr(q24, MemOperand(x6, 16, PostIndex));
4479 __ Ldr(q25, MemOperand(x6, 16, PostIndex));
4480 __ Ldr(q26, MemOperand(x6, 16, PostIndex));
4481 __ Ldr(q27, MemOperand(x6));
4482 __ Ld4(v24.S(), v25.S(), v26.S(), v27.S(), 2,
4483 MemOperand(x23, x25, PostIndex));
4484 __ Add(x25, x25, 1);
4485
4486 __ Mov(x7, x24);
4487 __ Ldr(q28, MemOperand(x7, 16, PostIndex));
4488 __ Ldr(q29, MemOperand(x7, 16, PostIndex));
4489 __ Ldr(q30, MemOperand(x7, 16, PostIndex));
4490 __ Ldr(q31, MemOperand(x7));
4491 __ Ld4(v28.D(), v29.D(), v30.D(), v31.D(), 1,
4492 MemOperand(x24, x25, PostIndex));
4493
4494 END();
4495
4496 RUN();
4497
4498 ASSERT_EQUAL_128(0x0004080c1014181c, 0x2024282c3034383c, q0);
4499 ASSERT_EQUAL_128(0x0105090d1115191d, 0x2125292d3135393d, q1);
4500 ASSERT_EQUAL_128(0x02060a0e12161a1e, 0x22262a2e32363a3e, q2);
4501 ASSERT_EQUAL_128(0x03070b0f13171b1f, 0x23272b2f33373b3f, q3);
4502 ASSERT_EQUAL_128(0x0100090811101918, 0x2120292831303938, q4);
4503 ASSERT_EQUAL_128(0x03020b0a13121b1a, 0x23222b2a33323b3a, q5);
4504 ASSERT_EQUAL_128(0x05040d0c15141d1c, 0x25242d2c35343d3c, q6);
4505 ASSERT_EQUAL_128(0x07060f0e17161f1e, 0x27262f2e37363f3e, q7);
4506 ASSERT_EQUAL_128(0x0302010013121110, 0x2322212033323130, q8);
4507 ASSERT_EQUAL_128(0x0706050417161514, 0x2726252437363534, q9);
4508 ASSERT_EQUAL_128(0x0b0a09081b1a1918, 0x2b2a29283b3a3938, q10);
4509 ASSERT_EQUAL_128(0x0f0e0d0c1f1e1d1c, 0x2f2e2d2c3f3e3d3c, q11);
4510 ASSERT_EQUAL_128(0x0706050403020100, 0x2726252423222120, q12);
4511 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x2f2e2d2c2b2a2928, q13);
4512 ASSERT_EQUAL_128(0x1716151413121110, 0x3736353433323130, q14);
4513 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x3f3e3d3c3b3a3938, q15);
4514 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q16);
4515 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q17);
4516 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q18);
4517 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736350333323130, q19);
4518 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q20);
4519 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q21);
4520 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q22);
4521 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x0706353433323130, q23);
4522 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q24);
4523 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q25);
4524 ASSERT_EQUAL_128(0x2f2e2d2c0b0a0908, 0x2726252423222120, q26);
4525 ASSERT_EQUAL_128(0x3f3e3d3c0f0e0d0c, 0x3736353433323130, q27);
4526 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q28);
4527 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q29);
4528 ASSERT_EQUAL_128(0x1716151413121110, 0x2726252423222120, q30);
4529 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x3736353433323130, q31);
4530
4531 ASSERT_EQUAL_64(src_base + 64, x17);
4532 ASSERT_EQUAL_64(src_base + 64, x18);
4533 ASSERT_EQUAL_64(src_base + 64, x19);
4534 ASSERT_EQUAL_64(src_base + 64, x20);
4535 ASSERT_EQUAL_64(src_base + 1, x21);
4536 ASSERT_EQUAL_64(src_base + 2, x22);
4537 ASSERT_EQUAL_64(src_base + 3, x23);
4538 ASSERT_EQUAL_64(src_base + 4, x24);
4539
4540 TEARDOWN();
4541}
4542
4543
4544TEST(neon_ld4_alllanes) {
4545 SETUP();
4546
4547 uint8_t src[64];
4548 for (unsigned i = 0; i < sizeof(src); i++) {
4549 src[i] = i;
4550 }
4551 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4552
4553 START();
4554 __ Mov(x17, src_base + 1);
4555 __ Mov(x18, 1);
4556 __ Ld4r(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(), MemOperand(x17));
4557 __ Add(x17, x17, 4);
4558 __ Ld4r(v4.V16B(), v5.V16B(), v6.V16B(), v7.V16B(), MemOperand(x17));
4559 __ Add(x17, x17, 1);
4560 __ Ld4r(v8.V4H(), v9.V4H(), v10.V4H(), v11.V4H(), MemOperand(x17));
4561 __ Add(x17, x17, 1);
4562 __ Ld4r(v12.V8H(), v13.V8H(), v14.V8H(), v15.V8H(), MemOperand(x17));
4563 __ Add(x17, x17, 8);
4564 __ Ld4r(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(), MemOperand(x17));
4565 __ Add(x17, x17, 1);
4566 __ Ld4r(v20.V4S(), v21.V4S(), v22.V4S(), v23.V4S(), MemOperand(x17));
4567 __ Add(x17, x17, 16);
4568 __ Ld4r(v24.V2D(), v25.V2D(), v26.V2D(), v27.V2D(), MemOperand(x17));
4569
4570
4571 END();
4572
4573 RUN();
4574
4575 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4576 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4577 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4578 ASSERT_EQUAL_128(0x0000000000000000, 0x0404040404040404, q3);
4579 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4580 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4581 ASSERT_EQUAL_128(0x0707070707070707, 0x0707070707070707, q6);
4582 ASSERT_EQUAL_128(0x0808080808080808, 0x0808080808080808, q7);
4583 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q8);
4584 ASSERT_EQUAL_128(0x0000000000000000, 0x0908090809080908, q9);
4585 ASSERT_EQUAL_128(0x0000000000000000, 0x0b0a0b0a0b0a0b0a, q10);
4586 ASSERT_EQUAL_128(0x0000000000000000, 0x0d0c0d0c0d0c0d0c, q11);
4587 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q12);
4588 ASSERT_EQUAL_128(0x0a090a090a090a09, 0x0a090a090a090a09, q13);
4589 ASSERT_EQUAL_128(0x0c0b0c0b0c0b0c0b, 0x0c0b0c0b0c0b0c0b, q14);
4590 ASSERT_EQUAL_128(0x0e0d0e0d0e0d0e0d, 0x0e0d0e0d0e0d0e0d, q15);
4591 ASSERT_EQUAL_128(0x0000000000000000, 0x1211100f1211100f, q16);
4592 ASSERT_EQUAL_128(0x0000000000000000, 0x1615141316151413, q17);
4593 ASSERT_EQUAL_128(0x0000000000000000, 0x1a1918171a191817, q18);
4594 ASSERT_EQUAL_128(0x0000000000000000, 0x1e1d1c1b1e1d1c1b, q19);
4595 ASSERT_EQUAL_128(0x1312111013121110, 0x1312111013121110, q20);
4596 ASSERT_EQUAL_128(0x1716151417161514, 0x1716151417161514, q21);
4597 ASSERT_EQUAL_128(0x1b1a19181b1a1918, 0x1b1a19181b1a1918, q22);
4598 ASSERT_EQUAL_128(0x1f1e1d1c1f1e1d1c, 0x1f1e1d1c1f1e1d1c, q23);
4599 ASSERT_EQUAL_128(0x2726252423222120, 0x2726252423222120, q24);
4600 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2f2e2d2c2b2a2928, q25);
4601 ASSERT_EQUAL_128(0x3736353433323130, 0x3736353433323130, q26);
4602 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3f3e3d3c3b3a3938, q27);
4603
4604 TEARDOWN();
4605}
4606
4607
4608TEST(neon_ld4_alllanes_postindex) {
4609 SETUP();
4610
4611 uint8_t src[64];
4612 for (unsigned i = 0; i < sizeof(src); i++) {
4613 src[i] = i;
4614 }
4615 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4616 __ Mov(x17, src_base + 1);
4617 __ Mov(x18, 1);
4618
4619 START();
4620 __ Mov(x17, src_base + 1);
4621 __ Mov(x18, 1);
4622 __ Ld4r(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(),
4623 MemOperand(x17, 4, PostIndex));
4624 __ Ld4r(v4.V16B(), v5.V16B(), v6.V16B(), v7.V16B(),
4625 MemOperand(x17, x18, PostIndex));
4626 __ Ld4r(v8.V4H(), v9.V4H(), v10.V4H(), v11.V4H(),
4627 MemOperand(x17, x18, PostIndex));
4628 __ Ld4r(v12.V8H(), v13.V8H(), v14.V8H(), v15.V8H(),
4629 MemOperand(x17, 8, PostIndex));
4630 __ Ld4r(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(),
4631 MemOperand(x17, x18, PostIndex));
4632 __ Ld4r(v20.V4S(), v21.V4S(), v22.V4S(), v23.V4S(),
4633 MemOperand(x17, 16, PostIndex));
4634 __ Ld4r(v24.V2D(), v25.V2D(), v26.V2D(), v27.V2D(),
4635 MemOperand(x17, 32, PostIndex));
4636 END();
4637
4638 RUN();
4639
4640 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4641 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4642 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4643 ASSERT_EQUAL_128(0x0000000000000000, 0x0404040404040404, q3);
4644 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4645 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4646 ASSERT_EQUAL_128(0x0707070707070707, 0x0707070707070707, q6);
4647 ASSERT_EQUAL_128(0x0808080808080808, 0x0808080808080808, q7);
4648 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q8);
4649 ASSERT_EQUAL_128(0x0000000000000000, 0x0908090809080908, q9);
4650 ASSERT_EQUAL_128(0x0000000000000000, 0x0b0a0b0a0b0a0b0a, q10);
4651 ASSERT_EQUAL_128(0x0000000000000000, 0x0d0c0d0c0d0c0d0c, q11);
4652 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q12);
4653 ASSERT_EQUAL_128(0x0a090a090a090a09, 0x0a090a090a090a09, q13);
4654 ASSERT_EQUAL_128(0x0c0b0c0b0c0b0c0b, 0x0c0b0c0b0c0b0c0b, q14);
4655 ASSERT_EQUAL_128(0x0e0d0e0d0e0d0e0d, 0x0e0d0e0d0e0d0e0d, q15);
4656 ASSERT_EQUAL_128(0x0000000000000000, 0x1211100f1211100f, q16);
4657 ASSERT_EQUAL_128(0x0000000000000000, 0x1615141316151413, q17);
4658 ASSERT_EQUAL_128(0x0000000000000000, 0x1a1918171a191817, q18);
4659 ASSERT_EQUAL_128(0x0000000000000000, 0x1e1d1c1b1e1d1c1b, q19);
4660 ASSERT_EQUAL_128(0x1312111013121110, 0x1312111013121110, q20);
4661 ASSERT_EQUAL_128(0x1716151417161514, 0x1716151417161514, q21);
4662 ASSERT_EQUAL_128(0x1b1a19181b1a1918, 0x1b1a19181b1a1918, q22);
4663 ASSERT_EQUAL_128(0x1f1e1d1c1f1e1d1c, 0x1f1e1d1c1f1e1d1c, q23);
4664 ASSERT_EQUAL_128(0x2726252423222120, 0x2726252423222120, q24);
4665 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2f2e2d2c2b2a2928, q25);
4666 ASSERT_EQUAL_128(0x3736353433323130, 0x3736353433323130, q26);
4667 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3f3e3d3c3b3a3938, q27);
4668 ASSERT_EQUAL_64(src_base + 64, x17);
4669
4670 TEARDOWN();
4671}
4672
4673
4674TEST(neon_st1_lane) {
4675 SETUP();
4676
4677 uint8_t src[64];
4678 for (unsigned i = 0; i < sizeof(src); i++) {
4679 src[i] = i;
4680 }
4681 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4682
4683 START();
4684 __ Mov(x17, src_base);
4685 __ Mov(x18, -16);
4686 __ Ldr(q0, MemOperand(x17));
4687
4688 for (int i = 15; i >= 0; i--) {
4689 __ St1(v0.B(), i, MemOperand(x17));
4690 __ Add(x17, x17, 1);
4691 }
4692 __ Ldr(q1, MemOperand(x17, x18));
4693
4694 for (int i = 7; i >= 0; i--) {
4695 __ St1(v0.H(), i, MemOperand(x17));
4696 __ Add(x17, x17, 2);
4697 }
4698 __ Ldr(q2, MemOperand(x17, x18));
4699
4700 for (int i = 3; i >= 0; i--) {
4701 __ St1(v0.S(), i, MemOperand(x17));
4702 __ Add(x17, x17, 4);
4703 }
4704 __ Ldr(q3, MemOperand(x17, x18));
4705
4706 for (int i = 1; i >= 0; i--) {
4707 __ St1(v0.D(), i, MemOperand(x17));
4708 __ Add(x17, x17, 8);
4709 }
4710 __ Ldr(q4, MemOperand(x17, x18));
4711
4712 END();
4713
4714 RUN();
4715
4716 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q1);
4717 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q2);
4718 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q3);
4719 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q4);
4720
4721 TEARDOWN();
4722}
4723
4724
4725TEST(neon_st2_lane) {
4726 SETUP();
4727
4728 // Struct size * addressing modes * element sizes * vector size.
4729 uint8_t dst[2 * 2 * 4 * 16];
4730 memset(dst, 0, sizeof(dst));
4731 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4732
4733 START();
4734 __ Mov(x17, dst_base);
4735 __ Mov(x18, dst_base);
4736 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
4737 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
4738
4739 // Test B stores with and without post index.
4740 for (int i = 15; i >= 0; i--) {
4741 __ St2(v0.B(), v1.B(), i, MemOperand(x18));
4742 __ Add(x18, x18, 2);
4743 }
4744 for (int i = 15; i >= 0; i--) {
4745 __ St2(v0.B(), v1.B(), i, MemOperand(x18, 2, PostIndex));
4746 }
4747 __ Ldr(q2, MemOperand(x17, 0 * 16));
4748 __ Ldr(q3, MemOperand(x17, 1 * 16));
4749 __ Ldr(q4, MemOperand(x17, 2 * 16));
4750 __ Ldr(q5, MemOperand(x17, 3 * 16));
4751
4752 // Test H stores with and without post index.
4753 __ Mov(x0, 4);
4754 for (int i = 7; i >= 0; i--) {
4755 __ St2(v0.H(), v1.H(), i, MemOperand(x18));
4756 __ Add(x18, x18, 4);
4757 }
4758 for (int i = 7; i >= 0; i--) {
4759 __ St2(v0.H(), v1.H(), i, MemOperand(x18, x0, PostIndex));
4760 }
4761 __ Ldr(q6, MemOperand(x17, 4 * 16));
4762 __ Ldr(q7, MemOperand(x17, 5 * 16));
4763 __ Ldr(q16, MemOperand(x17, 6 * 16));
4764 __ Ldr(q17, MemOperand(x17, 7 * 16));
4765
4766 // Test S stores with and without post index.
4767 for (int i = 3; i >= 0; i--) {
4768 __ St2(v0.S(), v1.S(), i, MemOperand(x18));
4769 __ Add(x18, x18, 8);
4770 }
4771 for (int i = 3; i >= 0; i--) {
4772 __ St2(v0.S(), v1.S(), i, MemOperand(x18, 8, PostIndex));
4773 }
4774 __ Ldr(q18, MemOperand(x17, 8 * 16));
4775 __ Ldr(q19, MemOperand(x17, 9 * 16));
4776 __ Ldr(q20, MemOperand(x17, 10 * 16));
4777 __ Ldr(q21, MemOperand(x17, 11 * 16));
4778
4779 // Test D stores with and without post index.
4780 __ Mov(x0, 16);
4781 __ St2(v0.D(), v1.D(), 1, MemOperand(x18));
4782 __ Add(x18, x18, 16);
4783 __ St2(v0.D(), v1.D(), 0, MemOperand(x18, 16, PostIndex));
4784 __ St2(v0.D(), v1.D(), 1, MemOperand(x18, x0, PostIndex));
4785 __ St2(v0.D(), v1.D(), 0, MemOperand(x18, x0, PostIndex));
4786 __ Ldr(q22, MemOperand(x17, 12 * 16));
4787 __ Ldr(q23, MemOperand(x17, 13 * 16));
4788 __ Ldr(q24, MemOperand(x17, 14 * 16));
4789 __ Ldr(q25, MemOperand(x17, 15 * 16));
4790 END();
4791
4792 RUN();
4793
4794 ASSERT_EQUAL_128(0x1707160615051404, 0x1303120211011000, q2);
4795 ASSERT_EQUAL_128(0x1f0f1e0e1d0d1c0c, 0x1b0b1a0a19091808, q3);
4796 ASSERT_EQUAL_128(0x1707160615051404, 0x1303120211011000, q4);
4797 ASSERT_EQUAL_128(0x1f0f1e0e1d0d1c0c, 0x1b0b1a0a19091808, q5);
4798
4799 ASSERT_EQUAL_128(0x1617060714150405, 0x1213020310110001, q6);
4800 ASSERT_EQUAL_128(0x1e1f0e0f1c1d0c0d, 0x1a1b0a0b18190809, q7);
4801 ASSERT_EQUAL_128(0x1617060714150405, 0x1213020310110001, q16);
4802 ASSERT_EQUAL_128(0x1e1f0e0f1c1d0c0d, 0x1a1b0a0b18190809, q17);
4803
4804 ASSERT_EQUAL_128(0x1415161704050607, 0x1011121300010203, q18);
4805 ASSERT_EQUAL_128(0x1c1d1e1f0c0d0e0f, 0x18191a1b08090a0b, q19);
4806 ASSERT_EQUAL_128(0x1415161704050607, 0x1011121300010203, q20);
4807 ASSERT_EQUAL_128(0x1c1d1e1f0c0d0e0f, 0x18191a1b08090a0b, q21);
4808
4809 ASSERT_EQUAL_128(0x1011121314151617, 0x0001020304050607, q22);
4810 ASSERT_EQUAL_128(0x18191a1b1c1d1e1f, 0x08090a0b0c0d0e0f, q23);
4811 ASSERT_EQUAL_128(0x1011121314151617, 0x0001020304050607, q22);
4812 ASSERT_EQUAL_128(0x18191a1b1c1d1e1f, 0x08090a0b0c0d0e0f, q23);
4813
4814 TEARDOWN();
4815}
4816
4817
4818TEST(neon_st3_lane) {
4819 SETUP();
4820
4821 // Struct size * addressing modes * element sizes * vector size.
4822 uint8_t dst[3 * 2 * 4 * 16];
4823 memset(dst, 0, sizeof(dst));
4824 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4825
4826 START();
4827 __ Mov(x17, dst_base);
4828 __ Mov(x18, dst_base);
4829 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
4830 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
4831 __ Movi(v2.V2D(), 0x2021222324252627, 0x28292a2b2c2d2e2f);
4832
4833 // Test B stores with and without post index.
4834 for (int i = 15; i >= 0; i--) {
4835 __ St3(v0.B(), v1.B(), v2.B(), i, MemOperand(x18));
4836 __ Add(x18, x18, 3);
4837 }
4838 for (int i = 15; i >= 0; i--) {
4839 __ St3(v0.B(), v1.B(), v2.B(), i, MemOperand(x18, 3, PostIndex));
4840 }
4841 __ Ldr(q3, MemOperand(x17, 0 * 16));
4842 __ Ldr(q4, MemOperand(x17, 1 * 16));
4843 __ Ldr(q5, MemOperand(x17, 2 * 16));
4844 __ Ldr(q6, MemOperand(x17, 3 * 16));
4845 __ Ldr(q7, MemOperand(x17, 4 * 16));
4846 __ Ldr(q16, MemOperand(x17, 5 * 16));
4847
4848 // Test H stores with and without post index.
4849 __ Mov(x0, 6);
4850 for (int i = 7; i >= 0; i--) {
4851 __ St3(v0.H(), v1.H(), v2.H(), i, MemOperand(x18));
4852 __ Add(x18, x18, 6);
4853 }
4854 for (int i = 7; i >= 0; i--) {
4855 __ St3(v0.H(), v1.H(), v2.H(), i, MemOperand(x18, x0, PostIndex));
4856 }
4857 __ Ldr(q17, MemOperand(x17, 6 * 16));
4858 __ Ldr(q18, MemOperand(x17, 7 * 16));
4859 __ Ldr(q19, MemOperand(x17, 8 * 16));
4860 __ Ldr(q20, MemOperand(x17, 9 * 16));
4861 __ Ldr(q21, MemOperand(x17, 10 * 16));
4862 __ Ldr(q22, MemOperand(x17, 11 * 16));
4863
4864 // Test S stores with and without post index.
4865 for (int i = 3; i >= 0; i--) {
4866 __ St3(v0.S(), v1.S(), v2.S(), i, MemOperand(x18));
4867 __ Add(x18, x18, 12);
4868 }
4869 for (int i = 3; i >= 0; i--) {
4870 __ St3(v0.S(), v1.S(), v2.S(), i, MemOperand(x18, 12, PostIndex));
4871 }
4872 __ Ldr(q23, MemOperand(x17, 12 * 16));
4873 __ Ldr(q24, MemOperand(x17, 13 * 16));
4874 __ Ldr(q25, MemOperand(x17, 14 * 16));
4875 __ Ldr(q26, MemOperand(x17, 15 * 16));
4876 __ Ldr(q27, MemOperand(x17, 16 * 16));
4877 __ Ldr(q28, MemOperand(x17, 17 * 16));
4878
4879 // Test D stores with and without post index.
4880 __ Mov(x0, 24);
4881 __ St3(v0.D(), v1.D(), v2.D(), 1, MemOperand(x18));
4882 __ Add(x18, x18, 24);
4883 __ St3(v0.D(), v1.D(), v2.D(), 0, MemOperand(x18, 24, PostIndex));
4884 __ St3(v0.D(), v1.D(), v2.D(), 1, MemOperand(x18, x0, PostIndex));
4885 __ Ldr(q29, MemOperand(x17, 18 * 16));
4886 __ Ldr(q30, MemOperand(x17, 19 * 16));
4887 __ Ldr(q31, MemOperand(x17, 20 * 16));
4888 END();
4889
4890 RUN();
4891
4892 ASSERT_EQUAL_128(0x0524140423130322, 0x1202211101201000, q3);
4893 ASSERT_EQUAL_128(0x1a0a291909281808, 0x2717072616062515, q4);
4894 ASSERT_EQUAL_128(0x2f1f0f2e1e0e2d1d, 0x0d2c1c0c2b1b0b2a, q5);
4895 ASSERT_EQUAL_128(0x0524140423130322, 0x1202211101201000, q6);
4896 ASSERT_EQUAL_128(0x1a0a291909281808, 0x2717072616062515, q7);
4897 ASSERT_EQUAL_128(0x2f1f0f2e1e0e2d1d, 0x0d2c1c0c2b1b0b2a, q16);
4898
4899 ASSERT_EQUAL_128(0x1415040522231213, 0x0203202110110001, q17);
4900 ASSERT_EQUAL_128(0x0a0b282918190809, 0x2627161706072425, q18);
4901 ASSERT_EQUAL_128(0x2e2f1e1f0e0f2c2d, 0x1c1d0c0d2a2b1a1b, q19);
4902 ASSERT_EQUAL_128(0x1415040522231213, 0x0203202110110001, q20);
4903 ASSERT_EQUAL_128(0x0a0b282918190809, 0x2627161706072425, q21);
4904 ASSERT_EQUAL_128(0x2e2f1e1f0e0f2c2d, 0x1c1d0c0d2a2b1a1b, q22);
4905
4906 ASSERT_EQUAL_128(0x0405060720212223, 0x1011121300010203, q23);
4907 ASSERT_EQUAL_128(0x18191a1b08090a0b, 0x2425262714151617, q24);
4908 ASSERT_EQUAL_128(0x2c2d2e2f1c1d1e1f, 0x0c0d0e0f28292a2b, q25);
4909 ASSERT_EQUAL_128(0x0405060720212223, 0x1011121300010203, q26);
4910 ASSERT_EQUAL_128(0x18191a1b08090a0b, 0x2425262714151617, q27);
4911 ASSERT_EQUAL_128(0x2c2d2e2f1c1d1e1f, 0x0c0d0e0f28292a2b, q28);
4912
4913 TEARDOWN();
4914}
4915
4916
4917TEST(neon_st4_lane) {
4918 SETUP();
4919
4920 // Struct size * element sizes * vector size.
4921 uint8_t dst[4 * 4 * 16];
4922 memset(dst, 0, sizeof(dst));
4923 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4924
4925 START();
4926 __ Mov(x17, dst_base);
4927 __ Mov(x18, dst_base);
4928 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
4929 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
4930 __ Movi(v2.V2D(), 0x2021222324252627, 0x28292a2b2c2d2e2f);
4931 __ Movi(v3.V2D(), 0x2021222324252627, 0x28292a2b2c2d2e2f);
4932
4933 // Test B stores without post index.
4934 for (int i = 15; i >= 0; i--) {
4935 __ St4(v0.B(), v1.B(), v2.B(), v3.B(), i, MemOperand(x18));
4936 __ Add(x18, x18, 4);
4937 }
4938 __ Ldr(q4, MemOperand(x17, 0 * 16));
4939 __ Ldr(q5, MemOperand(x17, 1 * 16));
4940 __ Ldr(q6, MemOperand(x17, 2 * 16));
4941 __ Ldr(q7, MemOperand(x17, 3 * 16));
4942
4943 // Test H stores with post index.
4944 __ Mov(x0, 8);
4945 for (int i = 7; i >= 0; i--) {
4946 __ St4(v0.H(), v1.H(), v2.H(), v3.H(), i, MemOperand(x18, x0, PostIndex));
4947 }
4948 __ Ldr(q16, MemOperand(x17, 4 * 16));
4949 __ Ldr(q17, MemOperand(x17, 5 * 16));
4950 __ Ldr(q18, MemOperand(x17, 6 * 16));
4951 __ Ldr(q19, MemOperand(x17, 7 * 16));
4952
4953 // Test S stores without post index.
4954 for (int i = 3; i >= 0; i--) {
4955 __ St4(v0.S(), v1.S(), v2.S(), v3.S(), i, MemOperand(x18));
4956 __ Add(x18, x18, 16);
4957 }
4958 __ Ldr(q20, MemOperand(x17, 8 * 16));
4959 __ Ldr(q21, MemOperand(x17, 9 * 16));
4960 __ Ldr(q22, MemOperand(x17, 10 * 16));
4961 __ Ldr(q23, MemOperand(x17, 11 * 16));
4962
4963 // Test D stores with post index.
4964 __ Mov(x0, 32);
4965 __ St4(v0.D(), v1.D(), v2.D(), v3.D(), 0, MemOperand(x18, 32, PostIndex));
4966 __ St4(v0.D(), v1.D(), v2.D(), v3.D(), 1, MemOperand(x18, x0, PostIndex));
4967
4968 __ Ldr(q24, MemOperand(x17, 12 * 16));
4969 __ Ldr(q25, MemOperand(x17, 13 * 16));
4970 __ Ldr(q26, MemOperand(x17, 14 * 16));
4971 __ Ldr(q27, MemOperand(x17, 15 * 16));
4972 END();
4973
4974 RUN();
4975
4976 ASSERT_EQUAL_128(0x2323130322221202, 0x2121110120201000, q4);
4977 ASSERT_EQUAL_128(0x2727170726261606, 0x2525150524241404, q5);
4978 ASSERT_EQUAL_128(0x2b2b1b0b2a2a1a0a, 0x2929190928281808, q6);
4979 ASSERT_EQUAL_128(0x2f2f1f0f2e2e1e0e, 0x2d2d1d0d2c2c1c0c, q7);
4980
4981 ASSERT_EQUAL_128(0x2223222312130203, 0x2021202110110001, q16);
4982 ASSERT_EQUAL_128(0x2627262716170607, 0x2425242514150405, q17);
4983 ASSERT_EQUAL_128(0x2a2b2a2b1a1b0a0b, 0x2829282918190809, q18);
4984 ASSERT_EQUAL_128(0x2e2f2e2f1e1f0e0f, 0x2c2d2c2d1c1d0c0d, q19);
4985
4986 ASSERT_EQUAL_128(0x2021222320212223, 0x1011121300010203, q20);
4987 ASSERT_EQUAL_128(0x2425262724252627, 0x1415161704050607, q21);
4988 ASSERT_EQUAL_128(0x28292a2b28292a2b, 0x18191a1b08090a0b, q22);
4989 ASSERT_EQUAL_128(0x2c2d2e2f2c2d2e2f, 0x1c1d1e1f0c0d0e0f, q23);
4990
4991 ASSERT_EQUAL_128(0x18191a1b1c1d1e1f, 0x08090a0b0c0d0e0f, q24);
4992 ASSERT_EQUAL_128(0x28292a2b2c2d2e2f, 0x28292a2b2c2d2e2f, q25);
4993 ASSERT_EQUAL_128(0x1011121314151617, 0x0001020304050607, q26);
4994 ASSERT_EQUAL_128(0x2021222324252627, 0x2021222324252627, q27);
4995
4996 TEARDOWN();
4997}
4998
4999
5000TEST(neon_ld1_lane_postindex) {
5001 SETUP();
5002
5003 uint8_t src[64];
5004 for (unsigned i = 0; i < sizeof(src); i++) {
5005 src[i] = i;
5006 }
5007 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5008
5009 START();
5010 __ Mov(x17, src_base);
5011 __ Mov(x18, src_base);
5012 __ Mov(x19, src_base);
5013 __ Mov(x20, src_base);
5014 __ Mov(x21, src_base);
5015 __ Mov(x22, src_base);
5016 __ Mov(x23, src_base);
5017 __ Mov(x24, src_base);
5018
5019 // Test loading whole register by element.
5020 for (int i = 15; i >= 0; i--) {
5021 __ Ld1(v0.B(), i, MemOperand(x17, 1, PostIndex));
5022 }
5023
5024 for (int i = 7; i >= 0; i--) {
5025 __ Ld1(v1.H(), i, MemOperand(x18, 2, PostIndex));
5026 }
5027
5028 for (int i = 3; i >= 0; i--) {
5029 __ Ld1(v2.S(), i, MemOperand(x19, 4, PostIndex));
5030 }
5031
5032 for (int i = 1; i >= 0; i--) {
5033 __ Ld1(v3.D(), i, MemOperand(x20, 8, PostIndex));
5034 }
5035
5036 // Test loading a single element into an initialised register.
5037 __ Mov(x25, 1);
5038 __ Ldr(q4, MemOperand(x21));
5039 __ Ld1(v4.B(), 4, MemOperand(x21, x25, PostIndex));
5040 __ Add(x25, x25, 1);
5041
5042 __ Ldr(q5, MemOperand(x22));
5043 __ Ld1(v5.H(), 3, MemOperand(x22, x25, PostIndex));
5044 __ Add(x25, x25, 1);
5045
5046 __ Ldr(q6, MemOperand(x23));
5047 __ Ld1(v6.S(), 2, MemOperand(x23, x25, PostIndex));
5048 __ Add(x25, x25, 1);
5049
5050 __ Ldr(q7, MemOperand(x24));
5051 __ Ld1(v7.D(), 1, MemOperand(x24, x25, PostIndex));
5052
5053 END();
5054
5055 RUN();
5056
5057 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
5058 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q1);
5059 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q2);
5060 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q3);
5061 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q4);
5062 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q5);
5063 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q6);
5064 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q7);
5065 ASSERT_EQUAL_64(src_base + 16, x17);
5066 ASSERT_EQUAL_64(src_base + 16, x18);
5067 ASSERT_EQUAL_64(src_base + 16, x19);
5068 ASSERT_EQUAL_64(src_base + 16, x20);
5069 ASSERT_EQUAL_64(src_base + 1, x21);
5070 ASSERT_EQUAL_64(src_base + 2, x22);
5071 ASSERT_EQUAL_64(src_base + 3, x23);
5072 ASSERT_EQUAL_64(src_base + 4, x24);
5073
5074 TEARDOWN();
5075}
5076
5077
5078TEST(neon_st1_lane_postindex) {
5079 SETUP();
5080
5081 uint8_t src[64];
5082 for (unsigned i = 0; i < sizeof(src); i++) {
5083 src[i] = i;
5084 }
5085 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5086
5087 START();
5088 __ Mov(x17, src_base);
5089 __ Mov(x18, -16);
5090 __ Ldr(q0, MemOperand(x17));
5091
5092 for (int i = 15; i >= 0; i--) {
5093 __ St1(v0.B(), i, MemOperand(x17, 1, PostIndex));
5094 }
5095 __ Ldr(q1, MemOperand(x17, x18));
5096
5097 for (int i = 7; i >= 0; i--) {
5098 __ St1(v0.H(), i, MemOperand(x17, 2, PostIndex));
5099 }
5100 __ Ldr(q2, MemOperand(x17, x18));
5101
5102 for (int i = 3; i >= 0; i--) {
5103 __ St1(v0.S(), i, MemOperand(x17, 4, PostIndex));
5104 }
5105 __ Ldr(q3, MemOperand(x17, x18));
5106
5107 for (int i = 1; i >= 0; i--) {
5108 __ St1(v0.D(), i, MemOperand(x17, 8, PostIndex));
5109 }
5110 __ Ldr(q4, MemOperand(x17, x18));
5111
5112 END();
5113
5114 RUN();
5115
5116 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q1);
5117 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q2);
5118 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q3);
5119 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q4);
5120
5121 TEARDOWN();
5122}
5123
5124
5125TEST(neon_ld1_alllanes) {
5126 SETUP();
5127
5128 uint8_t src[64];
5129 for (unsigned i = 0; i < sizeof(src); i++) {
5130 src[i] = i;
5131 }
5132 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5133
5134 START();
5135 __ Mov(x17, src_base + 1);
5136 __ Ld1r(v0.V8B(), MemOperand(x17));
5137 __ Add(x17, x17, 1);
5138 __ Ld1r(v1.V16B(), MemOperand(x17));
5139 __ Add(x17, x17, 1);
5140 __ Ld1r(v2.V4H(), MemOperand(x17));
5141 __ Add(x17, x17, 1);
5142 __ Ld1r(v3.V8H(), MemOperand(x17));
5143 __ Add(x17, x17, 1);
5144 __ Ld1r(v4.V2S(), MemOperand(x17));
5145 __ Add(x17, x17, 1);
5146 __ Ld1r(v5.V4S(), MemOperand(x17));
5147 __ Add(x17, x17, 1);
5148 __ Ld1r(v6.V1D(), MemOperand(x17));
5149 __ Add(x17, x17, 1);
5150 __ Ld1r(v7.V2D(), MemOperand(x17));
5151 END();
5152
5153 RUN();
5154
5155 ASSERT_EQUAL_128(0, 0x0101010101010101, q0);
5156 ASSERT_EQUAL_128(0x0202020202020202, 0x0202020202020202, q1);
5157 ASSERT_EQUAL_128(0, 0x0403040304030403, q2);
5158 ASSERT_EQUAL_128(0x0504050405040504, 0x0504050405040504, q3);
5159 ASSERT_EQUAL_128(0, 0x0807060508070605, q4);
5160 ASSERT_EQUAL_128(0x0908070609080706, 0x0908070609080706, q5);
5161 ASSERT_EQUAL_128(0, 0x0e0d0c0b0a090807, q6);
5162 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0f0e0d0c0b0a0908, q7);
5163
5164 TEARDOWN();
5165}
5166
5167
5168TEST(neon_ld1_alllanes_postindex) {
5169 SETUP();
5170
5171 uint8_t src[64];
5172 for (unsigned i = 0; i < sizeof(src); i++) {
5173 src[i] = i;
5174 }
5175 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5176
5177 START();
5178 __ Mov(x17, src_base + 1);
5179 __ Mov(x18, 1);
5180 __ Ld1r(v0.V8B(), MemOperand(x17, 1, PostIndex));
5181 __ Ld1r(v1.V16B(), MemOperand(x17, x18, PostIndex));
5182 __ Ld1r(v2.V4H(), MemOperand(x17, x18, PostIndex));
5183 __ Ld1r(v3.V8H(), MemOperand(x17, 2, PostIndex));
5184 __ Ld1r(v4.V2S(), MemOperand(x17, x18, PostIndex));
5185 __ Ld1r(v5.V4S(), MemOperand(x17, 4, PostIndex));
5186 __ Ld1r(v6.V2D(), MemOperand(x17, 8, PostIndex));
5187 END();
5188
5189 RUN();
5190
5191 ASSERT_EQUAL_128(0, 0x0101010101010101, q0);
5192 ASSERT_EQUAL_128(0x0202020202020202, 0x0202020202020202, q1);
5193 ASSERT_EQUAL_128(0, 0x0403040304030403, q2);
5194 ASSERT_EQUAL_128(0x0504050405040504, 0x0504050405040504, q3);
5195 ASSERT_EQUAL_128(0, 0x0908070609080706, q4);
5196 ASSERT_EQUAL_128(0x0a0908070a090807, 0x0a0908070a090807, q5);
5197 ASSERT_EQUAL_128(0x1211100f0e0d0c0b, 0x1211100f0e0d0c0b, q6);
5198 ASSERT_EQUAL_64(src_base + 19, x17);
5199
5200 TEARDOWN();
5201}
5202
5203
5204TEST(neon_st1_d) {
5205 SETUP();
5206
5207 uint8_t src[14 * kDRegSizeInBytes];
5208 for (unsigned i = 0; i < sizeof(src); i++) {
5209 src[i] = i;
5210 }
5211 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5212
5213 START();
5214 __ Mov(x17, src_base);
5215 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5216 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5217 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5218 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5219 __ Mov(x17, src_base);
5220
5221 __ St1(v0.V8B(), MemOperand(x17));
5222 __ Ldr(d16, MemOperand(x17, 8, PostIndex));
5223
5224 __ St1(v0.V8B(), v1.V8B(), MemOperand(x17));
5225 __ Ldr(q17, MemOperand(x17, 16, PostIndex));
5226
5227 __ St1(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x17));
5228 __ Ldr(d18, MemOperand(x17, 8, PostIndex));
5229 __ Ldr(d19, MemOperand(x17, 8, PostIndex));
5230 __ Ldr(d20, MemOperand(x17, 8, PostIndex));
5231
5232 __ St1(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(), MemOperand(x17));
5233 __ Ldr(q21, MemOperand(x17, 16, PostIndex));
5234 __ Ldr(q22, MemOperand(x17, 16, PostIndex));
5235
5236 __ St1(v0.V1D(), v1.V1D(), v2.V1D(), v3.V1D(), MemOperand(x17));
5237 __ Ldr(q23, MemOperand(x17, 16, PostIndex));
5238 __ Ldr(q24, MemOperand(x17));
5239 END();
5240
5241 RUN();
5242
5243 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q0);
5244 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q1);
5245 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q2);
5246 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323130, q3);
5247 ASSERT_EQUAL_128(0, 0x0706050403020100, q16);
5248 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q17);
5249 ASSERT_EQUAL_128(0, 0x0706050403020100, q18);
5250 ASSERT_EQUAL_128(0, 0x1716151413121110, q19);
5251 ASSERT_EQUAL_128(0, 0x2726252423222120, q20);
5252 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q21);
5253 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q22);
5254 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q23);
5255 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q24);
5256
5257 TEARDOWN();
5258}
5259
5260
5261TEST(neon_st1_d_postindex) {
5262 SETUP();
5263
5264 uint8_t src[64 + 14 * kDRegSizeInBytes];
5265 for (unsigned i = 0; i < sizeof(src); i++) {
5266 src[i] = i;
5267 }
5268 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5269
5270 START();
5271 __ Mov(x17, src_base);
5272 __ Mov(x18, -8);
5273 __ Mov(x19, -16);
5274 __ Mov(x20, -24);
5275 __ Mov(x21, -32);
5276 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5277 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5278 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5279 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5280 __ Mov(x17, src_base);
5281
5282 __ St1(v0.V8B(), MemOperand(x17, 8, PostIndex));
5283 __ Ldr(d16, MemOperand(x17, x18));
5284
5285 __ St1(v0.V8B(), v1.V8B(), MemOperand(x17, 16, PostIndex));
5286 __ Ldr(q17, MemOperand(x17, x19));
5287
5288 __ St1(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x17, 24, PostIndex));
5289 __ Ldr(d18, MemOperand(x17, x20));
5290 __ Ldr(d19, MemOperand(x17, x19));
5291 __ Ldr(d20, MemOperand(x17, x18));
5292
5293 __ St1(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(),
5294 MemOperand(x17, 32, PostIndex));
5295 __ Ldr(q21, MemOperand(x17, x21));
5296 __ Ldr(q22, MemOperand(x17, x19));
5297
5298 __ St1(v0.V1D(), v1.V1D(), v2.V1D(), v3.V1D(),
5299 MemOperand(x17, 32, PostIndex));
5300 __ Ldr(q23, MemOperand(x17, x21));
5301 __ Ldr(q24, MemOperand(x17, x19));
5302 END();
5303
5304 RUN();
5305
5306 ASSERT_EQUAL_128(0, 0x0706050403020100, q16);
5307 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q17);
5308 ASSERT_EQUAL_128(0, 0x0706050403020100, q18);
5309 ASSERT_EQUAL_128(0, 0x1716151413121110, q19);
5310 ASSERT_EQUAL_128(0, 0x2726252423222120, q20);
5311 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q21);
5312 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q22);
5313 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q23);
5314 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q24);
5315
5316 TEARDOWN();
5317}
5318
5319
5320TEST(neon_st1_q) {
5321 SETUP();
5322
5323 uint8_t src[64 + 160];
5324 for (unsigned i = 0; i < sizeof(src); i++) {
5325 src[i] = i;
5326 }
5327 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5328
5329 START();
5330 __ Mov(x17, src_base);
5331 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5332 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5333 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5334 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5335
5336 __ St1(v0.V16B(), MemOperand(x17));
5337 __ Ldr(q16, MemOperand(x17, 16, PostIndex));
5338
5339 __ St1(v0.V8H(), v1.V8H(), MemOperand(x17));
5340 __ Ldr(q17, MemOperand(x17, 16, PostIndex));
5341 __ Ldr(q18, MemOperand(x17, 16, PostIndex));
5342
5343 __ St1(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x17));
5344 __ Ldr(q19, MemOperand(x17, 16, PostIndex));
5345 __ Ldr(q20, MemOperand(x17, 16, PostIndex));
5346 __ Ldr(q21, MemOperand(x17, 16, PostIndex));
5347
5348 __ St1(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(), MemOperand(x17));
5349 __ Ldr(q22, MemOperand(x17, 16, PostIndex));
5350 __ Ldr(q23, MemOperand(x17, 16, PostIndex));
5351 __ Ldr(q24, MemOperand(x17, 16, PostIndex));
5352 __ Ldr(q25, MemOperand(x17));
5353 END();
5354
5355 RUN();
5356
5357 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q16);
5358 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q17);
5359 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q18);
5360 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q19);
5361 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q20);
5362 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q21);
5363 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q22);
5364 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q23);
5365 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q24);
5366 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323130, q25);
5367
5368 TEARDOWN();
5369}
5370
5371
5372TEST(neon_st1_q_postindex) {
5373 SETUP();
5374
5375 uint8_t src[64 + 160];
5376 for (unsigned i = 0; i < sizeof(src); i++) {
5377 src[i] = i;
5378 }
5379 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5380
5381 START();
5382 __ Mov(x17, src_base);
5383 __ Mov(x18, -16);
5384 __ Mov(x19, -32);
5385 __ Mov(x20, -48);
5386 __ Mov(x21, -64);
5387 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5388 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5389 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5390 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5391
5392 __ St1(v0.V16B(), MemOperand(x17, 16, PostIndex));
5393 __ Ldr(q16, MemOperand(x17, x18));
5394
5395 __ St1(v0.V8H(), v1.V8H(), MemOperand(x17, 32, PostIndex));
5396 __ Ldr(q17, MemOperand(x17, x19));
5397 __ Ldr(q18, MemOperand(x17, x18));
5398
5399 __ St1(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x17, 48, PostIndex));
5400 __ Ldr(q19, MemOperand(x17, x20));
5401 __ Ldr(q20, MemOperand(x17, x19));
5402 __ Ldr(q21, MemOperand(x17, x18));
5403
5404 __ St1(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(),
5405 MemOperand(x17, 64, PostIndex));
5406 __ Ldr(q22, MemOperand(x17, x21));
5407 __ Ldr(q23, MemOperand(x17, x20));
5408 __ Ldr(q24, MemOperand(x17, x19));
5409 __ Ldr(q25, MemOperand(x17, x18));
5410
5411 END();
5412
5413 RUN();
5414
5415 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q16);
5416 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q17);
5417 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q18);
5418 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q19);
5419 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q20);
5420 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q21);
5421 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q22);
5422 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q23);
5423 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q24);
5424 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323130, q25);
5425
5426 TEARDOWN();
5427}
5428
5429
5430TEST(neon_st2_d) {
5431 SETUP();
5432
5433 uint8_t src[4*16];
5434 for (unsigned i = 0; i < sizeof(src); i++) {
5435 src[i] = i;
5436 }
5437 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5438
5439 START();
5440 __ Mov(x17, src_base);
5441 __ Mov(x18, src_base);
5442 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5443 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5444
5445 __ St2(v0.V8B(), v1.V8B(), MemOperand(x18));
5446 __ Add(x18, x18, 22);
5447 __ St2(v0.V4H(), v1.V4H(), MemOperand(x18));
5448 __ Add(x18, x18, 11);
5449 __ St2(v0.V2S(), v1.V2S(), MemOperand(x18));
5450
5451 __ Mov(x19, src_base);
5452 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5453 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5454 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5455 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5456
5457 END();
5458
5459 RUN();
5460
5461 ASSERT_EQUAL_128(0x1707160615051404, 0x1303120211011000, q0);
5462 ASSERT_EQUAL_128(0x0504131203021110, 0x0100151413121110, q1);
5463 ASSERT_EQUAL_128(0x1615140706050413, 0x1211100302010014, q2);
5464 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323117, q3);
5465
5466 TEARDOWN();
5467}
5468
5469
5470TEST(neon_st2_d_postindex) {
5471 SETUP();
5472
5473 uint8_t src[4*16];
5474 for (unsigned i = 0; i < sizeof(src); i++) {
5475 src[i] = i;
5476 }
5477 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5478
5479 START();
5480 __ Mov(x22, 5);
5481 __ Mov(x17, src_base);
5482 __ Mov(x18, src_base);
5483 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5484 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5485
5486 __ St2(v0.V8B(), v1.V8B(), MemOperand(x18, x22, PostIndex));
5487 __ St2(v0.V4H(), v1.V4H(), MemOperand(x18, 16, PostIndex));
5488 __ St2(v0.V2S(), v1.V2S(), MemOperand(x18));
5489
5490
5491 __ Mov(x19, src_base);
5492 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5493 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5494 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5495
5496 END();
5497
5498 RUN();
5499
5500 ASSERT_EQUAL_128(0x1405041312030211, 0x1001000211011000, q0);
5501 ASSERT_EQUAL_128(0x0605041312111003, 0x0201001716070615, q1);
5502 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726251716151407, q2);
5503
5504 TEARDOWN();
5505}
5506
5507
5508TEST(neon_st2_q) {
5509 SETUP();
5510
5511 uint8_t src[5*16];
5512 for (unsigned i = 0; i < sizeof(src); i++) {
5513 src[i] = i;
5514 }
5515 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5516
5517 START();
5518 __ Mov(x17, src_base);
5519 __ Mov(x18, src_base);
5520 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5521 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5522
5523 __ St2(v0.V16B(), v1.V16B(), MemOperand(x18));
5524 __ Add(x18, x18, 8);
5525 __ St2(v0.V8H(), v1.V8H(), MemOperand(x18));
5526 __ Add(x18, x18, 22);
5527 __ St2(v0.V4S(), v1.V4S(), MemOperand(x18));
5528 __ Add(x18, x18, 2);
5529 __ St2(v0.V2D(), v1.V2D(), MemOperand(x18));
5530
5531 __ Mov(x19, src_base);
5532 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5533 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5534 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5535 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5536
5537 END();
5538
5539 RUN();
5540
5541 ASSERT_EQUAL_128(0x1312030211100100, 0x1303120211011000, q0);
5542 ASSERT_EQUAL_128(0x01000b0a19180908, 0x1716070615140504, q1);
5543 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q2);
5544 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0f0e0d0c0b0a0908, q3);
5545 TEARDOWN();
5546}
5547
5548
5549TEST(neon_st2_q_postindex) {
5550 SETUP();
5551
5552 uint8_t src[5*16];
5553 for (unsigned i = 0; i < sizeof(src); i++) {
5554 src[i] = i;
5555 }
5556 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5557
5558 START();
5559 __ Mov(x22, 5);
5560 __ Mov(x17, src_base);
5561 __ Mov(x18, src_base);
5562 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5563 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5564
5565 __ St2(v0.V16B(), v1.V16B(), MemOperand(x18, x22, PostIndex));
5566 __ St2(v0.V8H(), v1.V8H(), MemOperand(x18, 32, PostIndex));
5567 __ St2(v0.V4S(), v1.V4S(), MemOperand(x18, x22, PostIndex));
5568 __ St2(v0.V2D(), v1.V2D(), MemOperand(x18));
5569
5570 __ Mov(x19, src_base);
5571 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5572 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5573 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5574 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5575 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5576
5577 END();
5578
5579 RUN();
5580
5581 ASSERT_EQUAL_128(0x1405041312030211, 0x1001000211011000, q0);
5582 ASSERT_EQUAL_128(0x1c0d0c1b1a0b0a19, 0x1809081716070615, q1);
5583 ASSERT_EQUAL_128(0x0504030201001003, 0x0201001f1e0f0e1d, q2);
5584 ASSERT_EQUAL_128(0x0d0c0b0a09081716, 0x1514131211100706, q3);
5585 ASSERT_EQUAL_128(0x4f4e4d4c4b4a1f1e, 0x1d1c1b1a19180f0e, q4);
5586
5587 TEARDOWN();
5588}
5589
5590
5591TEST(neon_st3_d) {
5592 SETUP();
5593
5594 uint8_t src[3*16];
5595 for (unsigned i = 0; i < sizeof(src); i++) {
5596 src[i] = i;
5597 }
5598 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5599
5600 START();
5601 __ Mov(x17, src_base);
5602 __ Mov(x18, src_base);
5603 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5604 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5605 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5606
5607 __ St3(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x18));
5608 __ Add(x18, x18, 3);
5609 __ St3(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x18));
5610 __ Add(x18, x18, 2);
5611 __ St3(v0.V2S(), v1.V2S(), v2.V2S(), MemOperand(x18));
5612
5613
5614 __ Mov(x19, src_base);
5615 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5616 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5617
5618 END();
5619
5620 RUN();
5621
5622 ASSERT_EQUAL_128(0x2221201312111003, 0x0201000100201000, q0);
5623 ASSERT_EQUAL_128(0x1f1e1d2726252417, 0x1615140706050423, q1);
5624
5625 TEARDOWN();
5626}
5627
5628
5629TEST(neon_st3_d_postindex) {
5630 SETUP();
5631
5632 uint8_t src[4*16];
5633 for (unsigned i = 0; i < sizeof(src); i++) {
5634 src[i] = i;
5635 }
5636 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5637
5638 START();
5639 __ Mov(x22, 5);
5640 __ Mov(x17, src_base);
5641 __ Mov(x18, src_base);
5642 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5643 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5644 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5645
5646 __ St3(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x18, x22, PostIndex));
5647 __ St3(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x18, 24, PostIndex));
5648 __ St3(v0.V2S(), v1.V2S(), v2.V2S(), MemOperand(x18));
5649
5650
5651 __ Mov(x19, src_base);
5652 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5653 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5654 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5655 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5656
5657 END();
5658
5659 RUN();
5660
5661 ASSERT_EQUAL_128(0x2213120302212011, 0x1001001101201000, q0);
5662 ASSERT_EQUAL_128(0x0201002726171607, 0x0625241514050423, q1);
5663 ASSERT_EQUAL_128(0x1615140706050423, 0x2221201312111003, q2);
5664 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736352726252417, q3);
5665
5666 TEARDOWN();
5667}
5668
5669
5670TEST(neon_st3_q) {
5671 SETUP();
5672
5673 uint8_t src[6*16];
5674 for (unsigned i = 0; i < sizeof(src); i++) {
5675 src[i] = i;
5676 }
5677 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5678
5679 START();
5680 __ Mov(x17, src_base);
5681 __ Mov(x18, src_base);
5682 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5683 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5684 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5685
5686 __ St3(v0.V16B(), v1.V16B(), v2.V16B(), MemOperand(x18));
5687 __ Add(x18, x18, 5);
5688 __ St3(v0.V8H(), v1.V8H(), v2.V8H(), MemOperand(x18));
5689 __ Add(x18, x18, 12);
5690 __ St3(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x18));
5691 __ Add(x18, x18, 22);
5692 __ St3(v0.V2D(), v1.V2D(), v2.V2D(), MemOperand(x18));
5693
5694 __ Mov(x19, src_base);
5695 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5696 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5697 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5698 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5699 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5700 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5701
5702 END();
5703
5704 RUN();
5705
5706 ASSERT_EQUAL_128(0x2213120302212011, 0x1001001101201000, q0);
5707 ASSERT_EQUAL_128(0x0605042322212013, 0x1211100302010023, q1);
5708 ASSERT_EQUAL_128(0x1007060504030201, 0x0025241716151407, q2);
5709 ASSERT_EQUAL_128(0x0827262524232221, 0x2017161514131211, q3);
5710 ASSERT_EQUAL_128(0x281f1e1d1c1b1a19, 0x180f0e0d0c0b0a09, q4);
5711 ASSERT_EQUAL_128(0x5f5e5d5c5b5a5958, 0x572f2e2d2c2b2a29, q5);
5712
5713 TEARDOWN();
5714}
5715
5716
5717TEST(neon_st3_q_postindex) {
5718 SETUP();
5719
5720 uint8_t src[7*16];
5721 for (unsigned i = 0; i < sizeof(src); i++) {
5722 src[i] = i;
5723 }
5724 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5725
5726 START();
5727 __ Mov(x22, 5);
5728 __ Mov(x17, src_base);
5729 __ Mov(x18, src_base);
5730 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5731 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5732 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5733
5734 __ St3(v0.V16B(), v1.V16B(), v2.V16B(), MemOperand(x18, x22, PostIndex));
5735 __ St3(v0.V8H(), v1.V8H(), v2.V8H(), MemOperand(x18, 48, PostIndex));
5736 __ St3(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x18, x22, PostIndex));
5737 __ St3(v0.V2D(), v1.V2D(), v2.V2D(), MemOperand(x18));
5738
5739 __ Mov(x19, src_base);
5740 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5741 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5742 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5743 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5744 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5745 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5746 __ Ldr(q6, MemOperand(x19, 16, PostIndex));
5747
5748 END();
5749
5750 RUN();
5751
5752 ASSERT_EQUAL_128(0x2213120302212011, 0x1001001101201000, q0);
5753 ASSERT_EQUAL_128(0x1809082726171607, 0x0625241514050423, q1);
5754 ASSERT_EQUAL_128(0x0e2d2c1d1c0d0c2b, 0x2a1b1a0b0a292819, q2);
5755 ASSERT_EQUAL_128(0x0504030201001003, 0x0201002f2e1f1e0f, q3);
5756 ASSERT_EQUAL_128(0x2524232221201716, 0x1514131211100706, q4);
5757 ASSERT_EQUAL_128(0x1d1c1b1a19180f0e, 0x0d0c0b0a09082726, q5);
5758 ASSERT_EQUAL_128(0x6f6e6d6c6b6a2f2e, 0x2d2c2b2a29281f1e, q6);
5759
5760 TEARDOWN();
5761}
5762
5763
5764TEST(neon_st4_d) {
5765 SETUP();
5766
5767 uint8_t src[4*16];
5768 for (unsigned i = 0; i < sizeof(src); i++) {
5769 src[i] = i;
5770 }
5771 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5772
5773 START();
5774 __ Mov(x17, src_base);
5775 __ Mov(x18, src_base);
5776 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5777 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5778 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5779 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5780
5781 __ St4(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(), MemOperand(x18));
5782 __ Add(x18, x18, 12);
5783 __ St4(v0.V4H(), v1.V4H(), v2.V4H(), v3.V4H(), MemOperand(x18));
5784 __ Add(x18, x18, 15);
5785 __ St4(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(), MemOperand(x18));
5786
5787
5788 __ Mov(x19, src_base);
5789 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5790 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5791 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5792 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5793
5794 END();
5795
5796 RUN();
5797
5798 ASSERT_EQUAL_128(0x1110010032221202, 0X3121110130201000, q0);
5799 ASSERT_EQUAL_128(0x1003020100322322, 0X1312030231302120, q1);
5800 ASSERT_EQUAL_128(0x1407060504333231, 0X3023222120131211, q2);
5801 ASSERT_EQUAL_128(0x3f3e3d3c3b373635, 0x3427262524171615, q3);
5802
5803 TEARDOWN();
5804}
5805
5806
5807TEST(neon_st4_d_postindex) {
5808 SETUP();
5809
5810 uint8_t src[5*16];
5811 for (unsigned i = 0; i < sizeof(src); i++) {
5812 src[i] = i;
5813 }
5814 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5815
5816 START();
5817 __ Mov(x22, 5);
5818 __ Mov(x17, src_base);
5819 __ Mov(x18, src_base);
5820 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5821 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5822 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5823 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5824
5825 __ St4(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(),
5826 MemOperand(x18, x22, PostIndex));
5827 __ St4(v0.V4H(), v1.V4H(), v2.V4H(), v3.V4H(),
5828 MemOperand(x18, 32, PostIndex));
5829 __ St4(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(),
5830 MemOperand(x18));
5831
5832
5833 __ Mov(x19, src_base);
5834 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5835 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5836 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5837 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5838 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5839
5840 END();
5841
5842 RUN();
5843
5844 ASSERT_EQUAL_128(0x1203023130212011, 0x1001000130201000, q0);
5845 ASSERT_EQUAL_128(0x1607063534252415, 0x1405043332232213, q1);
5846 ASSERT_EQUAL_128(0x2221201312111003, 0x0201003736272617, q2);
5847 ASSERT_EQUAL_128(0x2625241716151407, 0x0605043332313023, q3);
5848 ASSERT_EQUAL_128(0x4f4e4d4c4b4a4948, 0x4746453736353427, q4);
5849
5850 TEARDOWN();
5851}
5852
5853
5854TEST(neon_st4_q) {
5855 SETUP();
5856
5857 uint8_t src[7*16];
5858 for (unsigned i = 0; i < sizeof(src); i++) {
5859 src[i] = i;
5860 }
5861 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5862
5863 START();
5864 __ Mov(x17, src_base);
5865 __ Mov(x18, src_base);
5866 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5867 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5868 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5869 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5870
5871 __ St4(v0.V16B(), v1.V16B(), v2.V16B(), v3.V16B(), MemOperand(x18));
5872 __ Add(x18, x18, 5);
5873 __ St4(v0.V8H(), v1.V8H(), v2.V8H(), v3.V8H(), MemOperand(x18));
5874 __ Add(x18, x18, 12);
5875 __ St4(v0.V4S(), v1.V4S(), v2.V4S(), v3.V4S(), MemOperand(x18));
5876 __ Add(x18, x18, 22);
5877 __ St4(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(), MemOperand(x18));
5878 __ Add(x18, x18, 10);
5879
5880 __ Mov(x19, src_base);
5881 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5882 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5883 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5884 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5885 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5886 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5887 __ Ldr(q6, MemOperand(x19, 16, PostIndex));
5888
5889 END();
5890
5891 RUN();
5892
5893 ASSERT_EQUAL_128(0x1203023130212011, 0x1001000130201000, q0);
5894 ASSERT_EQUAL_128(0x3231302322212013, 0x1211100302010013, q1);
5895 ASSERT_EQUAL_128(0x1007060504030201, 0x0015140706050433, q2);
5896 ASSERT_EQUAL_128(0x3027262524232221, 0x2017161514131211, q3);
5897 ASSERT_EQUAL_128(0x180f0e0d0c0b0a09, 0x0837363534333231, q4);
5898 ASSERT_EQUAL_128(0x382f2e2d2c2b2a29, 0x281f1e1d1c1b1a19, q5);
5899 ASSERT_EQUAL_128(0x6f6e6d6c6b6a6968, 0x673f3e3d3c3b3a39, q6);
5900
5901 TEARDOWN();
5902}
5903
5904
5905TEST(neon_st4_q_postindex) {
5906 SETUP();
5907
5908 uint8_t src[9*16];
5909 for (unsigned i = 0; i < sizeof(src); i++) {
5910 src[i] = i;
5911 }
5912 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5913
5914 START();
5915 __ Mov(x22, 5);
5916 __ Mov(x17, src_base);
5917 __ Mov(x18, src_base);
5918 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5919 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5920 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5921 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5922
5923 __ St4(v0.V16B(), v1.V16B(), v2.V16B(), v3.V16B(),
5924 MemOperand(x18, x22, PostIndex));
5925 __ St4(v0.V8H(), v1.V8H(), v2.V8H(), v3.V8H(),
5926 MemOperand(x18, 64, PostIndex));
5927 __ St4(v0.V4S(), v1.V4S(), v2.V4S(), v3.V4S(),
5928 MemOperand(x18, x22, PostIndex));
5929 __ St4(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(),
5930 MemOperand(x18));
5931
5932 __ Mov(x19, src_base);
5933 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5934 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5935 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5936 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5937 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5938 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5939 __ Ldr(q6, MemOperand(x19, 16, PostIndex));
5940 __ Ldr(q7, MemOperand(x19, 16, PostIndex));
5941 __ Ldr(q8, MemOperand(x19, 16, PostIndex));
5942
5943 END();
5944
5945 RUN();
5946
5947 ASSERT_EQUAL_128(0x1203023130212011, 0x1001000130201000, q0);
5948 ASSERT_EQUAL_128(0x1607063534252415, 0x1405043332232213, q1);
5949 ASSERT_EQUAL_128(0x1a0b0a3938292819, 0x1809083736272617, q2);
5950 ASSERT_EQUAL_128(0x1e0f0e3d3c2d2c1d, 0x1c0d0c3b3a2b2a1b, q3);
5951 ASSERT_EQUAL_128(0x0504030201001003, 0x0201003f3e2f2e1f, q4);
5952 ASSERT_EQUAL_128(0x2524232221201716, 0x1514131211100706, q5);
5953 ASSERT_EQUAL_128(0x0d0c0b0a09083736, 0x3534333231302726, q6);
5954 ASSERT_EQUAL_128(0x2d2c2b2a29281f1e, 0x1d1c1b1a19180f0e, q7);
5955 ASSERT_EQUAL_128(0x8f8e8d8c8b8a3f3e, 0x3d3c3b3a39382f2e, q8);
5956
5957 TEARDOWN();
5958}
5959
5960
armvixlad96eda2013-06-14 11:42:37 +01005961TEST(ldp_stp_float) {
5962 SETUP();
5963
5964 float src[2] = {1.0, 2.0};
5965 float dst[3] = {0.0, 0.0, 0.0};
5966 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5967 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
5968
5969 START();
5970 __ Mov(x16, src_base);
5971 __ Mov(x17, dst_base);
5972 __ Ldp(s31, s0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
5973 __ Stp(s0, s31, MemOperand(x17, sizeof(dst[1]), PreIndex));
5974 END();
5975
5976 RUN();
5977
5978 ASSERT_EQUAL_FP32(1.0, s31);
5979 ASSERT_EQUAL_FP32(2.0, s0);
5980 ASSERT_EQUAL_FP32(0.0, dst[0]);
5981 ASSERT_EQUAL_FP32(2.0, dst[1]);
5982 ASSERT_EQUAL_FP32(1.0, dst[2]);
5983 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
5984 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
5985
5986 TEARDOWN();
5987}
5988
5989
5990TEST(ldp_stp_double) {
5991 SETUP();
5992
5993 double src[2] = {1.0, 2.0};
5994 double dst[3] = {0.0, 0.0, 0.0};
5995 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5996 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
5997
5998 START();
5999 __ Mov(x16, src_base);
6000 __ Mov(x17, dst_base);
6001 __ Ldp(d31, d0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
6002 __ Stp(d0, d31, MemOperand(x17, sizeof(dst[1]), PreIndex));
6003 END();
6004
6005 RUN();
6006
6007 ASSERT_EQUAL_FP64(1.0, d31);
6008 ASSERT_EQUAL_FP64(2.0, d0);
6009 ASSERT_EQUAL_FP64(0.0, dst[0]);
6010 ASSERT_EQUAL_FP64(2.0, dst[1]);
6011 ASSERT_EQUAL_FP64(1.0, dst[2]);
6012 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
6013 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
6014
6015 TEARDOWN();
6016}
6017
6018
armvixl5289c592015-03-02 13:52:04 +00006019TEST(ldp_stp_quad) {
6020 SETUP();
6021
6022 uint64_t src[4] = {0x0123456789abcdef, 0xaaaaaaaa55555555,
6023 0xfedcba9876543210, 0x55555555aaaaaaaa};
6024 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
6025 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6026 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6027
6028 START();
6029 __ Mov(x16, src_base);
6030 __ Mov(x17, dst_base);
6031 __ Ldp(q31, q0, MemOperand(x16, 4 * sizeof(src[0]), PostIndex));
6032 __ Stp(q0, q31, MemOperand(x17, 2 * sizeof(dst[1]), PreIndex));
6033 END();
6034
6035 RUN();
6036
6037 ASSERT_EQUAL_128(0xaaaaaaaa55555555, 0x0123456789abcdef, q31);
6038 ASSERT_EQUAL_128(0x55555555aaaaaaaa, 0xfedcba9876543210, q0);
6039 ASSERT_EQUAL_64(0, dst[0]);
6040 ASSERT_EQUAL_64(0, dst[1]);
6041 ASSERT_EQUAL_64(0xfedcba9876543210, dst[2]);
6042 ASSERT_EQUAL_64(0x55555555aaaaaaaa, dst[3]);
6043 ASSERT_EQUAL_64(0x0123456789abcdef, dst[4]);
6044 ASSERT_EQUAL_64(0xaaaaaaaa55555555, dst[5]);
6045 ASSERT_EQUAL_64(src_base + 4 * sizeof(src[0]), x16);
6046 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[1]), x17);
6047
6048 TEARDOWN();
6049}
6050
6051
armvixlad96eda2013-06-14 11:42:37 +01006052TEST(ldp_stp_offset) {
6053 SETUP();
6054
armvixlb0c8ae22014-03-21 14:03:59 +00006055 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6056 0xffeeddccbbaa9988};
armvixlad96eda2013-06-14 11:42:37 +01006057 uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
6058 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6059 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6060
6061 START();
6062 __ Mov(x16, src_base);
6063 __ Mov(x17, dst_base);
6064 __ Mov(x18, src_base + 24);
6065 __ Mov(x19, dst_base + 56);
6066 __ Ldp(w0, w1, MemOperand(x16));
6067 __ Ldp(w2, w3, MemOperand(x16, 4));
6068 __ Ldp(x4, x5, MemOperand(x16, 8));
6069 __ Ldp(w6, w7, MemOperand(x18, -12));
6070 __ Ldp(x8, x9, MemOperand(x18, -16));
6071 __ Stp(w0, w1, MemOperand(x17));
6072 __ Stp(w2, w3, MemOperand(x17, 8));
6073 __ Stp(x4, x5, MemOperand(x17, 16));
6074 __ Stp(w6, w7, MemOperand(x19, -24));
6075 __ Stp(x8, x9, MemOperand(x19, -16));
6076 END();
6077
6078 RUN();
6079
6080 ASSERT_EQUAL_64(0x44556677, x0);
6081 ASSERT_EQUAL_64(0x00112233, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00006082 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
armvixlad96eda2013-06-14 11:42:37 +01006083 ASSERT_EQUAL_64(0x00112233, x2);
6084 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006085 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
6086 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6087 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
6088 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6089 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01006090 ASSERT_EQUAL_64(0x8899aabb, x6);
6091 ASSERT_EQUAL_64(0xbbaa9988, x7);
armvixlb0c8ae22014-03-21 14:03:59 +00006092 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
6093 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
6094 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
6095 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
6096 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
armvixlad96eda2013-06-14 11:42:37 +01006097 ASSERT_EQUAL_64(src_base, x16);
6098 ASSERT_EQUAL_64(dst_base, x17);
6099 ASSERT_EQUAL_64(src_base + 24, x18);
6100 ASSERT_EQUAL_64(dst_base + 56, x19);
6101
6102 TEARDOWN();
6103}
6104
6105
armvixlc68cb642014-09-25 18:49:30 +01006106TEST(ldp_stp_offset_wide) {
6107 SETUP();
6108
6109 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6110 0xffeeddccbbaa9988};
6111 uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
6112 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6113 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6114 // Move base too far from the array to force multiple instructions
6115 // to be emitted.
6116 const int64_t base_offset = 1024;
6117
6118 START();
6119 __ Mov(x20, src_base - base_offset);
6120 __ Mov(x21, dst_base - base_offset);
6121 __ Mov(x18, src_base + base_offset + 24);
6122 __ Mov(x19, dst_base + base_offset + 56);
6123 __ Ldp(w0, w1, MemOperand(x20, base_offset));
6124 __ Ldp(w2, w3, MemOperand(x20, base_offset + 4));
6125 __ Ldp(x4, x5, MemOperand(x20, base_offset + 8));
6126 __ Ldp(w6, w7, MemOperand(x18, -12 - base_offset));
6127 __ Ldp(x8, x9, MemOperand(x18, -16 - base_offset));
6128 __ Stp(w0, w1, MemOperand(x21, base_offset));
6129 __ Stp(w2, w3, MemOperand(x21, base_offset + 8));
6130 __ Stp(x4, x5, MemOperand(x21, base_offset + 16));
6131 __ Stp(w6, w7, MemOperand(x19, -24 - base_offset));
6132 __ Stp(x8, x9, MemOperand(x19, -16 - base_offset));
6133 END();
6134
6135 RUN();
6136
6137 ASSERT_EQUAL_64(0x44556677, x0);
6138 ASSERT_EQUAL_64(0x00112233, x1);
6139 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
6140 ASSERT_EQUAL_64(0x00112233, x2);
6141 ASSERT_EQUAL_64(0xccddeeff, x3);
6142 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
6143 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6144 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
6145 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6146 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
6147 ASSERT_EQUAL_64(0x8899aabb, x6);
6148 ASSERT_EQUAL_64(0xbbaa9988, x7);
6149 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
6150 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
6151 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
6152 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
6153 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
6154 ASSERT_EQUAL_64(src_base - base_offset, x20);
6155 ASSERT_EQUAL_64(dst_base - base_offset, x21);
6156 ASSERT_EQUAL_64(src_base + base_offset + 24, x18);
6157 ASSERT_EQUAL_64(dst_base + base_offset + 56, x19);
6158
6159 TEARDOWN();
6160}
6161
6162
armvixlad96eda2013-06-14 11:42:37 +01006163TEST(ldnp_stnp_offset) {
6164 SETUP();
6165
armvixl5289c592015-03-02 13:52:04 +00006166 uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
6167 0xffeeddccbbaa9988, 0x7766554433221100};
6168 uint64_t dst[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
armvixlad96eda2013-06-14 11:42:37 +01006169 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6170 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6171
6172 START();
6173 __ Mov(x16, src_base);
6174 __ Mov(x17, dst_base);
6175 __ Mov(x18, src_base + 24);
armvixl5289c592015-03-02 13:52:04 +00006176 __ Mov(x19, dst_base + 64);
6177 __ Mov(x20, src_base + 32);
6178
6179 // Ensure address set up has happened before executing non-temporal ops.
6180 __ Dmb(InnerShareable, BarrierAll);
6181
armvixlad96eda2013-06-14 11:42:37 +01006182 __ Ldnp(w0, w1, MemOperand(x16));
6183 __ Ldnp(w2, w3, MemOperand(x16, 4));
6184 __ Ldnp(x4, x5, MemOperand(x16, 8));
6185 __ Ldnp(w6, w7, MemOperand(x18, -12));
6186 __ Ldnp(x8, x9, MemOperand(x18, -16));
armvixl5289c592015-03-02 13:52:04 +00006187 __ Ldnp(q16, q17, MemOperand(x16));
6188 __ Ldnp(q19, q18, MemOperand(x20, -32));
armvixlad96eda2013-06-14 11:42:37 +01006189 __ Stnp(w0, w1, MemOperand(x17));
6190 __ Stnp(w2, w3, MemOperand(x17, 8));
6191 __ Stnp(x4, x5, MemOperand(x17, 16));
armvixl5289c592015-03-02 13:52:04 +00006192 __ Stnp(w6, w7, MemOperand(x19, -32));
6193 __ Stnp(x8, x9, MemOperand(x19, -24));
6194 __ Stnp(q17, q16, MemOperand(x19));
6195 __ Stnp(q18, q19, MemOperand(x19, 32));
armvixlad96eda2013-06-14 11:42:37 +01006196 END();
6197
6198 RUN();
6199
6200 ASSERT_EQUAL_64(0x44556677, x0);
6201 ASSERT_EQUAL_64(0x00112233, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00006202 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
armvixlad96eda2013-06-14 11:42:37 +01006203 ASSERT_EQUAL_64(0x00112233, x2);
6204 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006205 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
6206 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6207 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
6208 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6209 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01006210 ASSERT_EQUAL_64(0x8899aabb, x6);
6211 ASSERT_EQUAL_64(0xbbaa9988, x7);
armvixlb0c8ae22014-03-21 14:03:59 +00006212 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
6213 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
6214 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
6215 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
6216 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
armvixl5289c592015-03-02 13:52:04 +00006217 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x0011223344556677, q16);
6218 ASSERT_EQUAL_128(0x7766554433221100, 0xffeeddccbbaa9988, q17);
6219 ASSERT_EQUAL_128(0x7766554433221100, 0xffeeddccbbaa9988, q18);
6220 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x0011223344556677, q19);
6221 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[8]);
6222 ASSERT_EQUAL_64(0x7766554433221100, dst[9]);
6223 ASSERT_EQUAL_64(0x0011223344556677, dst[10]);
6224 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[11]);
6225 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[12]);
6226 ASSERT_EQUAL_64(0x7766554433221100, dst[13]);
6227 ASSERT_EQUAL_64(0x0011223344556677, dst[14]);
6228 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[15]);
armvixlad96eda2013-06-14 11:42:37 +01006229 ASSERT_EQUAL_64(src_base, x16);
6230 ASSERT_EQUAL_64(dst_base, x17);
6231 ASSERT_EQUAL_64(src_base + 24, x18);
armvixl5289c592015-03-02 13:52:04 +00006232 ASSERT_EQUAL_64(dst_base + 64, x19);
6233 ASSERT_EQUAL_64(src_base + 32, x20);
6234
6235 TEARDOWN();
6236}
6237
6238
6239TEST(ldnp_stnp_offset_float) {
6240 SETUP();
6241
6242 float src[3] = {1.2, 2.3, 3.4};
6243 float dst[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6244 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6245 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6246
6247 START();
6248 __ Mov(x16, src_base);
6249 __ Mov(x17, dst_base);
6250 __ Mov(x18, src_base + 12);
6251 __ Mov(x19, dst_base + 24);
6252
6253 // Ensure address set up has happened before executing non-temporal ops.
6254 __ Dmb(InnerShareable, BarrierAll);
6255
6256 __ Ldnp(s0, s1, MemOperand(x16));
6257 __ Ldnp(s2, s3, MemOperand(x16, 4));
6258 __ Ldnp(s5, s4, MemOperand(x18, -8));
6259 __ Stnp(s1, s0, MemOperand(x17));
6260 __ Stnp(s3, s2, MemOperand(x17, 8));
6261 __ Stnp(s4, s5, MemOperand(x19, -8));
6262 END();
6263
6264 RUN();
6265
6266 ASSERT_EQUAL_FP32(1.2, s0);
6267 ASSERT_EQUAL_FP32(2.3, s1);
6268 ASSERT_EQUAL_FP32(2.3, dst[0]);
6269 ASSERT_EQUAL_FP32(1.2, dst[1]);
6270 ASSERT_EQUAL_FP32(2.3, s2);
6271 ASSERT_EQUAL_FP32(3.4, s3);
6272 ASSERT_EQUAL_FP32(3.4, dst[2]);
6273 ASSERT_EQUAL_FP32(2.3, dst[3]);
6274 ASSERT_EQUAL_FP32(3.4, s4);
6275 ASSERT_EQUAL_FP32(2.3, s5);
6276 ASSERT_EQUAL_FP32(3.4, dst[4]);
6277 ASSERT_EQUAL_FP32(2.3, dst[5]);
6278 ASSERT_EQUAL_64(src_base, x16);
6279 ASSERT_EQUAL_64(dst_base, x17);
6280 ASSERT_EQUAL_64(src_base + 12, x18);
6281 ASSERT_EQUAL_64(dst_base + 24, x19);
6282
6283 TEARDOWN();
6284}
6285
6286
6287TEST(ldnp_stnp_offset_double) {
6288 SETUP();
6289
6290 double src[3] = {1.2, 2.3, 3.4};
6291 double dst[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6292 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6293 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6294
6295 START();
6296 __ Mov(x16, src_base);
6297 __ Mov(x17, dst_base);
6298 __ Mov(x18, src_base + 24);
6299 __ Mov(x19, dst_base + 48);
6300
6301 // Ensure address set up has happened before executing non-temporal ops.
6302 __ Dmb(InnerShareable, BarrierAll);
6303
6304 __ Ldnp(d0, d1, MemOperand(x16));
6305 __ Ldnp(d2, d3, MemOperand(x16, 8));
6306 __ Ldnp(d5, d4, MemOperand(x18, -16));
6307 __ Stnp(d1, d0, MemOperand(x17));
6308 __ Stnp(d3, d2, MemOperand(x17, 16));
6309 __ Stnp(d4, d5, MemOperand(x19, -16));
6310 END();
6311
6312 RUN();
6313
6314 ASSERT_EQUAL_FP64(1.2, d0);
6315 ASSERT_EQUAL_FP64(2.3, d1);
6316 ASSERT_EQUAL_FP64(2.3, dst[0]);
6317 ASSERT_EQUAL_FP64(1.2, dst[1]);
6318 ASSERT_EQUAL_FP64(2.3, d2);
6319 ASSERT_EQUAL_FP64(3.4, d3);
6320 ASSERT_EQUAL_FP64(3.4, dst[2]);
6321 ASSERT_EQUAL_FP64(2.3, dst[3]);
6322 ASSERT_EQUAL_FP64(3.4, d4);
6323 ASSERT_EQUAL_FP64(2.3, d5);
6324 ASSERT_EQUAL_FP64(3.4, dst[4]);
6325 ASSERT_EQUAL_FP64(2.3, dst[5]);
6326 ASSERT_EQUAL_64(src_base, x16);
6327 ASSERT_EQUAL_64(dst_base, x17);
6328 ASSERT_EQUAL_64(src_base + 24, x18);
6329 ASSERT_EQUAL_64(dst_base + 48, x19);
armvixlad96eda2013-06-14 11:42:37 +01006330
6331 TEARDOWN();
6332}
6333
6334
6335TEST(ldp_stp_preindex) {
6336 SETUP();
6337
armvixlb0c8ae22014-03-21 14:03:59 +00006338 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6339 0xffeeddccbbaa9988};
armvixlad96eda2013-06-14 11:42:37 +01006340 uint64_t dst[5] = {0, 0, 0, 0, 0};
6341 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6342 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6343
6344 START();
6345 __ Mov(x16, src_base);
6346 __ Mov(x17, dst_base);
6347 __ Mov(x18, dst_base + 16);
6348 __ Ldp(w0, w1, MemOperand(x16, 4, PreIndex));
6349 __ Mov(x19, x16);
6350 __ Ldp(w2, w3, MemOperand(x16, -4, PreIndex));
6351 __ Stp(w2, w3, MemOperand(x17, 4, PreIndex));
6352 __ Mov(x20, x17);
6353 __ Stp(w0, w1, MemOperand(x17, -4, PreIndex));
6354 __ Ldp(x4, x5, MemOperand(x16, 8, PreIndex));
6355 __ Mov(x21, x16);
6356 __ Ldp(x6, x7, MemOperand(x16, -8, PreIndex));
6357 __ Stp(x7, x6, MemOperand(x18, 8, PreIndex));
6358 __ Mov(x22, x18);
6359 __ Stp(x5, x4, MemOperand(x18, -8, PreIndex));
6360 END();
6361
6362 RUN();
6363
6364 ASSERT_EQUAL_64(0x00112233, x0);
6365 ASSERT_EQUAL_64(0xccddeeff, x1);
6366 ASSERT_EQUAL_64(0x44556677, x2);
6367 ASSERT_EQUAL_64(0x00112233, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006368 ASSERT_EQUAL_64(0xccddeeff00112233, dst[0]);
6369 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6370 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6371 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6372 ASSERT_EQUAL_64(0x0011223344556677, x6);
6373 ASSERT_EQUAL_64(0x8899aabbccddeeff, x7);
6374 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6375 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6376 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01006377 ASSERT_EQUAL_64(src_base, x16);
6378 ASSERT_EQUAL_64(dst_base, x17);
6379 ASSERT_EQUAL_64(dst_base + 16, x18);
6380 ASSERT_EQUAL_64(src_base + 4, x19);
6381 ASSERT_EQUAL_64(dst_base + 4, x20);
6382 ASSERT_EQUAL_64(src_base + 8, x21);
6383 ASSERT_EQUAL_64(dst_base + 24, x22);
6384
6385 TEARDOWN();
6386}
6387
6388
armvixlc68cb642014-09-25 18:49:30 +01006389TEST(ldp_stp_preindex_wide) {
6390 SETUP();
6391
6392 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6393 0xffeeddccbbaa9988};
6394 uint64_t dst[5] = {0, 0, 0, 0, 0};
6395 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6396 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6397 // Move base too far from the array to force multiple instructions
6398 // to be emitted.
6399 const int64_t base_offset = 1024;
6400
6401 START();
6402 __ Mov(x24, src_base - base_offset);
6403 __ Mov(x25, dst_base + base_offset);
6404 __ Mov(x18, dst_base + base_offset + 16);
6405 __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PreIndex));
6406 __ Mov(x19, x24);
6407 __ Mov(x24, src_base - base_offset + 4);
6408 __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PreIndex));
6409 __ Stp(w2, w3, MemOperand(x25, 4 - base_offset , PreIndex));
6410 __ Mov(x20, x25);
6411 __ Mov(x25, dst_base + base_offset + 4);
6412 __ Mov(x24, src_base - base_offset);
6413 __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PreIndex));
6414 __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PreIndex));
6415 __ Mov(x21, x24);
6416 __ Mov(x24, src_base - base_offset + 8);
6417 __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PreIndex));
6418 __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PreIndex));
6419 __ Mov(x22, x18);
6420 __ Mov(x18, dst_base + base_offset + 16 + 8);
6421 __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PreIndex));
6422 END();
6423
6424 RUN();
6425
6426 ASSERT_EQUAL_64(0x00112233, x0);
6427 ASSERT_EQUAL_64(0xccddeeff, x1);
6428 ASSERT_EQUAL_64(0x44556677, x2);
6429 ASSERT_EQUAL_64(0x00112233, x3);
6430 ASSERT_EQUAL_64(0xccddeeff00112233, dst[0]);
6431 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6432 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6433 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6434 ASSERT_EQUAL_64(0x0011223344556677, x6);
6435 ASSERT_EQUAL_64(0x8899aabbccddeeff, x7);
6436 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6437 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6438 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
6439 ASSERT_EQUAL_64(src_base, x24);
6440 ASSERT_EQUAL_64(dst_base, x25);
6441 ASSERT_EQUAL_64(dst_base + 16, x18);
6442 ASSERT_EQUAL_64(src_base + 4, x19);
6443 ASSERT_EQUAL_64(dst_base + 4, x20);
6444 ASSERT_EQUAL_64(src_base + 8, x21);
6445 ASSERT_EQUAL_64(dst_base + 24, x22);
6446
6447 TEARDOWN();
6448}
6449
6450
armvixlad96eda2013-06-14 11:42:37 +01006451TEST(ldp_stp_postindex) {
6452 SETUP();
6453
armvixlb0c8ae22014-03-21 14:03:59 +00006454 uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
6455 0xffeeddccbbaa9988, 0x7766554433221100};
armvixlad96eda2013-06-14 11:42:37 +01006456 uint64_t dst[5] = {0, 0, 0, 0, 0};
6457 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6458 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6459
6460 START();
6461 __ Mov(x16, src_base);
6462 __ Mov(x17, dst_base);
6463 __ Mov(x18, dst_base + 16);
6464 __ Ldp(w0, w1, MemOperand(x16, 4, PostIndex));
6465 __ Mov(x19, x16);
6466 __ Ldp(w2, w3, MemOperand(x16, -4, PostIndex));
6467 __ Stp(w2, w3, MemOperand(x17, 4, PostIndex));
6468 __ Mov(x20, x17);
6469 __ Stp(w0, w1, MemOperand(x17, -4, PostIndex));
6470 __ Ldp(x4, x5, MemOperand(x16, 8, PostIndex));
6471 __ Mov(x21, x16);
6472 __ Ldp(x6, x7, MemOperand(x16, -8, PostIndex));
6473 __ Stp(x7, x6, MemOperand(x18, 8, PostIndex));
6474 __ Mov(x22, x18);
6475 __ Stp(x5, x4, MemOperand(x18, -8, PostIndex));
6476 END();
6477
6478 RUN();
6479
6480 ASSERT_EQUAL_64(0x44556677, x0);
6481 ASSERT_EQUAL_64(0x00112233, x1);
6482 ASSERT_EQUAL_64(0x00112233, x2);
6483 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006484 ASSERT_EQUAL_64(0x4455667700112233, dst[0]);
6485 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6486 ASSERT_EQUAL_64(0x0011223344556677, x4);
6487 ASSERT_EQUAL_64(0x8899aabbccddeeff, x5);
6488 ASSERT_EQUAL_64(0x8899aabbccddeeff, x6);
6489 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x7);
6490 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6491 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6492 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01006493 ASSERT_EQUAL_64(src_base, x16);
6494 ASSERT_EQUAL_64(dst_base, x17);
6495 ASSERT_EQUAL_64(dst_base + 16, x18);
6496 ASSERT_EQUAL_64(src_base + 4, x19);
6497 ASSERT_EQUAL_64(dst_base + 4, x20);
6498 ASSERT_EQUAL_64(src_base + 8, x21);
6499 ASSERT_EQUAL_64(dst_base + 24, x22);
6500
6501 TEARDOWN();
6502}
6503
6504
armvixlc68cb642014-09-25 18:49:30 +01006505TEST(ldp_stp_postindex_wide) {
6506 SETUP();
6507
6508 uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
6509 0xffeeddccbbaa9988, 0x7766554433221100};
6510 uint64_t dst[5] = {0, 0, 0, 0, 0};
6511 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6512 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6513 // Move base too far from the array to force multiple instructions
6514 // to be emitted.
6515 const int64_t base_offset = 1024;
6516
6517 START();
6518 __ Mov(x24, src_base);
6519 __ Mov(x25, dst_base);
6520 __ Mov(x18, dst_base + 16);
6521 __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PostIndex));
6522 __ Mov(x19, x24);
6523 __ Sub(x24, x24, base_offset);
6524 __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PostIndex));
6525 __ Stp(w2, w3, MemOperand(x25, 4 - base_offset, PostIndex));
6526 __ Mov(x20, x25);
6527 __ Sub(x24, x24, base_offset);
6528 __ Add(x25, x25, base_offset);
6529 __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PostIndex));
6530 __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PostIndex));
6531 __ Mov(x21, x24);
6532 __ Sub(x24, x24, base_offset);
6533 __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PostIndex));
6534 __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PostIndex));
6535 __ Mov(x22, x18);
6536 __ Add(x18, x18, base_offset);
6537 __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PostIndex));
6538 END();
6539
6540 RUN();
6541
6542 ASSERT_EQUAL_64(0x44556677, x0);
6543 ASSERT_EQUAL_64(0x00112233, x1);
6544 ASSERT_EQUAL_64(0x00112233, x2);
6545 ASSERT_EQUAL_64(0xccddeeff, x3);
6546 ASSERT_EQUAL_64(0x4455667700112233, dst[0]);
6547 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6548 ASSERT_EQUAL_64(0x0011223344556677, x4);
6549 ASSERT_EQUAL_64(0x8899aabbccddeeff, x5);
6550 ASSERT_EQUAL_64(0x8899aabbccddeeff, x6);
6551 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x7);
6552 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6553 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6554 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
6555 ASSERT_EQUAL_64(src_base + base_offset, x24);
6556 ASSERT_EQUAL_64(dst_base - base_offset, x25);
6557 ASSERT_EQUAL_64(dst_base - base_offset + 16, x18);
6558 ASSERT_EQUAL_64(src_base + base_offset + 4, x19);
6559 ASSERT_EQUAL_64(dst_base - base_offset + 4, x20);
6560 ASSERT_EQUAL_64(src_base + base_offset + 8, x21);
6561 ASSERT_EQUAL_64(dst_base - base_offset + 24, x22);
6562
6563 TEARDOWN();
6564}
6565
6566
armvixlad96eda2013-06-14 11:42:37 +01006567TEST(ldp_sign_extend) {
6568 SETUP();
6569
6570 uint32_t src[2] = {0x80000000, 0x7fffffff};
6571 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6572
6573 START();
6574 __ Mov(x24, src_base);
6575 __ Ldpsw(x0, x1, MemOperand(x24));
6576 END();
6577
6578 RUN();
6579
armvixlb0c8ae22014-03-21 14:03:59 +00006580 ASSERT_EQUAL_64(0xffffffff80000000, x0);
6581 ASSERT_EQUAL_64(0x000000007fffffff, x1);
armvixlad96eda2013-06-14 11:42:37 +01006582
6583 TEARDOWN();
6584}
6585
6586
6587TEST(ldur_stur) {
6588 SETUP();
6589
armvixlb0c8ae22014-03-21 14:03:59 +00006590 int64_t src[2] = {0x0123456789abcdef, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01006591 int64_t dst[5] = {0, 0, 0, 0, 0};
6592 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6593 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6594
6595 START();
6596 __ Mov(x17, src_base);
6597 __ Mov(x18, dst_base);
6598 __ Mov(x19, src_base + 16);
6599 __ Mov(x20, dst_base + 32);
6600 __ Mov(x21, dst_base + 40);
6601 __ Ldr(w0, MemOperand(x17, 1));
6602 __ Str(w0, MemOperand(x18, 2));
6603 __ Ldr(x1, MemOperand(x17, 3));
6604 __ Str(x1, MemOperand(x18, 9));
6605 __ Ldr(w2, MemOperand(x19, -9));
6606 __ Str(w2, MemOperand(x20, -5));
6607 __ Ldrb(w3, MemOperand(x19, -1));
6608 __ Strb(w3, MemOperand(x21, -1));
6609 END();
6610
6611 RUN();
6612
6613 ASSERT_EQUAL_64(0x6789abcd, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00006614 ASSERT_EQUAL_64(0x00006789abcd0000, dst[0]);
6615 ASSERT_EQUAL_64(0xabcdef0123456789, x1);
6616 ASSERT_EQUAL_64(0xcdef012345678900, dst[1]);
armvixlad96eda2013-06-14 11:42:37 +01006617 ASSERT_EQUAL_64(0x000000ab, dst[2]);
6618 ASSERT_EQUAL_64(0xabcdef01, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00006619 ASSERT_EQUAL_64(0x00abcdef01000000, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01006620 ASSERT_EQUAL_64(0x00000001, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006621 ASSERT_EQUAL_64(0x0100000000000000, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01006622 ASSERT_EQUAL_64(src_base, x17);
6623 ASSERT_EQUAL_64(dst_base, x18);
6624 ASSERT_EQUAL_64(src_base + 16, x19);
6625 ASSERT_EQUAL_64(dst_base + 32, x20);
6626
6627 TEARDOWN();
6628}
6629
6630
armvixl5289c592015-03-02 13:52:04 +00006631TEST(ldur_stur_fp) {
6632 SETUP();
6633
6634 int64_t src[3] = {0x0123456789abcdef, 0x0123456789abcdef,
6635 0x0123456789abcdef};
6636 int64_t dst[5] = {0, 0, 0, 0, 0};
6637 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6638 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6639
6640 START();
6641 __ Mov(x17, src_base);
6642 __ Mov(x18, dst_base);
6643 __ Ldr(b0, MemOperand(x17));
6644 __ Str(b0, MemOperand(x18));
6645 __ Ldr(h1, MemOperand(x17, 1));
6646 __ Str(h1, MemOperand(x18, 1));
6647 __ Ldr(s2, MemOperand(x17, 2));
6648 __ Str(s2, MemOperand(x18, 3));
6649 __ Ldr(d3, MemOperand(x17, 3));
6650 __ Str(d3, MemOperand(x18, 7));
6651 __ Ldr(q4, MemOperand(x17, 4));
6652 __ Str(q4, MemOperand(x18, 15));
6653 END();
6654
6655 RUN();
6656
6657 ASSERT_EQUAL_128(0, 0xef, q0);
6658 ASSERT_EQUAL_128(0, 0xabcd, q1);
6659 ASSERT_EQUAL_128(0, 0x456789ab, q2);
6660 ASSERT_EQUAL_128(0, 0xabcdef0123456789, q3);
6661 ASSERT_EQUAL_128(0x89abcdef01234567, 0x89abcdef01234567, q4);
6662 ASSERT_EQUAL_64(0x89456789ababcdef, dst[0]);
6663 ASSERT_EQUAL_64(0x67abcdef01234567, dst[1]);
6664 ASSERT_EQUAL_64(0x6789abcdef012345, dst[2]);
6665 ASSERT_EQUAL_64(0x0089abcdef012345, dst[3]);
6666
6667 TEARDOWN();
6668}
6669
6670
armvixlad96eda2013-06-14 11:42:37 +01006671TEST(ldr_literal) {
6672 SETUP();
6673
6674 START();
armvixlb0c8ae22014-03-21 14:03:59 +00006675 __ Ldr(x2, 0x1234567890abcdef);
armvixlad96eda2013-06-14 11:42:37 +01006676 __ Ldr(w3, 0xfedcba09);
armvixlc68cb642014-09-25 18:49:30 +01006677 __ Ldrsw(x4, 0x7fffffff);
6678 __ Ldrsw(x5, 0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006679 __ Ldr(q11, 0x1234000056780000, 0xabcd0000ef000000);
armvixlad96eda2013-06-14 11:42:37 +01006680 __ Ldr(d13, 1.234);
6681 __ Ldr(s25, 2.5);
6682 END();
6683
6684 RUN();
6685
armvixlb0c8ae22014-03-21 14:03:59 +00006686 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
armvixlad96eda2013-06-14 11:42:37 +01006687 ASSERT_EQUAL_64(0xfedcba09, x3);
armvixlc68cb642014-09-25 18:49:30 +01006688 ASSERT_EQUAL_64(0x7fffffff, x4);
6689 ASSERT_EQUAL_64(0xffffffff80000000, x5);
armvixl5289c592015-03-02 13:52:04 +00006690 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
armvixlad96eda2013-06-14 11:42:37 +01006691 ASSERT_EQUAL_FP64(1.234, d13);
6692 ASSERT_EQUAL_FP32(2.5, s25);
6693
6694 TEARDOWN();
6695}
6696
6697
armvixlc68cb642014-09-25 18:49:30 +01006698TEST(ldr_literal_range) {
6699 SETUP();
armvixlad96eda2013-06-14 11:42:37 +01006700
6701 START();
armvixlc68cb642014-09-25 18:49:30 +01006702 // Make sure the pool is empty;
6703 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
armvixlad96eda2013-06-14 11:42:37 +01006704 ASSERT_LITERAL_POOL_SIZE(0);
6705
armvixlc68cb642014-09-25 18:49:30 +01006706 // Create some literal pool entries.
armvixlb0c8ae22014-03-21 14:03:59 +00006707 __ Ldr(x0, 0x1234567890abcdef);
armvixlad96eda2013-06-14 11:42:37 +01006708 __ Ldr(w1, 0xfedcba09);
armvixlc68cb642014-09-25 18:49:30 +01006709 __ Ldrsw(x2, 0x7fffffff);
6710 __ Ldrsw(x3, 0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006711 __ Ldr(q2, 0x1234000056780000, 0xabcd0000ef000000);
armvixlad96eda2013-06-14 11:42:37 +01006712 __ Ldr(d0, 1.234);
6713 __ Ldr(s1, 2.5);
armvixl5289c592015-03-02 13:52:04 +00006714 ASSERT_LITERAL_POOL_SIZE(48);
armvixlad96eda2013-06-14 11:42:37 +01006715
armvixlc68cb642014-09-25 18:49:30 +01006716 // Emit more code than the maximum literal load range to ensure the pool
6717 // should be emitted.
armvixl330dc712014-11-25 10:38:32 +00006718 const ptrdiff_t end = masm.CursorOffset() + 2 * kMaxLoadLiteralRange;
6719 while (masm.CursorOffset() < end) {
armvixlad96eda2013-06-14 11:42:37 +01006720 __ Nop();
armvixlad96eda2013-06-14 11:42:37 +01006721 }
6722
armvixlc68cb642014-09-25 18:49:30 +01006723 // The pool should have been emitted.
armvixlad96eda2013-06-14 11:42:37 +01006724 ASSERT_LITERAL_POOL_SIZE(0);
6725
6726 // These loads should be after the pool (and will require a new one).
armvixlb0c8ae22014-03-21 14:03:59 +00006727 __ Ldr(x4, 0x34567890abcdef12);
armvixlad96eda2013-06-14 11:42:37 +01006728 __ Ldr(w5, 0xdcba09fe);
armvixlc68cb642014-09-25 18:49:30 +01006729 __ Ldrsw(x6, 0x7fffffff);
6730 __ Ldrsw(x7, 0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006731 __ Ldr(q6, 0x1234000056780000, 0xabcd0000ef000000);
armvixlad96eda2013-06-14 11:42:37 +01006732 __ Ldr(d4, 123.4);
6733 __ Ldr(s5, 250.0);
armvixl5289c592015-03-02 13:52:04 +00006734 ASSERT_LITERAL_POOL_SIZE(48);
armvixlad96eda2013-06-14 11:42:37 +01006735 END();
6736
6737 RUN();
6738
6739 // Check that the literals loaded correctly.
armvixlb0c8ae22014-03-21 14:03:59 +00006740 ASSERT_EQUAL_64(0x1234567890abcdef, x0);
armvixlad96eda2013-06-14 11:42:37 +01006741 ASSERT_EQUAL_64(0xfedcba09, x1);
armvixlc68cb642014-09-25 18:49:30 +01006742 ASSERT_EQUAL_64(0x7fffffff, x2);
6743 ASSERT_EQUAL_64(0xffffffff80000000, x3);
armvixl5289c592015-03-02 13:52:04 +00006744 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q2);
armvixlad96eda2013-06-14 11:42:37 +01006745 ASSERT_EQUAL_FP64(1.234, d0);
6746 ASSERT_EQUAL_FP32(2.5, s1);
armvixlb0c8ae22014-03-21 14:03:59 +00006747 ASSERT_EQUAL_64(0x34567890abcdef12, x4);
armvixlad96eda2013-06-14 11:42:37 +01006748 ASSERT_EQUAL_64(0xdcba09fe, x5);
armvixlc68cb642014-09-25 18:49:30 +01006749 ASSERT_EQUAL_64(0x7fffffff, x6);
6750 ASSERT_EQUAL_64(0xffffffff80000000, x7);
armvixl5289c592015-03-02 13:52:04 +00006751 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q6);
armvixlad96eda2013-06-14 11:42:37 +01006752 ASSERT_EQUAL_FP64(123.4, d4);
6753 ASSERT_EQUAL_FP32(250.0, s5);
6754
6755 TEARDOWN();
6756}
6757
6758
armvixl5289c592015-03-02 13:52:04 +00006759TEST(ldr_literal_values_q) {
6760 SETUP();
6761
6762 static const uint64_t kHalfValues[] = {
6763 0x8000000000000000, 0x7fffffffffffffff, 0x0000000000000000,
6764 0xffffffffffffffff, 0x00ff00ff00ff00ff, 0x1234567890abcdef
6765 };
6766 const int card = sizeof(kHalfValues) / sizeof(kHalfValues[0]);
6767 const Register& ref_low64 = x1;
6768 const Register& ref_high64 = x2;
6769 const Register& loaded_low64 = x3;
6770 const Register& loaded_high64 = x4;
6771 const VRegister& tgt = q0;
6772
6773 START();
6774 __ Mov(x0, 0);
6775
6776 for (int i = 0; i < card; i++) {
6777 __ Mov(ref_low64, kHalfValues[i]);
6778 for (int j = 0; j < card; j++) {
6779 __ Mov(ref_high64, kHalfValues[j]);
6780 __ Ldr(tgt, kHalfValues[j], kHalfValues[i]);
6781 __ Mov(loaded_low64, tgt.V2D(), 0);
6782 __ Mov(loaded_high64, tgt.V2D(), 1);
6783 __ Cmp(loaded_low64, ref_low64);
6784 __ Ccmp(loaded_high64, ref_high64, NoFlag, eq);
6785 __ Cset(x0, ne);
6786 }
6787 }
6788 END();
6789
6790 RUN();
6791
6792 // If one of the values differs, the trace can be used to identify which one.
6793 ASSERT_EQUAL_64(0, x0);
6794
6795 TEARDOWN();
6796}
6797
6798
armvixlc68cb642014-09-25 18:49:30 +01006799template <typename T>
6800void LoadIntValueHelper(T values[], int card) {
6801 SETUP();
6802
6803 const bool is_32bits = (sizeof(T) == 4);
6804 const Register& tgt1 = is_32bits ? w1 : x1;
6805 const Register& tgt2 = is_32bits ? w2 : x2;
6806
6807 START();
6808 __ Mov(x0, 0);
6809
6810 // If one of the values differ then x0 will be one.
6811 for (int i = 0; i < card; ++i) {
6812 __ Mov(tgt1, values[i]);
6813 __ Ldr(tgt2, values[i]);
6814 __ Cmp(tgt1, tgt2);
6815 __ Cset(x0, ne);
6816 }
6817 END();
6818
6819 RUN();
6820
6821 // If one of the values differs, the trace can be used to identify which one.
6822 ASSERT_EQUAL_64(0, x0);
6823
6824 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +01006825}
6826
6827
armvixlc68cb642014-09-25 18:49:30 +01006828TEST(ldr_literal_values_x) {
6829 static const uint64_t kValues[] = {
6830 0x8000000000000000, 0x7fffffffffffffff, 0x0000000000000000,
6831 0xffffffffffffffff, 0x00ff00ff00ff00ff, 0x1234567890abcdef
6832 };
6833
6834 LoadIntValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006835}
6836
6837
armvixlc68cb642014-09-25 18:49:30 +01006838TEST(ldr_literal_values_w) {
6839 static const uint32_t kValues[] = {
6840 0x80000000, 0x7fffffff, 0x00000000, 0xffffffff, 0x00ff00ff, 0x12345678,
6841 0x90abcdef
6842 };
6843
6844 LoadIntValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006845}
6846
6847
armvixlc68cb642014-09-25 18:49:30 +01006848template <typename T>
6849void LoadFPValueHelper(T values[], int card) {
6850 SETUP();
6851
6852 const bool is_32bits = (sizeof(T) == 4);
6853 const FPRegister& fp_tgt = is_32bits ? s2 : d2;
6854 const Register& tgt1 = is_32bits ? w1 : x1;
6855 const Register& tgt2 = is_32bits ? w2 : x2;
6856
6857 START();
6858 __ Mov(x0, 0);
6859
6860 // If one of the values differ then x0 will be one.
6861 for (int i = 0; i < card; ++i) {
6862 __ Mov(tgt1, is_32bits ? float_to_rawbits(values[i])
6863 : double_to_rawbits(values[i]));
6864 __ Ldr(fp_tgt, values[i]);
6865 __ Fmov(tgt2, fp_tgt);
6866 __ Cmp(tgt1, tgt2);
6867 __ Cset(x0, ne);
6868 }
6869 END();
6870
6871 RUN();
6872
6873 // If one of the values differs, the trace can be used to identify which one.
6874 ASSERT_EQUAL_64(0, x0);
6875
6876 TEARDOWN();
6877}
6878
6879TEST(ldr_literal_values_d) {
6880 static const double kValues[] = {
6881 -0.0, 0.0, -1.0, 1.0, -1e10, 1e10
6882 };
6883
6884 LoadFPValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006885}
6886
6887
armvixlc68cb642014-09-25 18:49:30 +01006888TEST(ldr_literal_values_s) {
6889 static const float kValues[] = {
6890 -0.0, 0.0, -1.0, 1.0, -1e10, 1e10
6891 };
6892
6893 LoadFPValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006894}
6895
6896
armvixlc68cb642014-09-25 18:49:30 +01006897TEST(ldr_literal_custom) {
armvixlc68cb642014-09-25 18:49:30 +01006898 SETUP();
6899 ALLOW_ASM();
6900
armvixl330dc712014-11-25 10:38:32 +00006901 Label end_of_pool_before;
6902 Label end_of_pool_after;
6903 Literal<uint64_t> before_x(0x1234567890abcdef);
6904 Literal<uint32_t> before_w(0xfedcba09);
6905 Literal<uint32_t> before_sx(0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006906 Literal<uint64_t> before_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006907 Literal<double> before_d(1.234);
6908 Literal<float> before_s(2.5);
6909 Literal<uint64_t> after_x(0x1234567890abcdef);
6910 Literal<uint32_t> after_w(0xfedcba09);
6911 Literal<uint32_t> after_sx(0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006912 Literal<uint64_t> after_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006913 Literal<double> after_d(1.234);
6914 Literal<float> after_s(2.5);
armvixlc68cb642014-09-25 18:49:30 +01006915
6916 START();
armvixlc68cb642014-09-25 18:49:30 +01006917
armvixl330dc712014-11-25 10:38:32 +00006918 // Manually generate a pool.
6919 __ B(&end_of_pool_before);
6920 __ place(&before_x);
6921 __ place(&before_w);
6922 __ place(&before_sx);
armvixl5289c592015-03-02 13:52:04 +00006923 __ place(&before_q);
armvixl330dc712014-11-25 10:38:32 +00006924 __ place(&before_d);
6925 __ place(&before_s);
6926 __ Bind(&end_of_pool_before);
6927
6928 __ ldr(x2, &before_x);
6929 __ ldr(w3, &before_w);
6930 __ ldrsw(x5, &before_sx);
armvixl5289c592015-03-02 13:52:04 +00006931 __ ldr(q11, &before_q);
armvixl330dc712014-11-25 10:38:32 +00006932 __ ldr(d13, &before_d);
6933 __ ldr(s25, &before_s);
6934
6935 __ ldr(x6, &after_x);
6936 __ ldr(w7, &after_w);
6937 __ ldrsw(x8, &after_sx);
armvixl5289c592015-03-02 13:52:04 +00006938 __ ldr(q18, &after_q);
armvixl330dc712014-11-25 10:38:32 +00006939 __ ldr(d14, &after_d);
6940 __ ldr(s26, &after_s);
6941
6942 // Manually generate a pool.
6943 __ B(&end_of_pool_after);
6944 __ place(&after_x);
6945 __ place(&after_w);
6946 __ place(&after_sx);
armvixl5289c592015-03-02 13:52:04 +00006947 __ place(&after_q);
armvixl330dc712014-11-25 10:38:32 +00006948 __ place(&after_d);
6949 __ place(&after_s);
6950 __ Bind(&end_of_pool_after);
6951
armvixlc68cb642014-09-25 18:49:30 +01006952 END();
6953
6954 RUN();
6955
6956 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
6957 ASSERT_EQUAL_64(0xfedcba09, x3);
6958 ASSERT_EQUAL_64(0xffffffff80000000, x5);
armvixl5289c592015-03-02 13:52:04 +00006959 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
armvixlc68cb642014-09-25 18:49:30 +01006960 ASSERT_EQUAL_FP64(1.234, d13);
6961 ASSERT_EQUAL_FP32(2.5, s25);
6962
armvixl330dc712014-11-25 10:38:32 +00006963 ASSERT_EQUAL_64(0x1234567890abcdef, x6);
6964 ASSERT_EQUAL_64(0xfedcba09, x7);
6965 ASSERT_EQUAL_64(0xffffffff80000000, x8);
armvixl5289c592015-03-02 13:52:04 +00006966 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q18);
armvixl330dc712014-11-25 10:38:32 +00006967 ASSERT_EQUAL_FP64(1.234, d14);
6968 ASSERT_EQUAL_FP32(2.5, s26);
6969
6970 TEARDOWN();
6971}
6972
6973
6974TEST(ldr_literal_custom_shared) {
6975 SETUP();
6976 ALLOW_ASM();
6977
6978 Label end_of_pool_before;
6979 Label end_of_pool_after;
6980 Literal<uint64_t> before_x(0x1234567890abcdef);
6981 Literal<uint32_t> before_w(0xfedcba09);
armvixl5289c592015-03-02 13:52:04 +00006982 Literal<uint64_t> before_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006983 Literal<double> before_d(1.234);
6984 Literal<float> before_s(2.5);
6985 Literal<uint64_t> after_x(0x1234567890abcdef);
6986 Literal<uint32_t> after_w(0xfedcba09);
armvixl5289c592015-03-02 13:52:04 +00006987 Literal<uint64_t> after_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006988 Literal<double> after_d(1.234);
6989 Literal<float> after_s(2.5);
6990
6991 START();
6992
6993 // Manually generate a pool.
6994 __ B(&end_of_pool_before);
6995 __ place(&before_x);
6996 __ place(&before_w);
armvixl5289c592015-03-02 13:52:04 +00006997 __ place(&before_q);
armvixl330dc712014-11-25 10:38:32 +00006998 __ place(&before_d);
6999 __ place(&before_s);
7000 __ Bind(&end_of_pool_before);
7001
7002 // Load the entries several times to test that literals can be shared.
7003 for (int i = 0; i < 50; i++) {
7004 __ ldr(x2, &before_x);
7005 __ ldr(w3, &before_w);
7006 __ ldrsw(x5, &before_w); // Re-use before_w.
armvixl5289c592015-03-02 13:52:04 +00007007 __ ldr(q11, &before_q);
armvixl330dc712014-11-25 10:38:32 +00007008 __ ldr(d13, &before_d);
7009 __ ldr(s25, &before_s);
7010
7011 __ ldr(x6, &after_x);
7012 __ ldr(w7, &after_w);
7013 __ ldrsw(x8, &after_w); // Re-use after_w.
armvixl5289c592015-03-02 13:52:04 +00007014 __ ldr(q18, &after_q);
armvixl330dc712014-11-25 10:38:32 +00007015 __ ldr(d14, &after_d);
7016 __ ldr(s26, &after_s);
7017 }
7018
7019 // Manually generate a pool.
7020 __ B(&end_of_pool_after);
7021 __ place(&after_x);
7022 __ place(&after_w);
armvixl5289c592015-03-02 13:52:04 +00007023 __ place(&after_q);
armvixl330dc712014-11-25 10:38:32 +00007024 __ place(&after_d);
7025 __ place(&after_s);
7026 __ Bind(&end_of_pool_after);
7027
7028 END();
7029
7030 RUN();
7031
7032 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
7033 ASSERT_EQUAL_64(0xfedcba09, x3);
7034 ASSERT_EQUAL_64(0xfffffffffedcba09, x5);
armvixl5289c592015-03-02 13:52:04 +00007035 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
armvixl330dc712014-11-25 10:38:32 +00007036 ASSERT_EQUAL_FP64(1.234, d13);
7037 ASSERT_EQUAL_FP32(2.5, s25);
7038
7039 ASSERT_EQUAL_64(0x1234567890abcdef, x6);
7040 ASSERT_EQUAL_64(0xfedcba09, x7);
7041 ASSERT_EQUAL_64(0xfffffffffedcba09, x8);
armvixl5289c592015-03-02 13:52:04 +00007042 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q18);
armvixl330dc712014-11-25 10:38:32 +00007043 ASSERT_EQUAL_FP64(1.234, d14);
7044 ASSERT_EQUAL_FP32(2.5, s26);
7045
7046 TEARDOWN();
7047}
7048
7049
7050TEST(prfm_offset) {
7051 SETUP();
7052
7053 START();
7054 // The address used in prfm doesn't have to be valid.
7055 __ Mov(x0, 0x0123456789abcdef);
7056
7057 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7058 // Unallocated prefetch operations are ignored, so test all of them.
7059 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7060
7061 __ Prfm(op, MemOperand(x0));
7062 __ Prfm(op, MemOperand(x0, 8));
7063 __ Prfm(op, MemOperand(x0, 32760));
7064 __ Prfm(op, MemOperand(x0, 32768));
7065
7066 __ Prfm(op, MemOperand(x0, 1));
7067 __ Prfm(op, MemOperand(x0, 9));
7068 __ Prfm(op, MemOperand(x0, 255));
7069 __ Prfm(op, MemOperand(x0, 257));
7070 __ Prfm(op, MemOperand(x0, -1));
7071 __ Prfm(op, MemOperand(x0, -9));
7072 __ Prfm(op, MemOperand(x0, -255));
7073 __ Prfm(op, MemOperand(x0, -257));
7074
7075 __ Prfm(op, MemOperand(x0, 0xfedcba9876543210));
7076 }
7077
7078 END();
7079 RUN();
7080 TEARDOWN();
7081}
7082
7083
7084TEST(prfm_regoffset) {
7085 SETUP();
7086
7087 START();
7088 // The address used in prfm doesn't have to be valid.
7089 __ Mov(x0, 0x0123456789abcdef);
7090
7091 CPURegList inputs(CPURegister::kRegister, kXRegSize, 10, 18);
7092 __ Mov(x10, 0);
7093 __ Mov(x11, 1);
7094 __ Mov(x12, 8);
7095 __ Mov(x13, 255);
7096 __ Mov(x14, -0);
7097 __ Mov(x15, -1);
7098 __ Mov(x16, -8);
7099 __ Mov(x17, -255);
7100 __ Mov(x18, 0xfedcba9876543210);
7101
7102 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7103 // Unallocated prefetch operations are ignored, so test all of them.
7104 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7105
7106 CPURegList loop = inputs;
7107 while (!loop.IsEmpty()) {
7108 Register input(loop.PopLowestIndex());
7109 __ Prfm(op, MemOperand(x0, input));
7110 __ Prfm(op, MemOperand(x0, input, UXTW));
7111 __ Prfm(op, MemOperand(x0, input, UXTW, 3));
7112 __ Prfm(op, MemOperand(x0, input, LSL));
7113 __ Prfm(op, MemOperand(x0, input, LSL, 3));
7114 __ Prfm(op, MemOperand(x0, input, SXTW));
7115 __ Prfm(op, MemOperand(x0, input, SXTW, 3));
7116 __ Prfm(op, MemOperand(x0, input, SXTX));
7117 __ Prfm(op, MemOperand(x0, input, SXTX, 3));
7118 }
7119 }
7120
7121 END();
7122 RUN();
7123 TEARDOWN();
7124}
7125
7126
7127TEST(prfm_literal_imm19) {
7128 SETUP();
7129 ALLOW_ASM();
7130 START();
7131
7132 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7133 // Unallocated prefetch operations are ignored, so test all of them.
7134 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7135
7136 // The address used in prfm doesn't have to be valid.
7137 __ prfm(op, 0);
7138 __ prfm(op, 1);
7139 __ prfm(op, -1);
7140 __ prfm(op, 1000);
7141 __ prfm(op, -1000);
7142 __ prfm(op, 0x3ffff);
7143 __ prfm(op, -0x40000);
7144 }
7145
7146 END();
7147 RUN();
7148 TEARDOWN();
7149}
7150
7151
7152TEST(prfm_literal) {
7153 SETUP();
7154 ALLOW_ASM();
7155
7156 Label end_of_pool_before;
7157 Label end_of_pool_after;
7158 Literal<uint64_t> before(0);
7159 Literal<uint64_t> after(0);
7160
7161 START();
7162
7163 // Manually generate a pool.
7164 __ B(&end_of_pool_before);
7165 __ place(&before);
7166 __ Bind(&end_of_pool_before);
7167
7168 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7169 // Unallocated prefetch operations are ignored, so test all of them.
7170 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7171
7172 CodeBufferCheckScope guard(&masm, 2 * kInstructionSize);
7173 __ prfm(op, &before);
7174 __ prfm(op, &after);
7175 }
7176
7177 // Manually generate a pool.
7178 __ B(&end_of_pool_after);
7179 __ place(&after);
7180 __ Bind(&end_of_pool_after);
7181
7182 END();
7183 RUN();
7184 TEARDOWN();
7185}
7186
7187
7188TEST(prfm_wide) {
7189 SETUP();
7190
7191 START();
7192 // The address used in prfm doesn't have to be valid.
7193 __ Mov(x0, 0x0123456789abcdef);
7194
7195 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7196 // Unallocated prefetch operations are ignored, so test all of them.
7197 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7198
7199 __ Prfm(op, MemOperand(x0, 0x40000));
7200 __ Prfm(op, MemOperand(x0, -0x40001));
7201 __ Prfm(op, MemOperand(x0, UINT64_C(0x5555555555555555)));
7202 __ Prfm(op, MemOperand(x0, UINT64_C(0xfedcba9876543210)));
7203 }
7204
7205 END();
7206 RUN();
7207 TEARDOWN();
7208}
7209
7210
7211TEST(load_prfm_literal) {
7212 // Test literals shared between both prfm and ldr.
7213 SETUP();
7214 ALLOW_ASM();
7215
7216 Label end_of_pool_before;
7217 Label end_of_pool_after;
7218 Literal<uint64_t> before_x(0x1234567890abcdef);
7219 Literal<uint32_t> before_w(0xfedcba09);
7220 Literal<uint32_t> before_sx(0x80000000);
7221 Literal<double> before_d(1.234);
7222 Literal<float> before_s(2.5);
7223 Literal<uint64_t> after_x(0x1234567890abcdef);
7224 Literal<uint32_t> after_w(0xfedcba09);
7225 Literal<uint32_t> after_sx(0x80000000);
7226 Literal<double> after_d(1.234);
7227 Literal<float> after_s(2.5);
7228
7229 START();
7230
7231 // Manually generate a pool.
7232 __ B(&end_of_pool_before);
7233 __ place(&before_x);
7234 __ place(&before_w);
7235 __ place(&before_sx);
7236 __ place(&before_d);
7237 __ place(&before_s);
7238 __ Bind(&end_of_pool_before);
7239
7240 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7241 // Unallocated prefetch operations are ignored, so test all of them.
7242 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7243
7244 __ prfm(op, &before_x);
7245 __ prfm(op, &before_w);
7246 __ prfm(op, &before_sx);
7247 __ prfm(op, &before_d);
7248 __ prfm(op, &before_s);
7249
7250 __ prfm(op, &after_x);
7251 __ prfm(op, &after_w);
7252 __ prfm(op, &after_sx);
7253 __ prfm(op, &after_d);
7254 __ prfm(op, &after_s);
7255 }
7256
7257 __ ldr(x2, &before_x);
7258 __ ldr(w3, &before_w);
7259 __ ldrsw(x5, &before_sx);
7260 __ ldr(d13, &before_d);
7261 __ ldr(s25, &before_s);
7262
7263 __ ldr(x6, &after_x);
7264 __ ldr(w7, &after_w);
7265 __ ldrsw(x8, &after_sx);
7266 __ ldr(d14, &after_d);
7267 __ ldr(s26, &after_s);
7268
7269 // Manually generate a pool.
7270 __ B(&end_of_pool_after);
7271 __ place(&after_x);
7272 __ place(&after_w);
7273 __ place(&after_sx);
7274 __ place(&after_d);
7275 __ place(&after_s);
7276 __ Bind(&end_of_pool_after);
7277
7278 END();
7279
7280 RUN();
7281
7282 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
7283 ASSERT_EQUAL_64(0xfedcba09, x3);
7284 ASSERT_EQUAL_64(0xffffffff80000000, x5);
7285 ASSERT_EQUAL_FP64(1.234, d13);
7286 ASSERT_EQUAL_FP32(2.5, s25);
7287
7288 ASSERT_EQUAL_64(0x1234567890abcdef, x6);
7289 ASSERT_EQUAL_64(0xfedcba09, x7);
7290 ASSERT_EQUAL_64(0xffffffff80000000, x8);
7291 ASSERT_EQUAL_FP64(1.234, d14);
7292 ASSERT_EQUAL_FP32(2.5, s26);
7293
armvixlc68cb642014-09-25 18:49:30 +01007294 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +01007295}
7296
7297
7298TEST(add_sub_imm) {
7299 SETUP();
7300
7301 START();
7302 __ Mov(x0, 0x0);
7303 __ Mov(x1, 0x1111);
armvixlb0c8ae22014-03-21 14:03:59 +00007304 __ Mov(x2, 0xffffffffffffffff);
7305 __ Mov(x3, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01007306
7307 __ Add(x10, x0, Operand(0x123));
7308 __ Add(x11, x1, Operand(0x122000));
7309 __ Add(x12, x0, Operand(0xabc << 12));
7310 __ Add(x13, x2, Operand(1));
7311
7312 __ Add(w14, w0, Operand(0x123));
7313 __ Add(w15, w1, Operand(0x122000));
7314 __ Add(w16, w0, Operand(0xabc << 12));
7315 __ Add(w17, w2, Operand(1));
7316
7317 __ Sub(x20, x0, Operand(0x1));
7318 __ Sub(x21, x1, Operand(0x111));
7319 __ Sub(x22, x1, Operand(0x1 << 12));
7320 __ Sub(x23, x3, Operand(1));
7321
7322 __ Sub(w24, w0, Operand(0x1));
7323 __ Sub(w25, w1, Operand(0x111));
7324 __ Sub(w26, w1, Operand(0x1 << 12));
7325 __ Sub(w27, w3, Operand(1));
7326 END();
7327
7328 RUN();
7329
7330 ASSERT_EQUAL_64(0x123, x10);
7331 ASSERT_EQUAL_64(0x123111, x11);
7332 ASSERT_EQUAL_64(0xabc000, x12);
7333 ASSERT_EQUAL_64(0x0, x13);
7334
7335 ASSERT_EQUAL_32(0x123, w14);
7336 ASSERT_EQUAL_32(0x123111, w15);
7337 ASSERT_EQUAL_32(0xabc000, w16);
7338 ASSERT_EQUAL_32(0x0, w17);
7339
armvixlb0c8ae22014-03-21 14:03:59 +00007340 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlad96eda2013-06-14 11:42:37 +01007341 ASSERT_EQUAL_64(0x1000, x21);
7342 ASSERT_EQUAL_64(0x111, x22);
armvixlb0c8ae22014-03-21 14:03:59 +00007343 ASSERT_EQUAL_64(0x7fffffffffffffff, x23);
armvixlad96eda2013-06-14 11:42:37 +01007344
7345 ASSERT_EQUAL_32(0xffffffff, w24);
7346 ASSERT_EQUAL_32(0x1000, w25);
7347 ASSERT_EQUAL_32(0x111, w26);
7348 ASSERT_EQUAL_32(0xffffffff, w27);
7349
7350 TEARDOWN();
7351}
7352
7353
7354TEST(add_sub_wide_imm) {
7355 SETUP();
7356
7357 START();
7358 __ Mov(x0, 0x0);
7359 __ Mov(x1, 0x1);
7360
armvixlb0c8ae22014-03-21 14:03:59 +00007361 __ Add(x10, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01007362 __ Add(x11, x1, Operand(0xffffffff));
7363
7364 __ Add(w12, w0, Operand(0x12345678));
7365 __ Add(w13, w1, Operand(0xffffffff));
7366
armvixl4a102ba2014-07-14 09:02:40 +01007367 __ Add(w18, w0, Operand(kWMinInt));
7368 __ Sub(w19, w0, Operand(kWMinInt));
armvixlad96eda2013-06-14 11:42:37 +01007369
armvixl4a102ba2014-07-14 09:02:40 +01007370 __ Sub(x20, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01007371 __ Sub(w21, w0, Operand(0x12345678));
armvixl4a102ba2014-07-14 09:02:40 +01007372
armvixlad96eda2013-06-14 11:42:37 +01007373 END();
7374
7375 RUN();
7376
armvixlb0c8ae22014-03-21 14:03:59 +00007377 ASSERT_EQUAL_64(0x1234567890abcdef, x10);
7378 ASSERT_EQUAL_64(0x100000000, x11);
armvixlad96eda2013-06-14 11:42:37 +01007379
7380 ASSERT_EQUAL_32(0x12345678, w12);
7381 ASSERT_EQUAL_64(0x0, x13);
7382
armvixl4a102ba2014-07-14 09:02:40 +01007383 ASSERT_EQUAL_32(kWMinInt, w18);
7384 ASSERT_EQUAL_32(kWMinInt, w19);
armvixlad96eda2013-06-14 11:42:37 +01007385
armvixl4a102ba2014-07-14 09:02:40 +01007386 ASSERT_EQUAL_64(-0x1234567890abcdef, x20);
armvixlad96eda2013-06-14 11:42:37 +01007387 ASSERT_EQUAL_32(-0x12345678, w21);
7388
7389 TEARDOWN();
7390}
7391
7392
7393TEST(add_sub_shifted) {
7394 SETUP();
7395
7396 START();
7397 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00007398 __ Mov(x1, 0x0123456789abcdef);
7399 __ Mov(x2, 0xfedcba9876543210);
7400 __ Mov(x3, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007401
7402 __ Add(x10, x1, Operand(x2));
7403 __ Add(x11, x0, Operand(x1, LSL, 8));
7404 __ Add(x12, x0, Operand(x1, LSR, 8));
7405 __ Add(x13, x0, Operand(x1, ASR, 8));
7406 __ Add(x14, x0, Operand(x2, ASR, 8));
7407 __ Add(w15, w0, Operand(w1, ASR, 8));
7408 __ Add(w18, w3, Operand(w1, ROR, 8));
7409 __ Add(x19, x3, Operand(x1, ROR, 8));
7410
7411 __ Sub(x20, x3, Operand(x2));
7412 __ Sub(x21, x3, Operand(x1, LSL, 8));
7413 __ Sub(x22, x3, Operand(x1, LSR, 8));
7414 __ Sub(x23, x3, Operand(x1, ASR, 8));
7415 __ Sub(x24, x3, Operand(x2, ASR, 8));
7416 __ Sub(w25, w3, Operand(w1, ASR, 8));
7417 __ Sub(w26, w3, Operand(w1, ROR, 8));
7418 __ Sub(x27, x3, Operand(x1, ROR, 8));
7419 END();
7420
7421 RUN();
7422
armvixlb0c8ae22014-03-21 14:03:59 +00007423 ASSERT_EQUAL_64(0xffffffffffffffff, x10);
7424 ASSERT_EQUAL_64(0x23456789abcdef00, x11);
7425 ASSERT_EQUAL_64(0x000123456789abcd, x12);
7426 ASSERT_EQUAL_64(0x000123456789abcd, x13);
7427 ASSERT_EQUAL_64(0xfffedcba98765432, x14);
armvixlad96eda2013-06-14 11:42:37 +01007428 ASSERT_EQUAL_64(0xff89abcd, x15);
7429 ASSERT_EQUAL_64(0xef89abcc, x18);
armvixlb0c8ae22014-03-21 14:03:59 +00007430 ASSERT_EQUAL_64(0xef0123456789abcc, x19);
armvixlad96eda2013-06-14 11:42:37 +01007431
armvixlb0c8ae22014-03-21 14:03:59 +00007432 ASSERT_EQUAL_64(0x0123456789abcdef, x20);
7433 ASSERT_EQUAL_64(0xdcba9876543210ff, x21);
7434 ASSERT_EQUAL_64(0xfffedcba98765432, x22);
7435 ASSERT_EQUAL_64(0xfffedcba98765432, x23);
7436 ASSERT_EQUAL_64(0x000123456789abcd, x24);
armvixlad96eda2013-06-14 11:42:37 +01007437 ASSERT_EQUAL_64(0x00765432, x25);
7438 ASSERT_EQUAL_64(0x10765432, x26);
armvixlb0c8ae22014-03-21 14:03:59 +00007439 ASSERT_EQUAL_64(0x10fedcba98765432, x27);
armvixlad96eda2013-06-14 11:42:37 +01007440
7441 TEARDOWN();
7442}
7443
7444
7445TEST(add_sub_extended) {
7446 SETUP();
7447
7448 START();
7449 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00007450 __ Mov(x1, 0x0123456789abcdef);
7451 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01007452 __ Mov(w3, 0x80);
7453
7454 __ Add(x10, x0, Operand(x1, UXTB, 0));
7455 __ Add(x11, x0, Operand(x1, UXTB, 1));
7456 __ Add(x12, x0, Operand(x1, UXTH, 2));
7457 __ Add(x13, x0, Operand(x1, UXTW, 4));
7458
7459 __ Add(x14, x0, Operand(x1, SXTB, 0));
7460 __ Add(x15, x0, Operand(x1, SXTB, 1));
7461 __ Add(x16, x0, Operand(x1, SXTH, 2));
7462 __ Add(x17, x0, Operand(x1, SXTW, 3));
7463 __ Add(x18, x0, Operand(x2, SXTB, 0));
7464 __ Add(x19, x0, Operand(x2, SXTB, 1));
7465 __ Add(x20, x0, Operand(x2, SXTH, 2));
7466 __ Add(x21, x0, Operand(x2, SXTW, 3));
7467
7468 __ Add(x22, x1, Operand(x2, SXTB, 1));
7469 __ Sub(x23, x1, Operand(x2, SXTB, 1));
7470
7471 __ Add(w24, w1, Operand(w2, UXTB, 2));
7472 __ Add(w25, w0, Operand(w1, SXTB, 0));
7473 __ Add(w26, w0, Operand(w1, SXTB, 1));
7474 __ Add(w27, w2, Operand(w1, SXTW, 3));
7475
7476 __ Add(w28, w0, Operand(w1, SXTW, 3));
7477 __ Add(x29, x0, Operand(w1, SXTW, 3));
7478
7479 __ Sub(x30, x0, Operand(w3, SXTB, 1));
7480 END();
7481
7482 RUN();
7483
armvixlb0c8ae22014-03-21 14:03:59 +00007484 ASSERT_EQUAL_64(0xef, x10);
7485 ASSERT_EQUAL_64(0x1de, x11);
7486 ASSERT_EQUAL_64(0x337bc, x12);
7487 ASSERT_EQUAL_64(0x89abcdef0, x13);
armvixlad96eda2013-06-14 11:42:37 +01007488
armvixlb0c8ae22014-03-21 14:03:59 +00007489 ASSERT_EQUAL_64(0xffffffffffffffef, x14);
7490 ASSERT_EQUAL_64(0xffffffffffffffde, x15);
7491 ASSERT_EQUAL_64(0xffffffffffff37bc, x16);
7492 ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x17);
7493 ASSERT_EQUAL_64(0x10, x18);
7494 ASSERT_EQUAL_64(0x20, x19);
7495 ASSERT_EQUAL_64(0xc840, x20);
7496 ASSERT_EQUAL_64(0x3b2a19080, x21);
armvixlad96eda2013-06-14 11:42:37 +01007497
armvixlb0c8ae22014-03-21 14:03:59 +00007498 ASSERT_EQUAL_64(0x0123456789abce0f, x22);
7499 ASSERT_EQUAL_64(0x0123456789abcdcf, x23);
armvixlad96eda2013-06-14 11:42:37 +01007500
7501 ASSERT_EQUAL_32(0x89abce2f, w24);
7502 ASSERT_EQUAL_32(0xffffffef, w25);
7503 ASSERT_EQUAL_32(0xffffffde, w26);
7504 ASSERT_EQUAL_32(0xc3b2a188, w27);
7505
7506 ASSERT_EQUAL_32(0x4d5e6f78, w28);
armvixlb0c8ae22014-03-21 14:03:59 +00007507 ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x29);
armvixlad96eda2013-06-14 11:42:37 +01007508
7509 ASSERT_EQUAL_64(256, x30);
7510
7511 TEARDOWN();
7512}
7513
7514
7515TEST(add_sub_negative) {
7516 SETUP();
7517
7518 START();
7519 __ Mov(x0, 0);
7520 __ Mov(x1, 4687);
7521 __ Mov(x2, 0x1122334455667788);
7522 __ Mov(w3, 0x11223344);
7523 __ Mov(w4, 400000);
7524
7525 __ Add(x10, x0, -42);
7526 __ Add(x11, x1, -687);
7527 __ Add(x12, x2, -0x88);
7528
7529 __ Sub(x13, x0, -600);
7530 __ Sub(x14, x1, -313);
7531 __ Sub(x15, x2, -0x555);
7532
7533 __ Add(w19, w3, -0x344);
7534 __ Add(w20, w4, -2000);
7535
7536 __ Sub(w21, w3, -0xbc);
7537 __ Sub(w22, w4, -2000);
7538 END();
7539
7540 RUN();
7541
7542 ASSERT_EQUAL_64(-42, x10);
7543 ASSERT_EQUAL_64(4000, x11);
7544 ASSERT_EQUAL_64(0x1122334455667700, x12);
7545
7546 ASSERT_EQUAL_64(600, x13);
7547 ASSERT_EQUAL_64(5000, x14);
7548 ASSERT_EQUAL_64(0x1122334455667cdd, x15);
7549
7550 ASSERT_EQUAL_32(0x11223000, w19);
7551 ASSERT_EQUAL_32(398000, w20);
7552
7553 ASSERT_EQUAL_32(0x11223400, w21);
7554 ASSERT_EQUAL_32(402000, w22);
7555
7556 TEARDOWN();
7557}
7558
7559
armvixlf37fdc02014-02-05 13:22:16 +00007560TEST(add_sub_zero) {
7561 SETUP();
7562
7563 START();
7564 __ Mov(x0, 0);
7565 __ Mov(x1, 0);
7566 __ Mov(x2, 0);
7567
7568 Label blob1;
7569 __ Bind(&blob1);
7570 __ Add(x0, x0, 0);
7571 __ Sub(x1, x1, 0);
7572 __ Sub(x2, x2, xzr);
armvixlb0c8ae22014-03-21 14:03:59 +00007573 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob1) == 0);
armvixlf37fdc02014-02-05 13:22:16 +00007574
7575 Label blob2;
7576 __ Bind(&blob2);
7577 __ Add(w3, w3, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00007578 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob2) != 0);
armvixlf37fdc02014-02-05 13:22:16 +00007579
7580 Label blob3;
7581 __ Bind(&blob3);
7582 __ Sub(w3, w3, wzr);
armvixlb0c8ae22014-03-21 14:03:59 +00007583 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob3) != 0);
armvixlf37fdc02014-02-05 13:22:16 +00007584
7585 END();
7586
7587 RUN();
7588
7589 ASSERT_EQUAL_64(0, x0);
7590 ASSERT_EQUAL_64(0, x1);
7591 ASSERT_EQUAL_64(0, x2);
7592
7593 TEARDOWN();
7594}
7595
7596
7597TEST(claim_drop_zero) {
7598 SETUP();
7599
7600 START();
7601
7602 Label start;
7603 __ Bind(&start);
7604 __ Claim(Operand(0));
7605 __ Drop(Operand(0));
7606 __ Claim(Operand(xzr));
7607 __ Drop(Operand(xzr));
armvixlb0c8ae22014-03-21 14:03:59 +00007608 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlf37fdc02014-02-05 13:22:16 +00007609
7610 END();
7611
7612 RUN();
7613
7614 TEARDOWN();
7615}
7616
7617
armvixlad96eda2013-06-14 11:42:37 +01007618TEST(neg) {
7619 SETUP();
7620
7621 START();
armvixlb0c8ae22014-03-21 14:03:59 +00007622 __ Mov(x0, 0xf123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01007623
7624 // Immediate.
7625 __ Neg(x1, 0x123);
7626 __ Neg(w2, 0x123);
7627
7628 // Shifted.
7629 __ Neg(x3, Operand(x0, LSL, 1));
7630 __ Neg(w4, Operand(w0, LSL, 2));
7631 __ Neg(x5, Operand(x0, LSR, 3));
7632 __ Neg(w6, Operand(w0, LSR, 4));
7633 __ Neg(x7, Operand(x0, ASR, 5));
7634 __ Neg(w8, Operand(w0, ASR, 6));
7635
7636 // Extended.
7637 __ Neg(w9, Operand(w0, UXTB));
7638 __ Neg(x10, Operand(x0, SXTB, 1));
7639 __ Neg(w11, Operand(w0, UXTH, 2));
7640 __ Neg(x12, Operand(x0, SXTH, 3));
7641 __ Neg(w13, Operand(w0, UXTW, 4));
7642 __ Neg(x14, Operand(x0, SXTW, 4));
7643 END();
7644
7645 RUN();
7646
armvixlb0c8ae22014-03-21 14:03:59 +00007647 ASSERT_EQUAL_64(0xfffffffffffffedd, x1);
armvixlad96eda2013-06-14 11:42:37 +01007648 ASSERT_EQUAL_64(0xfffffedd, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00007649 ASSERT_EQUAL_64(0x1db97530eca86422, x3);
armvixlad96eda2013-06-14 11:42:37 +01007650 ASSERT_EQUAL_64(0xd950c844, x4);
armvixlb0c8ae22014-03-21 14:03:59 +00007651 ASSERT_EQUAL_64(0xe1db97530eca8643, x5);
armvixlad96eda2013-06-14 11:42:37 +01007652 ASSERT_EQUAL_64(0xf7654322, x6);
armvixlb0c8ae22014-03-21 14:03:59 +00007653 ASSERT_EQUAL_64(0x0076e5d4c3b2a191, x7);
armvixlad96eda2013-06-14 11:42:37 +01007654 ASSERT_EQUAL_64(0x01d950c9, x8);
7655 ASSERT_EQUAL_64(0xffffff11, x9);
armvixlb0c8ae22014-03-21 14:03:59 +00007656 ASSERT_EQUAL_64(0x0000000000000022, x10);
armvixlad96eda2013-06-14 11:42:37 +01007657 ASSERT_EQUAL_64(0xfffcc844, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00007658 ASSERT_EQUAL_64(0x0000000000019088, x12);
armvixlad96eda2013-06-14 11:42:37 +01007659 ASSERT_EQUAL_64(0x65432110, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00007660 ASSERT_EQUAL_64(0x0000000765432110, x14);
armvixlad96eda2013-06-14 11:42:37 +01007661
7662 TEARDOWN();
7663}
7664
7665
7666TEST(adc_sbc_shift) {
7667 SETUP();
7668
7669 START();
7670 __ Mov(x0, 0);
7671 __ Mov(x1, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00007672 __ Mov(x2, 0x0123456789abcdef);
7673 __ Mov(x3, 0xfedcba9876543210);
7674 __ Mov(x4, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007675
7676 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007677 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01007678
7679 __ Adc(x5, x2, Operand(x3));
7680 __ Adc(x6, x0, Operand(x1, LSL, 60));
7681 __ Sbc(x7, x4, Operand(x3, LSR, 4));
7682 __ Adc(x8, x2, Operand(x3, ASR, 4));
7683 __ Adc(x9, x2, Operand(x3, ROR, 8));
7684
7685 __ Adc(w10, w2, Operand(w3));
7686 __ Adc(w11, w0, Operand(w1, LSL, 30));
7687 __ Sbc(w12, w4, Operand(w3, LSR, 4));
7688 __ Adc(w13, w2, Operand(w3, ASR, 4));
7689 __ Adc(w14, w2, Operand(w3, ROR, 8));
7690
7691 // Set the C flag.
7692 __ Cmp(w0, Operand(w0));
7693
7694 __ Adc(x18, x2, Operand(x3));
7695 __ Adc(x19, x0, Operand(x1, LSL, 60));
7696 __ Sbc(x20, x4, Operand(x3, LSR, 4));
7697 __ Adc(x21, x2, Operand(x3, ASR, 4));
7698 __ Adc(x22, x2, Operand(x3, ROR, 8));
7699
7700 __ Adc(w23, w2, Operand(w3));
7701 __ Adc(w24, w0, Operand(w1, LSL, 30));
7702 __ Sbc(w25, w4, Operand(w3, LSR, 4));
7703 __ Adc(w26, w2, Operand(w3, ASR, 4));
7704 __ Adc(w27, w2, Operand(w3, ROR, 8));
7705 END();
7706
7707 RUN();
7708
armvixlb0c8ae22014-03-21 14:03:59 +00007709 ASSERT_EQUAL_64(0xffffffffffffffff, x5);
7710 ASSERT_EQUAL_64(INT64_C(1) << 60, x6);
7711 ASSERT_EQUAL_64(0xf0123456789abcdd, x7);
7712 ASSERT_EQUAL_64(0x0111111111111110, x8);
7713 ASSERT_EQUAL_64(0x1222222222222221, x9);
armvixlad96eda2013-06-14 11:42:37 +01007714
7715 ASSERT_EQUAL_32(0xffffffff, w10);
armvixlb0c8ae22014-03-21 14:03:59 +00007716 ASSERT_EQUAL_32(INT32_C(1) << 30, w11);
armvixlad96eda2013-06-14 11:42:37 +01007717 ASSERT_EQUAL_32(0xf89abcdd, w12);
7718 ASSERT_EQUAL_32(0x91111110, w13);
7719 ASSERT_EQUAL_32(0x9a222221, w14);
7720
armvixlb0c8ae22014-03-21 14:03:59 +00007721 ASSERT_EQUAL_64(0xffffffffffffffff + 1, x18);
7722 ASSERT_EQUAL_64((INT64_C(1) << 60) + 1, x19);
7723 ASSERT_EQUAL_64(0xf0123456789abcdd + 1, x20);
7724 ASSERT_EQUAL_64(0x0111111111111110 + 1, x21);
7725 ASSERT_EQUAL_64(0x1222222222222221 + 1, x22);
armvixlad96eda2013-06-14 11:42:37 +01007726
7727 ASSERT_EQUAL_32(0xffffffff + 1, w23);
armvixlb0c8ae22014-03-21 14:03:59 +00007728 ASSERT_EQUAL_32((INT32_C(1) << 30) + 1, w24);
armvixlad96eda2013-06-14 11:42:37 +01007729 ASSERT_EQUAL_32(0xf89abcdd + 1, w25);
7730 ASSERT_EQUAL_32(0x91111110 + 1, w26);
7731 ASSERT_EQUAL_32(0x9a222221 + 1, w27);
7732
7733 // Check that adc correctly sets the condition flags.
7734 START();
7735 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00007736 __ Mov(x1, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007737 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007738 __ Adds(x0, x0, Operand(0));
7739 __ Adcs(x10, x0, Operand(x1));
armvixlad96eda2013-06-14 11:42:37 +01007740 END();
7741
7742 RUN();
7743
7744 ASSERT_EQUAL_NZCV(ZCFlag);
armvixlf37fdc02014-02-05 13:22:16 +00007745 ASSERT_EQUAL_64(0, x10);
armvixlad96eda2013-06-14 11:42:37 +01007746
7747 START();
7748 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00007749 __ Mov(x1, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01007750 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007751 __ Adds(x0, x0, Operand(0));
7752 __ Adcs(x10, x0, Operand(x1, ASR, 63));
armvixlad96eda2013-06-14 11:42:37 +01007753 END();
7754
7755 RUN();
7756
7757 ASSERT_EQUAL_NZCV(ZCFlag);
armvixlf37fdc02014-02-05 13:22:16 +00007758 ASSERT_EQUAL_64(0, x10);
armvixlad96eda2013-06-14 11:42:37 +01007759
7760 START();
7761 __ Mov(x0, 0x10);
armvixlb0c8ae22014-03-21 14:03:59 +00007762 __ Mov(x1, 0x07ffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007763 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007764 __ Adds(x0, x0, Operand(0));
7765 __ Adcs(x10, x0, Operand(x1, LSL, 4));
armvixlad96eda2013-06-14 11:42:37 +01007766 END();
7767
7768 RUN();
7769
7770 ASSERT_EQUAL_NZCV(NVFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00007771 ASSERT_EQUAL_64(0x8000000000000000, x10);
armvixlf37fdc02014-02-05 13:22:16 +00007772
7773 // Check that sbc correctly sets the condition flags.
7774 START();
7775 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00007776 __ Mov(x1, 0xffffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00007777 // Clear the C flag.
7778 __ Adds(x0, x0, Operand(0));
7779 __ Sbcs(x10, x0, Operand(x1));
7780 END();
7781
7782 RUN();
7783
7784 ASSERT_EQUAL_NZCV(ZFlag);
7785 ASSERT_EQUAL_64(0, x10);
7786
7787 START();
7788 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00007789 __ Mov(x1, 0xffffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00007790 // Clear the C flag.
7791 __ Adds(x0, x0, Operand(0));
7792 __ Sbcs(x10, x0, Operand(x1, LSR, 1));
7793 END();
7794
7795 RUN();
7796
7797 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00007798 ASSERT_EQUAL_64(0x8000000000000001, x10);
armvixlf37fdc02014-02-05 13:22:16 +00007799
7800 START();
7801 __ Mov(x0, 0);
7802 // Clear the C flag.
7803 __ Adds(x0, x0, Operand(0));
armvixlb0c8ae22014-03-21 14:03:59 +00007804 __ Sbcs(x10, x0, Operand(0xffffffffffffffff));
armvixlf37fdc02014-02-05 13:22:16 +00007805 END();
7806
7807 RUN();
7808
7809 ASSERT_EQUAL_NZCV(ZFlag);
7810 ASSERT_EQUAL_64(0, x10);
7811
armvixlb0c8ae22014-03-21 14:03:59 +00007812 START();
armvixlf37fdc02014-02-05 13:22:16 +00007813 __ Mov(w0, 0x7fffffff);
7814 // Clear the C flag.
7815 __ Adds(x0, x0, Operand(0));
7816 __ Ngcs(w10, w0);
7817 END();
7818
7819 RUN();
7820
7821 ASSERT_EQUAL_NZCV(NFlag);
7822 ASSERT_EQUAL_64(0x80000000, x10);
7823
7824 START();
7825 // Clear the C flag.
7826 __ Adds(x0, x0, Operand(0));
armvixlb0c8ae22014-03-21 14:03:59 +00007827 __ Ngcs(x10, 0x7fffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00007828 END();
7829
7830 RUN();
7831
7832 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00007833 ASSERT_EQUAL_64(0x8000000000000000, x10);
armvixlf37fdc02014-02-05 13:22:16 +00007834
armvixlb0c8ae22014-03-21 14:03:59 +00007835 START();
armvixlf37fdc02014-02-05 13:22:16 +00007836 __ Mov(x0, 0);
7837 // Set the C flag.
7838 __ Cmp(x0, Operand(x0));
7839 __ Sbcs(x10, x0, Operand(1));
7840 END();
7841
7842 RUN();
7843
7844 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00007845 ASSERT_EQUAL_64(0xffffffffffffffff, x10);
armvixlf37fdc02014-02-05 13:22:16 +00007846
armvixlb0c8ae22014-03-21 14:03:59 +00007847 START();
armvixlf37fdc02014-02-05 13:22:16 +00007848 __ Mov(x0, 0);
7849 // Set the C flag.
7850 __ Cmp(x0, Operand(x0));
armvixlb0c8ae22014-03-21 14:03:59 +00007851 __ Ngcs(x10, 0x7fffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00007852 END();
7853
7854 RUN();
7855
7856 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00007857 ASSERT_EQUAL_64(0x8000000000000001, x10);
armvixlad96eda2013-06-14 11:42:37 +01007858
7859 TEARDOWN();
7860}
7861
7862
7863TEST(adc_sbc_extend) {
7864 SETUP();
7865
7866 START();
7867 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007868 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01007869
7870 __ Mov(x0, 0);
7871 __ Mov(x1, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00007872 __ Mov(x2, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01007873
7874 __ Adc(x10, x1, Operand(w2, UXTB, 1));
7875 __ Adc(x11, x1, Operand(x2, SXTH, 2));
7876 __ Sbc(x12, x1, Operand(w2, UXTW, 4));
7877 __ Adc(x13, x1, Operand(x2, UXTX, 4));
7878
7879 __ Adc(w14, w1, Operand(w2, UXTB, 1));
7880 __ Adc(w15, w1, Operand(w2, SXTH, 2));
7881 __ Adc(w9, w1, Operand(w2, UXTW, 4));
7882
7883 // Set the C flag.
7884 __ Cmp(w0, Operand(w0));
7885
7886 __ Adc(x20, x1, Operand(w2, UXTB, 1));
7887 __ Adc(x21, x1, Operand(x2, SXTH, 2));
7888 __ Sbc(x22, x1, Operand(w2, UXTW, 4));
7889 __ Adc(x23, x1, Operand(x2, UXTX, 4));
7890
7891 __ Adc(w24, w1, Operand(w2, UXTB, 1));
7892 __ Adc(w25, w1, Operand(w2, SXTH, 2));
7893 __ Adc(w26, w1, Operand(w2, UXTW, 4));
7894 END();
7895
7896 RUN();
7897
7898 ASSERT_EQUAL_64(0x1df, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00007899 ASSERT_EQUAL_64(0xffffffffffff37bd, x11);
7900 ASSERT_EQUAL_64(0xfffffff765432110, x12);
7901 ASSERT_EQUAL_64(0x123456789abcdef1, x13);
armvixlad96eda2013-06-14 11:42:37 +01007902
7903 ASSERT_EQUAL_32(0x1df, w14);
7904 ASSERT_EQUAL_32(0xffff37bd, w15);
7905 ASSERT_EQUAL_32(0x9abcdef1, w9);
7906
7907 ASSERT_EQUAL_64(0x1df + 1, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00007908 ASSERT_EQUAL_64(0xffffffffffff37bd + 1, x21);
7909 ASSERT_EQUAL_64(0xfffffff765432110 + 1, x22);
7910 ASSERT_EQUAL_64(0x123456789abcdef1 + 1, x23);
armvixlad96eda2013-06-14 11:42:37 +01007911
7912 ASSERT_EQUAL_32(0x1df + 1, w24);
7913 ASSERT_EQUAL_32(0xffff37bd + 1, w25);
7914 ASSERT_EQUAL_32(0x9abcdef1 + 1, w26);
7915
7916 // Check that adc correctly sets the condition flags.
7917 START();
7918 __ Mov(x0, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00007919 __ Mov(x1, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007920 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007921 __ Adds(x0, x0, Operand(0));
7922 __ Adcs(x10, x0, Operand(x1, SXTX, 1));
armvixlad96eda2013-06-14 11:42:37 +01007923 END();
7924
7925 RUN();
7926
7927 ASSERT_EQUAL_NZCV(CFlag);
7928
7929 START();
armvixlb0c8ae22014-03-21 14:03:59 +00007930 __ Mov(x0, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007931 __ Mov(x1, 1);
7932 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007933 __ Adds(x0, x0, Operand(0));
7934 __ Adcs(x10, x0, Operand(x1, UXTB, 2));
armvixlad96eda2013-06-14 11:42:37 +01007935 END();
7936
7937 RUN();
7938
7939 ASSERT_EQUAL_NZCV(NVFlag);
7940
7941 START();
armvixlb0c8ae22014-03-21 14:03:59 +00007942 __ Mov(x0, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007943 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007944 __ Adds(x0, x0, Operand(0));
7945 __ Adcs(x10, x0, Operand(1));
armvixlad96eda2013-06-14 11:42:37 +01007946 END();
7947
7948 RUN();
7949
7950 ASSERT_EQUAL_NZCV(NVFlag);
7951
7952 TEARDOWN();
7953}
7954
7955
7956TEST(adc_sbc_wide_imm) {
7957 SETUP();
7958
7959 START();
7960 __ Mov(x0, 0);
7961
7962 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007963 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01007964
armvixlb0c8ae22014-03-21 14:03:59 +00007965 __ Adc(x7, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01007966 __ Adc(w8, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00007967 __ Sbc(x9, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00007968 __ Sbc(w10, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00007969 __ Ngc(x11, Operand(0xffffffff00000000));
armvixlf37fdc02014-02-05 13:22:16 +00007970 __ Ngc(w12, Operand(0xffff0000));
armvixlad96eda2013-06-14 11:42:37 +01007971
7972 // Set the C flag.
7973 __ Cmp(w0, Operand(w0));
7974
armvixlb0c8ae22014-03-21 14:03:59 +00007975 __ Adc(x18, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00007976 __ Adc(w19, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00007977 __ Sbc(x20, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00007978 __ Sbc(w21, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00007979 __ Ngc(x22, Operand(0xffffffff00000000));
armvixlf37fdc02014-02-05 13:22:16 +00007980 __ Ngc(w23, Operand(0xffff0000));
armvixlad96eda2013-06-14 11:42:37 +01007981 END();
7982
7983 RUN();
7984
armvixlb0c8ae22014-03-21 14:03:59 +00007985 ASSERT_EQUAL_64(0x1234567890abcdef, x7);
armvixlad96eda2013-06-14 11:42:37 +01007986 ASSERT_EQUAL_64(0xffffffff, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00007987 ASSERT_EQUAL_64(0xedcba9876f543210, x9);
armvixlf37fdc02014-02-05 13:22:16 +00007988 ASSERT_EQUAL_64(0, x10);
7989 ASSERT_EQUAL_64(0xffffffff, x11);
7990 ASSERT_EQUAL_64(0xffff, x12);
7991
armvixlb0c8ae22014-03-21 14:03:59 +00007992 ASSERT_EQUAL_64(0x1234567890abcdef + 1, x18);
armvixlf37fdc02014-02-05 13:22:16 +00007993 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +00007994 ASSERT_EQUAL_64(0xedcba9876f543211, x20);
armvixlf37fdc02014-02-05 13:22:16 +00007995 ASSERT_EQUAL_64(1, x21);
armvixlb0c8ae22014-03-21 14:03:59 +00007996 ASSERT_EQUAL_64(0x0000000100000000, x22);
7997 ASSERT_EQUAL_64(0x0000000000010000, x23);
armvixlad96eda2013-06-14 11:42:37 +01007998
7999 TEARDOWN();
8000}
8001
8002TEST(flags) {
8003 SETUP();
8004
8005 START();
8006 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00008007 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01008008 __ Neg(x10, Operand(x0));
8009 __ Neg(x11, Operand(x1));
8010 __ Neg(w12, Operand(w1));
8011 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008012 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01008013 __ Ngc(x13, Operand(x0));
8014 // Set the C flag.
8015 __ Cmp(x0, Operand(x0));
8016 __ Ngc(w14, Operand(w0));
8017 END();
8018
8019 RUN();
8020
8021 ASSERT_EQUAL_64(0, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00008022 ASSERT_EQUAL_64(-0x1111111111111111, x11);
armvixlad96eda2013-06-14 11:42:37 +01008023 ASSERT_EQUAL_32(-0x11111111, w12);
armvixlb0c8ae22014-03-21 14:03:59 +00008024 ASSERT_EQUAL_64(-1, x13);
armvixlad96eda2013-06-14 11:42:37 +01008025 ASSERT_EQUAL_32(0, w14);
8026
8027 START();
8028 __ Mov(x0, 0);
8029 __ Cmp(x0, Operand(x0));
8030 END();
8031
8032 RUN();
8033
8034 ASSERT_EQUAL_NZCV(ZCFlag);
8035
8036 START();
8037 __ Mov(w0, 0);
8038 __ Cmp(w0, Operand(w0));
8039 END();
8040
8041 RUN();
8042
8043 ASSERT_EQUAL_NZCV(ZCFlag);
8044
8045 START();
8046 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00008047 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01008048 __ Cmp(x0, Operand(x1));
8049 END();
8050
8051 RUN();
8052
8053 ASSERT_EQUAL_NZCV(NFlag);
8054
8055 START();
8056 __ Mov(w0, 0);
8057 __ Mov(w1, 0x11111111);
8058 __ Cmp(w0, Operand(w1));
8059 END();
8060
8061 RUN();
8062
8063 ASSERT_EQUAL_NZCV(NFlag);
8064
8065 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008066 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01008067 __ Cmp(x1, Operand(0));
8068 END();
8069
8070 RUN();
8071
8072 ASSERT_EQUAL_NZCV(CFlag);
8073
8074 START();
8075 __ Mov(w1, 0x11111111);
8076 __ Cmp(w1, Operand(0));
8077 END();
8078
8079 RUN();
8080
8081 ASSERT_EQUAL_NZCV(CFlag);
8082
8083 START();
8084 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00008085 __ Mov(x1, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008086 __ Cmn(x1, Operand(x0));
8087 END();
8088
8089 RUN();
8090
8091 ASSERT_EQUAL_NZCV(NVFlag);
8092
8093 START();
8094 __ Mov(w0, 1);
8095 __ Mov(w1, 0x7fffffff);
8096 __ Cmn(w1, Operand(w0));
8097 END();
8098
8099 RUN();
8100
8101 ASSERT_EQUAL_NZCV(NVFlag);
8102
8103 START();
8104 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00008105 __ Mov(x1, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008106 __ Cmn(x1, Operand(x0));
8107 END();
8108
8109 RUN();
8110
8111 ASSERT_EQUAL_NZCV(ZCFlag);
8112
8113 START();
8114 __ Mov(w0, 1);
8115 __ Mov(w1, 0xffffffff);
8116 __ Cmn(w1, Operand(w0));
8117 END();
8118
8119 RUN();
8120
8121 ASSERT_EQUAL_NZCV(ZCFlag);
8122
8123 START();
8124 __ Mov(w0, 0);
8125 __ Mov(w1, 1);
8126 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008127 __ Adds(w0, w0, Operand(0));
8128 __ Ngcs(w0, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +01008129 END();
8130
8131 RUN();
8132
8133 ASSERT_EQUAL_NZCV(NFlag);
8134
8135 START();
8136 __ Mov(w0, 0);
8137 __ Mov(w1, 0);
8138 // Set the C flag.
8139 __ Cmp(w0, Operand(w0));
armvixlf37fdc02014-02-05 13:22:16 +00008140 __ Ngcs(w0, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +01008141 END();
8142
8143 RUN();
8144
8145 ASSERT_EQUAL_NZCV(ZCFlag);
8146
8147 TEARDOWN();
8148}
8149
8150
8151TEST(cmp_shift) {
8152 SETUP();
8153
8154 START();
8155 __ Mov(x18, 0xf0000000);
armvixlb0c8ae22014-03-21 14:03:59 +00008156 __ Mov(x19, 0xf000000010000000);
8157 __ Mov(x20, 0xf0000000f0000000);
8158 __ Mov(x21, 0x7800000078000000);
8159 __ Mov(x22, 0x3c0000003c000000);
8160 __ Mov(x23, 0x8000000780000000);
8161 __ Mov(x24, 0x0000000f00000000);
8162 __ Mov(x25, 0x00000003c0000000);
8163 __ Mov(x26, 0x8000000780000000);
armvixlad96eda2013-06-14 11:42:37 +01008164 __ Mov(x27, 0xc0000003);
8165
8166 __ Cmp(w20, Operand(w21, LSL, 1));
8167 __ Mrs(x0, NZCV);
8168
8169 __ Cmp(x20, Operand(x22, LSL, 2));
8170 __ Mrs(x1, NZCV);
8171
8172 __ Cmp(w19, Operand(w23, LSR, 3));
8173 __ Mrs(x2, NZCV);
8174
8175 __ Cmp(x18, Operand(x24, LSR, 4));
8176 __ Mrs(x3, NZCV);
8177
8178 __ Cmp(w20, Operand(w25, ASR, 2));
8179 __ Mrs(x4, NZCV);
8180
8181 __ Cmp(x20, Operand(x26, ASR, 3));
8182 __ Mrs(x5, NZCV);
8183
8184 __ Cmp(w27, Operand(w22, ROR, 28));
8185 __ Mrs(x6, NZCV);
8186
8187 __ Cmp(x20, Operand(x21, ROR, 31));
8188 __ Mrs(x7, NZCV);
8189 END();
8190
8191 RUN();
8192
8193 ASSERT_EQUAL_32(ZCFlag, w0);
8194 ASSERT_EQUAL_32(ZCFlag, w1);
8195 ASSERT_EQUAL_32(ZCFlag, w2);
8196 ASSERT_EQUAL_32(ZCFlag, w3);
8197 ASSERT_EQUAL_32(ZCFlag, w4);
8198 ASSERT_EQUAL_32(ZCFlag, w5);
8199 ASSERT_EQUAL_32(ZCFlag, w6);
8200 ASSERT_EQUAL_32(ZCFlag, w7);
8201
8202 TEARDOWN();
8203}
8204
8205
8206TEST(cmp_extend) {
8207 SETUP();
8208
8209 START();
8210 __ Mov(w20, 0x2);
8211 __ Mov(w21, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00008212 __ Mov(x22, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008213 __ Mov(x23, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00008214 __ Mov(x24, 0xfffffffffffffffe);
armvixlad96eda2013-06-14 11:42:37 +01008215 __ Mov(x25, 0xffff);
8216 __ Mov(x26, 0xffffffff);
8217
8218 __ Cmp(w20, Operand(w21, LSL, 1));
8219 __ Mrs(x0, NZCV);
8220
8221 __ Cmp(x22, Operand(x23, SXTB, 0));
8222 __ Mrs(x1, NZCV);
8223
8224 __ Cmp(x24, Operand(x23, SXTB, 1));
8225 __ Mrs(x2, NZCV);
8226
8227 __ Cmp(x24, Operand(x23, UXTB, 1));
8228 __ Mrs(x3, NZCV);
8229
8230 __ Cmp(w22, Operand(w25, UXTH));
8231 __ Mrs(x4, NZCV);
8232
8233 __ Cmp(x22, Operand(x25, SXTH));
8234 __ Mrs(x5, NZCV);
8235
8236 __ Cmp(x22, Operand(x26, UXTW));
8237 __ Mrs(x6, NZCV);
8238
8239 __ Cmp(x24, Operand(x26, SXTW, 1));
8240 __ Mrs(x7, NZCV);
8241 END();
8242
8243 RUN();
8244
8245 ASSERT_EQUAL_32(ZCFlag, w0);
8246 ASSERT_EQUAL_32(ZCFlag, w1);
8247 ASSERT_EQUAL_32(ZCFlag, w2);
8248 ASSERT_EQUAL_32(NCFlag, w3);
8249 ASSERT_EQUAL_32(NCFlag, w4);
8250 ASSERT_EQUAL_32(ZCFlag, w5);
8251 ASSERT_EQUAL_32(NCFlag, w6);
8252 ASSERT_EQUAL_32(ZCFlag, w7);
8253
8254 TEARDOWN();
8255}
8256
8257
8258TEST(ccmp) {
8259 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008260 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008261
8262 START();
8263 __ Mov(w16, 0);
8264 __ Mov(w17, 1);
armvixl578645f2013-08-15 17:21:42 +01008265 __ Cmp(w16, w16);
8266 __ Ccmp(w16, w17, NCFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01008267 __ Mrs(x0, NZCV);
8268
armvixl578645f2013-08-15 17:21:42 +01008269 __ Cmp(w16, w16);
8270 __ Ccmp(w16, w17, NCFlag, ne);
armvixlad96eda2013-06-14 11:42:37 +01008271 __ Mrs(x1, NZCV);
8272
armvixl578645f2013-08-15 17:21:42 +01008273 __ Cmp(x16, x16);
8274 __ Ccmn(x16, 2, NZCVFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01008275 __ Mrs(x2, NZCV);
8276
armvixl578645f2013-08-15 17:21:42 +01008277 __ Cmp(x16, x16);
8278 __ Ccmn(x16, 2, NZCVFlag, ne);
armvixlad96eda2013-06-14 11:42:37 +01008279 __ Mrs(x3, NZCV);
armvixl578645f2013-08-15 17:21:42 +01008280
armvixlc68cb642014-09-25 18:49:30 +01008281 // The MacroAssembler does not allow al as a condition.
armvixl578645f2013-08-15 17:21:42 +01008282 __ ccmp(x16, x16, NZCVFlag, al);
8283 __ Mrs(x4, NZCV);
8284
armvixlc68cb642014-09-25 18:49:30 +01008285 // The MacroAssembler does not allow nv as a condition.
armvixl578645f2013-08-15 17:21:42 +01008286 __ ccmp(x16, x16, NZCVFlag, nv);
8287 __ Mrs(x5, NZCV);
8288
armvixlad96eda2013-06-14 11:42:37 +01008289 END();
8290
8291 RUN();
8292
8293 ASSERT_EQUAL_32(NFlag, w0);
8294 ASSERT_EQUAL_32(NCFlag, w1);
8295 ASSERT_EQUAL_32(NoFlag, w2);
8296 ASSERT_EQUAL_32(NZCVFlag, w3);
armvixl578645f2013-08-15 17:21:42 +01008297 ASSERT_EQUAL_32(ZCFlag, w4);
8298 ASSERT_EQUAL_32(ZCFlag, w5);
armvixlad96eda2013-06-14 11:42:37 +01008299
8300 TEARDOWN();
8301}
8302
8303
8304TEST(ccmp_wide_imm) {
8305 SETUP();
8306
8307 START();
8308 __ Mov(w20, 0);
8309
8310 __ Cmp(w20, Operand(w20));
8311 __ Ccmp(w20, Operand(0x12345678), NZCVFlag, eq);
8312 __ Mrs(x0, NZCV);
8313
8314 __ Cmp(w20, Operand(w20));
armvixlb0c8ae22014-03-21 14:03:59 +00008315 __ Ccmp(x20, Operand(0xffffffffffffffff), NZCVFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01008316 __ Mrs(x1, NZCV);
8317 END();
8318
8319 RUN();
8320
8321 ASSERT_EQUAL_32(NFlag, w0);
8322 ASSERT_EQUAL_32(NoFlag, w1);
8323
8324 TEARDOWN();
8325}
8326
8327
8328TEST(ccmp_shift_extend) {
8329 SETUP();
8330
8331 START();
8332 __ Mov(w20, 0x2);
8333 __ Mov(w21, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00008334 __ Mov(x22, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008335 __ Mov(x23, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00008336 __ Mov(x24, 0xfffffffffffffffe);
armvixlad96eda2013-06-14 11:42:37 +01008337
8338 __ Cmp(w20, Operand(w20));
8339 __ Ccmp(w20, Operand(w21, LSL, 1), NZCVFlag, eq);
8340 __ Mrs(x0, NZCV);
8341
8342 __ Cmp(w20, Operand(w20));
8343 __ Ccmp(x22, Operand(x23, SXTB, 0), NZCVFlag, eq);
8344 __ Mrs(x1, NZCV);
8345
8346 __ Cmp(w20, Operand(w20));
8347 __ Ccmp(x24, Operand(x23, SXTB, 1), NZCVFlag, eq);
8348 __ Mrs(x2, NZCV);
8349
8350 __ Cmp(w20, Operand(w20));
8351 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, eq);
8352 __ Mrs(x3, NZCV);
8353
8354 __ Cmp(w20, Operand(w20));
8355 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, ne);
8356 __ Mrs(x4, NZCV);
8357 END();
8358
8359 RUN();
8360
8361 ASSERT_EQUAL_32(ZCFlag, w0);
8362 ASSERT_EQUAL_32(ZCFlag, w1);
8363 ASSERT_EQUAL_32(ZCFlag, w2);
8364 ASSERT_EQUAL_32(NCFlag, w3);
8365 ASSERT_EQUAL_32(NZCVFlag, w4);
8366
8367 TEARDOWN();
8368}
8369
8370
8371TEST(csel) {
8372 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008373 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008374
8375 START();
8376 __ Mov(x16, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00008377 __ Mov(x24, 0x0000000f0000000f);
8378 __ Mov(x25, 0x0000001f0000001f);
armvixlad96eda2013-06-14 11:42:37 +01008379
8380 __ Cmp(w16, Operand(0));
8381 __ Csel(w0, w24, w25, eq);
8382 __ Csel(w1, w24, w25, ne);
8383 __ Csinc(w2, w24, w25, mi);
8384 __ Csinc(w3, w24, w25, pl);
8385
armvixlc68cb642014-09-25 18:49:30 +01008386 // The MacroAssembler does not allow al or nv as a condition.
armvixl578645f2013-08-15 17:21:42 +01008387 __ csel(w13, w24, w25, al);
8388 __ csel(x14, x24, x25, nv);
8389
armvixlad96eda2013-06-14 11:42:37 +01008390 __ Cmp(x16, Operand(1));
8391 __ Csinv(x4, x24, x25, gt);
8392 __ Csinv(x5, x24, x25, le);
8393 __ Csneg(x6, x24, x25, hs);
8394 __ Csneg(x7, x24, x25, lo);
8395
8396 __ Cset(w8, ne);
8397 __ Csetm(w9, ne);
8398 __ Cinc(x10, x25, ne);
8399 __ Cinv(x11, x24, ne);
8400 __ Cneg(x12, x24, ne);
armvixl578645f2013-08-15 17:21:42 +01008401
armvixlc68cb642014-09-25 18:49:30 +01008402 // The MacroAssembler does not allow al or nv as a condition.
armvixl578645f2013-08-15 17:21:42 +01008403 __ csel(w15, w24, w25, al);
8404 __ csel(x17, x24, x25, nv);
8405
armvixlad96eda2013-06-14 11:42:37 +01008406 END();
8407
8408 RUN();
8409
8410 ASSERT_EQUAL_64(0x0000000f, x0);
8411 ASSERT_EQUAL_64(0x0000001f, x1);
8412 ASSERT_EQUAL_64(0x00000020, x2);
8413 ASSERT_EQUAL_64(0x0000000f, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00008414 ASSERT_EQUAL_64(0xffffffe0ffffffe0, x4);
8415 ASSERT_EQUAL_64(0x0000000f0000000f, x5);
8416 ASSERT_EQUAL_64(0xffffffe0ffffffe1, x6);
8417 ASSERT_EQUAL_64(0x0000000f0000000f, x7);
armvixlad96eda2013-06-14 11:42:37 +01008418 ASSERT_EQUAL_64(0x00000001, x8);
8419 ASSERT_EQUAL_64(0xffffffff, x9);
armvixlb0c8ae22014-03-21 14:03:59 +00008420 ASSERT_EQUAL_64(0x0000001f00000020, x10);
8421 ASSERT_EQUAL_64(0xfffffff0fffffff0, x11);
8422 ASSERT_EQUAL_64(0xfffffff0fffffff1, x12);
armvixl578645f2013-08-15 17:21:42 +01008423 ASSERT_EQUAL_64(0x0000000f, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00008424 ASSERT_EQUAL_64(0x0000000f0000000f, x14);
armvixl578645f2013-08-15 17:21:42 +01008425 ASSERT_EQUAL_64(0x0000000f, x15);
armvixlb0c8ae22014-03-21 14:03:59 +00008426 ASSERT_EQUAL_64(0x0000000f0000000f, x17);
armvixlad96eda2013-06-14 11:42:37 +01008427
8428 TEARDOWN();
8429}
8430
8431
armvixlf37fdc02014-02-05 13:22:16 +00008432TEST(csel_imm) {
8433 SETUP();
8434
8435 START();
8436 __ Mov(x18, 0);
8437 __ Mov(x19, 0x80000000);
armvixlb0c8ae22014-03-21 14:03:59 +00008438 __ Mov(x20, 0x8000000000000000);
armvixlf37fdc02014-02-05 13:22:16 +00008439
8440 __ Cmp(x18, Operand(0));
8441 __ Csel(w0, w19, -2, ne);
8442 __ Csel(w1, w19, -1, ne);
8443 __ Csel(w2, w19, 0, ne);
8444 __ Csel(w3, w19, 1, ne);
8445 __ Csel(w4, w19, 2, ne);
8446 __ Csel(w5, w19, Operand(w19, ASR, 31), ne);
8447 __ Csel(w6, w19, Operand(w19, ROR, 1), ne);
8448 __ Csel(w7, w19, 3, eq);
8449
8450 __ Csel(x8, x20, -2, ne);
8451 __ Csel(x9, x20, -1, ne);
8452 __ Csel(x10, x20, 0, ne);
8453 __ Csel(x11, x20, 1, ne);
8454 __ Csel(x12, x20, 2, ne);
8455 __ Csel(x13, x20, Operand(x20, ASR, 63), ne);
8456 __ Csel(x14, x20, Operand(x20, ROR, 1), ne);
8457 __ Csel(x15, x20, 3, eq);
8458
8459 END();
8460
8461 RUN();
8462
8463 ASSERT_EQUAL_32(-2, w0);
8464 ASSERT_EQUAL_32(-1, w1);
8465 ASSERT_EQUAL_32(0, w2);
8466 ASSERT_EQUAL_32(1, w3);
8467 ASSERT_EQUAL_32(2, w4);
8468 ASSERT_EQUAL_32(-1, w5);
8469 ASSERT_EQUAL_32(0x40000000, w6);
8470 ASSERT_EQUAL_32(0x80000000, w7);
8471
8472 ASSERT_EQUAL_64(-2, x8);
8473 ASSERT_EQUAL_64(-1, x9);
8474 ASSERT_EQUAL_64(0, x10);
8475 ASSERT_EQUAL_64(1, x11);
8476 ASSERT_EQUAL_64(2, x12);
8477 ASSERT_EQUAL_64(-1, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00008478 ASSERT_EQUAL_64(0x4000000000000000, x14);
8479 ASSERT_EQUAL_64(0x8000000000000000, x15);
armvixlf37fdc02014-02-05 13:22:16 +00008480
8481 TEARDOWN();
8482}
8483
8484
armvixlad96eda2013-06-14 11:42:37 +01008485TEST(lslv) {
8486 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008487 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008488
armvixlb0c8ae22014-03-21 14:03:59 +00008489 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01008490 int shift[] = {1, 3, 5, 9, 17, 33};
8491
8492 START();
8493 __ Mov(x0, value);
8494 __ Mov(w1, shift[0]);
8495 __ Mov(w2, shift[1]);
8496 __ Mov(w3, shift[2]);
8497 __ Mov(w4, shift[3]);
8498 __ Mov(w5, shift[4]);
8499 __ Mov(w6, shift[5]);
8500
armvixlc68cb642014-09-25 18:49:30 +01008501 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008502 __ lslv(x0, x0, xzr);
8503
8504 __ Lsl(x16, x0, x1);
8505 __ Lsl(x17, x0, x2);
8506 __ Lsl(x18, x0, x3);
8507 __ Lsl(x19, x0, x4);
8508 __ Lsl(x20, x0, x5);
8509 __ Lsl(x21, x0, x6);
8510
8511 __ Lsl(w22, w0, w1);
8512 __ Lsl(w23, w0, w2);
8513 __ Lsl(w24, w0, w3);
8514 __ Lsl(w25, w0, w4);
8515 __ Lsl(w26, w0, w5);
8516 __ Lsl(w27, w0, w6);
8517 END();
8518
8519 RUN();
8520
8521 ASSERT_EQUAL_64(value, x0);
8522 ASSERT_EQUAL_64(value << (shift[0] & 63), x16);
8523 ASSERT_EQUAL_64(value << (shift[1] & 63), x17);
8524 ASSERT_EQUAL_64(value << (shift[2] & 63), x18);
8525 ASSERT_EQUAL_64(value << (shift[3] & 63), x19);
8526 ASSERT_EQUAL_64(value << (shift[4] & 63), x20);
8527 ASSERT_EQUAL_64(value << (shift[5] & 63), x21);
8528 ASSERT_EQUAL_32(value << (shift[0] & 31), w22);
8529 ASSERT_EQUAL_32(value << (shift[1] & 31), w23);
8530 ASSERT_EQUAL_32(value << (shift[2] & 31), w24);
8531 ASSERT_EQUAL_32(value << (shift[3] & 31), w25);
8532 ASSERT_EQUAL_32(value << (shift[4] & 31), w26);
8533 ASSERT_EQUAL_32(value << (shift[5] & 31), w27);
8534
8535 TEARDOWN();
8536}
8537
8538
8539TEST(lsrv) {
8540 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008541 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008542
armvixlb0c8ae22014-03-21 14:03:59 +00008543 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01008544 int shift[] = {1, 3, 5, 9, 17, 33};
8545
8546 START();
8547 __ Mov(x0, value);
8548 __ Mov(w1, shift[0]);
8549 __ Mov(w2, shift[1]);
8550 __ Mov(w3, shift[2]);
8551 __ Mov(w4, shift[3]);
8552 __ Mov(w5, shift[4]);
8553 __ Mov(w6, shift[5]);
8554
armvixlc68cb642014-09-25 18:49:30 +01008555 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008556 __ lsrv(x0, x0, xzr);
8557
8558 __ Lsr(x16, x0, x1);
8559 __ Lsr(x17, x0, x2);
8560 __ Lsr(x18, x0, x3);
8561 __ Lsr(x19, x0, x4);
8562 __ Lsr(x20, x0, x5);
8563 __ Lsr(x21, x0, x6);
8564
8565 __ Lsr(w22, w0, w1);
8566 __ Lsr(w23, w0, w2);
8567 __ Lsr(w24, w0, w3);
8568 __ Lsr(w25, w0, w4);
8569 __ Lsr(w26, w0, w5);
8570 __ Lsr(w27, w0, w6);
8571 END();
8572
8573 RUN();
8574
8575 ASSERT_EQUAL_64(value, x0);
8576 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
8577 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
8578 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
8579 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
8580 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
8581 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
8582
armvixlb0c8ae22014-03-21 14:03:59 +00008583 value &= 0xffffffff;
armvixlad96eda2013-06-14 11:42:37 +01008584 ASSERT_EQUAL_32(value >> (shift[0] & 31), w22);
8585 ASSERT_EQUAL_32(value >> (shift[1] & 31), w23);
8586 ASSERT_EQUAL_32(value >> (shift[2] & 31), w24);
8587 ASSERT_EQUAL_32(value >> (shift[3] & 31), w25);
8588 ASSERT_EQUAL_32(value >> (shift[4] & 31), w26);
8589 ASSERT_EQUAL_32(value >> (shift[5] & 31), w27);
8590
8591 TEARDOWN();
8592}
8593
8594
8595TEST(asrv) {
8596 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008597 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008598
armvixlb0c8ae22014-03-21 14:03:59 +00008599 int64_t value = 0xfedcba98fedcba98;
armvixlad96eda2013-06-14 11:42:37 +01008600 int shift[] = {1, 3, 5, 9, 17, 33};
8601
8602 START();
8603 __ Mov(x0, value);
8604 __ Mov(w1, shift[0]);
8605 __ Mov(w2, shift[1]);
8606 __ Mov(w3, shift[2]);
8607 __ Mov(w4, shift[3]);
8608 __ Mov(w5, shift[4]);
8609 __ Mov(w6, shift[5]);
8610
armvixlc68cb642014-09-25 18:49:30 +01008611 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008612 __ asrv(x0, x0, xzr);
8613
8614 __ Asr(x16, x0, x1);
8615 __ Asr(x17, x0, x2);
8616 __ Asr(x18, x0, x3);
8617 __ Asr(x19, x0, x4);
8618 __ Asr(x20, x0, x5);
8619 __ Asr(x21, x0, x6);
8620
8621 __ Asr(w22, w0, w1);
8622 __ Asr(w23, w0, w2);
8623 __ Asr(w24, w0, w3);
8624 __ Asr(w25, w0, w4);
8625 __ Asr(w26, w0, w5);
8626 __ Asr(w27, w0, w6);
8627 END();
8628
8629 RUN();
8630
8631 ASSERT_EQUAL_64(value, x0);
8632 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
8633 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
8634 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
8635 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
8636 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
8637 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
8638
armvixlb0c8ae22014-03-21 14:03:59 +00008639 int32_t value32 = static_cast<int32_t>(value & 0xffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008640 ASSERT_EQUAL_32(value32 >> (shift[0] & 31), w22);
8641 ASSERT_EQUAL_32(value32 >> (shift[1] & 31), w23);
8642 ASSERT_EQUAL_32(value32 >> (shift[2] & 31), w24);
8643 ASSERT_EQUAL_32(value32 >> (shift[3] & 31), w25);
8644 ASSERT_EQUAL_32(value32 >> (shift[4] & 31), w26);
8645 ASSERT_EQUAL_32(value32 >> (shift[5] & 31), w27);
8646
8647 TEARDOWN();
8648}
8649
8650
8651TEST(rorv) {
8652 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008653 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008654
armvixlb0c8ae22014-03-21 14:03:59 +00008655 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01008656 int shift[] = {4, 8, 12, 16, 24, 36};
8657
8658 START();
8659 __ Mov(x0, value);
8660 __ Mov(w1, shift[0]);
8661 __ Mov(w2, shift[1]);
8662 __ Mov(w3, shift[2]);
8663 __ Mov(w4, shift[3]);
8664 __ Mov(w5, shift[4]);
8665 __ Mov(w6, shift[5]);
8666
armvixlc68cb642014-09-25 18:49:30 +01008667 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008668 __ rorv(x0, x0, xzr);
8669
8670 __ Ror(x16, x0, x1);
8671 __ Ror(x17, x0, x2);
8672 __ Ror(x18, x0, x3);
8673 __ Ror(x19, x0, x4);
8674 __ Ror(x20, x0, x5);
8675 __ Ror(x21, x0, x6);
8676
8677 __ Ror(w22, w0, w1);
8678 __ Ror(w23, w0, w2);
8679 __ Ror(w24, w0, w3);
8680 __ Ror(w25, w0, w4);
8681 __ Ror(w26, w0, w5);
8682 __ Ror(w27, w0, w6);
8683 END();
8684
8685 RUN();
8686
8687 ASSERT_EQUAL_64(value, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00008688 ASSERT_EQUAL_64(0xf0123456789abcde, x16);
8689 ASSERT_EQUAL_64(0xef0123456789abcd, x17);
8690 ASSERT_EQUAL_64(0xdef0123456789abc, x18);
8691 ASSERT_EQUAL_64(0xcdef0123456789ab, x19);
8692 ASSERT_EQUAL_64(0xabcdef0123456789, x20);
8693 ASSERT_EQUAL_64(0x789abcdef0123456, x21);
armvixlad96eda2013-06-14 11:42:37 +01008694 ASSERT_EQUAL_32(0xf89abcde, w22);
8695 ASSERT_EQUAL_32(0xef89abcd, w23);
8696 ASSERT_EQUAL_32(0xdef89abc, w24);
8697 ASSERT_EQUAL_32(0xcdef89ab, w25);
8698 ASSERT_EQUAL_32(0xabcdef89, w26);
8699 ASSERT_EQUAL_32(0xf89abcde, w27);
8700
8701 TEARDOWN();
8702}
8703
8704
8705TEST(bfm) {
8706 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008707 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008708
8709 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008710 __ Mov(x1, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01008711
armvixlb0c8ae22014-03-21 14:03:59 +00008712 __ Mov(x10, 0x8888888888888888);
8713 __ Mov(x11, 0x8888888888888888);
8714 __ Mov(x12, 0x8888888888888888);
8715 __ Mov(x13, 0x8888888888888888);
armvixlad96eda2013-06-14 11:42:37 +01008716 __ Mov(w20, 0x88888888);
8717 __ Mov(w21, 0x88888888);
8718
armvixlc68cb642014-09-25 18:49:30 +01008719 // There are no macro instruction for bfm.
armvixl5289c592015-03-02 13:52:04 +00008720 __ Bfm(x10, x1, 16, 31);
8721 __ Bfm(x11, x1, 32, 15);
armvixlad96eda2013-06-14 11:42:37 +01008722
armvixl5289c592015-03-02 13:52:04 +00008723 __ Bfm(w20, w1, 16, 23);
8724 __ Bfm(w21, w1, 24, 15);
armvixlad96eda2013-06-14 11:42:37 +01008725
8726 // Aliases.
8727 __ Bfi(x12, x1, 16, 8);
8728 __ Bfxil(x13, x1, 16, 8);
8729 END();
8730
8731 RUN();
8732
8733
armvixlb0c8ae22014-03-21 14:03:59 +00008734 ASSERT_EQUAL_64(0x88888888888889ab, x10);
8735 ASSERT_EQUAL_64(0x8888cdef88888888, x11);
armvixlad96eda2013-06-14 11:42:37 +01008736
8737 ASSERT_EQUAL_32(0x888888ab, w20);
8738 ASSERT_EQUAL_32(0x88cdef88, w21);
8739
armvixlb0c8ae22014-03-21 14:03:59 +00008740 ASSERT_EQUAL_64(0x8888888888ef8888, x12);
8741 ASSERT_EQUAL_64(0x88888888888888ab, x13);
armvixlad96eda2013-06-14 11:42:37 +01008742
8743 TEARDOWN();
8744}
8745
8746
8747TEST(sbfm) {
8748 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008749 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008750
8751 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008752 __ Mov(x1, 0x0123456789abcdef);
8753 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01008754
armvixlc68cb642014-09-25 18:49:30 +01008755 // There are no macro instruction for sbfm.
armvixl5289c592015-03-02 13:52:04 +00008756 __ Sbfm(x10, x1, 16, 31);
8757 __ Sbfm(x11, x1, 32, 15);
8758 __ Sbfm(x12, x1, 32, 47);
8759 __ Sbfm(x13, x1, 48, 35);
armvixlad96eda2013-06-14 11:42:37 +01008760
armvixl5289c592015-03-02 13:52:04 +00008761 __ Sbfm(w14, w1, 16, 23);
8762 __ Sbfm(w15, w1, 24, 15);
8763 __ Sbfm(w16, w2, 16, 23);
8764 __ Sbfm(w17, w2, 24, 15);
armvixlad96eda2013-06-14 11:42:37 +01008765
8766 // Aliases.
8767 __ Asr(x18, x1, 32);
8768 __ Asr(x19, x2, 32);
8769 __ Sbfiz(x20, x1, 8, 16);
8770 __ Sbfiz(x21, x2, 8, 16);
8771 __ Sbfx(x22, x1, 8, 16);
8772 __ Sbfx(x23, x2, 8, 16);
armvixlf37fdc02014-02-05 13:22:16 +00008773 __ Sxtb(x24, w1);
armvixlad96eda2013-06-14 11:42:37 +01008774 __ Sxtb(x25, x2);
armvixlf37fdc02014-02-05 13:22:16 +00008775 __ Sxth(x26, w1);
armvixlad96eda2013-06-14 11:42:37 +01008776 __ Sxth(x27, x2);
armvixlf37fdc02014-02-05 13:22:16 +00008777 __ Sxtw(x28, w1);
armvixlad96eda2013-06-14 11:42:37 +01008778 __ Sxtw(x29, x2);
8779 END();
8780
8781 RUN();
8782
8783
armvixlb0c8ae22014-03-21 14:03:59 +00008784 ASSERT_EQUAL_64(0xffffffffffff89ab, x10);
8785 ASSERT_EQUAL_64(0xffffcdef00000000, x11);
8786 ASSERT_EQUAL_64(0x0000000000004567, x12);
8787 ASSERT_EQUAL_64(0x000789abcdef0000, x13);
armvixlad96eda2013-06-14 11:42:37 +01008788
8789 ASSERT_EQUAL_32(0xffffffab, w14);
8790 ASSERT_EQUAL_32(0xffcdef00, w15);
armvixlb0c8ae22014-03-21 14:03:59 +00008791 ASSERT_EQUAL_32(0x00000054, w16);
armvixlad96eda2013-06-14 11:42:37 +01008792 ASSERT_EQUAL_32(0x00321000, w17);
8793
armvixlb0c8ae22014-03-21 14:03:59 +00008794 ASSERT_EQUAL_64(0x0000000001234567, x18);
8795 ASSERT_EQUAL_64(0xfffffffffedcba98, x19);
8796 ASSERT_EQUAL_64(0xffffffffffcdef00, x20);
8797 ASSERT_EQUAL_64(0x0000000000321000, x21);
8798 ASSERT_EQUAL_64(0xffffffffffffabcd, x22);
8799 ASSERT_EQUAL_64(0x0000000000005432, x23);
8800 ASSERT_EQUAL_64(0xffffffffffffffef, x24);
8801 ASSERT_EQUAL_64(0x0000000000000010, x25);
8802 ASSERT_EQUAL_64(0xffffffffffffcdef, x26);
8803 ASSERT_EQUAL_64(0x0000000000003210, x27);
8804 ASSERT_EQUAL_64(0xffffffff89abcdef, x28);
8805 ASSERT_EQUAL_64(0x0000000076543210, x29);
armvixlad96eda2013-06-14 11:42:37 +01008806
8807 TEARDOWN();
8808}
8809
8810
8811TEST(ubfm) {
8812 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008813 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008814
8815 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008816 __ Mov(x1, 0x0123456789abcdef);
8817 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01008818
armvixlb0c8ae22014-03-21 14:03:59 +00008819 __ Mov(x10, 0x8888888888888888);
8820 __ Mov(x11, 0x8888888888888888);
armvixlad96eda2013-06-14 11:42:37 +01008821
armvixlc68cb642014-09-25 18:49:30 +01008822 // There are no macro instruction for ubfm.
armvixl5289c592015-03-02 13:52:04 +00008823 __ Ubfm(x10, x1, 16, 31);
8824 __ Ubfm(x11, x1, 32, 15);
8825 __ Ubfm(x12, x1, 32, 47);
8826 __ Ubfm(x13, x1, 48, 35);
armvixlad96eda2013-06-14 11:42:37 +01008827
armvixl5289c592015-03-02 13:52:04 +00008828 __ Ubfm(w25, w1, 16, 23);
8829 __ Ubfm(w26, w1, 24, 15);
8830 __ Ubfm(w27, w2, 16, 23);
8831 __ Ubfm(w28, w2, 24, 15);
armvixlad96eda2013-06-14 11:42:37 +01008832
8833 // Aliases
8834 __ Lsl(x15, x1, 63);
8835 __ Lsl(x16, x1, 0);
8836 __ Lsr(x17, x1, 32);
8837 __ Ubfiz(x18, x1, 8, 16);
8838 __ Ubfx(x19, x1, 8, 16);
8839 __ Uxtb(x20, x1);
8840 __ Uxth(x21, x1);
8841 __ Uxtw(x22, x1);
8842 END();
8843
8844 RUN();
8845
armvixlb0c8ae22014-03-21 14:03:59 +00008846 ASSERT_EQUAL_64(0x00000000000089ab, x10);
8847 ASSERT_EQUAL_64(0x0000cdef00000000, x11);
8848 ASSERT_EQUAL_64(0x0000000000004567, x12);
8849 ASSERT_EQUAL_64(0x000789abcdef0000, x13);
armvixlad96eda2013-06-14 11:42:37 +01008850
8851 ASSERT_EQUAL_32(0x000000ab, w25);
8852 ASSERT_EQUAL_32(0x00cdef00, w26);
armvixlb0c8ae22014-03-21 14:03:59 +00008853 ASSERT_EQUAL_32(0x00000054, w27);
armvixlad96eda2013-06-14 11:42:37 +01008854 ASSERT_EQUAL_32(0x00321000, w28);
8855
armvixlb0c8ae22014-03-21 14:03:59 +00008856 ASSERT_EQUAL_64(0x8000000000000000, x15);
8857 ASSERT_EQUAL_64(0x0123456789abcdef, x16);
8858 ASSERT_EQUAL_64(0x0000000001234567, x17);
8859 ASSERT_EQUAL_64(0x0000000000cdef00, x18);
8860 ASSERT_EQUAL_64(0x000000000000abcd, x19);
8861 ASSERT_EQUAL_64(0x00000000000000ef, x20);
8862 ASSERT_EQUAL_64(0x000000000000cdef, x21);
8863 ASSERT_EQUAL_64(0x0000000089abcdef, x22);
armvixlad96eda2013-06-14 11:42:37 +01008864
8865 TEARDOWN();
8866}
8867
8868
8869TEST(extr) {
8870 SETUP();
8871
8872 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008873 __ Mov(x1, 0x0123456789abcdef);
8874 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01008875
8876 __ Extr(w10, w1, w2, 0);
8877 __ Extr(w11, w1, w2, 1);
8878 __ Extr(x12, x2, x1, 2);
8879
8880 __ Ror(w13, w1, 0);
8881 __ Ror(w14, w2, 17);
8882 __ Ror(w15, w1, 31);
armvixl4a102ba2014-07-14 09:02:40 +01008883 __ Ror(x18, x2, 0);
8884 __ Ror(x19, x2, 1);
8885 __ Ror(x20, x1, 63);
armvixlad96eda2013-06-14 11:42:37 +01008886 END();
8887
8888 RUN();
8889
8890 ASSERT_EQUAL_64(0x76543210, x10);
8891 ASSERT_EQUAL_64(0xbb2a1908, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00008892 ASSERT_EQUAL_64(0x0048d159e26af37b, x12);
armvixlad96eda2013-06-14 11:42:37 +01008893 ASSERT_EQUAL_64(0x89abcdef, x13);
8894 ASSERT_EQUAL_64(0x19083b2a, x14);
8895 ASSERT_EQUAL_64(0x13579bdf, x15);
armvixl4a102ba2014-07-14 09:02:40 +01008896 ASSERT_EQUAL_64(0xfedcba9876543210, x18);
8897 ASSERT_EQUAL_64(0x7f6e5d4c3b2a1908, x19);
8898 ASSERT_EQUAL_64(0x02468acf13579bde, x20);
armvixlad96eda2013-06-14 11:42:37 +01008899
8900 TEARDOWN();
8901}
8902
8903
8904TEST(fmov_imm) {
8905 SETUP();
8906
8907 START();
8908 __ Fmov(s11, 1.0);
8909 __ Fmov(d22, -13.0);
8910 __ Fmov(s1, 255.0);
8911 __ Fmov(d2, 12.34567);
8912 __ Fmov(s3, 0.0);
8913 __ Fmov(d4, 0.0);
8914 __ Fmov(s5, kFP32PositiveInfinity);
8915 __ Fmov(d6, kFP64NegativeInfinity);
8916 END();
8917
8918 RUN();
8919
8920 ASSERT_EQUAL_FP32(1.0, s11);
8921 ASSERT_EQUAL_FP64(-13.0, d22);
8922 ASSERT_EQUAL_FP32(255.0, s1);
8923 ASSERT_EQUAL_FP64(12.34567, d2);
8924 ASSERT_EQUAL_FP32(0.0, s3);
8925 ASSERT_EQUAL_FP64(0.0, d4);
8926 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
8927 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d6);
8928
8929 TEARDOWN();
8930}
8931
8932
8933TEST(fmov_reg) {
8934 SETUP();
8935
8936 START();
8937 __ Fmov(s20, 1.0);
8938 __ Fmov(w10, s20);
8939 __ Fmov(s30, w10);
8940 __ Fmov(s5, s20);
8941 __ Fmov(d1, -13.0);
8942 __ Fmov(x1, d1);
8943 __ Fmov(d2, x1);
8944 __ Fmov(d4, d1);
armvixlb0c8ae22014-03-21 14:03:59 +00008945 __ Fmov(d6, rawbits_to_double(0x0123456789abcdef));
armvixlad96eda2013-06-14 11:42:37 +01008946 __ Fmov(s6, s6);
armvixl5289c592015-03-02 13:52:04 +00008947
8948 __ Fmov(d0, 0.0);
8949 __ Fmov(v0.D(), 1, x1);
8950 __ Fmov(x2, v0.D(), 1);
8951
armvixlad96eda2013-06-14 11:42:37 +01008952 END();
8953
8954 RUN();
8955
8956 ASSERT_EQUAL_32(float_to_rawbits(1.0), w10);
8957 ASSERT_EQUAL_FP32(1.0, s30);
8958 ASSERT_EQUAL_FP32(1.0, s5);
8959 ASSERT_EQUAL_64(double_to_rawbits(-13.0), x1);
8960 ASSERT_EQUAL_FP64(-13.0, d2);
8961 ASSERT_EQUAL_FP64(-13.0, d4);
8962 ASSERT_EQUAL_FP32(rawbits_to_float(0x89abcdef), s6);
armvixl5289c592015-03-02 13:52:04 +00008963 ASSERT_EQUAL_128(double_to_rawbits(-13.0), 0x0000000000000000, q0);
8964 ASSERT_EQUAL_64(double_to_rawbits(-13.0), x2);
armvixlad96eda2013-06-14 11:42:37 +01008965 TEARDOWN();
8966}
8967
8968
8969TEST(fadd) {
8970 SETUP();
8971
8972 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008973 __ Fmov(s14, -0.0f);
8974 __ Fmov(s15, kFP32PositiveInfinity);
8975 __ Fmov(s16, kFP32NegativeInfinity);
8976 __ Fmov(s17, 3.25f);
8977 __ Fmov(s18, 1.0f);
8978 __ Fmov(s19, 0.0f);
armvixlad96eda2013-06-14 11:42:37 +01008979
8980 __ Fmov(d26, -0.0);
8981 __ Fmov(d27, kFP64PositiveInfinity);
8982 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00008983 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01008984 __ Fmov(d30, -2.0);
8985 __ Fmov(d31, 2.25);
8986
armvixlb0c8ae22014-03-21 14:03:59 +00008987 __ Fadd(s0, s17, s18);
8988 __ Fadd(s1, s18, s19);
8989 __ Fadd(s2, s14, s18);
8990 __ Fadd(s3, s15, s18);
8991 __ Fadd(s4, s16, s18);
8992 __ Fadd(s5, s15, s16);
8993 __ Fadd(s6, s16, s15);
armvixlad96eda2013-06-14 11:42:37 +01008994
armvixlb0c8ae22014-03-21 14:03:59 +00008995 __ Fadd(d7, d30, d31);
8996 __ Fadd(d8, d29, d31);
8997 __ Fadd(d9, d26, d31);
8998 __ Fadd(d10, d27, d31);
8999 __ Fadd(d11, d28, d31);
9000 __ Fadd(d12, d27, d28);
9001 __ Fadd(d13, d28, d27);
armvixlad96eda2013-06-14 11:42:37 +01009002 END();
9003
9004 RUN();
9005
9006 ASSERT_EQUAL_FP32(4.25, s0);
9007 ASSERT_EQUAL_FP32(1.0, s1);
9008 ASSERT_EQUAL_FP32(1.0, s2);
9009 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
9010 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00009011 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9012 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9013 ASSERT_EQUAL_FP64(0.25, d7);
9014 ASSERT_EQUAL_FP64(2.25, d8);
9015 ASSERT_EQUAL_FP64(2.25, d9);
9016 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d10);
9017 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d11);
9018 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9019 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009020
9021 TEARDOWN();
9022}
9023
9024
9025TEST(fsub) {
9026 SETUP();
9027
9028 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009029 __ Fmov(s14, -0.0f);
9030 __ Fmov(s15, kFP32PositiveInfinity);
9031 __ Fmov(s16, kFP32NegativeInfinity);
9032 __ Fmov(s17, 3.25f);
9033 __ Fmov(s18, 1.0f);
9034 __ Fmov(s19, 0.0f);
armvixlad96eda2013-06-14 11:42:37 +01009035
9036 __ Fmov(d26, -0.0);
9037 __ Fmov(d27, kFP64PositiveInfinity);
9038 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009039 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01009040 __ Fmov(d30, -2.0);
9041 __ Fmov(d31, 2.25);
9042
armvixlb0c8ae22014-03-21 14:03:59 +00009043 __ Fsub(s0, s17, s18);
9044 __ Fsub(s1, s18, s19);
9045 __ Fsub(s2, s14, s18);
9046 __ Fsub(s3, s18, s15);
9047 __ Fsub(s4, s18, s16);
9048 __ Fsub(s5, s15, s15);
9049 __ Fsub(s6, s16, s16);
armvixlad96eda2013-06-14 11:42:37 +01009050
armvixlb0c8ae22014-03-21 14:03:59 +00009051 __ Fsub(d7, d30, d31);
9052 __ Fsub(d8, d29, d31);
9053 __ Fsub(d9, d26, d31);
9054 __ Fsub(d10, d31, d27);
9055 __ Fsub(d11, d31, d28);
9056 __ Fsub(d12, d27, d27);
9057 __ Fsub(d13, d28, d28);
armvixlad96eda2013-06-14 11:42:37 +01009058 END();
9059
9060 RUN();
9061
9062 ASSERT_EQUAL_FP32(2.25, s0);
9063 ASSERT_EQUAL_FP32(1.0, s1);
9064 ASSERT_EQUAL_FP32(-1.0, s2);
9065 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
9066 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00009067 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9068 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9069 ASSERT_EQUAL_FP64(-4.25, d7);
9070 ASSERT_EQUAL_FP64(-2.25, d8);
9071 ASSERT_EQUAL_FP64(-2.25, d9);
9072 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
9073 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
9074 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9075 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009076
9077 TEARDOWN();
9078}
9079
9080
9081TEST(fmul) {
9082 SETUP();
9083
9084 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009085 __ Fmov(s14, -0.0f);
9086 __ Fmov(s15, kFP32PositiveInfinity);
9087 __ Fmov(s16, kFP32NegativeInfinity);
9088 __ Fmov(s17, 3.25f);
9089 __ Fmov(s18, 2.0f);
9090 __ Fmov(s19, 0.0f);
9091 __ Fmov(s20, -2.0f);
armvixlad96eda2013-06-14 11:42:37 +01009092
9093 __ Fmov(d26, -0.0);
9094 __ Fmov(d27, kFP64PositiveInfinity);
9095 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009096 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01009097 __ Fmov(d30, -2.0);
9098 __ Fmov(d31, 2.25);
9099
armvixlb0c8ae22014-03-21 14:03:59 +00009100 __ Fmul(s0, s17, s18);
9101 __ Fmul(s1, s18, s19);
9102 __ Fmul(s2, s14, s14);
9103 __ Fmul(s3, s15, s20);
9104 __ Fmul(s4, s16, s20);
9105 __ Fmul(s5, s15, s19);
9106 __ Fmul(s6, s19, s16);
armvixlad96eda2013-06-14 11:42:37 +01009107
armvixlb0c8ae22014-03-21 14:03:59 +00009108 __ Fmul(d7, d30, d31);
9109 __ Fmul(d8, d29, d31);
9110 __ Fmul(d9, d26, d26);
9111 __ Fmul(d10, d27, d30);
9112 __ Fmul(d11, d28, d30);
9113 __ Fmul(d12, d27, d29);
9114 __ Fmul(d13, d29, d28);
armvixlad96eda2013-06-14 11:42:37 +01009115 END();
9116
9117 RUN();
9118
9119 ASSERT_EQUAL_FP32(6.5, s0);
9120 ASSERT_EQUAL_FP32(0.0, s1);
9121 ASSERT_EQUAL_FP32(0.0, s2);
9122 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
9123 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00009124 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9125 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9126 ASSERT_EQUAL_FP64(-4.5, d7);
9127 ASSERT_EQUAL_FP64(0.0, d8);
9128 ASSERT_EQUAL_FP64(0.0, d9);
9129 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
9130 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
9131 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9132 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009133
9134 TEARDOWN();
9135}
9136
9137
armvixlb0c8ae22014-03-21 14:03:59 +00009138static void FmaddFmsubHelper(double n, double m, double a,
9139 double fmadd, double fmsub,
9140 double fnmadd, double fnmsub) {
armvixlad96eda2013-06-14 11:42:37 +01009141 SETUP();
armvixlad96eda2013-06-14 11:42:37 +01009142 START();
armvixlad96eda2013-06-14 11:42:37 +01009143
armvixlf37fdc02014-02-05 13:22:16 +00009144 __ Fmov(d0, n);
9145 __ Fmov(d1, m);
9146 __ Fmov(d2, a);
9147 __ Fmadd(d28, d0, d1, d2);
9148 __ Fmsub(d29, d0, d1, d2);
9149 __ Fnmadd(d30, d0, d1, d2);
9150 __ Fnmsub(d31, d0, d1, d2);
armvixlad96eda2013-06-14 11:42:37 +01009151
armvixlad96eda2013-06-14 11:42:37 +01009152 END();
armvixlad96eda2013-06-14 11:42:37 +01009153 RUN();
9154
armvixlf37fdc02014-02-05 13:22:16 +00009155 ASSERT_EQUAL_FP64(fmadd, d28);
9156 ASSERT_EQUAL_FP64(fmsub, d29);
armvixlb0c8ae22014-03-21 14:03:59 +00009157 ASSERT_EQUAL_FP64(fnmadd, d30);
9158 ASSERT_EQUAL_FP64(fnmsub, d31);
armvixlad96eda2013-06-14 11:42:37 +01009159
9160 TEARDOWN();
9161}
9162
9163
armvixlf37fdc02014-02-05 13:22:16 +00009164TEST(fmadd_fmsub_double) {
armvixlb0c8ae22014-03-21 14:03:59 +00009165 // It's hard to check the result of fused operations because the only way to
9166 // calculate the result is using fma, which is what the simulator uses anyway.
armvixlf37fdc02014-02-05 13:22:16 +00009167
armvixlb0c8ae22014-03-21 14:03:59 +00009168 // Basic operation.
9169 FmaddFmsubHelper(1.0, 2.0, 3.0, 5.0, 1.0, -5.0, -1.0);
9170 FmaddFmsubHelper(-1.0, 2.0, 3.0, 1.0, 5.0, -1.0, -5.0);
armvixlf37fdc02014-02-05 13:22:16 +00009171
armvixlb0c8ae22014-03-21 14:03:59 +00009172 // Check the sign of exact zeroes.
9173 // n m a fmadd fmsub fnmadd fnmsub
9174 FmaddFmsubHelper(-0.0, +0.0, -0.0, -0.0, +0.0, +0.0, +0.0);
9175 FmaddFmsubHelper(+0.0, +0.0, -0.0, +0.0, -0.0, +0.0, +0.0);
9176 FmaddFmsubHelper(+0.0, +0.0, +0.0, +0.0, +0.0, -0.0, +0.0);
9177 FmaddFmsubHelper(-0.0, +0.0, +0.0, +0.0, +0.0, +0.0, -0.0);
9178 FmaddFmsubHelper(+0.0, -0.0, -0.0, -0.0, +0.0, +0.0, +0.0);
9179 FmaddFmsubHelper(-0.0, -0.0, -0.0, +0.0, -0.0, +0.0, +0.0);
9180 FmaddFmsubHelper(-0.0, -0.0, +0.0, +0.0, +0.0, -0.0, +0.0);
9181 FmaddFmsubHelper(+0.0, -0.0, +0.0, +0.0, +0.0, +0.0, -0.0);
9182
9183 // Check NaN generation.
9184 FmaddFmsubHelper(kFP64PositiveInfinity, 0.0, 42.0,
9185 kFP64DefaultNaN, kFP64DefaultNaN,
9186 kFP64DefaultNaN, kFP64DefaultNaN);
9187 FmaddFmsubHelper(0.0, kFP64PositiveInfinity, 42.0,
9188 kFP64DefaultNaN, kFP64DefaultNaN,
9189 kFP64DefaultNaN, kFP64DefaultNaN);
9190 FmaddFmsubHelper(kFP64PositiveInfinity, 1.0, kFP64PositiveInfinity,
9191 kFP64PositiveInfinity, // inf + ( inf * 1) = inf
9192 kFP64DefaultNaN, // inf + (-inf * 1) = NaN
9193 kFP64NegativeInfinity, // -inf + (-inf * 1) = -inf
9194 kFP64DefaultNaN); // -inf + ( inf * 1) = NaN
9195 FmaddFmsubHelper(kFP64NegativeInfinity, 1.0, kFP64PositiveInfinity,
9196 kFP64DefaultNaN, // inf + (-inf * 1) = NaN
9197 kFP64PositiveInfinity, // inf + ( inf * 1) = inf
9198 kFP64DefaultNaN, // -inf + ( inf * 1) = NaN
9199 kFP64NegativeInfinity); // -inf + (-inf * 1) = -inf
armvixlf37fdc02014-02-05 13:22:16 +00009200}
9201
9202
armvixlb0c8ae22014-03-21 14:03:59 +00009203static void FmaddFmsubHelper(float n, float m, float a,
9204 float fmadd, float fmsub,
9205 float fnmadd, float fnmsub) {
armvixlf37fdc02014-02-05 13:22:16 +00009206 SETUP();
9207 START();
9208
9209 __ Fmov(s0, n);
9210 __ Fmov(s1, m);
9211 __ Fmov(s2, a);
armvixlb0c8ae22014-03-21 14:03:59 +00009212 __ Fmadd(s28, s0, s1, s2);
9213 __ Fmsub(s29, s0, s1, s2);
9214 __ Fnmadd(s30, s0, s1, s2);
9215 __ Fnmsub(s31, s0, s1, s2);
armvixlf37fdc02014-02-05 13:22:16 +00009216
9217 END();
9218 RUN();
9219
armvixlb0c8ae22014-03-21 14:03:59 +00009220 ASSERT_EQUAL_FP32(fmadd, s28);
9221 ASSERT_EQUAL_FP32(fmsub, s29);
9222 ASSERT_EQUAL_FP32(fnmadd, s30);
9223 ASSERT_EQUAL_FP32(fnmsub, s31);
armvixlf37fdc02014-02-05 13:22:16 +00009224
9225 TEARDOWN();
9226}
9227
9228
9229TEST(fmadd_fmsub_float) {
armvixlb0c8ae22014-03-21 14:03:59 +00009230 // It's hard to check the result of fused operations because the only way to
9231 // calculate the result is using fma, which is what the simulator uses anyway.
armvixlf37fdc02014-02-05 13:22:16 +00009232
armvixlb0c8ae22014-03-21 14:03:59 +00009233 // Basic operation.
9234 FmaddFmsubHelper(1.0f, 2.0f, 3.0f, 5.0f, 1.0f, -5.0f, -1.0f);
9235 FmaddFmsubHelper(-1.0f, 2.0f, 3.0f, 1.0f, 5.0f, -1.0f, -5.0f);
armvixlf37fdc02014-02-05 13:22:16 +00009236
armvixlb0c8ae22014-03-21 14:03:59 +00009237 // Check the sign of exact zeroes.
9238 // n m a fmadd fmsub fnmadd fnmsub
9239 FmaddFmsubHelper(-0.0f, +0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
9240 FmaddFmsubHelper(+0.0f, +0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
9241 FmaddFmsubHelper(+0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
9242 FmaddFmsubHelper(-0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
9243 FmaddFmsubHelper(+0.0f, -0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
9244 FmaddFmsubHelper(-0.0f, -0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
9245 FmaddFmsubHelper(-0.0f, -0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
9246 FmaddFmsubHelper(+0.0f, -0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
9247
9248 // Check NaN generation.
9249 FmaddFmsubHelper(kFP32PositiveInfinity, 0.0f, 42.0f,
9250 kFP32DefaultNaN, kFP32DefaultNaN,
9251 kFP32DefaultNaN, kFP32DefaultNaN);
9252 FmaddFmsubHelper(0.0f, kFP32PositiveInfinity, 42.0f,
9253 kFP32DefaultNaN, kFP32DefaultNaN,
9254 kFP32DefaultNaN, kFP32DefaultNaN);
9255 FmaddFmsubHelper(kFP32PositiveInfinity, 1.0f, kFP32PositiveInfinity,
9256 kFP32PositiveInfinity, // inf + ( inf * 1) = inf
9257 kFP32DefaultNaN, // inf + (-inf * 1) = NaN
9258 kFP32NegativeInfinity, // -inf + (-inf * 1) = -inf
9259 kFP32DefaultNaN); // -inf + ( inf * 1) = NaN
9260 FmaddFmsubHelper(kFP32NegativeInfinity, 1.0f, kFP32PositiveInfinity,
9261 kFP32DefaultNaN, // inf + (-inf * 1) = NaN
9262 kFP32PositiveInfinity, // inf + ( inf * 1) = inf
9263 kFP32DefaultNaN, // -inf + ( inf * 1) = NaN
9264 kFP32NegativeInfinity); // -inf + (-inf * 1) = -inf
armvixlf37fdc02014-02-05 13:22:16 +00009265}
9266
9267
armvixlb0c8ae22014-03-21 14:03:59 +00009268TEST(fmadd_fmsub_double_nans) {
9269 // Make sure that NaN propagation works correctly.
9270 double s1 = rawbits_to_double(0x7ff5555511111111);
9271 double s2 = rawbits_to_double(0x7ff5555522222222);
9272 double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
9273 double q1 = rawbits_to_double(0x7ffaaaaa11111111);
9274 double q2 = rawbits_to_double(0x7ffaaaaa22222222);
9275 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
9276 VIXL_ASSERT(IsSignallingNaN(s1));
9277 VIXL_ASSERT(IsSignallingNaN(s2));
9278 VIXL_ASSERT(IsSignallingNaN(sa));
9279 VIXL_ASSERT(IsQuietNaN(q1));
9280 VIXL_ASSERT(IsQuietNaN(q2));
9281 VIXL_ASSERT(IsQuietNaN(qa));
armvixlf37fdc02014-02-05 13:22:16 +00009282
armvixlb0c8ae22014-03-21 14:03:59 +00009283 // The input NaNs after passing through ProcessNaN.
9284 double s1_proc = rawbits_to_double(0x7ffd555511111111);
9285 double s2_proc = rawbits_to_double(0x7ffd555522222222);
9286 double sa_proc = rawbits_to_double(0x7ffd5555aaaaaaaa);
9287 double q1_proc = q1;
9288 double q2_proc = q2;
9289 double qa_proc = qa;
9290 VIXL_ASSERT(IsQuietNaN(s1_proc));
9291 VIXL_ASSERT(IsQuietNaN(s2_proc));
9292 VIXL_ASSERT(IsQuietNaN(sa_proc));
9293 VIXL_ASSERT(IsQuietNaN(q1_proc));
9294 VIXL_ASSERT(IsQuietNaN(q2_proc));
9295 VIXL_ASSERT(IsQuietNaN(qa_proc));
armvixlf37fdc02014-02-05 13:22:16 +00009296
armvixl5799d6c2014-05-01 11:05:00 +01009297 // Negated NaNs as it would be done on ARMv8 hardware.
9298 double s1_proc_neg = rawbits_to_double(0xfffd555511111111);
9299 double sa_proc_neg = rawbits_to_double(0xfffd5555aaaaaaaa);
9300 double q1_proc_neg = rawbits_to_double(0xfffaaaaa11111111);
9301 double qa_proc_neg = rawbits_to_double(0xfffaaaaaaaaaaaaa);
9302 VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
9303 VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
9304 VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
9305 VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
9306
armvixlb0c8ae22014-03-21 14:03:59 +00009307 // Quiet NaNs are propagated.
armvixl5799d6c2014-05-01 11:05:00 +01009308 FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009309 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009310 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9311 FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
9312 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9313 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9314 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00009315
armvixlb0c8ae22014-03-21 14:03:59 +00009316 // Signalling NaNs are propagated, and made quiet.
armvixl5799d6c2014-05-01 11:05:00 +01009317 FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009318 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009319 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9320 FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9321 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9322 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9323 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00009324
armvixlb0c8ae22014-03-21 14:03:59 +00009325 // Signalling NaNs take precedence over quiet NaNs.
armvixl5799d6c2014-05-01 11:05:00 +01009326 FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009327 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009328 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9329 FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9330 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9331 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9332 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00009333
armvixlb0c8ae22014-03-21 14:03:59 +00009334 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
9335 FmaddFmsubHelper(0, kFP64PositiveInfinity, qa,
9336 kFP64DefaultNaN, kFP64DefaultNaN,
9337 kFP64DefaultNaN, kFP64DefaultNaN);
9338 FmaddFmsubHelper(kFP64PositiveInfinity, 0, qa,
9339 kFP64DefaultNaN, kFP64DefaultNaN,
9340 kFP64DefaultNaN, kFP64DefaultNaN);
9341 FmaddFmsubHelper(0, kFP64NegativeInfinity, qa,
9342 kFP64DefaultNaN, kFP64DefaultNaN,
9343 kFP64DefaultNaN, kFP64DefaultNaN);
9344 FmaddFmsubHelper(kFP64NegativeInfinity, 0, qa,
9345 kFP64DefaultNaN, kFP64DefaultNaN,
9346 kFP64DefaultNaN, kFP64DefaultNaN);
9347}
armvixlf37fdc02014-02-05 13:22:16 +00009348
armvixlf37fdc02014-02-05 13:22:16 +00009349
armvixlb0c8ae22014-03-21 14:03:59 +00009350TEST(fmadd_fmsub_float_nans) {
9351 // Make sure that NaN propagation works correctly.
9352 float s1 = rawbits_to_float(0x7f951111);
9353 float s2 = rawbits_to_float(0x7f952222);
9354 float sa = rawbits_to_float(0x7f95aaaa);
9355 float q1 = rawbits_to_float(0x7fea1111);
9356 float q2 = rawbits_to_float(0x7fea2222);
9357 float qa = rawbits_to_float(0x7feaaaaa);
9358 VIXL_ASSERT(IsSignallingNaN(s1));
9359 VIXL_ASSERT(IsSignallingNaN(s2));
9360 VIXL_ASSERT(IsSignallingNaN(sa));
9361 VIXL_ASSERT(IsQuietNaN(q1));
9362 VIXL_ASSERT(IsQuietNaN(q2));
9363 VIXL_ASSERT(IsQuietNaN(qa));
armvixlf37fdc02014-02-05 13:22:16 +00009364
armvixlb0c8ae22014-03-21 14:03:59 +00009365 // The input NaNs after passing through ProcessNaN.
9366 float s1_proc = rawbits_to_float(0x7fd51111);
9367 float s2_proc = rawbits_to_float(0x7fd52222);
9368 float sa_proc = rawbits_to_float(0x7fd5aaaa);
9369 float q1_proc = q1;
9370 float q2_proc = q2;
9371 float qa_proc = qa;
9372 VIXL_ASSERT(IsQuietNaN(s1_proc));
9373 VIXL_ASSERT(IsQuietNaN(s2_proc));
9374 VIXL_ASSERT(IsQuietNaN(sa_proc));
9375 VIXL_ASSERT(IsQuietNaN(q1_proc));
9376 VIXL_ASSERT(IsQuietNaN(q2_proc));
9377 VIXL_ASSERT(IsQuietNaN(qa_proc));
9378
armvixl5799d6c2014-05-01 11:05:00 +01009379 // Negated NaNs as it would be done on ARMv8 hardware.
9380 float s1_proc_neg = rawbits_to_float(0xffd51111);
9381 float sa_proc_neg = rawbits_to_float(0xffd5aaaa);
9382 float q1_proc_neg = rawbits_to_float(0xffea1111);
9383 float qa_proc_neg = rawbits_to_float(0xffeaaaaa);
9384 VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
9385 VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
9386 VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
9387 VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
9388
armvixlb0c8ae22014-03-21 14:03:59 +00009389 // Quiet NaNs are propagated.
armvixl5799d6c2014-05-01 11:05:00 +01009390 FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009391 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009392 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9393 FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
9394 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9395 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9396 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00009397
9398 // Signalling NaNs are propagated, and made quiet.
armvixl5799d6c2014-05-01 11:05:00 +01009399 FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009400 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009401 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9402 FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9403 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9404 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9405 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00009406
9407 // Signalling NaNs take precedence over quiet NaNs.
armvixl5799d6c2014-05-01 11:05:00 +01009408 FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009409 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009410 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9411 FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9412 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9413 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9414 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00009415
9416 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
9417 FmaddFmsubHelper(0, kFP32PositiveInfinity, qa,
9418 kFP32DefaultNaN, kFP32DefaultNaN,
9419 kFP32DefaultNaN, kFP32DefaultNaN);
9420 FmaddFmsubHelper(kFP32PositiveInfinity, 0, qa,
9421 kFP32DefaultNaN, kFP32DefaultNaN,
9422 kFP32DefaultNaN, kFP32DefaultNaN);
9423 FmaddFmsubHelper(0, kFP32NegativeInfinity, qa,
9424 kFP32DefaultNaN, kFP32DefaultNaN,
9425 kFP32DefaultNaN, kFP32DefaultNaN);
9426 FmaddFmsubHelper(kFP32NegativeInfinity, 0, qa,
9427 kFP32DefaultNaN, kFP32DefaultNaN,
9428 kFP32DefaultNaN, kFP32DefaultNaN);
armvixlf37fdc02014-02-05 13:22:16 +00009429}
9430
9431
armvixlad96eda2013-06-14 11:42:37 +01009432TEST(fdiv) {
9433 SETUP();
9434
9435 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009436 __ Fmov(s14, -0.0f);
9437 __ Fmov(s15, kFP32PositiveInfinity);
9438 __ Fmov(s16, kFP32NegativeInfinity);
9439 __ Fmov(s17, 3.25f);
9440 __ Fmov(s18, 2.0f);
9441 __ Fmov(s19, 2.0f);
9442 __ Fmov(s20, -2.0f);
armvixlad96eda2013-06-14 11:42:37 +01009443
9444 __ Fmov(d26, -0.0);
9445 __ Fmov(d27, kFP64PositiveInfinity);
9446 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009447 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01009448 __ Fmov(d30, -2.0);
9449 __ Fmov(d31, 2.25);
9450
armvixlb0c8ae22014-03-21 14:03:59 +00009451 __ Fdiv(s0, s17, s18);
9452 __ Fdiv(s1, s18, s19);
9453 __ Fdiv(s2, s14, s18);
9454 __ Fdiv(s3, s18, s15);
9455 __ Fdiv(s4, s18, s16);
9456 __ Fdiv(s5, s15, s16);
9457 __ Fdiv(s6, s14, s14);
9458
9459 __ Fdiv(d7, d31, d30);
9460 __ Fdiv(d8, d29, d31);
9461 __ Fdiv(d9, d26, d31);
9462 __ Fdiv(d10, d31, d27);
9463 __ Fdiv(d11, d31, d28);
9464 __ Fdiv(d12, d28, d27);
9465 __ Fdiv(d13, d29, d29);
armvixlad96eda2013-06-14 11:42:37 +01009466 END();
9467
9468 RUN();
9469
armvixlb0c8ae22014-03-21 14:03:59 +00009470 ASSERT_EQUAL_FP32(1.625f, s0);
9471 ASSERT_EQUAL_FP32(1.0f, s1);
9472 ASSERT_EQUAL_FP32(-0.0f, s2);
9473 ASSERT_EQUAL_FP32(0.0f, s3);
9474 ASSERT_EQUAL_FP32(-0.0f, s4);
9475 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9476 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9477 ASSERT_EQUAL_FP64(-1.125, d7);
armvixlad96eda2013-06-14 11:42:37 +01009478 ASSERT_EQUAL_FP64(0.0, d8);
9479 ASSERT_EQUAL_FP64(-0.0, d9);
armvixlb0c8ae22014-03-21 14:03:59 +00009480 ASSERT_EQUAL_FP64(0.0, d10);
9481 ASSERT_EQUAL_FP64(-0.0, d11);
9482 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9483 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009484
9485 TEARDOWN();
9486}
9487
9488
armvixlf37fdc02014-02-05 13:22:16 +00009489static float MinMaxHelper(float n,
9490 float m,
9491 bool min,
9492 float quiet_nan_substitute = 0.0) {
armvixlb0c8ae22014-03-21 14:03:59 +00009493 const uint64_t kFP32QuietNaNMask = 0x00400000;
armvixlf37fdc02014-02-05 13:22:16 +00009494 uint32_t raw_n = float_to_rawbits(n);
9495 uint32_t raw_m = float_to_rawbits(m);
armvixlad96eda2013-06-14 11:42:37 +01009496
armvixl6e2c8272015-03-31 11:04:14 +01009497 if (std::isnan(n) && ((raw_n & kFP32QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009498 // n is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009499 return rawbits_to_float(raw_n | kFP32QuietNaNMask);
armvixl6e2c8272015-03-31 11:04:14 +01009500 } else if (std::isnan(m) && ((raw_m & kFP32QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009501 // m is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009502 return rawbits_to_float(raw_m | kFP32QuietNaNMask);
armvixlf37fdc02014-02-05 13:22:16 +00009503 } else if (quiet_nan_substitute == 0.0) {
armvixl6e2c8272015-03-31 11:04:14 +01009504 if (std::isnan(n)) {
armvixlf37fdc02014-02-05 13:22:16 +00009505 // n is quiet NaN.
9506 return n;
armvixl6e2c8272015-03-31 11:04:14 +01009507 } else if (std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009508 // m is quiet NaN.
9509 return m;
9510 }
9511 } else {
9512 // Substitute n or m if one is quiet, but not both.
armvixl6e2c8272015-03-31 11:04:14 +01009513 if (std::isnan(n) && !std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009514 // n is quiet NaN: replace with substitute.
9515 n = quiet_nan_substitute;
armvixl6e2c8272015-03-31 11:04:14 +01009516 } else if (!std::isnan(n) && std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009517 // m is quiet NaN: replace with substitute.
9518 m = quiet_nan_substitute;
armvixlad96eda2013-06-14 11:42:37 +01009519 }
9520 }
armvixlad96eda2013-06-14 11:42:37 +01009521
armvixlf37fdc02014-02-05 13:22:16 +00009522 if ((n == 0.0) && (m == 0.0) &&
9523 (copysign(1.0, n) != copysign(1.0, m))) {
9524 return min ? -0.0 : 0.0;
9525 }
armvixlad96eda2013-06-14 11:42:37 +01009526
armvixlf37fdc02014-02-05 13:22:16 +00009527 return min ? fminf(n, m) : fmaxf(n, m);
armvixlad96eda2013-06-14 11:42:37 +01009528}
9529
9530
armvixlf37fdc02014-02-05 13:22:16 +00009531static double MinMaxHelper(double n,
9532 double m,
9533 bool min,
9534 double quiet_nan_substitute = 0.0) {
armvixlb0c8ae22014-03-21 14:03:59 +00009535 const uint64_t kFP64QuietNaNMask = 0x0008000000000000;
armvixlf37fdc02014-02-05 13:22:16 +00009536 uint64_t raw_n = double_to_rawbits(n);
9537 uint64_t raw_m = double_to_rawbits(m);
armvixlad96eda2013-06-14 11:42:37 +01009538
armvixl6e2c8272015-03-31 11:04:14 +01009539 if (std::isnan(n) && ((raw_n & kFP64QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009540 // n is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009541 return rawbits_to_double(raw_n | kFP64QuietNaNMask);
armvixl6e2c8272015-03-31 11:04:14 +01009542 } else if (std::isnan(m) && ((raw_m & kFP64QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009543 // m is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009544 return rawbits_to_double(raw_m | kFP64QuietNaNMask);
armvixlf37fdc02014-02-05 13:22:16 +00009545 } else if (quiet_nan_substitute == 0.0) {
armvixl6e2c8272015-03-31 11:04:14 +01009546 if (std::isnan(n)) {
armvixlf37fdc02014-02-05 13:22:16 +00009547 // n is quiet NaN.
9548 return n;
armvixl6e2c8272015-03-31 11:04:14 +01009549 } else if (std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009550 // m is quiet NaN.
9551 return m;
9552 }
9553 } else {
9554 // Substitute n or m if one is quiet, but not both.
armvixl6e2c8272015-03-31 11:04:14 +01009555 if (std::isnan(n) && !std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009556 // n is quiet NaN: replace with substitute.
9557 n = quiet_nan_substitute;
armvixl6e2c8272015-03-31 11:04:14 +01009558 } else if (!std::isnan(n) && std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009559 // m is quiet NaN: replace with substitute.
9560 m = quiet_nan_substitute;
armvixlad96eda2013-06-14 11:42:37 +01009561 }
9562 }
armvixlf37fdc02014-02-05 13:22:16 +00009563
9564 if ((n == 0.0) && (m == 0.0) &&
9565 (copysign(1.0, n) != copysign(1.0, m))) {
9566 return min ? -0.0 : 0.0;
9567 }
9568
9569 return min ? fmin(n, m) : fmax(n, m);
9570}
9571
9572
9573static void FminFmaxDoubleHelper(double n, double m, double min, double max,
9574 double minnm, double maxnm) {
9575 SETUP();
9576
9577 START();
9578 __ Fmov(d0, n);
9579 __ Fmov(d1, m);
9580 __ Fmin(d28, d0, d1);
9581 __ Fmax(d29, d0, d1);
9582 __ Fminnm(d30, d0, d1);
9583 __ Fmaxnm(d31, d0, d1);
armvixlad96eda2013-06-14 11:42:37 +01009584 END();
9585
9586 RUN();
9587
armvixlf37fdc02014-02-05 13:22:16 +00009588 ASSERT_EQUAL_FP64(min, d28);
9589 ASSERT_EQUAL_FP64(max, d29);
9590 ASSERT_EQUAL_FP64(minnm, d30);
9591 ASSERT_EQUAL_FP64(maxnm, d31);
armvixlad96eda2013-06-14 11:42:37 +01009592
9593 TEARDOWN();
9594}
9595
9596
armvixlf37fdc02014-02-05 13:22:16 +00009597TEST(fmax_fmin_d) {
armvixlb0c8ae22014-03-21 14:03:59 +00009598 // Use non-standard NaNs to check that the payload bits are preserved.
9599 double snan = rawbits_to_double(0x7ff5555512345678);
9600 double qnan = rawbits_to_double(0x7ffaaaaa87654321);
9601
9602 double snan_processed = rawbits_to_double(0x7ffd555512345678);
9603 double qnan_processed = qnan;
9604
9605 VIXL_ASSERT(IsSignallingNaN(snan));
9606 VIXL_ASSERT(IsQuietNaN(qnan));
9607 VIXL_ASSERT(IsQuietNaN(snan_processed));
9608 VIXL_ASSERT(IsQuietNaN(qnan_processed));
9609
armvixlf37fdc02014-02-05 13:22:16 +00009610 // Bootstrap tests.
9611 FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0);
9612 FminFmaxDoubleHelper(0, 1, 0, 1, 0, 1);
9613 FminFmaxDoubleHelper(kFP64PositiveInfinity, kFP64NegativeInfinity,
9614 kFP64NegativeInfinity, kFP64PositiveInfinity,
9615 kFP64NegativeInfinity, kFP64PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009616 FminFmaxDoubleHelper(snan, 0,
9617 snan_processed, snan_processed,
9618 snan_processed, snan_processed);
9619 FminFmaxDoubleHelper(0, snan,
9620 snan_processed, snan_processed,
9621 snan_processed, snan_processed);
9622 FminFmaxDoubleHelper(qnan, 0,
9623 qnan_processed, qnan_processed,
armvixlf37fdc02014-02-05 13:22:16 +00009624 0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00009625 FminFmaxDoubleHelper(0, qnan,
9626 qnan_processed, qnan_processed,
9627 0, 0);
9628 FminFmaxDoubleHelper(qnan, snan,
9629 snan_processed, snan_processed,
9630 snan_processed, snan_processed);
9631 FminFmaxDoubleHelper(snan, qnan,
9632 snan_processed, snan_processed,
9633 snan_processed, snan_processed);
armvixlf37fdc02014-02-05 13:22:16 +00009634
9635 // Iterate over all combinations of inputs.
9636 double inputs[] = { DBL_MAX, DBL_MIN, 1.0, 0.0,
9637 -DBL_MAX, -DBL_MIN, -1.0, -0.0,
9638 kFP64PositiveInfinity, kFP64NegativeInfinity,
9639 kFP64QuietNaN, kFP64SignallingNaN };
9640
9641 const int count = sizeof(inputs) / sizeof(inputs[0]);
9642
9643 for (int in = 0; in < count; in++) {
9644 double n = inputs[in];
9645 for (int im = 0; im < count; im++) {
9646 double m = inputs[im];
9647 FminFmaxDoubleHelper(n, m,
9648 MinMaxHelper(n, m, true),
9649 MinMaxHelper(n, m, false),
9650 MinMaxHelper(n, m, true, kFP64PositiveInfinity),
9651 MinMaxHelper(n, m, false, kFP64NegativeInfinity));
9652 }
9653 }
9654}
9655
9656
9657static void FminFmaxFloatHelper(float n, float m, float min, float max,
9658 float minnm, float maxnm) {
9659 SETUP();
9660
9661 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009662 __ Fmov(s0, n);
9663 __ Fmov(s1, m);
armvixlf37fdc02014-02-05 13:22:16 +00009664 __ Fmin(s28, s0, s1);
9665 __ Fmax(s29, s0, s1);
9666 __ Fminnm(s30, s0, s1);
9667 __ Fmaxnm(s31, s0, s1);
9668 END();
9669
9670 RUN();
9671
9672 ASSERT_EQUAL_FP32(min, s28);
9673 ASSERT_EQUAL_FP32(max, s29);
9674 ASSERT_EQUAL_FP32(minnm, s30);
9675 ASSERT_EQUAL_FP32(maxnm, s31);
9676
9677 TEARDOWN();
9678}
9679
9680
9681TEST(fmax_fmin_s) {
armvixlb0c8ae22014-03-21 14:03:59 +00009682 // Use non-standard NaNs to check that the payload bits are preserved.
9683 float snan = rawbits_to_float(0x7f951234);
9684 float qnan = rawbits_to_float(0x7fea8765);
9685
9686 float snan_processed = rawbits_to_float(0x7fd51234);
9687 float qnan_processed = qnan;
9688
9689 VIXL_ASSERT(IsSignallingNaN(snan));
9690 VIXL_ASSERT(IsQuietNaN(qnan));
9691 VIXL_ASSERT(IsQuietNaN(snan_processed));
9692 VIXL_ASSERT(IsQuietNaN(qnan_processed));
9693
armvixlf37fdc02014-02-05 13:22:16 +00009694 // Bootstrap tests.
9695 FminFmaxFloatHelper(0, 0, 0, 0, 0, 0);
9696 FminFmaxFloatHelper(0, 1, 0, 1, 0, 1);
9697 FminFmaxFloatHelper(kFP32PositiveInfinity, kFP32NegativeInfinity,
9698 kFP32NegativeInfinity, kFP32PositiveInfinity,
9699 kFP32NegativeInfinity, kFP32PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009700 FminFmaxFloatHelper(snan, 0,
9701 snan_processed, snan_processed,
9702 snan_processed, snan_processed);
9703 FminFmaxFloatHelper(0, snan,
9704 snan_processed, snan_processed,
9705 snan_processed, snan_processed);
9706 FminFmaxFloatHelper(qnan, 0,
9707 qnan_processed, qnan_processed,
armvixlf37fdc02014-02-05 13:22:16 +00009708 0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00009709 FminFmaxFloatHelper(0, qnan,
9710 qnan_processed, qnan_processed,
9711 0, 0);
9712 FminFmaxFloatHelper(qnan, snan,
9713 snan_processed, snan_processed,
9714 snan_processed, snan_processed);
9715 FminFmaxFloatHelper(snan, qnan,
9716 snan_processed, snan_processed,
9717 snan_processed, snan_processed);
armvixlf37fdc02014-02-05 13:22:16 +00009718
9719 // Iterate over all combinations of inputs.
9720 float inputs[] = { FLT_MAX, FLT_MIN, 1.0, 0.0,
9721 -FLT_MAX, -FLT_MIN, -1.0, -0.0,
9722 kFP32PositiveInfinity, kFP32NegativeInfinity,
9723 kFP32QuietNaN, kFP32SignallingNaN };
9724
9725 const int count = sizeof(inputs) / sizeof(inputs[0]);
9726
9727 for (int in = 0; in < count; in++) {
9728 float n = inputs[in];
9729 for (int im = 0; im < count; im++) {
9730 float m = inputs[im];
9731 FminFmaxFloatHelper(n, m,
9732 MinMaxHelper(n, m, true),
9733 MinMaxHelper(n, m, false),
9734 MinMaxHelper(n, m, true, kFP32PositiveInfinity),
9735 MinMaxHelper(n, m, false, kFP32NegativeInfinity));
9736 }
9737 }
9738}
9739
9740
armvixlad96eda2013-06-14 11:42:37 +01009741TEST(fccmp) {
9742 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01009743 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01009744
9745 START();
9746 __ Fmov(s16, 0.0);
9747 __ Fmov(s17, 0.5);
9748 __ Fmov(d18, -0.5);
9749 __ Fmov(d19, -1.0);
9750 __ Mov(x20, 0);
armvixl6e2c8272015-03-31 11:04:14 +01009751 __ Mov(x21, 0x7ff0000000000001); // Double precision NaN.
9752 __ Fmov(d21, x21);
9753 __ Mov(w22, 0x7f800001); // Single precision NaN.
9754 __ Fmov(s22, w22);
armvixlad96eda2013-06-14 11:42:37 +01009755
armvixl578645f2013-08-15 17:21:42 +01009756 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009757 __ Fccmp(s16, s16, NoFlag, eq);
9758 __ Mrs(x0, NZCV);
9759
armvixl578645f2013-08-15 17:21:42 +01009760 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009761 __ Fccmp(s16, s16, VFlag, ne);
9762 __ Mrs(x1, NZCV);
9763
armvixl578645f2013-08-15 17:21:42 +01009764 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009765 __ Fccmp(s16, s17, CFlag, ge);
9766 __ Mrs(x2, NZCV);
9767
armvixl578645f2013-08-15 17:21:42 +01009768 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009769 __ Fccmp(s16, s17, CVFlag, lt);
9770 __ Mrs(x3, NZCV);
9771
armvixl578645f2013-08-15 17:21:42 +01009772 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009773 __ Fccmp(d18, d18, ZFlag, le);
9774 __ Mrs(x4, NZCV);
9775
armvixl578645f2013-08-15 17:21:42 +01009776 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009777 __ Fccmp(d18, d18, ZVFlag, gt);
9778 __ Mrs(x5, NZCV);
9779
armvixl578645f2013-08-15 17:21:42 +01009780 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009781 __ Fccmp(d18, d19, ZCVFlag, ls);
9782 __ Mrs(x6, NZCV);
9783
armvixl578645f2013-08-15 17:21:42 +01009784 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009785 __ Fccmp(d18, d19, NFlag, hi);
9786 __ Mrs(x7, NZCV);
armvixl578645f2013-08-15 17:21:42 +01009787
armvixlc68cb642014-09-25 18:49:30 +01009788 // The Macro Assembler does not allow al or nv as condition.
armvixl578645f2013-08-15 17:21:42 +01009789 __ fccmp(s16, s16, NFlag, al);
9790 __ Mrs(x8, NZCV);
9791
9792 __ fccmp(d18, d18, NFlag, nv);
9793 __ Mrs(x9, NZCV);
armvixl6e2c8272015-03-31 11:04:14 +01009794
9795 __ Cmp(x20, 0);
9796 __ Fccmpe(s16, s16, NoFlag, eq);
9797 __ Mrs(x10, NZCV);
9798
9799 __ Cmp(x20, 0);
9800 __ Fccmpe(d18, d19, ZCVFlag, ls);
9801 __ Mrs(x11, NZCV);
9802
9803 __ Cmp(x20, 0);
9804 __ Fccmpe(d21, d21, NoFlag, eq);
9805 __ Mrs(x12, NZCV);
9806
9807 __ Cmp(x20, 0);
9808 __ Fccmpe(s22, s22, NoFlag, eq);
9809 __ Mrs(x13, NZCV);
armvixlad96eda2013-06-14 11:42:37 +01009810 END();
9811
9812 RUN();
9813
9814 ASSERT_EQUAL_32(ZCFlag, w0);
9815 ASSERT_EQUAL_32(VFlag, w1);
9816 ASSERT_EQUAL_32(NFlag, w2);
9817 ASSERT_EQUAL_32(CVFlag, w3);
9818 ASSERT_EQUAL_32(ZCFlag, w4);
9819 ASSERT_EQUAL_32(ZVFlag, w5);
9820 ASSERT_EQUAL_32(CFlag, w6);
9821 ASSERT_EQUAL_32(NFlag, w7);
armvixl578645f2013-08-15 17:21:42 +01009822 ASSERT_EQUAL_32(ZCFlag, w8);
9823 ASSERT_EQUAL_32(ZCFlag, w9);
armvixl6e2c8272015-03-31 11:04:14 +01009824 ASSERT_EQUAL_32(ZCFlag, w10);
9825 ASSERT_EQUAL_32(CFlag, w11);
9826 ASSERT_EQUAL_32(CVFlag, w12);
9827 ASSERT_EQUAL_32(CVFlag, w13);
armvixlad96eda2013-06-14 11:42:37 +01009828
9829 TEARDOWN();
9830}
9831
9832
9833TEST(fcmp) {
9834 SETUP();
9835
9836 START();
armvixlf37fdc02014-02-05 13:22:16 +00009837
9838 // Some of these tests require a floating-point scratch register assigned to
9839 // the macro assembler, but most do not.
armvixlb0c8ae22014-03-21 14:03:59 +00009840 {
9841 UseScratchRegisterScope temps(&masm);
9842 temps.ExcludeAll();
9843 temps.Include(ip0, ip1);
armvixlf37fdc02014-02-05 13:22:16 +00009844
armvixlb0c8ae22014-03-21 14:03:59 +00009845 __ Fmov(s8, 0.0);
9846 __ Fmov(s9, 0.5);
9847 __ Mov(w18, 0x7f800001); // Single precision NaN.
9848 __ Fmov(s18, w18);
armvixlad96eda2013-06-14 11:42:37 +01009849
armvixlb0c8ae22014-03-21 14:03:59 +00009850 __ Fcmp(s8, s8);
9851 __ Mrs(x0, NZCV);
9852 __ Fcmp(s8, s9);
9853 __ Mrs(x1, NZCV);
9854 __ Fcmp(s9, s8);
9855 __ Mrs(x2, NZCV);
9856 __ Fcmp(s8, s18);
9857 __ Mrs(x3, NZCV);
9858 __ Fcmp(s18, s18);
9859 __ Mrs(x4, NZCV);
9860 __ Fcmp(s8, 0.0);
9861 __ Mrs(x5, NZCV);
9862 temps.Include(d0);
9863 __ Fcmp(s8, 255.0);
9864 temps.Exclude(d0);
9865 __ Mrs(x6, NZCV);
armvixlad96eda2013-06-14 11:42:37 +01009866
armvixlb0c8ae22014-03-21 14:03:59 +00009867 __ Fmov(d19, 0.0);
9868 __ Fmov(d20, 0.5);
9869 __ Mov(x21, 0x7ff0000000000001); // Double precision NaN.
9870 __ Fmov(d21, x21);
armvixlad96eda2013-06-14 11:42:37 +01009871
armvixlb0c8ae22014-03-21 14:03:59 +00009872 __ Fcmp(d19, d19);
9873 __ Mrs(x10, NZCV);
9874 __ Fcmp(d19, d20);
9875 __ Mrs(x11, NZCV);
9876 __ Fcmp(d20, d19);
9877 __ Mrs(x12, NZCV);
9878 __ Fcmp(d19, d21);
9879 __ Mrs(x13, NZCV);
9880 __ Fcmp(d21, d21);
9881 __ Mrs(x14, NZCV);
9882 __ Fcmp(d19, 0.0);
9883 __ Mrs(x15, NZCV);
9884 temps.Include(d0);
9885 __ Fcmp(d19, 12.3456);
9886 temps.Exclude(d0);
9887 __ Mrs(x16, NZCV);
armvixl6e2c8272015-03-31 11:04:14 +01009888
9889 __ Fcmpe(s8, s8);
9890 __ Mrs(x22, NZCV);
9891 __ Fcmpe(s8, 0.0);
9892 __ Mrs(x23, NZCV);
9893 __ Fcmpe(d19, d19);
9894 __ Mrs(x24, NZCV);
9895 __ Fcmpe(d19, 0.0);
9896 __ Mrs(x25, NZCV);
9897 __ Fcmpe(s18, s18);
9898 __ Mrs(x26, NZCV);
9899 __ Fcmpe(d21, d21);
9900 __ Mrs(x27, NZCV);
armvixlb0c8ae22014-03-21 14:03:59 +00009901 }
9902
armvixlad96eda2013-06-14 11:42:37 +01009903 END();
9904
9905 RUN();
9906
9907 ASSERT_EQUAL_32(ZCFlag, w0);
9908 ASSERT_EQUAL_32(NFlag, w1);
9909 ASSERT_EQUAL_32(CFlag, w2);
9910 ASSERT_EQUAL_32(CVFlag, w3);
9911 ASSERT_EQUAL_32(CVFlag, w4);
9912 ASSERT_EQUAL_32(ZCFlag, w5);
9913 ASSERT_EQUAL_32(NFlag, w6);
9914 ASSERT_EQUAL_32(ZCFlag, w10);
9915 ASSERT_EQUAL_32(NFlag, w11);
9916 ASSERT_EQUAL_32(CFlag, w12);
9917 ASSERT_EQUAL_32(CVFlag, w13);
9918 ASSERT_EQUAL_32(CVFlag, w14);
9919 ASSERT_EQUAL_32(ZCFlag, w15);
9920 ASSERT_EQUAL_32(NFlag, w16);
armvixl6e2c8272015-03-31 11:04:14 +01009921 ASSERT_EQUAL_32(ZCFlag, w22);
9922 ASSERT_EQUAL_32(ZCFlag, w23);
9923 ASSERT_EQUAL_32(ZCFlag, w24);
9924 ASSERT_EQUAL_32(ZCFlag, w25);
9925 ASSERT_EQUAL_32(CVFlag, w26);
9926 ASSERT_EQUAL_32(CVFlag, w27);
armvixlad96eda2013-06-14 11:42:37 +01009927
9928 TEARDOWN();
9929}
9930
9931
9932TEST(fcsel) {
9933 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01009934 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01009935
9936 START();
9937 __ Mov(x16, 0);
9938 __ Fmov(s16, 1.0);
9939 __ Fmov(s17, 2.0);
9940 __ Fmov(d18, 3.0);
9941 __ Fmov(d19, 4.0);
9942
armvixl578645f2013-08-15 17:21:42 +01009943 __ Cmp(x16, 0);
armvixlad96eda2013-06-14 11:42:37 +01009944 __ Fcsel(s0, s16, s17, eq);
9945 __ Fcsel(s1, s16, s17, ne);
9946 __ Fcsel(d2, d18, d19, eq);
9947 __ Fcsel(d3, d18, d19, ne);
armvixlc68cb642014-09-25 18:49:30 +01009948 // The Macro Assembler does not allow al or nv as condition.
armvixl578645f2013-08-15 17:21:42 +01009949 __ fcsel(s4, s16, s17, al);
9950 __ fcsel(d5, d18, d19, nv);
armvixlad96eda2013-06-14 11:42:37 +01009951 END();
9952
9953 RUN();
9954
9955 ASSERT_EQUAL_FP32(1.0, s0);
9956 ASSERT_EQUAL_FP32(2.0, s1);
9957 ASSERT_EQUAL_FP64(3.0, d2);
9958 ASSERT_EQUAL_FP64(4.0, d3);
armvixl578645f2013-08-15 17:21:42 +01009959 ASSERT_EQUAL_FP32(1.0, s4);
9960 ASSERT_EQUAL_FP64(3.0, d5);
armvixlad96eda2013-06-14 11:42:37 +01009961
9962 TEARDOWN();
9963}
9964
9965
9966TEST(fneg) {
9967 SETUP();
9968
9969 START();
9970 __ Fmov(s16, 1.0);
9971 __ Fmov(s17, 0.0);
9972 __ Fmov(s18, kFP32PositiveInfinity);
9973 __ Fmov(d19, 1.0);
9974 __ Fmov(d20, 0.0);
9975 __ Fmov(d21, kFP64PositiveInfinity);
9976
9977 __ Fneg(s0, s16);
9978 __ Fneg(s1, s0);
9979 __ Fneg(s2, s17);
9980 __ Fneg(s3, s2);
9981 __ Fneg(s4, s18);
9982 __ Fneg(s5, s4);
9983 __ Fneg(d6, d19);
9984 __ Fneg(d7, d6);
9985 __ Fneg(d8, d20);
9986 __ Fneg(d9, d8);
9987 __ Fneg(d10, d21);
9988 __ Fneg(d11, d10);
9989 END();
9990
9991 RUN();
9992
9993 ASSERT_EQUAL_FP32(-1.0, s0);
9994 ASSERT_EQUAL_FP32(1.0, s1);
9995 ASSERT_EQUAL_FP32(-0.0, s2);
9996 ASSERT_EQUAL_FP32(0.0, s3);
9997 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
9998 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
9999 ASSERT_EQUAL_FP64(-1.0, d6);
10000 ASSERT_EQUAL_FP64(1.0, d7);
10001 ASSERT_EQUAL_FP64(-0.0, d8);
10002 ASSERT_EQUAL_FP64(0.0, d9);
10003 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
10004 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
10005
10006 TEARDOWN();
10007}
10008
10009
10010TEST(fabs) {
10011 SETUP();
10012
10013 START();
10014 __ Fmov(s16, -1.0);
10015 __ Fmov(s17, -0.0);
10016 __ Fmov(s18, kFP32NegativeInfinity);
10017 __ Fmov(d19, -1.0);
10018 __ Fmov(d20, -0.0);
10019 __ Fmov(d21, kFP64NegativeInfinity);
10020
10021 __ Fabs(s0, s16);
10022 __ Fabs(s1, s0);
10023 __ Fabs(s2, s17);
10024 __ Fabs(s3, s18);
10025 __ Fabs(d4, d19);
10026 __ Fabs(d5, d4);
10027 __ Fabs(d6, d20);
10028 __ Fabs(d7, d21);
10029 END();
10030
10031 RUN();
10032
10033 ASSERT_EQUAL_FP32(1.0, s0);
10034 ASSERT_EQUAL_FP32(1.0, s1);
10035 ASSERT_EQUAL_FP32(0.0, s2);
10036 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
10037 ASSERT_EQUAL_FP64(1.0, d4);
10038 ASSERT_EQUAL_FP64(1.0, d5);
10039 ASSERT_EQUAL_FP64(0.0, d6);
10040 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
10041
10042 TEARDOWN();
10043}
10044
10045
10046TEST(fsqrt) {
10047 SETUP();
10048
10049 START();
10050 __ Fmov(s16, 0.0);
10051 __ Fmov(s17, 1.0);
10052 __ Fmov(s18, 0.25);
10053 __ Fmov(s19, 65536.0);
10054 __ Fmov(s20, -0.0);
10055 __ Fmov(s21, kFP32PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000010056 __ Fmov(s22, -1.0);
10057 __ Fmov(d23, 0.0);
10058 __ Fmov(d24, 1.0);
10059 __ Fmov(d25, 0.25);
10060 __ Fmov(d26, 4294967296.0);
10061 __ Fmov(d27, -0.0);
10062 __ Fmov(d28, kFP64PositiveInfinity);
10063 __ Fmov(d29, -1.0);
armvixlad96eda2013-06-14 11:42:37 +010010064
10065 __ Fsqrt(s0, s16);
10066 __ Fsqrt(s1, s17);
10067 __ Fsqrt(s2, s18);
10068 __ Fsqrt(s3, s19);
10069 __ Fsqrt(s4, s20);
10070 __ Fsqrt(s5, s21);
armvixlb0c8ae22014-03-21 14:03:59 +000010071 __ Fsqrt(s6, s22);
armvixlad96eda2013-06-14 11:42:37 +010010072 __ Fsqrt(d7, d23);
10073 __ Fsqrt(d8, d24);
10074 __ Fsqrt(d9, d25);
10075 __ Fsqrt(d10, d26);
10076 __ Fsqrt(d11, d27);
armvixlb0c8ae22014-03-21 14:03:59 +000010077 __ Fsqrt(d12, d28);
10078 __ Fsqrt(d13, d29);
armvixlad96eda2013-06-14 11:42:37 +010010079 END();
10080
10081 RUN();
10082
10083 ASSERT_EQUAL_FP32(0.0, s0);
10084 ASSERT_EQUAL_FP32(1.0, s1);
10085 ASSERT_EQUAL_FP32(0.5, s2);
10086 ASSERT_EQUAL_FP32(256.0, s3);
10087 ASSERT_EQUAL_FP32(-0.0, s4);
10088 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
armvixlb0c8ae22014-03-21 14:03:59 +000010089 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
10090 ASSERT_EQUAL_FP64(0.0, d7);
10091 ASSERT_EQUAL_FP64(1.0, d8);
10092 ASSERT_EQUAL_FP64(0.5, d9);
10093 ASSERT_EQUAL_FP64(65536.0, d10);
10094 ASSERT_EQUAL_FP64(-0.0, d11);
10095 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d12);
10096 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +010010097
10098 TEARDOWN();
10099}
10100
10101
armvixlf37fdc02014-02-05 13:22:16 +000010102TEST(frinta) {
10103 SETUP();
10104
10105 START();
10106 __ Fmov(s16, 1.0);
10107 __ Fmov(s17, 1.1);
10108 __ Fmov(s18, 1.5);
10109 __ Fmov(s19, 1.9);
10110 __ Fmov(s20, 2.5);
10111 __ Fmov(s21, -1.5);
10112 __ Fmov(s22, -2.5);
10113 __ Fmov(s23, kFP32PositiveInfinity);
10114 __ Fmov(s24, kFP32NegativeInfinity);
10115 __ Fmov(s25, 0.0);
10116 __ Fmov(s26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010117 __ Fmov(s27, -0.2);
armvixlf37fdc02014-02-05 13:22:16 +000010118
10119 __ Frinta(s0, s16);
10120 __ Frinta(s1, s17);
10121 __ Frinta(s2, s18);
10122 __ Frinta(s3, s19);
10123 __ Frinta(s4, s20);
10124 __ Frinta(s5, s21);
10125 __ Frinta(s6, s22);
10126 __ Frinta(s7, s23);
10127 __ Frinta(s8, s24);
10128 __ Frinta(s9, s25);
10129 __ Frinta(s10, s26);
armvixl5799d6c2014-05-01 11:05:00 +010010130 __ Frinta(s11, s27);
armvixlf37fdc02014-02-05 13:22:16 +000010131
10132 __ Fmov(d16, 1.0);
10133 __ Fmov(d17, 1.1);
10134 __ Fmov(d18, 1.5);
10135 __ Fmov(d19, 1.9);
10136 __ Fmov(d20, 2.5);
10137 __ Fmov(d21, -1.5);
10138 __ Fmov(d22, -2.5);
10139 __ Fmov(d23, kFP32PositiveInfinity);
10140 __ Fmov(d24, kFP32NegativeInfinity);
10141 __ Fmov(d25, 0.0);
10142 __ Fmov(d26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010143 __ Fmov(d27, -0.2);
armvixlf37fdc02014-02-05 13:22:16 +000010144
armvixl5799d6c2014-05-01 11:05:00 +010010145 __ Frinta(d12, d16);
10146 __ Frinta(d13, d17);
10147 __ Frinta(d14, d18);
10148 __ Frinta(d15, d19);
10149 __ Frinta(d16, d20);
10150 __ Frinta(d17, d21);
10151 __ Frinta(d18, d22);
10152 __ Frinta(d19, d23);
10153 __ Frinta(d20, d24);
10154 __ Frinta(d21, d25);
10155 __ Frinta(d22, d26);
10156 __ Frinta(d23, d27);
armvixlf37fdc02014-02-05 13:22:16 +000010157 END();
10158
10159 RUN();
10160
10161 ASSERT_EQUAL_FP32(1.0, s0);
10162 ASSERT_EQUAL_FP32(1.0, s1);
10163 ASSERT_EQUAL_FP32(2.0, s2);
10164 ASSERT_EQUAL_FP32(2.0, s3);
10165 ASSERT_EQUAL_FP32(3.0, s4);
10166 ASSERT_EQUAL_FP32(-2.0, s5);
10167 ASSERT_EQUAL_FP32(-3.0, s6);
10168 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10169 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10170 ASSERT_EQUAL_FP32(0.0, s9);
10171 ASSERT_EQUAL_FP32(-0.0, s10);
armvixl5799d6c2014-05-01 11:05:00 +010010172 ASSERT_EQUAL_FP32(-0.0, s11);
armvixlf37fdc02014-02-05 13:22:16 +000010173 ASSERT_EQUAL_FP64(1.0, d12);
armvixl5799d6c2014-05-01 11:05:00 +010010174 ASSERT_EQUAL_FP64(1.0, d13);
armvixlf37fdc02014-02-05 13:22:16 +000010175 ASSERT_EQUAL_FP64(2.0, d14);
armvixl5799d6c2014-05-01 11:05:00 +010010176 ASSERT_EQUAL_FP64(2.0, d15);
10177 ASSERT_EQUAL_FP64(3.0, d16);
10178 ASSERT_EQUAL_FP64(-2.0, d17);
10179 ASSERT_EQUAL_FP64(-3.0, d18);
10180 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10181 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10182 ASSERT_EQUAL_FP64(0.0, d21);
10183 ASSERT_EQUAL_FP64(-0.0, d22);
10184 ASSERT_EQUAL_FP64(-0.0, d23);
10185
10186 TEARDOWN();
10187}
10188
10189
armvixl330dc712014-11-25 10:38:32 +000010190TEST(frinti) {
10191 // VIXL only supports the round-to-nearest FPCR mode, so this test has the
10192 // same results as frintn.
10193 SETUP();
10194
10195 START();
10196 __ Fmov(s16, 1.0);
10197 __ Fmov(s17, 1.1);
10198 __ Fmov(s18, 1.5);
10199 __ Fmov(s19, 1.9);
10200 __ Fmov(s20, 2.5);
10201 __ Fmov(s21, -1.5);
10202 __ Fmov(s22, -2.5);
10203 __ Fmov(s23, kFP32PositiveInfinity);
10204 __ Fmov(s24, kFP32NegativeInfinity);
10205 __ Fmov(s25, 0.0);
10206 __ Fmov(s26, -0.0);
10207 __ Fmov(s27, -0.2);
10208
10209 __ Frinti(s0, s16);
10210 __ Frinti(s1, s17);
10211 __ Frinti(s2, s18);
10212 __ Frinti(s3, s19);
10213 __ Frinti(s4, s20);
10214 __ Frinti(s5, s21);
10215 __ Frinti(s6, s22);
10216 __ Frinti(s7, s23);
10217 __ Frinti(s8, s24);
10218 __ Frinti(s9, s25);
10219 __ Frinti(s10, s26);
10220 __ Frinti(s11, s27);
10221
10222 __ Fmov(d16, 1.0);
10223 __ Fmov(d17, 1.1);
10224 __ Fmov(d18, 1.5);
10225 __ Fmov(d19, 1.9);
10226 __ Fmov(d20, 2.5);
10227 __ Fmov(d21, -1.5);
10228 __ Fmov(d22, -2.5);
10229 __ Fmov(d23, kFP32PositiveInfinity);
10230 __ Fmov(d24, kFP32NegativeInfinity);
10231 __ Fmov(d25, 0.0);
10232 __ Fmov(d26, -0.0);
10233 __ Fmov(d27, -0.2);
10234
10235 __ Frinti(d12, d16);
10236 __ Frinti(d13, d17);
10237 __ Frinti(d14, d18);
10238 __ Frinti(d15, d19);
10239 __ Frinti(d16, d20);
10240 __ Frinti(d17, d21);
10241 __ Frinti(d18, d22);
10242 __ Frinti(d19, d23);
10243 __ Frinti(d20, d24);
10244 __ Frinti(d21, d25);
10245 __ Frinti(d22, d26);
10246 __ Frinti(d23, d27);
10247 END();
10248
10249 RUN();
10250
10251 ASSERT_EQUAL_FP32(1.0, s0);
10252 ASSERT_EQUAL_FP32(1.0, s1);
10253 ASSERT_EQUAL_FP32(2.0, s2);
10254 ASSERT_EQUAL_FP32(2.0, s3);
10255 ASSERT_EQUAL_FP32(2.0, s4);
10256 ASSERT_EQUAL_FP32(-2.0, s5);
10257 ASSERT_EQUAL_FP32(-2.0, s6);
10258 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10259 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10260 ASSERT_EQUAL_FP32(0.0, s9);
10261 ASSERT_EQUAL_FP32(-0.0, s10);
10262 ASSERT_EQUAL_FP32(-0.0, s11);
10263 ASSERT_EQUAL_FP64(1.0, d12);
10264 ASSERT_EQUAL_FP64(1.0, d13);
10265 ASSERT_EQUAL_FP64(2.0, d14);
10266 ASSERT_EQUAL_FP64(2.0, d15);
10267 ASSERT_EQUAL_FP64(2.0, d16);
10268 ASSERT_EQUAL_FP64(-2.0, d17);
10269 ASSERT_EQUAL_FP64(-2.0, d18);
10270 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10271 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10272 ASSERT_EQUAL_FP64(0.0, d21);
10273 ASSERT_EQUAL_FP64(-0.0, d22);
10274 ASSERT_EQUAL_FP64(-0.0, d23);
10275
10276 TEARDOWN();
10277}
10278
10279
armvixl5799d6c2014-05-01 11:05:00 +010010280TEST(frintm) {
10281 SETUP();
10282
10283 START();
10284 __ Fmov(s16, 1.0);
10285 __ Fmov(s17, 1.1);
10286 __ Fmov(s18, 1.5);
10287 __ Fmov(s19, 1.9);
10288 __ Fmov(s20, 2.5);
10289 __ Fmov(s21, -1.5);
10290 __ Fmov(s22, -2.5);
10291 __ Fmov(s23, kFP32PositiveInfinity);
10292 __ Fmov(s24, kFP32NegativeInfinity);
10293 __ Fmov(s25, 0.0);
10294 __ Fmov(s26, -0.0);
10295 __ Fmov(s27, -0.2);
10296
10297 __ Frintm(s0, s16);
10298 __ Frintm(s1, s17);
10299 __ Frintm(s2, s18);
10300 __ Frintm(s3, s19);
10301 __ Frintm(s4, s20);
10302 __ Frintm(s5, s21);
10303 __ Frintm(s6, s22);
10304 __ Frintm(s7, s23);
10305 __ Frintm(s8, s24);
10306 __ Frintm(s9, s25);
10307 __ Frintm(s10, s26);
10308 __ Frintm(s11, s27);
10309
10310 __ Fmov(d16, 1.0);
10311 __ Fmov(d17, 1.1);
10312 __ Fmov(d18, 1.5);
10313 __ Fmov(d19, 1.9);
10314 __ Fmov(d20, 2.5);
10315 __ Fmov(d21, -1.5);
10316 __ Fmov(d22, -2.5);
10317 __ Fmov(d23, kFP32PositiveInfinity);
10318 __ Fmov(d24, kFP32NegativeInfinity);
10319 __ Fmov(d25, 0.0);
10320 __ Fmov(d26, -0.0);
10321 __ Fmov(d27, -0.2);
10322
10323 __ Frintm(d12, d16);
10324 __ Frintm(d13, d17);
10325 __ Frintm(d14, d18);
10326 __ Frintm(d15, d19);
10327 __ Frintm(d16, d20);
10328 __ Frintm(d17, d21);
10329 __ Frintm(d18, d22);
10330 __ Frintm(d19, d23);
10331 __ Frintm(d20, d24);
10332 __ Frintm(d21, d25);
10333 __ Frintm(d22, d26);
10334 __ Frintm(d23, d27);
10335 END();
10336
10337 RUN();
10338
10339 ASSERT_EQUAL_FP32(1.0, s0);
10340 ASSERT_EQUAL_FP32(1.0, s1);
10341 ASSERT_EQUAL_FP32(1.0, s2);
10342 ASSERT_EQUAL_FP32(1.0, s3);
10343 ASSERT_EQUAL_FP32(2.0, s4);
10344 ASSERT_EQUAL_FP32(-2.0, s5);
10345 ASSERT_EQUAL_FP32(-3.0, s6);
10346 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10347 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10348 ASSERT_EQUAL_FP32(0.0, s9);
10349 ASSERT_EQUAL_FP32(-0.0, s10);
10350 ASSERT_EQUAL_FP32(-1.0, s11);
10351 ASSERT_EQUAL_FP64(1.0, d12);
10352 ASSERT_EQUAL_FP64(1.0, d13);
10353 ASSERT_EQUAL_FP64(1.0, d14);
10354 ASSERT_EQUAL_FP64(1.0, d15);
10355 ASSERT_EQUAL_FP64(2.0, d16);
10356 ASSERT_EQUAL_FP64(-2.0, d17);
10357 ASSERT_EQUAL_FP64(-3.0, d18);
10358 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10359 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10360 ASSERT_EQUAL_FP64(0.0, d21);
10361 ASSERT_EQUAL_FP64(-0.0, d22);
10362 ASSERT_EQUAL_FP64(-1.0, d23);
armvixlf37fdc02014-02-05 13:22:16 +000010363
10364 TEARDOWN();
10365}
10366
10367
armvixlad96eda2013-06-14 11:42:37 +010010368TEST(frintn) {
10369 SETUP();
10370
10371 START();
10372 __ Fmov(s16, 1.0);
10373 __ Fmov(s17, 1.1);
10374 __ Fmov(s18, 1.5);
10375 __ Fmov(s19, 1.9);
10376 __ Fmov(s20, 2.5);
10377 __ Fmov(s21, -1.5);
10378 __ Fmov(s22, -2.5);
10379 __ Fmov(s23, kFP32PositiveInfinity);
10380 __ Fmov(s24, kFP32NegativeInfinity);
10381 __ Fmov(s25, 0.0);
10382 __ Fmov(s26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010383 __ Fmov(s27, -0.2);
armvixlad96eda2013-06-14 11:42:37 +010010384
10385 __ Frintn(s0, s16);
10386 __ Frintn(s1, s17);
10387 __ Frintn(s2, s18);
10388 __ Frintn(s3, s19);
10389 __ Frintn(s4, s20);
10390 __ Frintn(s5, s21);
10391 __ Frintn(s6, s22);
10392 __ Frintn(s7, s23);
10393 __ Frintn(s8, s24);
10394 __ Frintn(s9, s25);
10395 __ Frintn(s10, s26);
armvixl5799d6c2014-05-01 11:05:00 +010010396 __ Frintn(s11, s27);
armvixlad96eda2013-06-14 11:42:37 +010010397
10398 __ Fmov(d16, 1.0);
10399 __ Fmov(d17, 1.1);
10400 __ Fmov(d18, 1.5);
10401 __ Fmov(d19, 1.9);
10402 __ Fmov(d20, 2.5);
10403 __ Fmov(d21, -1.5);
10404 __ Fmov(d22, -2.5);
10405 __ Fmov(d23, kFP32PositiveInfinity);
10406 __ Fmov(d24, kFP32NegativeInfinity);
10407 __ Fmov(d25, 0.0);
10408 __ Fmov(d26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010409 __ Fmov(d27, -0.2);
armvixlad96eda2013-06-14 11:42:37 +010010410
armvixl5799d6c2014-05-01 11:05:00 +010010411 __ Frintn(d12, d16);
10412 __ Frintn(d13, d17);
10413 __ Frintn(d14, d18);
10414 __ Frintn(d15, d19);
10415 __ Frintn(d16, d20);
10416 __ Frintn(d17, d21);
10417 __ Frintn(d18, d22);
10418 __ Frintn(d19, d23);
10419 __ Frintn(d20, d24);
10420 __ Frintn(d21, d25);
10421 __ Frintn(d22, d26);
10422 __ Frintn(d23, d27);
armvixlad96eda2013-06-14 11:42:37 +010010423 END();
10424
10425 RUN();
10426
10427 ASSERT_EQUAL_FP32(1.0, s0);
10428 ASSERT_EQUAL_FP32(1.0, s1);
10429 ASSERT_EQUAL_FP32(2.0, s2);
10430 ASSERT_EQUAL_FP32(2.0, s3);
10431 ASSERT_EQUAL_FP32(2.0, s4);
10432 ASSERT_EQUAL_FP32(-2.0, s5);
10433 ASSERT_EQUAL_FP32(-2.0, s6);
10434 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10435 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10436 ASSERT_EQUAL_FP32(0.0, s9);
10437 ASSERT_EQUAL_FP32(-0.0, s10);
armvixl5799d6c2014-05-01 11:05:00 +010010438 ASSERT_EQUAL_FP32(-0.0, s11);
armvixlad96eda2013-06-14 11:42:37 +010010439 ASSERT_EQUAL_FP64(1.0, d12);
armvixl5799d6c2014-05-01 11:05:00 +010010440 ASSERT_EQUAL_FP64(1.0, d13);
armvixlad96eda2013-06-14 11:42:37 +010010441 ASSERT_EQUAL_FP64(2.0, d14);
10442 ASSERT_EQUAL_FP64(2.0, d15);
armvixl5799d6c2014-05-01 11:05:00 +010010443 ASSERT_EQUAL_FP64(2.0, d16);
armvixlad96eda2013-06-14 11:42:37 +010010444 ASSERT_EQUAL_FP64(-2.0, d17);
armvixl5799d6c2014-05-01 11:05:00 +010010445 ASSERT_EQUAL_FP64(-2.0, d18);
10446 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10447 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10448 ASSERT_EQUAL_FP64(0.0, d21);
10449 ASSERT_EQUAL_FP64(-0.0, d22);
10450 ASSERT_EQUAL_FP64(-0.0, d23);
armvixlad96eda2013-06-14 11:42:37 +010010451
10452 TEARDOWN();
10453}
10454
10455
armvixl330dc712014-11-25 10:38:32 +000010456TEST(frintp) {
10457 SETUP();
10458
10459 START();
10460 __ Fmov(s16, 1.0);
10461 __ Fmov(s17, 1.1);
10462 __ Fmov(s18, 1.5);
10463 __ Fmov(s19, 1.9);
10464 __ Fmov(s20, 2.5);
10465 __ Fmov(s21, -1.5);
10466 __ Fmov(s22, -2.5);
10467 __ Fmov(s23, kFP32PositiveInfinity);
10468 __ Fmov(s24, kFP32NegativeInfinity);
10469 __ Fmov(s25, 0.0);
10470 __ Fmov(s26, -0.0);
10471 __ Fmov(s27, -0.2);
10472
10473 __ Frintp(s0, s16);
10474 __ Frintp(s1, s17);
10475 __ Frintp(s2, s18);
10476 __ Frintp(s3, s19);
10477 __ Frintp(s4, s20);
10478 __ Frintp(s5, s21);
10479 __ Frintp(s6, s22);
10480 __ Frintp(s7, s23);
10481 __ Frintp(s8, s24);
10482 __ Frintp(s9, s25);
10483 __ Frintp(s10, s26);
10484 __ Frintp(s11, s27);
10485
10486 __ Fmov(d16, 1.0);
10487 __ Fmov(d17, 1.1);
10488 __ Fmov(d18, 1.5);
10489 __ Fmov(d19, 1.9);
10490 __ Fmov(d20, 2.5);
10491 __ Fmov(d21, -1.5);
10492 __ Fmov(d22, -2.5);
10493 __ Fmov(d23, kFP32PositiveInfinity);
10494 __ Fmov(d24, kFP32NegativeInfinity);
10495 __ Fmov(d25, 0.0);
10496 __ Fmov(d26, -0.0);
10497 __ Fmov(d27, -0.2);
10498
10499 __ Frintp(d12, d16);
10500 __ Frintp(d13, d17);
10501 __ Frintp(d14, d18);
10502 __ Frintp(d15, d19);
10503 __ Frintp(d16, d20);
10504 __ Frintp(d17, d21);
10505 __ Frintp(d18, d22);
10506 __ Frintp(d19, d23);
10507 __ Frintp(d20, d24);
10508 __ Frintp(d21, d25);
10509 __ Frintp(d22, d26);
10510 __ Frintp(d23, d27);
10511 END();
10512
10513 RUN();
10514
10515 ASSERT_EQUAL_FP32(1.0, s0);
10516 ASSERT_EQUAL_FP32(2.0, s1);
10517 ASSERT_EQUAL_FP32(2.0, s2);
10518 ASSERT_EQUAL_FP32(2.0, s3);
10519 ASSERT_EQUAL_FP32(3.0, s4);
10520 ASSERT_EQUAL_FP32(-1.0, s5);
10521 ASSERT_EQUAL_FP32(-2.0, s6);
10522 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10523 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10524 ASSERT_EQUAL_FP32(0.0, s9);
10525 ASSERT_EQUAL_FP32(-0.0, s10);
10526 ASSERT_EQUAL_FP32(-0.0, s11);
10527 ASSERT_EQUAL_FP64(1.0, d12);
10528 ASSERT_EQUAL_FP64(2.0, d13);
10529 ASSERT_EQUAL_FP64(2.0, d14);
10530 ASSERT_EQUAL_FP64(2.0, d15);
10531 ASSERT_EQUAL_FP64(3.0, d16);
10532 ASSERT_EQUAL_FP64(-1.0, d17);
10533 ASSERT_EQUAL_FP64(-2.0, d18);
10534 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10535 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10536 ASSERT_EQUAL_FP64(0.0, d21);
10537 ASSERT_EQUAL_FP64(-0.0, d22);
10538 ASSERT_EQUAL_FP64(-0.0, d23);
10539
10540 TEARDOWN();
10541}
10542
10543
10544TEST(frintx) {
10545 // VIXL only supports the round-to-nearest FPCR mode, and it doesn't support
10546 // FP exceptions, so this test has the same results as frintn (and frinti).
10547 SETUP();
10548
10549 START();
10550 __ Fmov(s16, 1.0);
10551 __ Fmov(s17, 1.1);
10552 __ Fmov(s18, 1.5);
10553 __ Fmov(s19, 1.9);
10554 __ Fmov(s20, 2.5);
10555 __ Fmov(s21, -1.5);
10556 __ Fmov(s22, -2.5);
10557 __ Fmov(s23, kFP32PositiveInfinity);
10558 __ Fmov(s24, kFP32NegativeInfinity);
10559 __ Fmov(s25, 0.0);
10560 __ Fmov(s26, -0.0);
10561 __ Fmov(s27, -0.2);
10562
10563 __ Frintx(s0, s16);
10564 __ Frintx(s1, s17);
10565 __ Frintx(s2, s18);
10566 __ Frintx(s3, s19);
10567 __ Frintx(s4, s20);
10568 __ Frintx(s5, s21);
10569 __ Frintx(s6, s22);
10570 __ Frintx(s7, s23);
10571 __ Frintx(s8, s24);
10572 __ Frintx(s9, s25);
10573 __ Frintx(s10, s26);
10574 __ Frintx(s11, s27);
10575
10576 __ Fmov(d16, 1.0);
10577 __ Fmov(d17, 1.1);
10578 __ Fmov(d18, 1.5);
10579 __ Fmov(d19, 1.9);
10580 __ Fmov(d20, 2.5);
10581 __ Fmov(d21, -1.5);
10582 __ Fmov(d22, -2.5);
10583 __ Fmov(d23, kFP32PositiveInfinity);
10584 __ Fmov(d24, kFP32NegativeInfinity);
10585 __ Fmov(d25, 0.0);
10586 __ Fmov(d26, -0.0);
10587 __ Fmov(d27, -0.2);
10588
10589 __ Frintx(d12, d16);
10590 __ Frintx(d13, d17);
10591 __ Frintx(d14, d18);
10592 __ Frintx(d15, d19);
10593 __ Frintx(d16, d20);
10594 __ Frintx(d17, d21);
10595 __ Frintx(d18, d22);
10596 __ Frintx(d19, d23);
10597 __ Frintx(d20, d24);
10598 __ Frintx(d21, d25);
10599 __ Frintx(d22, d26);
10600 __ Frintx(d23, d27);
10601 END();
10602
10603 RUN();
10604
10605 ASSERT_EQUAL_FP32(1.0, s0);
10606 ASSERT_EQUAL_FP32(1.0, s1);
10607 ASSERT_EQUAL_FP32(2.0, s2);
10608 ASSERT_EQUAL_FP32(2.0, s3);
10609 ASSERT_EQUAL_FP32(2.0, s4);
10610 ASSERT_EQUAL_FP32(-2.0, s5);
10611 ASSERT_EQUAL_FP32(-2.0, s6);
10612 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10613 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10614 ASSERT_EQUAL_FP32(0.0, s9);
10615 ASSERT_EQUAL_FP32(-0.0, s10);
10616 ASSERT_EQUAL_FP32(-0.0, s11);
10617 ASSERT_EQUAL_FP64(1.0, d12);
10618 ASSERT_EQUAL_FP64(1.0, d13);
10619 ASSERT_EQUAL_FP64(2.0, d14);
10620 ASSERT_EQUAL_FP64(2.0, d15);
10621 ASSERT_EQUAL_FP64(2.0, d16);
10622 ASSERT_EQUAL_FP64(-2.0, d17);
10623 ASSERT_EQUAL_FP64(-2.0, d18);
10624 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10625 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10626 ASSERT_EQUAL_FP64(0.0, d21);
10627 ASSERT_EQUAL_FP64(-0.0, d22);
10628 ASSERT_EQUAL_FP64(-0.0, d23);
10629
10630 TEARDOWN();
10631}
10632
10633
armvixlad96eda2013-06-14 11:42:37 +010010634TEST(frintz) {
10635 SETUP();
10636
10637 START();
10638 __ Fmov(s16, 1.0);
10639 __ Fmov(s17, 1.1);
10640 __ Fmov(s18, 1.5);
10641 __ Fmov(s19, 1.9);
10642 __ Fmov(s20, 2.5);
10643 __ Fmov(s21, -1.5);
10644 __ Fmov(s22, -2.5);
10645 __ Fmov(s23, kFP32PositiveInfinity);
10646 __ Fmov(s24, kFP32NegativeInfinity);
10647 __ Fmov(s25, 0.0);
10648 __ Fmov(s26, -0.0);
10649
10650 __ Frintz(s0, s16);
10651 __ Frintz(s1, s17);
10652 __ Frintz(s2, s18);
10653 __ Frintz(s3, s19);
10654 __ Frintz(s4, s20);
10655 __ Frintz(s5, s21);
10656 __ Frintz(s6, s22);
10657 __ Frintz(s7, s23);
10658 __ Frintz(s8, s24);
10659 __ Frintz(s9, s25);
10660 __ Frintz(s10, s26);
10661
10662 __ Fmov(d16, 1.0);
10663 __ Fmov(d17, 1.1);
10664 __ Fmov(d18, 1.5);
10665 __ Fmov(d19, 1.9);
10666 __ Fmov(d20, 2.5);
10667 __ Fmov(d21, -1.5);
10668 __ Fmov(d22, -2.5);
10669 __ Fmov(d23, kFP32PositiveInfinity);
10670 __ Fmov(d24, kFP32NegativeInfinity);
10671 __ Fmov(d25, 0.0);
10672 __ Fmov(d26, -0.0);
10673
10674 __ Frintz(d11, d16);
10675 __ Frintz(d12, d17);
10676 __ Frintz(d13, d18);
10677 __ Frintz(d14, d19);
10678 __ Frintz(d15, d20);
10679 __ Frintz(d16, d21);
10680 __ Frintz(d17, d22);
10681 __ Frintz(d18, d23);
10682 __ Frintz(d19, d24);
10683 __ Frintz(d20, d25);
10684 __ Frintz(d21, d26);
10685 END();
10686
10687 RUN();
10688
10689 ASSERT_EQUAL_FP32(1.0, s0);
10690 ASSERT_EQUAL_FP32(1.0, s1);
10691 ASSERT_EQUAL_FP32(1.0, s2);
10692 ASSERT_EQUAL_FP32(1.0, s3);
10693 ASSERT_EQUAL_FP32(2.0, s4);
10694 ASSERT_EQUAL_FP32(-1.0, s5);
10695 ASSERT_EQUAL_FP32(-2.0, s6);
10696 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10697 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10698 ASSERT_EQUAL_FP32(0.0, s9);
10699 ASSERT_EQUAL_FP32(-0.0, s10);
10700 ASSERT_EQUAL_FP64(1.0, d11);
10701 ASSERT_EQUAL_FP64(1.0, d12);
10702 ASSERT_EQUAL_FP64(1.0, d13);
10703 ASSERT_EQUAL_FP64(1.0, d14);
10704 ASSERT_EQUAL_FP64(2.0, d15);
10705 ASSERT_EQUAL_FP64(-1.0, d16);
10706 ASSERT_EQUAL_FP64(-2.0, d17);
10707 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
10708 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
10709 ASSERT_EQUAL_FP64(0.0, d20);
10710 ASSERT_EQUAL_FP64(-0.0, d21);
10711
10712 TEARDOWN();
10713}
10714
10715
armvixl578645f2013-08-15 17:21:42 +010010716TEST(fcvt_ds) {
armvixlad96eda2013-06-14 11:42:37 +010010717 SETUP();
10718
10719 START();
10720 __ Fmov(s16, 1.0);
10721 __ Fmov(s17, 1.1);
10722 __ Fmov(s18, 1.5);
10723 __ Fmov(s19, 1.9);
10724 __ Fmov(s20, 2.5);
10725 __ Fmov(s21, -1.5);
10726 __ Fmov(s22, -2.5);
10727 __ Fmov(s23, kFP32PositiveInfinity);
10728 __ Fmov(s24, kFP32NegativeInfinity);
10729 __ Fmov(s25, 0.0);
10730 __ Fmov(s26, -0.0);
armvixl578645f2013-08-15 17:21:42 +010010731 __ Fmov(s27, FLT_MAX);
10732 __ Fmov(s28, FLT_MIN);
10733 __ Fmov(s29, rawbits_to_float(0x7fc12345)); // Quiet NaN.
10734 __ Fmov(s30, rawbits_to_float(0x7f812345)); // Signalling NaN.
armvixlad96eda2013-06-14 11:42:37 +010010735
10736 __ Fcvt(d0, s16);
10737 __ Fcvt(d1, s17);
10738 __ Fcvt(d2, s18);
10739 __ Fcvt(d3, s19);
10740 __ Fcvt(d4, s20);
10741 __ Fcvt(d5, s21);
10742 __ Fcvt(d6, s22);
10743 __ Fcvt(d7, s23);
10744 __ Fcvt(d8, s24);
10745 __ Fcvt(d9, s25);
10746 __ Fcvt(d10, s26);
armvixl578645f2013-08-15 17:21:42 +010010747 __ Fcvt(d11, s27);
10748 __ Fcvt(d12, s28);
10749 __ Fcvt(d13, s29);
10750 __ Fcvt(d14, s30);
armvixlad96eda2013-06-14 11:42:37 +010010751 END();
10752
10753 RUN();
10754
10755 ASSERT_EQUAL_FP64(1.0f, d0);
10756 ASSERT_EQUAL_FP64(1.1f, d1);
10757 ASSERT_EQUAL_FP64(1.5f, d2);
10758 ASSERT_EQUAL_FP64(1.9f, d3);
10759 ASSERT_EQUAL_FP64(2.5f, d4);
10760 ASSERT_EQUAL_FP64(-1.5f, d5);
10761 ASSERT_EQUAL_FP64(-2.5f, d6);
10762 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
10763 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8);
10764 ASSERT_EQUAL_FP64(0.0f, d9);
10765 ASSERT_EQUAL_FP64(-0.0f, d10);
armvixl578645f2013-08-15 17:21:42 +010010766 ASSERT_EQUAL_FP64(FLT_MAX, d11);
10767 ASSERT_EQUAL_FP64(FLT_MIN, d12);
10768
10769 // Check that the NaN payload is preserved according to A64 conversion rules:
10770 // - The sign bit is preserved.
10771 // - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
10772 // - The remaining mantissa bits are copied until they run out.
10773 // - The low-order bits that haven't already been assigned are set to 0.
10774 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d13);
10775 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d14);
armvixlad96eda2013-06-14 11:42:37 +010010776
10777 TEARDOWN();
10778}
10779
10780
armvixl578645f2013-08-15 17:21:42 +010010781TEST(fcvt_sd) {
armvixl5799d6c2014-05-01 11:05:00 +010010782 // Test simple conversions here. Complex behaviour (such as rounding
10783 // specifics) are tested in the simulator tests.
armvixl578645f2013-08-15 17:21:42 +010010784
armvixl5799d6c2014-05-01 11:05:00 +010010785 SETUP();
armvixl578645f2013-08-15 17:21:42 +010010786
armvixl5799d6c2014-05-01 11:05:00 +010010787 START();
10788 __ Fmov(d16, 1.0);
10789 __ Fmov(d17, 1.1);
10790 __ Fmov(d18, 1.5);
10791 __ Fmov(d19, 1.9);
10792 __ Fmov(d20, 2.5);
10793 __ Fmov(d21, -1.5);
10794 __ Fmov(d22, -2.5);
10795 __ Fmov(d23, kFP32PositiveInfinity);
10796 __ Fmov(d24, kFP32NegativeInfinity);
10797 __ Fmov(d25, 0.0);
10798 __ Fmov(d26, -0.0);
10799 __ Fmov(d27, FLT_MAX);
10800 __ Fmov(d28, FLT_MIN);
10801 __ Fmov(d29, rawbits_to_double(0x7ff82468a0000000)); // Quiet NaN.
10802 __ Fmov(d30, rawbits_to_double(0x7ff02468a0000000)); // Signalling NaN.
armvixl578645f2013-08-15 17:21:42 +010010803
armvixl5799d6c2014-05-01 11:05:00 +010010804 __ Fcvt(s0, d16);
10805 __ Fcvt(s1, d17);
10806 __ Fcvt(s2, d18);
10807 __ Fcvt(s3, d19);
10808 __ Fcvt(s4, d20);
10809 __ Fcvt(s5, d21);
10810 __ Fcvt(s6, d22);
10811 __ Fcvt(s7, d23);
10812 __ Fcvt(s8, d24);
10813 __ Fcvt(s9, d25);
10814 __ Fcvt(s10, d26);
10815 __ Fcvt(s11, d27);
10816 __ Fcvt(s12, d28);
10817 __ Fcvt(s13, d29);
10818 __ Fcvt(s14, d30);
10819 END();
armvixl578645f2013-08-15 17:21:42 +010010820
armvixl5799d6c2014-05-01 11:05:00 +010010821 RUN();
armvixl578645f2013-08-15 17:21:42 +010010822
armvixl5799d6c2014-05-01 11:05:00 +010010823 ASSERT_EQUAL_FP32(1.0f, s0);
10824 ASSERT_EQUAL_FP32(1.1f, s1);
10825 ASSERT_EQUAL_FP32(1.5f, s2);
10826 ASSERT_EQUAL_FP32(1.9f, s3);
10827 ASSERT_EQUAL_FP32(2.5f, s4);
10828 ASSERT_EQUAL_FP32(-1.5f, s5);
10829 ASSERT_EQUAL_FP32(-2.5f, s6);
10830 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10831 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10832 ASSERT_EQUAL_FP32(0.0f, s9);
10833 ASSERT_EQUAL_FP32(-0.0f, s10);
10834 ASSERT_EQUAL_FP32(FLT_MAX, s11);
10835 ASSERT_EQUAL_FP32(FLT_MIN, s12);
armvixl578645f2013-08-15 17:21:42 +010010836
armvixl5799d6c2014-05-01 11:05:00 +010010837 // Check that the NaN payload is preserved according to A64 conversion rules:
10838 // - The sign bit is preserved.
10839 // - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
10840 // - The remaining mantissa bits are copied until they run out.
10841 // - The low-order bits that haven't already been assigned are set to 0.
10842 ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s13);
10843 ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s14);
armvixl578645f2013-08-15 17:21:42 +010010844
armvixl5799d6c2014-05-01 11:05:00 +010010845 TEARDOWN();
armvixl578645f2013-08-15 17:21:42 +010010846}
10847
10848
armvixl5289c592015-03-02 13:52:04 +000010849TEST(fcvt_half) {
10850 SETUP();
10851
10852 START();
10853 Label done;
10854 {
10855 // Check all exact conversions from half to float and back.
10856 Label ok, fail;
10857 __ Mov(w0, 0);
10858 for (int i = 0; i < 0xffff; i += 3) {
10859 if ((i & 0x7c00) == 0x7c00) continue;
10860 __ Mov(w1, i);
10861 __ Fmov(s1, w1);
10862 __ Fcvt(s2, h1);
10863 __ Fcvt(h2, s2);
10864 __ Fmov(w2, s2);
10865 __ Cmp(w1, w2);
10866 __ B(&fail, ne);
10867 }
10868 __ B(&ok);
10869 __ Bind(&fail);
10870 __ Mov(w0, 1);
10871 __ B(&done);
10872 __ Bind(&ok);
10873 }
10874 {
10875 // Check all exact conversions from half to double and back.
10876 Label ok, fail;
10877 for (int i = 0; i < 0xffff; i += 3) {
10878 if ((i & 0x7c00) == 0x7c00) continue;
10879 __ Mov(w1, i);
10880 __ Fmov(s1, w1);
10881 __ Fcvt(d2, h1);
10882 __ Fcvt(h2, d2);
10883 __ Mov(w2, v2.S(), 0);
10884 __ Cmp(w1, w2);
10885 __ B(&fail, ne);
10886 }
10887 __ B(&ok);
10888 __ Bind(&fail);
10889 __ Mov(w0, 2);
10890 __ Bind(&ok);
10891 }
10892 __ Bind(&done);
10893
10894 // Check some other interesting values.
10895 __ Fmov(s0, kFP32PositiveInfinity);
10896 __ Fmov(s1, kFP32NegativeInfinity);
10897 __ Fmov(s2, 65504); // Max half precision.
10898 __ Fmov(s3, 6.10352e-5); // Min positive normal.
10899 __ Fmov(s4, 6.09756e-5); // Max subnormal.
10900 __ Fmov(s5, 5.96046e-8); // Min positive subnormal.
10901 __ Fmov(s6, 5e-9); // Not representable -> zero.
10902 __ Fmov(s7, -0.0);
10903 __ Fcvt(h0, s0);
10904 __ Fcvt(h1, s1);
10905 __ Fcvt(h2, s2);
10906 __ Fcvt(h3, s3);
10907 __ Fcvt(h4, s4);
10908 __ Fcvt(h5, s5);
10909 __ Fcvt(h6, s6);
10910 __ Fcvt(h7, s7);
10911
10912 __ Fmov(d20, kFP64PositiveInfinity);
10913 __ Fmov(d21, kFP64NegativeInfinity);
10914 __ Fmov(d22, 65504); // Max half precision.
10915 __ Fmov(d23, 6.10352e-5); // Min positive normal.
10916 __ Fmov(d24, 6.09756e-5); // Max subnormal.
10917 __ Fmov(d25, 5.96046e-8); // Min positive subnormal.
10918 __ Fmov(d26, 5e-9); // Not representable -> zero.
10919 __ Fmov(d27, -0.0);
10920 __ Fcvt(h20, d20);
10921 __ Fcvt(h21, d21);
10922 __ Fcvt(h22, d22);
10923 __ Fcvt(h23, d23);
10924 __ Fcvt(h24, d24);
10925 __ Fcvt(h25, d25);
10926 __ Fcvt(h26, d26);
10927 __ Fcvt(h27, d27);
10928 END();
10929
10930 RUN();
10931
10932 ASSERT_EQUAL_32(0, w0); // 1 => float failed, 2 => double failed.
10933 ASSERT_EQUAL_128(0, kFP16PositiveInfinity, q0);
10934 ASSERT_EQUAL_128(0, kFP16NegativeInfinity, q1);
10935 ASSERT_EQUAL_128(0, 0x7bff, q2);
10936 ASSERT_EQUAL_128(0, 0x0400, q3);
10937 ASSERT_EQUAL_128(0, 0x03ff, q4);
10938 ASSERT_EQUAL_128(0, 0x0001, q5);
10939 ASSERT_EQUAL_128(0, 0, q6);
10940 ASSERT_EQUAL_128(0, 0x8000, q7);
10941 ASSERT_EQUAL_128(0, kFP16PositiveInfinity, q20);
10942 ASSERT_EQUAL_128(0, kFP16NegativeInfinity, q21);
10943 ASSERT_EQUAL_128(0, 0x7bff, q22);
10944 ASSERT_EQUAL_128(0, 0x0400, q23);
10945 ASSERT_EQUAL_128(0, 0x03ff, q24);
10946 ASSERT_EQUAL_128(0, 0x0001, q25);
10947 ASSERT_EQUAL_128(0, 0, q26);
10948 ASSERT_EQUAL_128(0, 0x8000, q27);
10949 TEARDOWN();
10950}
10951
10952
armvixlf37fdc02014-02-05 13:22:16 +000010953TEST(fcvtas) {
10954 SETUP();
10955
10956 START();
10957 __ Fmov(s0, 1.0);
10958 __ Fmov(s1, 1.1);
10959 __ Fmov(s2, 2.5);
10960 __ Fmov(s3, -2.5);
10961 __ Fmov(s4, kFP32PositiveInfinity);
10962 __ Fmov(s5, kFP32NegativeInfinity);
10963 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
10964 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
10965 __ Fmov(d8, 1.0);
10966 __ Fmov(d9, 1.1);
10967 __ Fmov(d10, 2.5);
10968 __ Fmov(d11, -2.5);
10969 __ Fmov(d12, kFP64PositiveInfinity);
10970 __ Fmov(d13, kFP64NegativeInfinity);
10971 __ Fmov(d14, kWMaxInt - 1);
10972 __ Fmov(d15, kWMinInt + 1);
10973 __ Fmov(s17, 1.1);
10974 __ Fmov(s18, 2.5);
10975 __ Fmov(s19, -2.5);
10976 __ Fmov(s20, kFP32PositiveInfinity);
10977 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000010978 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +000010979 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
10980 __ Fmov(d24, 1.1);
10981 __ Fmov(d25, 2.5);
10982 __ Fmov(d26, -2.5);
10983 __ Fmov(d27, kFP64PositiveInfinity);
10984 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000010985 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +000010986 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
10987
10988 __ Fcvtas(w0, s0);
10989 __ Fcvtas(w1, s1);
10990 __ Fcvtas(w2, s2);
10991 __ Fcvtas(w3, s3);
10992 __ Fcvtas(w4, s4);
10993 __ Fcvtas(w5, s5);
10994 __ Fcvtas(w6, s6);
10995 __ Fcvtas(w7, s7);
10996 __ Fcvtas(w8, d8);
10997 __ Fcvtas(w9, d9);
10998 __ Fcvtas(w10, d10);
10999 __ Fcvtas(w11, d11);
11000 __ Fcvtas(w12, d12);
11001 __ Fcvtas(w13, d13);
11002 __ Fcvtas(w14, d14);
11003 __ Fcvtas(w15, d15);
11004 __ Fcvtas(x17, s17);
11005 __ Fcvtas(x18, s18);
11006 __ Fcvtas(x19, s19);
11007 __ Fcvtas(x20, s20);
11008 __ Fcvtas(x21, s21);
11009 __ Fcvtas(x22, s22);
11010 __ Fcvtas(x23, s23);
11011 __ Fcvtas(x24, d24);
11012 __ Fcvtas(x25, d25);
11013 __ Fcvtas(x26, d26);
11014 __ Fcvtas(x27, d27);
11015 __ Fcvtas(x28, d28);
11016 __ Fcvtas(x29, d29);
11017 __ Fcvtas(x30, d30);
11018 END();
11019
11020 RUN();
11021
11022 ASSERT_EQUAL_64(1, x0);
11023 ASSERT_EQUAL_64(1, x1);
11024 ASSERT_EQUAL_64(3, x2);
11025 ASSERT_EQUAL_64(0xfffffffd, x3);
11026 ASSERT_EQUAL_64(0x7fffffff, x4);
11027 ASSERT_EQUAL_64(0x80000000, x5);
11028 ASSERT_EQUAL_64(0x7fffff80, x6);
11029 ASSERT_EQUAL_64(0x80000080, x7);
11030 ASSERT_EQUAL_64(1, x8);
11031 ASSERT_EQUAL_64(1, x9);
11032 ASSERT_EQUAL_64(3, x10);
11033 ASSERT_EQUAL_64(0xfffffffd, x11);
11034 ASSERT_EQUAL_64(0x7fffffff, x12);
11035 ASSERT_EQUAL_64(0x80000000, x13);
11036 ASSERT_EQUAL_64(0x7ffffffe, x14);
11037 ASSERT_EQUAL_64(0x80000001, x15);
11038 ASSERT_EQUAL_64(1, x17);
11039 ASSERT_EQUAL_64(3, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011040 ASSERT_EQUAL_64(0xfffffffffffffffd, x19);
11041 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11042 ASSERT_EQUAL_64(0x8000000000000000, x21);
11043 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11044 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlf37fdc02014-02-05 13:22:16 +000011045 ASSERT_EQUAL_64(1, x24);
11046 ASSERT_EQUAL_64(3, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011047 ASSERT_EQUAL_64(0xfffffffffffffffd, x26);
11048 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11049 ASSERT_EQUAL_64(0x8000000000000000, x28);
11050 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11051 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlf37fdc02014-02-05 13:22:16 +000011052
11053 TEARDOWN();
11054}
11055
11056
11057TEST(fcvtau) {
11058 SETUP();
11059
11060 START();
11061 __ Fmov(s0, 1.0);
11062 __ Fmov(s1, 1.1);
11063 __ Fmov(s2, 2.5);
11064 __ Fmov(s3, -2.5);
11065 __ Fmov(s4, kFP32PositiveInfinity);
11066 __ Fmov(s5, kFP32NegativeInfinity);
11067 __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX.
11068 __ Fmov(d8, 1.0);
11069 __ Fmov(d9, 1.1);
11070 __ Fmov(d10, 2.5);
11071 __ Fmov(d11, -2.5);
11072 __ Fmov(d12, kFP64PositiveInfinity);
11073 __ Fmov(d13, kFP64NegativeInfinity);
11074 __ Fmov(d14, 0xfffffffe);
11075 __ Fmov(s16, 1.0);
11076 __ Fmov(s17, 1.1);
11077 __ Fmov(s18, 2.5);
11078 __ Fmov(s19, -2.5);
11079 __ Fmov(s20, kFP32PositiveInfinity);
11080 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011081 __ Fmov(s22, 0xffffff0000000000); // Largest float < UINT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +000011082 __ Fmov(d24, 1.1);
11083 __ Fmov(d25, 2.5);
11084 __ Fmov(d26, -2.5);
11085 __ Fmov(d27, kFP64PositiveInfinity);
11086 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011087 __ Fmov(d29, 0xfffffffffffff800); // Largest double < UINT64_MAX.
11088 __ Fmov(s30, 0x100000000);
armvixlf37fdc02014-02-05 13:22:16 +000011089
11090 __ Fcvtau(w0, s0);
11091 __ Fcvtau(w1, s1);
11092 __ Fcvtau(w2, s2);
11093 __ Fcvtau(w3, s3);
11094 __ Fcvtau(w4, s4);
11095 __ Fcvtau(w5, s5);
11096 __ Fcvtau(w6, s6);
11097 __ Fcvtau(w8, d8);
11098 __ Fcvtau(w9, d9);
11099 __ Fcvtau(w10, d10);
11100 __ Fcvtau(w11, d11);
11101 __ Fcvtau(w12, d12);
11102 __ Fcvtau(w13, d13);
11103 __ Fcvtau(w14, d14);
11104 __ Fcvtau(w15, d15);
11105 __ Fcvtau(x16, s16);
11106 __ Fcvtau(x17, s17);
11107 __ Fcvtau(x18, s18);
11108 __ Fcvtau(x19, s19);
11109 __ Fcvtau(x20, s20);
11110 __ Fcvtau(x21, s21);
11111 __ Fcvtau(x22, s22);
11112 __ Fcvtau(x24, d24);
11113 __ Fcvtau(x25, d25);
11114 __ Fcvtau(x26, d26);
11115 __ Fcvtau(x27, d27);
11116 __ Fcvtau(x28, d28);
11117 __ Fcvtau(x29, d29);
11118 __ Fcvtau(w30, s30);
11119 END();
11120
11121 RUN();
11122
11123 ASSERT_EQUAL_64(1, x0);
11124 ASSERT_EQUAL_64(1, x1);
11125 ASSERT_EQUAL_64(3, x2);
11126 ASSERT_EQUAL_64(0, x3);
11127 ASSERT_EQUAL_64(0xffffffff, x4);
11128 ASSERT_EQUAL_64(0, x5);
11129 ASSERT_EQUAL_64(0xffffff00, x6);
11130 ASSERT_EQUAL_64(1, x8);
11131 ASSERT_EQUAL_64(1, x9);
11132 ASSERT_EQUAL_64(3, x10);
11133 ASSERT_EQUAL_64(0, x11);
11134 ASSERT_EQUAL_64(0xffffffff, x12);
11135 ASSERT_EQUAL_64(0, x13);
11136 ASSERT_EQUAL_64(0xfffffffe, x14);
11137 ASSERT_EQUAL_64(1, x16);
11138 ASSERT_EQUAL_64(1, x17);
11139 ASSERT_EQUAL_64(3, x18);
11140 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +000011141 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlf37fdc02014-02-05 13:22:16 +000011142 ASSERT_EQUAL_64(0, x21);
armvixlb0c8ae22014-03-21 14:03:59 +000011143 ASSERT_EQUAL_64(0xffffff0000000000, x22);
armvixlf37fdc02014-02-05 13:22:16 +000011144 ASSERT_EQUAL_64(1, x24);
11145 ASSERT_EQUAL_64(3, x25);
11146 ASSERT_EQUAL_64(0, x26);
armvixlb0c8ae22014-03-21 14:03:59 +000011147 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
armvixlf37fdc02014-02-05 13:22:16 +000011148 ASSERT_EQUAL_64(0, x28);
armvixlb0c8ae22014-03-21 14:03:59 +000011149 ASSERT_EQUAL_64(0xfffffffffffff800, x29);
armvixlf37fdc02014-02-05 13:22:16 +000011150 ASSERT_EQUAL_64(0xffffffff, x30);
11151
11152 TEARDOWN();
11153}
11154
11155
armvixlad96eda2013-06-14 11:42:37 +010011156TEST(fcvtms) {
11157 SETUP();
11158
11159 START();
11160 __ Fmov(s0, 1.0);
11161 __ Fmov(s1, 1.1);
11162 __ Fmov(s2, 1.5);
11163 __ Fmov(s3, -1.5);
11164 __ Fmov(s4, kFP32PositiveInfinity);
11165 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011166 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11167 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011168 __ Fmov(d8, 1.0);
11169 __ Fmov(d9, 1.1);
11170 __ Fmov(d10, 1.5);
11171 __ Fmov(d11, -1.5);
11172 __ Fmov(d12, kFP64PositiveInfinity);
11173 __ Fmov(d13, kFP64NegativeInfinity);
11174 __ Fmov(d14, kWMaxInt - 1);
11175 __ Fmov(d15, kWMinInt + 1);
11176 __ Fmov(s17, 1.1);
11177 __ Fmov(s18, 1.5);
11178 __ Fmov(s19, -1.5);
11179 __ Fmov(s20, kFP32PositiveInfinity);
11180 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011181 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11182 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011183 __ Fmov(d24, 1.1);
11184 __ Fmov(d25, 1.5);
11185 __ Fmov(d26, -1.5);
11186 __ Fmov(d27, kFP64PositiveInfinity);
11187 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011188 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11189 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011190
11191 __ Fcvtms(w0, s0);
11192 __ Fcvtms(w1, s1);
11193 __ Fcvtms(w2, s2);
11194 __ Fcvtms(w3, s3);
11195 __ Fcvtms(w4, s4);
11196 __ Fcvtms(w5, s5);
11197 __ Fcvtms(w6, s6);
11198 __ Fcvtms(w7, s7);
11199 __ Fcvtms(w8, d8);
11200 __ Fcvtms(w9, d9);
11201 __ Fcvtms(w10, d10);
11202 __ Fcvtms(w11, d11);
11203 __ Fcvtms(w12, d12);
11204 __ Fcvtms(w13, d13);
11205 __ Fcvtms(w14, d14);
11206 __ Fcvtms(w15, d15);
11207 __ Fcvtms(x17, s17);
11208 __ Fcvtms(x18, s18);
11209 __ Fcvtms(x19, s19);
11210 __ Fcvtms(x20, s20);
11211 __ Fcvtms(x21, s21);
11212 __ Fcvtms(x22, s22);
11213 __ Fcvtms(x23, s23);
11214 __ Fcvtms(x24, d24);
11215 __ Fcvtms(x25, d25);
11216 __ Fcvtms(x26, d26);
11217 __ Fcvtms(x27, d27);
11218 __ Fcvtms(x28, d28);
11219 __ Fcvtms(x29, d29);
11220 __ Fcvtms(x30, d30);
11221 END();
11222
11223 RUN();
11224
11225 ASSERT_EQUAL_64(1, x0);
11226 ASSERT_EQUAL_64(1, x1);
11227 ASSERT_EQUAL_64(1, x2);
11228 ASSERT_EQUAL_64(0xfffffffe, x3);
11229 ASSERT_EQUAL_64(0x7fffffff, x4);
11230 ASSERT_EQUAL_64(0x80000000, x5);
11231 ASSERT_EQUAL_64(0x7fffff80, x6);
11232 ASSERT_EQUAL_64(0x80000080, x7);
11233 ASSERT_EQUAL_64(1, x8);
11234 ASSERT_EQUAL_64(1, x9);
11235 ASSERT_EQUAL_64(1, x10);
11236 ASSERT_EQUAL_64(0xfffffffe, x11);
11237 ASSERT_EQUAL_64(0x7fffffff, x12);
11238 ASSERT_EQUAL_64(0x80000000, x13);
11239 ASSERT_EQUAL_64(0x7ffffffe, x14);
11240 ASSERT_EQUAL_64(0x80000001, x15);
11241 ASSERT_EQUAL_64(1, x17);
11242 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011243 ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
11244 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11245 ASSERT_EQUAL_64(0x8000000000000000, x21);
11246 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11247 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010011248 ASSERT_EQUAL_64(1, x24);
11249 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011250 ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
11251 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11252 ASSERT_EQUAL_64(0x8000000000000000, x28);
11253 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11254 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +010011255
11256 TEARDOWN();
11257}
11258
11259
11260TEST(fcvtmu) {
11261 SETUP();
11262
11263 START();
11264 __ Fmov(s0, 1.0);
11265 __ Fmov(s1, 1.1);
11266 __ Fmov(s2, 1.5);
11267 __ Fmov(s3, -1.5);
11268 __ Fmov(s4, kFP32PositiveInfinity);
11269 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011270 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11271 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011272 __ Fmov(d8, 1.0);
11273 __ Fmov(d9, 1.1);
11274 __ Fmov(d10, 1.5);
11275 __ Fmov(d11, -1.5);
11276 __ Fmov(d12, kFP64PositiveInfinity);
11277 __ Fmov(d13, kFP64NegativeInfinity);
11278 __ Fmov(d14, kWMaxInt - 1);
11279 __ Fmov(d15, kWMinInt + 1);
11280 __ Fmov(s17, 1.1);
11281 __ Fmov(s18, 1.5);
11282 __ Fmov(s19, -1.5);
11283 __ Fmov(s20, kFP32PositiveInfinity);
11284 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011285 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11286 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011287 __ Fmov(d24, 1.1);
11288 __ Fmov(d25, 1.5);
11289 __ Fmov(d26, -1.5);
11290 __ Fmov(d27, kFP64PositiveInfinity);
11291 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011292 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11293 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011294
11295 __ Fcvtmu(w0, s0);
11296 __ Fcvtmu(w1, s1);
11297 __ Fcvtmu(w2, s2);
11298 __ Fcvtmu(w3, s3);
11299 __ Fcvtmu(w4, s4);
11300 __ Fcvtmu(w5, s5);
11301 __ Fcvtmu(w6, s6);
11302 __ Fcvtmu(w7, s7);
11303 __ Fcvtmu(w8, d8);
11304 __ Fcvtmu(w9, d9);
11305 __ Fcvtmu(w10, d10);
11306 __ Fcvtmu(w11, d11);
11307 __ Fcvtmu(w12, d12);
11308 __ Fcvtmu(w13, d13);
11309 __ Fcvtmu(w14, d14);
11310 __ Fcvtmu(x17, s17);
11311 __ Fcvtmu(x18, s18);
11312 __ Fcvtmu(x19, s19);
11313 __ Fcvtmu(x20, s20);
11314 __ Fcvtmu(x21, s21);
11315 __ Fcvtmu(x22, s22);
11316 __ Fcvtmu(x23, s23);
11317 __ Fcvtmu(x24, d24);
11318 __ Fcvtmu(x25, d25);
11319 __ Fcvtmu(x26, d26);
11320 __ Fcvtmu(x27, d27);
11321 __ Fcvtmu(x28, d28);
11322 __ Fcvtmu(x29, d29);
11323 __ Fcvtmu(x30, d30);
11324 END();
11325
11326 RUN();
11327
11328 ASSERT_EQUAL_64(1, x0);
11329 ASSERT_EQUAL_64(1, x1);
11330 ASSERT_EQUAL_64(1, x2);
11331 ASSERT_EQUAL_64(0, x3);
11332 ASSERT_EQUAL_64(0xffffffff, x4);
11333 ASSERT_EQUAL_64(0, x5);
11334 ASSERT_EQUAL_64(0x7fffff80, x6);
11335 ASSERT_EQUAL_64(0, x7);
11336 ASSERT_EQUAL_64(1, x8);
11337 ASSERT_EQUAL_64(1, x9);
11338 ASSERT_EQUAL_64(1, x10);
11339 ASSERT_EQUAL_64(0, x11);
11340 ASSERT_EQUAL_64(0xffffffff, x12);
11341 ASSERT_EQUAL_64(0, x13);
11342 ASSERT_EQUAL_64(0x7ffffffe, x14);
11343 ASSERT_EQUAL_64(1, x17);
11344 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011345 ASSERT_EQUAL_64(0, x19);
11346 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
11347 ASSERT_EQUAL_64(0, x21);
11348 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11349 ASSERT_EQUAL_64(0, x23);
armvixlad96eda2013-06-14 11:42:37 +010011350 ASSERT_EQUAL_64(1, x24);
11351 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011352 ASSERT_EQUAL_64(0, x26);
11353 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
11354 ASSERT_EQUAL_64(0, x28);
11355 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11356 ASSERT_EQUAL_64(0, x30);
armvixlad96eda2013-06-14 11:42:37 +010011357
11358 TEARDOWN();
11359}
11360
11361
11362TEST(fcvtns) {
11363 SETUP();
11364
11365 START();
11366 __ Fmov(s0, 1.0);
11367 __ Fmov(s1, 1.1);
11368 __ Fmov(s2, 1.5);
11369 __ Fmov(s3, -1.5);
11370 __ Fmov(s4, kFP32PositiveInfinity);
11371 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011372 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11373 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011374 __ Fmov(d8, 1.0);
11375 __ Fmov(d9, 1.1);
11376 __ Fmov(d10, 1.5);
11377 __ Fmov(d11, -1.5);
11378 __ Fmov(d12, kFP64PositiveInfinity);
11379 __ Fmov(d13, kFP64NegativeInfinity);
11380 __ Fmov(d14, kWMaxInt - 1);
11381 __ Fmov(d15, kWMinInt + 1);
11382 __ Fmov(s17, 1.1);
11383 __ Fmov(s18, 1.5);
11384 __ Fmov(s19, -1.5);
11385 __ Fmov(s20, kFP32PositiveInfinity);
11386 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011387 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11388 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011389 __ Fmov(d24, 1.1);
11390 __ Fmov(d25, 1.5);
11391 __ Fmov(d26, -1.5);
11392 __ Fmov(d27, kFP64PositiveInfinity);
11393 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011394 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11395 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011396
11397 __ Fcvtns(w0, s0);
11398 __ Fcvtns(w1, s1);
11399 __ Fcvtns(w2, s2);
11400 __ Fcvtns(w3, s3);
11401 __ Fcvtns(w4, s4);
11402 __ Fcvtns(w5, s5);
11403 __ Fcvtns(w6, s6);
11404 __ Fcvtns(w7, s7);
11405 __ Fcvtns(w8, d8);
11406 __ Fcvtns(w9, d9);
11407 __ Fcvtns(w10, d10);
11408 __ Fcvtns(w11, d11);
11409 __ Fcvtns(w12, d12);
11410 __ Fcvtns(w13, d13);
11411 __ Fcvtns(w14, d14);
11412 __ Fcvtns(w15, d15);
11413 __ Fcvtns(x17, s17);
11414 __ Fcvtns(x18, s18);
11415 __ Fcvtns(x19, s19);
11416 __ Fcvtns(x20, s20);
11417 __ Fcvtns(x21, s21);
11418 __ Fcvtns(x22, s22);
11419 __ Fcvtns(x23, s23);
11420 __ Fcvtns(x24, d24);
11421 __ Fcvtns(x25, d25);
11422 __ Fcvtns(x26, d26);
11423 __ Fcvtns(x27, d27);
11424 __ Fcvtns(x28, d28);
11425 __ Fcvtns(x29, d29);
11426 __ Fcvtns(x30, d30);
11427 END();
11428
11429 RUN();
11430
11431 ASSERT_EQUAL_64(1, x0);
11432 ASSERT_EQUAL_64(1, x1);
11433 ASSERT_EQUAL_64(2, x2);
11434 ASSERT_EQUAL_64(0xfffffffe, x3);
11435 ASSERT_EQUAL_64(0x7fffffff, x4);
11436 ASSERT_EQUAL_64(0x80000000, x5);
11437 ASSERT_EQUAL_64(0x7fffff80, x6);
11438 ASSERT_EQUAL_64(0x80000080, x7);
11439 ASSERT_EQUAL_64(1, x8);
11440 ASSERT_EQUAL_64(1, x9);
11441 ASSERT_EQUAL_64(2, x10);
11442 ASSERT_EQUAL_64(0xfffffffe, x11);
11443 ASSERT_EQUAL_64(0x7fffffff, x12);
11444 ASSERT_EQUAL_64(0x80000000, x13);
11445 ASSERT_EQUAL_64(0x7ffffffe, x14);
11446 ASSERT_EQUAL_64(0x80000001, x15);
11447 ASSERT_EQUAL_64(1, x17);
11448 ASSERT_EQUAL_64(2, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011449 ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
11450 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11451 ASSERT_EQUAL_64(0x8000000000000000, x21);
11452 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11453 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010011454 ASSERT_EQUAL_64(1, x24);
11455 ASSERT_EQUAL_64(2, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011456 ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
11457 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11458 ASSERT_EQUAL_64(0x8000000000000000, x28);
11459 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11460 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +010011461
11462 TEARDOWN();
11463}
11464
11465
11466TEST(fcvtnu) {
11467 SETUP();
11468
11469 START();
11470 __ Fmov(s0, 1.0);
11471 __ Fmov(s1, 1.1);
11472 __ Fmov(s2, 1.5);
11473 __ Fmov(s3, -1.5);
11474 __ Fmov(s4, kFP32PositiveInfinity);
11475 __ Fmov(s5, kFP32NegativeInfinity);
11476 __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX.
11477 __ Fmov(d8, 1.0);
11478 __ Fmov(d9, 1.1);
11479 __ Fmov(d10, 1.5);
11480 __ Fmov(d11, -1.5);
11481 __ Fmov(d12, kFP64PositiveInfinity);
11482 __ Fmov(d13, kFP64NegativeInfinity);
11483 __ Fmov(d14, 0xfffffffe);
11484 __ Fmov(s16, 1.0);
11485 __ Fmov(s17, 1.1);
11486 __ Fmov(s18, 1.5);
11487 __ Fmov(s19, -1.5);
11488 __ Fmov(s20, kFP32PositiveInfinity);
11489 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011490 __ Fmov(s22, 0xffffff0000000000); // Largest float < UINT64_MAX.
armvixlad96eda2013-06-14 11:42:37 +010011491 __ Fmov(d24, 1.1);
11492 __ Fmov(d25, 1.5);
11493 __ Fmov(d26, -1.5);
11494 __ Fmov(d27, kFP64PositiveInfinity);
11495 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011496 __ Fmov(d29, 0xfffffffffffff800); // Largest double < UINT64_MAX.
11497 __ Fmov(s30, 0x100000000);
armvixlad96eda2013-06-14 11:42:37 +010011498
11499 __ Fcvtnu(w0, s0);
11500 __ Fcvtnu(w1, s1);
11501 __ Fcvtnu(w2, s2);
11502 __ Fcvtnu(w3, s3);
11503 __ Fcvtnu(w4, s4);
11504 __ Fcvtnu(w5, s5);
11505 __ Fcvtnu(w6, s6);
11506 __ Fcvtnu(w8, d8);
11507 __ Fcvtnu(w9, d9);
11508 __ Fcvtnu(w10, d10);
11509 __ Fcvtnu(w11, d11);
11510 __ Fcvtnu(w12, d12);
11511 __ Fcvtnu(w13, d13);
11512 __ Fcvtnu(w14, d14);
11513 __ Fcvtnu(w15, d15);
11514 __ Fcvtnu(x16, s16);
11515 __ Fcvtnu(x17, s17);
11516 __ Fcvtnu(x18, s18);
11517 __ Fcvtnu(x19, s19);
11518 __ Fcvtnu(x20, s20);
11519 __ Fcvtnu(x21, s21);
11520 __ Fcvtnu(x22, s22);
11521 __ Fcvtnu(x24, d24);
11522 __ Fcvtnu(x25, d25);
11523 __ Fcvtnu(x26, d26);
11524 __ Fcvtnu(x27, d27);
11525 __ Fcvtnu(x28, d28);
11526 __ Fcvtnu(x29, d29);
11527 __ Fcvtnu(w30, s30);
11528 END();
11529
11530 RUN();
11531
11532 ASSERT_EQUAL_64(1, x0);
11533 ASSERT_EQUAL_64(1, x1);
11534 ASSERT_EQUAL_64(2, x2);
11535 ASSERT_EQUAL_64(0, x3);
11536 ASSERT_EQUAL_64(0xffffffff, x4);
11537 ASSERT_EQUAL_64(0, x5);
11538 ASSERT_EQUAL_64(0xffffff00, x6);
11539 ASSERT_EQUAL_64(1, x8);
11540 ASSERT_EQUAL_64(1, x9);
11541 ASSERT_EQUAL_64(2, x10);
11542 ASSERT_EQUAL_64(0, x11);
11543 ASSERT_EQUAL_64(0xffffffff, x12);
11544 ASSERT_EQUAL_64(0, x13);
11545 ASSERT_EQUAL_64(0xfffffffe, x14);
11546 ASSERT_EQUAL_64(1, x16);
11547 ASSERT_EQUAL_64(1, x17);
11548 ASSERT_EQUAL_64(2, x18);
11549 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +000011550 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlad96eda2013-06-14 11:42:37 +010011551 ASSERT_EQUAL_64(0, x21);
armvixlb0c8ae22014-03-21 14:03:59 +000011552 ASSERT_EQUAL_64(0xffffff0000000000, x22);
armvixlad96eda2013-06-14 11:42:37 +010011553 ASSERT_EQUAL_64(1, x24);
11554 ASSERT_EQUAL_64(2, x25);
11555 ASSERT_EQUAL_64(0, x26);
armvixlb0c8ae22014-03-21 14:03:59 +000011556 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
armvixlad96eda2013-06-14 11:42:37 +010011557 ASSERT_EQUAL_64(0, x28);
armvixlb0c8ae22014-03-21 14:03:59 +000011558 ASSERT_EQUAL_64(0xfffffffffffff800, x29);
armvixlad96eda2013-06-14 11:42:37 +010011559 ASSERT_EQUAL_64(0xffffffff, x30);
11560
11561 TEARDOWN();
11562}
11563
11564
11565TEST(fcvtzs) {
11566 SETUP();
11567
11568 START();
11569 __ Fmov(s0, 1.0);
11570 __ Fmov(s1, 1.1);
11571 __ Fmov(s2, 1.5);
11572 __ Fmov(s3, -1.5);
11573 __ Fmov(s4, kFP32PositiveInfinity);
11574 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011575 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11576 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011577 __ Fmov(d8, 1.0);
11578 __ Fmov(d9, 1.1);
11579 __ Fmov(d10, 1.5);
11580 __ Fmov(d11, -1.5);
11581 __ Fmov(d12, kFP64PositiveInfinity);
11582 __ Fmov(d13, kFP64NegativeInfinity);
11583 __ Fmov(d14, kWMaxInt - 1);
11584 __ Fmov(d15, kWMinInt + 1);
11585 __ Fmov(s17, 1.1);
11586 __ Fmov(s18, 1.5);
11587 __ Fmov(s19, -1.5);
11588 __ Fmov(s20, kFP32PositiveInfinity);
11589 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011590 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11591 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011592 __ Fmov(d24, 1.1);
11593 __ Fmov(d25, 1.5);
11594 __ Fmov(d26, -1.5);
11595 __ Fmov(d27, kFP64PositiveInfinity);
11596 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011597 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11598 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011599
11600 __ Fcvtzs(w0, s0);
11601 __ Fcvtzs(w1, s1);
11602 __ Fcvtzs(w2, s2);
11603 __ Fcvtzs(w3, s3);
11604 __ Fcvtzs(w4, s4);
11605 __ Fcvtzs(w5, s5);
11606 __ Fcvtzs(w6, s6);
11607 __ Fcvtzs(w7, s7);
11608 __ Fcvtzs(w8, d8);
11609 __ Fcvtzs(w9, d9);
11610 __ Fcvtzs(w10, d10);
11611 __ Fcvtzs(w11, d11);
11612 __ Fcvtzs(w12, d12);
11613 __ Fcvtzs(w13, d13);
11614 __ Fcvtzs(w14, d14);
11615 __ Fcvtzs(w15, d15);
11616 __ Fcvtzs(x17, s17);
11617 __ Fcvtzs(x18, s18);
11618 __ Fcvtzs(x19, s19);
11619 __ Fcvtzs(x20, s20);
11620 __ Fcvtzs(x21, s21);
11621 __ Fcvtzs(x22, s22);
11622 __ Fcvtzs(x23, s23);
11623 __ Fcvtzs(x24, d24);
11624 __ Fcvtzs(x25, d25);
11625 __ Fcvtzs(x26, d26);
11626 __ Fcvtzs(x27, d27);
11627 __ Fcvtzs(x28, d28);
11628 __ Fcvtzs(x29, d29);
11629 __ Fcvtzs(x30, d30);
11630 END();
11631
11632 RUN();
11633
11634 ASSERT_EQUAL_64(1, x0);
11635 ASSERT_EQUAL_64(1, x1);
11636 ASSERT_EQUAL_64(1, x2);
11637 ASSERT_EQUAL_64(0xffffffff, x3);
11638 ASSERT_EQUAL_64(0x7fffffff, x4);
11639 ASSERT_EQUAL_64(0x80000000, x5);
11640 ASSERT_EQUAL_64(0x7fffff80, x6);
11641 ASSERT_EQUAL_64(0x80000080, x7);
11642 ASSERT_EQUAL_64(1, x8);
11643 ASSERT_EQUAL_64(1, x9);
11644 ASSERT_EQUAL_64(1, x10);
11645 ASSERT_EQUAL_64(0xffffffff, x11);
11646 ASSERT_EQUAL_64(0x7fffffff, x12);
11647 ASSERT_EQUAL_64(0x80000000, x13);
11648 ASSERT_EQUAL_64(0x7ffffffe, x14);
11649 ASSERT_EQUAL_64(0x80000001, x15);
11650 ASSERT_EQUAL_64(1, x17);
11651 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011652 ASSERT_EQUAL_64(0xffffffffffffffff, x19);
11653 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11654 ASSERT_EQUAL_64(0x8000000000000000, x21);
11655 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11656 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010011657 ASSERT_EQUAL_64(1, x24);
11658 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011659 ASSERT_EQUAL_64(0xffffffffffffffff, x26);
11660 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11661 ASSERT_EQUAL_64(0x8000000000000000, x28);
11662 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11663 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +010011664
11665 TEARDOWN();
11666}
11667
11668TEST(fcvtzu) {
11669 SETUP();
11670
11671 START();
11672 __ Fmov(s0, 1.0);
11673 __ Fmov(s1, 1.1);
11674 __ Fmov(s2, 1.5);
11675 __ Fmov(s3, -1.5);
11676 __ Fmov(s4, kFP32PositiveInfinity);
11677 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011678 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11679 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011680 __ Fmov(d8, 1.0);
11681 __ Fmov(d9, 1.1);
11682 __ Fmov(d10, 1.5);
11683 __ Fmov(d11, -1.5);
11684 __ Fmov(d12, kFP64PositiveInfinity);
11685 __ Fmov(d13, kFP64NegativeInfinity);
11686 __ Fmov(d14, kWMaxInt - 1);
11687 __ Fmov(d15, kWMinInt + 1);
11688 __ Fmov(s17, 1.1);
11689 __ Fmov(s18, 1.5);
11690 __ Fmov(s19, -1.5);
11691 __ Fmov(s20, kFP32PositiveInfinity);
11692 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011693 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11694 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011695 __ Fmov(d24, 1.1);
11696 __ Fmov(d25, 1.5);
11697 __ Fmov(d26, -1.5);
11698 __ Fmov(d27, kFP64PositiveInfinity);
11699 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011700 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11701 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011702
11703 __ Fcvtzu(w0, s0);
11704 __ Fcvtzu(w1, s1);
11705 __ Fcvtzu(w2, s2);
11706 __ Fcvtzu(w3, s3);
11707 __ Fcvtzu(w4, s4);
11708 __ Fcvtzu(w5, s5);
11709 __ Fcvtzu(w6, s6);
11710 __ Fcvtzu(w7, s7);
11711 __ Fcvtzu(w8, d8);
11712 __ Fcvtzu(w9, d9);
11713 __ Fcvtzu(w10, d10);
11714 __ Fcvtzu(w11, d11);
11715 __ Fcvtzu(w12, d12);
11716 __ Fcvtzu(w13, d13);
11717 __ Fcvtzu(w14, d14);
11718 __ Fcvtzu(x17, s17);
11719 __ Fcvtzu(x18, s18);
11720 __ Fcvtzu(x19, s19);
11721 __ Fcvtzu(x20, s20);
11722 __ Fcvtzu(x21, s21);
11723 __ Fcvtzu(x22, s22);
11724 __ Fcvtzu(x23, s23);
11725 __ Fcvtzu(x24, d24);
11726 __ Fcvtzu(x25, d25);
11727 __ Fcvtzu(x26, d26);
11728 __ Fcvtzu(x27, d27);
11729 __ Fcvtzu(x28, d28);
11730 __ Fcvtzu(x29, d29);
11731 __ Fcvtzu(x30, d30);
11732 END();
11733
11734 RUN();
11735
11736 ASSERT_EQUAL_64(1, x0);
11737 ASSERT_EQUAL_64(1, x1);
11738 ASSERT_EQUAL_64(1, x2);
11739 ASSERT_EQUAL_64(0, x3);
11740 ASSERT_EQUAL_64(0xffffffff, x4);
11741 ASSERT_EQUAL_64(0, x5);
11742 ASSERT_EQUAL_64(0x7fffff80, x6);
11743 ASSERT_EQUAL_64(0, x7);
11744 ASSERT_EQUAL_64(1, x8);
11745 ASSERT_EQUAL_64(1, x9);
11746 ASSERT_EQUAL_64(1, x10);
11747 ASSERT_EQUAL_64(0, x11);
11748 ASSERT_EQUAL_64(0xffffffff, x12);
11749 ASSERT_EQUAL_64(0, x13);
11750 ASSERT_EQUAL_64(0x7ffffffe, x14);
11751 ASSERT_EQUAL_64(1, x17);
11752 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011753 ASSERT_EQUAL_64(0, x19);
11754 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
11755 ASSERT_EQUAL_64(0, x21);
11756 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11757 ASSERT_EQUAL_64(0, x23);
armvixlad96eda2013-06-14 11:42:37 +010011758 ASSERT_EQUAL_64(1, x24);
11759 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011760 ASSERT_EQUAL_64(0, x26);
11761 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
11762 ASSERT_EQUAL_64(0, x28);
11763 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11764 ASSERT_EQUAL_64(0, x30);
armvixlad96eda2013-06-14 11:42:37 +010011765
11766 TEARDOWN();
11767}
11768
11769
armvixl5289c592015-03-02 13:52:04 +000011770TEST(neon_fcvtl) {
11771 SETUP();
11772
11773 START();
11774
11775 __ Movi(v0.V2D(), 0x000080007efffeff, 0x3100b1007c00fc00);
11776 __ Movi(v1.V2D(), 0x03ff83ff00038003, 0x000180017c01fc01);
11777 __ Movi(v2.V2D(), 0x3e200000be200000, 0x7f800000ff800000);
11778 __ Movi(v3.V2D(), 0x0000000080000000, 0x7f8fffffff8fffff);
11779 __ Movi(v4.V2D(), 0x7fcfffffffcfffff, 0x0000000180000001);
11780 __ Fcvtl(v16.V4S(), v0.V4H());
11781 __ Fcvtl2(v17.V4S(), v0.V8H());
11782 __ Fcvtl(v18.V4S(), v1.V4H());
11783 __ Fcvtl2(v19.V4S(), v1.V8H());
11784
11785 __ Fcvtl(v20.V2D(), v2.V2S());
11786 __ Fcvtl2(v21.V2D(), v2.V4S());
11787 __ Fcvtl(v22.V2D(), v3.V2S());
11788 __ Fcvtl2(v23.V2D(), v3.V4S());
11789 __ Fcvtl(v24.V2D(), v4.V2S());
11790 __ Fcvtl2(v25.V2D(), v4.V4S());
11791
11792 END();
11793
11794 RUN();
11795 ASSERT_EQUAL_128(0x3e200000be200000, 0x7f800000ff800000, q16);
11796 ASSERT_EQUAL_128(0x0000000080000000, 0x7fdfe000ffdfe000, q17);
11797 ASSERT_EQUAL_128(0x33800000b3800000, 0x7fc02000ffc02000, q18);
11798 ASSERT_EQUAL_128(0x387fc000b87fc000, 0x34400000b4400000, q19);
11799 ASSERT_EQUAL_128(0x7ff0000000000000, 0xfff0000000000000, q20);
11800 ASSERT_EQUAL_128(0x3fc4000000000000, 0xbfc4000000000000, q21);
11801 ASSERT_EQUAL_128(0x7ff9ffffe0000000, 0xfff9ffffe0000000, q22);
11802 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000000000, q23);
11803 ASSERT_EQUAL_128(0x36a0000000000000, 0xb6a0000000000000, q24);
11804 ASSERT_EQUAL_128(0x7ff9ffffe0000000, 0xfff9ffffe0000000, q25);
11805 TEARDOWN();
11806}
11807
11808
11809TEST(neon_fcvtn) {
11810 SETUP();
11811
11812 START();
11813
11814 __ Movi(v0.V2D(), 0x3e200000be200000, 0x7f800000ff800000);
11815 __ Movi(v1.V2D(), 0x0000000080000000, 0x7f8fffffff8fffff);
11816 __ Movi(v2.V2D(), 0x7fcfffffffcfffff, 0x0000000180000001);
11817 __ Movi(v3.V2D(), 0x3fc4000000000000, 0xbfc4000000000000);
11818 __ Movi(v4.V2D(), 0x7ff0000000000000, 0xfff0000000000000);
11819 __ Movi(v5.V2D(), 0x0000000000000000, 0x8000000000000000);
11820 __ Movi(v6.V2D(), 0x7ff0ffffffffffff, 0xfff0ffffffffffff);
11821 __ Movi(v7.V2D(), 0x7ff8ffffffffffff, 0xfff8ffffffffffff);
11822 __ Movi(v8.V2D(), 0x0000000000000001, 0x8000000000000001);
11823
11824 __ Fcvtn(v16.V4H(), v0.V4S());
11825 __ Fcvtn2(v16.V8H(), v1.V4S());
11826 __ Fcvtn(v17.V4H(), v2.V4S());
11827 __ Fcvtn(v18.V2S(), v3.V2D());
11828 __ Fcvtn2(v18.V4S(), v4.V2D());
11829 __ Fcvtn(v19.V2S(), v5.V2D());
11830 __ Fcvtn2(v19.V4S(), v6.V2D());
11831 __ Fcvtn(v20.V2S(), v7.V2D());
11832 __ Fcvtn2(v20.V4S(), v8.V2D());
11833 END();
11834
11835 RUN();
11836 ASSERT_EQUAL_128(0x000080007e7ffe7f, 0x3100b1007c00fc00, q16);
11837 ASSERT_EQUAL_128(0, 0x7e7ffe7f00008000, q17);
11838 ASSERT_EQUAL_128(0x7f800000ff800000, 0x3e200000be200000, q18);
11839 ASSERT_EQUAL_128(0x7fc7ffffffc7ffff, 0x0000000080000000, q19);
11840 ASSERT_EQUAL_128(0x0000000080000000, 0x7fc7ffffffc7ffff, q20);
11841 TEARDOWN();
11842}
11843
11844
11845TEST(neon_fcvtxn) {
11846 SETUP();
11847
11848 START();
11849 __ Movi(v0.V2D(), 0x3e200000be200000, 0x7f800000ff800000);
11850 __ Movi(v1.V2D(), 0x0000000080000000, 0x7f8fffffff8fffff);
11851 __ Movi(v2.V2D(), 0x7fcfffffffcfffff, 0x0000000180000001);
11852 __ Movi(v3.V2D(), 0x3fc4000000000000, 0xbfc4000000000000);
11853 __ Movi(v4.V2D(), 0x7ff0000000000000, 0xfff0000000000000);
11854 __ Movi(v5.V2D(), 0x0000000000000000, 0x8000000000000000);
11855 __ Movi(v6.V2D(), 0x7ff0ffffffffffff, 0xfff0ffffffffffff);
11856 __ Movi(v7.V2D(), 0x7ff8ffffffffffff, 0xfff8ffffffffffff);
11857 __ Movi(v8.V2D(), 0x0000000000000001, 0x8000000000000001);
11858 __ Movi(v9.V2D(), 0x41ed000000000000, 0x41efffffffefffff);
11859 __ Fcvtxn(v16.V2S(), v0.V2D());
11860 __ Fcvtxn2(v16.V4S(), v1.V2D());
11861 __ Fcvtxn(v17.V2S(), v2.V2D());
11862 __ Fcvtxn2(v17.V4S(), v3.V2D());
11863 __ Fcvtxn(v18.V2S(), v4.V2D());
11864 __ Fcvtxn2(v18.V4S(), v5.V2D());
11865 __ Fcvtxn(v19.V2S(), v6.V2D());
11866 __ Fcvtxn2(v19.V4S(), v7.V2D());
11867 __ Fcvtxn(v20.V2S(), v8.V2D());
11868 __ Fcvtxn2(v20.V4S(), v9.V2D());
11869 __ Fcvtxn(s21, d0);
11870 END();
11871
11872 RUN();
11873 ASSERT_EQUAL_128(0x000000017f7fffff, 0x310000057f7fffff, q16);
11874 ASSERT_EQUAL_128(0x3e200000be200000, 0x7f7fffff00000001, q17);
11875 ASSERT_EQUAL_128(0x0000000080000000, 0x7f800000ff800000, q18);
11876 ASSERT_EQUAL_128(0x7fc7ffffffc7ffff, 0x7fc7ffffffc7ffff, q19);
11877 ASSERT_EQUAL_128(0x4f6800004f7fffff, 0x0000000180000001, q20);
11878 ASSERT_EQUAL_128(0, 0x7f7fffff, q21);
11879 TEARDOWN();
11880}
11881
11882
armvixl578645f2013-08-15 17:21:42 +010011883// Test that scvtf and ucvtf can convert the 64-bit input into the expected
11884// value. All possible values of 'fbits' are tested. The expected value is
11885// modified accordingly in each case.
11886//
11887// The expected value is specified as the bit encoding of the expected double
11888// produced by scvtf (expected_scvtf_bits) as well as ucvtf
11889// (expected_ucvtf_bits).
11890//
11891// Where the input value is representable by int32_t or uint32_t, conversions
11892// from W registers will also be tested.
11893static void TestUScvtfHelper(uint64_t in,
11894 uint64_t expected_scvtf_bits,
11895 uint64_t expected_ucvtf_bits) {
11896 uint64_t u64 = in;
11897 uint32_t u32 = u64 & 0xffffffff;
11898 int64_t s64 = static_cast<int64_t>(in);
11899 int32_t s32 = s64 & 0x7fffffff;
11900
11901 bool cvtf_s32 = (s64 == s32);
11902 bool cvtf_u32 = (u64 == u32);
11903
11904 double results_scvtf_x[65];
11905 double results_ucvtf_x[65];
11906 double results_scvtf_w[33];
11907 double results_ucvtf_w[33];
11908
armvixlad96eda2013-06-14 11:42:37 +010011909 SETUP();
armvixlad96eda2013-06-14 11:42:37 +010011910 START();
armvixlad96eda2013-06-14 11:42:37 +010011911
armvixlb0c8ae22014-03-21 14:03:59 +000011912 __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
11913 __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
11914 __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
11915 __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
armvixl578645f2013-08-15 17:21:42 +010011916
11917 __ Mov(x10, s64);
11918
11919 // Corrupt the top word, in case it is accidentally used during W-register
11920 // conversions.
11921 __ Mov(x11, 0x5555555555555555);
11922 __ Bfi(x11, x10, 0, kWRegSize);
11923
11924 // Test integer conversions.
11925 __ Scvtf(d0, x10);
11926 __ Ucvtf(d1, x10);
11927 __ Scvtf(d2, w11);
11928 __ Ucvtf(d3, w11);
11929 __ Str(d0, MemOperand(x0));
11930 __ Str(d1, MemOperand(x1));
11931 __ Str(d2, MemOperand(x2));
11932 __ Str(d3, MemOperand(x3));
11933
11934 // Test all possible values of fbits.
11935 for (int fbits = 1; fbits <= 32; fbits++) {
11936 __ Scvtf(d0, x10, fbits);
11937 __ Ucvtf(d1, x10, fbits);
11938 __ Scvtf(d2, w11, fbits);
11939 __ Ucvtf(d3, w11, fbits);
11940 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
11941 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
11942 __ Str(d2, MemOperand(x2, fbits * kDRegSizeInBytes));
11943 __ Str(d3, MemOperand(x3, fbits * kDRegSizeInBytes));
11944 }
11945
11946 // Conversions from W registers can only handle fbits values <= 32, so just
11947 // test conversions from X registers for 32 < fbits <= 64.
11948 for (int fbits = 33; fbits <= 64; fbits++) {
11949 __ Scvtf(d0, x10, fbits);
11950 __ Ucvtf(d1, x10, fbits);
11951 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
11952 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
11953 }
11954
11955 END();
armvixlad96eda2013-06-14 11:42:37 +010011956 RUN();
11957
armvixl578645f2013-08-15 17:21:42 +010011958 // Check the results.
11959 double expected_scvtf_base = rawbits_to_double(expected_scvtf_bits);
11960 double expected_ucvtf_base = rawbits_to_double(expected_ucvtf_bits);
11961
11962 for (int fbits = 0; fbits <= 32; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010011963 double expected_scvtf = expected_scvtf_base / std::pow(2, fbits);
11964 double expected_ucvtf = expected_ucvtf_base / std::pow(2, fbits);
armvixl578645f2013-08-15 17:21:42 +010011965 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
11966 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
11967 if (cvtf_s32) ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_w[fbits]);
11968 if (cvtf_u32) ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_w[fbits]);
11969 }
11970 for (int fbits = 33; fbits <= 64; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010011971 double expected_scvtf = expected_scvtf_base / std::pow(2, fbits);
11972 double expected_ucvtf = expected_ucvtf_base / std::pow(2, fbits);
armvixl578645f2013-08-15 17:21:42 +010011973 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
11974 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
11975 }
armvixlad96eda2013-06-14 11:42:37 +010011976
11977 TEARDOWN();
11978}
11979
11980
armvixl578645f2013-08-15 17:21:42 +010011981TEST(scvtf_ucvtf_double) {
11982 // Simple conversions of positive numbers which require no rounding; the
11983 // results should not depened on the rounding mode, and ucvtf and scvtf should
11984 // produce the same result.
11985 TestUScvtfHelper(0x0000000000000000, 0x0000000000000000, 0x0000000000000000);
11986 TestUScvtfHelper(0x0000000000000001, 0x3ff0000000000000, 0x3ff0000000000000);
11987 TestUScvtfHelper(0x0000000040000000, 0x41d0000000000000, 0x41d0000000000000);
11988 TestUScvtfHelper(0x0000000100000000, 0x41f0000000000000, 0x41f0000000000000);
11989 TestUScvtfHelper(0x4000000000000000, 0x43d0000000000000, 0x43d0000000000000);
11990 // Test mantissa extremities.
11991 TestUScvtfHelper(0x4000000000000400, 0x43d0000000000001, 0x43d0000000000001);
11992 // The largest int32_t that fits in a double.
11993 TestUScvtfHelper(0x000000007fffffff, 0x41dfffffffc00000, 0x41dfffffffc00000);
11994 // Values that would be negative if treated as an int32_t.
11995 TestUScvtfHelper(0x00000000ffffffff, 0x41efffffffe00000, 0x41efffffffe00000);
11996 TestUScvtfHelper(0x0000000080000000, 0x41e0000000000000, 0x41e0000000000000);
11997 TestUScvtfHelper(0x0000000080000001, 0x41e0000000200000, 0x41e0000000200000);
11998 // The largest int64_t that fits in a double.
11999 TestUScvtfHelper(0x7ffffffffffffc00, 0x43dfffffffffffff, 0x43dfffffffffffff);
12000 // Check for bit pattern reproduction.
12001 TestUScvtfHelper(0x0123456789abcde0, 0x43723456789abcde, 0x43723456789abcde);
12002 TestUScvtfHelper(0x0000000012345678, 0x41b2345678000000, 0x41b2345678000000);
12003
12004 // Simple conversions of negative int64_t values. These require no rounding,
12005 // and the results should not depend on the rounding mode.
12006 TestUScvtfHelper(0xffffffffc0000000, 0xc1d0000000000000, 0x43effffffff80000);
12007 TestUScvtfHelper(0xffffffff00000000, 0xc1f0000000000000, 0x43efffffffe00000);
12008 TestUScvtfHelper(0xc000000000000000, 0xc3d0000000000000, 0x43e8000000000000);
12009
12010 // Conversions which require rounding.
12011 TestUScvtfHelper(0x1000000000000000, 0x43b0000000000000, 0x43b0000000000000);
12012 TestUScvtfHelper(0x1000000000000001, 0x43b0000000000000, 0x43b0000000000000);
12013 TestUScvtfHelper(0x1000000000000080, 0x43b0000000000000, 0x43b0000000000000);
12014 TestUScvtfHelper(0x1000000000000081, 0x43b0000000000001, 0x43b0000000000001);
12015 TestUScvtfHelper(0x1000000000000100, 0x43b0000000000001, 0x43b0000000000001);
12016 TestUScvtfHelper(0x1000000000000101, 0x43b0000000000001, 0x43b0000000000001);
12017 TestUScvtfHelper(0x1000000000000180, 0x43b0000000000002, 0x43b0000000000002);
12018 TestUScvtfHelper(0x1000000000000181, 0x43b0000000000002, 0x43b0000000000002);
12019 TestUScvtfHelper(0x1000000000000200, 0x43b0000000000002, 0x43b0000000000002);
12020 TestUScvtfHelper(0x1000000000000201, 0x43b0000000000002, 0x43b0000000000002);
12021 TestUScvtfHelper(0x1000000000000280, 0x43b0000000000002, 0x43b0000000000002);
12022 TestUScvtfHelper(0x1000000000000281, 0x43b0000000000003, 0x43b0000000000003);
12023 TestUScvtfHelper(0x1000000000000300, 0x43b0000000000003, 0x43b0000000000003);
12024 // Check rounding of negative int64_t values (and large uint64_t values).
12025 TestUScvtfHelper(0x8000000000000000, 0xc3e0000000000000, 0x43e0000000000000);
12026 TestUScvtfHelper(0x8000000000000001, 0xc3e0000000000000, 0x43e0000000000000);
12027 TestUScvtfHelper(0x8000000000000200, 0xc3e0000000000000, 0x43e0000000000000);
12028 TestUScvtfHelper(0x8000000000000201, 0xc3dfffffffffffff, 0x43e0000000000000);
12029 TestUScvtfHelper(0x8000000000000400, 0xc3dfffffffffffff, 0x43e0000000000000);
12030 TestUScvtfHelper(0x8000000000000401, 0xc3dfffffffffffff, 0x43e0000000000001);
12031 TestUScvtfHelper(0x8000000000000600, 0xc3dffffffffffffe, 0x43e0000000000001);
12032 TestUScvtfHelper(0x8000000000000601, 0xc3dffffffffffffe, 0x43e0000000000001);
12033 TestUScvtfHelper(0x8000000000000800, 0xc3dffffffffffffe, 0x43e0000000000001);
12034 TestUScvtfHelper(0x8000000000000801, 0xc3dffffffffffffe, 0x43e0000000000001);
12035 TestUScvtfHelper(0x8000000000000a00, 0xc3dffffffffffffe, 0x43e0000000000001);
12036 TestUScvtfHelper(0x8000000000000a01, 0xc3dffffffffffffd, 0x43e0000000000001);
12037 TestUScvtfHelper(0x8000000000000c00, 0xc3dffffffffffffd, 0x43e0000000000002);
12038 // Round up to produce a result that's too big for the input to represent.
12039 TestUScvtfHelper(0x7ffffffffffffe00, 0x43e0000000000000, 0x43e0000000000000);
12040 TestUScvtfHelper(0x7fffffffffffffff, 0x43e0000000000000, 0x43e0000000000000);
12041 TestUScvtfHelper(0xfffffffffffffc00, 0xc090000000000000, 0x43f0000000000000);
12042 TestUScvtfHelper(0xffffffffffffffff, 0xbff0000000000000, 0x43f0000000000000);
12043}
12044
12045
12046// The same as TestUScvtfHelper, but convert to floats.
12047static void TestUScvtf32Helper(uint64_t in,
12048 uint32_t expected_scvtf_bits,
12049 uint32_t expected_ucvtf_bits) {
12050 uint64_t u64 = in;
12051 uint32_t u32 = u64 & 0xffffffff;
12052 int64_t s64 = static_cast<int64_t>(in);
12053 int32_t s32 = s64 & 0x7fffffff;
12054
12055 bool cvtf_s32 = (s64 == s32);
12056 bool cvtf_u32 = (u64 == u32);
12057
12058 float results_scvtf_x[65];
12059 float results_ucvtf_x[65];
12060 float results_scvtf_w[33];
12061 float results_ucvtf_w[33];
12062
armvixlad96eda2013-06-14 11:42:37 +010012063 SETUP();
armvixlad96eda2013-06-14 11:42:37 +010012064 START();
armvixlad96eda2013-06-14 11:42:37 +010012065
armvixlb0c8ae22014-03-21 14:03:59 +000012066 __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
12067 __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
12068 __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
12069 __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
armvixl578645f2013-08-15 17:21:42 +010012070
12071 __ Mov(x10, s64);
12072
12073 // Corrupt the top word, in case it is accidentally used during W-register
12074 // conversions.
12075 __ Mov(x11, 0x5555555555555555);
12076 __ Bfi(x11, x10, 0, kWRegSize);
12077
12078 // Test integer conversions.
12079 __ Scvtf(s0, x10);
12080 __ Ucvtf(s1, x10);
12081 __ Scvtf(s2, w11);
12082 __ Ucvtf(s3, w11);
12083 __ Str(s0, MemOperand(x0));
12084 __ Str(s1, MemOperand(x1));
12085 __ Str(s2, MemOperand(x2));
12086 __ Str(s3, MemOperand(x3));
12087
12088 // Test all possible values of fbits.
12089 for (int fbits = 1; fbits <= 32; fbits++) {
12090 __ Scvtf(s0, x10, fbits);
12091 __ Ucvtf(s1, x10, fbits);
12092 __ Scvtf(s2, w11, fbits);
12093 __ Ucvtf(s3, w11, fbits);
12094 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
12095 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
12096 __ Str(s2, MemOperand(x2, fbits * kSRegSizeInBytes));
12097 __ Str(s3, MemOperand(x3, fbits * kSRegSizeInBytes));
12098 }
12099
12100 // Conversions from W registers can only handle fbits values <= 32, so just
12101 // test conversions from X registers for 32 < fbits <= 64.
12102 for (int fbits = 33; fbits <= 64; fbits++) {
12103 __ Scvtf(s0, x10, fbits);
12104 __ Ucvtf(s1, x10, fbits);
12105 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
12106 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
12107 }
armvixlad96eda2013-06-14 11:42:37 +010012108
12109 END();
armvixlad96eda2013-06-14 11:42:37 +010012110 RUN();
12111
armvixl578645f2013-08-15 17:21:42 +010012112 // Check the results.
12113 float expected_scvtf_base = rawbits_to_float(expected_scvtf_bits);
12114 float expected_ucvtf_base = rawbits_to_float(expected_ucvtf_bits);
armvixlad96eda2013-06-14 11:42:37 +010012115
armvixl578645f2013-08-15 17:21:42 +010012116 for (int fbits = 0; fbits <= 32; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010012117 float expected_scvtf = expected_scvtf_base / std::pow(2.0f, fbits);
12118 float expected_ucvtf = expected_ucvtf_base / std::pow(2.0f, fbits);
armvixl578645f2013-08-15 17:21:42 +010012119 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
12120 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
12121 if (cvtf_s32) ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_w[fbits]);
12122 if (cvtf_u32) ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_w[fbits]);
armvixl578645f2013-08-15 17:21:42 +010012123 }
12124 for (int fbits = 33; fbits <= 64; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010012125 float expected_scvtf = expected_scvtf_base / std::pow(2.0f, fbits);
12126 float expected_ucvtf = expected_ucvtf_base / std::pow(2.0f, fbits);
armvixl578645f2013-08-15 17:21:42 +010012127 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
12128 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
12129 }
armvixlad96eda2013-06-14 11:42:37 +010012130
12131 TEARDOWN();
12132}
12133
12134
armvixl578645f2013-08-15 17:21:42 +010012135TEST(scvtf_ucvtf_float) {
12136 // Simple conversions of positive numbers which require no rounding; the
12137 // results should not depened on the rounding mode, and ucvtf and scvtf should
12138 // produce the same result.
12139 TestUScvtf32Helper(0x0000000000000000, 0x00000000, 0x00000000);
12140 TestUScvtf32Helper(0x0000000000000001, 0x3f800000, 0x3f800000);
12141 TestUScvtf32Helper(0x0000000040000000, 0x4e800000, 0x4e800000);
12142 TestUScvtf32Helper(0x0000000100000000, 0x4f800000, 0x4f800000);
12143 TestUScvtf32Helper(0x4000000000000000, 0x5e800000, 0x5e800000);
12144 // Test mantissa extremities.
12145 TestUScvtf32Helper(0x0000000000800001, 0x4b000001, 0x4b000001);
12146 TestUScvtf32Helper(0x4000008000000000, 0x5e800001, 0x5e800001);
12147 // The largest int32_t that fits in a float.
12148 TestUScvtf32Helper(0x000000007fffff80, 0x4effffff, 0x4effffff);
12149 // Values that would be negative if treated as an int32_t.
12150 TestUScvtf32Helper(0x00000000ffffff00, 0x4f7fffff, 0x4f7fffff);
12151 TestUScvtf32Helper(0x0000000080000000, 0x4f000000, 0x4f000000);
12152 TestUScvtf32Helper(0x0000000080000100, 0x4f000001, 0x4f000001);
12153 // The largest int64_t that fits in a float.
12154 TestUScvtf32Helper(0x7fffff8000000000, 0x5effffff, 0x5effffff);
12155 // Check for bit pattern reproduction.
12156 TestUScvtf32Helper(0x0000000000876543, 0x4b076543, 0x4b076543);
12157
12158 // Simple conversions of negative int64_t values. These require no rounding,
12159 // and the results should not depend on the rounding mode.
12160 TestUScvtf32Helper(0xfffffc0000000000, 0xd4800000, 0x5f7ffffc);
12161 TestUScvtf32Helper(0xc000000000000000, 0xde800000, 0x5f400000);
12162
12163 // Conversions which require rounding.
12164 TestUScvtf32Helper(0x0000800000000000, 0x57000000, 0x57000000);
12165 TestUScvtf32Helper(0x0000800000000001, 0x57000000, 0x57000000);
12166 TestUScvtf32Helper(0x0000800000800000, 0x57000000, 0x57000000);
12167 TestUScvtf32Helper(0x0000800000800001, 0x57000001, 0x57000001);
12168 TestUScvtf32Helper(0x0000800001000000, 0x57000001, 0x57000001);
12169 TestUScvtf32Helper(0x0000800001000001, 0x57000001, 0x57000001);
12170 TestUScvtf32Helper(0x0000800001800000, 0x57000002, 0x57000002);
12171 TestUScvtf32Helper(0x0000800001800001, 0x57000002, 0x57000002);
12172 TestUScvtf32Helper(0x0000800002000000, 0x57000002, 0x57000002);
12173 TestUScvtf32Helper(0x0000800002000001, 0x57000002, 0x57000002);
12174 TestUScvtf32Helper(0x0000800002800000, 0x57000002, 0x57000002);
12175 TestUScvtf32Helper(0x0000800002800001, 0x57000003, 0x57000003);
12176 TestUScvtf32Helper(0x0000800003000000, 0x57000003, 0x57000003);
12177 // Check rounding of negative int64_t values (and large uint64_t values).
12178 TestUScvtf32Helper(0x8000000000000000, 0xdf000000, 0x5f000000);
12179 TestUScvtf32Helper(0x8000000000000001, 0xdf000000, 0x5f000000);
12180 TestUScvtf32Helper(0x8000004000000000, 0xdf000000, 0x5f000000);
12181 TestUScvtf32Helper(0x8000004000000001, 0xdeffffff, 0x5f000000);
12182 TestUScvtf32Helper(0x8000008000000000, 0xdeffffff, 0x5f000000);
12183 TestUScvtf32Helper(0x8000008000000001, 0xdeffffff, 0x5f000001);
12184 TestUScvtf32Helper(0x800000c000000000, 0xdefffffe, 0x5f000001);
12185 TestUScvtf32Helper(0x800000c000000001, 0xdefffffe, 0x5f000001);
12186 TestUScvtf32Helper(0x8000010000000000, 0xdefffffe, 0x5f000001);
12187 TestUScvtf32Helper(0x8000010000000001, 0xdefffffe, 0x5f000001);
12188 TestUScvtf32Helper(0x8000014000000000, 0xdefffffe, 0x5f000001);
12189 TestUScvtf32Helper(0x8000014000000001, 0xdefffffd, 0x5f000001);
12190 TestUScvtf32Helper(0x8000018000000000, 0xdefffffd, 0x5f000002);
12191 // Round up to produce a result that's too big for the input to represent.
12192 TestUScvtf32Helper(0x000000007fffffc0, 0x4f000000, 0x4f000000);
12193 TestUScvtf32Helper(0x000000007fffffff, 0x4f000000, 0x4f000000);
12194 TestUScvtf32Helper(0x00000000ffffff80, 0x4f800000, 0x4f800000);
12195 TestUScvtf32Helper(0x00000000ffffffff, 0x4f800000, 0x4f800000);
12196 TestUScvtf32Helper(0x7fffffc000000000, 0x5f000000, 0x5f000000);
12197 TestUScvtf32Helper(0x7fffffffffffffff, 0x5f000000, 0x5f000000);
12198 TestUScvtf32Helper(0xffffff8000000000, 0xd3000000, 0x5f800000);
12199 TestUScvtf32Helper(0xffffffffffffffff, 0xbf800000, 0x5f800000);
12200}
12201
12202
armvixlad96eda2013-06-14 11:42:37 +010012203TEST(system_mrs) {
12204 SETUP();
12205
12206 START();
12207 __ Mov(w0, 0);
12208 __ Mov(w1, 1);
12209 __ Mov(w2, 0x80000000);
12210
12211 // Set the Z and C flags.
12212 __ Cmp(w0, w0);
12213 __ Mrs(x3, NZCV);
12214
12215 // Set the N flag.
12216 __ Cmp(w0, w1);
12217 __ Mrs(x4, NZCV);
12218
12219 // Set the Z, C and V flags.
armvixlf37fdc02014-02-05 13:22:16 +000012220 __ Adds(w0, w2, w2);
armvixlad96eda2013-06-14 11:42:37 +010012221 __ Mrs(x5, NZCV);
armvixl578645f2013-08-15 17:21:42 +010012222
12223 // Read the default FPCR.
12224 __ Mrs(x6, FPCR);
armvixlad96eda2013-06-14 11:42:37 +010012225 END();
12226
12227 RUN();
12228
armvixl578645f2013-08-15 17:21:42 +010012229 // NZCV
armvixlad96eda2013-06-14 11:42:37 +010012230 ASSERT_EQUAL_32(ZCFlag, w3);
12231 ASSERT_EQUAL_32(NFlag, w4);
12232 ASSERT_EQUAL_32(ZCVFlag, w5);
12233
armvixl578645f2013-08-15 17:21:42 +010012234 // FPCR
12235 // The default FPCR on Linux-based platforms is 0.
12236 ASSERT_EQUAL_32(0, w6);
12237
armvixlad96eda2013-06-14 11:42:37 +010012238 TEARDOWN();
12239}
12240
12241
12242TEST(system_msr) {
armvixl578645f2013-08-15 17:21:42 +010012243 // All FPCR fields that must be implemented: AHP, DN, FZ, RMode
12244 const uint64_t fpcr_core = 0x07c00000;
12245
12246 // All FPCR fields (including fields which may be read-as-zero):
12247 // Stride, Len
12248 // IDE, IXE, UFE, OFE, DZE, IOE
12249 const uint64_t fpcr_all = fpcr_core | 0x00379f00;
12250
armvixlad96eda2013-06-14 11:42:37 +010012251 SETUP();
12252
12253 START();
12254 __ Mov(w0, 0);
12255 __ Mov(w1, 0x7fffffff);
12256
12257 __ Mov(x7, 0);
12258
12259 __ Mov(x10, NVFlag);
12260 __ Cmp(w0, w0); // Set Z and C.
12261 __ Msr(NZCV, x10); // Set N and V.
12262 // The Msr should have overwritten every flag set by the Cmp.
12263 __ Cinc(x7, x7, mi); // N
12264 __ Cinc(x7, x7, ne); // !Z
12265 __ Cinc(x7, x7, lo); // !C
12266 __ Cinc(x7, x7, vs); // V
12267
12268 __ Mov(x10, ZCFlag);
12269 __ Cmn(w1, w1); // Set N and V.
12270 __ Msr(NZCV, x10); // Set Z and C.
12271 // The Msr should have overwritten every flag set by the Cmn.
12272 __ Cinc(x7, x7, pl); // !N
12273 __ Cinc(x7, x7, eq); // Z
12274 __ Cinc(x7, x7, hs); // C
12275 __ Cinc(x7, x7, vc); // !V
12276
armvixl578645f2013-08-15 17:21:42 +010012277 // All core FPCR fields must be writable.
12278 __ Mov(x8, fpcr_core);
12279 __ Msr(FPCR, x8);
12280 __ Mrs(x8, FPCR);
12281
12282 // All FPCR fields, including optional ones. This part of the test doesn't
12283 // achieve much other than ensuring that supported fields can be cleared by
12284 // the next test.
12285 __ Mov(x9, fpcr_all);
12286 __ Msr(FPCR, x9);
12287 __ Mrs(x9, FPCR);
12288 __ And(x9, x9, fpcr_core);
12289
12290 // The undefined bits must ignore writes.
12291 // It's conceivable that a future version of the architecture could use these
12292 // fields (making this test fail), but in the meantime this is a useful test
12293 // for the simulator.
12294 __ Mov(x10, ~fpcr_all);
12295 __ Msr(FPCR, x10);
12296 __ Mrs(x10, FPCR);
12297
armvixlad96eda2013-06-14 11:42:37 +010012298 END();
12299
12300 RUN();
12301
12302 // We should have incremented x7 (from 0) exactly 8 times.
12303 ASSERT_EQUAL_64(8, x7);
12304
armvixl578645f2013-08-15 17:21:42 +010012305 ASSERT_EQUAL_64(fpcr_core, x8);
12306 ASSERT_EQUAL_64(fpcr_core, x9);
12307 ASSERT_EQUAL_64(0, x10);
12308
armvixlad96eda2013-06-14 11:42:37 +010012309 TEARDOWN();
12310}
12311
12312
12313TEST(system_nop) {
12314 SETUP();
12315 RegisterDump before;
12316
12317 START();
12318 before.Dump(&masm);
12319 __ Nop();
12320 END();
12321
12322 RUN();
12323
12324 ASSERT_EQUAL_REGISTERS(before);
12325 ASSERT_EQUAL_NZCV(before.flags_nzcv());
12326
12327 TEARDOWN();
12328}
12329
12330
12331TEST(zero_dest) {
12332 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010012333 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +010012334 RegisterDump before;
12335
12336 START();
12337 // Preserve the stack pointer, in case we clobber it.
12338 __ Mov(x30, sp);
12339 // Initialize the other registers used in this test.
armvixlb0c8ae22014-03-21 14:03:59 +000012340 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012341 __ Mov(x0, 0);
12342 __ Mov(x1, literal_base);
12343 for (unsigned i = 2; i < x30.code(); i++) {
12344 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
12345 }
12346 before.Dump(&masm);
12347
12348 // All of these instructions should be NOPs in these forms, but have
12349 // alternate forms which can write into the stack pointer.
12350 __ add(xzr, x0, x1);
12351 __ add(xzr, x1, xzr);
12352 __ add(xzr, xzr, x1);
12353
12354 __ and_(xzr, x0, x2);
12355 __ and_(xzr, x2, xzr);
12356 __ and_(xzr, xzr, x2);
12357
12358 __ bic(xzr, x0, x3);
12359 __ bic(xzr, x3, xzr);
12360 __ bic(xzr, xzr, x3);
12361
12362 __ eon(xzr, x0, x4);
12363 __ eon(xzr, x4, xzr);
12364 __ eon(xzr, xzr, x4);
12365
12366 __ eor(xzr, x0, x5);
12367 __ eor(xzr, x5, xzr);
12368 __ eor(xzr, xzr, x5);
12369
12370 __ orr(xzr, x0, x6);
12371 __ orr(xzr, x6, xzr);
12372 __ orr(xzr, xzr, x6);
12373
12374 __ sub(xzr, x0, x7);
12375 __ sub(xzr, x7, xzr);
12376 __ sub(xzr, xzr, x7);
12377
12378 // Swap the saved stack pointer with the real one. If sp was written
12379 // during the test, it will show up in x30. This is done because the test
12380 // framework assumes that sp will be valid at the end of the test.
12381 __ Mov(x29, x30);
12382 __ Mov(x30, sp);
12383 __ Mov(sp, x29);
12384 // We used x29 as a scratch register, so reset it to make sure it doesn't
12385 // trigger a test failure.
12386 __ Add(x29, x28, x1);
12387 END();
12388
12389 RUN();
12390
12391 ASSERT_EQUAL_REGISTERS(before);
12392 ASSERT_EQUAL_NZCV(before.flags_nzcv());
12393
12394 TEARDOWN();
12395}
12396
12397
12398TEST(zero_dest_setflags) {
12399 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010012400 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +010012401 RegisterDump before;
12402
12403 START();
12404 // Preserve the stack pointer, in case we clobber it.
12405 __ Mov(x30, sp);
12406 // Initialize the other registers used in this test.
armvixlb0c8ae22014-03-21 14:03:59 +000012407 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012408 __ Mov(x0, 0);
12409 __ Mov(x1, literal_base);
12410 for (int i = 2; i < 30; i++) {
12411 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
12412 }
12413 before.Dump(&masm);
12414
12415 // All of these instructions should only write to the flags in these forms,
12416 // but have alternate forms which can write into the stack pointer.
armvixlf37fdc02014-02-05 13:22:16 +000012417 __ adds(xzr, x0, Operand(x1, UXTX));
12418 __ adds(xzr, x1, Operand(xzr, UXTX));
12419 __ adds(xzr, x1, 1234);
12420 __ adds(xzr, x0, x1);
12421 __ adds(xzr, x1, xzr);
12422 __ adds(xzr, xzr, x1);
armvixlad96eda2013-06-14 11:42:37 +010012423
armvixlf37fdc02014-02-05 13:22:16 +000012424 __ ands(xzr, x2, ~0xf);
12425 __ ands(xzr, xzr, ~0xf);
12426 __ ands(xzr, x0, x2);
12427 __ ands(xzr, x2, xzr);
12428 __ ands(xzr, xzr, x2);
armvixlad96eda2013-06-14 11:42:37 +010012429
armvixlf37fdc02014-02-05 13:22:16 +000012430 __ bics(xzr, x3, ~0xf);
12431 __ bics(xzr, xzr, ~0xf);
12432 __ bics(xzr, x0, x3);
12433 __ bics(xzr, x3, xzr);
12434 __ bics(xzr, xzr, x3);
armvixlad96eda2013-06-14 11:42:37 +010012435
armvixlf37fdc02014-02-05 13:22:16 +000012436 __ subs(xzr, x0, Operand(x3, UXTX));
12437 __ subs(xzr, x3, Operand(xzr, UXTX));
12438 __ subs(xzr, x3, 1234);
12439 __ subs(xzr, x0, x3);
12440 __ subs(xzr, x3, xzr);
12441 __ subs(xzr, xzr, x3);
armvixlad96eda2013-06-14 11:42:37 +010012442
12443 // Swap the saved stack pointer with the real one. If sp was written
12444 // during the test, it will show up in x30. This is done because the test
12445 // framework assumes that sp will be valid at the end of the test.
12446 __ Mov(x29, x30);
12447 __ Mov(x30, sp);
12448 __ Mov(sp, x29);
12449 // We used x29 as a scratch register, so reset it to make sure it doesn't
12450 // trigger a test failure.
12451 __ Add(x29, x28, x1);
12452 END();
12453
12454 RUN();
12455
12456 ASSERT_EQUAL_REGISTERS(before);
12457
12458 TEARDOWN();
12459}
12460
12461
12462TEST(register_bit) {
12463 // No code generation takes place in this test, so no need to setup and
12464 // teardown.
12465
12466 // Simple tests.
armvixlb0c8ae22014-03-21 14:03:59 +000012467 assert(x0.Bit() == (UINT64_C(1) << 0));
12468 assert(x1.Bit() == (UINT64_C(1) << 1));
12469 assert(x10.Bit() == (UINT64_C(1) << 10));
armvixlad96eda2013-06-14 11:42:37 +010012470
12471 // AAPCS64 definitions.
armvixlb0c8ae22014-03-21 14:03:59 +000012472 assert(lr.Bit() == (UINT64_C(1) << kLinkRegCode));
armvixlad96eda2013-06-14 11:42:37 +010012473
12474 // Fixed (hardware) definitions.
armvixlb0c8ae22014-03-21 14:03:59 +000012475 assert(xzr.Bit() == (UINT64_C(1) << kZeroRegCode));
armvixlad96eda2013-06-14 11:42:37 +010012476
12477 // Internal ABI definitions.
armvixlb0c8ae22014-03-21 14:03:59 +000012478 assert(sp.Bit() == (UINT64_C(1) << kSPRegInternalCode));
armvixlad96eda2013-06-14 11:42:37 +010012479 assert(sp.Bit() != xzr.Bit());
12480
12481 // xn.Bit() == wn.Bit() at all times, for the same n.
12482 assert(x0.Bit() == w0.Bit());
12483 assert(x1.Bit() == w1.Bit());
12484 assert(x10.Bit() == w10.Bit());
12485 assert(xzr.Bit() == wzr.Bit());
12486 assert(sp.Bit() == wsp.Bit());
12487}
12488
12489
12490TEST(stack_pointer_override) {
12491 // This test generates some stack maintenance code, but the test only checks
12492 // the reported state.
12493 SETUP();
12494 START();
12495
12496 // The default stack pointer in VIXL is sp.
12497 assert(sp.Is(__ StackPointer()));
12498 __ SetStackPointer(x0);
12499 assert(x0.Is(__ StackPointer()));
12500 __ SetStackPointer(x28);
12501 assert(x28.Is(__ StackPointer()));
12502 __ SetStackPointer(sp);
12503 assert(sp.Is(__ StackPointer()));
12504
12505 END();
12506 RUN();
12507 TEARDOWN();
12508}
12509
12510
12511TEST(peek_poke_simple) {
12512 SETUP();
12513 START();
12514
12515 static const RegList x0_to_x3 = x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit();
12516 static const RegList x10_to_x13 = x10.Bit() | x11.Bit() |
12517 x12.Bit() | x13.Bit();
12518
12519 // The literal base is chosen to have two useful properties:
12520 // * When multiplied by small values (such as a register index), this value
12521 // is clearly readable in the result.
12522 // * The value is not formed from repeating fixed-size smaller values, so it
12523 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000012524 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012525
12526 // Initialize the registers.
12527 __ Mov(x0, literal_base);
12528 __ Add(x1, x0, x0);
12529 __ Add(x2, x1, x0);
12530 __ Add(x3, x2, x0);
12531
12532 __ Claim(32);
12533
12534 // Simple exchange.
12535 // After this test:
12536 // x0-x3 should be unchanged.
12537 // w10-w13 should contain the lower words of x0-x3.
12538 __ Poke(x0, 0);
12539 __ Poke(x1, 8);
12540 __ Poke(x2, 16);
12541 __ Poke(x3, 24);
12542 Clobber(&masm, x0_to_x3);
12543 __ Peek(x0, 0);
12544 __ Peek(x1, 8);
12545 __ Peek(x2, 16);
12546 __ Peek(x3, 24);
12547
12548 __ Poke(w0, 0);
12549 __ Poke(w1, 4);
12550 __ Poke(w2, 8);
12551 __ Poke(w3, 12);
12552 Clobber(&masm, x10_to_x13);
12553 __ Peek(w10, 0);
12554 __ Peek(w11, 4);
12555 __ Peek(w12, 8);
12556 __ Peek(w13, 12);
12557
12558 __ Drop(32);
12559
12560 END();
12561 RUN();
12562
12563 ASSERT_EQUAL_64(literal_base * 1, x0);
12564 ASSERT_EQUAL_64(literal_base * 2, x1);
12565 ASSERT_EQUAL_64(literal_base * 3, x2);
12566 ASSERT_EQUAL_64(literal_base * 4, x3);
12567
12568 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
12569 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
12570 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
12571 ASSERT_EQUAL_64((literal_base * 4) & 0xffffffff, x13);
12572
12573 TEARDOWN();
12574}
12575
12576
12577TEST(peek_poke_unaligned) {
12578 SETUP();
12579 START();
12580
12581 // The literal base is chosen to have two useful properties:
12582 // * When multiplied by small values (such as a register index), this value
12583 // is clearly readable in the result.
12584 // * The value is not formed from repeating fixed-size smaller values, so it
12585 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000012586 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012587
12588 // Initialize the registers.
12589 __ Mov(x0, literal_base);
12590 __ Add(x1, x0, x0);
12591 __ Add(x2, x1, x0);
12592 __ Add(x3, x2, x0);
12593 __ Add(x4, x3, x0);
12594 __ Add(x5, x4, x0);
12595 __ Add(x6, x5, x0);
12596
12597 __ Claim(32);
12598
12599 // Unaligned exchanges.
12600 // After this test:
12601 // x0-x6 should be unchanged.
12602 // w10-w12 should contain the lower words of x0-x2.
12603 __ Poke(x0, 1);
12604 Clobber(&masm, x0.Bit());
12605 __ Peek(x0, 1);
12606 __ Poke(x1, 2);
12607 Clobber(&masm, x1.Bit());
12608 __ Peek(x1, 2);
12609 __ Poke(x2, 3);
12610 Clobber(&masm, x2.Bit());
12611 __ Peek(x2, 3);
12612 __ Poke(x3, 4);
12613 Clobber(&masm, x3.Bit());
12614 __ Peek(x3, 4);
12615 __ Poke(x4, 5);
12616 Clobber(&masm, x4.Bit());
12617 __ Peek(x4, 5);
12618 __ Poke(x5, 6);
12619 Clobber(&masm, x5.Bit());
12620 __ Peek(x5, 6);
12621 __ Poke(x6, 7);
12622 Clobber(&masm, x6.Bit());
12623 __ Peek(x6, 7);
12624
12625 __ Poke(w0, 1);
12626 Clobber(&masm, w10.Bit());
12627 __ Peek(w10, 1);
12628 __ Poke(w1, 2);
12629 Clobber(&masm, w11.Bit());
12630 __ Peek(w11, 2);
12631 __ Poke(w2, 3);
12632 Clobber(&masm, w12.Bit());
12633 __ Peek(w12, 3);
12634
12635 __ Drop(32);
12636
12637 END();
12638 RUN();
12639
12640 ASSERT_EQUAL_64(literal_base * 1, x0);
12641 ASSERT_EQUAL_64(literal_base * 2, x1);
12642 ASSERT_EQUAL_64(literal_base * 3, x2);
12643 ASSERT_EQUAL_64(literal_base * 4, x3);
12644 ASSERT_EQUAL_64(literal_base * 5, x4);
12645 ASSERT_EQUAL_64(literal_base * 6, x5);
12646 ASSERT_EQUAL_64(literal_base * 7, x6);
12647
12648 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
12649 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
12650 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
12651
12652 TEARDOWN();
12653}
12654
12655
12656TEST(peek_poke_endianness) {
12657 SETUP();
12658 START();
12659
12660 // The literal base is chosen to have two useful properties:
12661 // * When multiplied by small values (such as a register index), this value
12662 // is clearly readable in the result.
12663 // * The value is not formed from repeating fixed-size smaller values, so it
12664 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000012665 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012666
12667 // Initialize the registers.
12668 __ Mov(x0, literal_base);
12669 __ Add(x1, x0, x0);
12670
12671 __ Claim(32);
12672
12673 // Endianness tests.
12674 // After this section:
12675 // x4 should match x0[31:0]:x0[63:32]
12676 // w5 should match w1[15:0]:w1[31:16]
12677 __ Poke(x0, 0);
12678 __ Poke(x0, 8);
12679 __ Peek(x4, 4);
12680
12681 __ Poke(w1, 0);
12682 __ Poke(w1, 4);
12683 __ Peek(w5, 2);
12684
12685 __ Drop(32);
12686
12687 END();
12688 RUN();
12689
12690 uint64_t x0_expected = literal_base * 1;
12691 uint64_t x1_expected = literal_base * 2;
12692 uint64_t x4_expected = (x0_expected << 32) | (x0_expected >> 32);
12693 uint64_t x5_expected = ((x1_expected << 16) & 0xffff0000) |
12694 ((x1_expected >> 16) & 0x0000ffff);
12695
12696 ASSERT_EQUAL_64(x0_expected, x0);
12697 ASSERT_EQUAL_64(x1_expected, x1);
12698 ASSERT_EQUAL_64(x4_expected, x4);
12699 ASSERT_EQUAL_64(x5_expected, x5);
12700
12701 TEARDOWN();
12702}
12703
12704
12705TEST(peek_poke_mixed) {
12706 SETUP();
12707 START();
12708
armvixl6e2c8272015-03-31 11:04:14 +010012709 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
12710 UseScratchRegisterScope temps(&masm);
12711 temps.ExcludeAll();
12712
armvixlad96eda2013-06-14 11:42:37 +010012713 // The literal base is chosen to have two useful properties:
12714 // * When multiplied by small values (such as a register index), this value
12715 // is clearly readable in the result.
12716 // * The value is not formed from repeating fixed-size smaller values, so it
12717 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000012718 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012719
12720 // Initialize the registers.
12721 __ Mov(x0, literal_base);
12722 __ Add(x1, x0, x0);
12723 __ Add(x2, x1, x0);
12724 __ Add(x3, x2, x0);
12725
12726 __ Claim(32);
12727
12728 // Mix with other stack operations.
12729 // After this section:
12730 // x0-x3 should be unchanged.
12731 // x6 should match x1[31:0]:x0[63:32]
12732 // w7 should match x1[15:0]:x0[63:48]
12733 __ Poke(x1, 8);
12734 __ Poke(x0, 0);
12735 {
armvixlb0c8ae22014-03-21 14:03:59 +000012736 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010012737 __ Mov(x4, __ StackPointer());
12738 __ SetStackPointer(x4);
12739
12740 __ Poke(wzr, 0); // Clobber the space we're about to drop.
12741 __ Drop(4);
12742 __ Peek(x6, 0);
12743 __ Claim(8);
12744 __ Peek(w7, 10);
12745 __ Poke(x3, 28);
12746 __ Poke(xzr, 0); // Clobber the space we're about to drop.
12747 __ Drop(8);
12748 __ Poke(x2, 12);
12749 __ Push(w0);
12750
12751 __ Mov(sp, __ StackPointer());
12752 __ SetStackPointer(sp);
12753 }
12754
12755 __ Pop(x0, x1, x2, x3);
12756
12757 END();
12758 RUN();
12759
12760 uint64_t x0_expected = literal_base * 1;
12761 uint64_t x1_expected = literal_base * 2;
12762 uint64_t x2_expected = literal_base * 3;
12763 uint64_t x3_expected = literal_base * 4;
12764 uint64_t x6_expected = (x1_expected << 32) | (x0_expected >> 32);
12765 uint64_t x7_expected = ((x1_expected << 16) & 0xffff0000) |
12766 ((x0_expected >> 48) & 0x0000ffff);
12767
12768 ASSERT_EQUAL_64(x0_expected, x0);
12769 ASSERT_EQUAL_64(x1_expected, x1);
12770 ASSERT_EQUAL_64(x2_expected, x2);
12771 ASSERT_EQUAL_64(x3_expected, x3);
12772 ASSERT_EQUAL_64(x6_expected, x6);
12773 ASSERT_EQUAL_64(x7_expected, x7);
12774
12775 TEARDOWN();
12776}
12777
12778
armvixlc68cb642014-09-25 18:49:30 +010012779TEST(peek_poke_reglist) {
12780 SETUP();
12781 START();
12782
armvixl6e2c8272015-03-31 11:04:14 +010012783 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
12784 UseScratchRegisterScope temps(&masm);
12785 temps.ExcludeAll();
12786
armvixlc68cb642014-09-25 18:49:30 +010012787 // The literal base is chosen to have two useful properties:
12788 // * When multiplied by small values (such as a register index), this value
12789 // is clearly readable in the result.
12790 // * The value is not formed from repeating fixed-size smaller values, so it
12791 // can be used to detect endianness-related errors.
12792 uint64_t base = 0x0100001000100101;
12793
12794 // Initialize the registers.
12795 __ Mov(x1, base);
12796 __ Add(x2, x1, x1);
12797 __ Add(x3, x2, x1);
12798 __ Add(x4, x3, x1);
12799
12800 CPURegList list_1(x1, x2, x3, x4);
12801 CPURegList list_2(x11, x12, x13, x14);
12802 int list_1_size = list_1.TotalSizeInBytes();
12803
12804 __ Claim(2 * list_1_size);
12805
12806 __ PokeCPURegList(list_1, 0);
12807 __ PokeXRegList(list_1.list(), list_1_size);
12808 __ PeekCPURegList(list_2, 2 * kXRegSizeInBytes);
12809 __ PeekXRegList(x15.Bit(), kWRegSizeInBytes);
12810 __ PeekWRegList(w16.Bit() | w17.Bit(), 3 * kXRegSizeInBytes);
12811
12812 __ Drop(2 * list_1_size);
12813
12814
12815 uint64_t base_d = 0x1010010001000010;
12816
12817 // Initialize the registers.
12818 __ Mov(x1, base_d);
12819 __ Add(x2, x1, x1);
12820 __ Add(x3, x2, x1);
12821 __ Add(x4, x3, x1);
12822 __ Fmov(d1, x1);
12823 __ Fmov(d2, x2);
12824 __ Fmov(d3, x3);
12825 __ Fmov(d4, x4);
12826
12827 CPURegList list_d_1(d1, d2, d3, d4);
12828 CPURegList list_d_2(d11, d12, d13, d14);
12829 int list_d_1_size = list_d_1.TotalSizeInBytes();
12830
12831 __ Claim(2 * list_d_1_size);
12832
12833 __ PokeCPURegList(list_d_1, 0);
12834 __ PokeDRegList(list_d_1.list(), list_d_1_size);
12835 __ PeekCPURegList(list_d_2, 2 * kDRegSizeInBytes);
12836 __ PeekDRegList(d15.Bit(), kSRegSizeInBytes);
12837 __ PeekSRegList(s16.Bit() | s17.Bit(), 3 * kDRegSizeInBytes);
12838
12839 __ Drop(2 * list_d_1_size);
12840
12841
12842 END();
12843 RUN();
12844
12845 ASSERT_EQUAL_64(3 * base, x11);
12846 ASSERT_EQUAL_64(4 * base, x12);
12847 ASSERT_EQUAL_64(1 * base, x13);
12848 ASSERT_EQUAL_64(2 * base, x14);
12849 ASSERT_EQUAL_64(((1 * base) >> kWRegSize) | ((2 * base) << kWRegSize), x15);
12850 ASSERT_EQUAL_64(2 * base, x14);
12851 ASSERT_EQUAL_32((4 * base) & kWRegMask, w16);
12852 ASSERT_EQUAL_32((4 * base) >> kWRegSize, w17);
12853
12854 ASSERT_EQUAL_FP64(rawbits_to_double(3 * base_d), d11);
12855 ASSERT_EQUAL_FP64(rawbits_to_double(4 * base_d), d12);
12856 ASSERT_EQUAL_FP64(rawbits_to_double(1 * base_d), d13);
12857 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base_d), d14);
12858 ASSERT_EQUAL_FP64(
12859 rawbits_to_double((base_d >> kSRegSize) | ((2 * base_d) << kSRegSize)),
12860 d15);
12861 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base_d), d14);
12862 ASSERT_EQUAL_FP32(rawbits_to_float((4 * base_d) & kSRegMask), s16);
12863 ASSERT_EQUAL_FP32(rawbits_to_float((4 * base_d) >> kSRegSize), s17);
12864
12865 TEARDOWN();
12866}
12867
12868
armvixl6e2c8272015-03-31 11:04:14 +010012869TEST(load_store_reglist) {
12870 SETUP();
12871 START();
12872
12873 // The literal base is chosen to have two useful properties:
12874 // * When multiplied by small values (such as a register index), this value
12875 // is clearly readable in the result.
12876 // * The value is not formed from repeating fixed-size smaller values, so it
12877 // can be used to detect endianness-related errors.
12878 uint64_t high_base = UINT32_C(0x01000010);
12879 uint64_t low_base = UINT32_C(0x00100101);
12880 uint64_t base = (high_base << 32) | low_base;
12881 uint64_t array[21];
12882 memset(array, 0, sizeof(array));
12883
12884 // Initialize the registers.
12885 __ Mov(x1, base);
12886 __ Add(x2, x1, x1);
12887 __ Add(x3, x2, x1);
12888 __ Add(x4, x3, x1);
12889 __ Fmov(d1, x1);
12890 __ Fmov(d2, x2);
12891 __ Fmov(d3, x3);
12892 __ Fmov(d4, x4);
12893 __ Fmov(d5, x1);
12894 __ Fmov(d6, x2);
12895 __ Fmov(d7, x3);
12896 __ Fmov(d8, x4);
12897
12898 Register reg_base = x20;
12899 Register reg_index = x21;
12900 int size_stored = 0;
12901
12902 __ Mov(reg_base, reinterpret_cast<uintptr_t>(&array));
12903
12904 // Test aligned accesses.
12905 CPURegList list_src(w1, w2, w3, w4);
12906 CPURegList list_dst(w11, w12, w13, w14);
12907 CPURegList list_fp_src_1(d1, d2, d3, d4);
12908 CPURegList list_fp_dst_1(d11, d12, d13, d14);
12909
12910 __ StoreCPURegList(list_src, MemOperand(reg_base, 0 * sizeof(uint64_t)));
12911 __ LoadCPURegList(list_dst, MemOperand(reg_base, 0 * sizeof(uint64_t)));
12912 size_stored += 4 * kWRegSizeInBytes;
12913
12914 __ Mov(reg_index, size_stored);
12915 __ StoreCPURegList(list_src, MemOperand(reg_base, reg_index));
12916 __ LoadCPURegList(list_dst, MemOperand(reg_base, reg_index));
12917 size_stored += 4 * kWRegSizeInBytes;
12918
12919 __ StoreCPURegList(list_fp_src_1, MemOperand(reg_base, size_stored));
12920 __ LoadCPURegList(list_fp_dst_1, MemOperand(reg_base, size_stored));
12921 size_stored += 4 * kDRegSizeInBytes;
12922
12923 __ Mov(reg_index, size_stored);
12924 __ StoreCPURegList(list_fp_src_1, MemOperand(reg_base, reg_index));
12925 __ LoadCPURegList(list_fp_dst_1, MemOperand(reg_base, reg_index));
12926 size_stored += 4 * kDRegSizeInBytes;
12927
12928 // Test unaligned accesses.
12929 CPURegList list_fp_src_2(d5, d6, d7, d8);
12930 CPURegList list_fp_dst_2(d15, d16, d17, d18);
12931
12932 __ Str(wzr, MemOperand(reg_base, size_stored));
12933 size_stored += 1 * kWRegSizeInBytes;
12934 __ StoreCPURegList(list_fp_src_2, MemOperand(reg_base, size_stored));
12935 __ LoadCPURegList(list_fp_dst_2, MemOperand(reg_base, size_stored));
12936 size_stored += 4 * kDRegSizeInBytes;
12937
12938 __ Mov(reg_index, size_stored);
12939 __ StoreCPURegList(list_fp_src_2, MemOperand(reg_base, reg_index));
12940 __ LoadCPURegList(list_fp_dst_2, MemOperand(reg_base, reg_index));
12941
12942 END();
12943 RUN();
12944
12945 VIXL_CHECK(array[0] == (1 * low_base) + (2 * low_base << kWRegSize));
12946 VIXL_CHECK(array[1] == (3 * low_base) + (4 * low_base << kWRegSize));
12947 VIXL_CHECK(array[2] == (1 * low_base) + (2 * low_base << kWRegSize));
12948 VIXL_CHECK(array[3] == (3 * low_base) + (4 * low_base << kWRegSize));
12949 VIXL_CHECK(array[4] == 1 * base);
12950 VIXL_CHECK(array[5] == 2 * base);
12951 VIXL_CHECK(array[6] == 3 * base);
12952 VIXL_CHECK(array[7] == 4 * base);
12953 VIXL_CHECK(array[8] == 1 * base);
12954 VIXL_CHECK(array[9] == 2 * base);
12955 VIXL_CHECK(array[10] == 3 * base);
12956 VIXL_CHECK(array[11] == 4 * base);
12957 VIXL_CHECK(array[12] == ((1 * low_base) << kSRegSize));
12958 VIXL_CHECK(array[13] == (((2 * low_base) << kSRegSize) | (1 * high_base)));
12959 VIXL_CHECK(array[14] == (((3 * low_base) << kSRegSize) | (2 * high_base)));
12960 VIXL_CHECK(array[15] == (((4 * low_base) << kSRegSize) | (3 * high_base)));
12961 VIXL_CHECK(array[16] == (((1 * low_base) << kSRegSize) | (4 * high_base)));
12962 VIXL_CHECK(array[17] == (((2 * low_base) << kSRegSize) | (1 * high_base)));
12963 VIXL_CHECK(array[18] == (((3 * low_base) << kSRegSize) | (2 * high_base)));
12964 VIXL_CHECK(array[19] == (((4 * low_base) << kSRegSize) | (3 * high_base)));
12965 VIXL_CHECK(array[20] == (4 * high_base));
12966
12967 ASSERT_EQUAL_64(1 * low_base, x11);
12968 ASSERT_EQUAL_64(2 * low_base, x12);
12969 ASSERT_EQUAL_64(3 * low_base, x13);
12970 ASSERT_EQUAL_64(4 * low_base, x14);
12971 ASSERT_EQUAL_FP64(rawbits_to_double(1 * base), d11);
12972 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base), d12);
12973 ASSERT_EQUAL_FP64(rawbits_to_double(3 * base), d13);
12974 ASSERT_EQUAL_FP64(rawbits_to_double(4 * base), d14);
12975 ASSERT_EQUAL_FP64(rawbits_to_double(1 * base), d15);
12976 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base), d16);
12977 ASSERT_EQUAL_FP64(rawbits_to_double(3 * base), d17);
12978 ASSERT_EQUAL_FP64(rawbits_to_double(4 * base), d18);
12979
12980 TEARDOWN();
12981}
12982
12983
armvixlad96eda2013-06-14 11:42:37 +010012984// This enum is used only as an argument to the push-pop test helpers.
12985enum PushPopMethod {
12986 // Push or Pop using the Push and Pop methods, with blocks of up to four
12987 // registers. (Smaller blocks will be used if necessary.)
12988 PushPopByFour,
12989
12990 // Use Push<Size>RegList and Pop<Size>RegList to transfer the registers.
12991 PushPopRegList
12992};
12993
12994
12995// The maximum number of registers that can be used by the PushPopXReg* tests,
12996// where a reg_count field is provided.
12997static int const kPushPopXRegMaxRegCount = -1;
12998
12999// Test a simple push-pop pattern:
13000// * Claim <claim> bytes to set the stack alignment.
13001// * Push <reg_count> registers with size <reg_size>.
13002// * Clobber the register contents.
13003// * Pop <reg_count> registers to restore the original contents.
13004// * Drop <claim> bytes to restore the original stack pointer.
13005//
13006// Different push and pop methods can be specified independently to test for
13007// proper word-endian behaviour.
13008static void PushPopXRegSimpleHelper(int reg_count,
13009 int claim,
13010 int reg_size,
13011 PushPopMethod push_method,
13012 PushPopMethod pop_method) {
13013 SETUP();
13014
13015 START();
13016
13017 // Arbitrarily pick a register to use as a stack pointer.
13018 const Register& stack_pointer = x20;
13019 const RegList allowed = ~stack_pointer.Bit();
13020 if (reg_count == kPushPopXRegMaxRegCount) {
13021 reg_count = CountSetBits(allowed, kNumberOfRegisters);
13022 }
13023 // Work out which registers to use, based on reg_size.
13024 Register r[kNumberOfRegisters];
13025 Register x[kNumberOfRegisters];
13026 RegList list = PopulateRegisterArray(NULL, x, r, reg_size, reg_count,
13027 allowed);
13028
armvixl6e2c8272015-03-31 11:04:14 +010013029 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13030 UseScratchRegisterScope temps(&masm);
13031 temps.ExcludeAll();
13032
armvixlad96eda2013-06-14 11:42:37 +010013033 // The literal base is chosen to have two useful properties:
13034 // * When multiplied by small values (such as a register index), this value
13035 // is clearly readable in the result.
13036 // * The value is not formed from repeating fixed-size smaller values, so it
13037 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000013038 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013039
13040 {
armvixlb0c8ae22014-03-21 14:03:59 +000013041 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013042 __ Mov(stack_pointer, __ StackPointer());
13043 __ SetStackPointer(stack_pointer);
13044
13045 int i;
13046
13047 // Initialize the registers.
13048 for (i = 0; i < reg_count; i++) {
13049 // Always write into the X register, to ensure that the upper word is
13050 // properly ignored by Push when testing W registers.
13051 __ Mov(x[i], literal_base * i);
13052 }
13053
13054 // Claim memory first, as requested.
13055 __ Claim(claim);
13056
13057 switch (push_method) {
13058 case PushPopByFour:
13059 // Push high-numbered registers first (to the highest addresses).
13060 for (i = reg_count; i >= 4; i -= 4) {
13061 __ Push(r[i-1], r[i-2], r[i-3], r[i-4]);
13062 }
13063 // Finish off the leftovers.
13064 switch (i) {
13065 case 3: __ Push(r[2], r[1], r[0]); break;
13066 case 2: __ Push(r[1], r[0]); break;
13067 case 1: __ Push(r[0]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013068 default: VIXL_ASSERT(i == 0); break;
armvixlad96eda2013-06-14 11:42:37 +010013069 }
13070 break;
13071 case PushPopRegList:
13072 __ PushSizeRegList(list, reg_size);
13073 break;
13074 }
13075
13076 // Clobber all the registers, to ensure that they get repopulated by Pop.
13077 Clobber(&masm, list);
13078
13079 switch (pop_method) {
13080 case PushPopByFour:
13081 // Pop low-numbered registers first (from the lowest addresses).
13082 for (i = 0; i <= (reg_count-4); i += 4) {
13083 __ Pop(r[i], r[i+1], r[i+2], r[i+3]);
13084 }
13085 // Finish off the leftovers.
13086 switch (reg_count - i) {
13087 case 3: __ Pop(r[i], r[i+1], r[i+2]); break;
13088 case 2: __ Pop(r[i], r[i+1]); break;
13089 case 1: __ Pop(r[i]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013090 default: VIXL_ASSERT(i == reg_count); break;
armvixlad96eda2013-06-14 11:42:37 +010013091 }
13092 break;
13093 case PushPopRegList:
13094 __ PopSizeRegList(list, reg_size);
13095 break;
13096 }
13097
13098 // Drop memory to restore stack_pointer.
13099 __ Drop(claim);
13100
13101 __ Mov(sp, __ StackPointer());
13102 __ SetStackPointer(sp);
13103 }
13104
13105 END();
13106
13107 RUN();
13108
13109 // Check that the register contents were preserved.
13110 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
13111 // that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +000013112 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +010013113 for (int i = 0; i < reg_count; i++) {
13114 if (x[i].Is(xzr)) {
13115 ASSERT_EQUAL_64(0, x[i]);
13116 } else {
13117 ASSERT_EQUAL_64(literal_base * i, x[i]);
13118 }
13119 }
13120
13121 TEARDOWN();
13122}
13123
13124
13125TEST(push_pop_xreg_simple_32) {
13126 for (int claim = 0; claim <= 8; claim++) {
13127 for (int count = 0; count <= 8; count++) {
13128 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13129 PushPopByFour, PushPopByFour);
13130 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13131 PushPopByFour, PushPopRegList);
13132 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13133 PushPopRegList, PushPopByFour);
13134 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13135 PushPopRegList, PushPopRegList);
13136 }
13137 // Test with the maximum number of registers.
13138 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13139 claim, kWRegSize, PushPopByFour, PushPopByFour);
13140 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13141 claim, kWRegSize, PushPopByFour, PushPopRegList);
13142 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13143 claim, kWRegSize, PushPopRegList, PushPopByFour);
13144 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13145 claim, kWRegSize, PushPopRegList, PushPopRegList);
13146 }
13147}
13148
13149
13150TEST(push_pop_xreg_simple_64) {
13151 for (int claim = 0; claim <= 8; claim++) {
13152 for (int count = 0; count <= 8; count++) {
13153 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13154 PushPopByFour, PushPopByFour);
13155 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13156 PushPopByFour, PushPopRegList);
13157 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13158 PushPopRegList, PushPopByFour);
13159 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13160 PushPopRegList, PushPopRegList);
13161 }
13162 // Test with the maximum number of registers.
13163 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13164 claim, kXRegSize, PushPopByFour, PushPopByFour);
13165 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13166 claim, kXRegSize, PushPopByFour, PushPopRegList);
13167 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13168 claim, kXRegSize, PushPopRegList, PushPopByFour);
13169 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13170 claim, kXRegSize, PushPopRegList, PushPopRegList);
13171 }
13172}
13173
13174
13175// The maximum number of registers that can be used by the PushPopFPXReg* tests,
13176// where a reg_count field is provided.
13177static int const kPushPopFPXRegMaxRegCount = -1;
13178
13179// Test a simple push-pop pattern:
13180// * Claim <claim> bytes to set the stack alignment.
13181// * Push <reg_count> FP registers with size <reg_size>.
13182// * Clobber the register contents.
13183// * Pop <reg_count> FP registers to restore the original contents.
13184// * Drop <claim> bytes to restore the original stack pointer.
13185//
13186// Different push and pop methods can be specified independently to test for
13187// proper word-endian behaviour.
13188static void PushPopFPXRegSimpleHelper(int reg_count,
13189 int claim,
13190 int reg_size,
13191 PushPopMethod push_method,
13192 PushPopMethod pop_method) {
13193 SETUP();
13194
13195 START();
13196
13197 // We can use any floating-point register. None of them are reserved for
13198 // debug code, for example.
13199 static RegList const allowed = ~0;
13200 if (reg_count == kPushPopFPXRegMaxRegCount) {
13201 reg_count = CountSetBits(allowed, kNumberOfFPRegisters);
13202 }
13203 // Work out which registers to use, based on reg_size.
13204 FPRegister v[kNumberOfRegisters];
13205 FPRegister d[kNumberOfRegisters];
13206 RegList list = PopulateFPRegisterArray(NULL, d, v, reg_size, reg_count,
13207 allowed);
13208
13209 // Arbitrarily pick a register to use as a stack pointer.
13210 const Register& stack_pointer = x10;
13211
armvixl6e2c8272015-03-31 11:04:14 +010013212 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13213 UseScratchRegisterScope temps(&masm);
13214 temps.ExcludeAll();
13215
armvixlad96eda2013-06-14 11:42:37 +010013216 // The literal base is chosen to have two useful properties:
13217 // * When multiplied (using an integer) by small values (such as a register
13218 // index), this value is clearly readable in the result.
13219 // * The value is not formed from repeating fixed-size smaller values, so it
13220 // can be used to detect endianness-related errors.
13221 // * It is never a floating-point NaN, and will therefore always compare
13222 // equal to itself.
armvixlb0c8ae22014-03-21 14:03:59 +000013223 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013224
13225 {
armvixlb0c8ae22014-03-21 14:03:59 +000013226 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013227 __ Mov(stack_pointer, __ StackPointer());
13228 __ SetStackPointer(stack_pointer);
13229
13230 int i;
13231
13232 // Initialize the registers, using X registers to load the literal.
13233 __ Mov(x0, 0);
13234 __ Mov(x1, literal_base);
13235 for (i = 0; i < reg_count; i++) {
13236 // Always write into the D register, to ensure that the upper word is
13237 // properly ignored by Push when testing S registers.
13238 __ Fmov(d[i], x0);
13239 // Calculate the next literal.
13240 __ Add(x0, x0, x1);
13241 }
13242
13243 // Claim memory first, as requested.
13244 __ Claim(claim);
13245
13246 switch (push_method) {
13247 case PushPopByFour:
13248 // Push high-numbered registers first (to the highest addresses).
13249 for (i = reg_count; i >= 4; i -= 4) {
13250 __ Push(v[i-1], v[i-2], v[i-3], v[i-4]);
13251 }
13252 // Finish off the leftovers.
13253 switch (i) {
13254 case 3: __ Push(v[2], v[1], v[0]); break;
13255 case 2: __ Push(v[1], v[0]); break;
13256 case 1: __ Push(v[0]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013257 default: VIXL_ASSERT(i == 0); break;
armvixlad96eda2013-06-14 11:42:37 +010013258 }
13259 break;
13260 case PushPopRegList:
armvixl5289c592015-03-02 13:52:04 +000013261 __ PushSizeRegList(list, reg_size, CPURegister::kVRegister);
armvixlad96eda2013-06-14 11:42:37 +010013262 break;
13263 }
13264
13265 // Clobber all the registers, to ensure that they get repopulated by Pop.
13266 ClobberFP(&masm, list);
13267
13268 switch (pop_method) {
13269 case PushPopByFour:
13270 // Pop low-numbered registers first (from the lowest addresses).
13271 for (i = 0; i <= (reg_count-4); i += 4) {
13272 __ Pop(v[i], v[i+1], v[i+2], v[i+3]);
13273 }
13274 // Finish off the leftovers.
13275 switch (reg_count - i) {
13276 case 3: __ Pop(v[i], v[i+1], v[i+2]); break;
13277 case 2: __ Pop(v[i], v[i+1]); break;
13278 case 1: __ Pop(v[i]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013279 default: VIXL_ASSERT(i == reg_count); break;
armvixlad96eda2013-06-14 11:42:37 +010013280 }
13281 break;
13282 case PushPopRegList:
armvixl5289c592015-03-02 13:52:04 +000013283 __ PopSizeRegList(list, reg_size, CPURegister::kVRegister);
armvixlad96eda2013-06-14 11:42:37 +010013284 break;
13285 }
13286
13287 // Drop memory to restore the stack pointer.
13288 __ Drop(claim);
13289
13290 __ Mov(sp, __ StackPointer());
13291 __ SetStackPointer(sp);
13292 }
13293
13294 END();
13295
13296 RUN();
13297
13298 // Check that the register contents were preserved.
13299 // Always use ASSERT_EQUAL_FP64, even when testing S registers, so we can
13300 // test that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +000013301 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +010013302 for (int i = 0; i < reg_count; i++) {
13303 uint64_t literal = literal_base * i;
13304 double expected;
13305 memcpy(&expected, &literal, sizeof(expected));
13306 ASSERT_EQUAL_FP64(expected, d[i]);
13307 }
13308
13309 TEARDOWN();
13310}
13311
13312
13313TEST(push_pop_fp_xreg_simple_32) {
13314 for (int claim = 0; claim <= 8; claim++) {
13315 for (int count = 0; count <= 8; count++) {
13316 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13317 PushPopByFour, PushPopByFour);
13318 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13319 PushPopByFour, PushPopRegList);
13320 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13321 PushPopRegList, PushPopByFour);
13322 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13323 PushPopRegList, PushPopRegList);
13324 }
13325 // Test with the maximum number of registers.
13326 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13327 PushPopByFour, PushPopByFour);
13328 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13329 PushPopByFour, PushPopRegList);
13330 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13331 PushPopRegList, PushPopByFour);
13332 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13333 PushPopRegList, PushPopRegList);
13334 }
13335}
13336
13337
13338TEST(push_pop_fp_xreg_simple_64) {
13339 for (int claim = 0; claim <= 8; claim++) {
13340 for (int count = 0; count <= 8; count++) {
13341 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13342 PushPopByFour, PushPopByFour);
13343 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13344 PushPopByFour, PushPopRegList);
13345 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13346 PushPopRegList, PushPopByFour);
13347 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13348 PushPopRegList, PushPopRegList);
13349 }
13350 // Test with the maximum number of registers.
13351 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13352 PushPopByFour, PushPopByFour);
13353 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13354 PushPopByFour, PushPopRegList);
13355 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13356 PushPopRegList, PushPopByFour);
13357 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13358 PushPopRegList, PushPopRegList);
13359 }
13360}
13361
13362
13363// Push and pop data using an overlapping combination of Push/Pop and
13364// RegList-based methods.
13365static void PushPopXRegMixedMethodsHelper(int claim, int reg_size) {
13366 SETUP();
13367
13368 // Arbitrarily pick a register to use as a stack pointer.
13369 const Register& stack_pointer = x5;
13370 const RegList allowed = ~stack_pointer.Bit();
13371 // Work out which registers to use, based on reg_size.
13372 Register r[10];
13373 Register x[10];
13374 PopulateRegisterArray(NULL, x, r, reg_size, 10, allowed);
13375
13376 // Calculate some handy register lists.
13377 RegList r0_to_r3 = 0;
13378 for (int i = 0; i <= 3; i++) {
13379 r0_to_r3 |= x[i].Bit();
13380 }
13381 RegList r4_to_r5 = 0;
13382 for (int i = 4; i <= 5; i++) {
13383 r4_to_r5 |= x[i].Bit();
13384 }
13385 RegList r6_to_r9 = 0;
13386 for (int i = 6; i <= 9; i++) {
13387 r6_to_r9 |= x[i].Bit();
13388 }
13389
armvixl6e2c8272015-03-31 11:04:14 +010013390 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13391 UseScratchRegisterScope temps(&masm);
13392 temps.ExcludeAll();
13393
armvixlad96eda2013-06-14 11:42:37 +010013394 // The literal base is chosen to have two useful properties:
13395 // * When multiplied by small values (such as a register index), this value
13396 // is clearly readable in the result.
13397 // * The value is not formed from repeating fixed-size smaller values, so it
13398 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000013399 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013400
13401 START();
13402 {
armvixlb0c8ae22014-03-21 14:03:59 +000013403 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013404 __ Mov(stack_pointer, __ StackPointer());
13405 __ SetStackPointer(stack_pointer);
13406
13407 // Claim memory first, as requested.
13408 __ Claim(claim);
13409
13410 __ Mov(x[3], literal_base * 3);
13411 __ Mov(x[2], literal_base * 2);
13412 __ Mov(x[1], literal_base * 1);
13413 __ Mov(x[0], literal_base * 0);
13414
13415 __ PushSizeRegList(r0_to_r3, reg_size);
13416 __ Push(r[3], r[2]);
13417
13418 Clobber(&masm, r0_to_r3);
13419 __ PopSizeRegList(r0_to_r3, reg_size);
13420
13421 __ Push(r[2], r[1], r[3], r[0]);
13422
13423 Clobber(&masm, r4_to_r5);
13424 __ Pop(r[4], r[5]);
13425 Clobber(&masm, r6_to_r9);
13426 __ Pop(r[6], r[7], r[8], r[9]);
13427
13428 // Drop memory to restore stack_pointer.
13429 __ Drop(claim);
13430
13431 __ Mov(sp, __ StackPointer());
13432 __ SetStackPointer(sp);
13433 }
13434
13435 END();
13436
13437 RUN();
13438
13439 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
13440 // that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +000013441 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +010013442
13443 ASSERT_EQUAL_64(literal_base * 3, x[9]);
13444 ASSERT_EQUAL_64(literal_base * 2, x[8]);
13445 ASSERT_EQUAL_64(literal_base * 0, x[7]);
13446 ASSERT_EQUAL_64(literal_base * 3, x[6]);
13447 ASSERT_EQUAL_64(literal_base * 1, x[5]);
13448 ASSERT_EQUAL_64(literal_base * 2, x[4]);
13449
13450 TEARDOWN();
13451}
13452
13453
13454TEST(push_pop_xreg_mixed_methods_64) {
13455 for (int claim = 0; claim <= 8; claim++) {
13456 PushPopXRegMixedMethodsHelper(claim, kXRegSize);
13457 }
13458}
13459
13460
13461TEST(push_pop_xreg_mixed_methods_32) {
13462 for (int claim = 0; claim <= 8; claim++) {
13463 PushPopXRegMixedMethodsHelper(claim, kWRegSize);
13464 }
13465}
13466
13467
13468// Push and pop data using overlapping X- and W-sized quantities.
13469static void PushPopXRegWXOverlapHelper(int reg_count, int claim) {
13470 SETUP();
13471
13472 // Arbitrarily pick a register to use as a stack pointer.
13473 const Register& stack_pointer = x10;
13474 const RegList allowed = ~stack_pointer.Bit();
13475 if (reg_count == kPushPopXRegMaxRegCount) {
13476 reg_count = CountSetBits(allowed, kNumberOfRegisters);
13477 }
13478 // Work out which registers to use, based on reg_size.
13479 Register w[kNumberOfRegisters];
13480 Register x[kNumberOfRegisters];
13481 RegList list = PopulateRegisterArray(w, x, NULL, 0, reg_count, allowed);
13482
13483 // The number of W-sized slots we expect to pop. When we pop, we alternate
13484 // between W and X registers, so we need reg_count*1.5 W-sized slots.
13485 int const requested_w_slots = reg_count + reg_count / 2;
13486
13487 // Track what _should_ be on the stack, using W-sized slots.
13488 static int const kMaxWSlots = kNumberOfRegisters + kNumberOfRegisters / 2;
13489 uint32_t stack[kMaxWSlots];
13490 for (int i = 0; i < kMaxWSlots; i++) {
13491 stack[i] = 0xdeadbeef;
13492 }
13493
armvixl6e2c8272015-03-31 11:04:14 +010013494 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13495 UseScratchRegisterScope temps(&masm);
13496 temps.ExcludeAll();
13497
armvixlad96eda2013-06-14 11:42:37 +010013498 // The literal base is chosen to have two useful properties:
13499 // * When multiplied by small values (such as a register index), this value
13500 // is clearly readable in the result.
13501 // * The value is not formed from repeating fixed-size smaller values, so it
13502 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000013503 static uint64_t const literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013504 static uint64_t const literal_base_hi = literal_base >> 32;
13505 static uint64_t const literal_base_lo = literal_base & 0xffffffff;
13506 static uint64_t const literal_base_w = literal_base & 0xffffffff;
13507
13508 START();
13509 {
armvixlb0c8ae22014-03-21 14:03:59 +000013510 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013511 __ Mov(stack_pointer, __ StackPointer());
13512 __ SetStackPointer(stack_pointer);
13513
13514 // Initialize the registers.
13515 for (int i = 0; i < reg_count; i++) {
13516 // Always write into the X register, to ensure that the upper word is
13517 // properly ignored by Push when testing W registers.
13518 __ Mov(x[i], literal_base * i);
13519 }
13520
13521 // Claim memory first, as requested.
13522 __ Claim(claim);
13523
13524 // The push-pop pattern is as follows:
13525 // Push: Pop:
13526 // x[0](hi) -> w[0]
13527 // x[0](lo) -> x[1](hi)
13528 // w[1] -> x[1](lo)
13529 // w[1] -> w[2]
13530 // x[2](hi) -> x[2](hi)
13531 // x[2](lo) -> x[2](lo)
13532 // x[2](hi) -> w[3]
13533 // x[2](lo) -> x[4](hi)
13534 // x[2](hi) -> x[4](lo)
13535 // x[2](lo) -> w[5]
13536 // w[3] -> x[5](hi)
13537 // w[3] -> x[6](lo)
13538 // w[3] -> w[7]
13539 // w[3] -> x[8](hi)
13540 // x[4](hi) -> x[8](lo)
13541 // x[4](lo) -> w[9]
13542 // ... pattern continues ...
13543 //
13544 // That is, registers are pushed starting with the lower numbers,
13545 // alternating between x and w registers, and pushing i%4+1 copies of each,
13546 // where i is the register number.
13547 // Registers are popped starting with the higher numbers one-by-one,
13548 // alternating between x and w registers, but only popping one at a time.
13549 //
13550 // This pattern provides a wide variety of alignment effects and overlaps.
13551
13552 // ---- Push ----
13553
13554 int active_w_slots = 0;
13555 for (int i = 0; active_w_slots < requested_w_slots; i++) {
armvixlb0c8ae22014-03-21 14:03:59 +000013556 VIXL_ASSERT(i < reg_count);
armvixlad96eda2013-06-14 11:42:37 +010013557 // In order to test various arguments to PushMultipleTimes, and to try to
13558 // exercise different alignment and overlap effects, we push each
13559 // register a different number of times.
13560 int times = i % 4 + 1;
13561 if (i & 1) {
13562 // Push odd-numbered registers as W registers.
13563 __ PushMultipleTimes(times, w[i]);
13564 // Fill in the expected stack slots.
13565 for (int j = 0; j < times; j++) {
13566 if (w[i].Is(wzr)) {
13567 // The zero register always writes zeroes.
13568 stack[active_w_slots++] = 0;
13569 } else {
13570 stack[active_w_slots++] = literal_base_w * i;
13571 }
13572 }
13573 } else {
13574 // Push even-numbered registers as X registers.
13575 __ PushMultipleTimes(times, x[i]);
13576 // Fill in the expected stack slots.
13577 for (int j = 0; j < times; j++) {
13578 if (x[i].Is(xzr)) {
13579 // The zero register always writes zeroes.
13580 stack[active_w_slots++] = 0;
13581 stack[active_w_slots++] = 0;
13582 } else {
13583 stack[active_w_slots++] = literal_base_hi * i;
13584 stack[active_w_slots++] = literal_base_lo * i;
13585 }
13586 }
13587 }
13588 }
13589 // Because we were pushing several registers at a time, we probably pushed
13590 // more than we needed to.
13591 if (active_w_slots > requested_w_slots) {
13592 __ Drop((active_w_slots - requested_w_slots) * kWRegSizeInBytes);
13593 // Bump the number of active W-sized slots back to where it should be,
13594 // and fill the empty space with a dummy value.
13595 do {
13596 stack[active_w_slots--] = 0xdeadbeef;
13597 } while (active_w_slots > requested_w_slots);
13598 }
13599
13600 // ---- Pop ----
13601
13602 Clobber(&masm, list);
13603
13604 // If popping an even number of registers, the first one will be X-sized.
13605 // Otherwise, the first one will be W-sized.
13606 bool next_is_64 = !(reg_count & 1);
13607 for (int i = reg_count-1; i >= 0; i--) {
13608 if (next_is_64) {
13609 __ Pop(x[i]);
13610 active_w_slots -= 2;
13611 } else {
13612 __ Pop(w[i]);
13613 active_w_slots -= 1;
13614 }
13615 next_is_64 = !next_is_64;
13616 }
armvixlb0c8ae22014-03-21 14:03:59 +000013617 VIXL_ASSERT(active_w_slots == 0);
armvixlad96eda2013-06-14 11:42:37 +010013618
13619 // Drop memory to restore stack_pointer.
13620 __ Drop(claim);
13621
13622 __ Mov(sp, __ StackPointer());
13623 __ SetStackPointer(sp);
13624 }
13625
13626 END();
13627
13628 RUN();
13629
13630 int slot = 0;
13631 for (int i = 0; i < reg_count; i++) {
13632 // Even-numbered registers were written as W registers.
13633 // Odd-numbered registers were written as X registers.
13634 bool expect_64 = (i & 1);
13635 uint64_t expected;
13636
13637 if (expect_64) {
13638 uint64_t hi = stack[slot++];
13639 uint64_t lo = stack[slot++];
13640 expected = (hi << 32) | lo;
13641 } else {
13642 expected = stack[slot++];
13643 }
13644
13645 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can
13646 // test that the upper word was properly cleared by Pop.
13647 if (x[i].Is(xzr)) {
13648 ASSERT_EQUAL_64(0, x[i]);
13649 } else {
13650 ASSERT_EQUAL_64(expected, x[i]);
13651 }
13652 }
armvixlb0c8ae22014-03-21 14:03:59 +000013653 VIXL_ASSERT(slot == requested_w_slots);
armvixlad96eda2013-06-14 11:42:37 +010013654
13655 TEARDOWN();
13656}
13657
13658
13659TEST(push_pop_xreg_wx_overlap) {
13660 for (int claim = 0; claim <= 8; claim++) {
13661 for (int count = 1; count <= 8; count++) {
13662 PushPopXRegWXOverlapHelper(count, claim);
13663 }
13664 // Test with the maximum number of registers.
13665 PushPopXRegWXOverlapHelper(kPushPopXRegMaxRegCount, claim);
13666 }
13667}
13668
13669
13670TEST(push_pop_sp) {
13671 SETUP();
13672
13673 START();
13674
armvixlb0c8ae22014-03-21 14:03:59 +000013675 VIXL_ASSERT(sp.Is(__ StackPointer()));
armvixlad96eda2013-06-14 11:42:37 +010013676
armvixl6e2c8272015-03-31 11:04:14 +010013677 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13678 UseScratchRegisterScope temps(&masm);
13679 temps.ExcludeAll();
13680
armvixlb0c8ae22014-03-21 14:03:59 +000013681 __ Mov(x3, 0x3333333333333333);
13682 __ Mov(x2, 0x2222222222222222);
13683 __ Mov(x1, 0x1111111111111111);
13684 __ Mov(x0, 0x0000000000000000);
armvixlad96eda2013-06-14 11:42:37 +010013685 __ Claim(2 * kXRegSizeInBytes);
13686 __ PushXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
13687 __ Push(x3, x2);
13688 __ PopXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
13689 __ Push(x2, x1, x3, x0);
13690 __ Pop(x4, x5);
13691 __ Pop(x6, x7, x8, x9);
13692
13693 __ Claim(2 * kXRegSizeInBytes);
13694 __ PushWRegList(w0.Bit() | w1.Bit() | w2.Bit() | w3.Bit());
13695 __ Push(w3, w1, w2, w0);
13696 __ PopWRegList(w10.Bit() | w11.Bit() | w12.Bit() | w13.Bit());
13697 __ Pop(w14, w15, w16, w17);
13698
13699 __ Claim(2 * kXRegSizeInBytes);
13700 __ Push(w2, w2, w1, w1);
13701 __ Push(x3, x3);
13702 __ Pop(w18, w19, w20, w21);
13703 __ Pop(x22, x23);
13704
13705 __ Claim(2 * kXRegSizeInBytes);
13706 __ PushXRegList(x1.Bit() | x22.Bit());
13707 __ PopXRegList(x24.Bit() | x26.Bit());
13708
13709 __ Claim(2 * kXRegSizeInBytes);
13710 __ PushWRegList(w1.Bit() | w2.Bit() | w4.Bit() | w22.Bit());
13711 __ PopWRegList(w25.Bit() | w27.Bit() | w28.Bit() | w29.Bit());
13712
13713 __ Claim(2 * kXRegSizeInBytes);
13714 __ PushXRegList(0);
13715 __ PopXRegList(0);
13716 __ PushXRegList(0xffffffff);
13717 __ PopXRegList(0xffffffff);
13718 __ Drop(12 * kXRegSizeInBytes);
13719 END();
13720
13721 RUN();
13722
armvixlb0c8ae22014-03-21 14:03:59 +000013723 ASSERT_EQUAL_64(0x1111111111111111, x3);
13724 ASSERT_EQUAL_64(0x0000000000000000, x2);
13725 ASSERT_EQUAL_64(0x3333333333333333, x1);
13726 ASSERT_EQUAL_64(0x2222222222222222, x0);
13727 ASSERT_EQUAL_64(0x3333333333333333, x9);
13728 ASSERT_EQUAL_64(0x2222222222222222, x8);
13729 ASSERT_EQUAL_64(0x0000000000000000, x7);
13730 ASSERT_EQUAL_64(0x3333333333333333, x6);
13731 ASSERT_EQUAL_64(0x1111111111111111, x5);
13732 ASSERT_EQUAL_64(0x2222222222222222, x4);
armvixlad96eda2013-06-14 11:42:37 +010013733
13734 ASSERT_EQUAL_32(0x11111111U, w13);
13735 ASSERT_EQUAL_32(0x33333333U, w12);
13736 ASSERT_EQUAL_32(0x00000000U, w11);
13737 ASSERT_EQUAL_32(0x22222222U, w10);
13738 ASSERT_EQUAL_32(0x11111111U, w17);
13739 ASSERT_EQUAL_32(0x00000000U, w16);
13740 ASSERT_EQUAL_32(0x33333333U, w15);
13741 ASSERT_EQUAL_32(0x22222222U, w14);
13742
13743 ASSERT_EQUAL_32(0x11111111U, w18);
13744 ASSERT_EQUAL_32(0x11111111U, w19);
13745 ASSERT_EQUAL_32(0x11111111U, w20);
13746 ASSERT_EQUAL_32(0x11111111U, w21);
armvixlb0c8ae22014-03-21 14:03:59 +000013747 ASSERT_EQUAL_64(0x3333333333333333, x22);
13748 ASSERT_EQUAL_64(0x0000000000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010013749
armvixlb0c8ae22014-03-21 14:03:59 +000013750 ASSERT_EQUAL_64(0x3333333333333333, x24);
13751 ASSERT_EQUAL_64(0x3333333333333333, x26);
armvixlad96eda2013-06-14 11:42:37 +010013752
13753 ASSERT_EQUAL_32(0x33333333U, w25);
13754 ASSERT_EQUAL_32(0x00000000U, w27);
13755 ASSERT_EQUAL_32(0x22222222U, w28);
13756 ASSERT_EQUAL_32(0x33333333U, w29);
13757 TEARDOWN();
13758}
13759
13760
13761TEST(noreg) {
13762 // This test doesn't generate any code, but it verifies some invariants
13763 // related to NoReg.
armvixlb0c8ae22014-03-21 14:03:59 +000013764 VIXL_CHECK(NoReg.Is(NoFPReg));
13765 VIXL_CHECK(NoFPReg.Is(NoReg));
armvixl5289c592015-03-02 13:52:04 +000013766
13767 VIXL_CHECK(NoVReg.Is(NoReg));
13768 VIXL_CHECK(NoReg.Is(NoVReg));
13769
armvixlb0c8ae22014-03-21 14:03:59 +000013770 VIXL_CHECK(NoReg.Is(NoCPUReg));
13771 VIXL_CHECK(NoCPUReg.Is(NoReg));
armvixl5289c592015-03-02 13:52:04 +000013772
armvixlb0c8ae22014-03-21 14:03:59 +000013773 VIXL_CHECK(NoFPReg.Is(NoCPUReg));
13774 VIXL_CHECK(NoCPUReg.Is(NoFPReg));
armvixlad96eda2013-06-14 11:42:37 +010013775
armvixl5289c592015-03-02 13:52:04 +000013776 VIXL_CHECK(NoVReg.Is(NoCPUReg));
13777 VIXL_CHECK(NoCPUReg.Is(NoVReg));
13778
armvixlb0c8ae22014-03-21 14:03:59 +000013779 VIXL_CHECK(NoReg.IsNone());
13780 VIXL_CHECK(NoFPReg.IsNone());
armvixl5289c592015-03-02 13:52:04 +000013781 VIXL_CHECK(NoVReg.IsNone());
armvixlb0c8ae22014-03-21 14:03:59 +000013782 VIXL_CHECK(NoCPUReg.IsNone());
armvixlad96eda2013-06-14 11:42:37 +010013783}
13784
13785
13786TEST(isvalid) {
13787 // This test doesn't generate any code, but it verifies some invariants
13788 // related to IsValid().
armvixlb0c8ae22014-03-21 14:03:59 +000013789 VIXL_CHECK(!NoReg.IsValid());
13790 VIXL_CHECK(!NoFPReg.IsValid());
armvixl5289c592015-03-02 13:52:04 +000013791 VIXL_CHECK(!NoVReg.IsValid());
armvixlb0c8ae22014-03-21 14:03:59 +000013792 VIXL_CHECK(!NoCPUReg.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013793
armvixlb0c8ae22014-03-21 14:03:59 +000013794 VIXL_CHECK(x0.IsValid());
13795 VIXL_CHECK(w0.IsValid());
13796 VIXL_CHECK(x30.IsValid());
13797 VIXL_CHECK(w30.IsValid());
13798 VIXL_CHECK(xzr.IsValid());
13799 VIXL_CHECK(wzr.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013800
armvixlb0c8ae22014-03-21 14:03:59 +000013801 VIXL_CHECK(sp.IsValid());
13802 VIXL_CHECK(wsp.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013803
armvixlb0c8ae22014-03-21 14:03:59 +000013804 VIXL_CHECK(d0.IsValid());
13805 VIXL_CHECK(s0.IsValid());
13806 VIXL_CHECK(d31.IsValid());
13807 VIXL_CHECK(s31.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013808
armvixlb0c8ae22014-03-21 14:03:59 +000013809 VIXL_CHECK(x0.IsValidRegister());
13810 VIXL_CHECK(w0.IsValidRegister());
13811 VIXL_CHECK(xzr.IsValidRegister());
13812 VIXL_CHECK(wzr.IsValidRegister());
13813 VIXL_CHECK(sp.IsValidRegister());
13814 VIXL_CHECK(wsp.IsValidRegister());
13815 VIXL_CHECK(!x0.IsValidFPRegister());
13816 VIXL_CHECK(!w0.IsValidFPRegister());
13817 VIXL_CHECK(!xzr.IsValidFPRegister());
13818 VIXL_CHECK(!wzr.IsValidFPRegister());
13819 VIXL_CHECK(!sp.IsValidFPRegister());
13820 VIXL_CHECK(!wsp.IsValidFPRegister());
armvixlad96eda2013-06-14 11:42:37 +010013821
armvixlb0c8ae22014-03-21 14:03:59 +000013822 VIXL_CHECK(d0.IsValidFPRegister());
13823 VIXL_CHECK(s0.IsValidFPRegister());
13824 VIXL_CHECK(!d0.IsValidRegister());
13825 VIXL_CHECK(!s0.IsValidRegister());
armvixlad96eda2013-06-14 11:42:37 +010013826
13827 // Test the same as before, but using CPURegister types. This shouldn't make
13828 // any difference.
armvixlb0c8ae22014-03-21 14:03:59 +000013829 VIXL_CHECK(static_cast<CPURegister>(x0).IsValid());
13830 VIXL_CHECK(static_cast<CPURegister>(w0).IsValid());
13831 VIXL_CHECK(static_cast<CPURegister>(x30).IsValid());
13832 VIXL_CHECK(static_cast<CPURegister>(w30).IsValid());
13833 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValid());
13834 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013835
armvixlb0c8ae22014-03-21 14:03:59 +000013836 VIXL_CHECK(static_cast<CPURegister>(sp).IsValid());
13837 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013838
armvixlb0c8ae22014-03-21 14:03:59 +000013839 VIXL_CHECK(static_cast<CPURegister>(d0).IsValid());
13840 VIXL_CHECK(static_cast<CPURegister>(s0).IsValid());
13841 VIXL_CHECK(static_cast<CPURegister>(d31).IsValid());
13842 VIXL_CHECK(static_cast<CPURegister>(s31).IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013843
armvixlb0c8ae22014-03-21 14:03:59 +000013844 VIXL_CHECK(static_cast<CPURegister>(x0).IsValidRegister());
13845 VIXL_CHECK(static_cast<CPURegister>(w0).IsValidRegister());
13846 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValidRegister());
13847 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValidRegister());
13848 VIXL_CHECK(static_cast<CPURegister>(sp).IsValidRegister());
13849 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValidRegister());
13850 VIXL_CHECK(!static_cast<CPURegister>(x0).IsValidFPRegister());
13851 VIXL_CHECK(!static_cast<CPURegister>(w0).IsValidFPRegister());
13852 VIXL_CHECK(!static_cast<CPURegister>(xzr).IsValidFPRegister());
13853 VIXL_CHECK(!static_cast<CPURegister>(wzr).IsValidFPRegister());
13854 VIXL_CHECK(!static_cast<CPURegister>(sp).IsValidFPRegister());
13855 VIXL_CHECK(!static_cast<CPURegister>(wsp).IsValidFPRegister());
armvixlad96eda2013-06-14 11:42:37 +010013856
armvixlb0c8ae22014-03-21 14:03:59 +000013857 VIXL_CHECK(static_cast<CPURegister>(d0).IsValidFPRegister());
13858 VIXL_CHECK(static_cast<CPURegister>(s0).IsValidFPRegister());
13859 VIXL_CHECK(!static_cast<CPURegister>(d0).IsValidRegister());
13860 VIXL_CHECK(!static_cast<CPURegister>(s0).IsValidRegister());
armvixlad96eda2013-06-14 11:42:37 +010013861}
13862
13863
13864TEST(printf) {
armvixlc68cb642014-09-25 18:49:30 +010013865 SETUP();
armvixlad96eda2013-06-14 11:42:37 +010013866 START();
13867
13868 char const * test_plain_string = "Printf with no arguments.\n";
13869 char const * test_substring = "'This is a substring.'";
13870 RegisterDump before;
13871
13872 // Initialize x29 to the value of the stack pointer. We will use x29 as a
13873 // temporary stack pointer later, and initializing it in this way allows the
13874 // RegisterDump check to pass.
13875 __ Mov(x29, __ StackPointer());
13876
13877 // Test simple integer arguments.
13878 __ Mov(x0, 1234);
13879 __ Mov(x1, 0x1234);
13880
13881 // Test simple floating-point arguments.
13882 __ Fmov(d0, 1.234);
13883
13884 // Test pointer (string) arguments.
13885 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
13886
13887 // Test the maximum number of arguments, and sign extension.
13888 __ Mov(w3, 0xffffffff);
13889 __ Mov(w4, 0xffffffff);
13890 __ Mov(x5, 0xffffffffffffffff);
13891 __ Mov(x6, 0xffffffffffffffff);
13892 __ Fmov(s1, 1.234);
13893 __ Fmov(s2, 2.345);
13894 __ Fmov(d3, 3.456);
13895 __ Fmov(d4, 4.567);
13896
13897 // Test printing callee-saved registers.
13898 __ Mov(x28, 0x123456789abcdef);
13899 __ Fmov(d10, 42.0);
13900
13901 // Test with three arguments.
13902 __ Mov(x10, 3);
13903 __ Mov(x11, 40);
13904 __ Mov(x12, 500);
13905
armvixl5799d6c2014-05-01 11:05:00 +010013906 // A single character.
13907 __ Mov(w13, 'x');
13908
13909 // Check that we don't clobber any registers.
armvixlad96eda2013-06-14 11:42:37 +010013910 before.Dump(&masm);
13911
13912 __ Printf(test_plain_string); // NOLINT(runtime/printf)
armvixl5799d6c2014-05-01 11:05:00 +010013913 __ Printf("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1);
13914 __ Printf("w5: %" PRId32 ", x5: %" PRId64"\n", w5, x5);
armvixlad96eda2013-06-14 11:42:37 +010013915 __ Printf("d0: %f\n", d0);
13916 __ Printf("Test %%s: %s\n", x2);
13917 __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
13918 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
13919 w3, w4, x5, x6);
13920 __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
armvixl5799d6c2014-05-01 11:05:00 +010013921 __ Printf("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
armvixlad96eda2013-06-14 11:42:37 +010013922 __ Printf("%g\n", d10);
armvixl5799d6c2014-05-01 11:05:00 +010013923 __ Printf("%%%%%s%%%c%%\n", x2, w13);
13924
13925 // Print the stack pointer (sp).
13926 __ Printf("StackPointer(sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
13927 __ StackPointer(), __ StackPointer().W());
armvixlad96eda2013-06-14 11:42:37 +010013928
13929 // Test with a different stack pointer.
13930 const Register old_stack_pointer = __ StackPointer();
armvixl5799d6c2014-05-01 11:05:00 +010013931 __ Mov(x29, old_stack_pointer);
armvixlad96eda2013-06-14 11:42:37 +010013932 __ SetStackPointer(x29);
armvixl5799d6c2014-05-01 11:05:00 +010013933 // Print the stack pointer (not sp).
13934 __ Printf("StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
13935 __ StackPointer(), __ StackPointer().W());
13936 __ Mov(old_stack_pointer, __ StackPointer());
armvixlad96eda2013-06-14 11:42:37 +010013937 __ SetStackPointer(old_stack_pointer);
13938
armvixl5799d6c2014-05-01 11:05:00 +010013939 // Test with three arguments.
armvixlad96eda2013-06-14 11:42:37 +010013940 __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12);
13941
armvixl5799d6c2014-05-01 11:05:00 +010013942 // Mixed argument types.
13943 __ Printf("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
13944 w3, s1, x5, d3);
13945 __ Printf("s1: %f, d3: %f, w3: %" PRId32 ", x5: %" PRId64 "\n",
13946 s1, d3, w3, x5);
13947
armvixlad96eda2013-06-14 11:42:37 +010013948 END();
13949 RUN();
13950
13951 // We cannot easily test the output of the Printf sequences, and because
13952 // Printf preserves all registers by default, we can't look at the number of
13953 // bytes that were printed. However, the printf_no_preserve test should check
13954 // that, and here we just test that we didn't clobber any registers.
13955 ASSERT_EQUAL_REGISTERS(before);
13956
13957 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +010013958}
13959
13960
13961TEST(printf_no_preserve) {
armvixlad96eda2013-06-14 11:42:37 +010013962 SETUP();
13963 START();
13964
13965 char const * test_plain_string = "Printf with no arguments.\n";
13966 char const * test_substring = "'This is a substring.'";
13967
13968 __ PrintfNoPreserve(test_plain_string);
13969 __ Mov(x19, x0);
13970
13971 // Test simple integer arguments.
13972 __ Mov(x0, 1234);
13973 __ Mov(x1, 0x1234);
13974 __ PrintfNoPreserve("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1);
13975 __ Mov(x20, x0);
13976
13977 // Test simple floating-point arguments.
13978 __ Fmov(d0, 1.234);
13979 __ PrintfNoPreserve("d0: %f\n", d0);
13980 __ Mov(x21, x0);
13981
13982 // Test pointer (string) arguments.
13983 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
13984 __ PrintfNoPreserve("Test %%s: %s\n", x2);
13985 __ Mov(x22, x0);
13986
13987 // Test the maximum number of arguments, and sign extension.
13988 __ Mov(w3, 0xffffffff);
13989 __ Mov(w4, 0xffffffff);
13990 __ Mov(x5, 0xffffffffffffffff);
13991 __ Mov(x6, 0xffffffffffffffff);
13992 __ PrintfNoPreserve("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
13993 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
13994 w3, w4, x5, x6);
13995 __ Mov(x23, x0);
13996
13997 __ Fmov(s1, 1.234);
13998 __ Fmov(s2, 2.345);
13999 __ Fmov(d3, 3.456);
14000 __ Fmov(d4, 4.567);
14001 __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
14002 __ Mov(x24, x0);
14003
14004 // Test printing callee-saved registers.
14005 __ Mov(x28, 0x123456789abcdef);
armvixl5799d6c2014-05-01 11:05:00 +010014006 __ PrintfNoPreserve("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
armvixlad96eda2013-06-14 11:42:37 +010014007 __ Mov(x25, x0);
14008
14009 __ Fmov(d10, 42.0);
14010 __ PrintfNoPreserve("%g\n", d10);
14011 __ Mov(x26, x0);
14012
14013 // Test with a different stack pointer.
14014 const Register old_stack_pointer = __ StackPointer();
14015 __ Mov(x29, old_stack_pointer);
14016 __ SetStackPointer(x29);
armvixl5799d6c2014-05-01 11:05:00 +010014017 // Print the stack pointer (not sp).
14018 __ PrintfNoPreserve(
14019 "StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
14020 __ StackPointer(), __ StackPointer().W());
armvixlad96eda2013-06-14 11:42:37 +010014021 __ Mov(x27, x0);
armvixlad96eda2013-06-14 11:42:37 +010014022 __ Mov(old_stack_pointer, __ StackPointer());
14023 __ SetStackPointer(old_stack_pointer);
14024
14025 // Test with three arguments.
14026 __ Mov(x3, 3);
14027 __ Mov(x4, 40);
14028 __ Mov(x5, 500);
14029 __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5);
14030 __ Mov(x28, x0);
14031
armvixl5799d6c2014-05-01 11:05:00 +010014032 // Mixed argument types.
14033 __ Mov(w3, 0xffffffff);
14034 __ Fmov(s1, 1.234);
14035 __ Mov(x5, 0xffffffffffffffff);
14036 __ Fmov(d3, 3.456);
14037 __ PrintfNoPreserve("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
14038 w3, s1, x5, d3);
14039 __ Mov(x29, x0);
14040
armvixlad96eda2013-06-14 11:42:37 +010014041 END();
14042 RUN();
14043
14044 // We cannot easily test the exact output of the Printf sequences, but we can
14045 // use the return code to check that the string length was correct.
14046
14047 // Printf with no arguments.
14048 ASSERT_EQUAL_64(strlen(test_plain_string), x19);
14049 // x0: 1234, x1: 0x00001234
14050 ASSERT_EQUAL_64(25, x20);
14051 // d0: 1.234000
14052 ASSERT_EQUAL_64(13, x21);
14053 // Test %s: 'This is a substring.'
14054 ASSERT_EQUAL_64(32, x22);
14055 // w3(uint32): 4294967295
14056 // w4(int32): -1
14057 // x5(uint64): 18446744073709551615
14058 // x6(int64): -1
14059 ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23);
14060 // %f: 1.234000
14061 // %g: 2.345
14062 // %e: 3.456000e+00
14063 // %E: 4.567000E+00
14064 ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24);
armvixl5799d6c2014-05-01 11:05:00 +010014065 // 0x89abcdef, 0x123456789abcdef
14066 ASSERT_EQUAL_64(30, x25);
armvixlad96eda2013-06-14 11:42:37 +010014067 // 42
14068 ASSERT_EQUAL_64(3, x26);
armvixl5799d6c2014-05-01 11:05:00 +010014069 // StackPointer(not sp): 0x00007fb037ae2370, 0x37ae2370
armvixlad96eda2013-06-14 11:42:37 +010014070 // Note: This is an example value, but the field width is fixed here so the
14071 // string length is still predictable.
armvixl5799d6c2014-05-01 11:05:00 +010014072 ASSERT_EQUAL_64(53, x27);
armvixlad96eda2013-06-14 11:42:37 +010014073 // 3=3, 4=40, 5=500
14074 ASSERT_EQUAL_64(17, x28);
armvixl5799d6c2014-05-01 11:05:00 +010014075 // w3: 4294967295, s1: 1.234000, x5: 18446744073709551615, d3: 3.456000
14076 ASSERT_EQUAL_64(69, x29);
armvixlad96eda2013-06-14 11:42:37 +010014077
14078 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +010014079}
14080
14081
14082#ifndef USE_SIMULATOR
14083TEST(trace) {
14084 // The Trace helper should not generate any code unless the simulator (or
14085 // debugger) is being used.
14086 SETUP();
14087 START();
14088
14089 Label start;
14090 __ Bind(&start);
14091 __ Trace(LOG_ALL, TRACE_ENABLE);
14092 __ Trace(LOG_ALL, TRACE_DISABLE);
armvixlb0c8ae22014-03-21 14:03:59 +000014093 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlad96eda2013-06-14 11:42:37 +010014094
14095 END();
14096 TEARDOWN();
14097}
14098#endif
14099
14100
14101#ifndef USE_SIMULATOR
14102TEST(log) {
14103 // The Log helper should not generate any code unless the simulator (or
14104 // debugger) is being used.
14105 SETUP();
14106 START();
14107
14108 Label start;
14109 __ Bind(&start);
14110 __ Log(LOG_ALL);
armvixlb0c8ae22014-03-21 14:03:59 +000014111 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlad96eda2013-06-14 11:42:37 +010014112
14113 END();
14114 TEARDOWN();
14115}
14116#endif
14117
14118
14119TEST(instruction_accurate_scope) {
14120 SETUP();
14121 START();
14122
14123 // By default macro instructions are allowed.
armvixlb0c8ae22014-03-21 14:03:59 +000014124 VIXL_ASSERT(masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +010014125 {
armvixlc68cb642014-09-25 18:49:30 +010014126 InstructionAccurateScope scope1(&masm, 2);
armvixlb0c8ae22014-03-21 14:03:59 +000014127 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlc68cb642014-09-25 18:49:30 +010014128 __ nop();
armvixlad96eda2013-06-14 11:42:37 +010014129 {
armvixlc68cb642014-09-25 18:49:30 +010014130 InstructionAccurateScope scope2(&masm, 1);
armvixlb0c8ae22014-03-21 14:03:59 +000014131 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlc68cb642014-09-25 18:49:30 +010014132 __ nop();
armvixlad96eda2013-06-14 11:42:37 +010014133 }
armvixlb0c8ae22014-03-21 14:03:59 +000014134 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +010014135 }
armvixlb0c8ae22014-03-21 14:03:59 +000014136 VIXL_ASSERT(masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +010014137
14138 {
14139 InstructionAccurateScope scope(&masm, 2);
14140 __ add(x0, x0, x0);
14141 __ sub(x0, x0, x0);
14142 }
14143
14144 END();
14145 RUN();
14146 TEARDOWN();
14147}
14148
14149
14150TEST(blr_lr) {
14151 // A simple test to check that the simulator correcty handle "blr lr".
14152 SETUP();
14153
14154 START();
14155 Label target;
14156 Label end;
14157
14158 __ Mov(x0, 0x0);
14159 __ Adr(lr, &target);
14160
14161 __ Blr(lr);
14162 __ Mov(x0, 0xdeadbeef);
14163 __ B(&end);
14164
14165 __ Bind(&target);
14166 __ Mov(x0, 0xc001c0de);
14167
14168 __ Bind(&end);
14169 END();
14170
14171 RUN();
14172
14173 ASSERT_EQUAL_64(0xc001c0de, x0);
14174
14175 TEARDOWN();
14176}
14177
armvixlf37fdc02014-02-05 13:22:16 +000014178
14179TEST(barriers) {
14180 // Generate all supported barriers, this is just a smoke test
14181 SETUP();
14182
14183 START();
14184
14185 // DMB
14186 __ Dmb(FullSystem, BarrierAll);
14187 __ Dmb(FullSystem, BarrierReads);
14188 __ Dmb(FullSystem, BarrierWrites);
14189 __ Dmb(FullSystem, BarrierOther);
14190
14191 __ Dmb(InnerShareable, BarrierAll);
14192 __ Dmb(InnerShareable, BarrierReads);
14193 __ Dmb(InnerShareable, BarrierWrites);
14194 __ Dmb(InnerShareable, BarrierOther);
14195
14196 __ Dmb(NonShareable, BarrierAll);
14197 __ Dmb(NonShareable, BarrierReads);
14198 __ Dmb(NonShareable, BarrierWrites);
14199 __ Dmb(NonShareable, BarrierOther);
14200
14201 __ Dmb(OuterShareable, BarrierAll);
14202 __ Dmb(OuterShareable, BarrierReads);
14203 __ Dmb(OuterShareable, BarrierWrites);
14204 __ Dmb(OuterShareable, BarrierOther);
14205
14206 // DSB
14207 __ Dsb(FullSystem, BarrierAll);
14208 __ Dsb(FullSystem, BarrierReads);
14209 __ Dsb(FullSystem, BarrierWrites);
14210 __ Dsb(FullSystem, BarrierOther);
14211
14212 __ Dsb(InnerShareable, BarrierAll);
14213 __ Dsb(InnerShareable, BarrierReads);
14214 __ Dsb(InnerShareable, BarrierWrites);
14215 __ Dsb(InnerShareable, BarrierOther);
14216
14217 __ Dsb(NonShareable, BarrierAll);
14218 __ Dsb(NonShareable, BarrierReads);
14219 __ Dsb(NonShareable, BarrierWrites);
14220 __ Dsb(NonShareable, BarrierOther);
14221
14222 __ Dsb(OuterShareable, BarrierAll);
14223 __ Dsb(OuterShareable, BarrierReads);
14224 __ Dsb(OuterShareable, BarrierWrites);
14225 __ Dsb(OuterShareable, BarrierOther);
14226
14227 // ISB
14228 __ Isb();
14229
14230 END();
14231
14232 RUN();
14233
14234 TEARDOWN();
14235}
14236
armvixlb0c8ae22014-03-21 14:03:59 +000014237
14238TEST(process_nan_double) {
14239 // Make sure that NaN propagation works correctly.
14240 double sn = rawbits_to_double(0x7ff5555511111111);
14241 double qn = rawbits_to_double(0x7ffaaaaa11111111);
14242 VIXL_ASSERT(IsSignallingNaN(sn));
14243 VIXL_ASSERT(IsQuietNaN(qn));
14244
14245 // The input NaNs after passing through ProcessNaN.
14246 double sn_proc = rawbits_to_double(0x7ffd555511111111);
14247 double qn_proc = qn;
14248 VIXL_ASSERT(IsQuietNaN(sn_proc));
14249 VIXL_ASSERT(IsQuietNaN(qn_proc));
14250
14251 SETUP();
14252 START();
14253
14254 // Execute a number of instructions which all use ProcessNaN, and check that
14255 // they all handle the NaN correctly.
14256 __ Fmov(d0, sn);
14257 __ Fmov(d10, qn);
14258
14259 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14260 // - Signalling NaN
14261 __ Fmov(d1, d0);
14262 __ Fabs(d2, d0);
14263 __ Fneg(d3, d0);
14264 // - Quiet NaN
14265 __ Fmov(d11, d10);
14266 __ Fabs(d12, d10);
14267 __ Fneg(d13, d10);
14268
14269 // Operations that use ProcessNaN.
14270 // - Signalling NaN
14271 __ Fsqrt(d4, d0);
14272 __ Frinta(d5, d0);
14273 __ Frintn(d6, d0);
14274 __ Frintz(d7, d0);
14275 // - Quiet NaN
14276 __ Fsqrt(d14, d10);
14277 __ Frinta(d15, d10);
14278 __ Frintn(d16, d10);
14279 __ Frintz(d17, d10);
14280
14281 // The behaviour of fcvt is checked in TEST(fcvt_sd).
14282
14283 END();
14284 RUN();
14285
14286 uint64_t qn_raw = double_to_rawbits(qn);
14287 uint64_t sn_raw = double_to_rawbits(sn);
14288
14289 // - Signalling NaN
14290 ASSERT_EQUAL_FP64(sn, d1);
14291 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw & ~kDSignMask), d2);
14292 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw ^ kDSignMask), d3);
14293 // - Quiet NaN
14294 ASSERT_EQUAL_FP64(qn, d11);
14295 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw & ~kDSignMask), d12);
14296 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw ^ kDSignMask), d13);
14297
14298 // - Signalling NaN
14299 ASSERT_EQUAL_FP64(sn_proc, d4);
14300 ASSERT_EQUAL_FP64(sn_proc, d5);
14301 ASSERT_EQUAL_FP64(sn_proc, d6);
14302 ASSERT_EQUAL_FP64(sn_proc, d7);
14303 // - Quiet NaN
14304 ASSERT_EQUAL_FP64(qn_proc, d14);
14305 ASSERT_EQUAL_FP64(qn_proc, d15);
14306 ASSERT_EQUAL_FP64(qn_proc, d16);
14307 ASSERT_EQUAL_FP64(qn_proc, d17);
14308
14309 TEARDOWN();
14310}
14311
14312
14313TEST(process_nan_float) {
14314 // Make sure that NaN propagation works correctly.
14315 float sn = rawbits_to_float(0x7f951111);
14316 float qn = rawbits_to_float(0x7fea1111);
14317 VIXL_ASSERT(IsSignallingNaN(sn));
14318 VIXL_ASSERT(IsQuietNaN(qn));
14319
14320 // The input NaNs after passing through ProcessNaN.
14321 float sn_proc = rawbits_to_float(0x7fd51111);
14322 float qn_proc = qn;
14323 VIXL_ASSERT(IsQuietNaN(sn_proc));
14324 VIXL_ASSERT(IsQuietNaN(qn_proc));
14325
14326 SETUP();
14327 START();
14328
14329 // Execute a number of instructions which all use ProcessNaN, and check that
14330 // they all handle the NaN correctly.
14331 __ Fmov(s0, sn);
14332 __ Fmov(s10, qn);
14333
14334 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14335 // - Signalling NaN
14336 __ Fmov(s1, s0);
14337 __ Fabs(s2, s0);
14338 __ Fneg(s3, s0);
14339 // - Quiet NaN
14340 __ Fmov(s11, s10);
14341 __ Fabs(s12, s10);
14342 __ Fneg(s13, s10);
14343
14344 // Operations that use ProcessNaN.
14345 // - Signalling NaN
14346 __ Fsqrt(s4, s0);
14347 __ Frinta(s5, s0);
14348 __ Frintn(s6, s0);
14349 __ Frintz(s7, s0);
14350 // - Quiet NaN
14351 __ Fsqrt(s14, s10);
14352 __ Frinta(s15, s10);
14353 __ Frintn(s16, s10);
14354 __ Frintz(s17, s10);
14355
14356 // The behaviour of fcvt is checked in TEST(fcvt_sd).
14357
14358 END();
14359 RUN();
14360
14361 uint32_t qn_raw = float_to_rawbits(qn);
14362 uint32_t sn_raw = float_to_rawbits(sn);
14363
14364 // - Signalling NaN
14365 ASSERT_EQUAL_FP32(sn, s1);
14366 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw & ~kSSignMask), s2);
14367 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw ^ kSSignMask), s3);
14368 // - Quiet NaN
14369 ASSERT_EQUAL_FP32(qn, s11);
14370 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw & ~kSSignMask), s12);
14371 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw ^ kSSignMask), s13);
14372
14373 // - Signalling NaN
14374 ASSERT_EQUAL_FP32(sn_proc, s4);
14375 ASSERT_EQUAL_FP32(sn_proc, s5);
14376 ASSERT_EQUAL_FP32(sn_proc, s6);
14377 ASSERT_EQUAL_FP32(sn_proc, s7);
14378 // - Quiet NaN
14379 ASSERT_EQUAL_FP32(qn_proc, s14);
14380 ASSERT_EQUAL_FP32(qn_proc, s15);
14381 ASSERT_EQUAL_FP32(qn_proc, s16);
14382 ASSERT_EQUAL_FP32(qn_proc, s17);
14383
14384 TEARDOWN();
14385}
14386
14387
14388static void ProcessNaNsHelper(double n, double m, double expected) {
armvixl6e2c8272015-03-31 11:04:14 +010014389 VIXL_ASSERT(std::isnan(n) || std::isnan(m));
14390 VIXL_ASSERT(std::isnan(expected));
armvixlb0c8ae22014-03-21 14:03:59 +000014391
14392 SETUP();
14393 START();
14394
14395 // Execute a number of instructions which all use ProcessNaNs, and check that
14396 // they all propagate NaNs correctly.
14397 __ Fmov(d0, n);
14398 __ Fmov(d1, m);
14399
14400 __ Fadd(d2, d0, d1);
14401 __ Fsub(d3, d0, d1);
14402 __ Fmul(d4, d0, d1);
14403 __ Fdiv(d5, d0, d1);
14404 __ Fmax(d6, d0, d1);
14405 __ Fmin(d7, d0, d1);
14406
14407 END();
14408 RUN();
14409
14410 ASSERT_EQUAL_FP64(expected, d2);
14411 ASSERT_EQUAL_FP64(expected, d3);
14412 ASSERT_EQUAL_FP64(expected, d4);
14413 ASSERT_EQUAL_FP64(expected, d5);
14414 ASSERT_EQUAL_FP64(expected, d6);
14415 ASSERT_EQUAL_FP64(expected, d7);
14416
14417 TEARDOWN();
14418}
14419
14420
14421TEST(process_nans_double) {
14422 // Make sure that NaN propagation works correctly.
14423 double sn = rawbits_to_double(0x7ff5555511111111);
14424 double sm = rawbits_to_double(0x7ff5555522222222);
14425 double qn = rawbits_to_double(0x7ffaaaaa11111111);
14426 double qm = rawbits_to_double(0x7ffaaaaa22222222);
14427 VIXL_ASSERT(IsSignallingNaN(sn));
14428 VIXL_ASSERT(IsSignallingNaN(sm));
14429 VIXL_ASSERT(IsQuietNaN(qn));
14430 VIXL_ASSERT(IsQuietNaN(qm));
14431
14432 // The input NaNs after passing through ProcessNaN.
14433 double sn_proc = rawbits_to_double(0x7ffd555511111111);
14434 double sm_proc = rawbits_to_double(0x7ffd555522222222);
14435 double qn_proc = qn;
14436 double qm_proc = qm;
14437 VIXL_ASSERT(IsQuietNaN(sn_proc));
14438 VIXL_ASSERT(IsQuietNaN(sm_proc));
14439 VIXL_ASSERT(IsQuietNaN(qn_proc));
14440 VIXL_ASSERT(IsQuietNaN(qm_proc));
14441
14442 // Quiet NaNs are propagated.
14443 ProcessNaNsHelper(qn, 0, qn_proc);
14444 ProcessNaNsHelper(0, qm, qm_proc);
14445 ProcessNaNsHelper(qn, qm, qn_proc);
14446
14447 // Signalling NaNs are propagated, and made quiet.
14448 ProcessNaNsHelper(sn, 0, sn_proc);
14449 ProcessNaNsHelper(0, sm, sm_proc);
14450 ProcessNaNsHelper(sn, sm, sn_proc);
14451
14452 // Signalling NaNs take precedence over quiet NaNs.
14453 ProcessNaNsHelper(sn, qm, sn_proc);
14454 ProcessNaNsHelper(qn, sm, sm_proc);
14455 ProcessNaNsHelper(sn, sm, sn_proc);
14456}
14457
14458
14459static void ProcessNaNsHelper(float n, float m, float expected) {
armvixl6e2c8272015-03-31 11:04:14 +010014460 VIXL_ASSERT(std::isnan(n) || std::isnan(m));
14461 VIXL_ASSERT(std::isnan(expected));
armvixlb0c8ae22014-03-21 14:03:59 +000014462
14463 SETUP();
14464 START();
14465
14466 // Execute a number of instructions which all use ProcessNaNs, and check that
14467 // they all propagate NaNs correctly.
14468 __ Fmov(s0, n);
14469 __ Fmov(s1, m);
14470
14471 __ Fadd(s2, s0, s1);
14472 __ Fsub(s3, s0, s1);
14473 __ Fmul(s4, s0, s1);
14474 __ Fdiv(s5, s0, s1);
14475 __ Fmax(s6, s0, s1);
14476 __ Fmin(s7, s0, s1);
14477
14478 END();
14479 RUN();
14480
14481 ASSERT_EQUAL_FP32(expected, s2);
14482 ASSERT_EQUAL_FP32(expected, s3);
14483 ASSERT_EQUAL_FP32(expected, s4);
14484 ASSERT_EQUAL_FP32(expected, s5);
14485 ASSERT_EQUAL_FP32(expected, s6);
14486 ASSERT_EQUAL_FP32(expected, s7);
14487
14488 TEARDOWN();
14489}
14490
14491
14492TEST(process_nans_float) {
14493 // Make sure that NaN propagation works correctly.
14494 float sn = rawbits_to_float(0x7f951111);
14495 float sm = rawbits_to_float(0x7f952222);
14496 float qn = rawbits_to_float(0x7fea1111);
14497 float qm = rawbits_to_float(0x7fea2222);
14498 VIXL_ASSERT(IsSignallingNaN(sn));
14499 VIXL_ASSERT(IsSignallingNaN(sm));
14500 VIXL_ASSERT(IsQuietNaN(qn));
14501 VIXL_ASSERT(IsQuietNaN(qm));
14502
14503 // The input NaNs after passing through ProcessNaN.
14504 float sn_proc = rawbits_to_float(0x7fd51111);
14505 float sm_proc = rawbits_to_float(0x7fd52222);
14506 float qn_proc = qn;
14507 float qm_proc = qm;
14508 VIXL_ASSERT(IsQuietNaN(sn_proc));
14509 VIXL_ASSERT(IsQuietNaN(sm_proc));
14510 VIXL_ASSERT(IsQuietNaN(qn_proc));
14511 VIXL_ASSERT(IsQuietNaN(qm_proc));
14512
14513 // Quiet NaNs are propagated.
14514 ProcessNaNsHelper(qn, 0, qn_proc);
14515 ProcessNaNsHelper(0, qm, qm_proc);
14516 ProcessNaNsHelper(qn, qm, qn_proc);
14517
14518 // Signalling NaNs are propagated, and made quiet.
14519 ProcessNaNsHelper(sn, 0, sn_proc);
14520 ProcessNaNsHelper(0, sm, sm_proc);
14521 ProcessNaNsHelper(sn, sm, sn_proc);
14522
14523 // Signalling NaNs take precedence over quiet NaNs.
14524 ProcessNaNsHelper(sn, qm, sn_proc);
14525 ProcessNaNsHelper(qn, sm, sm_proc);
14526 ProcessNaNsHelper(sn, sm, sn_proc);
14527}
14528
14529
14530static void DefaultNaNHelper(float n, float m, float a) {
armvixl6e2c8272015-03-31 11:04:14 +010014531 VIXL_ASSERT(std::isnan(n) || std::isnan(m) || std::isnan(a));
armvixlb0c8ae22014-03-21 14:03:59 +000014532
armvixl6e2c8272015-03-31 11:04:14 +010014533 bool test_1op = std::isnan(n);
14534 bool test_2op = std::isnan(n) || std::isnan(m);
armvixlb0c8ae22014-03-21 14:03:59 +000014535
14536 SETUP();
14537 START();
14538
14539 // Enable Default-NaN mode in the FPCR.
14540 __ Mrs(x0, FPCR);
14541 __ Orr(x1, x0, DN_mask);
14542 __ Msr(FPCR, x1);
14543
14544 // Execute a number of instructions which all use ProcessNaNs, and check that
14545 // they all produce the default NaN.
14546 __ Fmov(s0, n);
14547 __ Fmov(s1, m);
14548 __ Fmov(s2, a);
14549
14550 if (test_1op) {
14551 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14552 __ Fmov(s10, s0);
14553 __ Fabs(s11, s0);
14554 __ Fneg(s12, s0);
14555
14556 // Operations that use ProcessNaN.
14557 __ Fsqrt(s13, s0);
14558 __ Frinta(s14, s0);
14559 __ Frintn(s15, s0);
14560 __ Frintz(s16, s0);
14561
14562 // Fcvt usually has special NaN handling, but it respects default-NaN mode.
14563 __ Fcvt(d17, s0);
14564 }
14565
14566 if (test_2op) {
14567 __ Fadd(s18, s0, s1);
14568 __ Fsub(s19, s0, s1);
14569 __ Fmul(s20, s0, s1);
14570 __ Fdiv(s21, s0, s1);
14571 __ Fmax(s22, s0, s1);
14572 __ Fmin(s23, s0, s1);
14573 }
14574
14575 __ Fmadd(s24, s0, s1, s2);
14576 __ Fmsub(s25, s0, s1, s2);
14577 __ Fnmadd(s26, s0, s1, s2);
14578 __ Fnmsub(s27, s0, s1, s2);
14579
14580 // Restore FPCR.
14581 __ Msr(FPCR, x0);
14582
14583 END();
14584 RUN();
14585
14586 if (test_1op) {
14587 uint32_t n_raw = float_to_rawbits(n);
14588 ASSERT_EQUAL_FP32(n, s10);
14589 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw & ~kSSignMask), s11);
14590 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw ^ kSSignMask), s12);
14591 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s13);
14592 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s14);
14593 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s15);
14594 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s16);
14595 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d17);
14596 }
14597
14598 if (test_2op) {
14599 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s18);
14600 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s19);
14601 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s20);
14602 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s21);
14603 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s22);
14604 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s23);
14605 }
14606
14607 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s24);
14608 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s25);
14609 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s26);
14610 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s27);
14611
14612 TEARDOWN();
14613}
14614
14615
14616TEST(default_nan_float) {
14617 float sn = rawbits_to_float(0x7f951111);
14618 float sm = rawbits_to_float(0x7f952222);
14619 float sa = rawbits_to_float(0x7f95aaaa);
14620 float qn = rawbits_to_float(0x7fea1111);
14621 float qm = rawbits_to_float(0x7fea2222);
14622 float qa = rawbits_to_float(0x7feaaaaa);
14623 VIXL_ASSERT(IsSignallingNaN(sn));
14624 VIXL_ASSERT(IsSignallingNaN(sm));
14625 VIXL_ASSERT(IsSignallingNaN(sa));
14626 VIXL_ASSERT(IsQuietNaN(qn));
14627 VIXL_ASSERT(IsQuietNaN(qm));
14628 VIXL_ASSERT(IsQuietNaN(qa));
14629
14630 // - Signalling NaNs
14631 DefaultNaNHelper(sn, 0.0f, 0.0f);
14632 DefaultNaNHelper(0.0f, sm, 0.0f);
14633 DefaultNaNHelper(0.0f, 0.0f, sa);
14634 DefaultNaNHelper(sn, sm, 0.0f);
14635 DefaultNaNHelper(0.0f, sm, sa);
14636 DefaultNaNHelper(sn, 0.0f, sa);
14637 DefaultNaNHelper(sn, sm, sa);
14638 // - Quiet NaNs
14639 DefaultNaNHelper(qn, 0.0f, 0.0f);
14640 DefaultNaNHelper(0.0f, qm, 0.0f);
14641 DefaultNaNHelper(0.0f, 0.0f, qa);
14642 DefaultNaNHelper(qn, qm, 0.0f);
14643 DefaultNaNHelper(0.0f, qm, qa);
14644 DefaultNaNHelper(qn, 0.0f, qa);
14645 DefaultNaNHelper(qn, qm, qa);
14646 // - Mixed NaNs
14647 DefaultNaNHelper(qn, sm, sa);
14648 DefaultNaNHelper(sn, qm, sa);
14649 DefaultNaNHelper(sn, sm, qa);
14650 DefaultNaNHelper(qn, qm, sa);
14651 DefaultNaNHelper(sn, qm, qa);
14652 DefaultNaNHelper(qn, sm, qa);
14653 DefaultNaNHelper(qn, qm, qa);
14654}
14655
14656
14657static void DefaultNaNHelper(double n, double m, double a) {
armvixl6e2c8272015-03-31 11:04:14 +010014658 VIXL_ASSERT(std::isnan(n) || std::isnan(m) || std::isnan(a));
armvixlb0c8ae22014-03-21 14:03:59 +000014659
armvixl6e2c8272015-03-31 11:04:14 +010014660 bool test_1op = std::isnan(n);
14661 bool test_2op = std::isnan(n) || std::isnan(m);
armvixlb0c8ae22014-03-21 14:03:59 +000014662
14663 SETUP();
14664 START();
14665
14666 // Enable Default-NaN mode in the FPCR.
14667 __ Mrs(x0, FPCR);
14668 __ Orr(x1, x0, DN_mask);
14669 __ Msr(FPCR, x1);
14670
14671 // Execute a number of instructions which all use ProcessNaNs, and check that
14672 // they all produce the default NaN.
14673 __ Fmov(d0, n);
14674 __ Fmov(d1, m);
14675 __ Fmov(d2, a);
14676
14677 if (test_1op) {
14678 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14679 __ Fmov(d10, d0);
14680 __ Fabs(d11, d0);
14681 __ Fneg(d12, d0);
14682
14683 // Operations that use ProcessNaN.
14684 __ Fsqrt(d13, d0);
14685 __ Frinta(d14, d0);
14686 __ Frintn(d15, d0);
14687 __ Frintz(d16, d0);
14688
14689 // Fcvt usually has special NaN handling, but it respects default-NaN mode.
14690 __ Fcvt(s17, d0);
14691 }
14692
14693 if (test_2op) {
14694 __ Fadd(d18, d0, d1);
14695 __ Fsub(d19, d0, d1);
14696 __ Fmul(d20, d0, d1);
14697 __ Fdiv(d21, d0, d1);
14698 __ Fmax(d22, d0, d1);
14699 __ Fmin(d23, d0, d1);
14700 }
14701
14702 __ Fmadd(d24, d0, d1, d2);
14703 __ Fmsub(d25, d0, d1, d2);
14704 __ Fnmadd(d26, d0, d1, d2);
14705 __ Fnmsub(d27, d0, d1, d2);
14706
14707 // Restore FPCR.
14708 __ Msr(FPCR, x0);
14709
14710 END();
14711 RUN();
14712
14713 if (test_1op) {
14714 uint64_t n_raw = double_to_rawbits(n);
14715 ASSERT_EQUAL_FP64(n, d10);
14716 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw & ~kDSignMask), d11);
14717 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw ^ kDSignMask), d12);
14718 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
14719 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d14);
14720 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d15);
14721 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d16);
14722 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s17);
14723 }
14724
14725 if (test_2op) {
14726 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d18);
14727 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d19);
14728 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d20);
14729 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d21);
14730 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d22);
14731 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d23);
14732 }
14733
14734 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d24);
14735 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d25);
14736 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d26);
14737 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d27);
14738
14739 TEARDOWN();
14740}
14741
14742
14743TEST(default_nan_double) {
14744 double sn = rawbits_to_double(0x7ff5555511111111);
14745 double sm = rawbits_to_double(0x7ff5555522222222);
14746 double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
14747 double qn = rawbits_to_double(0x7ffaaaaa11111111);
14748 double qm = rawbits_to_double(0x7ffaaaaa22222222);
14749 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
14750 VIXL_ASSERT(IsSignallingNaN(sn));
14751 VIXL_ASSERT(IsSignallingNaN(sm));
14752 VIXL_ASSERT(IsSignallingNaN(sa));
14753 VIXL_ASSERT(IsQuietNaN(qn));
14754 VIXL_ASSERT(IsQuietNaN(qm));
14755 VIXL_ASSERT(IsQuietNaN(qa));
14756
14757 // - Signalling NaNs
14758 DefaultNaNHelper(sn, 0.0, 0.0);
14759 DefaultNaNHelper(0.0, sm, 0.0);
14760 DefaultNaNHelper(0.0, 0.0, sa);
14761 DefaultNaNHelper(sn, sm, 0.0);
14762 DefaultNaNHelper(0.0, sm, sa);
14763 DefaultNaNHelper(sn, 0.0, sa);
14764 DefaultNaNHelper(sn, sm, sa);
14765 // - Quiet NaNs
14766 DefaultNaNHelper(qn, 0.0, 0.0);
14767 DefaultNaNHelper(0.0, qm, 0.0);
14768 DefaultNaNHelper(0.0, 0.0, qa);
14769 DefaultNaNHelper(qn, qm, 0.0);
14770 DefaultNaNHelper(0.0, qm, qa);
14771 DefaultNaNHelper(qn, 0.0, qa);
14772 DefaultNaNHelper(qn, qm, qa);
14773 // - Mixed NaNs
14774 DefaultNaNHelper(qn, sm, sa);
14775 DefaultNaNHelper(sn, qm, sa);
14776 DefaultNaNHelper(sn, sm, qa);
14777 DefaultNaNHelper(qn, qm, sa);
14778 DefaultNaNHelper(sn, qm, qa);
14779 DefaultNaNHelper(qn, sm, qa);
14780 DefaultNaNHelper(qn, qm, qa);
14781}
14782
14783
armvixl4a102ba2014-07-14 09:02:40 +010014784TEST(ldar_stlr) {
14785 // The middle value is read, modified, and written. The padding exists only to
14786 // check for over-write.
14787 uint8_t b[] = {0, 0x12, 0};
14788 uint16_t h[] = {0, 0x1234, 0};
14789 uint32_t w[] = {0, 0x12345678, 0};
14790 uint64_t x[] = {0, 0x123456789abcdef0, 0};
14791
14792 SETUP();
14793 START();
14794
14795 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
14796 __ Ldarb(w0, MemOperand(x10));
14797 __ Add(w0, w0, 1);
14798 __ Stlrb(w0, MemOperand(x10));
14799
14800 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
14801 __ Ldarh(w0, MemOperand(x10));
14802 __ Add(w0, w0, 1);
14803 __ Stlrh(w0, MemOperand(x10));
14804
14805 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
14806 __ Ldar(w0, MemOperand(x10));
14807 __ Add(w0, w0, 1);
14808 __ Stlr(w0, MemOperand(x10));
14809
14810 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
14811 __ Ldar(x0, MemOperand(x10));
14812 __ Add(x0, x0, 1);
14813 __ Stlr(x0, MemOperand(x10));
14814
14815 END();
14816 RUN();
14817
14818 ASSERT_EQUAL_32(0x13, b[1]);
14819 ASSERT_EQUAL_32(0x1235, h[1]);
14820 ASSERT_EQUAL_32(0x12345679, w[1]);
14821 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
14822
14823 // Check for over-write.
14824 ASSERT_EQUAL_32(0, b[0]);
14825 ASSERT_EQUAL_32(0, b[2]);
14826 ASSERT_EQUAL_32(0, h[0]);
14827 ASSERT_EQUAL_32(0, h[2]);
14828 ASSERT_EQUAL_32(0, w[0]);
14829 ASSERT_EQUAL_32(0, w[2]);
14830 ASSERT_EQUAL_32(0, x[0]);
14831 ASSERT_EQUAL_32(0, x[2]);
14832
14833 TEARDOWN();
14834}
14835
14836
14837TEST(ldxr_stxr) {
14838 // The middle value is read, modified, and written. The padding exists only to
14839 // check for over-write.
14840 uint8_t b[] = {0, 0x12, 0};
14841 uint16_t h[] = {0, 0x1234, 0};
14842 uint32_t w[] = {0, 0x12345678, 0};
14843 uint64_t x[] = {0, 0x123456789abcdef0, 0};
14844
14845 // As above, but get suitably-aligned values for ldxp and stxp.
14846 uint32_t wp_data[] = {0, 0, 0, 0, 0};
14847 uint32_t * wp = AlignUp(wp_data + 1, kWRegSizeInBytes * 2) - 1;
14848 wp[1] = 0x12345678; // wp[1] is 64-bit-aligned.
14849 wp[2] = 0x87654321;
14850 uint64_t xp_data[] = {0, 0, 0, 0, 0};
14851 uint64_t * xp = AlignUp(xp_data + 1, kXRegSizeInBytes * 2) - 1;
14852 xp[1] = 0x123456789abcdef0; // xp[1] is 128-bit-aligned.
14853 xp[2] = 0x0fedcba987654321;
14854
14855 SETUP();
14856 START();
14857
14858 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
14859 Label try_b;
14860 __ Bind(&try_b);
14861 __ Ldxrb(w0, MemOperand(x10));
14862 __ Add(w0, w0, 1);
14863 __ Stxrb(w5, w0, MemOperand(x10));
14864 __ Cbnz(w5, &try_b);
14865
14866 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
14867 Label try_h;
14868 __ Bind(&try_h);
14869 __ Ldxrh(w0, MemOperand(x10));
14870 __ Add(w0, w0, 1);
14871 __ Stxrh(w5, w0, MemOperand(x10));
14872 __ Cbnz(w5, &try_h);
14873
14874 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
14875 Label try_w;
14876 __ Bind(&try_w);
14877 __ Ldxr(w0, MemOperand(x10));
14878 __ Add(w0, w0, 1);
14879 __ Stxr(w5, w0, MemOperand(x10));
14880 __ Cbnz(w5, &try_w);
14881
14882 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
14883 Label try_x;
14884 __ Bind(&try_x);
14885 __ Ldxr(x0, MemOperand(x10));
14886 __ Add(x0, x0, 1);
14887 __ Stxr(w5, x0, MemOperand(x10));
14888 __ Cbnz(w5, &try_x);
14889
14890 __ Mov(x10, reinterpret_cast<uintptr_t>(&wp[1]));
14891 Label try_wp;
14892 __ Bind(&try_wp);
14893 __ Ldxp(w0, w1, MemOperand(x10));
14894 __ Add(w0, w0, 1);
14895 __ Add(w1, w1, 1);
14896 __ Stxp(w5, w0, w1, MemOperand(x10));
14897 __ Cbnz(w5, &try_wp);
14898
14899 __ Mov(x10, reinterpret_cast<uintptr_t>(&xp[1]));
14900 Label try_xp;
14901 __ Bind(&try_xp);
14902 __ Ldxp(x0, x1, MemOperand(x10));
14903 __ Add(x0, x0, 1);
14904 __ Add(x1, x1, 1);
14905 __ Stxp(w5, x0, x1, MemOperand(x10));
14906 __ Cbnz(w5, &try_xp);
14907
14908 END();
14909 RUN();
14910
14911 ASSERT_EQUAL_32(0x13, b[1]);
14912 ASSERT_EQUAL_32(0x1235, h[1]);
14913 ASSERT_EQUAL_32(0x12345679, w[1]);
14914 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
14915 ASSERT_EQUAL_32(0x12345679, wp[1]);
14916 ASSERT_EQUAL_32(0x87654322, wp[2]);
14917 ASSERT_EQUAL_64(0x123456789abcdef1, xp[1]);
14918 ASSERT_EQUAL_64(0x0fedcba987654322, xp[2]);
14919
14920 // Check for over-write.
14921 ASSERT_EQUAL_32(0, b[0]);
14922 ASSERT_EQUAL_32(0, b[2]);
14923 ASSERT_EQUAL_32(0, h[0]);
14924 ASSERT_EQUAL_32(0, h[2]);
14925 ASSERT_EQUAL_32(0, w[0]);
14926 ASSERT_EQUAL_32(0, w[2]);
14927 ASSERT_EQUAL_64(0, x[0]);
14928 ASSERT_EQUAL_64(0, x[2]);
14929 ASSERT_EQUAL_32(0, wp[0]);
14930 ASSERT_EQUAL_32(0, wp[3]);
14931 ASSERT_EQUAL_64(0, xp[0]);
14932 ASSERT_EQUAL_64(0, xp[3]);
14933
14934 TEARDOWN();
14935}
14936
14937
14938TEST(ldaxr_stlxr) {
14939 // The middle value is read, modified, and written. The padding exists only to
14940 // check for over-write.
14941 uint8_t b[] = {0, 0x12, 0};
14942 uint16_t h[] = {0, 0x1234, 0};
14943 uint32_t w[] = {0, 0x12345678, 0};
14944 uint64_t x[] = {0, 0x123456789abcdef0, 0};
14945
14946 // As above, but get suitably-aligned values for ldxp and stxp.
14947 uint32_t wp_data[] = {0, 0, 0, 0, 0};
14948 uint32_t * wp = AlignUp(wp_data + 1, kWRegSizeInBytes * 2) - 1;
14949 wp[1] = 0x12345678; // wp[1] is 64-bit-aligned.
14950 wp[2] = 0x87654321;
14951 uint64_t xp_data[] = {0, 0, 0, 0, 0};
14952 uint64_t * xp = AlignUp(xp_data + 1, kXRegSizeInBytes * 2) - 1;
14953 xp[1] = 0x123456789abcdef0; // xp[1] is 128-bit-aligned.
14954 xp[2] = 0x0fedcba987654321;
14955
14956 SETUP();
14957 START();
14958
14959 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
14960 Label try_b;
14961 __ Bind(&try_b);
14962 __ Ldaxrb(w0, MemOperand(x10));
14963 __ Add(w0, w0, 1);
14964 __ Stlxrb(w5, w0, MemOperand(x10));
14965 __ Cbnz(w5, &try_b);
14966
14967 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
14968 Label try_h;
14969 __ Bind(&try_h);
14970 __ Ldaxrh(w0, MemOperand(x10));
14971 __ Add(w0, w0, 1);
14972 __ Stlxrh(w5, w0, MemOperand(x10));
14973 __ Cbnz(w5, &try_h);
14974
14975 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
14976 Label try_w;
14977 __ Bind(&try_w);
14978 __ Ldaxr(w0, MemOperand(x10));
14979 __ Add(w0, w0, 1);
14980 __ Stlxr(w5, w0, MemOperand(x10));
14981 __ Cbnz(w5, &try_w);
14982
14983 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
14984 Label try_x;
14985 __ Bind(&try_x);
14986 __ Ldaxr(x0, MemOperand(x10));
14987 __ Add(x0, x0, 1);
14988 __ Stlxr(w5, x0, MemOperand(x10));
14989 __ Cbnz(w5, &try_x);
14990
14991 __ Mov(x10, reinterpret_cast<uintptr_t>(&wp[1]));
14992 Label try_wp;
14993 __ Bind(&try_wp);
14994 __ Ldaxp(w0, w1, MemOperand(x10));
14995 __ Add(w0, w0, 1);
14996 __ Add(w1, w1, 1);
14997 __ Stlxp(w5, w0, w1, MemOperand(x10));
14998 __ Cbnz(w5, &try_wp);
14999
15000 __ Mov(x10, reinterpret_cast<uintptr_t>(&xp[1]));
15001 Label try_xp;
15002 __ Bind(&try_xp);
15003 __ Ldaxp(x0, x1, MemOperand(x10));
15004 __ Add(x0, x0, 1);
15005 __ Add(x1, x1, 1);
15006 __ Stlxp(w5, x0, x1, MemOperand(x10));
15007 __ Cbnz(w5, &try_xp);
15008
15009 END();
15010 RUN();
15011
15012 ASSERT_EQUAL_32(0x13, b[1]);
15013 ASSERT_EQUAL_32(0x1235, h[1]);
15014 ASSERT_EQUAL_32(0x12345679, w[1]);
15015 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
15016 ASSERT_EQUAL_32(0x12345679, wp[1]);
15017 ASSERT_EQUAL_32(0x87654322, wp[2]);
15018 ASSERT_EQUAL_64(0x123456789abcdef1, xp[1]);
15019 ASSERT_EQUAL_64(0x0fedcba987654322, xp[2]);
15020
15021 // Check for over-write.
15022 ASSERT_EQUAL_32(0, b[0]);
15023 ASSERT_EQUAL_32(0, b[2]);
15024 ASSERT_EQUAL_32(0, h[0]);
15025 ASSERT_EQUAL_32(0, h[2]);
15026 ASSERT_EQUAL_32(0, w[0]);
15027 ASSERT_EQUAL_32(0, w[2]);
15028 ASSERT_EQUAL_64(0, x[0]);
15029 ASSERT_EQUAL_64(0, x[2]);
15030 ASSERT_EQUAL_32(0, wp[0]);
15031 ASSERT_EQUAL_32(0, wp[3]);
15032 ASSERT_EQUAL_64(0, xp[0]);
15033 ASSERT_EQUAL_64(0, xp[3]);
15034
15035 TEARDOWN();
15036}
15037
15038
15039TEST(clrex) {
15040 // This data should never be written.
15041 uint64_t data[] = {0, 0, 0};
15042 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
15043
15044 SETUP();
15045 START();
15046
15047 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
15048 __ Mov(w6, 0);
15049
15050 __ Ldxrb(w0, MemOperand(x10));
15051 __ Clrex();
15052 __ Add(w0, w0, 1);
15053 __ Stxrb(w5, w0, MemOperand(x10));
15054 __ Add(w6, w6, w5);
15055
15056 __ Ldxrh(w0, MemOperand(x10));
15057 __ Clrex();
15058 __ Add(w0, w0, 1);
15059 __ Stxrh(w5, w0, MemOperand(x10));
15060 __ Add(w6, w6, w5);
15061
15062 __ Ldxr(w0, MemOperand(x10));
15063 __ Clrex();
15064 __ Add(w0, w0, 1);
15065 __ Stxr(w5, w0, MemOperand(x10));
15066 __ Add(w6, w6, w5);
15067
15068 __ Ldxr(x0, MemOperand(x10));
15069 __ Clrex();
15070 __ Add(x0, x0, 1);
15071 __ Stxr(w5, x0, MemOperand(x10));
15072 __ Add(w6, w6, w5);
15073
15074 __ Ldxp(w0, w1, MemOperand(x10));
15075 __ Clrex();
15076 __ Add(w0, w0, 1);
15077 __ Add(w1, w1, 1);
15078 __ Stxp(w5, w0, w1, MemOperand(x10));
15079 __ Add(w6, w6, w5);
15080
15081 __ Ldxp(x0, x1, MemOperand(x10));
15082 __ Clrex();
15083 __ Add(x0, x0, 1);
15084 __ Add(x1, x1, 1);
15085 __ Stxp(w5, x0, x1, MemOperand(x10));
15086 __ Add(w6, w6, w5);
15087
15088 // Acquire-release variants.
15089
15090 __ Ldaxrb(w0, MemOperand(x10));
15091 __ Clrex();
15092 __ Add(w0, w0, 1);
15093 __ Stlxrb(w5, w0, MemOperand(x10));
15094 __ Add(w6, w6, w5);
15095
15096 __ Ldaxrh(w0, MemOperand(x10));
15097 __ Clrex();
15098 __ Add(w0, w0, 1);
15099 __ Stlxrh(w5, w0, MemOperand(x10));
15100 __ Add(w6, w6, w5);
15101
15102 __ Ldaxr(w0, MemOperand(x10));
15103 __ Clrex();
15104 __ Add(w0, w0, 1);
15105 __ Stlxr(w5, w0, MemOperand(x10));
15106 __ Add(w6, w6, w5);
15107
15108 __ Ldaxr(x0, MemOperand(x10));
15109 __ Clrex();
15110 __ Add(x0, x0, 1);
15111 __ Stlxr(w5, x0, MemOperand(x10));
15112 __ Add(w6, w6, w5);
15113
15114 __ Ldaxp(w0, w1, MemOperand(x10));
15115 __ Clrex();
15116 __ Add(w0, w0, 1);
15117 __ Add(w1, w1, 1);
15118 __ Stlxp(w5, w0, w1, MemOperand(x10));
15119 __ Add(w6, w6, w5);
15120
15121 __ Ldaxp(x0, x1, MemOperand(x10));
15122 __ Clrex();
15123 __ Add(x0, x0, 1);
15124 __ Add(x1, x1, 1);
15125 __ Stlxp(w5, x0, x1, MemOperand(x10));
15126 __ Add(w6, w6, w5);
15127
15128 END();
15129 RUN();
15130
15131 // None of the 12 store-exclusives should have succeeded.
15132 ASSERT_EQUAL_32(12, w6);
15133
15134 ASSERT_EQUAL_64(0, data[0]);
15135 ASSERT_EQUAL_64(0, data[1]);
15136 ASSERT_EQUAL_64(0, data[2]);
15137}
15138
15139
15140#ifdef USE_SIMULATOR
15141// Check that the simulator occasionally makes store-exclusive fail.
15142TEST(ldxr_stxr_fail) {
15143 uint64_t data[] = {0, 0, 0};
15144 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
15145
15146 // Impose a hard limit on the number of attempts, so the test cannot hang.
15147 static const uint64_t kWatchdog = 10000;
15148 Label done;
15149
15150 SETUP();
15151 START();
15152
15153 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
15154 __ Mov(x11, kWatchdog);
15155
15156 // This loop is the opposite of what we normally do with ldxr and stxr; we
15157 // keep trying until we fail (or the watchdog counter runs out).
15158 Label try_b;
15159 __ Bind(&try_b);
15160 __ Ldxrb(w0, MemOperand(x10));
15161 __ Stxrb(w5, w0, MemOperand(x10));
15162 // Check the watchdog counter.
15163 __ Sub(x11, x11, 1);
15164 __ Cbz(x11, &done);
15165 // Check the exclusive-store result.
15166 __ Cbz(w5, &try_b);
15167
15168 Label try_h;
15169 __ Bind(&try_h);
15170 __ Ldxrh(w0, MemOperand(x10));
15171 __ Stxrh(w5, w0, MemOperand(x10));
15172 __ Sub(x11, x11, 1);
15173 __ Cbz(x11, &done);
15174 __ Cbz(w5, &try_h);
15175
15176 Label try_w;
15177 __ Bind(&try_w);
15178 __ Ldxr(w0, MemOperand(x10));
15179 __ Stxr(w5, w0, MemOperand(x10));
15180 __ Sub(x11, x11, 1);
15181 __ Cbz(x11, &done);
15182 __ Cbz(w5, &try_w);
15183
15184 Label try_x;
15185 __ Bind(&try_x);
15186 __ Ldxr(x0, MemOperand(x10));
15187 __ Stxr(w5, x0, MemOperand(x10));
15188 __ Sub(x11, x11, 1);
15189 __ Cbz(x11, &done);
15190 __ Cbz(w5, &try_x);
15191
15192 Label try_wp;
15193 __ Bind(&try_wp);
15194 __ Ldxp(w0, w1, MemOperand(x10));
15195 __ Stxp(w5, w0, w1, MemOperand(x10));
15196 __ Sub(x11, x11, 1);
15197 __ Cbz(x11, &done);
15198 __ Cbz(w5, &try_wp);
15199
15200 Label try_xp;
15201 __ Bind(&try_xp);
15202 __ Ldxp(x0, x1, MemOperand(x10));
15203 __ Stxp(w5, x0, x1, MemOperand(x10));
15204 __ Sub(x11, x11, 1);
15205 __ Cbz(x11, &done);
15206 __ Cbz(w5, &try_xp);
15207
15208 __ Bind(&done);
15209 // Trigger an error if x11 (watchdog) is zero.
15210 __ Cmp(x11, 0);
15211 __ Cset(x12, eq);
15212
15213 END();
15214 RUN();
15215
15216 // Check that the watchdog counter didn't run out.
15217 ASSERT_EQUAL_64(0, x12);
15218}
15219#endif
15220
15221
15222#ifdef USE_SIMULATOR
15223// Check that the simulator occasionally makes store-exclusive fail.
15224TEST(ldaxr_stlxr_fail) {
15225 uint64_t data[] = {0, 0, 0};
15226 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
15227
15228 // Impose a hard limit on the number of attempts, so the test cannot hang.
15229 static const uint64_t kWatchdog = 10000;
15230 Label done;
15231
15232 SETUP();
15233 START();
15234
15235 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
15236 __ Mov(x11, kWatchdog);
15237
15238 // This loop is the opposite of what we normally do with ldxr and stxr; we
15239 // keep trying until we fail (or the watchdog counter runs out).
15240 Label try_b;
15241 __ Bind(&try_b);
15242 __ Ldxrb(w0, MemOperand(x10));
15243 __ Stxrb(w5, w0, MemOperand(x10));
15244 // Check the watchdog counter.
15245 __ Sub(x11, x11, 1);
15246 __ Cbz(x11, &done);
15247 // Check the exclusive-store result.
15248 __ Cbz(w5, &try_b);
15249
15250 Label try_h;
15251 __ Bind(&try_h);
15252 __ Ldaxrh(w0, MemOperand(x10));
15253 __ Stlxrh(w5, w0, MemOperand(x10));
15254 __ Sub(x11, x11, 1);
15255 __ Cbz(x11, &done);
15256 __ Cbz(w5, &try_h);
15257
15258 Label try_w;
15259 __ Bind(&try_w);
15260 __ Ldaxr(w0, MemOperand(x10));
15261 __ Stlxr(w5, w0, MemOperand(x10));
15262 __ Sub(x11, x11, 1);
15263 __ Cbz(x11, &done);
15264 __ Cbz(w5, &try_w);
15265
15266 Label try_x;
15267 __ Bind(&try_x);
15268 __ Ldaxr(x0, MemOperand(x10));
15269 __ Stlxr(w5, x0, MemOperand(x10));
15270 __ Sub(x11, x11, 1);
15271 __ Cbz(x11, &done);
15272 __ Cbz(w5, &try_x);
15273
15274 Label try_wp;
15275 __ Bind(&try_wp);
15276 __ Ldaxp(w0, w1, MemOperand(x10));
15277 __ Stlxp(w5, w0, w1, MemOperand(x10));
15278 __ Sub(x11, x11, 1);
15279 __ Cbz(x11, &done);
15280 __ Cbz(w5, &try_wp);
15281
15282 Label try_xp;
15283 __ Bind(&try_xp);
15284 __ Ldaxp(x0, x1, MemOperand(x10));
15285 __ Stlxp(w5, x0, x1, MemOperand(x10));
15286 __ Sub(x11, x11, 1);
15287 __ Cbz(x11, &done);
15288 __ Cbz(w5, &try_xp);
15289
15290 __ Bind(&done);
15291 // Trigger an error if x11 (watchdog) is zero.
15292 __ Cmp(x11, 0);
15293 __ Cset(x12, eq);
15294
15295 END();
15296 RUN();
15297
15298 // Check that the watchdog counter didn't run out.
15299 ASSERT_EQUAL_64(0, x12);
15300}
15301#endif
15302
15303
15304TEST(load_store_tagged_immediate_offset) {
15305 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15306 int tag_count = sizeof(tags) / sizeof(tags[0]);
15307
armvixl5289c592015-03-02 13:52:04 +000015308 const int kMaxDataLength = 160;
armvixl4a102ba2014-07-14 09:02:40 +010015309
15310 for (int i = 0; i < tag_count; i++) {
15311 unsigned char src[kMaxDataLength];
15312 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
15313 uint64_t src_tag = tags[i];
15314 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
15315
15316 for (int k = 0; k < kMaxDataLength; k++) {
15317 src[k] = k + 1;
15318 }
15319
15320 for (int j = 0; j < tag_count; j++) {
15321 unsigned char dst[kMaxDataLength];
15322 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
15323 uint64_t dst_tag = tags[j];
15324 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
15325
15326 memset(dst, 0, kMaxDataLength);
15327
15328 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015329 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010015330 START();
15331
15332 __ Mov(x0, src_tagged);
15333 __ Mov(x1, dst_tagged);
15334
15335 int offset = 0;
15336
15337 // Scaled-immediate offsets.
armvixl5289c592015-03-02 13:52:04 +000015338 __ ldp(q0, q1, MemOperand(x0, offset));
15339 __ stp(q0, q1, MemOperand(x1, offset));
15340 offset += 2 * kQRegSizeInBytes;
armvixl4a102ba2014-07-14 09:02:40 +010015341
15342 __ ldp(x2, x3, MemOperand(x0, offset));
15343 __ stp(x2, x3, MemOperand(x1, offset));
15344 offset += 2 * kXRegSizeInBytes;
15345
15346 __ ldpsw(x2, x3, MemOperand(x0, offset));
15347 __ stp(w2, w3, MemOperand(x1, offset));
15348 offset += 2 * kWRegSizeInBytes;
15349
15350 __ ldp(d0, d1, MemOperand(x0, offset));
15351 __ stp(d0, d1, MemOperand(x1, offset));
15352 offset += 2 * kDRegSizeInBytes;
15353
15354 __ ldp(w2, w3, MemOperand(x0, offset));
15355 __ stp(w2, w3, MemOperand(x1, offset));
15356 offset += 2 * kWRegSizeInBytes;
15357
15358 __ ldp(s0, s1, MemOperand(x0, offset));
15359 __ stp(s0, s1, MemOperand(x1, offset));
15360 offset += 2 * kSRegSizeInBytes;
15361
15362 __ ldr(x2, MemOperand(x0, offset), RequireScaledOffset);
15363 __ str(x2, MemOperand(x1, offset), RequireScaledOffset);
15364 offset += kXRegSizeInBytes;
15365
15366 __ ldr(d0, MemOperand(x0, offset), RequireScaledOffset);
15367 __ str(d0, MemOperand(x1, offset), RequireScaledOffset);
15368 offset += kDRegSizeInBytes;
15369
15370 __ ldr(w2, MemOperand(x0, offset), RequireScaledOffset);
15371 __ str(w2, MemOperand(x1, offset), RequireScaledOffset);
15372 offset += kWRegSizeInBytes;
15373
15374 __ ldr(s0, MemOperand(x0, offset), RequireScaledOffset);
15375 __ str(s0, MemOperand(x1, offset), RequireScaledOffset);
15376 offset += kSRegSizeInBytes;
15377
15378 __ ldrh(w2, MemOperand(x0, offset), RequireScaledOffset);
15379 __ strh(w2, MemOperand(x1, offset), RequireScaledOffset);
15380 offset += 2;
15381
15382 __ ldrsh(w2, MemOperand(x0, offset), RequireScaledOffset);
15383 __ strh(w2, MemOperand(x1, offset), RequireScaledOffset);
15384 offset += 2;
15385
15386 __ ldrb(w2, MemOperand(x0, offset), RequireScaledOffset);
15387 __ strb(w2, MemOperand(x1, offset), RequireScaledOffset);
15388 offset += 1;
15389
15390 __ ldrsb(w2, MemOperand(x0, offset), RequireScaledOffset);
15391 __ strb(w2, MemOperand(x1, offset), RequireScaledOffset);
15392 offset += 1;
15393
15394 // Unscaled-immediate offsets.
15395
15396 __ ldur(x2, MemOperand(x0, offset), RequireUnscaledOffset);
15397 __ stur(x2, MemOperand(x1, offset), RequireUnscaledOffset);
15398 offset += kXRegSizeInBytes;
15399
15400 __ ldur(d0, MemOperand(x0, offset), RequireUnscaledOffset);
15401 __ stur(d0, MemOperand(x1, offset), RequireUnscaledOffset);
15402 offset += kDRegSizeInBytes;
15403
15404 __ ldur(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15405 __ stur(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15406 offset += kWRegSizeInBytes;
15407
15408 __ ldur(s0, MemOperand(x0, offset), RequireUnscaledOffset);
15409 __ stur(s0, MemOperand(x1, offset), RequireUnscaledOffset);
15410 offset += kSRegSizeInBytes;
15411
15412 __ ldurh(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15413 __ sturh(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15414 offset += 2;
15415
15416 __ ldursh(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15417 __ sturh(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15418 offset += 2;
15419
15420 __ ldurb(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15421 __ sturb(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15422 offset += 1;
15423
15424 __ ldursb(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15425 __ sturb(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15426 offset += 1;
15427
15428 // Extract the tag (so we can test that it was preserved correctly).
15429 __ Ubfx(x0, x0, kAddressTagOffset, kAddressTagWidth);
15430 __ Ubfx(x1, x1, kAddressTagOffset, kAddressTagWidth);
15431
15432 VIXL_ASSERT(kMaxDataLength >= offset);
15433
15434 END();
15435 RUN();
15436
15437 ASSERT_EQUAL_64(src_tag, x0);
15438 ASSERT_EQUAL_64(dst_tag, x1);
15439
15440 for (int k = 0; k < offset; k++) {
15441 VIXL_CHECK(src[k] == dst[k]);
15442 }
15443
15444 TEARDOWN();
15445 }
15446 }
15447}
15448
15449
15450TEST(load_store_tagged_immediate_preindex) {
15451 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15452 int tag_count = sizeof(tags) / sizeof(tags[0]);
15453
15454 const int kMaxDataLength = 128;
15455
15456 for (int i = 0; i < tag_count; i++) {
15457 unsigned char src[kMaxDataLength];
15458 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
15459 uint64_t src_tag = tags[i];
15460 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
15461
15462 for (int k = 0; k < kMaxDataLength; k++) {
15463 src[k] = k + 1;
15464 }
15465
15466 for (int j = 0; j < tag_count; j++) {
15467 unsigned char dst[kMaxDataLength];
15468 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
15469 uint64_t dst_tag = tags[j];
15470 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
15471
15472 for (int k = 0; k < kMaxDataLength; k++) {
15473 dst[k] = 0;
15474 }
15475
15476 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015477 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010015478 START();
15479
15480 // Each MemOperand must apply a pre-index equal to the size of the
15481 // previous access.
15482
15483 // Start with a non-zero preindex.
armvixl5289c592015-03-02 13:52:04 +000015484 int preindex = 62 * kXRegSizeInBytes;
armvixlc68cb642014-09-25 18:49:30 +010015485 int data_length = 0;
armvixl4a102ba2014-07-14 09:02:40 +010015486
15487 __ Mov(x0, src_tagged - preindex);
15488 __ Mov(x1, dst_tagged - preindex);
15489
armvixl5289c592015-03-02 13:52:04 +000015490 __ ldp(q0, q1, MemOperand(x0, preindex, PreIndex));
15491 __ stp(q0, q1, MemOperand(x1, preindex, PreIndex));
15492 preindex = 2 * kQRegSizeInBytes;
15493 data_length = preindex;
15494
armvixl4a102ba2014-07-14 09:02:40 +010015495 __ ldp(x2, x3, MemOperand(x0, preindex, PreIndex));
15496 __ stp(x2, x3, MemOperand(x1, preindex, PreIndex));
15497 preindex = 2 * kXRegSizeInBytes;
armvixl5289c592015-03-02 13:52:04 +000015498 data_length += preindex;
armvixl4a102ba2014-07-14 09:02:40 +010015499
15500 __ ldpsw(x2, x3, MemOperand(x0, preindex, PreIndex));
15501 __ stp(w2, w3, MemOperand(x1, preindex, PreIndex));
15502 preindex = 2 * kWRegSizeInBytes;
15503 data_length += preindex;
15504
15505 __ ldp(d0, d1, MemOperand(x0, preindex, PreIndex));
15506 __ stp(d0, d1, MemOperand(x1, preindex, PreIndex));
15507 preindex = 2 * kDRegSizeInBytes;
15508 data_length += preindex;
15509
15510 __ ldp(w2, w3, MemOperand(x0, preindex, PreIndex));
15511 __ stp(w2, w3, MemOperand(x1, preindex, PreIndex));
15512 preindex = 2 * kWRegSizeInBytes;
15513 data_length += preindex;
15514
15515 __ ldp(s0, s1, MemOperand(x0, preindex, PreIndex));
15516 __ stp(s0, s1, MemOperand(x1, preindex, PreIndex));
15517 preindex = 2 * kSRegSizeInBytes;
15518 data_length += preindex;
15519
15520 __ ldr(x2, MemOperand(x0, preindex, PreIndex));
15521 __ str(x2, MemOperand(x1, preindex, PreIndex));
15522 preindex = kXRegSizeInBytes;
15523 data_length += preindex;
15524
15525 __ ldr(d0, MemOperand(x0, preindex, PreIndex));
15526 __ str(d0, MemOperand(x1, preindex, PreIndex));
15527 preindex = kDRegSizeInBytes;
15528 data_length += preindex;
15529
15530 __ ldr(w2, MemOperand(x0, preindex, PreIndex));
15531 __ str(w2, MemOperand(x1, preindex, PreIndex));
15532 preindex = kWRegSizeInBytes;
15533 data_length += preindex;
15534
15535 __ ldr(s0, MemOperand(x0, preindex, PreIndex));
15536 __ str(s0, MemOperand(x1, preindex, PreIndex));
15537 preindex = kSRegSizeInBytes;
15538 data_length += preindex;
15539
15540 __ ldrh(w2, MemOperand(x0, preindex, PreIndex));
15541 __ strh(w2, MemOperand(x1, preindex, PreIndex));
15542 preindex = 2;
15543 data_length += preindex;
15544
15545 __ ldrsh(w2, MemOperand(x0, preindex, PreIndex));
15546 __ strh(w2, MemOperand(x1, preindex, PreIndex));
15547 preindex = 2;
15548 data_length += preindex;
15549
15550 __ ldrb(w2, MemOperand(x0, preindex, PreIndex));
15551 __ strb(w2, MemOperand(x1, preindex, PreIndex));
15552 preindex = 1;
15553 data_length += preindex;
15554
15555 __ ldrsb(w2, MemOperand(x0, preindex, PreIndex));
15556 __ strb(w2, MemOperand(x1, preindex, PreIndex));
15557 preindex = 1;
15558 data_length += preindex;
15559
15560 VIXL_ASSERT(kMaxDataLength >= data_length);
15561
15562 END();
15563 RUN();
15564
15565 // Check that the preindex was correctly applied in each operation, and
15566 // that the tag was preserved.
15567 ASSERT_EQUAL_64(src_tagged + data_length - preindex, x0);
15568 ASSERT_EQUAL_64(dst_tagged + data_length - preindex, x1);
15569
15570 for (int k = 0; k < data_length; k++) {
15571 VIXL_CHECK(src[k] == dst[k]);
15572 }
15573
15574 TEARDOWN();
15575 }
15576 }
15577}
15578
15579
15580TEST(load_store_tagged_immediate_postindex) {
15581 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15582 int tag_count = sizeof(tags) / sizeof(tags[0]);
15583
15584 const int kMaxDataLength = 128;
15585
15586 for (int i = 0; i < tag_count; i++) {
15587 unsigned char src[kMaxDataLength];
15588 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
15589 uint64_t src_tag = tags[i];
15590 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
15591
15592 for (int k = 0; k < kMaxDataLength; k++) {
15593 src[k] = k + 1;
15594 }
15595
15596 for (int j = 0; j < tag_count; j++) {
15597 unsigned char dst[kMaxDataLength];
15598 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
15599 uint64_t dst_tag = tags[j];
15600 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
15601
15602 for (int k = 0; k < kMaxDataLength; k++) {
15603 dst[k] = 0;
15604 }
15605
15606 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015607 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010015608 START();
15609
armvixlc68cb642014-09-25 18:49:30 +010015610 int postindex = 2 * kXRegSizeInBytes;
15611 int data_length = 0;
15612
armvixl4a102ba2014-07-14 09:02:40 +010015613 __ Mov(x0, src_tagged);
15614 __ Mov(x1, dst_tagged);
15615
armvixl4a102ba2014-07-14 09:02:40 +010015616 __ ldp(x2, x3, MemOperand(x0, postindex, PostIndex));
15617 __ stp(x2, x3, MemOperand(x1, postindex, PostIndex));
armvixlc68cb642014-09-25 18:49:30 +010015618 data_length = postindex;
armvixl4a102ba2014-07-14 09:02:40 +010015619
armvixl5289c592015-03-02 13:52:04 +000015620 postindex = 2 * kQRegSizeInBytes;
15621 __ ldp(q0, q1, MemOperand(x0, postindex, PostIndex));
15622 __ stp(q0, q1, MemOperand(x1, postindex, PostIndex));
15623 data_length += postindex;
15624
armvixl4a102ba2014-07-14 09:02:40 +010015625 postindex = 2 * kWRegSizeInBytes;
15626 __ ldpsw(x2, x3, MemOperand(x0, postindex, PostIndex));
15627 __ stp(w2, w3, MemOperand(x1, postindex, PostIndex));
15628 data_length += postindex;
15629
15630 postindex = 2 * kDRegSizeInBytes;
15631 __ ldp(d0, d1, MemOperand(x0, postindex, PostIndex));
15632 __ stp(d0, d1, MemOperand(x1, postindex, PostIndex));
15633 data_length += postindex;
15634
15635 postindex = 2 * kWRegSizeInBytes;
15636 __ ldp(w2, w3, MemOperand(x0, postindex, PostIndex));
15637 __ stp(w2, w3, MemOperand(x1, postindex, PostIndex));
15638 data_length += postindex;
15639
15640 postindex = 2 * kSRegSizeInBytes;
15641 __ ldp(s0, s1, MemOperand(x0, postindex, PostIndex));
15642 __ stp(s0, s1, MemOperand(x1, postindex, PostIndex));
15643 data_length += postindex;
15644
15645 postindex = kXRegSizeInBytes;
15646 __ ldr(x2, MemOperand(x0, postindex, PostIndex));
15647 __ str(x2, MemOperand(x1, postindex, PostIndex));
15648 data_length += postindex;
15649
15650 postindex = kDRegSizeInBytes;
15651 __ ldr(d0, MemOperand(x0, postindex, PostIndex));
15652 __ str(d0, MemOperand(x1, postindex, PostIndex));
15653 data_length += postindex;
15654
15655 postindex = kWRegSizeInBytes;
15656 __ ldr(w2, MemOperand(x0, postindex, PostIndex));
15657 __ str(w2, MemOperand(x1, postindex, PostIndex));
15658 data_length += postindex;
15659
15660 postindex = kSRegSizeInBytes;
15661 __ ldr(s0, MemOperand(x0, postindex, PostIndex));
15662 __ str(s0, MemOperand(x1, postindex, PostIndex));
15663 data_length += postindex;
15664
15665 postindex = 2;
15666 __ ldrh(w2, MemOperand(x0, postindex, PostIndex));
15667 __ strh(w2, MemOperand(x1, postindex, PostIndex));
15668 data_length += postindex;
15669
15670 postindex = 2;
15671 __ ldrsh(w2, MemOperand(x0, postindex, PostIndex));
15672 __ strh(w2, MemOperand(x1, postindex, PostIndex));
15673 data_length += postindex;
15674
15675 postindex = 1;
15676 __ ldrb(w2, MemOperand(x0, postindex, PostIndex));
15677 __ strb(w2, MemOperand(x1, postindex, PostIndex));
15678 data_length += postindex;
15679
15680 postindex = 1;
15681 __ ldrsb(w2, MemOperand(x0, postindex, PostIndex));
15682 __ strb(w2, MemOperand(x1, postindex, PostIndex));
15683 data_length += postindex;
15684
15685 VIXL_ASSERT(kMaxDataLength >= data_length);
15686
15687 END();
15688 RUN();
15689
15690 // Check that the postindex was correctly applied in each operation, and
15691 // that the tag was preserved.
15692 ASSERT_EQUAL_64(src_tagged + data_length, x0);
15693 ASSERT_EQUAL_64(dst_tagged + data_length, x1);
15694
15695 for (int k = 0; k < data_length; k++) {
15696 VIXL_CHECK(src[k] == dst[k]);
15697 }
15698
15699 TEARDOWN();
15700 }
15701 }
15702}
15703
15704
15705TEST(load_store_tagged_register_offset) {
15706 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15707 int tag_count = sizeof(tags) / sizeof(tags[0]);
15708
15709 const int kMaxDataLength = 128;
15710
15711 for (int i = 0; i < tag_count; i++) {
15712 unsigned char src[kMaxDataLength];
15713 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
15714 uint64_t src_tag = tags[i];
15715 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
15716
15717 for (int k = 0; k < kMaxDataLength; k++) {
15718 src[k] = k + 1;
15719 }
15720
15721 for (int j = 0; j < tag_count; j++) {
15722 unsigned char dst[kMaxDataLength];
15723 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
15724 uint64_t dst_tag = tags[j];
15725 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
15726
15727 // Also tag the offset register; the operation should still succeed.
15728 for (int o = 0; o < tag_count; o++) {
15729 uint64_t offset_base = CPU::SetPointerTag(UINT64_C(0), tags[o]);
15730 int data_length = 0;
15731
15732 for (int k = 0; k < kMaxDataLength; k++) {
15733 dst[k] = 0;
15734 }
15735
15736 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015737 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010015738 START();
15739
15740 __ Mov(x0, src_tagged);
15741 __ Mov(x1, dst_tagged);
15742
15743 __ Mov(x10, offset_base + data_length);
15744 __ ldr(x2, MemOperand(x0, x10));
15745 __ str(x2, MemOperand(x1, x10));
15746 data_length += kXRegSizeInBytes;
15747
15748 __ Mov(x10, offset_base + data_length);
15749 __ ldr(d0, MemOperand(x0, x10));
15750 __ str(d0, MemOperand(x1, x10));
15751 data_length += kDRegSizeInBytes;
15752
15753 __ Mov(x10, offset_base + data_length);
15754 __ ldr(w2, MemOperand(x0, x10));
15755 __ str(w2, MemOperand(x1, x10));
15756 data_length += kWRegSizeInBytes;
15757
15758 __ Mov(x10, offset_base + data_length);
15759 __ ldr(s0, MemOperand(x0, x10));
15760 __ str(s0, MemOperand(x1, x10));
15761 data_length += kSRegSizeInBytes;
15762
15763 __ Mov(x10, offset_base + data_length);
15764 __ ldrh(w2, MemOperand(x0, x10));
15765 __ strh(w2, MemOperand(x1, x10));
15766 data_length += 2;
15767
15768 __ Mov(x10, offset_base + data_length);
15769 __ ldrsh(w2, MemOperand(x0, x10));
15770 __ strh(w2, MemOperand(x1, x10));
15771 data_length += 2;
15772
15773 __ Mov(x10, offset_base + data_length);
15774 __ ldrb(w2, MemOperand(x0, x10));
15775 __ strb(w2, MemOperand(x1, x10));
15776 data_length += 1;
15777
15778 __ Mov(x10, offset_base + data_length);
15779 __ ldrsb(w2, MemOperand(x0, x10));
15780 __ strb(w2, MemOperand(x1, x10));
15781 data_length += 1;
15782
15783 VIXL_ASSERT(kMaxDataLength >= data_length);
15784
15785 END();
15786 RUN();
15787
15788 // Check that the postindex was correctly applied in each operation, and
15789 // that the tag was preserved.
15790 ASSERT_EQUAL_64(src_tagged, x0);
15791 ASSERT_EQUAL_64(dst_tagged, x1);
15792 ASSERT_EQUAL_64(offset_base + data_length - 1, x10);
15793
15794 for (int k = 0; k < data_length; k++) {
15795 VIXL_CHECK(src[k] == dst[k]);
15796 }
15797
15798 TEARDOWN();
15799 }
15800 }
15801 }
15802}
15803
15804
armvixl5289c592015-03-02 13:52:04 +000015805TEST(load_store_tagged_register_postindex) {
15806 uint64_t src[] = { 0x0706050403020100, 0x0f0e0d0c0b0a0908 };
15807 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15808 int tag_count = sizeof(tags) / sizeof(tags[0]);
15809
15810 for (int j = 0; j < tag_count; j++) {
15811 for (int i = 0; i < tag_count; i++) {
15812 SETUP();
15813 uint64_t src_base = reinterpret_cast<uint64_t>(src);
15814 uint64_t src_tagged = CPU::SetPointerTag(src_base, tags[i]);
15815 uint64_t offset_tagged = CPU::SetPointerTag(UINT64_C(0), tags[j]);
15816
15817 START();
15818 __ Mov(x10, src_tagged);
15819 __ Mov(x11, offset_tagged);
15820 __ Ld1(v0.V16B(), MemOperand(x10, x11, PostIndex));
15821 // TODO: add other instructions (ld2-4, st1-4) as they become available.
15822 END();
15823
15824 RUN();
15825
15826 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q0);
15827 ASSERT_EQUAL_64(src_tagged + offset_tagged, x10);
15828
15829 TEARDOWN();
15830 }
15831 }
15832}
15833
15834
armvixlc68cb642014-09-25 18:49:30 +010015835TEST(branch_tagged) {
15836 SETUP();
15837 START();
15838
15839 Label loop, loop_entry, done;
15840 __ Adr(x0, &loop);
15841 __ Mov(x1, 0);
15842 __ B(&loop_entry);
15843
15844 __ Bind(&loop);
15845 __ Add(x1, x1, 1); // Count successful jumps.
15846
15847 // Advance to the next tag, then bail out if we've come back around to tag 0.
15848 __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
15849 __ Tst(x0, kAddressTagMask);
15850 __ B(eq, &done);
15851
15852 __ Bind(&loop_entry);
15853 __ Br(x0);
15854
15855 __ Bind(&done);
15856
15857 END();
15858 RUN();
15859
15860 ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
15861
15862 TEARDOWN();
15863}
15864
15865
15866TEST(branch_and_link_tagged) {
15867 SETUP();
15868 START();
15869
15870 Label loop, loop_entry, done;
15871 __ Adr(x0, &loop);
15872 __ Mov(x1, 0);
15873 __ B(&loop_entry);
15874
15875 __ Bind(&loop);
15876
15877 // Bail out (before counting a successful jump) if lr appears to be tagged.
15878 __ Tst(lr, kAddressTagMask);
15879 __ B(ne, &done);
15880
15881 __ Add(x1, x1, 1); // Count successful jumps.
15882
15883 // Advance to the next tag, then bail out if we've come back around to tag 0.
15884 __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
15885 __ Tst(x0, kAddressTagMask);
15886 __ B(eq, &done);
15887
15888 __ Bind(&loop_entry);
15889 __ Blr(x0);
15890
15891 __ Bind(&done);
15892
15893 END();
15894 RUN();
15895
15896 ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
15897
15898 TEARDOWN();
15899}
15900
15901
15902TEST(branch_tagged_and_adr_adrp) {
15903 SETUP_CUSTOM(BUF_SIZE, PageOffsetDependentCode);
15904 START();
15905
15906 Label loop, loop_entry, done;
15907 __ Adr(x0, &loop);
15908 __ Mov(x1, 0);
15909 __ B(&loop_entry);
15910
15911 __ Bind(&loop);
15912
15913 // Bail out (before counting a successful jump) if `adr x10, ...` is tagged.
15914 __ Adr(x10, &done);
15915 __ Tst(x10, kAddressTagMask);
15916 __ B(ne, &done);
15917
15918 // Bail out (before counting a successful jump) if `adrp x11, ...` is tagged.
15919 __ Adrp(x11, &done);
15920 __ Tst(x11, kAddressTagMask);
15921 __ B(ne, &done);
15922
15923 __ Add(x1, x1, 1); // Count successful iterations.
15924
15925 // Advance to the next tag, then bail out if we've come back around to tag 0.
15926 __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
15927 __ Tst(x0, kAddressTagMask);
15928 __ B(eq, &done);
15929
15930 __ Bind(&loop_entry);
15931 __ Br(x0);
15932
15933 __ Bind(&done);
15934
15935 END();
15936 RUN();
15937
15938 ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
15939
15940 TEARDOWN();
15941}
15942
armvixl5289c592015-03-02 13:52:04 +000015943TEST(neon_3same_addp) {
15944 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015945
armvixl5289c592015-03-02 13:52:04 +000015946 START();
15947
15948 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
15949 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
15950 __ Addp(v16.V16B(), v0.V16B(), v1.V16B());
15951
15952 END();
15953
15954 RUN();
15955 ASSERT_EQUAL_128(0x00ff54ffff54aaff, 0xffffffffffffffff, q16);
15956 TEARDOWN();
15957}
15958
15959TEST(neon_3same_sqdmulh_sqrdmulh) {
15960 SETUP();
15961
15962 START();
15963
15964 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000040004008000);
15965 __ Movi(v1.V2D(), 0x0000000000000000, 0x0000002000108000);
15966 __ Movi(v2.V2D(), 0x0400000080000000, 0x0400000080000000);
15967 __ Movi(v3.V2D(), 0x0000002080000000, 0x0000001080000000);
15968
15969 __ Sqdmulh(v16.V4H(), v0.V4H(), v1.V4H());
15970 __ Sqdmulh(v17.V4S(), v2.V4S(), v3.V4S());
15971 __ Sqdmulh(h18, h0, h1);
15972 __ Sqdmulh(s19, s2, s3);
15973
15974 __ Sqrdmulh(v20.V4H(), v0.V4H(), v1.V4H());
15975 __ Sqrdmulh(v21.V4S(), v2.V4S(), v3.V4S());
15976 __ Sqrdmulh(h22, h0, h1);
15977 __ Sqrdmulh(s23, s2, s3);
15978
15979 END();
15980
15981 RUN();
15982 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000100007fff, q16);
15983 ASSERT_EQUAL_128(0x000000017fffffff, 0x000000007fffffff, q17);
15984 ASSERT_EQUAL_128(0, 0x7fff, q18);
15985 ASSERT_EQUAL_128(0, 0x7fffffff, q19);
15986 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000100017fff, q20);
15987 ASSERT_EQUAL_128(0x000000017fffffff, 0x000000017fffffff, q21);
15988 ASSERT_EQUAL_128(0, 0x7fff, q22);
15989 ASSERT_EQUAL_128(0, 0x7fffffff, q23);
15990 TEARDOWN();
15991}
15992
15993TEST(neon_byelement_sqdmulh_sqrdmulh) {
15994 SETUP();
15995
15996 START();
15997
15998 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000040004008000);
15999 __ Movi(v1.V2D(), 0x0000000000000000, 0x0000002000108000);
16000 __ Movi(v2.V2D(), 0x0400000080000000, 0x0400000080000000);
16001 __ Movi(v3.V2D(), 0x0000002080000000, 0x0000001080000000);
16002
16003 __ Sqdmulh(v16.V4H(), v0.V4H(), v1.H(), 1);
16004 __ Sqdmulh(v17.V4S(), v2.V4S(), v3.S(), 1);
16005 __ Sqdmulh(h18, h0, v1.H(), 0);
16006 __ Sqdmulh(s19, s2, v3.S(), 0);
16007
16008 __ Sqrdmulh(v20.V4H(), v0.V4H(), v1.H(), 1);
16009 __ Sqrdmulh(v21.V4S(), v2.V4S(), v3.S(), 1);
16010 __ Sqrdmulh(h22, h0, v1.H(), 0);
16011 __ Sqrdmulh(s23, s2, v3.S(), 0);
16012
16013 END();
16014
16015 RUN();
16016 ASSERT_EQUAL_128(0x0000000000000000, 0x000000000000fff0, q16);
16017 ASSERT_EQUAL_128(0x00000000fffffff0, 0x00000000fffffff0, q17);
16018 ASSERT_EQUAL_128(0, 0x7fff, q18);
16019 ASSERT_EQUAL_128(0, 0x7fffffff, q19);
16020 ASSERT_EQUAL_128(0x0000000000000000, 0x000000010001fff0, q20);
16021 ASSERT_EQUAL_128(0x00000001fffffff0, 0x00000001fffffff0, q21);
16022 ASSERT_EQUAL_128(0, 0x7fff, q22);
16023 ASSERT_EQUAL_128(0, 0x7fffffff, q23);
16024 TEARDOWN();
16025}
16026
16027
16028TEST(neon_2regmisc_saddlp) {
16029 SETUP();
16030
16031 START();
16032
16033 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16034
16035 __ Saddlp(v16.V8H(), v0.V16B());
16036 __ Saddlp(v17.V4H(), v0.V8B());
16037
16038 __ Saddlp(v18.V4S(), v0.V8H());
16039 __ Saddlp(v19.V2S(), v0.V4H());
16040
16041 __ Saddlp(v20.V2D(), v0.V4S());
16042 __ Saddlp(v21.V1D(), v0.V2S());
16043
16044 END();
16045
16046 RUN();
16047 ASSERT_EQUAL_128(0x0080ffffff010080, 0xff01ffff0080ff01, q16);
16048 ASSERT_EQUAL_128(0x0000000000000000, 0xff01ffff0080ff01, q17);
16049 ASSERT_EQUAL_128(0x0000800000000081, 0xffff7f81ffff8200, q18);
16050 ASSERT_EQUAL_128(0x0000000000000000, 0xffff7f81ffff8200, q19);
16051 ASSERT_EQUAL_128(0x0000000000818000, 0xffffffff82017f81, q20);
16052 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffff82017f81, q21);
16053 TEARDOWN();
16054}
16055
16056TEST(neon_2regmisc_uaddlp) {
16057 SETUP();
16058
16059 START();
16060
16061 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16062
16063 __ Uaddlp(v16.V8H(), v0.V16B());
16064 __ Uaddlp(v17.V4H(), v0.V8B());
16065
16066 __ Uaddlp(v18.V4S(), v0.V8H());
16067 __ Uaddlp(v19.V2S(), v0.V4H());
16068
16069 __ Uaddlp(v20.V2D(), v0.V4S());
16070 __ Uaddlp(v21.V1D(), v0.V2S());
16071
16072 END();
16073
16074 RUN();
16075 ASSERT_EQUAL_128(0x008000ff01010080, 0x010100ff00800101, q16);
16076 ASSERT_EQUAL_128(0x0000000000000000, 0x010100ff00800101, q17);
16077 ASSERT_EQUAL_128(0x0000800000010081, 0x00017f8100008200, q18);
16078 ASSERT_EQUAL_128(0x0000000000000000, 0x00017f8100008200, q19);
16079 ASSERT_EQUAL_128(0x0000000100818000, 0x0000000082017f81, q20);
16080 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000082017f81, q21);
16081 TEARDOWN();
16082}
16083
16084TEST(neon_2regmisc_sadalp) {
16085 SETUP();
16086
16087 START();
16088
16089 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16090 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
16091 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
16092 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
16093 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
16094
16095 __ Mov(v16.V16B(), v1.V16B());
16096 __ Mov(v17.V16B(), v1.V16B());
16097 __ Sadalp(v16.V8H(), v0.V16B());
16098 __ Sadalp(v17.V4H(), v0.V8B());
16099
16100 __ Mov(v18.V16B(), v2.V16B());
16101 __ Mov(v19.V16B(), v2.V16B());
16102 __ Sadalp(v18.V4S(), v1.V8H());
16103 __ Sadalp(v19.V2S(), v1.V4H());
16104
16105 __ Mov(v20.V16B(), v3.V16B());
16106 __ Mov(v21.V16B(), v4.V16B());
16107 __ Sadalp(v20.V2D(), v2.V4S());
16108 __ Sadalp(v21.V1D(), v2.V2S());
16109
16110 END();
16111
16112 RUN();
16113 ASSERT_EQUAL_128(0x80808000ff000080, 0xff00ffff00817f00, q16);
16114 ASSERT_EQUAL_128(0x0000000000000000, 0xff00ffff00817f00, q17);
16115 ASSERT_EQUAL_128(0x7fff0001fffffffe, 0xffffffff80007fff, q18);
16116 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffff80007fff, q19);
16117 ASSERT_EQUAL_128(0x7fffffff80000000, 0x800000007ffffffe, q20);
16118 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
16119 TEARDOWN();
16120}
16121
16122TEST(neon_2regmisc_uadalp) {
16123 SETUP();
16124
16125 START();
16126
16127 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16128 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
16129 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
16130 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
16131 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
16132
16133 __ Mov(v16.V16B(), v1.V16B());
16134 __ Mov(v17.V16B(), v1.V16B());
16135 __ Uadalp(v16.V8H(), v0.V16B());
16136 __ Uadalp(v17.V4H(), v0.V8B());
16137
16138 __ Mov(v18.V16B(), v2.V16B());
16139 __ Mov(v19.V16B(), v2.V16B());
16140 __ Uadalp(v18.V4S(), v1.V8H());
16141 __ Uadalp(v19.V2S(), v1.V4H());
16142
16143 __ Mov(v20.V16B(), v3.V16B());
16144 __ Mov(v21.V16B(), v4.V16B());
16145 __ Uadalp(v20.V2D(), v2.V4S());
16146 __ Uadalp(v21.V1D(), v2.V2S());
16147
16148 END();
16149
16150 RUN();
16151 ASSERT_EQUAL_128(0x8080810001000080, 0x010000ff00818100, q16);
16152 ASSERT_EQUAL_128(0x0000000000000000, 0x010000ff00818100, q17);
16153 ASSERT_EQUAL_128(0x800100010000fffe, 0x0000ffff80007fff, q18);
16154 ASSERT_EQUAL_128(0x0000000000000000, 0x0000ffff80007fff, q19);
16155 ASSERT_EQUAL_128(0x8000000180000000, 0x800000007ffffffe, q20);
16156 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
16157 TEARDOWN();
16158}
16159
16160TEST(neon_3same_mul) {
16161 SETUP();
16162
16163 START();
16164
16165 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16166 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16167 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16168 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16169
16170 __ Mla(v16.V16B(), v0.V16B(), v1.V16B());
16171 __ Mls(v17.V16B(), v0.V16B(), v1.V16B());
16172 __ Mul(v18.V16B(), v0.V16B(), v1.V16B());
16173
16174 END();
16175
16176 RUN();
16177 ASSERT_EQUAL_128(0x0102757605b1b208, 0x5f0a61450db90f56, q16);
16178 ASSERT_EQUAL_128(0x01029192055b5c08, 0xb30ab5d30d630faa, q17);
16179 ASSERT_EQUAL_128(0x0000727200abab00, 0x5600563900ab0056, q18);
16180 TEARDOWN();
16181}
16182
16183
16184
16185TEST(neon_3same_absdiff) {
16186 SETUP();
16187
16188 START();
16189
16190 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16191 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16192 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16193 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16194
16195 __ Saba(v16.V16B(), v0.V16B(), v1.V16B());
16196 __ Uaba(v17.V16B(), v0.V16B(), v1.V16B());
16197 __ Sabd(v18.V16B(), v0.V16B(), v1.V16B());
16198 __ Uabd(v19.V16B(), v0.V16B(), v1.V16B());
16199
16200 END();
16201
16202 RUN();
16203 ASSERT_EQUAL_128(0x0202aeaf065c5d5e, 0x5e5f600c62646455, q16);
16204 ASSERT_EQUAL_128(0x0002585904b0b1b2, 0x5e5f600c62b86455, q17);
16205 ASSERT_EQUAL_128(0x0100abab01565656, 0x5555550055565555, q18);
16206 ASSERT_EQUAL_128(0xff005555ffaaaaaa, 0x5555550055aa5555, q19);
16207 TEARDOWN();
16208}
16209
16210
16211TEST(neon_byelement_mul) {
16212 SETUP();
16213
16214 START();
16215
16216 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16217 __ Movi(v1.V2D(), 0x000155aaff55ff00, 0xaa55ff55555500ff);
16218
16219
16220 __ Mul(v16.V4H(), v0.V4H(), v1.H(), 0);
16221 __ Mul(v17.V8H(), v0.V8H(), v1.H(), 7);
16222 __ Mul(v18.V2S(), v0.V2S(), v1.S(), 0);
16223 __ Mul(v19.V4S(), v0.V4S(), v1.S(), 3);
16224
16225 __ Movi(v20.V2D(), 0x0000000000000000, 0x0001000200030004);
16226 __ Movi(v21.V2D(), 0x0005000600070008, 0x0001000200030004);
16227 __ Mla(v20.V4H(), v0.V4H(), v1.H(), 0);
16228 __ Mla(v21.V8H(), v0.V8H(), v1.H(), 7);
16229
16230 __ Movi(v22.V2D(), 0x0000000000000000, 0x0000000200000004);
16231 __ Movi(v23.V2D(), 0x0000000600000008, 0x0000000200000004);
16232 __ Mla(v22.V2S(), v0.V2S(), v1.S(), 0);
16233 __ Mla(v23.V4S(), v0.V4S(), v1.S(), 3);
16234
16235 __ Movi(v24.V2D(), 0x0000000000000000, 0x0100aaabfe015456);
16236 __ Movi(v25.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16237 __ Mls(v24.V4H(), v0.V4H(), v1.H(), 0);
16238 __ Mls(v25.V8H(), v0.V8H(), v1.H(), 7);
16239
16240 __ Movi(v26.V2D(), 0x0000000000000000, 0xc8e2aaabe1c85456);
16241 __ Movi(v27.V2D(), 0x39545572c6aa54e4, 0x39545572c6aa54e4);
16242 __ Mls(v26.V2S(), v0.V2S(), v1.S(), 0);
16243 __ Mls(v27.V4S(), v0.V4S(), v1.S(), 3);
16244
16245 END();
16246
16247 RUN();
16248 ASSERT_EQUAL_128(0x0000000000000000, 0x0100aaabfe015456, q16);
16249 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q17);
16250 ASSERT_EQUAL_128(0x0000000000000000, 0xc8e2aaabe1c85456, q18);
16251 ASSERT_EQUAL_128(0x39545572c6aa54e4, 0x39545572c6aa54e4, q19);
16252
16253 ASSERT_EQUAL_128(0x0000000000000000, 0x0101aaadfe04545a, q20);
16254 ASSERT_EQUAL_128(0xff05aa5b010655b2, 0xff01aa57010255ae, q21);
16255 ASSERT_EQUAL_128(0x0000000000000000, 0xc8e2aaade1c8545a, q22);
16256 ASSERT_EQUAL_128(0x39545578c6aa54ec, 0x39545574c6aa54e8, q23);
16257
16258 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16259 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16260 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q26);
16261 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q27);
16262 TEARDOWN();
16263}
16264
16265
16266TEST(neon_byelement_mull) {
16267 SETUP();
16268
16269 START();
16270
16271 __ Movi(v0.V2D(), 0xaa55ff55555500ff, 0xff00aa5500ff55aa);
16272 __ Movi(v1.V2D(), 0x000155aaff55ff00, 0xaa55ff55555500ff);
16273
16274
16275 __ Smull(v16.V4S(), v0.V4H(), v1.H(), 7);
16276 __ Smull2(v17.V4S(), v0.V8H(), v1.H(), 0);
16277 __ Umull(v18.V4S(), v0.V4H(), v1.H(), 7);
16278 __ Umull2(v19.V4S(), v0.V8H(), v1.H(), 0);
16279
16280 __ Movi(v20.V2D(), 0x0000000100000002, 0x0000000200000001);
16281 __ Movi(v21.V2D(), 0x0000000100000002, 0x0000000200000001);
16282 __ Movi(v22.V2D(), 0x0000000100000002, 0x0000000200000001);
16283 __ Movi(v23.V2D(), 0x0000000100000002, 0x0000000200000001);
16284
16285 __ Smlal(v20.V4S(), v0.V4H(), v1.H(), 7);
16286 __ Smlal2(v21.V4S(), v0.V8H(), v1.H(), 0);
16287 __ Umlal(v22.V4S(), v0.V4H(), v1.H(), 7);
16288 __ Umlal2(v23.V4S(), v0.V8H(), v1.H(), 0);
16289
16290 __ Movi(v24.V2D(), 0xffffff00ffffaa55, 0x000000ff000055aa);
16291 __ Movi(v25.V2D(), 0xffaaaaabffff55ab, 0x0054ffab0000fe01);
16292 __ Movi(v26.V2D(), 0x0000ff000000aa55, 0x000000ff000055aa);
16293 __ Movi(v27.V2D(), 0x00a9aaab00fe55ab, 0x0054ffab0000fe01);
16294
16295 __ Smlsl(v24.V4S(), v0.V4H(), v1.H(), 7);
16296 __ Smlsl2(v25.V4S(), v0.V8H(), v1.H(), 0);
16297 __ Umlsl(v26.V4S(), v0.V4H(), v1.H(), 7);
16298 __ Umlsl2(v27.V4S(), v0.V8H(), v1.H(), 0);
16299
16300 END();
16301
16302 RUN();
16303
16304 ASSERT_EQUAL_128(0xffffff00ffffaa55, 0x000000ff000055aa, q16);
16305 ASSERT_EQUAL_128(0xffaaaaabffff55ab, 0x0054ffab0000fe01, q17);
16306 ASSERT_EQUAL_128(0x0000ff000000aa55, 0x000000ff000055aa, q18);
16307 ASSERT_EQUAL_128(0x00a9aaab00fe55ab, 0x0054ffab0000fe01, q19);
16308
16309 ASSERT_EQUAL_128(0xffffff01ffffaa57, 0x00000101000055ab, q20);
16310 ASSERT_EQUAL_128(0xffaaaaacffff55ad, 0x0054ffad0000fe02, q21);
16311 ASSERT_EQUAL_128(0x0000ff010000aa57, 0x00000101000055ab, q22);
16312 ASSERT_EQUAL_128(0x00a9aaac00fe55ad, 0x0054ffad0000fe02, q23);
16313
16314 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16315 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16316 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q26);
16317 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q27);
16318
16319 TEARDOWN();
16320}
16321
16322
16323TEST(neon_byelement_sqdmull) {
16324 SETUP();
16325
16326 START();
16327
16328 __ Movi(v0.V2D(), 0xaa55ff55555500ff, 0xff00aa5500ff55aa);
16329 __ Movi(v1.V2D(), 0x000155aaff55ff00, 0xaa55ff55555500ff);
16330
16331 __ Sqdmull(v16.V4S(), v0.V4H(), v1.H(), 7);
16332 __ Sqdmull2(v17.V4S(), v0.V8H(), v1.H(), 0);
16333 __ Sqdmull(s18, h0, v1.H(), 7);
16334
16335 __ Movi(v20.V2D(), 0x0000000100000002, 0x0000000200000001);
16336 __ Movi(v21.V2D(), 0x0000000100000002, 0x0000000200000001);
16337 __ Movi(v22.V2D(), 0x0000000100000002, 0x0000000200000001);
16338
16339 __ Sqdmlal(v20.V4S(), v0.V4H(), v1.H(), 7);
16340 __ Sqdmlal2(v21.V4S(), v0.V8H(), v1.H(), 0);
16341 __ Sqdmlal(s22, h0, v1.H(), 7);
16342
16343 __ Movi(v24.V2D(), 0xfffffe00ffff54aa, 0x000001fe0000ab54);
16344 __ Movi(v25.V2D(), 0xff555556fffeab56, 0x00a9ff560001fc02);
16345 __ Movi(v26.V2D(), 0x0000000000000000, 0x000000000000ab54);
16346
16347 __ Sqdmlsl(v24.V4S(), v0.V4H(), v1.H(), 7);
16348 __ Sqdmlsl2(v25.V4S(), v0.V8H(), v1.H(), 0);
16349 __ Sqdmlsl(s26, h0, v1.H(), 7);
16350
16351 END();
16352
16353 RUN();
16354
16355 ASSERT_EQUAL_128(0xfffffe00ffff54aa, 0x000001fe0000ab54, q16);
16356 ASSERT_EQUAL_128(0xff555556fffeab56, 0x00a9ff560001fc02, q17);
16357 ASSERT_EQUAL_128(0, 0x0000ab54, q18);
16358
16359 ASSERT_EQUAL_128(0xfffffe01ffff54ac, 0x000002000000ab55, q20);
16360 ASSERT_EQUAL_128(0xff555557fffeab58, 0x00a9ff580001fc03, q21);
16361 ASSERT_EQUAL_128(0, 0x0000ab55, q22);
16362
16363 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16364 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16365 ASSERT_EQUAL_128(0, 0x00000000, q26);
16366
16367 TEARDOWN();
16368}
16369
16370
16371TEST(neon_3diff_absdiff) {
16372 SETUP();
16373
16374 START();
16375
16376 __ Movi(v0.V2D(), 0xff00aa5500ff55ab, 0xff00aa5500ff55aa);
16377 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16378 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16379 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16380 __ Movi(v18.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16381 __ Movi(v19.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16382
16383 __ Sabal(v16.V8H(), v0.V8B(), v1.V8B());
16384 __ Uabal(v17.V8H(), v0.V8B(), v1.V8B());
16385 __ Sabal2(v18.V8H(), v0.V16B(), v1.V16B());
16386 __ Uabal2(v19.V8H(), v0.V16B(), v1.V16B());
16387
16388 END();
16389
16390 RUN();
16391 ASSERT_EQUAL_128(0x01570359055b0708, 0x095f0b620d630f55, q16);
16392 ASSERT_EQUAL_128(0x01570359055b0708, 0x095f0bb60d630f55, q17);
16393 ASSERT_EQUAL_128(0x0103030405b107b3, 0x090b0b620d640f55, q18);
16394 ASSERT_EQUAL_128(0x02010304055b075d, 0x0a090bb60db80fab, q19);
16395 TEARDOWN();
16396}
16397
16398
16399TEST(neon_3diff_sqdmull) {
16400 SETUP();
16401
16402 START();
16403
16404 __ Movi(v0.V2D(), 0x7fff7fff80008000, 0x80007fff7fff8000);
16405 __ Movi(v1.V2D(), 0x80007fff7fff8000, 0x7fff7fff80008000);
16406 __ Movi(v2.V2D(), 0x800000007fffffff, 0x7fffffff80000000);
16407 __ Movi(v3.V2D(), 0x8000000080000000, 0x8000000080000000);
16408
16409 __ Sqdmull(v16.V4S(), v0.V4H(), v1.V4H());
16410 __ Sqdmull2(v17.V4S(), v0.V8H(), v1.V8H());
16411 __ Sqdmull(v18.V2D(), v2.V2S(), v3.V2S());
16412 __ Sqdmull2(v19.V2D(), v2.V4S(), v3.V4S());
16413 __ Sqdmull(s20, h0, h1);
16414 __ Sqdmull(d21, s2, s3);
16415
16416 END();
16417
16418 RUN();
16419 ASSERT_EQUAL_128(0x800100007ffe0002, 0x800100007fffffff, q16);
16420 ASSERT_EQUAL_128(0x800100007ffe0002, 0x800100007fffffff, q17);
16421 ASSERT_EQUAL_128(0x8000000100000000, 0x7fffffffffffffff, q18);
16422 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x8000000100000000, q19);
16423 ASSERT_EQUAL_128(0, 0x7fffffff, q20);
16424 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q21);
16425 TEARDOWN();
16426}
16427
16428
16429TEST(neon_3diff_sqdmlal) {
16430 SETUP();
16431
16432 START();
16433
16434 __ Movi(v0.V2D(), 0x7fff7fff80008000, 0x80007fff7fff8000);
16435 __ Movi(v1.V2D(), 0x80007fff7fff8000, 0x7fff7fff80008000);
16436 __ Movi(v2.V2D(), 0x800000007fffffff, 0x7fffffff80000000);
16437 __ Movi(v3.V2D(), 0x8000000080000000, 0x8000000080000000);
16438
16439 __ Movi(v16.V2D(), 0xffffffff00000001, 0x8fffffff00000001);
16440 __ Movi(v17.V2D(), 0x00000001ffffffff, 0x00000001ffffffff);
16441 __ Movi(v18.V2D(), 0x8000000000000001, 0x0000000000000001);
16442 __ Movi(v19.V2D(), 0xffffffffffffffff, 0x7fffffffffffffff);
16443 __ Movi(v20.V2D(), 0, 0x00000001);
16444 __ Movi(v21.V2D(), 0, 0x00000001);
16445
16446 __ Sqdmlal(v16.V4S(), v0.V4H(), v1.V4H());
16447 __ Sqdmlal2(v17.V4S(), v0.V8H(), v1.V8H());
16448 __ Sqdmlal(v18.V2D(), v2.V2S(), v3.V2S());
16449 __ Sqdmlal2(v19.V2D(), v2.V4S(), v3.V4S());
16450 __ Sqdmlal(s20, h0, h1);
16451 __ Sqdmlal(d21, s2, s3);
16452
16453 END();
16454
16455 RUN();
16456 ASSERT_EQUAL_128(0x8000ffff7ffe0003, 0x800000007fffffff, q16);
16457 ASSERT_EQUAL_128(0x800100017ffe0001, 0x800100017ffffffe, q17);
16458 ASSERT_EQUAL_128(0x8000000000000000, 0x7fffffffffffffff, q18);
16459 ASSERT_EQUAL_128(0x7ffffffffffffffe, 0x00000000ffffffff, q19);
16460 ASSERT_EQUAL_128(0, 0x7fffffff, q20);
16461 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q21);
16462 TEARDOWN();
16463}
16464
16465
16466TEST(neon_3diff_sqdmlsl) {
16467 SETUP();
16468
16469 START();
16470
16471 __ Movi(v0.V2D(), 0x7fff7fff80008000, 0x80007fff7fff8000);
16472 __ Movi(v1.V2D(), 0x80007fff7fff8000, 0x7fff7fff80008000);
16473 __ Movi(v2.V2D(), 0x800000007fffffff, 0x7fffffff80000000);
16474 __ Movi(v3.V2D(), 0x8000000080000000, 0x8000000080000000);
16475
16476 __ Movi(v16.V2D(), 0xffffffff00000001, 0x7ffffffe80000001);
16477 __ Movi(v17.V2D(), 0x00000001ffffffff, 0x7ffffffe00000001);
16478 __ Movi(v18.V2D(), 0x8000000000000001, 0x8000000000000001);
16479 __ Movi(v19.V2D(), 0xfffffffffffffffe, 0x7fffffffffffffff);
16480 __ Movi(v20.V2D(), 0, 0x00000001);
16481 __ Movi(v21.V2D(), 0, 0x00000001);
16482
16483 __ Sqdmlsl(v16.V4S(), v0.V4H(), v1.V4H());
16484 __ Sqdmlsl2(v17.V4S(), v0.V8H(), v1.V8H());
16485 __ Sqdmlsl(v18.V2D(), v2.V2S(), v3.V2S());
16486 __ Sqdmlsl2(v19.V2D(), v2.V4S(), v3.V4S());
16487 __ Sqdmlsl(s20, h0, h1);
16488 __ Sqdmlsl(d21, s2, s3);
16489
16490 END();
16491
16492 RUN();
16493 ASSERT_EQUAL_128(0x7ffeffff8001ffff, 0x7fffffff80000000, q16);
16494 ASSERT_EQUAL_128(0x7fff00018001fffd, 0x7fffffff80000002, q17);
16495 ASSERT_EQUAL_128(0xffffffff00000001, 0x8000000000000000, q18);
16496 ASSERT_EQUAL_128(0x8000000000000000, 0x7fffffffffffffff, q19);
16497 ASSERT_EQUAL_128(0, 0x80000002, q20);
16498 ASSERT_EQUAL_128(0, 0x8000000000000002, q21);
16499
16500 TEARDOWN();
16501}
16502
16503
16504TEST(neon_3diff_mla) {
16505 SETUP();
16506
16507 START();
16508
16509 __ Movi(v0.V2D(), 0xff00aa5500ff55ab, 0xff00aa5500ff55aa);
16510 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16511 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16512 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16513 __ Movi(v18.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16514 __ Movi(v19.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16515
16516 __ Smlal(v16.V8H(), v0.V8B(), v1.V8B());
16517 __ Umlal(v17.V8H(), v0.V8B(), v1.V8B());
16518 __ Smlal2(v18.V8H(), v0.V16B(), v1.V16B());
16519 __ Umlal2(v19.V8H(), v0.V16B(), v1.V16B());
16520
16521 END();
16522
16523 RUN();
16524 ASSERT_EQUAL_128(0x01580304055c2341, 0x090a0ab70d0e0f56, q16);
16525 ASSERT_EQUAL_128(0xaa580304ae5c2341, 0x090a5fb70d0eb856, q17);
16526 ASSERT_EQUAL_128(0x01020304e878ea7a, 0x090a0ab70cb90f00, q18);
16527 ASSERT_EQUAL_128(0x010203043d783f7a, 0x090a5fb761b90f00, q19);
16528 TEARDOWN();
16529}
16530
16531
16532TEST(neon_3diff_mls) {
16533 SETUP();
16534
16535 START();
16536
16537 __ Movi(v0.V2D(), 0xff00aa5500ff55ab, 0xff00aa5500ff55aa);
16538 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16539 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16540 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16541 __ Movi(v18.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16542 __ Movi(v19.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16543
16544 __ Smlsl(v16.V8H(), v0.V8B(), v1.V8B());
16545 __ Umlsl(v17.V8H(), v0.V8B(), v1.V8B());
16546 __ Smlsl2(v18.V8H(), v0.V16B(), v1.V16B());
16547 __ Umlsl2(v19.V8H(), v0.V16B(), v1.V16B());
16548
16549 END();
16550
16551 RUN();
16552 ASSERT_EQUAL_128(0x00ac030404b0eacf, 0x090a0b610d0e0eaa, q16);
16553 ASSERT_EQUAL_128(0x57ac03045bb0eacf, 0x090ab6610d0e65aa, q17);
16554 ASSERT_EQUAL_128(0x0102030421942396, 0x090a0b610d630f00, q18);
16555 ASSERT_EQUAL_128(0x01020304cc94ce96, 0x090ab661b8630f00, q19);
16556 TEARDOWN();
16557}
16558
16559
16560TEST(neon_3same_compare) {
16561 SETUP();
16562
16563 START();
16564
16565 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16566 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16567
16568 __ Cmeq(v16.V16B(), v0.V16B(), v0.V16B());
16569 __ Cmeq(v17.V16B(), v0.V16B(), v1.V16B());
16570 __ Cmge(v18.V16B(), v0.V16B(), v0.V16B());
16571 __ Cmge(v19.V16B(), v0.V16B(), v1.V16B());
16572 __ Cmgt(v20.V16B(), v0.V16B(), v0.V16B());
16573 __ Cmgt(v21.V16B(), v0.V16B(), v1.V16B());
16574 __ Cmhi(v22.V16B(), v0.V16B(), v0.V16B());
16575 __ Cmhi(v23.V16B(), v0.V16B(), v1.V16B());
16576 __ Cmhs(v24.V16B(), v0.V16B(), v0.V16B());
16577 __ Cmhs(v25.V16B(), v0.V16B(), v1.V16B());
16578
16579 END();
16580
16581 RUN();
16582 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q16);
16583 ASSERT_EQUAL_128(0x00ff000000000000, 0x000000ff00000000, q17);
16584 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q18);
16585 ASSERT_EQUAL_128(0x00ff00ffff00ff00, 0xff0000ff0000ff00, q19);
16586 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
16587 ASSERT_EQUAL_128(0x000000ffff00ff00, 0xff0000000000ff00, q21);
16588 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q22);
16589 ASSERT_EQUAL_128(0xff00ff0000ff00ff, 0xff00000000ffff00, q23);
16590 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q24);
16591 ASSERT_EQUAL_128(0xffffff0000ff00ff, 0xff0000ff00ffff00, q25);
16592 TEARDOWN();
16593}
16594
16595
16596TEST(neon_3same_scalar_compare) {
16597 SETUP();
16598
16599 START();
16600
16601 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16602 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16603
16604 __ Cmeq(d16, d0, d0);
16605 __ Cmeq(d17, d0, d1);
16606 __ Cmeq(d18, d1, d0);
16607 __ Cmge(d19, d0, d0);
16608 __ Cmge(d20, d0, d1);
16609 __ Cmge(d21, d1, d0);
16610 __ Cmgt(d22, d0, d0);
16611 __ Cmgt(d23, d0, d1);
16612 __ Cmhi(d24, d0, d0);
16613 __ Cmhi(d25, d0, d1);
16614 __ Cmhs(d26, d0, d0);
16615 __ Cmhs(d27, d0, d1);
16616 __ Cmhs(d28, d1, d0);
16617
16618 END();
16619
16620 RUN();
16621
16622 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q16);
16623 ASSERT_EQUAL_128(0, 0x0000000000000000, q17);
16624 ASSERT_EQUAL_128(0, 0x0000000000000000, q18);
16625 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
16626 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q20);
16627 ASSERT_EQUAL_128(0, 0x0000000000000000, q21);
16628 ASSERT_EQUAL_128(0, 0x0000000000000000, q22);
16629 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q23);
16630 ASSERT_EQUAL_128(0, 0x0000000000000000, q24);
16631 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q25);
16632 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q26);
16633 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q27);
16634 ASSERT_EQUAL_128(0, 0x0000000000000000, q28);
16635
16636 TEARDOWN();
16637}
16638
16639TEST(neon_2regmisc_fcmeq) {
16640 SETUP();
16641
16642 START();
16643
16644 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16645 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16646 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16647 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16648
16649 __ Fcmeq(s16, s0, 0.0);
16650 __ Fcmeq(s17, s1, 0.0);
16651 __ Fcmeq(s18, s2, 0.0);
16652 __ Fcmeq(d19, d0, 0.0);
16653 __ Fcmeq(d20, d1, 0.0);
16654 __ Fcmeq(d21, d2, 0.0);
16655 __ Fcmeq(v22.V2S(), v0.V2S(), 0.0);
16656 __ Fcmeq(v23.V4S(), v1.V4S(), 0.0);
16657 __ Fcmeq(v24.V2D(), v1.V2D(), 0.0);
16658 __ Fcmeq(v25.V2D(), v2.V2D(), 0.0);
16659
16660 END();
16661
16662 RUN();
16663 ASSERT_EQUAL_128(0, 0xffffffff, q16);
16664 ASSERT_EQUAL_128(0, 0x00000000, q17);
16665 ASSERT_EQUAL_128(0, 0x00000000, q18);
16666 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
16667 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16668 ASSERT_EQUAL_128(0, 0x0000000000000000, q21);
16669 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q22);
16670 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16671 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16672 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16673 TEARDOWN();
16674}
16675
16676TEST(neon_2regmisc_fcmge) {
16677 SETUP();
16678
16679 START();
16680
16681 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16682 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16683 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16684 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16685
16686 __ Fcmge(s16, s0, 0.0);
16687 __ Fcmge(s17, s1, 0.0);
16688 __ Fcmge(s18, s2, 0.0);
16689 __ Fcmge(d19, d0, 0.0);
16690 __ Fcmge(d20, d1, 0.0);
16691 __ Fcmge(d21, d3, 0.0);
16692 __ Fcmge(v22.V2S(), v0.V2S(), 0.0);
16693 __ Fcmge(v23.V4S(), v1.V4S(), 0.0);
16694 __ Fcmge(v24.V2D(), v1.V2D(), 0.0);
16695 __ Fcmge(v25.V2D(), v3.V2D(), 0.0);
16696
16697 END();
16698
16699 RUN();
16700 ASSERT_EQUAL_128(0, 0xffffffff, q16);
16701 ASSERT_EQUAL_128(0, 0x00000000, q17);
16702 ASSERT_EQUAL_128(0, 0x00000000, q18);
16703 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
16704 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16705 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
16706 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q22);
16707 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16708 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16709 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
16710 TEARDOWN();
16711}
16712
16713
16714TEST(neon_2regmisc_fcmgt) {
16715 SETUP();
16716
16717 START();
16718
16719 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16720 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16721 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16722 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16723
16724 __ Fcmgt(s16, s0, 0.0);
16725 __ Fcmgt(s17, s1, 0.0);
16726 __ Fcmgt(s18, s2, 0.0);
16727 __ Fcmgt(d19, d0, 0.0);
16728 __ Fcmgt(d20, d1, 0.0);
16729 __ Fcmgt(d21, d3, 0.0);
16730 __ Fcmgt(v22.V2S(), v0.V2S(), 0.0);
16731 __ Fcmgt(v23.V4S(), v1.V4S(), 0.0);
16732 __ Fcmgt(v24.V2D(), v1.V2D(), 0.0);
16733 __ Fcmgt(v25.V2D(), v3.V2D(), 0.0);
16734
16735 END();
16736
16737 RUN();
16738 ASSERT_EQUAL_128(0, 0x00000000, q16);
16739 ASSERT_EQUAL_128(0, 0x00000000, q17);
16740 ASSERT_EQUAL_128(0, 0x00000000, q18);
16741 ASSERT_EQUAL_128(0, 0x0000000000000000, q19);
16742 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16743 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
16744 ASSERT_EQUAL_128(0, 0x0000000000000000, q22);
16745 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16746 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16747 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
16748 TEARDOWN();
16749}
16750
16751TEST(neon_2regmisc_fcmle) {
16752 SETUP();
16753
16754 START();
16755
16756 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16757 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16758 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16759 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16760
16761 __ Fcmle(s16, s0, 0.0);
16762 __ Fcmle(s17, s1, 0.0);
16763 __ Fcmle(s18, s3, 0.0);
16764 __ Fcmle(d19, d0, 0.0);
16765 __ Fcmle(d20, d1, 0.0);
16766 __ Fcmle(d21, d2, 0.0);
16767 __ Fcmle(v22.V2S(), v0.V2S(), 0.0);
16768 __ Fcmle(v23.V4S(), v1.V4S(), 0.0);
16769 __ Fcmle(v24.V2D(), v1.V2D(), 0.0);
16770 __ Fcmle(v25.V2D(), v2.V2D(), 0.0);
16771
16772 END();
16773
16774 RUN();
16775 ASSERT_EQUAL_128(0, 0xffffffff, q16);
16776 ASSERT_EQUAL_128(0, 0x00000000, q17);
16777 ASSERT_EQUAL_128(0, 0x00000000, q18);
16778 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
16779 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16780 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
16781 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q22);
16782 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16783 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16784 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
16785 TEARDOWN();
16786}
16787
16788
16789TEST(neon_2regmisc_fcmlt) {
16790 SETUP();
16791
16792 START();
16793
16794 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16795 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16796 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16797 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16798
16799 __ Fcmlt(s16, s0, 0.0);
16800 __ Fcmlt(s17, s1, 0.0);
16801 __ Fcmlt(s18, s3, 0.0);
16802 __ Fcmlt(d19, d0, 0.0);
16803 __ Fcmlt(d20, d1, 0.0);
16804 __ Fcmlt(d21, d2, 0.0);
16805 __ Fcmlt(v22.V2S(), v0.V2S(), 0.0);
16806 __ Fcmlt(v23.V4S(), v1.V4S(), 0.0);
16807 __ Fcmlt(v24.V2D(), v1.V2D(), 0.0);
16808 __ Fcmlt(v25.V2D(), v2.V2D(), 0.0);
16809
16810 END();
16811
16812 RUN();
16813 ASSERT_EQUAL_128(0, 0x00000000, q16);
16814 ASSERT_EQUAL_128(0, 0x00000000, q17);
16815 ASSERT_EQUAL_128(0, 0x00000000, q18);
16816 ASSERT_EQUAL_128(0, 0x0000000000000000, q19);
16817 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16818 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
16819 ASSERT_EQUAL_128(0, 0x0000000000000000, q22);
16820 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16821 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16822 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
16823 TEARDOWN();
16824}
16825
16826TEST(neon_2regmisc_cmeq) {
16827 SETUP();
16828
16829 START();
16830
16831 __ Movi(v0.V2D(), 0x0001000200030004, 0x0000000000000000);
16832 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
16833
16834 __ Cmeq(v16.V8B(), v1.V8B(), 0);
16835 __ Cmeq(v17.V16B(), v1.V16B(), 0);
16836 __ Cmeq(v18.V4H(), v1.V4H(), 0);
16837 __ Cmeq(v19.V8H(), v1.V8H(), 0);
16838 __ Cmeq(v20.V2S(), v0.V2S(), 0);
16839 __ Cmeq(v21.V4S(), v0.V4S(), 0);
16840 __ Cmeq(d22, d0, 0);
16841 __ Cmeq(d23, d1, 0);
16842 __ Cmeq(v24.V2D(), v0.V2D(), 0);
16843
16844 END();
16845
16846 RUN();
16847 ASSERT_EQUAL_128(0x0000000000000000, 0xffff00000000ff00, q16);
16848 ASSERT_EQUAL_128(0xffff0000000000ff, 0xffff00000000ff00, q17);
16849 ASSERT_EQUAL_128(0x0000000000000000, 0xffff000000000000, q18);
16850 ASSERT_EQUAL_128(0xffff000000000000, 0xffff000000000000, q19);
16851 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q20);
16852 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q21);
16853 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
16854 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16855 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
16856 TEARDOWN();
16857}
16858
16859
16860TEST(neon_2regmisc_cmge) {
16861 SETUP();
16862
16863 START();
16864
16865 __ Movi(v0.V2D(), 0xff01000200030004, 0x0000000000000000);
16866 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
16867
16868 __ Cmge(v16.V8B(), v1.V8B(), 0);
16869 __ Cmge(v17.V16B(), v1.V16B(), 0);
16870 __ Cmge(v18.V4H(), v1.V4H(), 0);
16871 __ Cmge(v19.V8H(), v1.V8H(), 0);
16872 __ Cmge(v20.V2S(), v0.V2S(), 0);
16873 __ Cmge(v21.V4S(), v0.V4S(), 0);
16874 __ Cmge(d22, d0, 0);
16875 __ Cmge(d23, d1, 0);
16876 __ Cmge(v24.V2D(), v0.V2D(), 0);
16877
16878 END();
16879
16880 RUN();
16881 ASSERT_EQUAL_128(0x0000000000000000, 0xffff00ffffffff00, q16);
16882 ASSERT_EQUAL_128(0xffffff0000ff00ff, 0xffff00ffffffff00, q17);
16883 ASSERT_EQUAL_128(0x0000000000000000, 0xffff0000ffffffff, q18);
16884 ASSERT_EQUAL_128(0xffffffff00000000, 0xffff0000ffffffff, q19);
16885 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q20);
16886 ASSERT_EQUAL_128(0x00000000ffffffff, 0xffffffffffffffff, q21);
16887 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
16888 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q23);
16889 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
16890 TEARDOWN();
16891}
16892
16893
16894TEST(neon_2regmisc_cmlt) {
16895 SETUP();
16896
16897 START();
16898
16899 __ Movi(v0.V2D(), 0x0001000200030004, 0xff00000000000000);
16900 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
16901
16902 __ Cmlt(v16.V8B(), v1.V8B(), 0);
16903 __ Cmlt(v17.V16B(), v1.V16B(), 0);
16904 __ Cmlt(v18.V4H(), v1.V4H(), 0);
16905 __ Cmlt(v19.V8H(), v1.V8H(), 0);
16906 __ Cmlt(v20.V2S(), v1.V2S(), 0);
16907 __ Cmlt(v21.V4S(), v1.V4S(), 0);
16908 __ Cmlt(d22, d0, 0);
16909 __ Cmlt(d23, d1, 0);
16910 __ Cmlt(v24.V2D(), v0.V2D(), 0);
16911
16912 END();
16913
16914 RUN();
16915 ASSERT_EQUAL_128(0x0000000000000000, 0x0000ff00000000ff, q16);
16916 ASSERT_EQUAL_128(0x000000ffff00ff00, 0x0000ff00000000ff, q17);
16917 ASSERT_EQUAL_128(0x0000000000000000, 0x0000ffff00000000, q18);
16918 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000ffff00000000, q19);
16919 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
16920 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000000000000000, q21);
16921 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
16922 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16923 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
16924 TEARDOWN();
16925}
16926
16927
16928TEST(neon_2regmisc_cmle) {
16929 SETUP();
16930
16931 START();
16932
16933 __ Movi(v0.V2D(), 0x0001000200030004, 0x0000000000000000);
16934 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
16935
16936 __ Cmle(v16.V8B(), v1.V8B(), 0);
16937 __ Cmle(v17.V16B(), v1.V16B(), 0);
16938 __ Cmle(v18.V4H(), v1.V4H(), 0);
16939 __ Cmle(v19.V8H(), v1.V8H(), 0);
16940 __ Cmle(v20.V2S(), v1.V2S(), 0);
16941 __ Cmle(v21.V4S(), v1.V4S(), 0);
16942 __ Cmle(d22, d0, 0);
16943 __ Cmle(d23, d1, 0);
16944 __ Cmle(v24.V2D(), v0.V2D(), 0);
16945
16946 END();
16947
16948 RUN();
16949 ASSERT_EQUAL_128(0x0000000000000000, 0xffffff000000ffff, q16);
16950 ASSERT_EQUAL_128(0xffff00ffff00ffff, 0xffffff000000ffff, q17);
16951 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffff00000000, q18);
16952 ASSERT_EQUAL_128(0xffff0000ffffffff, 0xffffffff00000000, q19);
16953 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
16954 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000000000000000, q21);
16955 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
16956 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16957 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
16958 TEARDOWN();
16959}
16960
16961
16962TEST(neon_2regmisc_cmgt) {
16963 SETUP();
16964
16965 START();
16966
16967 __ Movi(v0.V2D(), 0x0001000200030004, 0x0000000000000000);
16968 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
16969
16970 __ Cmgt(v16.V8B(), v1.V8B(), 0);
16971 __ Cmgt(v17.V16B(), v1.V16B(), 0);
16972 __ Cmgt(v18.V4H(), v1.V4H(), 0);
16973 __ Cmgt(v19.V8H(), v1.V8H(), 0);
16974 __ Cmgt(v20.V2S(), v0.V2S(), 0);
16975 __ Cmgt(v21.V4S(), v0.V4S(), 0);
16976 __ Cmgt(d22, d0, 0);
16977 __ Cmgt(d23, d1, 0);
16978 __ Cmgt(v24.V2D(), v0.V2D(), 0);
16979
16980 END();
16981
16982 RUN();
16983 ASSERT_EQUAL_128(0x0000000000000000, 0x000000ffffff0000, q16);
16984 ASSERT_EQUAL_128(0x0000ff0000ff0000, 0x000000ffffff0000, q17);
16985 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q18);
16986 ASSERT_EQUAL_128(0x0000ffff00000000, 0x00000000ffffffff, q19);
16987 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
16988 ASSERT_EQUAL_128(0xffffffffffffffff, 0x0000000000000000, q21);
16989 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q22);
16990 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q23);
16991 ASSERT_EQUAL_128(0xffffffffffffffff, 0x0000000000000000, q24);
16992 TEARDOWN();
16993}
16994
16995
16996TEST(neon_2regmisc_neg) {
16997 SETUP();
16998
16999 START();
17000
17001 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17002 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17003 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17004 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17005 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17006
17007 __ Neg(v16.V8B(), v0.V8B());
17008 __ Neg(v17.V16B(), v0.V16B());
17009 __ Neg(v18.V4H(), v1.V4H());
17010 __ Neg(v19.V8H(), v1.V8H());
17011 __ Neg(v20.V2S(), v2.V2S());
17012 __ Neg(v21.V4S(), v2.V4S());
17013 __ Neg(d22, d3);
17014 __ Neg(v23.V2D(), v3.V2D());
17015 __ Neg(v24.V2D(), v4.V2D());
17016
17017 END();
17018
17019 RUN();
17020 ASSERT_EQUAL_128(0x0000000000000000, 0x807f0100ff81807f, q16);
17021 ASSERT_EQUAL_128(0x81ff00017f8081ff, 0x807f0100ff81807f, q17);
17022 ASSERT_EQUAL_128(0x0000000000000000, 0x00010000ffff8001, q18);
17023 ASSERT_EQUAL_128(0x80007fff00010000, 0x00010000ffff8001, q19);
17024 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000001, q20);
17025 ASSERT_EQUAL_128(0x8000000000000001, 0x0000000080000001, q21);
17026 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000000001, q22);
17027 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x8000000000000001, q23);
17028 ASSERT_EQUAL_128(0x8000000000000000, 0x0000000000000000, q24);
17029
17030 TEARDOWN();
17031}
17032
17033
17034TEST(neon_2regmisc_sqneg) {
17035 SETUP();
17036
17037 START();
17038
17039 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17040 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17041 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17042 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17043 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17044
17045 __ Sqneg(v16.V8B(), v0.V8B());
17046 __ Sqneg(v17.V16B(), v0.V16B());
17047 __ Sqneg(v18.V4H(), v1.V4H());
17048 __ Sqneg(v19.V8H(), v1.V8H());
17049 __ Sqneg(v20.V2S(), v2.V2S());
17050 __ Sqneg(v21.V4S(), v2.V4S());
17051 __ Sqneg(v22.V2D(), v3.V2D());
17052 __ Sqneg(v23.V2D(), v4.V2D());
17053
17054 __ Sqneg(b24, b0);
17055 __ Sqneg(h25, h1);
17056 __ Sqneg(s26, s2);
17057 __ Sqneg(d27, d3);
17058
17059 END();
17060
17061 RUN();
17062 ASSERT_EQUAL_128(0x0000000000000000, 0x7f7f0100ff817f7f, q16);
17063 ASSERT_EQUAL_128(0x81ff00017f7f81ff, 0x7f7f0100ff817f7f, q17);
17064 ASSERT_EQUAL_128(0x0000000000000000, 0x00010000ffff8001, q18);
17065 ASSERT_EQUAL_128(0x7fff7fff00010000, 0x00010000ffff8001, q19);
17066 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000001, q20);
17067 ASSERT_EQUAL_128(0x7fffffff00000001, 0x0000000080000001, q21);
17068 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x8000000000000001, q22);
17069 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x0000000000000000, q23);
17070
17071 ASSERT_EQUAL_128(0, 0x7f, q24);
17072 ASSERT_EQUAL_128(0, 0x8001, q25);
17073 ASSERT_EQUAL_128(0, 0x80000001, q26);
17074 ASSERT_EQUAL_128(0, 0x8000000000000001, q27);
17075
17076 TEARDOWN();
17077}
17078
17079
17080TEST(neon_2regmisc_abs) {
17081 SETUP();
17082
17083 START();
17084
17085 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17086 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17087 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17088 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17089 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17090
17091 __ Abs(v16.V8B(), v0.V8B());
17092 __ Abs(v17.V16B(), v0.V16B());
17093 __ Abs(v18.V4H(), v1.V4H());
17094 __ Abs(v19.V8H(), v1.V8H());
17095 __ Abs(v20.V2S(), v2.V2S());
17096 __ Abs(v21.V4S(), v2.V4S());
17097 __ Abs(d22, d3);
17098 __ Abs(v23.V2D(), v3.V2D());
17099 __ Abs(v24.V2D(), v4.V2D());
17100
17101 END();
17102
17103 RUN();
17104 ASSERT_EQUAL_128(0x0000000000000000, 0x807f0100017f807f, q16);
17105 ASSERT_EQUAL_128(0x7f0100017f807f01, 0x807f0100017f807f, q17);
17106 ASSERT_EQUAL_128(0x0000000000000000, 0x0001000000017fff, q18);
17107 ASSERT_EQUAL_128(0x80007fff00010000, 0x0001000000017fff, q19);
17108 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
17109 ASSERT_EQUAL_128(0x8000000000000001, 0x000000007fffffff, q21);
17110 ASSERT_EQUAL_128(0x0000000000000000, 0x7fffffffffffffff, q22);
17111 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x7fffffffffffffff, q23);
17112 ASSERT_EQUAL_128(0x8000000000000000, 0x0000000000000000, q24);
17113
17114 TEARDOWN();
17115}
17116
17117
17118TEST(neon_2regmisc_sqabs) {
17119 SETUP();
17120
17121 START();
17122
17123 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17124 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17125 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17126 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17127 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17128
17129 __ Sqabs(v16.V8B(), v0.V8B());
17130 __ Sqabs(v17.V16B(), v0.V16B());
17131 __ Sqabs(v18.V4H(), v1.V4H());
17132 __ Sqabs(v19.V8H(), v1.V8H());
17133 __ Sqabs(v20.V2S(), v2.V2S());
17134 __ Sqabs(v21.V4S(), v2.V4S());
17135 __ Sqabs(v22.V2D(), v3.V2D());
17136 __ Sqabs(v23.V2D(), v4.V2D());
17137
17138 __ Sqabs(b24, b0);
17139 __ Sqabs(h25, h1);
17140 __ Sqabs(s26, s2);
17141 __ Sqabs(d27, d3);
17142
17143 END();
17144
17145 RUN();
17146 ASSERT_EQUAL_128(0x0000000000000000, 0x7f7f0100017f7f7f, q16);
17147 ASSERT_EQUAL_128(0x7f0100017f7f7f01, 0x7f7f0100017f7f7f, q17);
17148 ASSERT_EQUAL_128(0x0000000000000000, 0x0001000000017fff, q18);
17149 ASSERT_EQUAL_128(0x7fff7fff00010000, 0x0001000000017fff, q19);
17150 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
17151 ASSERT_EQUAL_128(0x7fffffff00000001, 0x000000007fffffff, q21);
17152 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x7fffffffffffffff, q22);
17153 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x0000000000000000, q23);
17154
17155 ASSERT_EQUAL_128(0, 0x7f, q24);
17156 ASSERT_EQUAL_128(0, 0x7fff, q25);
17157 ASSERT_EQUAL_128(0, 0x7fffffff, q26);
17158 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q27);
17159
17160 TEARDOWN();
17161}
17162
17163TEST(neon_2regmisc_suqadd) {
17164 SETUP();
17165
17166 START();
17167
17168 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17169 __ Movi(v1.V2D(), 0x017f8081ff00017f, 0x010080ff7f0180ff);
17170
17171 __ Movi(v2.V2D(), 0x80008001ffff0000, 0xffff000000017ffd);
17172 __ Movi(v3.V2D(), 0xffff000080008001, 0x00017fffffff0001);
17173
17174 __ Movi(v4.V2D(), 0x80000000fffffffe, 0xfffffff17ffffffe);
17175 __ Movi(v5.V2D(), 0xffffffff80000000, 0x7fffffff00000002);
17176
17177 __ Movi(v6.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17178 __ Movi(v7.V2D(), 0x8000000000000000, 0x8000000000000002);
17179
17180 __ Mov(v16.V2D(), v0.V2D());
17181 __ Mov(v17.V2D(), v0.V2D());
17182 __ Mov(v18.V2D(), v2.V2D());
17183 __ Mov(v19.V2D(), v2.V2D());
17184 __ Mov(v20.V2D(), v4.V2D());
17185 __ Mov(v21.V2D(), v4.V2D());
17186 __ Mov(v22.V2D(), v6.V2D());
17187
17188 __ Mov(v23.V2D(), v0.V2D());
17189 __ Mov(v24.V2D(), v2.V2D());
17190 __ Mov(v25.V2D(), v4.V2D());
17191 __ Mov(v26.V2D(), v6.V2D());
17192
17193 __ Suqadd(v16.V8B(), v1.V8B());
17194 __ Suqadd(v17.V16B(), v1.V16B());
17195 __ Suqadd(v18.V4H(), v3.V4H());
17196 __ Suqadd(v19.V8H(), v3.V8H());
17197 __ Suqadd(v20.V2S(), v5.V2S());
17198 __ Suqadd(v21.V4S(), v5.V4S());
17199 __ Suqadd(v22.V2D(), v7.V2D());
17200
17201 __ Suqadd(b23, b1);
17202 __ Suqadd(h24, h3);
17203 __ Suqadd(s25, s5);
17204 __ Suqadd(d26, d7);
17205
17206 END();
17207
17208 RUN();
17209 ASSERT_EQUAL_128(0x0000000000000000, 0x81817f7f7f7f007f, q16);
17210 ASSERT_EQUAL_128(0x7f7f7f7f7f807f7f, 0x81817f7f7f7f007f, q17);
17211 ASSERT_EQUAL_128(0x0000000000000000, 0x00007fff7fff7ffe, q18);
17212 ASSERT_EQUAL_128(0x7fff80017fff7fff, 0x00007fff7fff7ffe, q19);
17213 ASSERT_EQUAL_128(0x0000000000000000, 0x7ffffff07fffffff, q20);
17214 ASSERT_EQUAL_128(0x7fffffff7ffffffe, 0x7ffffff07fffffff, q21);
17215 ASSERT_EQUAL_128(0x0000000000000001, 0x7fffffffffffffff, q22);
17216
17217 ASSERT_EQUAL_128(0, 0x7f, q23);
17218 ASSERT_EQUAL_128(0, 0x7ffe, q24);
17219 ASSERT_EQUAL_128(0, 0x7fffffff, q25);
17220 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q26);
17221 TEARDOWN();
17222}
17223
17224TEST(neon_2regmisc_usqadd) {
17225 SETUP();
17226
17227 START();
17228
17229 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f7ffe);
17230 __ Movi(v1.V2D(), 0x017f8081ff00017f, 0x010080ff7f018002);
17231
17232 __ Movi(v2.V2D(), 0x80008001fffe0000, 0xffff000000017ffd);
17233 __ Movi(v3.V2D(), 0xffff000000028001, 0x00017fffffff0001);
17234
17235 __ Movi(v4.V2D(), 0x80000000fffffffe, 0x00000001fffffffe);
17236 __ Movi(v5.V2D(), 0xffffffff80000000, 0xfffffffe00000002);
17237
17238 __ Movi(v6.V2D(), 0x8000000000000002, 0x7fffffffffffffff);
17239 __ Movi(v7.V2D(), 0x7fffffffffffffff, 0x8000000000000000);
17240
17241 __ Mov(v16.V2D(), v0.V2D());
17242 __ Mov(v17.V2D(), v0.V2D());
17243 __ Mov(v18.V2D(), v2.V2D());
17244 __ Mov(v19.V2D(), v2.V2D());
17245 __ Mov(v20.V2D(), v4.V2D());
17246 __ Mov(v21.V2D(), v4.V2D());
17247 __ Mov(v22.V2D(), v6.V2D());
17248
17249 __ Mov(v23.V2D(), v0.V2D());
17250 __ Mov(v24.V2D(), v2.V2D());
17251 __ Mov(v25.V2D(), v4.V2D());
17252 __ Mov(v26.V2D(), v6.V2D());
17253
17254 __ Usqadd(v16.V8B(), v1.V8B());
17255 __ Usqadd(v17.V16B(), v1.V16B());
17256 __ Usqadd(v18.V4H(), v3.V4H());
17257 __ Usqadd(v19.V8H(), v3.V8H());
17258 __ Usqadd(v20.V2S(), v5.V2S());
17259 __ Usqadd(v21.V4S(), v5.V4S());
17260 __ Usqadd(v22.V2D(), v7.V2D());
17261
17262 __ Usqadd(b23, b1);
17263 __ Usqadd(h24, h3);
17264 __ Usqadd(s25, s5);
17265 __ Usqadd(d26, d7);
17266
17267 END();
17268
17269 RUN();
17270 ASSERT_EQUAL_128(0x0000000000000000, 0x81817f00808000ff, q16);
17271 ASSERT_EQUAL_128(0x8080008080808080, 0x81817f00808000ff, q17);
17272 ASSERT_EQUAL_128(0x0000000000000000, 0xffff7fff00007ffe, q18);
17273 ASSERT_EQUAL_128(0x7fff8001ffff0000, 0xffff7fff00007ffe, q19);
17274 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q20);
17275 ASSERT_EQUAL_128(0x7fffffff7ffffffe, 0x00000000ffffffff, q21);
17276 ASSERT_EQUAL_128(0xffffffffffffffff, 0x0000000000000000, q22);
17277
17278 ASSERT_EQUAL_128(0, 0xff, q23);
17279 ASSERT_EQUAL_128(0, 0x7ffe, q24);
17280 ASSERT_EQUAL_128(0, 0xffffffff, q25);
17281 ASSERT_EQUAL_128(0, 0x0000000000000000, q26);
17282 TEARDOWN();
17283}
17284
17285
17286TEST(system_sys) {
17287 SETUP();
17288 const char* msg = "SYS test!";
17289 uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
17290
17291 START();
17292 __ Mov(x4, msg_addr);
17293 __ Sys(3, 0x7, 0x5, 1, x4);
17294 __ Mov(x3, x4);
17295 __ Sys(3, 0x7, 0xa, 1, x3);
17296 __ Mov(x2, x3);
17297 __ Sys(3, 0x7, 0xb, 1, x2);
17298 __ Mov(x1, x2);
17299 __ Sys(3, 0x7, 0xe, 1, x1);
17300 // TODO: Add tests to check ZVA equivalent.
17301 END();
17302
17303 RUN();
17304
17305 TEARDOWN();
17306}
17307
17308
17309TEST(system_ic) {
17310 SETUP();
17311 const char* msg = "IC test!";
17312 uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
17313
17314 START();
17315 __ Mov(x11, msg_addr);
17316 __ Ic(IVAU, x11);
17317 END();
17318
17319 RUN();
17320
17321 TEARDOWN();
17322}
17323
17324
17325TEST(system_dc) {
17326 SETUP();
17327 const char* msg = "DC test!";
17328 uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
17329
17330 START();
17331 __ Mov(x20, msg_addr);
17332 __ Dc(CVAC, x20);
17333 __ Mov(x21, x20);
17334 __ Dc(CVAU, x21);
17335 __ Mov(x22, x21);
17336 __ Dc(CIVAC, x22);
17337 // TODO: Add tests to check ZVA.
17338 END();
17339
17340 RUN();
17341
17342 TEARDOWN();
17343}
17344
17345
17346TEST(neon_2regmisc_xtn) {
17347 SETUP();
17348
17349 START();
17350
17351 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17352 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17353 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17354 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17355 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17356
17357 __ Xtn(v16.V8B(), v0.V8H());
17358 __ Xtn2(v16.V16B(), v1.V8H());
17359 __ Xtn(v17.V4H(), v1.V4S());
17360 __ Xtn2(v17.V8H(), v2.V4S());
17361 __ Xtn(v18.V2S(), v3.V2D());
17362 __ Xtn2(v18.V4S(), v4.V2D());
17363
17364 END();
17365
17366 RUN();
17367 ASSERT_EQUAL_128(0x0001ff00ff0001ff, 0x01ff800181007f81, q16);
17368 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x8001000000007fff, q17);
17369 ASSERT_EQUAL_128(0x0000000000000000, 0x00000001ffffffff, q18);
17370 TEARDOWN();
17371}
17372
17373
17374TEST(neon_2regmisc_sqxtn) {
17375 SETUP();
17376
17377 START();
17378
17379 __ Movi(v0.V2D(), 0x7f01007a81807f01, 0x8081ff00017f8081);
17380 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17381 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17382 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17383 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17384
17385 __ Sqxtn(v16.V8B(), v0.V8H());
17386 __ Sqxtn2(v16.V16B(), v1.V8H());
17387 __ Sqxtn(v17.V4H(), v1.V4S());
17388 __ Sqxtn2(v17.V8H(), v2.V4S());
17389 __ Sqxtn(v18.V2S(), v3.V2D());
17390 __ Sqxtn2(v18.V4S(), v4.V2D());
17391 __ Sqxtn(b19, h0);
17392 __ Sqxtn(h20, s0);
17393 __ Sqxtn(s21, d0);
17394
17395 END();
17396
17397 RUN();
17398 ASSERT_EQUAL_128(0x8080ff00ff00017f, 0x7f7a807f80807f80, q16);
17399 ASSERT_EQUAL_128(0x8000ffff00007fff, 0x8000800080007fff, q17);
17400 ASSERT_EQUAL_128(0x8000000000000000, 0x800000007fffffff, q18);
17401 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000080, q19);
17402 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000007fff, q20);
17403 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000000, q21);
17404 TEARDOWN();
17405}
17406
17407
17408TEST(neon_2regmisc_uqxtn) {
17409 SETUP();
17410
17411 START();
17412
17413 __ Movi(v0.V2D(), 0x7f01007a81807f01, 0x8081ff00017f8081);
17414 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17415 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17416 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17417 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17418
17419 __ Uqxtn(v16.V8B(), v0.V8H());
17420 __ Uqxtn2(v16.V16B(), v1.V8H());
17421 __ Uqxtn(v17.V4H(), v1.V4S());
17422 __ Uqxtn2(v17.V8H(), v2.V4S());
17423 __ Uqxtn(v18.V2S(), v3.V2D());
17424 __ Uqxtn2(v18.V4S(), v4.V2D());
17425 __ Uqxtn(b19, h0);
17426 __ Uqxtn(h20, s0);
17427 __ Uqxtn(s21, d0);
17428
17429 END();
17430
17431 RUN();
17432 ASSERT_EQUAL_128(0xffffff00ff0001ff, 0xff7affffffffffff, q16);
17433 ASSERT_EQUAL_128(0xffffffff0000ffff, 0xffffffffffffffff, q17);
17434 ASSERT_EQUAL_128(0xffffffff00000000, 0xffffffffffffffff, q18);
17435 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000000000ff, q19);
17436 ASSERT_EQUAL_128(0x0000000000000000, 0x000000000000ffff, q20);
17437 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q21);
17438 TEARDOWN();
17439}
17440
17441
17442TEST(neon_2regmisc_sqxtun) {
17443 SETUP();
17444
17445 START();
17446
17447 __ Movi(v0.V2D(), 0x7f01007a81807f01, 0x8081ff00017f8081);
17448 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17449 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17450 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17451 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17452
17453 __ Sqxtun(v16.V8B(), v0.V8H());
17454 __ Sqxtun2(v16.V16B(), v1.V8H());
17455 __ Sqxtun(v17.V4H(), v1.V4S());
17456 __ Sqxtun2(v17.V8H(), v2.V4S());
17457 __ Sqxtun(v18.V2S(), v3.V2D());
17458 __ Sqxtun2(v18.V4S(), v4.V2D());
17459 __ Sqxtun(b19, h0);
17460 __ Sqxtun(h20, s0);
17461 __ Sqxtun(s21, d0);
17462
17463 END();
17464
17465 RUN();
17466 ASSERT_EQUAL_128(0x00000000000001ff, 0xff7a00ff0000ff00, q16);
17467 ASSERT_EQUAL_128(0x000000000000ffff, 0x000000000000ffff, q17);
17468 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q18);
17469 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q19);
17470 ASSERT_EQUAL_128(0x0000000000000000, 0x000000000000ffff, q20);
17471 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q21);
17472 TEARDOWN();
17473}
17474
17475TEST(neon_3same_and) {
17476 SETUP();
17477
17478 START();
17479
17480 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17481 __ Movi(v1.V2D(), 0x00aa55aaff55ff00, 0xaa55ff00555500ff);
17482
17483 __ And(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17484 __ And(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17485 __ And(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17486 __ And(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17487 END();
17488
17489 RUN();
17490 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q16);
17491 ASSERT_EQUAL_128(0x0000000000555500, 0xaa00aa00005500aa, q17);
17492 ASSERT_EQUAL_128(0, 0xff00aa5500ff55aa, q24);
17493 ASSERT_EQUAL_128(0, 0xaa00aa00005500aa, q25);
17494 TEARDOWN();
17495}
17496
17497TEST(neon_3same_bic) {
17498 SETUP();
17499
17500 START();
17501
17502 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17503 __ Movi(v1.V2D(), 0x00ffaa00aa55aaff, 0xffff005500ff00ff);
17504
17505 __ Bic(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17506 __ Bic(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17507 __ Bic(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17508 __ Bic(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17509 END();
17510
17511 RUN();
17512 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q16);
17513 ASSERT_EQUAL_128(0xff00005500aa5500, 0x0000aa0000005500, q17);
17514 ASSERT_EQUAL_128(0, 0x0000000000000000, q24);
17515 ASSERT_EQUAL_128(0, 0x0000aa0000005500, q25);
17516 TEARDOWN();
17517}
17518
17519TEST(neon_3same_orr) {
17520 SETUP();
17521
17522 START();
17523
17524 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17525 __ Movi(v1.V2D(), 0x00aa55aaff55ff00, 0xaa55ff00555500ff);
17526
17527 __ Orr(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17528 __ Orr(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17529 __ Orr(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17530 __ Orr(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17531 END();
17532
17533 RUN();
17534 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q16);
17535 ASSERT_EQUAL_128(0xffaaffffffffffaa, 0xff55ff5555ff55ff, q17);
17536 ASSERT_EQUAL_128(0, 0xff00aa5500ff55aa, q24);
17537 ASSERT_EQUAL_128(0, 0xff55ff5555ff55ff, q25);
17538 TEARDOWN();
17539}
17540
17541TEST(neon_3same_mov) {
17542 SETUP();
17543
17544 START();
17545
17546 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17547
17548 __ Mov(v16.V16B(), v0.V16B());
17549 __ Mov(v17.V8H(), v0.V8H());
17550 __ Mov(v18.V4S(), v0.V4S());
17551 __ Mov(v19.V2D(), v0.V2D());
17552
17553 __ Mov(v24.V8B(), v0.V8B());
17554 __ Mov(v25.V4H(), v0.V4H());
17555 __ Mov(v26.V2S(), v0.V2S());
17556 END();
17557
17558 RUN();
17559
17560 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q16);
17561 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q17);
17562 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q18);
17563 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q19);
17564
17565 ASSERT_EQUAL_128(0x0, 0xff00aa5500ff55aa, q24);
17566 ASSERT_EQUAL_128(0x0, 0xff00aa5500ff55aa, q25);
17567 ASSERT_EQUAL_128(0x0, 0xff00aa5500ff55aa, q26);
17568
17569 TEARDOWN();
17570}
17571
17572TEST(neon_3same_orn) {
17573 SETUP();
17574
17575 START();
17576
17577 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17578 __ Movi(v1.V2D(), 0x00aa55aaff55ff00, 0xaa55ff00555500ff);
17579
17580 __ Orn(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17581 __ Orn(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17582 __ Orn(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17583 __ Orn(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17584 END();
17585
17586 RUN();
17587 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q16);
17588 ASSERT_EQUAL_128(0xff55aa5500ff55ff, 0xffaaaaffaaffffaa, q17);
17589 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q24);
17590 ASSERT_EQUAL_128(0, 0xffaaaaffaaffffaa, q25);
17591 TEARDOWN();
17592}
17593
17594TEST(neon_3same_eor) {
17595 SETUP();
17596
17597 START();
17598
17599 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17600 __ Movi(v1.V2D(), 0x00ffaa00aa55aaff, 0xffff005500ff00ff);
17601
17602 __ Eor(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17603 __ Eor(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17604 __ Eor(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17605 __ Eor(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17606 END();
17607
17608 RUN();
17609 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q16);
17610 ASSERT_EQUAL_128(0xffff0055aaaaff55, 0x00ffaa0000005555, q17);
17611 ASSERT_EQUAL_128(0, 0x0000000000000000, q24);
17612 ASSERT_EQUAL_128(0, 0x00ffaa0000005555, q25);
17613 TEARDOWN();
17614}
17615
17616TEST(neon_3same_bif) {
17617 SETUP();
17618
17619 START();
17620
17621 __ Movi(v16.V2D(), 0xffff0000ff00ffff, 0xffff00000000aaaa);
17622 __ Movi(v0.V2D(), 0xff00ff00ff005555, 0xaaaa5555aaaaaaaa);
17623 __ Movi(v1.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
17624
17625 __ Movi(v17.V2D(), 0x5555aa55cccccccc, 0x33333333f0f0f0f0);
17626 __ Movi(v2.V2D(), 0x555555aaff00ff00, 0xff00ff00ff00ff00);
17627 __ Movi(v3.V2D(), 0xaa55aa5500ffff00, 0x00ffff0000ffff00);
17628
17629 __ Movi(v18.V2D(), 0, 0xf0f0f0f00f0f0f0f);
17630 __ Movi(v4.V2D(), 0, 0xf0f0f0f0f0f0f0f0);
17631 __ Movi(v5.V2D(), 0, 0x00ffff0000ffff00);
17632
17633 __ Bif(v16.V16B(), v0.V16B(), v1.V16B());
17634 __ Bif(v17.V16B(), v2.V16B(), v3.V16B());
17635 __ Bif(v18.V8B(), v4.V8B(), v5.V8B());
17636 END();
17637
17638 RUN();
17639
17640 ASSERT_EQUAL_128(0xffffff00ff0055ff, 0xffaa0055aa00aaaa, q16);
17641 ASSERT_EQUAL_128(0x5555ffffffcccc00, 0xff333300fff0f000, q17);
17642 ASSERT_EQUAL_128(0, 0xf0f0f0f0f00f0ff0, q18);
17643 TEARDOWN();
17644}
17645
17646TEST(neon_3same_bit) {
17647 SETUP();
17648
17649 START();
17650
17651 __ Movi(v16.V2D(), 0xffff0000ff00ffff, 0xffff00000000aaaa);
17652 __ Movi(v0.V2D(), 0xff00ff00ff005555, 0xaaaa5555aaaaaaaa);
17653 __ Movi(v1.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
17654
17655 __ Movi(v17.V2D(), 0x5555aa55cccccccc, 0x33333333f0f0f0f0);
17656 __ Movi(v2.V2D(), 0x555555aaff00ff00, 0xff00ff00ff00ff00);
17657 __ Movi(v3.V2D(), 0xaa55aa5500ffff00, 0x00ffff0000ffff00);
17658
17659 __ Movi(v18.V2D(), 0, 0xf0f0f0f00f0f0f0f);
17660 __ Movi(v4.V2D(), 0, 0xf0f0f0f0f0f0f0f0);
17661 __ Movi(v5.V2D(), 0, 0x00ffff0000ffff00);
17662
17663 __ Bit(v16.V16B(), v0.V16B(), v1.V16B());
17664 __ Bit(v17.V16B(), v2.V16B(), v3.V16B());
17665 __ Bit(v18.V8B(), v4.V8B(), v5.V8B());
17666 END();
17667
17668 RUN();
17669
17670 ASSERT_EQUAL_128(0xff000000ff00ff55, 0xaaff550000aaaaaa, q16);
17671 ASSERT_EQUAL_128(0x55550000cc00ffcc, 0x3300ff33f000fff0, q17);
17672 ASSERT_EQUAL_128(0, 0xf0f0f0f00ff0f00f, q18);
17673 TEARDOWN();
17674}
17675
17676TEST(neon_3same_bsl) {
17677 SETUP();
17678
17679 START();
17680
17681 __ Movi(v16.V2D(), 0xffff0000ff00ffff, 0xffff00000000aaaa);
17682 __ Movi(v0.V2D(), 0xff00ff00ff005555, 0xaaaa5555aaaaaaaa);
17683 __ Movi(v1.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
17684
17685 __ Movi(v17.V2D(), 0x5555aa55cccccccc, 0x33333333f0f0f0f0);
17686 __ Movi(v2.V2D(), 0x555555aaff00ff00, 0xff00ff00ff00ff00);
17687 __ Movi(v3.V2D(), 0xaa55aa5500ffff00, 0x00ffff0000ffff00);
17688
17689 __ Movi(v18.V2D(), 0, 0xf0f0f0f00f0f0f0f);
17690 __ Movi(v4.V2D(), 0, 0xf0f0f0f0f0f0f0f0);
17691 __ Movi(v5.V2D(), 0, 0x00ffff0000ffff00);
17692
17693 __ Bsl(v16.V16B(), v0.V16B(), v1.V16B());
17694 __ Bsl(v17.V16B(), v2.V16B(), v3.V16B());
17695 __ Bsl(v18.V8B(), v4.V8B(), v5.V8B());
17696 END();
17697
17698 RUN();
17699
17700 ASSERT_EQUAL_128(0xff0000ffff005555, 0xaaaa55aa55aaffaa, q16);
17701 ASSERT_EQUAL_128(0xff550000cc33ff00, 0x33ccff00f00fff00, q17);
17702 ASSERT_EQUAL_128(0, 0xf0fffff000f0f000, q18);
17703 TEARDOWN();
17704}
17705
17706
17707TEST(neon_3same_smax) {
17708 SETUP();
17709
17710 START();
17711
17712 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
17713 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17714
17715 __ Smax(v16.V8B(), v0.V8B(), v1.V8B());
17716 __ Smax(v18.V4H(), v0.V4H(), v1.V4H());
17717 __ Smax(v20.V2S(), v0.V2S(), v1.V2S());
17718
17719 __ Smax(v17.V16B(), v0.V16B(), v1.V16B());
17720 __ Smax(v19.V8H(), v0.V8H(), v1.V8H());
17721 __ Smax(v21.V4S(), v0.V4S(), v1.V4S());
17722 END();
17723
17724 RUN();
17725
17726 ASSERT_EQUAL_128(0x0, 0x0000000000005555, q16);
17727 ASSERT_EQUAL_128(0x0, 0x00000000000055ff, q18);
17728 ASSERT_EQUAL_128(0x0, 0x000000000000aa55, q20);
17729 ASSERT_EQUAL_128(0x55aa555555555555, 0x0000000000005555, q17);
17730 ASSERT_EQUAL_128(0x55aa555555555555, 0x00000000000055ff, q19);
17731 ASSERT_EQUAL_128(0x55aa555555555555, 0x000000000000aa55, q21);
17732 TEARDOWN();
17733}
17734
17735
17736TEST(neon_3same_smaxp) {
17737 SETUP();
17738
17739 START();
17740
17741 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
17742 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17743
17744 __ Smaxp(v16.V8B(), v0.V8B(), v1.V8B());
17745 __ Smaxp(v18.V4H(), v0.V4H(), v1.V4H());
17746 __ Smaxp(v20.V2S(), v0.V2S(), v1.V2S());
17747
17748 __ Smaxp(v17.V16B(), v0.V16B(), v1.V16B());
17749 __ Smaxp(v19.V8H(), v0.V8H(), v1.V8H());
17750 __ Smaxp(v21.V4S(), v0.V4S(), v1.V4S());
17751 END();
17752
17753 RUN();
17754
17755 ASSERT_EQUAL_128(0x0, 0x0000ff55ffff0055, q16);
17756 ASSERT_EQUAL_128(0x0, 0x000055ffffff0000, q18);
17757 ASSERT_EQUAL_128(0x0, 0x000000000000aa55, q20);
17758 ASSERT_EQUAL_128(0x5555aaaa0000ff55, 0xaaaa5555ffff0055, q17);
17759 ASSERT_EQUAL_128(0x55aaaaaa000055ff, 0xaaaa5555ffff0000, q19);
17760 ASSERT_EQUAL_128(0x55aa555500000000, 0x555555550000aa55, q21);
17761 TEARDOWN();
17762}
17763
17764
17765TEST(neon_addp_scalar) {
17766 SETUP();
17767
17768 START();
17769
17770 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17771 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17772 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17773
17774 __ Addp(d16, v0.V2D());
17775 __ Addp(d17, v1.V2D());
17776 __ Addp(d18, v2.V2D());
17777
17778 END();
17779
17780 RUN();
17781
17782 ASSERT_EQUAL_128(0x0, 0x00224466ef66fa80, q16);
17783 ASSERT_EQUAL_128(0x0, 0x55aa5556aa5500a9, q17);
17784 ASSERT_EQUAL_128(0x0, 0xaaaaaaa96655ff55, q18);
17785 TEARDOWN();
17786}
17787
17788TEST(neon_acrosslanes_addv) {
17789 SETUP();
17790
17791 START();
17792
17793 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17794 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17795 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17796
17797 __ Addv(b16, v0.V8B());
17798 __ Addv(b17, v0.V16B());
17799 __ Addv(h18, v1.V4H());
17800 __ Addv(h19, v1.V8H());
17801 __ Addv(s20, v2.V4S());
17802
17803 END();
17804
17805 RUN();
17806
17807 ASSERT_EQUAL_128(0x0, 0xc7, q16);
17808 ASSERT_EQUAL_128(0x0, 0x99, q17);
17809 ASSERT_EQUAL_128(0x0, 0x55a9, q18);
17810 ASSERT_EQUAL_128(0x0, 0x55fc, q19);
17811 ASSERT_EQUAL_128(0x0, 0x1100a9fe, q20);
17812 TEARDOWN();
17813}
17814
17815
17816TEST(neon_acrosslanes_saddlv) {
17817 SETUP();
17818
17819 START();
17820
17821 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17822 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17823 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17824
17825 __ Saddlv(h16, v0.V8B());
17826 __ Saddlv(h17, v0.V16B());
17827 __ Saddlv(s18, v1.V4H());
17828 __ Saddlv(s19, v1.V8H());
17829 __ Saddlv(d20, v2.V4S());
17830
17831 END();
17832
17833 RUN();
17834
17835 ASSERT_EQUAL_128(0x0, 0xffc7, q16);
17836 ASSERT_EQUAL_128(0x0, 0xff99, q17);
17837 ASSERT_EQUAL_128(0x0, 0x000055a9, q18);
17838 ASSERT_EQUAL_128(0x0, 0x000055fc, q19);
17839 ASSERT_EQUAL_128(0x0, 0x0000001100a9fe, q20);
17840 TEARDOWN();
17841}
17842
17843
17844TEST(neon_acrosslanes_uaddlv) {
17845 SETUP();
17846
17847 START();
17848
17849 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17850 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17851 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17852
17853 __ Uaddlv(h16, v0.V8B());
17854 __ Uaddlv(h17, v0.V16B());
17855 __ Uaddlv(s18, v1.V4H());
17856 __ Uaddlv(s19, v1.V8H());
17857 __ Uaddlv(d20, v2.V4S());
17858
17859 END();
17860
17861 RUN();
17862
17863 ASSERT_EQUAL_128(0x0, 0x02c7, q16);
17864 ASSERT_EQUAL_128(0x0, 0x0599, q17);
17865 ASSERT_EQUAL_128(0x0, 0x000155a9, q18);
17866 ASSERT_EQUAL_128(0x0, 0x000355fc, q19);
17867 ASSERT_EQUAL_128(0x0, 0x000000021100a9fe, q20);
17868 TEARDOWN();
17869}
17870
17871
17872TEST(neon_acrosslanes_smaxv) {
17873 SETUP();
17874
17875 START();
17876
17877 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17878 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17879 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17880
17881 __ Smaxv(b16, v0.V8B());
17882 __ Smaxv(b17, v0.V16B());
17883 __ Smaxv(h18, v1.V4H());
17884 __ Smaxv(h19, v1.V8H());
17885 __ Smaxv(s20, v2.V4S());
17886
17887 END();
17888
17889 RUN();
17890
17891 ASSERT_EQUAL_128(0x0, 0x33, q16);
17892 ASSERT_EQUAL_128(0x0, 0x44, q17);
17893 ASSERT_EQUAL_128(0x0, 0x55ff, q18);
17894 ASSERT_EQUAL_128(0x0, 0x55ff, q19);
17895 ASSERT_EQUAL_128(0x0, 0x66555555, q20);
17896 TEARDOWN();
17897}
17898
17899
17900TEST(neon_acrosslanes_sminv) {
17901 SETUP();
17902
17903 START();
17904
17905 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17906 __ Movi(v1.V2D(), 0xfffa5555aaaaaaaa, 0x00000000ffaa55ff);
17907 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17908
17909 __ Sminv(b16, v0.V8B());
17910 __ Sminv(b17, v0.V16B());
17911 __ Sminv(h18, v1.V4H());
17912 __ Sminv(h19, v1.V8H());
17913 __ Sminv(s20, v2.V4S());
17914
17915 END();
17916
17917 RUN();
17918
17919 ASSERT_EQUAL_128(0x0, 0xaa, q16);
17920 ASSERT_EQUAL_128(0x0, 0x80, q17);
17921 ASSERT_EQUAL_128(0x0, 0xffaa, q18);
17922 ASSERT_EQUAL_128(0x0, 0xaaaa, q19);
17923 ASSERT_EQUAL_128(0x0, 0xaaaaaaaa, q20);
17924 TEARDOWN();
17925}
17926
17927TEST(neon_acrosslanes_umaxv) {
17928 SETUP();
17929
17930 START();
17931
17932 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17933 __ Movi(v1.V2D(), 0x55aa5555aaaaffab, 0x00000000ffaa55ff);
17934 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17935
17936 __ Umaxv(b16, v0.V8B());
17937 __ Umaxv(b17, v0.V16B());
17938 __ Umaxv(h18, v1.V4H());
17939 __ Umaxv(h19, v1.V8H());
17940 __ Umaxv(s20, v2.V4S());
17941
17942 END();
17943
17944 RUN();
17945
17946 ASSERT_EQUAL_128(0x0, 0xfc, q16);
17947 ASSERT_EQUAL_128(0x0, 0xfe, q17);
17948 ASSERT_EQUAL_128(0x0, 0xffaa, q18);
17949 ASSERT_EQUAL_128(0x0, 0xffab, q19);
17950 ASSERT_EQUAL_128(0x0, 0xffffffff, q20);
17951 TEARDOWN();
17952}
17953
17954
17955TEST(neon_acrosslanes_uminv) {
17956 SETUP();
17957
17958 START();
17959
17960 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x02112233aabbfc01);
17961 __ Movi(v1.V2D(), 0xfffa5555aaaa0000, 0x00010003ffaa55ff);
17962 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17963
17964 __ Uminv(b16, v0.V8B());
17965 __ Uminv(b17, v0.V16B());
17966 __ Uminv(h18, v1.V4H());
17967 __ Uminv(h19, v1.V8H());
17968 __ Uminv(s20, v2.V4S());
17969
17970 END();
17971
17972 RUN();
17973
17974 ASSERT_EQUAL_128(0x0, 0x01, q16);
17975 ASSERT_EQUAL_128(0x0, 0x00, q17);
17976 ASSERT_EQUAL_128(0x0, 0x0001, q18);
17977 ASSERT_EQUAL_128(0x0, 0x0000, q19);
17978 ASSERT_EQUAL_128(0x0, 0x0000aa00, q20);
17979 TEARDOWN();
17980}
17981
17982
17983TEST(neon_3same_smin) {
17984 SETUP();
17985
17986 START();
17987
17988 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
17989 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17990
17991 __ Smin(v16.V8B(), v0.V8B(), v1.V8B());
17992 __ Smin(v18.V4H(), v0.V4H(), v1.V4H());
17993 __ Smin(v20.V2S(), v0.V2S(), v1.V2S());
17994
17995 __ Smin(v17.V16B(), v0.V16B(), v1.V16B());
17996 __ Smin(v19.V8H(), v0.V8H(), v1.V8H());
17997 __ Smin(v21.V4S(), v0.V4S(), v1.V4S());
17998 END();
17999
18000 RUN();
18001
18002 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaaff, q16);
18003 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaa55, q18);
18004 ASSERT_EQUAL_128(0x0, 0xffffffffffaa55ff, q20);
18005 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaaff, q17);
18006 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaa55, q19);
18007 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaa55ff, q21);
18008 TEARDOWN();
18009}
18010
18011
18012TEST(neon_3same_umax) {
18013 SETUP();
18014
18015 START();
18016
18017 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
18018 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18019
18020 __ Umax(v16.V8B(), v0.V8B(), v1.V8B());
18021 __ Umax(v18.V4H(), v0.V4H(), v1.V4H());
18022 __ Umax(v20.V2S(), v0.V2S(), v1.V2S());
18023
18024 __ Umax(v17.V16B(), v0.V16B(), v1.V16B());
18025 __ Umax(v19.V8H(), v0.V8H(), v1.V8H());
18026 __ Umax(v21.V4S(), v0.V4S(), v1.V4S());
18027 END();
18028
18029 RUN();
18030
18031 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaaff, q16);
18032 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaa55, q18);
18033 ASSERT_EQUAL_128(0x0, 0xffffffffffaa55ff, q20);
18034 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaaff, q17);
18035 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaa55, q19);
18036 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaa55ff, q21);
18037 TEARDOWN();
18038}
18039
18040
18041TEST(neon_3same_umin) {
18042 SETUP();
18043
18044 START();
18045
18046 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
18047 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18048
18049 __ Umin(v16.V8B(), v0.V8B(), v1.V8B());
18050 __ Umin(v18.V4H(), v0.V4H(), v1.V4H());
18051 __ Umin(v20.V2S(), v0.V2S(), v1.V2S());
18052
18053 __ Umin(v17.V16B(), v0.V16B(), v1.V16B());
18054 __ Umin(v19.V8H(), v0.V8H(), v1.V8H());
18055 __ Umin(v21.V4S(), v0.V4S(), v1.V4S());
18056 END();
18057
18058 RUN();
18059
18060 ASSERT_EQUAL_128(0x0, 0x0000000000005555, q16);
18061 ASSERT_EQUAL_128(0x0, 0x00000000000055ff, q18);
18062 ASSERT_EQUAL_128(0x0, 0x000000000000aa55, q20);
18063 ASSERT_EQUAL_128(0x55aa555555555555, 0x0000000000005555, q17);
18064 ASSERT_EQUAL_128(0x55aa555555555555, 0x00000000000055ff, q19);
18065 ASSERT_EQUAL_128(0x55aa555555555555, 0x000000000000aa55, q21);
18066 TEARDOWN();
18067}
18068
18069
18070TEST(neon_2regmisc_mvn) {
18071 SETUP();
18072
18073 START();
18074
18075 __ Movi(v0.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
18076
18077 __ Mvn(v16.V16B(), v0.V16B());
18078 __ Mvn(v17.V8H(), v0.V8H());
18079 __ Mvn(v18.V4S(), v0.V4S());
18080 __ Mvn(v19.V2D(), v0.V2D());
18081
18082 __ Mvn(v24.V8B(), v0.V8B());
18083 __ Mvn(v25.V4H(), v0.V4H());
18084 __ Mvn(v26.V2S(), v0.V2S());
18085
18086 END();
18087
18088 RUN();
18089
18090 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q16);
18091 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q17);
18092 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q18);
18093 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q19);
18094
18095 ASSERT_EQUAL_128(0x0, 0xaa55aa55aa55aa55, q24);
18096 ASSERT_EQUAL_128(0x0, 0xaa55aa55aa55aa55, q25);
18097 ASSERT_EQUAL_128(0x0, 0xaa55aa55aa55aa55, q26);
18098 TEARDOWN();
18099}
18100
18101
18102TEST(neon_2regmisc_not) {
18103 SETUP();
18104
18105 START();
18106
18107 __ Movi(v0.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
18108 __ Movi(v1.V2D(), 0, 0x00ffff0000ffff00);
18109
18110 __ Not(v16.V16B(), v0.V16B());
18111 __ Not(v17.V8B(), v1.V8B());
18112 END();
18113
18114 RUN();
18115
18116 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q16);
18117 ASSERT_EQUAL_128(0x0, 0xff0000ffff0000ff, q17);
18118 TEARDOWN();
18119}
18120
18121TEST(neon_2regmisc_cls_clz_cnt) {
18122 SETUP();
18123
18124 START();
18125
18126 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18127 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18128
18129 __ Cls(v16.V8B() , v1.V8B());
18130 __ Cls(v17.V16B(), v1.V16B());
18131 __ Cls(v18.V4H() , v1.V4H());
18132 __ Cls(v19.V8H() , v1.V8H());
18133 __ Cls(v20.V2S() , v1.V2S());
18134 __ Cls(v21.V4S() , v1.V4S());
18135
18136 __ Clz(v22.V8B() , v0.V8B());
18137 __ Clz(v23.V16B(), v0.V16B());
18138 __ Clz(v24.V4H() , v0.V4H());
18139 __ Clz(v25.V8H() , v0.V8H());
18140 __ Clz(v26.V2S() , v0.V2S());
18141 __ Clz(v27.V4S() , v0.V4S());
18142
18143 __ Cnt(v28.V8B() , v0.V8B());
18144 __ Cnt(v29.V16B(), v1.V16B());
18145
18146 END();
18147
18148 RUN();
18149
18150 ASSERT_EQUAL_128(0x0000000000000000, 0x0601000000000102, q16);
18151 ASSERT_EQUAL_128(0x0601000000000102, 0x0601000000000102, q17);
18152 ASSERT_EQUAL_128(0x0000000000000000, 0x0006000000000001, q18);
18153 ASSERT_EQUAL_128(0x0006000000000001, 0x0006000000000001, q19);
18154 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000600000000, q20);
18155 ASSERT_EQUAL_128(0x0000000600000000, 0x0000000600000000, q21);
18156
18157 ASSERT_EQUAL_128(0x0000000000000000, 0x0404040404040404, q22);
18158 ASSERT_EQUAL_128(0x0807060605050505, 0x0404040404040404, q23);
18159 ASSERT_EQUAL_128(0x0000000000000000, 0x0004000400040004, q24);
18160 ASSERT_EQUAL_128(0x000f000600050005, 0x0004000400040004, q25);
18161 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000400000004, q26);
18162 ASSERT_EQUAL_128(0x0000000f00000005, 0x0000000400000004, q27);
18163
18164 ASSERT_EQUAL_128(0x0000000000000000, 0x0102020302030304, q28);
18165 ASSERT_EQUAL_128(0x0705050305030301, 0x0103030503050507, q29);
18166
18167 TEARDOWN();
18168}
18169
18170TEST(neon_2regmisc_rev) {
18171 SETUP();
18172
18173 START();
18174
18175 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18176 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18177
18178 __ Rev16(v16.V8B() , v0.V8B());
18179 __ Rev16(v17.V16B(), v0.V16B());
18180
18181 __ Rev32(v18.V8B() , v0.V8B());
18182 __ Rev32(v19.V16B(), v0.V16B());
18183 __ Rev32(v20.V4H() , v0.V4H());
18184 __ Rev32(v21.V8H() , v0.V8H());
18185
18186 __ Rev64(v22.V8B() , v0.V8B());
18187 __ Rev64(v23.V16B(), v0.V16B());
18188 __ Rev64(v24.V4H() , v0.V4H());
18189 __ Rev64(v25.V8H() , v0.V8H());
18190 __ Rev64(v26.V2S() , v0.V2S());
18191 __ Rev64(v27.V4S() , v0.V4S());
18192
18193 __ Rbit(v28.V8B() , v1.V8B());
18194 __ Rbit(v29.V16B(), v1.V16B());
18195
18196 END();
18197
18198 RUN();
18199
18200 ASSERT_EQUAL_128(0x0000000000000000, 0x09080b0a0d0c0f0e, q16);
18201 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q17);
18202
18203 ASSERT_EQUAL_128(0x0000000000000000, 0x0b0a09080f0e0d0c, q18);
18204 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q19);
18205 ASSERT_EQUAL_128(0x0000000000000000, 0x0a0b08090e0f0c0d, q20);
18206 ASSERT_EQUAL_128(0x0203000106070405, 0x0a0b08090e0f0c0d, q21);
18207
18208 ASSERT_EQUAL_128(0x0000000000000000, 0x0f0e0d0c0b0a0908, q22);
18209 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q23);
18210 ASSERT_EQUAL_128(0x0000000000000000, 0x0e0f0c0d0a0b0809, q24);
18211 ASSERT_EQUAL_128(0x0607040502030001, 0x0e0f0c0d0a0b0809, q25);
18212 ASSERT_EQUAL_128(0x0000000000000000, 0x0c0d0e0f08090a0b, q26);
18213 ASSERT_EQUAL_128(0x0405060700010203, 0x0c0d0e0f08090a0b, q27);
18214
18215 ASSERT_EQUAL_128(0x0000000000000000, 0x80c4a2e691d5b3f7, q28);
18216 ASSERT_EQUAL_128(0x7f3b5d196e2a4c08, 0x80c4a2e691d5b3f7, q29);
18217
18218 TEARDOWN();
18219}
18220
18221
18222TEST(neon_sli) {
18223 SETUP();
18224
18225 START();
18226
18227 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18228 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18229
18230 __ Mov(v16.V2D(), v0.V2D());
18231 __ Mov(v17.V2D(), v0.V2D());
18232 __ Mov(v18.V2D(), v0.V2D());
18233 __ Mov(v19.V2D(), v0.V2D());
18234 __ Mov(v20.V2D(), v0.V2D());
18235 __ Mov(v21.V2D(), v0.V2D());
18236 __ Mov(v22.V2D(), v0.V2D());
18237 __ Mov(v23.V2D(), v0.V2D());
18238
18239 __ Sli(v16.V8B(), v1.V8B(), 4);
18240 __ Sli(v17.V16B(), v1.V16B(), 7);
18241 __ Sli(v18.V4H(), v1.V4H(), 8);
18242 __ Sli(v19.V8H(), v1.V8H(), 15);
18243 __ Sli(v20.V2S(), v1.V2S(), 0);
18244 __ Sli(v21.V4S(), v1.V4S(), 31);
18245 __ Sli(v22.V2D(), v1.V2D(), 48);
18246
18247 __ Sli(d23, d1, 48);
18248
18249 END();
18250
18251 RUN();
18252
18253 ASSERT_EQUAL_128(0x0000000000000000, 0x18395a7b9cbddeff, q16);
18254 ASSERT_EQUAL_128(0x0001020304050607, 0x88898a8b8c8d8e8f, q17);
18255 ASSERT_EQUAL_128(0x0000000000000000, 0x2309670bab0def0f, q18);
18256 ASSERT_EQUAL_128(0x0001020304050607, 0x88098a0b8c0d8e0f, q19);
18257 ASSERT_EQUAL_128(0x0000000000000000, 0x0123456789abcdef, q20);
18258 ASSERT_EQUAL_128(0x0001020304050607, 0x88090a0b8c0d0e0f, q21);
18259 ASSERT_EQUAL_128(0x3210020304050607, 0xcdef0a0b0c0d0e0f, q22);
18260
18261 ASSERT_EQUAL_128(0x0000000000000000, 0xcdef0a0b0c0d0e0f, q23);
18262
18263
18264 TEARDOWN();
18265}
18266
18267
18268TEST(neon_sri) {
18269 SETUP();
18270
18271 START();
18272
18273 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18274 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18275
18276 __ Mov(v16.V2D(), v0.V2D());
18277 __ Mov(v17.V2D(), v0.V2D());
18278 __ Mov(v18.V2D(), v0.V2D());
18279 __ Mov(v19.V2D(), v0.V2D());
18280 __ Mov(v20.V2D(), v0.V2D());
18281 __ Mov(v21.V2D(), v0.V2D());
18282 __ Mov(v22.V2D(), v0.V2D());
18283 __ Mov(v23.V2D(), v0.V2D());
18284
18285 __ Sri(v16.V8B(), v1.V8B(), 4);
18286 __ Sri(v17.V16B(), v1.V16B(), 7);
18287 __ Sri(v18.V4H(), v1.V4H(), 8);
18288 __ Sri(v19.V8H(), v1.V8H(), 15);
18289 __ Sri(v20.V2S(), v1.V2S(), 1);
18290 __ Sri(v21.V4S(), v1.V4S(), 31);
18291 __ Sri(v22.V2D(), v1.V2D(), 48);
18292
18293 __ Sri(d23, d1, 48);
18294
18295 END();
18296
18297 RUN();
18298
18299 ASSERT_EQUAL_128(0x0000000000000000, 0x00020406080a0c0e, q16);
18300 ASSERT_EQUAL_128(0x0101030304040606, 0x08080a0a0d0d0f0f, q17);
18301 ASSERT_EQUAL_128(0x0000000000000000, 0x08010a450c890ecd, q18);
18302 ASSERT_EQUAL_128(0x0001020304040606, 0x08080a0a0c0d0e0f, q19);
18303 ASSERT_EQUAL_128(0x0000000000000000, 0x0091a2b344d5e6f7, q20);
18304 ASSERT_EQUAL_128(0x0001020304050606, 0x08090a0a0c0d0e0f, q21);
18305 ASSERT_EQUAL_128(0x000102030405fedc, 0x08090a0b0c0d0123, q22);
18306
18307 ASSERT_EQUAL_128(0x0000000000000000, 0x08090a0b0c0d0123, q23);
18308
18309
18310 TEARDOWN();
18311}
18312
18313
18314TEST(neon_shrn) {
18315 SETUP();
18316
18317 START();
18318
18319 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18320 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18321 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18322 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18323 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18324
18325 __ Shrn(v16.V8B(), v0.V8H(), 8);
18326 __ Shrn2(v16.V16B(), v1.V8H(), 1);
18327 __ Shrn(v17.V4H(), v1.V4S(), 16);
18328 __ Shrn2(v17.V8H(), v2.V4S(), 1);
18329 __ Shrn(v18.V2S(), v3.V2D(), 32);
18330 __ Shrn2(v18.V4S(), v3.V2D(), 1);
18331
18332 END();
18333
18334 RUN();
18335 ASSERT_EQUAL_128(0x0000ff00ff0000ff, 0x7f00817f80ff0180, q16);
18336 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x8000ffffffff0001, q17);
18337 ASSERT_EQUAL_128(0x00000000ffffffff, 0x800000007fffffff, q18);
18338 TEARDOWN();
18339}
18340
18341
18342TEST(neon_rshrn) {
18343 SETUP();
18344
18345 START();
18346
18347 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18348 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18349 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18350 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18351 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18352
18353 __ Rshrn(v16.V8B(), v0.V8H(), 8);
18354 __ Rshrn2(v16.V16B(), v1.V8H(), 1);
18355 __ Rshrn(v17.V4H(), v1.V4S(), 16);
18356 __ Rshrn2(v17.V8H(), v2.V4S(), 1);
18357 __ Rshrn(v18.V2S(), v3.V2D(), 32);
18358 __ Rshrn2(v18.V4S(), v3.V2D(), 1);
18359
18360 END();
18361
18362 RUN();
18363 ASSERT_EQUAL_128(0x0001000000000100, 0x7f01827f81ff0181, q16);
18364 ASSERT_EQUAL_128(0x0000000000000000, 0x8001ffffffff0001, q17);
18365 ASSERT_EQUAL_128(0x0000000100000000, 0x8000000080000000, q18);
18366 TEARDOWN();
18367}
18368
18369
18370TEST(neon_uqshrn) {
18371 SETUP();
18372
18373 START();
18374
18375 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18376 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18377 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18378 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18379 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18380
18381 __ Uqshrn(v16.V8B(), v0.V8H(), 8);
18382 __ Uqshrn2(v16.V16B(), v1.V8H(), 1);
18383 __ Uqshrn(v17.V4H(), v1.V4S(), 16);
18384 __ Uqshrn2(v17.V8H(), v2.V4S(), 1);
18385 __ Uqshrn(v18.V2S(), v3.V2D(), 32);
18386 __ Uqshrn2(v18.V4S(), v3.V2D(), 1);
18387
18388 __ Uqshrn(b19, h0, 8);
18389 __ Uqshrn(h20, s1, 16);
18390 __ Uqshrn(s21, d3, 32);
18391
18392 END();
18393
18394 RUN();
18395 ASSERT_EQUAL_128(0xffffff00ff0000ff, 0x7f00817f80ff0180, q16);
18396 ASSERT_EQUAL_128(0xffffffff0000ffff, 0x8000ffffffff0001, q17);
18397 ASSERT_EQUAL_128(0xffffffffffffffff, 0x800000007fffffff, q18);
18398 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000080, q19);
18399 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18400 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18401 TEARDOWN();
18402}
18403
18404
18405TEST(neon_uqrshrn) {
18406 SETUP();
18407
18408 START();
18409
18410 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18411 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18412 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18413 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18414 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18415
18416 __ Uqrshrn(v16.V8B(), v0.V8H(), 8);
18417 __ Uqrshrn2(v16.V16B(), v1.V8H(), 1);
18418 __ Uqrshrn(v17.V4H(), v1.V4S(), 16);
18419 __ Uqrshrn2(v17.V8H(), v2.V4S(), 1);
18420 __ Uqrshrn(v18.V2S(), v3.V2D(), 32);
18421 __ Uqrshrn2(v18.V4S(), v3.V2D(), 1);
18422
18423 __ Uqrshrn(b19, h0, 8);
18424 __ Uqrshrn(h20, s1, 16);
18425 __ Uqrshrn(s21, d3, 32);
18426
18427 END();
18428
18429 RUN();
18430 ASSERT_EQUAL_128(0xffffff00ff0001ff, 0x7f01827f81ff0181, q16);
18431 ASSERT_EQUAL_128(0xffffffff0000ffff, 0x8001ffffffff0001, q17);
18432 ASSERT_EQUAL_128(0xffffffffffffffff, 0x8000000080000000, q18);
18433 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000081, q19);
18434 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18435 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000000, q21);
18436 TEARDOWN();
18437}
18438
18439
18440TEST(neon_sqshrn) {
18441 SETUP();
18442
18443 START();
18444
18445 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18446 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18447 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18448 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18449 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18450
18451 __ Sqshrn(v16.V8B(), v0.V8H(), 8);
18452 __ Sqshrn2(v16.V16B(), v1.V8H(), 1);
18453 __ Sqshrn(v17.V4H(), v1.V4S(), 16);
18454 __ Sqshrn2(v17.V8H(), v2.V4S(), 1);
18455 __ Sqshrn(v18.V2S(), v3.V2D(), 32);
18456 __ Sqshrn2(v18.V4S(), v3.V2D(), 1);
18457
18458 __ Sqshrn(b19, h0, 8);
18459 __ Sqshrn(h20, s1, 16);
18460 __ Sqshrn(s21, d3, 32);
18461
18462 END();
18463
18464 RUN();
18465 ASSERT_EQUAL_128(0x8080ff00ff00007f, 0x7f00817f80ff0180, q16);
18466 ASSERT_EQUAL_128(0x8000ffff00007fff, 0x8000ffffffff0001, q17);
18467 ASSERT_EQUAL_128(0x800000007fffffff, 0x800000007fffffff, q18);
18468 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000080, q19);
18469 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18470 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18471 TEARDOWN();
18472}
18473
18474
18475TEST(neon_sqrshrn) {
18476 SETUP();
18477
18478 START();
18479
18480 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18481 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18482 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18483 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18484 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18485
18486 __ Sqrshrn(v16.V8B(), v0.V8H(), 8);
18487 __ Sqrshrn2(v16.V16B(), v1.V8H(), 1);
18488 __ Sqrshrn(v17.V4H(), v1.V4S(), 16);
18489 __ Sqrshrn2(v17.V8H(), v2.V4S(), 1);
18490 __ Sqrshrn(v18.V2S(), v3.V2D(), 32);
18491 __ Sqrshrn2(v18.V4S(), v3.V2D(), 1);
18492
18493 __ Sqrshrn(b19, h0, 8);
18494 __ Sqrshrn(h20, s1, 16);
18495 __ Sqrshrn(s21, d3, 32);
18496
18497 END();
18498
18499 RUN();
18500 ASSERT_EQUAL_128(0x808000000000017f, 0x7f01827f81ff0181, q16);
18501 ASSERT_EQUAL_128(0x8000000000007fff, 0x8001ffffffff0001, q17);
18502 ASSERT_EQUAL_128(0x800000007fffffff, 0x800000007fffffff, q18);
18503 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000081, q19);
18504 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18505 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18506 TEARDOWN();
18507}
18508
18509
18510TEST(neon_sqshrun) {
18511 SETUP();
18512
18513 START();
18514
18515 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18516 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18517 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18518 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18519 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18520
18521 __ Sqshrun(v16.V8B(), v0.V8H(), 8);
18522 __ Sqshrun2(v16.V16B(), v1.V8H(), 1);
18523 __ Sqshrun(v17.V4H(), v1.V4S(), 16);
18524 __ Sqshrun2(v17.V8H(), v2.V4S(), 1);
18525 __ Sqshrun(v18.V2S(), v3.V2D(), 32);
18526 __ Sqshrun2(v18.V4S(), v3.V2D(), 1);
18527
18528 __ Sqshrun(b19, h0, 8);
18529 __ Sqshrun(h20, s1, 16);
18530 __ Sqshrun(s21, d3, 32);
18531
18532 END();
18533
18534 RUN();
18535 ASSERT_EQUAL_128(0x00000000000000ff, 0x7f00007f00000100, q16);
18536 ASSERT_EQUAL_128(0x000000000000ffff, 0x0000000000000001, q17);
18537 ASSERT_EQUAL_128(0x00000000ffffffff, 0x000000007fffffff, q18);
18538 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q19);
18539 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18540 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18541 TEARDOWN();
18542}
18543
18544
18545TEST(neon_sqrshrun) {
18546 SETUP();
18547
18548 START();
18549
18550 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18551 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18552 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18553 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18554 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18555
18556 __ Sqrshrun(v16.V8B(), v0.V8H(), 8);
18557 __ Sqrshrun2(v16.V16B(), v1.V8H(), 1);
18558 __ Sqrshrun(v17.V4H(), v1.V4S(), 16);
18559 __ Sqrshrun2(v17.V8H(), v2.V4S(), 1);
18560 __ Sqrshrun(v18.V2S(), v3.V2D(), 32);
18561 __ Sqrshrun2(v18.V4S(), v3.V2D(), 1);
18562
18563 __ Sqrshrun(b19, h0, 8);
18564 __ Sqrshrun(h20, s1, 16);
18565 __ Sqrshrun(s21, d3, 32);
18566
18567 END();
18568
18569 RUN();
18570 ASSERT_EQUAL_128(0x00000000000001ff, 0x7f01007f00000100, q16);
18571 ASSERT_EQUAL_128(0x000000000000ffff, 0x0000000000000001, q17);
18572 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000000080000000, q18);
18573 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q19);
18574 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18575 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000000, q21);
18576 TEARDOWN();
18577}
18578
18579TEST(neon_modimm_bic) {
18580 SETUP();
18581
18582 START();
18583
18584 __ Movi(v16.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18585 __ Movi(v17.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18586 __ Movi(v18.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18587 __ Movi(v19.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18588 __ Movi(v20.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18589 __ Movi(v21.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18590 __ Movi(v22.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18591 __ Movi(v23.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18592 __ Movi(v24.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18593 __ Movi(v25.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18594 __ Movi(v26.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18595 __ Movi(v27.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18596
18597 __ Bic(v16.V4H(), 0x00, 0);
18598 __ Bic(v17.V4H(), 0xff, 8);
18599 __ Bic(v18.V8H(), 0x00, 0);
18600 __ Bic(v19.V8H(), 0xff, 8);
18601
18602 __ Bic(v20.V2S(), 0x00, 0);
18603 __ Bic(v21.V2S(), 0xff, 8);
18604 __ Bic(v22.V2S(), 0x00, 16);
18605 __ Bic(v23.V2S(), 0xff, 24);
18606
18607 __ Bic(v24.V4S(), 0xff, 0);
18608 __ Bic(v25.V4S(), 0x00, 8);
18609 __ Bic(v26.V4S(), 0xff, 16);
18610 __ Bic(v27.V4S(), 0x00, 24);
18611
18612 END();
18613
18614 RUN();
18615
18616 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q16);
18617 ASSERT_EQUAL_128(0x0, 0x005500ff000000aa, q17);
18618 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q18);
18619 ASSERT_EQUAL_128(0x00aa0055000000aa, 0x005500ff000000aa, q19);
18620
18621 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q20);
18622 ASSERT_EQUAL_128(0x0, 0x555500ff000000aa, q21);
18623 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q22);
18624 ASSERT_EQUAL_128(0x0, 0x0055ffff0000aaaa, q23);
18625
18626 ASSERT_EQUAL_128(0x00aaff00ff005500, 0x5555ff000000aa00, q24);
18627 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q25);
18628 ASSERT_EQUAL_128(0x0000ff55ff0055aa, 0x5500ffff0000aaaa, q26);
18629 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q27);
18630
18631 TEARDOWN();
18632}
18633
18634
18635TEST(neon_modimm_movi_16bit_any) {
18636 SETUP();
18637
18638 START();
18639
18640 __ Movi(v0.V4H(), 0xabab);
18641 __ Movi(v1.V4H(), 0xab00);
18642 __ Movi(v2.V4H(), 0xabff);
18643 __ Movi(v3.V8H(), 0x00ab);
18644 __ Movi(v4.V8H(), 0xffab);
18645 __ Movi(v5.V8H(), 0xabcd);
18646
18647 END();
18648
18649 RUN();
18650
18651 ASSERT_EQUAL_128(0x0, 0xabababababababab, q0);
18652 ASSERT_EQUAL_128(0x0, 0xab00ab00ab00ab00, q1);
18653 ASSERT_EQUAL_128(0x0, 0xabffabffabffabff, q2);
18654 ASSERT_EQUAL_128(0x00ab00ab00ab00ab, 0x00ab00ab00ab00ab, q3);
18655 ASSERT_EQUAL_128(0xffabffabffabffab, 0xffabffabffabffab, q4);
18656 ASSERT_EQUAL_128(0xabcdabcdabcdabcd, 0xabcdabcdabcdabcd, q5);
18657
18658 TEARDOWN();
18659}
18660
18661
18662TEST(neon_modimm_movi_32bit_any) {
18663 SETUP();
18664
18665 START();
18666
18667 __ Movi(v0.V2S(), 0x000000ab);
18668 __ Movi(v1.V2S(), 0x0000ab00);
18669 __ Movi(v2.V4S(), 0x00ab0000);
18670 __ Movi(v3.V4S(), 0xab000000);
18671
18672 __ Movi(v4.V2S(), 0xffffffab);
18673 __ Movi(v5.V2S(), 0xffffabff);
18674 __ Movi(v6.V4S(), 0xffabffff);
18675 __ Movi(v7.V4S(), 0xabffffff);
18676
18677 __ Movi(v16.V2S(), 0x0000abff);
18678 __ Movi(v17.V2S(), 0x00abffff);
18679 __ Movi(v18.V4S(), 0xffab0000);
18680 __ Movi(v19.V4S(), 0xffffab00);
18681
18682 __ Movi(v20.V4S(), 0xabababab);
18683 __ Movi(v21.V4S(), 0xabcdabcd);
18684 __ Movi(v22.V4S(), 0xabcdef01);
18685 __ Movi(v23.V4S(), 0x00ffff00);
18686
18687 END();
18688
18689 RUN();
18690
18691 ASSERT_EQUAL_128(0x0, 0x000000ab000000ab, q0);
18692 ASSERT_EQUAL_128(0x0, 0x0000ab000000ab00, q1);
18693 ASSERT_EQUAL_128(0x00ab000000ab0000, 0x00ab000000ab0000, q2);
18694 ASSERT_EQUAL_128(0xab000000ab000000, 0xab000000ab000000, q3);
18695
18696 ASSERT_EQUAL_128(0x0, 0xffffffabffffffab, q4);
18697 ASSERT_EQUAL_128(0x0, 0xffffabffffffabff, q5);
18698 ASSERT_EQUAL_128(0xffabffffffabffff, 0xffabffffffabffff, q6);
18699 ASSERT_EQUAL_128(0xabffffffabffffff, 0xabffffffabffffff, q7);
18700
18701 ASSERT_EQUAL_128(0x0, 0x0000abff0000abff, q16);
18702 ASSERT_EQUAL_128(0x0, 0x00abffff00abffff, q17);
18703 ASSERT_EQUAL_128(0xffab0000ffab0000, 0xffab0000ffab0000, q18);
18704 ASSERT_EQUAL_128(0xffffab00ffffab00, 0xffffab00ffffab00, q19);
18705
18706 ASSERT_EQUAL_128(0xabababababababab, 0xabababababababab, q20);
18707 ASSERT_EQUAL_128(0xabcdabcdabcdabcd, 0xabcdabcdabcdabcd, q21);
18708 ASSERT_EQUAL_128(0xabcdef01abcdef01, 0xabcdef01abcdef01, q22);
18709 ASSERT_EQUAL_128(0x00ffff0000ffff00, 0x00ffff0000ffff00, q23);
18710 TEARDOWN();
18711}
18712
18713
18714TEST(neon_modimm_movi_64bit_any) {
18715 SETUP();
18716
18717 START();
18718
18719 __ Movi(v0.V1D(), 0x00ffff0000ffffff);
18720 __ Movi(v1.V2D(), 0xabababababababab);
18721 __ Movi(v2.V2D(), 0xabcdabcdabcdabcd);
18722 __ Movi(v3.V2D(), 0xabcdef01abcdef01);
18723 __ Movi(v4.V1D(), 0xabcdef0123456789);
18724 __ Movi(v5.V2D(), 0xabcdef0123456789);
18725
18726 END();
18727
18728 RUN();
18729
18730 ASSERT_EQUAL_128(0x0, 0x00ffff0000ffffff, q0);
18731 ASSERT_EQUAL_128(0xabababababababab, 0xabababababababab, q1);
18732 ASSERT_EQUAL_128(0xabcdabcdabcdabcd, 0xabcdabcdabcdabcd, q2);
18733 ASSERT_EQUAL_128(0xabcdef01abcdef01, 0xabcdef01abcdef01, q3);
18734 ASSERT_EQUAL_128(0x0, 0xabcdef0123456789, q4);
18735 ASSERT_EQUAL_128(0xabcdef0123456789, 0xabcdef0123456789, q5);
18736
18737 TEARDOWN();
18738}
18739
18740
18741TEST(neon_modimm_movi) {
18742 SETUP();
18743
18744 START();
18745
18746 __ Movi(v0.V8B(), 0xaa);
18747 __ Movi(v1.V16B(), 0x55);
18748
18749 __ Movi(d2, 0x00ffff0000ffffff);
18750 __ Movi(v3.V2D(), 0x00ffff0000ffffff);
18751
18752 __ Movi(v16.V4H(), 0x00, LSL, 0);
18753 __ Movi(v17.V4H(), 0xff, LSL, 8);
18754 __ Movi(v18.V8H(), 0x00, LSL, 0);
18755 __ Movi(v19.V8H(), 0xff, LSL, 8);
18756
18757 __ Movi(v20.V2S(), 0x00, LSL, 0);
18758 __ Movi(v21.V2S(), 0xff, LSL, 8);
18759 __ Movi(v22.V2S(), 0x00, LSL, 16);
18760 __ Movi(v23.V2S(), 0xff, LSL, 24);
18761
18762 __ Movi(v24.V4S(), 0xff, LSL, 0);
18763 __ Movi(v25.V4S(), 0x00, LSL, 8);
18764 __ Movi(v26.V4S(), 0xff, LSL, 16);
18765 __ Movi(v27.V4S(), 0x00, LSL, 24);
18766
18767 __ Movi(v28.V2S(), 0xaa, MSL, 8);
18768 __ Movi(v29.V2S(), 0x55, MSL, 16);
18769 __ Movi(v30.V4S(), 0xff, MSL, 8);
18770 __ Movi(v31.V4S(), 0x00, MSL, 16);
18771
18772 END();
18773
18774 RUN();
18775
18776 ASSERT_EQUAL_128(0x0, 0xaaaaaaaaaaaaaaaa, q0);
18777 ASSERT_EQUAL_128(0x5555555555555555, 0x5555555555555555, q1);
18778
18779 ASSERT_EQUAL_128(0x0, 0x00ffff0000ffffff, q2);
18780 ASSERT_EQUAL_128(0x00ffff0000ffffff, 0x00ffff0000ffffff, q3);
18781
18782 ASSERT_EQUAL_128(0x0, 0x0000000000000000, q16);
18783 ASSERT_EQUAL_128(0x0, 0xff00ff00ff00ff00, q17);
18784 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q18);
18785 ASSERT_EQUAL_128(0xff00ff00ff00ff00, 0xff00ff00ff00ff00, q19);
18786
18787 ASSERT_EQUAL_128(0x0, 0x0000000000000000, q20);
18788 ASSERT_EQUAL_128(0x0, 0x0000ff000000ff00, q21);
18789 ASSERT_EQUAL_128(0x0, 0x0000000000000000, q22);
18790 ASSERT_EQUAL_128(0x0, 0xff000000ff000000, q23);
18791
18792 ASSERT_EQUAL_128(0x000000ff000000ff, 0x000000ff000000ff, q24);
18793 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
18794 ASSERT_EQUAL_128(0x00ff000000ff0000, 0x00ff000000ff0000, q26);
18795 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q27);
18796
18797 ASSERT_EQUAL_128(0x0, 0x0000aaff0000aaff, q28);
18798 ASSERT_EQUAL_128(0x0, 0x0055ffff0055ffff, q29);
18799 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x0000ffff0000ffff, q30);
18800 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x0000ffff0000ffff, q31);
18801
18802 TEARDOWN();
18803}
18804
18805
18806TEST(neon_modimm_mvni) {
18807 SETUP();
18808
18809 START();
18810
18811 __ Mvni(v16.V4H(), 0x00, LSL, 0);
18812 __ Mvni(v17.V4H(), 0xff, LSL, 8);
18813 __ Mvni(v18.V8H(), 0x00, LSL, 0);
18814 __ Mvni(v19.V8H(), 0xff, LSL, 8);
18815
18816 __ Mvni(v20.V2S(), 0x00, LSL, 0);
18817 __ Mvni(v21.V2S(), 0xff, LSL, 8);
18818 __ Mvni(v22.V2S(), 0x00, LSL, 16);
18819 __ Mvni(v23.V2S(), 0xff, LSL, 24);
18820
18821 __ Mvni(v24.V4S(), 0xff, LSL, 0);
18822 __ Mvni(v25.V4S(), 0x00, LSL, 8);
18823 __ Mvni(v26.V4S(), 0xff, LSL, 16);
18824 __ Mvni(v27.V4S(), 0x00, LSL, 24);
18825
18826 __ Mvni(v28.V2S(), 0xaa, MSL, 8);
18827 __ Mvni(v29.V2S(), 0x55, MSL, 16);
18828 __ Mvni(v30.V4S(), 0xff, MSL, 8);
18829 __ Mvni(v31.V4S(), 0x00, MSL, 16);
18830
18831 END();
18832
18833 RUN();
18834
18835 ASSERT_EQUAL_128(0x0, 0xffffffffffffffff, q16);
18836 ASSERT_EQUAL_128(0x0, 0x00ff00ff00ff00ff, q17);
18837 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q18);
18838 ASSERT_EQUAL_128(0x00ff00ff00ff00ff, 0x00ff00ff00ff00ff, q19);
18839
18840 ASSERT_EQUAL_128(0x0, 0xffffffffffffffff, q20);
18841 ASSERT_EQUAL_128(0x0, 0xffff00ffffff00ff, q21);
18842 ASSERT_EQUAL_128(0x0, 0xffffffffffffffff, q22);
18843 ASSERT_EQUAL_128(0x0, 0x00ffffff00ffffff, q23);
18844
18845 ASSERT_EQUAL_128(0xffffff00ffffff00, 0xffffff00ffffff00, q24);
18846 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
18847 ASSERT_EQUAL_128(0xff00ffffff00ffff, 0xff00ffffff00ffff, q26);
18848 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q27);
18849
18850 ASSERT_EQUAL_128(0x0, 0xffff5500ffff5500, q28);
18851 ASSERT_EQUAL_128(0x0, 0xffaa0000ffaa0000, q29);
18852 ASSERT_EQUAL_128(0xffff0000ffff0000, 0xffff0000ffff0000, q30);
18853 ASSERT_EQUAL_128(0xffff0000ffff0000, 0xffff0000ffff0000, q31);
18854
18855 TEARDOWN();
18856}
18857
18858
18859TEST(neon_modimm_orr) {
18860 SETUP();
18861
18862 START();
18863
18864 __ Movi(v16.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18865 __ Movi(v17.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18866 __ Movi(v18.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18867 __ Movi(v19.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18868 __ Movi(v20.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18869 __ Movi(v21.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18870 __ Movi(v22.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18871 __ Movi(v23.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18872 __ Movi(v24.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18873 __ Movi(v25.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18874 __ Movi(v26.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18875 __ Movi(v27.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18876
18877 __ Orr(v16.V4H(), 0x00, 0);
18878 __ Orr(v17.V4H(), 0xff, 8);
18879 __ Orr(v18.V8H(), 0x00, 0);
18880 __ Orr(v19.V8H(), 0xff, 8);
18881
18882 __ Orr(v20.V2S(), 0x00, 0);
18883 __ Orr(v21.V2S(), 0xff, 8);
18884 __ Orr(v22.V2S(), 0x00, 16);
18885 __ Orr(v23.V2S(), 0xff, 24);
18886
18887 __ Orr(v24.V4S(), 0xff, 0);
18888 __ Orr(v25.V4S(), 0x00, 8);
18889 __ Orr(v26.V4S(), 0xff, 16);
18890 __ Orr(v27.V4S(), 0x00, 24);
18891
18892 END();
18893
18894 RUN();
18895
18896 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q16);
18897 ASSERT_EQUAL_128(0x0, 0xff55ffffff00ffaa, q17);
18898 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q18);
18899 ASSERT_EQUAL_128(0xffaaff55ff00ffaa, 0xff55ffffff00ffaa, q19);
18900
18901 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q20);
18902 ASSERT_EQUAL_128(0x0, 0x5555ffff0000ffaa, q21);
18903 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q22);
18904 ASSERT_EQUAL_128(0x0, 0xff55ffffff00aaaa, q23);
18905
18906 ASSERT_EQUAL_128(0x00aaffffff0055ff, 0x5555ffff0000aaff, q24);
18907 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q25);
18908 ASSERT_EQUAL_128(0x00ffff55ffff55aa, 0x55ffffff00ffaaaa, q26);
18909 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q27);
18910
18911 TEARDOWN();
18912}
18913
18914
18915// TODO: add arbitrary values once load literal to Q registers is supported.
18916TEST(neon_modimm_fmov) {
18917 SETUP();
18918
18919 // Immediates which can be encoded in the instructions.
18920 const float kOne = 1.0f;
18921 const float kPointFive = 0.5f;
18922 const double kMinusThirteen = -13.0;
18923 // Immediates which cannot be encoded in the instructions.
18924 const float kNonImmFP32 = 255.0f;
18925 const double kNonImmFP64 = 12.3456;
18926
18927 START();
18928 __ Fmov(v11.V2S(), kOne);
18929 __ Fmov(v12.V4S(), kPointFive);
18930 __ Fmov(v22.V2D(), kMinusThirteen);
18931 __ Fmov(v13.V2S(), kNonImmFP32);
18932 __ Fmov(v14.V4S(), kNonImmFP32);
18933 __ Fmov(v23.V2D(), kNonImmFP64);
18934 __ Fmov(v1.V2S(), 0.0);
18935 __ Fmov(v2.V4S(), 0.0);
18936 __ Fmov(v3.V2D(), 0.0);
18937 __ Fmov(v4.V2S(), kFP32PositiveInfinity);
18938 __ Fmov(v5.V4S(), kFP32PositiveInfinity);
18939 __ Fmov(v6.V2D(), kFP64PositiveInfinity);
18940 END();
18941
18942 RUN();
18943
18944 const uint64_t kOne1S = float_to_rawbits(1.0);
18945 const uint64_t kOne2S = (kOne1S << 32) | kOne1S;
18946 const uint64_t kPointFive1S = float_to_rawbits(0.5);
18947 const uint64_t kPointFive2S = (kPointFive1S << 32) | kPointFive1S;
18948 const uint64_t kMinusThirteen1D = double_to_rawbits(-13.0);
18949 const uint64_t kNonImmFP321S = float_to_rawbits(kNonImmFP32);
18950 const uint64_t kNonImmFP322S = (kNonImmFP321S << 32) | kNonImmFP321S;
18951 const uint64_t kNonImmFP641D = double_to_rawbits(kNonImmFP64);
18952 const uint64_t kFP32Inf1S = float_to_rawbits(kFP32PositiveInfinity);
18953 const uint64_t kFP32Inf2S = (kFP32Inf1S << 32) | kFP32Inf1S;
18954 const uint64_t kFP64Inf1D = double_to_rawbits(kFP64PositiveInfinity);
18955
18956 ASSERT_EQUAL_128(0x0, kOne2S, q11);
18957 ASSERT_EQUAL_128(kPointFive2S, kPointFive2S, q12);
18958 ASSERT_EQUAL_128(kMinusThirteen1D, kMinusThirteen1D, q22);
18959 ASSERT_EQUAL_128(0x0, kNonImmFP322S, q13);
18960 ASSERT_EQUAL_128(kNonImmFP322S, kNonImmFP322S, q14);
18961 ASSERT_EQUAL_128(kNonImmFP641D, kNonImmFP641D, q23);
18962 ASSERT_EQUAL_128(0x0, 0x0, q1);
18963 ASSERT_EQUAL_128(0x0, 0x0, q2);
18964 ASSERT_EQUAL_128(0x0, 0x0, q3);
18965 ASSERT_EQUAL_128(0x0, kFP32Inf2S, q4);
18966 ASSERT_EQUAL_128(kFP32Inf2S, kFP32Inf2S, q5);
18967 ASSERT_EQUAL_128(kFP64Inf1D, kFP64Inf1D, q6);
18968
18969 TEARDOWN();
18970}
18971
18972
18973TEST(neon_perm) {
18974 SETUP();
18975
18976 START();
18977
18978 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18979 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
18980
18981 __ Trn1(v16.V16B(), v0.V16B(), v1.V16B());
18982 __ Trn2(v17.V16B(), v0.V16B(), v1.V16B());
18983 __ Zip1(v18.V16B(), v0.V16B(), v1.V16B());
18984 __ Zip2(v19.V16B(), v0.V16B(), v1.V16B());
18985 __ Uzp1(v20.V16B(), v0.V16B(), v1.V16B());
18986 __ Uzp2(v21.V16B(), v0.V16B(), v1.V16B());
18987
18988 END();
18989
18990 RUN();
18991
18992 ASSERT_EQUAL_128(0x1101130315051707, 0x19091b0b1d0d1f0f, q16);
18993 ASSERT_EQUAL_128(0x1000120214041606, 0x18081a0a1c0c1e0e, q17);
18994 ASSERT_EQUAL_128(0x180819091a0a1b0b, 0x1c0c1d0d1e0e1f0f, q18);
18995 ASSERT_EQUAL_128(0x1000110112021303, 0x1404150516061707, q19);
18996 ASSERT_EQUAL_128(0x11131517191b1d1f, 0x01030507090b0d0f, q20);
18997 ASSERT_EQUAL_128(0x10121416181a1c1e, 0x00020406080a0c0e, q21);
18998
18999 TEARDOWN();
19000}
19001
19002
19003TEST(neon_copy_dup_element) {
19004 SETUP();
19005
19006 START();
19007
19008 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19009 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19010 __ Movi(v2.V2D(), 0xffeddccbbaae9988, 0x0011223344556677);
19011 __ Movi(v3.V2D(), 0x7766554433221100, 0x8899aabbccddeeff);
19012 __ Movi(v4.V2D(), 0x7766554433221100, 0x0123456789abcdef);
19013 __ Movi(v5.V2D(), 0x0011223344556677, 0x0123456789abcdef);
19014
19015 __ Dup(v16.V16B(), v0.B(), 0);
19016 __ Dup(v17.V8H(), v1.H(), 7);
19017 __ Dup(v18.V4S(), v1.S(), 3);
19018 __ Dup(v19.V2D(), v0.D(), 0);
19019
19020 __ Dup(v20.V8B(), v0.B(), 0);
19021 __ Dup(v21.V4H(), v1.H(), 7);
19022 __ Dup(v22.V2S(), v1.S(), 3);
19023
19024 __ Dup(v23.B(), v0.B(), 0);
19025 __ Dup(v24.H(), v1.H(), 7);
19026 __ Dup(v25.S(), v1.S(), 3);
19027 __ Dup(v26.D(), v0.D(), 0);
19028
19029 __ Dup(v2.V16B(), v2.B(), 0);
19030 __ Dup(v3.V8H(), v3.H(), 7);
19031 __ Dup(v4.V4S(), v4.S(), 0);
19032 __ Dup(v5.V2D(), v5.D(), 1);
19033
19034 END();
19035
19036 RUN();
19037
19038 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q16);
19039 ASSERT_EQUAL_128(0xffedffedffedffed, 0xffedffedffedffed, q17);
19040 ASSERT_EQUAL_128(0xffeddccbffeddccb, 0xffeddccbffeddccb, q18);
19041 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x8899aabbccddeeff, q19);
19042
19043 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q20);
19044 ASSERT_EQUAL_128(0, 0xffedffedffedffed, q21);
19045 ASSERT_EQUAL_128(0, 0xffeddccbffeddccb, q22);
19046
19047 ASSERT_EQUAL_128(0, 0x00000000000000ff, q23);
19048 ASSERT_EQUAL_128(0, 0x000000000000ffed, q24);
19049 ASSERT_EQUAL_128(0, 0x00000000ffeddccb, q25);
19050 ASSERT_EQUAL_128(0, 0x8899aabbccddeeff, q26);
19051
19052 ASSERT_EQUAL_128(0x7777777777777777, 0x7777777777777777, q2);
19053 ASSERT_EQUAL_128(0x7766776677667766, 0x7766776677667766, q3);
19054 ASSERT_EQUAL_128(0x89abcdef89abcdef, 0x89abcdef89abcdef, q4);
19055 ASSERT_EQUAL_128(0x0011223344556677, 0x0011223344556677, q5);
19056 TEARDOWN();
19057}
19058
19059
19060TEST(neon_copy_dup_general) {
19061 SETUP();
19062
19063 START();
19064
19065 __ Mov(x0, 0x0011223344556677);
19066
19067 __ Dup(v16.V16B(), w0);
19068 __ Dup(v17.V8H(), w0);
19069 __ Dup(v18.V4S(), w0);
19070 __ Dup(v19.V2D(), x0);
19071
19072 __ Dup(v20.V8B(), w0);
19073 __ Dup(v21.V4H(), w0);
19074 __ Dup(v22.V2S(), w0);
19075
19076 __ Dup(v2.V16B(), wzr);
19077 __ Dup(v3.V8H(), wzr);
19078 __ Dup(v4.V4S(), wzr);
19079 __ Dup(v5.V2D(), xzr);
19080
19081 END();
19082
19083 RUN();
19084
19085 ASSERT_EQUAL_128(0x7777777777777777, 0x7777777777777777, q16);
19086 ASSERT_EQUAL_128(0x6677667766776677, 0x6677667766776677, q17);
19087 ASSERT_EQUAL_128(0x4455667744556677, 0x4455667744556677, q18);
19088 ASSERT_EQUAL_128(0x0011223344556677, 0x0011223344556677, q19);
19089
19090 ASSERT_EQUAL_128(0, 0x7777777777777777, q20);
19091 ASSERT_EQUAL_128(0, 0x6677667766776677, q21);
19092 ASSERT_EQUAL_128(0, 0x4455667744556677, q22);
19093
19094 ASSERT_EQUAL_128(0, 0, q2);
19095 ASSERT_EQUAL_128(0, 0, q3);
19096 ASSERT_EQUAL_128(0, 0, q4);
19097 ASSERT_EQUAL_128(0, 0, q5);
19098 TEARDOWN();
19099}
19100
19101
19102TEST(neon_copy_ins_element) {
19103 SETUP();
19104
19105 START();
19106
19107 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19108 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19109 __ Movi(v16.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19110 __ Movi(v17.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
19111 __ Movi(v18.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19112 __ Movi(v19.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19113
19114 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19115 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19116 __ Movi(v4.V2D(), 0, 0x0123456789abcdef);
19117 __ Movi(v5.V2D(), 0, 0x0123456789abcdef);
19118
19119 __ Ins(v16.V16B(), 15, v0.V16B(), 0);
19120 __ Ins(v17.V8H(), 0, v1.V8H(), 7);
19121 __ Ins(v18.V4S(), 3, v1.V4S(), 0);
19122 __ Ins(v19.V2D(), 1, v0.V2D(), 0);
19123
19124 __ Ins(v2.V16B(), 2, v2.V16B(), 0);
19125 __ Ins(v3.V8H(), 0, v3.V8H(), 7);
19126 __ Ins(v4.V4S(), 3, v4.V4S(), 0);
19127 __ Ins(v5.V2D(), 0, v5.V2D(), 1);
19128
19129 END();
19130
19131 RUN();
19132
19133 ASSERT_EQUAL_128(0xff23456789abcdef, 0xfedcba9876543210, q16);
19134 ASSERT_EQUAL_128(0xfedcba9876543210, 0x0123456789abffed, q17);
19135 ASSERT_EQUAL_128(0x3322110044556677, 0x8899aabbccddeeff, q18);
19136 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x8899aabbccddeeff, q19);
19137
19138 ASSERT_EQUAL_128(0, 0x0011223344776677, q2);
19139 ASSERT_EQUAL_128(0, 0x8899aabbccdd0000, q3);
19140 ASSERT_EQUAL_128(0x89abcdef00000000, 0x0123456789abcdef, q4);
19141 ASSERT_EQUAL_128(0, 0, q5);
19142 TEARDOWN();
19143}
19144
19145
19146TEST(neon_copy_mov_element) {
19147 SETUP();
19148
19149 START();
19150
19151 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19152 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19153 __ Movi(v16.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19154 __ Movi(v17.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
19155 __ Movi(v18.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19156 __ Movi(v19.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19157
19158 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19159 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19160 __ Movi(v4.V2D(), 0, 0x0123456789abcdef);
19161 __ Movi(v5.V2D(), 0, 0x0123456789abcdef);
19162
19163 __ Mov(v16.V16B(), 15, v0.V16B(), 0);
19164 __ Mov(v17.V8H(), 0, v1.V8H(), 7);
19165 __ Mov(v18.V4S(), 3, v1.V4S(), 0);
19166 __ Mov(v19.V2D(), 1, v0.V2D(), 0);
19167
19168 __ Mov(v2.V16B(), 2, v2.V16B(), 0);
19169 __ Mov(v3.V8H(), 0, v3.V8H(), 7);
19170 __ Mov(v4.V4S(), 3, v4.V4S(), 0);
19171 __ Mov(v5.V2D(), 0, v5.V2D(), 1);
19172
19173 END();
19174
19175 RUN();
19176
19177 ASSERT_EQUAL_128(0xff23456789abcdef, 0xfedcba9876543210, q16);
19178 ASSERT_EQUAL_128(0xfedcba9876543210, 0x0123456789abffed, q17);
19179 ASSERT_EQUAL_128(0x3322110044556677, 0x8899aabbccddeeff, q18);
19180 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x8899aabbccddeeff, q19);
19181
19182 ASSERT_EQUAL_128(0, 0x0011223344776677, q2);
19183 ASSERT_EQUAL_128(0, 0x8899aabbccdd0000, q3);
19184 ASSERT_EQUAL_128(0x89abcdef00000000, 0x0123456789abcdef, q4);
19185 ASSERT_EQUAL_128(0, 0, q5);
19186 TEARDOWN();
19187}
19188
19189
19190TEST(neon_copy_smov) {
19191 SETUP();
19192
19193 START();
19194
19195 __ Movi(v0.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19196
19197 __ Smov(w0, v0.B(), 7);
19198 __ Smov(w1, v0.B(), 15);
19199
19200 __ Smov(w2, v0.H(), 0);
19201 __ Smov(w3, v0.H(), 3);
19202
19203 __ Smov(x4, v0.B(), 7);
19204 __ Smov(x5, v0.B(), 15);
19205
19206 __ Smov(x6, v0.H(), 0);
19207 __ Smov(x7, v0.H(), 3);
19208
19209 __ Smov(x16, v0.S(), 0);
19210 __ Smov(x17, v0.S(), 1);
19211
19212 END();
19213
19214 RUN();
19215
19216 ASSERT_EQUAL_32(0xfffffffe, w0);
19217 ASSERT_EQUAL_32(0x00000001, w1);
19218 ASSERT_EQUAL_32(0x00003210, w2);
19219 ASSERT_EQUAL_32(0xfffffedc, w3);
19220 ASSERT_EQUAL_64(0xfffffffffffffffe, x4);
19221 ASSERT_EQUAL_64(0x0000000000000001, x5);
19222 ASSERT_EQUAL_64(0x0000000000003210, x6);
19223 ASSERT_EQUAL_64(0xfffffffffffffedc, x7);
19224 ASSERT_EQUAL_64(0x0000000076543210, x16);
19225 ASSERT_EQUAL_64(0xfffffffffedcba98, x17);
19226
19227 TEARDOWN();
19228}
19229
19230
19231TEST(neon_copy_umov_mov) {
19232 SETUP();
19233
19234 START();
19235
19236 __ Movi(v0.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19237
19238 __ Umov(w0, v0.B(), 15);
19239 __ Umov(w1, v0.H(), 0);
19240 __ Umov(w2, v0.S(), 3);
19241 __ Umov(x3, v0.D(), 1);
19242
19243 __ Mov(w4, v0.S(), 3);
19244 __ Mov(x5, v0.D(), 1);
19245
19246 END();
19247
19248 RUN();
19249
19250 ASSERT_EQUAL_32(0x00000001, w0);
19251 ASSERT_EQUAL_32(0x00003210, w1);
19252 ASSERT_EQUAL_32(0x01234567, w2);
19253 ASSERT_EQUAL_64(0x0123456789abcdef, x3);
19254 ASSERT_EQUAL_32(0x01234567, w4);
19255 ASSERT_EQUAL_64(0x0123456789abcdef, x5);
19256
19257 TEARDOWN();
19258}
19259
19260
19261TEST(neon_copy_ins_general) {
19262 SETUP();
19263
19264 START();
19265
19266 __ Mov(x0, 0x0011223344556677);
19267 __ Movi(v16.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19268 __ Movi(v17.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
19269 __ Movi(v18.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19270 __ Movi(v19.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19271
19272 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19273 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19274 __ Movi(v4.V2D(), 0, 0x0123456789abcdef);
19275 __ Movi(v5.V2D(), 0, 0x0123456789abcdef);
19276
19277 __ Ins(v16.V16B(), 15, w0);
19278 __ Ins(v17.V8H(), 0, w0);
19279 __ Ins(v18.V4S(), 3, w0);
19280 __ Ins(v19.V2D(), 0, x0);
19281
19282 __ Ins(v2.V16B(), 2, w0);
19283 __ Ins(v3.V8H(), 0, w0);
19284 __ Ins(v4.V4S(), 3, w0);
19285 __ Ins(v5.V2D(), 1, x0);
19286
19287 END();
19288
19289 RUN();
19290
19291 ASSERT_EQUAL_128(0x7723456789abcdef, 0xfedcba9876543210, q16);
19292 ASSERT_EQUAL_128(0xfedcba9876543210, 0x0123456789ab6677, q17);
19293 ASSERT_EQUAL_128(0x4455667744556677, 0x8899aabbccddeeff, q18);
19294 ASSERT_EQUAL_128(0x0011223344556677, 0x0011223344556677, q19);
19295
19296 ASSERT_EQUAL_128(0, 0x0011223344776677, q2);
19297 ASSERT_EQUAL_128(0, 0x8899aabbccdd6677, q3);
19298 ASSERT_EQUAL_128(0x4455667700000000, 0x0123456789abcdef, q4);
19299 ASSERT_EQUAL_128(0x0011223344556677, 0x0123456789abcdef, q5);
19300 TEARDOWN();
19301}
19302
19303
19304TEST(neon_extract_ext) {
19305 SETUP();
19306
19307 START();
19308
19309 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19310 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19311
19312 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19313 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19314
19315 __ Ext(v16.V16B(), v0.V16B(), v1.V16B(), 0);
19316 __ Ext(v17.V16B(), v0.V16B(), v1.V16B(), 15);
19317 __ Ext(v1.V16B(), v0.V16B(), v1.V16B(), 8); // Dest is same as one Src
19318 __ Ext(v0.V16B(), v0.V16B(), v0.V16B(), 8); // All reg are the same
19319
19320 __ Ext(v18.V8B(), v2.V8B(), v3.V8B(), 0);
19321 __ Ext(v19.V8B(), v2.V8B(), v3.V8B(), 7);
19322 __ Ext(v2.V8B(), v2.V8B(), v3.V8B(), 4); // Dest is same as one Src
19323 __ Ext(v3.V8B(), v3.V8B(), v3.V8B(), 4); // All reg are the same
19324
19325 END();
19326
19327 RUN();
19328
19329 ASSERT_EQUAL_128(0x0011223344556677, 0x8899aabbccddeeff, q16);
19330 ASSERT_EQUAL_128(0xeddccbbaae998877, 0x6655443322110000, q17);
19331 ASSERT_EQUAL_128(0x7766554433221100, 0x0011223344556677, q1);
19332 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x0011223344556677, q0);
19333
19334 ASSERT_EQUAL_128(0, 0x0011223344556677, q18);
19335 ASSERT_EQUAL_128(0, 0x99aabbccddeeff00, q19);
19336 ASSERT_EQUAL_128(0, 0xccddeeff00112233, q2);
19337 ASSERT_EQUAL_128(0, 0xccddeeff8899aabb, q3);
19338 TEARDOWN();
19339}
19340
19341
19342TEST(neon_3different_uaddl) {
19343 SETUP();
19344
19345 START();
19346
19347 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000);
19348 __ Movi(v1.V2D(), 0, 0x00010280810e0fff);
19349 __ Movi(v2.V2D(), 0, 0x0101010101010101);
19350
19351 __ Movi(v3.V2D(), 0x0000000000000000, 0x0000000000000000);
19352 __ Movi(v4.V2D(), 0x0000000000000000, 0x0000000000000000);
19353 __ Movi(v5.V2D(), 0, 0x0000000180008001);
19354 __ Movi(v6.V2D(), 0, 0x000e000ff000ffff);
19355 __ Movi(v7.V2D(), 0, 0x0001000100010001);
19356
19357 __ Movi(v16.V2D(), 0x0000000000000000, 0x0000000000000000);
19358 __ Movi(v17.V2D(), 0x0000000000000000, 0x0000000000000000);
19359 __ Movi(v18.V2D(), 0, 0x0000000000000001);
19360 __ Movi(v19.V2D(), 0, 0x80000001ffffffff);
19361 __ Movi(v20.V2D(), 0, 0x0000000100000001);
19362
19363 __ Uaddl(v0.V8H(), v1.V8B(), v2.V8B());
19364
19365 __ Uaddl(v3.V4S(), v5.V4H(), v7.V4H());
19366 __ Uaddl(v4.V4S(), v6.V4H(), v7.V4H());
19367
19368 __ Uaddl(v16.V2D(), v18.V2S(), v20.V2S());
19369 __ Uaddl(v17.V2D(), v19.V2S(), v20.V2S());
19370
19371
19372 END();
19373
19374 RUN();
19375
19376 ASSERT_EQUAL_128(0x0001000200030081, 0x0082000f00100100, q0);
19377 ASSERT_EQUAL_128(0x0000000100000002, 0x0000800100008002, q3);
19378 ASSERT_EQUAL_128(0x0000000f00000010, 0x0000f00100010000, q4);
19379 ASSERT_EQUAL_128(0x0000000000000001, 0x0000000000000002, q16);
19380 ASSERT_EQUAL_128(0x0000000080000002, 0x0000000100000000, q17);
19381 TEARDOWN();
19382}
19383
19384
19385TEST(neon_3different_addhn_subhn) {
19386 SETUP();
19387
19388 START();
19389
19390 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19391 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19392 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19393 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
19394 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
19395
19396 __ Addhn(v16.V8B(), v0.V8H(), v1.V8H());
19397 __ Addhn2(v16.V16B(), v2.V8H(), v3.V8H());
19398 __ Raddhn(v17.V8B(), v0.V8H(), v1.V8H());
19399 __ Raddhn2(v17.V16B(), v2.V8H(), v3.V8H());
19400 __ Subhn(v18.V8B(), v0.V8H(), v1.V8H());
19401 __ Subhn2(v18.V16B(), v2.V8H(), v3.V8H());
19402 __ Rsubhn(v19.V8B(), v0.V8H(), v1.V8H());
19403 __ Rsubhn2(v19.V16B(), v2.V8H(), v3.V8H());
19404
19405 END();
19406
19407 RUN();
19408
19409 ASSERT_EQUAL_128(0x0000ff007fff7fff, 0xff81817f80ff0100, q16);
19410 ASSERT_EQUAL_128(0x0000000080008000, 0xff81817f81ff0201, q17);
19411 ASSERT_EQUAL_128(0x0000ffff80008000, 0xff80817f80ff0100, q18);
19412 ASSERT_EQUAL_128(0x0000000080008000, 0xff81827f81ff0101, q19);
19413 TEARDOWN();
19414}
19415
19416TEST(neon_d_only_scalar) {
19417 SETUP();
19418
19419 START();
19420
19421 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
19422 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
19423 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x1000000010001010);
19424 __ Movi(v3.V2D(), 0xffffffffffffffff, 2);
19425 __ Movi(v4.V2D(), 0xffffffffffffffff, -2);
19426
19427 __ Add(d16, d0, d0);
19428 __ Add(d17, d1, d1);
19429 __ Add(d18, d2, d2);
19430 __ Sub(d19, d0, d0);
19431 __ Sub(d20, d0, d1);
19432 __ Sub(d21, d1, d0);
19433 __ Ushl(d22, d0, d3);
19434 __ Ushl(d23, d0, d4);
19435 __ Sshl(d24, d0, d3);
19436 __ Sshl(d25, d0, d4);
19437 __ Ushr(d26, d0, 1);
19438 __ Sshr(d27, d0, 3);
19439 __ Shl(d28, d0, 0);
19440 __ Shl(d29, d0, 16);
19441
19442 END();
19443
19444 RUN();
19445
19446 ASSERT_EQUAL_128(0, 0xe0000001e001e1e0, q16);
19447 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q17);
19448 ASSERT_EQUAL_128(0, 0x2000000020002020, q18);
19449 ASSERT_EQUAL_128(0, 0, q19);
19450 ASSERT_EQUAL_128(0, 0x7000000170017171, q20);
19451 ASSERT_EQUAL_128(0, 0x8ffffffe8ffe8e8f, q21);
19452 ASSERT_EQUAL_128(0, 0xc0000003c003c3c0, q22);
19453 ASSERT_EQUAL_128(0, 0x3c0000003c003c3c, q23);
19454 ASSERT_EQUAL_128(0, 0xc0000003c003c3c0, q24);
19455 ASSERT_EQUAL_128(0, 0xfc0000003c003c3c, q25);
19456 ASSERT_EQUAL_128(0, 0x7800000078007878, q26);
19457 ASSERT_EQUAL_128(0, 0xfe0000001e001e1e, q27);
19458 ASSERT_EQUAL_128(0, 0xf0000000f000f0f0, q28);
19459 ASSERT_EQUAL_128(0, 0x0000f000f0f00000, q29);
19460
19461 TEARDOWN();
19462}
19463
19464
19465TEST(neon_sqshl_imm_scalar) {
19466 SETUP();
19467
19468 START();
19469
19470 __ Movi(v0.V2D(), 0x0, 0x7f);
19471 __ Movi(v1.V2D(), 0x0, 0x80);
19472 __ Movi(v2.V2D(), 0x0, 0x01);
19473 __ Sqshl(b16, b0, 1);
19474 __ Sqshl(b17, b1, 1);
19475 __ Sqshl(b18, b2, 1);
19476
19477 __ Movi(v0.V2D(), 0x0, 0x7fff);
19478 __ Movi(v1.V2D(), 0x0, 0x8000);
19479 __ Movi(v2.V2D(), 0x0, 0x0001);
19480 __ Sqshl(h19, h0, 1);
19481 __ Sqshl(h20, h1, 1);
19482 __ Sqshl(h21, h2, 1);
19483
19484 __ Movi(v0.V2D(), 0x0, 0x7fffffff);
19485 __ Movi(v1.V2D(), 0x0, 0x80000000);
19486 __ Movi(v2.V2D(), 0x0, 0x00000001);
19487 __ Sqshl(s22, s0, 1);
19488 __ Sqshl(s23, s1, 1);
19489 __ Sqshl(s24, s2, 1);
19490
19491 __ Movi(v0.V2D(), 0x0, 0x7fffffffffffffff);
19492 __ Movi(v1.V2D(), 0x0, 0x8000000000000000);
19493 __ Movi(v2.V2D(), 0x0, 0x0000000000000001);
19494 __ Sqshl(d25, d0, 1);
19495 __ Sqshl(d26, d1, 1);
19496 __ Sqshl(d27, d2, 1);
19497
19498 END();
19499
19500 RUN();
19501
19502 ASSERT_EQUAL_128(0, 0x7f, q16);
19503 ASSERT_EQUAL_128(0, 0x80, q17);
19504 ASSERT_EQUAL_128(0, 0x02, q18);
19505
19506 ASSERT_EQUAL_128(0, 0x7fff, q19);
19507 ASSERT_EQUAL_128(0, 0x8000, q20);
19508 ASSERT_EQUAL_128(0, 0x0002, q21);
19509
19510 ASSERT_EQUAL_128(0, 0x7fffffff, q22);
19511 ASSERT_EQUAL_128(0, 0x80000000, q23);
19512 ASSERT_EQUAL_128(0, 0x00000002, q24);
19513
19514 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q25);
19515 ASSERT_EQUAL_128(0, 0x8000000000000000, q26);
19516 ASSERT_EQUAL_128(0, 0x0000000000000002, q27);
19517
19518 TEARDOWN();
19519}
19520
19521
19522TEST(neon_uqshl_imm_scalar) {
19523 SETUP();
19524
19525 START();
19526
19527 __ Movi(v0.V2D(), 0x0, 0x7f);
19528 __ Movi(v1.V2D(), 0x0, 0x80);
19529 __ Movi(v2.V2D(), 0x0, 0x01);
19530 __ Uqshl(b16, b0, 1);
19531 __ Uqshl(b17, b1, 1);
19532 __ Uqshl(b18, b2, 1);
19533
19534 __ Movi(v0.V2D(), 0x0, 0x7fff);
19535 __ Movi(v1.V2D(), 0x0, 0x8000);
19536 __ Movi(v2.V2D(), 0x0, 0x0001);
19537 __ Uqshl(h19, h0, 1);
19538 __ Uqshl(h20, h1, 1);
19539 __ Uqshl(h21, h2, 1);
19540
19541 __ Movi(v0.V2D(), 0x0, 0x7fffffff);
19542 __ Movi(v1.V2D(), 0x0, 0x80000000);
19543 __ Movi(v2.V2D(), 0x0, 0x00000001);
19544 __ Uqshl(s22, s0, 1);
19545 __ Uqshl(s23, s1, 1);
19546 __ Uqshl(s24, s2, 1);
19547
19548 __ Movi(v0.V2D(), 0x0, 0x7fffffffffffffff);
19549 __ Movi(v1.V2D(), 0x0, 0x8000000000000000);
19550 __ Movi(v2.V2D(), 0x0, 0x0000000000000001);
19551 __ Uqshl(d25, d0, 1);
19552 __ Uqshl(d26, d1, 1);
19553 __ Uqshl(d27, d2, 1);
19554
19555 END();
19556
19557 RUN();
19558
19559 ASSERT_EQUAL_128(0, 0xfe, q16);
19560 ASSERT_EQUAL_128(0, 0xff, q17);
19561 ASSERT_EQUAL_128(0, 0x02, q18);
19562
19563 ASSERT_EQUAL_128(0, 0xfffe, q19);
19564 ASSERT_EQUAL_128(0, 0xffff, q20);
19565 ASSERT_EQUAL_128(0, 0x0002, q21);
19566
19567 ASSERT_EQUAL_128(0, 0xfffffffe, q22);
19568 ASSERT_EQUAL_128(0, 0xffffffff, q23);
19569 ASSERT_EQUAL_128(0, 0x00000002, q24);
19570
19571 ASSERT_EQUAL_128(0, 0xfffffffffffffffe, q25);
19572 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q26);
19573 ASSERT_EQUAL_128(0, 0x0000000000000002, q27);
19574
19575 TEARDOWN();
19576}
19577
19578
19579TEST(neon_sqshlu_scalar) {
19580 SETUP();
19581
19582 START();
19583
19584 __ Movi(v0.V2D(), 0x0, 0x7f);
19585 __ Movi(v1.V2D(), 0x0, 0x80);
19586 __ Movi(v2.V2D(), 0x0, 0x01);
19587 __ Sqshlu(b16, b0, 2);
19588 __ Sqshlu(b17, b1, 2);
19589 __ Sqshlu(b18, b2, 2);
19590
19591 __ Movi(v0.V2D(), 0x0, 0x7fff);
19592 __ Movi(v1.V2D(), 0x0, 0x8000);
19593 __ Movi(v2.V2D(), 0x0, 0x0001);
19594 __ Sqshlu(h19, h0, 2);
19595 __ Sqshlu(h20, h1, 2);
19596 __ Sqshlu(h21, h2, 2);
19597
19598 __ Movi(v0.V2D(), 0x0, 0x7fffffff);
19599 __ Movi(v1.V2D(), 0x0, 0x80000000);
19600 __ Movi(v2.V2D(), 0x0, 0x00000001);
19601 __ Sqshlu(s22, s0, 2);
19602 __ Sqshlu(s23, s1, 2);
19603 __ Sqshlu(s24, s2, 2);
19604
19605 __ Movi(v0.V2D(), 0x0, 0x7fffffffffffffff);
19606 __ Movi(v1.V2D(), 0x0, 0x8000000000000000);
19607 __ Movi(v2.V2D(), 0x0, 0x0000000000000001);
19608 __ Sqshlu(d25, d0, 2);
19609 __ Sqshlu(d26, d1, 2);
19610 __ Sqshlu(d27, d2, 2);
19611
19612 END();
19613
19614 RUN();
19615
19616 ASSERT_EQUAL_128(0, 0xff, q16);
19617 ASSERT_EQUAL_128(0, 0x00, q17);
19618 ASSERT_EQUAL_128(0, 0x04, q18);
19619
19620 ASSERT_EQUAL_128(0, 0xffff, q19);
19621 ASSERT_EQUAL_128(0, 0x0000, q20);
19622 ASSERT_EQUAL_128(0, 0x0004, q21);
19623
19624 ASSERT_EQUAL_128(0, 0xffffffff, q22);
19625 ASSERT_EQUAL_128(0, 0x00000000, q23);
19626 ASSERT_EQUAL_128(0, 0x00000004, q24);
19627
19628 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q25);
19629 ASSERT_EQUAL_128(0, 0x0000000000000000, q26);
19630 ASSERT_EQUAL_128(0, 0x0000000000000004, q27);
19631
19632 TEARDOWN();
19633}
19634
19635
19636TEST(neon_sshll) {
19637 SETUP();
19638
19639 START();
19640
19641 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19642 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19643 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19644
19645 __ Sshll(v16.V8H(), v0.V8B(), 4);
19646 __ Sshll2(v17.V8H(), v0.V16B(), 4);
19647
19648 __ Sshll(v18.V4S(), v1.V4H(), 8);
19649 __ Sshll2(v19.V4S(), v1.V8H(), 8);
19650
19651 __ Sshll(v20.V2D(), v2.V2S(), 16);
19652 __ Sshll2(v21.V2D(), v2.V4S(), 16);
19653
19654 END();
19655
19656 RUN();
19657
19658 ASSERT_EQUAL_128(0xf800f810fff00000, 0x001007f0f800f810, q16);
19659 ASSERT_EQUAL_128(0x07f000100000fff0, 0xf810f80007f00010, q17);
19660 ASSERT_EQUAL_128(0xffffff0000000000, 0x00000100007fff00, q18);
19661 ASSERT_EQUAL_128(0xff800000ff800100, 0xffffff0000000000, q19);
19662 ASSERT_EQUAL_128(0x0000000000000000, 0x00007fffffff0000, q20);
19663 ASSERT_EQUAL_128(0xffff800000000000, 0xffffffffffff0000, q21);
19664 TEARDOWN();
19665}
19666
19667TEST(neon_shll) {
19668 SETUP();
19669
19670 START();
19671
19672 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19673 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19674 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19675
19676 __ Shll(v16.V8H(), v0.V8B(), 8);
19677 __ Shll2(v17.V8H(), v0.V16B(), 8);
19678
19679 __ Shll(v18.V4S(), v1.V4H(), 16);
19680 __ Shll2(v19.V4S(), v1.V8H(), 16);
19681
19682 __ Shll(v20.V2D(), v2.V2S(), 32);
19683 __ Shll2(v21.V2D(), v2.V4S(), 32);
19684
19685 END();
19686
19687 RUN();
19688
19689 ASSERT_EQUAL_128(0x80008100ff000000, 0x01007f0080008100, q16);
19690 ASSERT_EQUAL_128(0x7f0001000000ff00, 0x810080007f000100, q17);
19691 ASSERT_EQUAL_128(0xffff000000000000, 0x000100007fff0000, q18);
19692 ASSERT_EQUAL_128(0x8000000080010000, 0xffff000000000000, q19);
19693 ASSERT_EQUAL_128(0x0000000000000000, 0x7fffffff00000000, q20);
19694 ASSERT_EQUAL_128(0x8000000000000000, 0xffffffff00000000, q21);
19695 TEARDOWN();
19696}
19697
19698TEST(neon_ushll) {
19699 SETUP();
19700
19701 START();
19702
19703 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19704 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19705 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19706
19707 __ Ushll(v16.V8H(), v0.V8B(), 4);
19708 __ Ushll2(v17.V8H(), v0.V16B(), 4);
19709
19710 __ Ushll(v18.V4S(), v1.V4H(), 8);
19711 __ Ushll2(v19.V4S(), v1.V8H(), 8);
19712
19713 __ Ushll(v20.V2D(), v2.V2S(), 16);
19714 __ Ushll2(v21.V2D(), v2.V4S(), 16);
19715
19716 END();
19717
19718 RUN();
19719
19720 ASSERT_EQUAL_128(0x080008100ff00000, 0x001007f008000810, q16);
19721 ASSERT_EQUAL_128(0x07f0001000000ff0, 0x0810080007f00010, q17);
19722 ASSERT_EQUAL_128(0x00ffff0000000000, 0x00000100007fff00, q18);
19723 ASSERT_EQUAL_128(0x0080000000800100, 0x00ffff0000000000, q19);
19724 ASSERT_EQUAL_128(0x0000000000000000, 0x00007fffffff0000, q20);
19725 ASSERT_EQUAL_128(0x0000800000000000, 0x0000ffffffff0000, q21);
19726 TEARDOWN();
19727}
19728
19729
19730TEST(neon_sxtl) {
19731 SETUP();
19732
19733 START();
19734
19735 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19736 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19737 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19738
19739 __ Sxtl(v16.V8H(), v0.V8B());
19740 __ Sxtl2(v17.V8H(), v0.V16B());
19741
19742 __ Sxtl(v18.V4S(), v1.V4H());
19743 __ Sxtl2(v19.V4S(), v1.V8H());
19744
19745 __ Sxtl(v20.V2D(), v2.V2S());
19746 __ Sxtl2(v21.V2D(), v2.V4S());
19747
19748 END();
19749
19750 RUN();
19751
19752 ASSERT_EQUAL_128(0xff80ff81ffff0000, 0x0001007fff80ff81, q16);
19753 ASSERT_EQUAL_128(0x007f00010000ffff, 0xff81ff80007f0001, q17);
19754 ASSERT_EQUAL_128(0xffffffff00000000, 0x0000000100007fff, q18);
19755 ASSERT_EQUAL_128(0xffff8000ffff8001, 0xffffffff00000000, q19);
19756 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
19757 ASSERT_EQUAL_128(0xffffffff80000000, 0xffffffffffffffff, q21);
19758 TEARDOWN();
19759}
19760
19761
19762TEST(neon_uxtl) {
19763 SETUP();
19764
19765 START();
19766
19767 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19768 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19769 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19770
19771 __ Uxtl(v16.V8H(), v0.V8B());
19772 __ Uxtl2(v17.V8H(), v0.V16B());
19773
19774 __ Uxtl(v18.V4S(), v1.V4H());
19775 __ Uxtl2(v19.V4S(), v1.V8H());
19776
19777 __ Uxtl(v20.V2D(), v2.V2S());
19778 __ Uxtl2(v21.V2D(), v2.V4S());
19779
19780 END();
19781
19782 RUN();
19783
19784 ASSERT_EQUAL_128(0x0080008100ff0000, 0x0001007f00800081, q16);
19785 ASSERT_EQUAL_128(0x007f0001000000ff, 0x00810080007f0001, q17);
19786 ASSERT_EQUAL_128(0x0000ffff00000000, 0x0000000100007fff, q18);
19787 ASSERT_EQUAL_128(0x0000800000008001, 0x0000ffff00000000, q19);
19788 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
19789 ASSERT_EQUAL_128(0x0000000080000000, 0x00000000ffffffff, q21);
19790 TEARDOWN();
19791}
19792
19793
19794TEST(neon_ssra) {
19795 SETUP();
19796
19797 START();
19798
19799 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19800 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19801 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19802 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
19803 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
19804
19805 __ Mov(v16.V2D(), v0.V2D());
19806 __ Mov(v17.V2D(), v0.V2D());
19807 __ Mov(v18.V2D(), v1.V2D());
19808 __ Mov(v19.V2D(), v1.V2D());
19809 __ Mov(v20.V2D(), v2.V2D());
19810 __ Mov(v21.V2D(), v2.V2D());
19811 __ Mov(v22.V2D(), v3.V2D());
19812 __ Mov(v23.V2D(), v4.V2D());
19813 __ Mov(v24.V2D(), v3.V2D());
19814 __ Mov(v25.V2D(), v4.V2D());
19815
19816 __ Ssra(v16.V8B(), v0.V8B(), 4);
19817 __ Ssra(v17.V16B(), v0.V16B(), 4);
19818
19819 __ Ssra(v18.V4H(), v1.V4H(), 8);
19820 __ Ssra(v19.V8H(), v1.V8H(), 8);
19821
19822 __ Ssra(v20.V2S(), v2.V2S(), 16);
19823 __ Ssra(v21.V4S(), v2.V4S(), 16);
19824
19825 __ Ssra(v22.V2D(), v3.V2D(), 32);
19826 __ Ssra(v23.V2D(), v4.V2D(), 32);
19827
19828 __ Ssra(d24, d3, 48);
19829
19830 END();
19831
19832 RUN();
19833
19834 ASSERT_EQUAL_128(0x0000000000000000, 0x7879fe0001867879, q16);
19835 ASSERT_EQUAL_128(0x860100fe79788601, 0x7879fe0001867879, q17);
19836 ASSERT_EQUAL_128(0x0000000000000000, 0xfffe00000001807e, q18);
19837 ASSERT_EQUAL_128(0x7f807f81fffe0000, 0xfffe00000001807e, q19);
19838 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007ffe, q20);
19839 ASSERT_EQUAL_128(0x7fff8000fffffffe, 0x0000000080007ffe, q21);
19840 ASSERT_EQUAL_128(0x7fffffff80000001, 0x800000007ffffffe, q22);
19841 ASSERT_EQUAL_128(0x7fffffff80000000, 0x0000000000000000, q23);
19842 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007ffe, q24);
19843 TEARDOWN();
19844}
19845
19846TEST(neon_srsra) {
19847 SETUP();
19848
19849 START();
19850
19851 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19852 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19853 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19854 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
19855 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
19856
19857 __ Mov(v16.V2D(), v0.V2D());
19858 __ Mov(v17.V2D(), v0.V2D());
19859 __ Mov(v18.V2D(), v1.V2D());
19860 __ Mov(v19.V2D(), v1.V2D());
19861 __ Mov(v20.V2D(), v2.V2D());
19862 __ Mov(v21.V2D(), v2.V2D());
19863 __ Mov(v22.V2D(), v3.V2D());
19864 __ Mov(v23.V2D(), v4.V2D());
19865 __ Mov(v24.V2D(), v3.V2D());
19866 __ Mov(v25.V2D(), v4.V2D());
19867
19868 __ Srsra(v16.V8B(), v0.V8B(), 4);
19869 __ Srsra(v17.V16B(), v0.V16B(), 4);
19870
19871 __ Srsra(v18.V4H(), v1.V4H(), 8);
19872 __ Srsra(v19.V8H(), v1.V8H(), 8);
19873
19874 __ Srsra(v20.V2S(), v2.V2S(), 16);
19875 __ Srsra(v21.V4S(), v2.V4S(), 16);
19876
19877 __ Srsra(v22.V2D(), v3.V2D(), 32);
19878 __ Srsra(v23.V2D(), v4.V2D(), 32);
19879
19880 __ Srsra(d24, d3, 48);
19881
19882 END();
19883
19884 RUN();
19885
19886 ASSERT_EQUAL_128(0x0000000000000000, 0x7879ff0001877879, q16);
19887 ASSERT_EQUAL_128(0x870100ff79788701, 0x7879ff0001877879, q17);
19888 ASSERT_EQUAL_128(0x0000000000000000, 0xffff00000001807f, q18);
19889 ASSERT_EQUAL_128(0x7f807f81ffff0000, 0xffff00000001807f, q19);
19890 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007fff, q20);
19891 ASSERT_EQUAL_128(0x7fff8000ffffffff, 0x0000000080007fff, q21);
19892 ASSERT_EQUAL_128(0x7fffffff80000001, 0x800000007fffffff, q22);
19893 ASSERT_EQUAL_128(0x7fffffff80000000, 0x0000000000000000, q23);
19894 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007fff, q24);
19895
19896 TEARDOWN();
19897}
19898
19899TEST(neon_usra) {
19900 SETUP();
19901
19902 START();
19903
19904 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19905 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19906 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19907 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
19908 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
19909
19910 __ Mov(v16.V2D(), v0.V2D());
19911 __ Mov(v17.V2D(), v0.V2D());
19912 __ Mov(v18.V2D(), v1.V2D());
19913 __ Mov(v19.V2D(), v1.V2D());
19914 __ Mov(v20.V2D(), v2.V2D());
19915 __ Mov(v21.V2D(), v2.V2D());
19916 __ Mov(v22.V2D(), v3.V2D());
19917 __ Mov(v23.V2D(), v4.V2D());
19918 __ Mov(v24.V2D(), v3.V2D());
19919 __ Mov(v25.V2D(), v4.V2D());
19920
19921 __ Usra(v16.V8B(), v0.V8B(), 4);
19922 __ Usra(v17.V16B(), v0.V16B(), 4);
19923
19924 __ Usra(v18.V4H(), v1.V4H(), 8);
19925 __ Usra(v19.V8H(), v1.V8H(), 8);
19926
19927 __ Usra(v20.V2S(), v2.V2S(), 16);
19928 __ Usra(v21.V4S(), v2.V4S(), 16);
19929
19930 __ Usra(v22.V2D(), v3.V2D(), 32);
19931 __ Usra(v23.V2D(), v4.V2D(), 32);
19932
19933 __ Usra(d24, d3, 48);
19934
19935 END();
19936
19937 RUN();
19938
19939 ASSERT_EQUAL_128(0x0000000000000000, 0x88890e0001868889, q16);
19940 ASSERT_EQUAL_128(0x8601000e89888601, 0x88890e0001868889, q17);
19941 ASSERT_EQUAL_128(0x0000000000000000, 0x00fe00000001807e, q18);
19942 ASSERT_EQUAL_128(0x8080808100fe0000, 0x00fe00000001807e, q19);
19943 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007ffe, q20);
19944 ASSERT_EQUAL_128(0x800080000000fffe, 0x0000000080007ffe, q21);
19945 ASSERT_EQUAL_128(0x8000000080000001, 0x800000007ffffffe, q22);
19946 ASSERT_EQUAL_128(0x8000000080000000, 0x0000000000000000, q23);
19947 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007ffe, q24);
19948
19949 TEARDOWN();
19950}
19951
19952TEST(neon_ursra) {
19953 SETUP();
19954
19955 START();
19956
19957 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19958 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19959 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19960 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
19961 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
19962
19963 __ Mov(v16.V2D(), v0.V2D());
19964 __ Mov(v17.V2D(), v0.V2D());
19965 __ Mov(v18.V2D(), v1.V2D());
19966 __ Mov(v19.V2D(), v1.V2D());
19967 __ Mov(v20.V2D(), v2.V2D());
19968 __ Mov(v21.V2D(), v2.V2D());
19969 __ Mov(v22.V2D(), v3.V2D());
19970 __ Mov(v23.V2D(), v4.V2D());
19971 __ Mov(v24.V2D(), v3.V2D());
19972 __ Mov(v25.V2D(), v4.V2D());
19973
19974 __ Ursra(v16.V8B(), v0.V8B(), 4);
19975 __ Ursra(v17.V16B(), v0.V16B(), 4);
19976
19977 __ Ursra(v18.V4H(), v1.V4H(), 8);
19978 __ Ursra(v19.V8H(), v1.V8H(), 8);
19979
19980 __ Ursra(v20.V2S(), v2.V2S(), 16);
19981 __ Ursra(v21.V4S(), v2.V4S(), 16);
19982
19983 __ Ursra(v22.V2D(), v3.V2D(), 32);
19984 __ Ursra(v23.V2D(), v4.V2D(), 32);
19985
19986 __ Ursra(d24, d3, 48);
19987
19988 END();
19989
19990 RUN();
19991
19992 ASSERT_EQUAL_128(0x0000000000000000, 0x88890f0001878889, q16);
19993 ASSERT_EQUAL_128(0x8701000f89888701, 0x88890f0001878889, q17);
19994 ASSERT_EQUAL_128(0x0000000000000000, 0x00ff00000001807f, q18);
19995 ASSERT_EQUAL_128(0x8080808100ff0000, 0x00ff00000001807f, q19);
19996 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007fff, q20);
19997 ASSERT_EQUAL_128(0x800080000000ffff, 0x0000000080007fff, q21);
19998 ASSERT_EQUAL_128(0x8000000080000001, 0x800000007fffffff, q22);
19999 ASSERT_EQUAL_128(0x8000000080000000, 0x0000000000000000, q23);
20000 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007fff, q24);
20001 TEARDOWN();
20002}
20003
20004
20005TEST(neon_uqshl_scalar) {
20006 SETUP();
20007
20008 START();
20009
20010 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20011 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20012 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20013 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20014
20015 __ Uqshl(b16, b0, b2);
20016 __ Uqshl(b17, b0, b3);
20017 __ Uqshl(b18, b1, b2);
20018 __ Uqshl(b19, b1, b3);
20019 __ Uqshl(h20, h0, h2);
20020 __ Uqshl(h21, h0, h3);
20021 __ Uqshl(h22, h1, h2);
20022 __ Uqshl(h23, h1, h3);
20023 __ Uqshl(s24, s0, s2);
20024 __ Uqshl(s25, s0, s3);
20025 __ Uqshl(s26, s1, s2);
20026 __ Uqshl(s27, s1, s3);
20027 __ Uqshl(d28, d0, d2);
20028 __ Uqshl(d29, d0, d3);
20029 __ Uqshl(d30, d1, d2);
20030 __ Uqshl(d31, d1, d3);
20031
20032 END();
20033
20034 RUN();
20035
20036 ASSERT_EQUAL_128(0, 0xff, q16);
20037 ASSERT_EQUAL_128(0, 0x78, q17);
20038 ASSERT_EQUAL_128(0, 0xfe, q18);
20039 ASSERT_EQUAL_128(0, 0x3f, q19);
20040 ASSERT_EQUAL_128(0, 0xffff, q20);
20041 ASSERT_EQUAL_128(0, 0x7878, q21);
20042 ASSERT_EQUAL_128(0, 0xfefe, q22);
20043 ASSERT_EQUAL_128(0, 0x3fbf, q23);
20044 ASSERT_EQUAL_128(0, 0xffffffff, q24);
20045 ASSERT_EQUAL_128(0, 0x78007878, q25);
20046 ASSERT_EQUAL_128(0, 0xfffefefe, q26);
20047 ASSERT_EQUAL_128(0, 0x3fffbfbf, q27);
20048 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q28);
20049 ASSERT_EQUAL_128(0, 0x7800000078007878, q29);
20050 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q30);
20051 ASSERT_EQUAL_128(0, 0x3fffffffbfffbfbf, q31);
20052
20053 TEARDOWN();
20054}
20055
20056
20057TEST(neon_sqshl_scalar) {
20058 SETUP();
20059
20060 START();
20061
20062 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xbfffffffbfffbfbf);
20063 __ Movi(v1.V2D(), 0x5555555555555555, 0x4000000040004040);
20064 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20065 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20066
20067 __ Sqshl(b16, b0, b2);
20068 __ Sqshl(b17, b0, b3);
20069 __ Sqshl(b18, b1, b2);
20070 __ Sqshl(b19, b1, b3);
20071 __ Sqshl(h20, h0, h2);
20072 __ Sqshl(h21, h0, h3);
20073 __ Sqshl(h22, h1, h2);
20074 __ Sqshl(h23, h1, h3);
20075 __ Sqshl(s24, s0, s2);
20076 __ Sqshl(s25, s0, s3);
20077 __ Sqshl(s26, s1, s2);
20078 __ Sqshl(s27, s1, s3);
20079 __ Sqshl(d28, d0, d2);
20080 __ Sqshl(d29, d0, d3);
20081 __ Sqshl(d30, d1, d2);
20082 __ Sqshl(d31, d1, d3);
20083
20084 END();
20085
20086 RUN();
20087
20088 ASSERT_EQUAL_128(0, 0x80, q16);
20089 ASSERT_EQUAL_128(0, 0xdf, q17);
20090 ASSERT_EQUAL_128(0, 0x7f, q18);
20091 ASSERT_EQUAL_128(0, 0x20, q19);
20092 ASSERT_EQUAL_128(0, 0x8000, q20);
20093 ASSERT_EQUAL_128(0, 0xdfdf, q21);
20094 ASSERT_EQUAL_128(0, 0x7fff, q22);
20095 ASSERT_EQUAL_128(0, 0x2020, q23);
20096 ASSERT_EQUAL_128(0, 0x80000000, q24);
20097 ASSERT_EQUAL_128(0, 0xdfffdfdf, q25);
20098 ASSERT_EQUAL_128(0, 0x7fffffff, q26);
20099 ASSERT_EQUAL_128(0, 0x20002020, q27);
20100 ASSERT_EQUAL_128(0, 0x8000000000000000, q28);
20101 ASSERT_EQUAL_128(0, 0xdfffffffdfffdfdf, q29);
20102 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q30);
20103 ASSERT_EQUAL_128(0, 0x2000000020002020, q31);
20104
20105 TEARDOWN();
20106}
20107
20108
20109TEST(neon_urshl_scalar) {
20110 SETUP();
20111
20112 START();
20113
20114 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20115 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20116 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20117 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20118
20119 __ Urshl(d28, d0, d2);
20120 __ Urshl(d29, d0, d3);
20121 __ Urshl(d30, d1, d2);
20122 __ Urshl(d31, d1, d3);
20123
20124 END();
20125
20126 RUN();
20127
20128 ASSERT_EQUAL_128(0, 0xe0000001e001e1e0, q28);
20129 ASSERT_EQUAL_128(0, 0x7800000078007878, q29);
20130 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q30);
20131 ASSERT_EQUAL_128(0, 0x3fffffffbfffbfc0, q31);
20132
20133 TEARDOWN();
20134}
20135
20136
20137TEST(neon_srshl_scalar) {
20138 SETUP();
20139
20140 START();
20141
20142 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xbfffffffbfffbfbf);
20143 __ Movi(v1.V2D(), 0x5555555555555555, 0x4000000040004040);
20144 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20145 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20146
20147 __ Srshl(d28, d0, d2);
20148 __ Srshl(d29, d0, d3);
20149 __ Srshl(d30, d1, d2);
20150 __ Srshl(d31, d1, d3);
20151
20152 END();
20153
20154 RUN();
20155
20156 ASSERT_EQUAL_128(0, 0x7fffffff7fff7f7e, q28);
20157 ASSERT_EQUAL_128(0, 0xdfffffffdfffdfe0, q29);
20158 ASSERT_EQUAL_128(0, 0x8000000080008080, q30);
20159 ASSERT_EQUAL_128(0, 0x2000000020002020, q31);
20160
20161 TEARDOWN();
20162}
20163
20164
20165TEST(neon_uqrshl_scalar) {
20166 SETUP();
20167
20168 START();
20169
20170 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20171 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20172 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20173 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20174
20175 __ Uqrshl(b16, b0, b2);
20176 __ Uqrshl(b17, b0, b3);
20177 __ Uqrshl(b18, b1, b2);
20178 __ Uqrshl(b19, b1, b3);
20179 __ Uqrshl(h20, h0, h2);
20180 __ Uqrshl(h21, h0, h3);
20181 __ Uqrshl(h22, h1, h2);
20182 __ Uqrshl(h23, h1, h3);
20183 __ Uqrshl(s24, s0, s2);
20184 __ Uqrshl(s25, s0, s3);
20185 __ Uqrshl(s26, s1, s2);
20186 __ Uqrshl(s27, s1, s3);
20187 __ Uqrshl(d28, d0, d2);
20188 __ Uqrshl(d29, d0, d3);
20189 __ Uqrshl(d30, d1, d2);
20190 __ Uqrshl(d31, d1, d3);
20191
20192 END();
20193
20194 RUN();
20195
20196 ASSERT_EQUAL_128(0, 0xff, q16);
20197 ASSERT_EQUAL_128(0, 0x78, q17);
20198 ASSERT_EQUAL_128(0, 0xfe, q18);
20199 ASSERT_EQUAL_128(0, 0x40, q19);
20200 ASSERT_EQUAL_128(0, 0xffff, q20);
20201 ASSERT_EQUAL_128(0, 0x7878, q21);
20202 ASSERT_EQUAL_128(0, 0xfefe, q22);
20203 ASSERT_EQUAL_128(0, 0x3fc0, q23);
20204 ASSERT_EQUAL_128(0, 0xffffffff, q24);
20205 ASSERT_EQUAL_128(0, 0x78007878, q25);
20206 ASSERT_EQUAL_128(0, 0xfffefefe, q26);
20207 ASSERT_EQUAL_128(0, 0x3fffbfc0, q27);
20208 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q28);
20209 ASSERT_EQUAL_128(0, 0x7800000078007878, q29);
20210 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q30);
20211 ASSERT_EQUAL_128(0, 0x3fffffffbfffbfc0, q31);
20212
20213 TEARDOWN();
20214}
20215
20216
20217TEST(neon_sqrshl_scalar) {
20218 SETUP();
20219
20220 START();
20221
20222 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xbfffffffbfffbfbf);
20223 __ Movi(v1.V2D(), 0x5555555555555555, 0x4000000040004040);
20224 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20225 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20226
20227 __ Sqrshl(b16, b0, b2);
20228 __ Sqrshl(b17, b0, b3);
20229 __ Sqrshl(b18, b1, b2);
20230 __ Sqrshl(b19, b1, b3);
20231 __ Sqrshl(h20, h0, h2);
20232 __ Sqrshl(h21, h0, h3);
20233 __ Sqrshl(h22, h1, h2);
20234 __ Sqrshl(h23, h1, h3);
20235 __ Sqrshl(s24, s0, s2);
20236 __ Sqrshl(s25, s0, s3);
20237 __ Sqrshl(s26, s1, s2);
20238 __ Sqrshl(s27, s1, s3);
20239 __ Sqrshl(d28, d0, d2);
20240 __ Sqrshl(d29, d0, d3);
20241 __ Sqrshl(d30, d1, d2);
20242 __ Sqrshl(d31, d1, d3);
20243
20244 END();
20245
20246 RUN();
20247
20248 ASSERT_EQUAL_128(0, 0x80, q16);
20249 ASSERT_EQUAL_128(0, 0xe0, q17);
20250 ASSERT_EQUAL_128(0, 0x7f, q18);
20251 ASSERT_EQUAL_128(0, 0x20, q19);
20252 ASSERT_EQUAL_128(0, 0x8000, q20);
20253 ASSERT_EQUAL_128(0, 0xdfe0, q21);
20254 ASSERT_EQUAL_128(0, 0x7fff, q22);
20255 ASSERT_EQUAL_128(0, 0x2020, q23);
20256 ASSERT_EQUAL_128(0, 0x80000000, q24);
20257 ASSERT_EQUAL_128(0, 0xdfffdfe0, q25);
20258 ASSERT_EQUAL_128(0, 0x7fffffff, q26);
20259 ASSERT_EQUAL_128(0, 0x20002020, q27);
20260 ASSERT_EQUAL_128(0, 0x8000000000000000, q28);
20261 ASSERT_EQUAL_128(0, 0xdfffffffdfffdfe0, q29);
20262 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q30);
20263 ASSERT_EQUAL_128(0, 0x2000000020002020, q31);
20264
20265 TEARDOWN();
20266}
20267
20268
20269TEST(neon_uqadd_scalar) {
20270 SETUP();
20271
20272 START();
20273
20274 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20275 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20276 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x1000000010001010);
20277
20278 __ Uqadd(b16, b0, b0);
20279 __ Uqadd(b17, b1, b1);
20280 __ Uqadd(b18, b2, b2);
20281 __ Uqadd(h19, h0, h0);
20282 __ Uqadd(h20, h1, h1);
20283 __ Uqadd(h21, h2, h2);
20284 __ Uqadd(s22, s0, s0);
20285 __ Uqadd(s23, s1, s1);
20286 __ Uqadd(s24, s2, s2);
20287 __ Uqadd(d25, d0, d0);
20288 __ Uqadd(d26, d1, d1);
20289 __ Uqadd(d27, d2, d2);
20290
20291 END();
20292
20293 RUN();
20294
20295 ASSERT_EQUAL_128(0, 0xff, q16);
20296 ASSERT_EQUAL_128(0, 0xfe, q17);
20297 ASSERT_EQUAL_128(0, 0x20, q18);
20298 ASSERT_EQUAL_128(0, 0xffff, q19);
20299 ASSERT_EQUAL_128(0, 0xfefe, q20);
20300 ASSERT_EQUAL_128(0, 0x2020, q21);
20301 ASSERT_EQUAL_128(0, 0xffffffff, q22);
20302 ASSERT_EQUAL_128(0, 0xfffefefe, q23);
20303 ASSERT_EQUAL_128(0, 0x20002020, q24);
20304 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q25);
20305 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q26);
20306 ASSERT_EQUAL_128(0, 0x2000000020002020, q27);
20307
20308 TEARDOWN();
20309}
20310
20311
20312TEST(neon_sqadd_scalar) {
20313 SETUP();
20314
20315 START();
20316
20317 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0x8000000180018181);
20318 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20319 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x1000000010001010);
20320
20321 __ Sqadd(b16, b0, b0);
20322 __ Sqadd(b17, b1, b1);
20323 __ Sqadd(b18, b2, b2);
20324 __ Sqadd(h19, h0, h0);
20325 __ Sqadd(h20, h1, h1);
20326 __ Sqadd(h21, h2, h2);
20327 __ Sqadd(s22, s0, s0);
20328 __ Sqadd(s23, s1, s1);
20329 __ Sqadd(s24, s2, s2);
20330 __ Sqadd(d25, d0, d0);
20331 __ Sqadd(d26, d1, d1);
20332 __ Sqadd(d27, d2, d2);
20333
20334 END();
20335
20336 RUN();
20337
20338 ASSERT_EQUAL_128(0, 0x80, q16);
20339 ASSERT_EQUAL_128(0, 0x7f, q17);
20340 ASSERT_EQUAL_128(0, 0x20, q18);
20341 ASSERT_EQUAL_128(0, 0x8000, q19);
20342 ASSERT_EQUAL_128(0, 0x7fff, q20);
20343 ASSERT_EQUAL_128(0, 0x2020, q21);
20344 ASSERT_EQUAL_128(0, 0x80000000, q22);
20345 ASSERT_EQUAL_128(0, 0x7fffffff, q23);
20346 ASSERT_EQUAL_128(0, 0x20002020, q24);
20347 ASSERT_EQUAL_128(0, 0x8000000000000000, q25);
20348 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q26);
20349 ASSERT_EQUAL_128(0, 0x2000000020002020, q27);
20350
20351 TEARDOWN();
20352}
20353
20354
20355TEST(neon_uqsub_scalar) {
20356 SETUP();
20357
20358 START();
20359
20360 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20361 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20362
20363 __ Uqsub(b16, b0, b0);
20364 __ Uqsub(b17, b0, b1);
20365 __ Uqsub(b18, b1, b0);
20366 __ Uqsub(h19, h0, h0);
20367 __ Uqsub(h20, h0, h1);
20368 __ Uqsub(h21, h1, h0);
20369 __ Uqsub(s22, s0, s0);
20370 __ Uqsub(s23, s0, s1);
20371 __ Uqsub(s24, s1, s0);
20372 __ Uqsub(d25, d0, d0);
20373 __ Uqsub(d26, d0, d1);
20374 __ Uqsub(d27, d1, d0);
20375
20376 END();
20377
20378 RUN();
20379
20380 ASSERT_EQUAL_128(0, 0, q16);
20381 ASSERT_EQUAL_128(0, 0x71, q17);
20382 ASSERT_EQUAL_128(0, 0, q18);
20383
20384 ASSERT_EQUAL_128(0, 0, q19);
20385 ASSERT_EQUAL_128(0, 0x7171, q20);
20386 ASSERT_EQUAL_128(0, 0, q21);
20387
20388 ASSERT_EQUAL_128(0, 0, q22);
20389 ASSERT_EQUAL_128(0, 0x70017171, q23);
20390 ASSERT_EQUAL_128(0, 0, q24);
20391
20392 ASSERT_EQUAL_128(0, 0, q25);
20393 ASSERT_EQUAL_128(0, 0x7000000170017171, q26);
20394 ASSERT_EQUAL_128(0, 0, q27);
20395
20396 TEARDOWN();
20397}
20398
20399
20400TEST(neon_sqsub_scalar) {
20401 SETUP();
20402
20403 START();
20404
20405 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20406 __ Movi(v1.V2D(), 0x5555555555555555, 0x7eeeeeee7eee7e7e);
20407
20408 __ Sqsub(b16, b0, b0);
20409 __ Sqsub(b17, b0, b1);
20410 __ Sqsub(b18, b1, b0);
20411 __ Sqsub(h19, h0, h0);
20412 __ Sqsub(h20, h0, h1);
20413 __ Sqsub(h21, h1, h0);
20414 __ Sqsub(s22, s0, s0);
20415 __ Sqsub(s23, s0, s1);
20416 __ Sqsub(s24, s1, s0);
20417 __ Sqsub(d25, d0, d0);
20418 __ Sqsub(d26, d0, d1);
20419 __ Sqsub(d27, d1, d0);
20420
20421 END();
20422
20423 RUN();
20424
20425 ASSERT_EQUAL_128(0, 0, q16);
20426 ASSERT_EQUAL_128(0, 0x80, q17);
20427 ASSERT_EQUAL_128(0, 0x7f, q18);
20428
20429 ASSERT_EQUAL_128(0, 0, q19);
20430 ASSERT_EQUAL_128(0, 0x8000, q20);
20431 ASSERT_EQUAL_128(0, 0x7fff, q21);
20432
20433 ASSERT_EQUAL_128(0, 0, q22);
20434 ASSERT_EQUAL_128(0, 0x80000000, q23);
20435 ASSERT_EQUAL_128(0, 0x7fffffff, q24);
20436
20437 ASSERT_EQUAL_128(0, 0, q25);
20438 ASSERT_EQUAL_128(0, 0x8000000000000000, q26);
20439 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q27);
20440
20441 TEARDOWN();
20442}
20443
20444
20445TEST(neon_fmla_fmls) {
20446 SETUP();
20447
20448 START();
20449 __ Movi(v0.V2D(), 0x3f80000040000000, 0x4100000000000000);
20450 __ Movi(v1.V2D(), 0x400000003f800000, 0x000000003f800000);
20451 __ Movi(v2.V2D(), 0x3f800000ffffffff, 0x7f800000ff800000);
20452 __ Mov(v16.V16B(), v0.V16B());
20453 __ Mov(v17.V16B(), v0.V16B());
20454 __ Mov(v18.V16B(), v0.V16B());
20455 __ Mov(v19.V16B(), v0.V16B());
20456 __ Mov(v20.V16B(), v0.V16B());
20457 __ Mov(v21.V16B(), v0.V16B());
20458
20459 __ Fmla(v16.V2S(), v1.V2S(), v2.V2S());
20460 __ Fmla(v17.V4S(), v1.V4S(), v2.V4S());
20461 __ Fmla(v18.V2D(), v1.V2D(), v2.V2D());
20462 __ Fmls(v19.V2S(), v1.V2S(), v2.V2S());
20463 __ Fmls(v20.V4S(), v1.V4S(), v2.V4S());
20464 __ Fmls(v21.V2D(), v1.V2D(), v2.V2D());
20465 END();
20466
20467 RUN();
20468
20469 ASSERT_EQUAL_128(0x0000000000000000, 0x7fc00000ff800000, q16);
20470 ASSERT_EQUAL_128(0x40400000ffffffff, 0x7fc00000ff800000, q17);
20471 ASSERT_EQUAL_128(0x3f9800015f8003f7, 0x41000000000000fe, q18);
20472 ASSERT_EQUAL_128(0x0000000000000000, 0x7fc000007f800000, q19);
20473 ASSERT_EQUAL_128(0xbf800000ffffffff, 0x7fc000007f800000, q20);
20474 ASSERT_EQUAL_128(0xbf8000023f0007ee, 0x40fffffffffffe04, q21);
20475
20476 TEARDOWN();
20477}
20478
20479
20480TEST(neon_fmulx_scalar) {
20481 SETUP();
20482
20483 START();
20484 __ Fmov(s0, 2.0);
20485 __ Fmov(s1, 0.5);
20486 __ Fmov(s2, 0.0);
20487 __ Fmov(s3, -0.0);
20488 __ Fmov(s4, kFP32PositiveInfinity);
20489 __ Fmov(s5, kFP32NegativeInfinity);
20490 __ Fmulx(s16, s0, s1);
20491 __ Fmulx(s17, s2, s4);
20492 __ Fmulx(s18, s2, s5);
20493 __ Fmulx(s19, s3, s4);
20494 __ Fmulx(s20, s3, s5);
20495
20496 __ Fmov(d21, 2.0);
20497 __ Fmov(d22, 0.5);
20498 __ Fmov(d23, 0.0);
20499 __ Fmov(d24, -0.0);
20500 __ Fmov(d25, kFP64PositiveInfinity);
20501 __ Fmov(d26, kFP64NegativeInfinity);
20502 __ Fmulx(d27, d21, d22);
20503 __ Fmulx(d28, d23, d25);
20504 __ Fmulx(d29, d23, d26);
20505 __ Fmulx(d30, d24, d25);
20506 __ Fmulx(d31, d24, d26);
20507 END();
20508
20509 RUN();
20510
20511 ASSERT_EQUAL_FP32(1.0, s16);
20512 ASSERT_EQUAL_FP32(2.0, s17);
20513 ASSERT_EQUAL_FP32(-2.0, s18);
20514 ASSERT_EQUAL_FP32(-2.0, s19);
20515 ASSERT_EQUAL_FP32(2.0, s20);
20516 ASSERT_EQUAL_FP64(1.0, d27);
20517 ASSERT_EQUAL_FP64(2.0, d28);
20518 ASSERT_EQUAL_FP64(-2.0, d29);
20519 ASSERT_EQUAL_FP64(-2.0, d30);
20520 ASSERT_EQUAL_FP64(2.0, d31);
20521
20522 TEARDOWN();
20523}
20524
20525
20526TEST(crc32b) {
20527 SETUP();
20528 START();
20529
20530 __ Mov(w0, 0);
20531 __ Mov(w1, 0);
20532 __ Crc32b(w10, w0, w1);
20533
20534 __ Mov(w0, 0x1);
20535 __ Mov(w1, 0x138);
20536 __ Crc32b(w11, w0, w1);
20537
20538 __ Mov(w0, 0x1);
20539 __ Mov(w1, 0x38);
20540 __ Crc32b(w12, w0, w1);
20541
20542 __ Mov(w0, 0);
20543 __ Mov(w1, 128);
20544 __ Crc32b(w13, w0, w1);
20545
20546 __ Mov(w0, UINT32_MAX);
20547 __ Mov(w1, 255);
20548 __ Crc32b(w14, w0, w1);
20549
20550 __ Mov(w0, 0x00010001);
20551 __ Mov(w1, 0x10001000);
20552 __ Crc32b(w15, w0, w1);
20553
20554 END();
20555 RUN();
20556
20557 ASSERT_EQUAL_64(0x0, x10);
20558 ASSERT_EQUAL_64(0x5f058808, x11);
20559 ASSERT_EQUAL_64(0x5f058808, x12);
20560 ASSERT_EQUAL_64(0xedb88320, x13);
20561 ASSERT_EQUAL_64(0x00ffffff, x14);
20562 ASSERT_EQUAL_64(0x77073196, x15);
20563
20564 TEARDOWN();
20565}
20566
20567
20568TEST(crc32h) {
20569 SETUP();
20570 START();
20571
20572 __ Mov(w0, 0);
20573 __ Mov(w1, 0);
20574 __ Crc32h(w10, w0, w1);
20575
20576 __ Mov(w0, 0x1);
20577 __ Mov(w1, 0x10038);
20578 __ Crc32h(w11, w0, w1);
20579
20580 __ Mov(w0, 0x1);
20581 __ Mov(w1, 0x38);
20582 __ Crc32h(w12, w0, w1);
20583
20584 __ Mov(w0, 0);
20585 __ Mov(w1, 128);
20586 __ Crc32h(w13, w0, w1);
20587
20588 __ Mov(w0, UINT32_MAX);
20589 __ Mov(w1, 255);
20590 __ Crc32h(w14, w0, w1);
20591
20592 __ Mov(w0, 0x00010001);
20593 __ Mov(w1, 0x10001000);
20594 __ Crc32h(w15, w0, w1);
20595
20596 END();
20597 RUN();
20598
20599 ASSERT_EQUAL_64(0x0, x10);
20600 ASSERT_EQUAL_64(0x0e848dba, x11);
20601 ASSERT_EQUAL_64(0x0e848dba, x12);
20602 ASSERT_EQUAL_64(0x3b83984b, x13);
20603 ASSERT_EQUAL_64(0x2d021072, x14);
20604 ASSERT_EQUAL_64(0x04ac2124, x15);
20605
20606 TEARDOWN();
20607}
20608
20609
20610TEST(crc32w) {
20611 SETUP();
20612 START();
20613
20614 __ Mov(w0, 0);
20615 __ Mov(w1, 0);
20616 __ Crc32w(w10, w0, w1);
20617
20618 __ Mov(w0, 0x1);
20619 __ Mov(w1, 0x80000031);
20620 __ Crc32w(w11, w0, w1);
20621
20622 __ Mov(w0, 0);
20623 __ Mov(w1, 128);
20624 __ Crc32w(w13, w0, w1);
20625
20626 __ Mov(w0, UINT32_MAX);
20627 __ Mov(w1, 255);
20628 __ Crc32w(w14, w0, w1);
20629
20630 __ Mov(w0, 0x00010001);
20631 __ Mov(w1, 0x10001000);
20632 __ Crc32w(w15, w0, w1);
20633
20634 END();
20635 RUN();
20636
20637 ASSERT_EQUAL_64(0x0, x10);
20638 ASSERT_EQUAL_64(0x1d937b81, x11);
20639 ASSERT_EQUAL_64(0xed59b63b, x13);
20640 ASSERT_EQUAL_64(0x00be2612, x14);
20641 ASSERT_EQUAL_64(0xa036e530, x15);
20642
20643 TEARDOWN();
20644}
20645
20646
20647TEST(crc32x) {
20648 SETUP();
20649 START();
20650
20651 __ Mov(w0, 0);
20652 __ Mov(x1, 0);
20653 __ Crc32x(w10, w0, x1);
20654
20655 __ Mov(w0, 0x1);
20656 __ Mov(x1, UINT64_C(0x0000000800000031));
20657 __ Crc32x(w11, w0, x1);
20658
20659 __ Mov(w0, 0);
20660 __ Mov(x1, 128);
20661 __ Crc32x(w13, w0, x1);
20662
20663 __ Mov(w0, UINT32_MAX);
20664 __ Mov(x1, 255);
20665 __ Crc32x(w14, w0, x1);
20666
20667 __ Mov(w0, 0x00010001);
20668 __ Mov(x1, UINT64_C(0x1000100000000000));
20669 __ Crc32x(w15, w0, x1);
20670
20671 END();
20672 RUN();
20673
20674 ASSERT_EQUAL_64(0x0, x10);
20675 ASSERT_EQUAL_64(0x40797b92, x11);
20676 ASSERT_EQUAL_64(0x533b85da, x13);
20677 ASSERT_EQUAL_64(0xbc962670, x14);
20678 ASSERT_EQUAL_64(0x0667602f, x15);
20679
20680 TEARDOWN();
20681}
20682
20683
20684TEST(crc32cb) {
20685 SETUP();
20686 START();
20687
20688 __ Mov(w0, 0);
20689 __ Mov(w1, 0);
20690 __ Crc32cb(w10, w0, w1);
20691
20692 __ Mov(w0, 0x1);
20693 __ Mov(w1, 0x138);
20694 __ Crc32cb(w11, w0, w1);
20695
20696 __ Mov(w0, 0x1);
20697 __ Mov(w1, 0x38);
20698 __ Crc32cb(w12, w0, w1);
20699
20700 __ Mov(w0, 0);
20701 __ Mov(w1, 128);
20702 __ Crc32cb(w13, w0, w1);
20703
20704 __ Mov(w0, UINT32_MAX);
20705 __ Mov(w1, 255);
20706 __ Crc32cb(w14, w0, w1);
20707
20708 __ Mov(w0, 0x00010001);
20709 __ Mov(w1, 0x10001000);
20710 __ Crc32cb(w15, w0, w1);
20711
20712 END();
20713 RUN();
20714
20715 ASSERT_EQUAL_64(0x0, x10);
20716 ASSERT_EQUAL_64(0x4851927d, x11);
20717 ASSERT_EQUAL_64(0x4851927d, x12);
20718 ASSERT_EQUAL_64(0x82f63b78, x13);
20719 ASSERT_EQUAL_64(0x00ffffff, x14);
20720 ASSERT_EQUAL_64(0xf26b8203, x15);
20721
20722 TEARDOWN();
20723}
20724
20725
20726TEST(crc32ch) {
20727 SETUP();
20728 START();
20729
20730 __ Mov(w0, 0);
20731 __ Mov(w1, 0);
20732 __ Crc32ch(w10, w0, w1);
20733
20734 __ Mov(w0, 0x1);
20735 __ Mov(w1, 0x10038);
20736 __ Crc32ch(w11, w0, w1);
20737
20738 __ Mov(w0, 0x1);
20739 __ Mov(w1, 0x38);
20740 __ Crc32ch(w12, w0, w1);
20741
20742 __ Mov(w0, 0);
20743 __ Mov(w1, 128);
20744 __ Crc32ch(w13, w0, w1);
20745
20746 __ Mov(w0, UINT32_MAX);
20747 __ Mov(w1, 255);
20748 __ Crc32ch(w14, w0, w1);
20749
20750 __ Mov(w0, 0x00010001);
20751 __ Mov(w1, 0x10001000);
20752 __ Crc32ch(w15, w0, w1);
20753
20754 END();
20755 RUN();
20756
20757 ASSERT_EQUAL_64(0x0, x10);
20758 ASSERT_EQUAL_64(0xcef8494c, x11);
20759 ASSERT_EQUAL_64(0xcef8494c, x12);
20760 ASSERT_EQUAL_64(0xfbc3faf9, x13);
20761 ASSERT_EQUAL_64(0xad7dacae, x14);
20762 ASSERT_EQUAL_64(0x03fc5f19, x15);
20763
20764 TEARDOWN();
20765}
20766
20767
20768TEST(crc32cw) {
20769 SETUP();
20770 START();
20771
20772 __ Mov(w0, 0);
20773 __ Mov(w1, 0);
20774 __ Crc32cw(w10, w0, w1);
20775
20776 __ Mov(w0, 0x1);
20777 __ Mov(w1, 0x80000031);
20778 __ Crc32cw(w11, w0, w1);
20779
20780 __ Mov(w0, 0);
20781 __ Mov(w1, 128);
20782 __ Crc32cw(w13, w0, w1);
20783
20784 __ Mov(w0, UINT32_MAX);
20785 __ Mov(w1, 255);
20786 __ Crc32cw(w14, w0, w1);
20787
20788 __ Mov(w0, 0x00010001);
20789 __ Mov(w1, 0x10001000);
20790 __ Crc32cw(w15, w0, w1);
20791
20792 END();
20793 RUN();
20794
20795 ASSERT_EQUAL_64(0x0, x10);
20796 ASSERT_EQUAL_64(0xbcb79ece, x11);
20797 ASSERT_EQUAL_64(0x52a0c93f, x13);
20798 ASSERT_EQUAL_64(0x9f9b5c7a, x14);
20799 ASSERT_EQUAL_64(0xae1b882a, x15);
20800
20801 TEARDOWN();
20802}
20803
20804
20805TEST(crc32cx) {
20806 SETUP();
20807 START();
20808
20809 __ Mov(w0, 0);
20810 __ Mov(x1, 0);
20811 __ Crc32cx(w10, w0, x1);
20812
20813 __ Mov(w0, 0x1);
20814 __ Mov(x1, UINT64_C(0x0000000800000031));
20815 __ Crc32cx(w11, w0, x1);
20816
20817 __ Mov(w0, 0);
20818 __ Mov(x1, 128);
20819 __ Crc32cx(w13, w0, x1);
20820
20821 __ Mov(w0, UINT32_MAX);
20822 __ Mov(x1, 255);
20823 __ Crc32cx(w14, w0, x1);
20824
20825 __ Mov(w0, 0x00010001);
20826 __ Mov(x1, UINT64_C(0x1000100000000000));
20827 __ Crc32cx(w15, w0, x1);
20828
20829 END();
20830 RUN();
20831
20832 ASSERT_EQUAL_64(0x0, x10);
20833 ASSERT_EQUAL_64(0x7f320fcb, x11);
20834 ASSERT_EQUAL_64(0x34019664, x13);
20835 ASSERT_EQUAL_64(0x6cc27dd0, x14);
20836 ASSERT_EQUAL_64(0xc6f0acdb, x15);
20837
20838 TEARDOWN();
20839}
20840
20841
20842TEST(neon_fabd_scalar) {
20843 SETUP();
20844
20845 START();
20846 __ Fmov(s0, 2.0);
20847 __ Fmov(s1, 0.5);
20848 __ Fmov(s2, 0.0);
20849 __ Fmov(s3, -0.0);
20850 __ Fmov(s4, kFP32PositiveInfinity);
20851 __ Fmov(s5, kFP32NegativeInfinity);
20852 __ Fabd(s16, s1, s0);
20853 __ Fabd(s17, s2, s3);
20854 __ Fabd(s18, s2, s5);
20855 __ Fabd(s19, s3, s4);
20856 __ Fabd(s20, s3, s5);
20857
20858 __ Fmov(d21, 2.0);
20859 __ Fmov(d22, 0.5);
20860 __ Fmov(d23, 0.0);
20861 __ Fmov(d24, -0.0);
20862 __ Fmov(d25, kFP64PositiveInfinity);
20863 __ Fmov(d26, kFP64NegativeInfinity);
20864 __ Fabd(d27, d21, d22);
20865 __ Fabd(d28, d23, d24);
20866 __ Fabd(d29, d23, d26);
20867 __ Fabd(d30, d24, d25);
20868 __ Fabd(d31, d24, d26);
20869 END();
20870
20871 RUN();
20872
20873 ASSERT_EQUAL_FP32(1.5, s16);
20874 ASSERT_EQUAL_FP32(0.0, s17);
20875 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s18);
20876 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s19);
20877 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s20);
20878 ASSERT_EQUAL_FP64(1.5, d27);
20879 ASSERT_EQUAL_FP64(0.0, d28);
20880 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d29);
20881 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d30);
20882 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d31);
20883
20884 TEARDOWN();
20885}
20886
20887
20888TEST(neon_faddp_scalar) {
20889 SETUP();
20890
20891 START();
20892 __ Movi(d0, 0x3f80000040000000);
20893 __ Movi(d1, 0xff8000007f800000);
20894 __ Movi(d2, 0x0000000080000000);
20895 __ Faddp(s0, v0.V2S());
20896 __ Faddp(s1, v1.V2S());
20897 __ Faddp(s2, v2.V2S());
20898
20899 __ Movi(v3.V2D(), 0xc000000000000000, 0x4000000000000000);
20900 __ Movi(v4.V2D(), 0xfff8000000000000, 0x7ff8000000000000);
20901 __ Movi(v5.V2D(), 0x0000000000000000, 0x8000000000000000);
20902 __ Faddp(d3, v3.V2D());
20903 __ Faddp(d4, v4.V2D());
20904 __ Faddp(d5, v5.V2D());
20905 END();
20906
20907 RUN();
20908
20909 ASSERT_EQUAL_FP32(3.0, s0);
20910 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s1);
20911 ASSERT_EQUAL_FP32(0.0, s2);
20912 ASSERT_EQUAL_FP64(0.0, d3);
20913 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d4);
20914 ASSERT_EQUAL_FP64(0.0, d5);
20915
20916 TEARDOWN();
20917}
20918
20919
20920TEST(neon_fmaxp_scalar) {
20921 SETUP();
20922
20923 START();
20924 __ Movi(d0, 0x3f80000040000000);
20925 __ Movi(d1, 0xff8000007f800000);
20926 __ Movi(d2, 0x7fc00000ff800000);
20927 __ Fmaxp(s0, v0.V2S());
20928 __ Fmaxp(s1, v1.V2S());
20929 __ Fmaxp(s2, v2.V2S());
20930
20931 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
20932 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
20933 __ Movi(v5.V2D(), 0x7ff0000000000000, 0x7ff8000000000000);
20934 __ Fmaxp(d3, v3.V2D());
20935 __ Fmaxp(d4, v4.V2D());
20936 __ Fmaxp(d5, v5.V2D());
20937 END();
20938
20939 RUN();
20940
20941 ASSERT_EQUAL_FP32(2.0, s0);
20942 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s1);
20943 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s2);
20944 ASSERT_EQUAL_FP64(2.0, d3);
20945 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d4);
20946 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d5);
20947
20948 TEARDOWN();
20949}
20950
20951
20952TEST(neon_fmaxnmp_scalar) {
20953 SETUP();
20954
20955 START();
20956 __ Movi(d0, 0x3f80000040000000);
20957 __ Movi(d1, 0xff8000007f800000);
20958 __ Movi(d2, 0x7fc00000ff800000);
20959 __ Fmaxnmp(s0, v0.V2S());
20960 __ Fmaxnmp(s1, v1.V2S());
20961 __ Fmaxnmp(s2, v2.V2S());
20962
20963 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
20964 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
20965 __ Movi(v5.V2D(), 0x7ff8000000000000, 0xfff0000000000000);
20966 __ Fmaxnmp(d3, v3.V2D());
20967 __ Fmaxnmp(d4, v4.V2D());
20968 __ Fmaxnmp(d5, v5.V2D());
20969 END();
20970
20971 RUN();
20972
20973 ASSERT_EQUAL_FP32(2.0, s0);
20974 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s1);
20975 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s2);
20976 ASSERT_EQUAL_FP64(2.0, d3);
20977 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d4);
20978 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d5);
20979
20980 TEARDOWN();
20981}
20982
20983
20984TEST(neon_fminp_scalar) {
20985 SETUP();
20986
20987 START();
20988 __ Movi(d0, 0x3f80000040000000);
20989 __ Movi(d1, 0xff8000007f800000);
20990 __ Movi(d2, 0x7fc00000ff800000);
20991 __ Fminp(s0, v0.V2S());
20992 __ Fminp(s1, v1.V2S());
20993 __ Fminp(s2, v2.V2S());
20994
20995 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
20996 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
20997 __ Movi(v5.V2D(), 0x7ff0000000000000, 0x7ff8000000000000);
20998 __ Fminp(d3, v3.V2D());
20999 __ Fminp(d4, v4.V2D());
21000 __ Fminp(d5, v5.V2D());
21001 END();
21002
21003 RUN();
21004
21005 ASSERT_EQUAL_FP32(1.0, s0);
21006 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s1);
21007 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s2);
21008 ASSERT_EQUAL_FP64(1.0, d3);
21009 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d4);
21010 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d5);
21011
21012 TEARDOWN();
21013}
21014
21015
21016TEST(neon_fminnmp_scalar) {
21017 SETUP();
21018
21019 START();
21020 __ Movi(d0, 0x3f80000040000000);
21021 __ Movi(d1, 0xff8000007f800000);
21022 __ Movi(d2, 0x7fc00000ff800000);
21023 __ Fminnmp(s0, v0.V2S());
21024 __ Fminnmp(s1, v1.V2S());
21025 __ Fminnmp(s2, v2.V2S());
21026
21027 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
21028 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
21029 __ Movi(v5.V2D(), 0x7ff8000000000000, 0xfff0000000000000);
21030 __ Fminnmp(d3, v3.V2D());
21031 __ Fminnmp(d4, v4.V2D());
21032 __ Fminnmp(d5, v5.V2D());
21033 END();
21034
21035 RUN();
21036
21037 ASSERT_EQUAL_FP32(1.0, s0);
21038 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s1);
21039 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s2);
21040 ASSERT_EQUAL_FP64(1.0, d3);
21041 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d4);
21042 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d5);
21043
21044 TEARDOWN();
21045}
21046
21047
21048TEST(neon_tbl) {
21049 SETUP();
21050
21051 START();
21052 __ Movi(v30.V2D(), 0xbf561e188b1280e9, 0xbd542b8cbd24e8e8);
21053 __ Movi(v31.V2D(), 0xb5e9883d2c88a46d, 0x12276d5b614c915e);
21054 __ Movi(v0.V2D(), 0xc45b7782bc5ecd72, 0x5dd4fe5a4bc6bf5e);
21055 __ Movi(v1.V2D(), 0x1e3254094bd1746a, 0xf099ecf50e861c80);
21056
21057 __ Movi(v4.V2D(), 0xf80c030100031f16, 0x00070504031201ff);
21058 __ Movi(v5.V2D(), 0x1f01001afc14202a, 0x2a081e1b0c02020c);
21059 __ Movi(v6.V2D(), 0x353f1a13022a2360, 0x2c464a00203a0a33);
21060 __ Movi(v7.V2D(), 0x64801a1c054cf30d, 0x793a2c052e213739);
21061
21062 __ Movi(v8.V2D(), 0xb7f60ad7d7d88f13, 0x13eefc240496e842);
21063 __ Movi(v9.V2D(), 0x1be199c7c69b47ec, 0x8e4b9919f6eed443);
21064 __ Movi(v10.V2D(), 0x9bd2e1654c69e48f, 0x2143d089e426c6d2);
21065 __ Movi(v11.V2D(), 0xc31dbdc4a0393065, 0x1ecc2077caaf64d8);
21066 __ Movi(v12.V2D(), 0x29b24463967bc6eb, 0xdaf59970df01c93b);
21067 __ Movi(v13.V2D(), 0x3e20a4a4cb6813f4, 0x20a5832713dae669);
21068 __ Movi(v14.V2D(), 0xc5ff9a94041b1fdf, 0x2f46cde38cba2682);
21069 __ Movi(v15.V2D(), 0xd8cc5b0e61f387e6, 0xe69d6d314971e8fd);
21070
21071 __ Tbl(v8.V16B(), v1.V16B(), v4.V16B());
21072 __ Tbl(v9.V16B(), v0.V16B(), v1.V16B(), v5.V16B());
21073 __ Tbl(v10.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V16B());
21074 __ Tbl(v11.V16B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V16B());
21075 __ Tbl(v12.V8B(), v1.V16B(), v4.V8B());
21076 __ Tbl(v13.V8B(), v0.V16B(), v1.V16B(), v5.V8B());
21077 __ Tbl(v14.V8B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V8B());
21078 __ Tbl(v15.V8B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V8B());
21079
21080 __ Movi(v16.V2D(), 0xb7f60ad7d7d88f13, 0x13eefc240496e842);
21081 __ Movi(v17.V2D(), 0x1be199c7c69b47ec, 0x8e4b9919f6eed443);
21082 __ Movi(v18.V2D(), 0x9bd2e1654c69e48f, 0x2143d089e426c6d2);
21083 __ Movi(v19.V2D(), 0xc31dbdc4a0393065, 0x1ecc2077caaf64d8);
21084 __ Movi(v20.V2D(), 0x29b24463967bc6eb, 0xdaf59970df01c93b);
21085 __ Movi(v21.V2D(), 0x3e20a4a4cb6813f4, 0x20a5832713dae669);
21086 __ Movi(v22.V2D(), 0xc5ff9a94041b1fdf, 0x2f46cde38cba2682);
21087 __ Movi(v23.V2D(), 0xd8cc5b0e61f387e6, 0xe69d6d314971e8fd);
21088
21089 __ Tbx(v16.V16B(), v1.V16B(), v4.V16B());
21090 __ Tbx(v17.V16B(), v0.V16B(), v1.V16B(), v5.V16B());
21091 __ Tbx(v18.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V16B());
21092 __ Tbx(v19.V16B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V16B());
21093 __ Tbx(v20.V8B(), v1.V16B(), v4.V8B());
21094 __ Tbx(v21.V8B(), v0.V16B(), v1.V16B(), v5.V8B());
21095 __ Tbx(v22.V8B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V8B());
21096 __ Tbx(v23.V8B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V8B());
21097 END();
21098
21099 RUN();
21100
21101 ASSERT_EQUAL_128(0x00090e1c800e0000, 0x80f0ecf50e001c00, v8);
21102 ASSERT_EQUAL_128(0x1ebf5ed100f50000, 0x0072324b82c6c682, v9);
21103 ASSERT_EQUAL_128(0x00005e4b4cd10e00, 0x0900005e80008800, v10);
21104 ASSERT_EQUAL_128(0x0000883d2b00001e, 0x00d1822b5bbff074, v11);
21105 ASSERT_EQUAL_128(0x0000000000000000, 0x80f0ecf50e001c00, v12);
21106 ASSERT_EQUAL_128(0x0000000000000000, 0x0072324b82c6c682, v13);
21107 ASSERT_EQUAL_128(0x0000000000000000, 0x0900005e80008800, v14);
21108 ASSERT_EQUAL_128(0x0000000000000000, 0x00d1822b5bbff074, v15);
21109
21110 ASSERT_EQUAL_128(0xb7090e1c800e8f13, 0x80f0ecf50e961c42, v16);
21111 ASSERT_EQUAL_128(0x1ebf5ed1c6f547ec, 0x8e72324b82c6c682, v17);
21112 ASSERT_EQUAL_128(0x9bd25e4b4cd10e8f, 0x0943d05e802688d2, v18);
21113 ASSERT_EQUAL_128(0xc31d883d2b39301e, 0x1ed1822b5bbff074, v19);
21114 ASSERT_EQUAL_128(0x0000000000000000, 0x80f0ecf50e011c3b, v20);
21115 ASSERT_EQUAL_128(0x0000000000000000, 0x2072324b82c6c682, v21);
21116 ASSERT_EQUAL_128(0x0000000000000000, 0x0946cd5e80ba8882, v22);
21117 ASSERT_EQUAL_128(0x0000000000000000, 0xe6d1822b5bbff074, v23);
21118
21119 TEARDOWN();
21120}
21121
21122
21123TEST(regress_cmp_shift_imm) {
21124 SETUP();
21125
21126 START();
21127
21128 __ Mov(x0, 0x3d720c8d);
21129 __ Cmp(x0, Operand(0x3d720c8d));
21130
21131 END();
21132 RUN();
21133
21134 ASSERT_EQUAL_NZCV(ZCFlag);
21135
21136 TEARDOWN();
21137}
21138
21139
21140TEST(compute_address) {
21141 SETUP();
21142
21143 START();
21144 int64_t base_address = INT64_C(0x123000000abc);
21145 int64_t reg_offset = INT64_C(0x1087654321);
21146 Register base = x0;
21147 Register offset = x1;
21148
21149 __ Mov(base, base_address);
21150 __ Mov(offset, reg_offset);
21151
21152
21153 __ ComputeAddress(x2, MemOperand(base, 0));
21154 __ ComputeAddress(x3, MemOperand(base, 8));
21155 __ ComputeAddress(x4, MemOperand(base, -100));
21156
21157 __ ComputeAddress(x5, MemOperand(base, offset));
21158 __ ComputeAddress(x6, MemOperand(base, offset, LSL, 2));
21159 __ ComputeAddress(x7, MemOperand(base, offset, LSL, 4));
21160 __ ComputeAddress(x8, MemOperand(base, offset, LSL, 8));
21161
21162 __ ComputeAddress(x9, MemOperand(base, offset, SXTW));
21163 __ ComputeAddress(x10, MemOperand(base, offset, UXTW, 1));
21164 __ ComputeAddress(x11, MemOperand(base, offset, SXTW, 2));
21165 __ ComputeAddress(x12, MemOperand(base, offset, UXTW, 3));
21166
21167 END();
21168
21169 RUN();
21170
21171 ASSERT_EQUAL_64(base_address, base);
21172
21173 ASSERT_EQUAL_64(INT64_C(0x123000000abc), x2);
21174 ASSERT_EQUAL_64(INT64_C(0x123000000ac4), x3);
21175 ASSERT_EQUAL_64(INT64_C(0x123000000a58), x4);
21176
21177 ASSERT_EQUAL_64(INT64_C(0x124087654ddd), x5);
21178 ASSERT_EQUAL_64(INT64_C(0x12721d951740), x6);
21179 ASSERT_EQUAL_64(INT64_C(0x133876543ccc), x7);
21180 ASSERT_EQUAL_64(INT64_C(0x22b765432bbc), x8);
21181
21182 ASSERT_EQUAL_64(INT64_C(0x122f87654ddd), x9);
21183 ASSERT_EQUAL_64(INT64_C(0x12310eca90fe), x10);
21184 ASSERT_EQUAL_64(INT64_C(0x122e1d951740), x11);
21185 ASSERT_EQUAL_64(INT64_C(0x12343b2a23c4), x12);
21186
21187 TEARDOWN();
21188}
21189
21190
21191TEST(far_branch_backward) {
21192 // Test that the MacroAssembler correctly resolves backward branches to labels
21193 // that are outside the immediate range of branch instructions.
21194 // Take into account that backward branches can reach one instruction further
21195 // than forward branches.
21196 const int overflow_size = kInstructionSize +
21197 std::max(Instruction::ImmBranchForwardRange(TestBranchType),
21198 std::max(Instruction::ImmBranchForwardRange(CompareBranchType),
21199 Instruction::ImmBranchForwardRange(CondBranchType)));
21200
21201 SETUP();
21202 START();
21203
21204 Label done, fail;
21205 Label test_tbz, test_cbz, test_bcond;
21206 Label success_tbz, success_cbz, success_bcond;
21207
21208 __ Mov(x0, 0);
21209 __ Mov(x1, 1);
21210 __ Mov(x10, 0);
21211
21212 __ B(&test_tbz);
21213 __ Bind(&success_tbz);
21214 __ Orr(x0, x0, 1 << 0);
21215 __ B(&test_cbz);
21216 __ Bind(&success_cbz);
21217 __ Orr(x0, x0, 1 << 1);
21218 __ B(&test_bcond);
21219 __ Bind(&success_bcond);
21220 __ Orr(x0, x0, 1 << 2);
21221
21222 __ B(&done);
21223
21224 // Generate enough code to overflow the immediate range of the three types of
21225 // branches below.
21226 for (unsigned i = 0; i < overflow_size / kInstructionSize; ++i) {
21227 if (i % 100 == 0) {
21228 // If we do land in this code, we do not want to execute so many nops
21229 // before reaching the end of test (especially if tracing is activated).
21230 __ B(&fail);
21231 } else {
21232 __ Nop();
21233 }
21234 }
21235 __ B(&fail);
21236
21237 __ Bind(&test_tbz);
21238 __ Tbz(x10, 7, &success_tbz);
21239 __ Bind(&test_cbz);
21240 __ Cbz(x10, &success_cbz);
21241 __ Bind(&test_bcond);
21242 __ Cmp(x10, 0);
21243 __ B(eq, &success_bcond);
21244
21245 // For each out-of-range branch instructions, at least two instructions should
21246 // have been generated.
21247 VIXL_CHECK(masm.SizeOfCodeGeneratedSince(&test_tbz) >= 7 * kInstructionSize);
21248
21249 __ Bind(&fail);
21250 __ Mov(x1, 0);
21251 __ Bind(&done);
21252
21253 END();
21254 RUN();
21255
21256 ASSERT_EQUAL_64(0x7, x0);
21257 ASSERT_EQUAL_64(0x1, x1);
21258
21259 TEARDOWN();
21260}
21261
21262
21263TEST(single_veneer) {
21264 SETUP();
21265 START();
21266
21267 const int max_range = Instruction::ImmBranchForwardRange(TestBranchType);
21268
21269 Label success, fail, done;
21270
21271 __ Mov(x0, 0);
21272 __ Mov(x1, 1);
21273 __ Mov(x10, 0);
21274
21275 __ Tbz(x10, 7, &success);
21276
21277 // Generate enough code to overflow the immediate range of the `tbz`.
21278 for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
21279 if (i % 100 == 0) {
21280 // If we do land in this code, we do not want to execute so many nops
21281 // before reaching the end of test (especially if tracing is activated).
21282 __ B(&fail);
21283 } else {
21284 __ Nop();
21285 }
21286 }
21287 __ B(&fail);
21288
21289 __ Bind(&success);
21290 __ Mov(x0, 1);
21291
21292 __ B(&done);
21293 __ Bind(&fail);
21294 __ Mov(x1, 0);
21295 __ Bind(&done);
21296
21297 END();
21298 RUN();
21299
21300 ASSERT_EQUAL_64(1, x0);
21301 ASSERT_EQUAL_64(1, x1);
21302
21303 TEARDOWN();
21304}
21305
21306
21307TEST(simple_veneers) {
21308 // Test that the MacroAssembler correctly emits veneers for forward branches
21309 // to labels that are outside the immediate range of branch instructions.
21310 const int max_range =
21311 std::max(Instruction::ImmBranchForwardRange(TestBranchType),
21312 std::max(Instruction::ImmBranchForwardRange(CompareBranchType),
21313 Instruction::ImmBranchForwardRange(CondBranchType)));
21314
21315 SETUP();
21316 START();
21317
21318 Label done, fail;
21319 Label test_tbz, test_cbz, test_bcond;
21320 Label success_tbz, success_cbz, success_bcond;
21321
21322 __ Mov(x0, 0);
21323 __ Mov(x1, 1);
21324 __ Mov(x10, 0);
21325
21326 __ Bind(&test_tbz);
21327 __ Tbz(x10, 7, &success_tbz);
21328 __ Bind(&test_cbz);
21329 __ Cbz(x10, &success_cbz);
21330 __ Bind(&test_bcond);
21331 __ Cmp(x10, 0);
21332 __ B(eq, &success_bcond);
21333
21334 // Generate enough code to overflow the immediate range of the three types of
21335 // branches below.
21336 for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
21337 if (i % 100 == 0) {
21338 // If we do land in this code, we do not want to execute so many nops
21339 // before reaching the end of test (especially if tracing is activated).
21340 __ B(&fail);
21341 } else {
21342 __ Nop();
21343 }
21344 }
21345 __ B(&fail);
21346
21347 __ Bind(&success_tbz);
21348 __ Orr(x0, x0, 1 << 0);
21349 __ B(&test_cbz);
21350 __ Bind(&success_cbz);
21351 __ Orr(x0, x0, 1 << 1);
21352 __ B(&test_bcond);
21353 __ Bind(&success_bcond);
21354 __ Orr(x0, x0, 1 << 2);
21355
21356 __ B(&done);
21357 __ Bind(&fail);
21358 __ Mov(x1, 0);
21359 __ Bind(&done);
21360
21361 END();
21362 RUN();
21363
21364 ASSERT_EQUAL_64(0x7, x0);
21365 ASSERT_EQUAL_64(0x1, x1);
21366
21367 TEARDOWN();
21368}
21369
21370
21371TEST(veneers_stress) {
21372 SETUP();
21373 START();
21374
21375 // This is a code generation test stressing the emission of veneers. The code
21376 // generated is not executed.
21377
21378 Label target;
21379 const unsigned max_range = Instruction::ImmBranchForwardRange(CondBranchType);
21380 const unsigned iterations =
21381 (max_range + max_range / 4) / (4 * kInstructionSize);
21382 for (unsigned i = 0; i < iterations; i++) {
21383 __ B(&target);
21384 __ B(eq, &target);
21385 __ Cbz(x0, &target);
21386 __ Tbz(x0, 0, &target);
21387 }
21388 __ Bind(&target);
21389
21390 END();
21391 TEARDOWN();
21392}
21393
21394
21395TEST(veneers_two_out_of_range) {
21396 SETUP();
21397 START();
21398
21399 // This is a code generation test. The code generated is not executed.
21400 // Ensure that the MacroAssembler considers unresolved branches to chose when
21401 // a veneer pool should be emitted. We generate two branches that go out of
21402 // range at the same offset. When the MacroAssembler decides to emit the
21403 // veneer pool, the emission of a first veneer should not cause the other
21404 // branch to go out of range.
21405
21406 int range_cbz = Instruction::ImmBranchForwardRange(CompareBranchType);
21407 int range_tbz = Instruction::ImmBranchForwardRange(TestBranchType);
21408 int max_target = masm.CursorOffset() + range_cbz;
21409
21410 Label done;
21411
21412 // We use different labels to prevent the MacroAssembler from sharing veneers.
21413 Label target_cbz, target_tbz;
21414
21415 __ Cbz(x0, &target_cbz);
21416 while (masm.CursorOffset() < max_target - range_tbz) {
21417 __ Nop();
21418 }
21419 __ Tbz(x0, 0, &target_tbz);
21420 while (masm.CursorOffset() < max_target) {
21421 __ Nop();
21422 }
21423
21424 // This additional nop makes the branches go out of range.
21425 __ Nop();
21426
21427 __ Bind(&target_cbz);
21428 __ Bind(&target_tbz);
21429
21430 END();
21431 TEARDOWN();
21432}
21433
21434
21435TEST(veneers_hanging) {
21436 SETUP();
21437 START();
21438
21439 // This is a code generation test. The code generated is not executed.
21440 // Ensure that the MacroAssembler considers unresolved branches to chose when
21441 // a veneer pool should be emitted. This is similar to the
21442 // 'veneers_two_out_of_range' test. We try to trigger the following situation:
21443 // b.eq label
21444 // b.eq label
21445 // ...
21446 // nop
21447 // ...
21448 // cbz x0, label
21449 // cbz x0, label
21450 // ...
21451 // tbz x0, 0 label
21452 // nop
21453 // ...
21454 // nop <- From here the `b.eq` and `cbz` instructions run out of range,
21455 // so a literal pool is required.
21456 // veneer
21457 // veneer
21458 // veneer <- The `tbz` runs out of range somewhere in the middle of the
21459 // veneer veneer pool.
21460 // veneer
21461
21462 const int range_bcond = Instruction::ImmBranchForwardRange(CondBranchType);
21463 const int range_cbz = Instruction::ImmBranchForwardRange(CompareBranchType);
21464 const int range_tbz = Instruction::ImmBranchForwardRange(TestBranchType);
21465 const int max_target = masm.CursorOffset() + range_bcond;
21466
21467 Label done;
21468 const int n_bcond = 100;
21469 const int n_cbz = 100;
21470 const int n_tbz = 1;
21471 const int kNTotalBranches = n_bcond + n_cbz + n_tbz;
21472
21473 // We use different labels to prevent the MacroAssembler from sharing veneers.
21474 Label labels[kNTotalBranches];
21475 for (int i = 0; i < kNTotalBranches; i++) {
21476 new(&labels[i]) Label();
21477 }
21478
21479 for (int i = 0; i < n_bcond; i++) {
21480 __ B(eq, &labels[i]);
21481 }
21482
21483 while (masm.CursorOffset() < max_target - range_cbz) {
21484 __ Nop();
21485 }
21486
21487 for (int i = 0; i < n_cbz; i++) {
21488 __ Cbz(x0, &labels[n_bcond + i]);
21489 }
21490
21491 // Ensure the 'tbz' will go out of range after some of the previously
21492 // generated branches.
21493 int margin = (n_bcond / 2) * kInstructionSize;
21494 while (masm.CursorOffset() < max_target - range_tbz + margin) {
21495 __ Nop();
21496 }
21497
21498 __ Tbz(x0, 0, &labels[n_bcond + n_cbz]);
21499
21500 while (masm.CursorOffset() < max_target) {
21501 __ Nop();
21502 }
21503
21504 // This additional nop makes the 'b.eq' and 'cbz' instructions go out of range
21505 // and forces the emission of a veneer pool. The 'tbz' is not yet out of
21506 // range, but will go out of range while veneers are emitted for the other
21507 // branches.
21508 // The MacroAssembler should ensure that veneers are correctly emitted for all
21509 // the branches, including the 'tbz'. Checks will fail if the target of a
21510 // branch is out of range.
21511 __ Nop();
21512
21513 for (int i = 0; i < kNTotalBranches; i++) {
21514 __ Bind(&labels[i]);
21515 }
21516
21517 END();
21518 TEARDOWN();
21519}
21520
21521
21522TEST(collision_literal_veneer_pools) {
21523 SETUP();
21524 START();
21525
21526 // This is a code generation test. The code generated is not executed.
21527
21528 // Make sure the literal pool is empty;
21529 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21530 ASSERT_LITERAL_POOL_SIZE(0);
21531
21532 // We chose the offsets below to (try to) trigger the following situation:
21533 // buffer offset
21534 // 0: tbz x0, 0, target_tbz ----------------------------------.
21535 // 4: nop |
21536 // ... |
21537 // nop |
21538 // literal gen: ldr s0, [pc + ...] ; load from `pool start + 0` |
21539 // ldr s0, [pc + ...] ; load from `pool start + 4` |
21540 // ... |
21541 // ldr s0, [pc + ...] |
21542 // pool start: floating-point literal (0.1) |
21543 // floating-point literal (1.1) |
21544 // ... |
21545 // floating-point literal (<n>.1) <-----tbz-max-range--'
21546 // floating-point literal (<n+1>.1)
21547 // ...
21548
21549 const int range_tbz = Instruction::ImmBranchForwardRange(TestBranchType);
21550 const int max_target = masm.CursorOffset() + range_tbz;
21551
21552 const size_t target_literal_pool_size = 100 * kInstructionSize;
21553 const int offset_start_literal_gen =
21554 target_literal_pool_size + target_literal_pool_size / 2;
21555
21556
21557 Label target_tbz;
21558
21559 __ Tbz(x0, 0, &target_tbz);
21560 VIXL_CHECK(masm.NumberOfPotentialVeneers() == 1);
21561 while (masm.CursorOffset() < max_target - offset_start_literal_gen) {
21562 __ Nop();
21563 }
21564 VIXL_CHECK(masm.NumberOfPotentialVeneers() == 1);
21565
21566 for (int i = 0; i < 100; i++) {
21567 // Use a different value to force one literal pool entry per iteration.
21568 __ Ldr(s0, i + 0.1);
21569 }
21570 VIXL_CHECK(masm.LiteralPoolSize() >= target_literal_pool_size);
21571
21572 // Force emission of a literal pool.
21573 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21574 ASSERT_LITERAL_POOL_SIZE(0);
21575
21576 // The branch should not have gone out of range during the emission of the
21577 // literal pool.
21578 __ Bind(&target_tbz);
21579
21580 VIXL_CHECK(masm.NumberOfPotentialVeneers() == 0);
21581
21582 END();
21583 TEARDOWN();
21584}
armvixlad96eda2013-06-14 11:42:37 +010021585} // namespace vixl