blob: 642b3d4dce9745418a382e33e01692be1faf5c51 [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
armvixldb644342015-07-21 11:37:10 +01001887static void AdrpOffsetHelper(int64_t offset) {
armvixl4a102ba2014-07-14 09:02:40 +01001888 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 {
armvixldb644342015-07-21 11:37:10 +01001909 int imm21 = static_cast<int>(offset);
armvixlc68cb642014-09-25 18:49:30 +01001910 InstructionAccurateScope scope_page(&masm, kPageSize / kInstructionSize);
armvixl4a102ba2014-07-14 09:02:40 +01001911 // Every adrp instruction on this page should return the same value.
1912 __ adrp(x0, imm21);
1913 __ adrp(x1, imm21);
1914 for (size_t i = 2; i < kPageSize / kInstructionSize; i += 2) {
1915 __ ccmp(x0, x1, NoFlag, eq);
1916 __ adrp(x1, imm21);
1917 }
1918 }
1919 }
1920
1921 END();
1922 RUN();
1923
1924 uintptr_t expected =
armvixldb644342015-07-21 11:37:10 +01001925 masm.GetLabelAddress<uintptr_t>(&page) + (kPageSize * offset);
armvixl4a102ba2014-07-14 09:02:40 +01001926 ASSERT_EQUAL_64(expected, x0);
1927 ASSERT_EQUAL_64(expected, x1);
1928 ASSERT_EQUAL_NZCV(ZCFlag);
1929
armvixlc68cb642014-09-25 18:49:30 +01001930 TEARDOWN_CUSTOM();
armvixl4a102ba2014-07-14 09:02:40 +01001931}
1932
1933
1934// Check that adrp produces the correct result for a specific offset.
1935TEST(adrp_offset) {
1936 AdrpOffsetHelper(0);
1937 AdrpOffsetHelper(1);
1938 AdrpOffsetHelper(-1);
1939 AdrpOffsetHelper(4);
1940 AdrpOffsetHelper(-4);
1941 AdrpOffsetHelper(0x000fffff);
1942 AdrpOffsetHelper(-0x000fffff);
1943 AdrpOffsetHelper(-0x00100000);
1944}
1945
1946
armvixlad96eda2013-06-14 11:42:37 +01001947TEST(branch_cond) {
1948 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01001949 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01001950
armvixl5289c592015-03-02 13:52:04 +00001951 Label done, wrong;
armvixlad96eda2013-06-14 11:42:37 +01001952
1953 START();
1954 __ Mov(x0, 0x1);
1955 __ Mov(x1, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00001956 __ Mov(x2, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01001957
1958 // For each 'cmp' instruction below, condition codes other than the ones
1959 // following it would branch.
1960
armvixl578645f2013-08-15 17:21:42 +01001961 __ Cmp(x1, 0);
armvixlad96eda2013-06-14 11:42:37 +01001962 __ B(&wrong, eq);
1963 __ B(&wrong, lo);
1964 __ B(&wrong, mi);
1965 __ B(&wrong, vs);
1966 __ B(&wrong, ls);
1967 __ B(&wrong, lt);
1968 __ B(&wrong, le);
1969 Label ok_1;
1970 __ B(&ok_1, ne);
1971 __ Mov(x0, 0x0);
1972 __ Bind(&ok_1);
1973
armvixl578645f2013-08-15 17:21:42 +01001974 __ Cmp(x1, 1);
armvixlad96eda2013-06-14 11:42:37 +01001975 __ B(&wrong, ne);
1976 __ B(&wrong, lo);
1977 __ B(&wrong, mi);
1978 __ B(&wrong, vs);
1979 __ B(&wrong, hi);
1980 __ B(&wrong, lt);
1981 __ B(&wrong, gt);
1982 Label ok_2;
1983 __ B(&ok_2, pl);
1984 __ Mov(x0, 0x0);
1985 __ Bind(&ok_2);
1986
armvixl578645f2013-08-15 17:21:42 +01001987 __ Cmp(x1, 2);
armvixlad96eda2013-06-14 11:42:37 +01001988 __ B(&wrong, eq);
1989 __ B(&wrong, hs);
1990 __ B(&wrong, pl);
1991 __ B(&wrong, vs);
1992 __ B(&wrong, hi);
1993 __ B(&wrong, ge);
1994 __ B(&wrong, gt);
1995 Label ok_3;
1996 __ B(&ok_3, vc);
1997 __ Mov(x0, 0x0);
1998 __ Bind(&ok_3);
1999
armvixl578645f2013-08-15 17:21:42 +01002000 __ Cmp(x2, 1);
armvixlad96eda2013-06-14 11:42:37 +01002001 __ B(&wrong, eq);
2002 __ B(&wrong, lo);
2003 __ B(&wrong, mi);
2004 __ B(&wrong, vc);
2005 __ B(&wrong, ls);
2006 __ B(&wrong, ge);
2007 __ B(&wrong, gt);
2008 Label ok_4;
2009 __ B(&ok_4, le);
2010 __ Mov(x0, 0x0);
2011 __ Bind(&ok_4);
armvixl578645f2013-08-15 17:21:42 +01002012
armvixlc68cb642014-09-25 18:49:30 +01002013 // The MacroAssembler does not allow al as a branch condition.
armvixl578645f2013-08-15 17:21:42 +01002014 Label ok_5;
2015 __ b(&ok_5, al);
2016 __ Mov(x0, 0x0);
2017 __ Bind(&ok_5);
2018
armvixlc68cb642014-09-25 18:49:30 +01002019 // The MacroAssembler does not allow nv as a branch condition.
armvixl578645f2013-08-15 17:21:42 +01002020 Label ok_6;
2021 __ b(&ok_6, nv);
2022 __ Mov(x0, 0x0);
2023 __ Bind(&ok_6);
2024
armvixl5289c592015-03-02 13:52:04 +00002025 __ B(&done);
armvixlad96eda2013-06-14 11:42:37 +01002026
2027 __ Bind(&wrong);
2028 __ Mov(x0, 0x0);
armvixl5289c592015-03-02 13:52:04 +00002029
2030 __ Bind(&done);
armvixlad96eda2013-06-14 11:42:37 +01002031 END();
2032
2033 RUN();
2034
2035 ASSERT_EQUAL_64(0x1, x0);
2036
2037 TEARDOWN();
2038}
2039
2040
2041TEST(branch_to_reg) {
2042 SETUP();
2043
2044 // Test br.
2045 Label fn1, after_fn1;
2046
2047 START();
2048 __ Mov(x29, lr);
2049
2050 __ Mov(x1, 0);
2051 __ B(&after_fn1);
2052
2053 __ Bind(&fn1);
2054 __ Mov(x0, lr);
2055 __ Mov(x1, 42);
2056 __ Br(x0);
2057
2058 __ Bind(&after_fn1);
2059 __ Bl(&fn1);
2060
2061 // Test blr.
2062 Label fn2, after_fn2;
2063
2064 __ Mov(x2, 0);
2065 __ B(&after_fn2);
2066
2067 __ Bind(&fn2);
2068 __ Mov(x0, lr);
2069 __ Mov(x2, 84);
2070 __ Blr(x0);
2071
2072 __ Bind(&after_fn2);
2073 __ Bl(&fn2);
2074 __ Mov(x3, lr);
2075
2076 __ Mov(lr, x29);
2077 END();
2078
2079 RUN();
2080
2081 ASSERT_EQUAL_64(core.xreg(3) + kInstructionSize, x0);
2082 ASSERT_EQUAL_64(42, x1);
2083 ASSERT_EQUAL_64(84, x2);
2084
2085 TEARDOWN();
2086}
2087
2088
2089TEST(compare_branch) {
2090 SETUP();
2091
2092 START();
2093 __ Mov(x0, 0);
2094 __ Mov(x1, 0);
2095 __ Mov(x2, 0);
2096 __ Mov(x3, 0);
2097 __ Mov(x4, 0);
2098 __ Mov(x5, 0);
2099 __ Mov(x16, 0);
2100 __ Mov(x17, 42);
2101
2102 Label zt, zt_end;
2103 __ Cbz(w16, &zt);
2104 __ B(&zt_end);
2105 __ Bind(&zt);
2106 __ Mov(x0, 1);
2107 __ Bind(&zt_end);
2108
2109 Label zf, zf_end;
2110 __ Cbz(x17, &zf);
2111 __ B(&zf_end);
2112 __ Bind(&zf);
2113 __ Mov(x1, 1);
2114 __ Bind(&zf_end);
2115
2116 Label nzt, nzt_end;
2117 __ Cbnz(w17, &nzt);
2118 __ B(&nzt_end);
2119 __ Bind(&nzt);
2120 __ Mov(x2, 1);
2121 __ Bind(&nzt_end);
2122
2123 Label nzf, nzf_end;
2124 __ Cbnz(x16, &nzf);
2125 __ B(&nzf_end);
2126 __ Bind(&nzf);
2127 __ Mov(x3, 1);
2128 __ Bind(&nzf_end);
2129
armvixlb0c8ae22014-03-21 14:03:59 +00002130 __ Mov(x18, 0xffffffff00000000);
armvixlad96eda2013-06-14 11:42:37 +01002131
2132 Label a, a_end;
2133 __ Cbz(w18, &a);
2134 __ B(&a_end);
2135 __ Bind(&a);
2136 __ Mov(x4, 1);
2137 __ Bind(&a_end);
2138
2139 Label b, b_end;
2140 __ Cbnz(w18, &b);
2141 __ B(&b_end);
2142 __ Bind(&b);
2143 __ Mov(x5, 1);
2144 __ Bind(&b_end);
2145
2146 END();
2147
2148 RUN();
2149
2150 ASSERT_EQUAL_64(1, x0);
2151 ASSERT_EQUAL_64(0, x1);
2152 ASSERT_EQUAL_64(1, x2);
2153 ASSERT_EQUAL_64(0, x3);
2154 ASSERT_EQUAL_64(1, x4);
2155 ASSERT_EQUAL_64(0, x5);
2156
2157 TEARDOWN();
2158}
2159
2160
2161TEST(test_branch) {
2162 SETUP();
2163
2164 START();
2165 __ Mov(x0, 0);
2166 __ Mov(x1, 0);
2167 __ Mov(x2, 0);
2168 __ Mov(x3, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00002169 __ Mov(x16, 0xaaaaaaaaaaaaaaaa);
armvixlad96eda2013-06-14 11:42:37 +01002170
2171 Label bz, bz_end;
armvixlf37fdc02014-02-05 13:22:16 +00002172 __ Tbz(w16, 0, &bz);
armvixlad96eda2013-06-14 11:42:37 +01002173 __ B(&bz_end);
2174 __ Bind(&bz);
2175 __ Mov(x0, 1);
2176 __ Bind(&bz_end);
2177
2178 Label bo, bo_end;
2179 __ Tbz(x16, 63, &bo);
2180 __ B(&bo_end);
2181 __ Bind(&bo);
2182 __ Mov(x1, 1);
2183 __ Bind(&bo_end);
2184
2185 Label nbz, nbz_end;
2186 __ Tbnz(x16, 61, &nbz);
2187 __ B(&nbz_end);
2188 __ Bind(&nbz);
2189 __ Mov(x2, 1);
2190 __ Bind(&nbz_end);
2191
2192 Label nbo, nbo_end;
armvixlf37fdc02014-02-05 13:22:16 +00002193 __ Tbnz(w16, 2, &nbo);
armvixlad96eda2013-06-14 11:42:37 +01002194 __ B(&nbo_end);
2195 __ Bind(&nbo);
2196 __ Mov(x3, 1);
2197 __ Bind(&nbo_end);
2198 END();
2199
2200 RUN();
2201
2202 ASSERT_EQUAL_64(1, x0);
2203 ASSERT_EQUAL_64(0, x1);
2204 ASSERT_EQUAL_64(1, x2);
2205 ASSERT_EQUAL_64(0, x3);
2206
2207 TEARDOWN();
2208}
2209
2210
armvixlb0c8ae22014-03-21 14:03:59 +00002211TEST(branch_type) {
2212 SETUP();
2213
2214 Label fail, done;
2215
2216 START();
2217 __ Mov(x0, 0x0);
2218 __ Mov(x10, 0x7);
2219 __ Mov(x11, 0x0);
2220
2221 // Test non taken branches.
2222 __ Cmp(x10, 0x7);
2223 __ B(&fail, ne);
2224 __ B(&fail, never);
2225 __ B(&fail, reg_zero, x10);
2226 __ B(&fail, reg_not_zero, x11);
2227 __ B(&fail, reg_bit_clear, x10, 0);
2228 __ B(&fail, reg_bit_set, x10, 3);
2229
2230 // Test taken branches.
2231 Label l1, l2, l3, l4, l5;
2232 __ Cmp(x10, 0x7);
2233 __ B(&l1, eq);
2234 __ B(&fail);
2235 __ Bind(&l1);
2236 __ B(&l2, always);
2237 __ B(&fail);
2238 __ Bind(&l2);
2239 __ B(&l3, reg_not_zero, x10);
2240 __ B(&fail);
2241 __ Bind(&l3);
2242 __ B(&l4, reg_bit_clear, x10, 15);
2243 __ B(&fail);
2244 __ Bind(&l4);
2245 __ B(&l5, reg_bit_set, x10, 1);
2246 __ B(&fail);
2247 __ Bind(&l5);
2248
2249 __ B(&done);
2250
2251 __ Bind(&fail);
2252 __ Mov(x0, 0x1);
2253
2254 __ Bind(&done);
2255
2256 END();
2257
2258 RUN();
2259
2260 ASSERT_EQUAL_64(0x0, x0);
2261
2262 TEARDOWN();
2263}
2264
2265
armvixlad96eda2013-06-14 11:42:37 +01002266TEST(ldr_str_offset) {
2267 SETUP();
2268
armvixlb0c8ae22014-03-21 14:03:59 +00002269 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002270 uint64_t dst[5] = {0, 0, 0, 0, 0};
2271 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2272 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2273
2274 START();
2275 __ Mov(x17, src_base);
2276 __ Mov(x18, dst_base);
2277 __ Ldr(w0, MemOperand(x17));
2278 __ Str(w0, MemOperand(x18));
2279 __ Ldr(w1, MemOperand(x17, 4));
2280 __ Str(w1, MemOperand(x18, 12));
2281 __ Ldr(x2, MemOperand(x17, 8));
2282 __ Str(x2, MemOperand(x18, 16));
2283 __ Ldrb(w3, MemOperand(x17, 1));
2284 __ Strb(w3, MemOperand(x18, 25));
2285 __ Ldrh(w4, MemOperand(x17, 2));
2286 __ Strh(w4, MemOperand(x18, 33));
2287 END();
2288
2289 RUN();
2290
2291 ASSERT_EQUAL_64(0x76543210, x0);
2292 ASSERT_EQUAL_64(0x76543210, dst[0]);
2293 ASSERT_EQUAL_64(0xfedcba98, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00002294 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2295 ASSERT_EQUAL_64(0x0123456789abcdef, x2);
2296 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
armvixlad96eda2013-06-14 11:42:37 +01002297 ASSERT_EQUAL_64(0x32, x3);
2298 ASSERT_EQUAL_64(0x3200, dst[3]);
2299 ASSERT_EQUAL_64(0x7654, x4);
2300 ASSERT_EQUAL_64(0x765400, dst[4]);
2301 ASSERT_EQUAL_64(src_base, x17);
2302 ASSERT_EQUAL_64(dst_base, x18);
2303
2304 TEARDOWN();
2305}
2306
2307
2308TEST(ldr_str_wide) {
2309 SETUP();
2310
2311 uint32_t src[8192];
2312 uint32_t dst[8192];
2313 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2314 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2315 memset(src, 0xaa, 8192 * sizeof(src[0]));
2316 memset(dst, 0xaa, 8192 * sizeof(dst[0]));
2317 src[0] = 0;
2318 src[6144] = 6144;
2319 src[8191] = 8191;
2320
2321 START();
2322 __ Mov(x22, src_base);
2323 __ Mov(x23, dst_base);
2324 __ Mov(x24, src_base);
2325 __ Mov(x25, dst_base);
2326 __ Mov(x26, src_base);
2327 __ Mov(x27, dst_base);
2328
2329 __ Ldr(w0, MemOperand(x22, 8191 * sizeof(src[0])));
2330 __ Str(w0, MemOperand(x23, 8191 * sizeof(dst[0])));
2331 __ Ldr(w1, MemOperand(x24, 4096 * sizeof(src[0]), PostIndex));
2332 __ Str(w1, MemOperand(x25, 4096 * sizeof(dst[0]), PostIndex));
2333 __ Ldr(w2, MemOperand(x26, 6144 * sizeof(src[0]), PreIndex));
2334 __ Str(w2, MemOperand(x27, 6144 * sizeof(dst[0]), PreIndex));
2335 END();
2336
2337 RUN();
2338
2339 ASSERT_EQUAL_32(8191, w0);
2340 ASSERT_EQUAL_32(8191, dst[8191]);
2341 ASSERT_EQUAL_64(src_base, x22);
2342 ASSERT_EQUAL_64(dst_base, x23);
2343 ASSERT_EQUAL_32(0, w1);
2344 ASSERT_EQUAL_32(0, dst[0]);
2345 ASSERT_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24);
2346 ASSERT_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25);
2347 ASSERT_EQUAL_32(6144, w2);
2348 ASSERT_EQUAL_32(6144, dst[6144]);
2349 ASSERT_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26);
2350 ASSERT_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27);
2351
2352 TEARDOWN();
2353}
2354
2355
2356TEST(ldr_str_preindex) {
2357 SETUP();
2358
armvixlb0c8ae22014-03-21 14:03:59 +00002359 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002360 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2361 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2362 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2363
2364 START();
2365 __ Mov(x17, src_base);
2366 __ Mov(x18, dst_base);
2367 __ Mov(x19, src_base);
2368 __ Mov(x20, dst_base);
2369 __ Mov(x21, src_base + 16);
2370 __ Mov(x22, dst_base + 40);
2371 __ Mov(x23, src_base);
2372 __ Mov(x24, dst_base);
2373 __ Mov(x25, src_base);
2374 __ Mov(x26, dst_base);
2375 __ Ldr(w0, MemOperand(x17, 4, PreIndex));
2376 __ Str(w0, MemOperand(x18, 12, PreIndex));
2377 __ Ldr(x1, MemOperand(x19, 8, PreIndex));
2378 __ Str(x1, MemOperand(x20, 16, PreIndex));
2379 __ Ldr(w2, MemOperand(x21, -4, PreIndex));
2380 __ Str(w2, MemOperand(x22, -4, PreIndex));
2381 __ Ldrb(w3, MemOperand(x23, 1, PreIndex));
2382 __ Strb(w3, MemOperand(x24, 25, PreIndex));
2383 __ Ldrh(w4, MemOperand(x25, 3, PreIndex));
2384 __ Strh(w4, MemOperand(x26, 41, PreIndex));
2385 END();
2386
2387 RUN();
2388
2389 ASSERT_EQUAL_64(0xfedcba98, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002390 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2391 ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2392 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
armvixlad96eda2013-06-14 11:42:37 +01002393 ASSERT_EQUAL_64(0x01234567, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00002394 ASSERT_EQUAL_64(0x0123456700000000, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01002395 ASSERT_EQUAL_64(0x32, x3);
2396 ASSERT_EQUAL_64(0x3200, dst[3]);
2397 ASSERT_EQUAL_64(0x9876, x4);
2398 ASSERT_EQUAL_64(0x987600, dst[5]);
2399 ASSERT_EQUAL_64(src_base + 4, x17);
2400 ASSERT_EQUAL_64(dst_base + 12, x18);
2401 ASSERT_EQUAL_64(src_base + 8, x19);
2402 ASSERT_EQUAL_64(dst_base + 16, x20);
2403 ASSERT_EQUAL_64(src_base + 12, x21);
2404 ASSERT_EQUAL_64(dst_base + 36, x22);
2405 ASSERT_EQUAL_64(src_base + 1, x23);
2406 ASSERT_EQUAL_64(dst_base + 25, x24);
2407 ASSERT_EQUAL_64(src_base + 3, x25);
2408 ASSERT_EQUAL_64(dst_base + 41, x26);
2409
2410 TEARDOWN();
2411}
2412
2413
2414TEST(ldr_str_postindex) {
2415 SETUP();
2416
armvixlb0c8ae22014-03-21 14:03:59 +00002417 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002418 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2419 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2420 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2421
2422 START();
2423 __ Mov(x17, src_base + 4);
2424 __ Mov(x18, dst_base + 12);
2425 __ Mov(x19, src_base + 8);
2426 __ Mov(x20, dst_base + 16);
2427 __ Mov(x21, src_base + 8);
2428 __ Mov(x22, dst_base + 32);
2429 __ Mov(x23, src_base + 1);
2430 __ Mov(x24, dst_base + 25);
2431 __ Mov(x25, src_base + 3);
2432 __ Mov(x26, dst_base + 41);
2433 __ Ldr(w0, MemOperand(x17, 4, PostIndex));
2434 __ Str(w0, MemOperand(x18, 12, PostIndex));
2435 __ Ldr(x1, MemOperand(x19, 8, PostIndex));
2436 __ Str(x1, MemOperand(x20, 16, PostIndex));
2437 __ Ldr(x2, MemOperand(x21, -8, PostIndex));
2438 __ Str(x2, MemOperand(x22, -32, PostIndex));
2439 __ Ldrb(w3, MemOperand(x23, 1, PostIndex));
2440 __ Strb(w3, MemOperand(x24, 5, PostIndex));
2441 __ Ldrh(w4, MemOperand(x25, -3, PostIndex));
2442 __ Strh(w4, MemOperand(x26, -41, PostIndex));
2443 END();
2444
2445 RUN();
2446
2447 ASSERT_EQUAL_64(0xfedcba98, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002448 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2449 ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2450 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
2451 ASSERT_EQUAL_64(0x0123456789abcdef, x2);
2452 ASSERT_EQUAL_64(0x0123456789abcdef, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01002453 ASSERT_EQUAL_64(0x32, x3);
2454 ASSERT_EQUAL_64(0x3200, dst[3]);
2455 ASSERT_EQUAL_64(0x9876, x4);
2456 ASSERT_EQUAL_64(0x987600, dst[5]);
2457 ASSERT_EQUAL_64(src_base + 8, x17);
2458 ASSERT_EQUAL_64(dst_base + 24, x18);
2459 ASSERT_EQUAL_64(src_base + 16, x19);
2460 ASSERT_EQUAL_64(dst_base + 32, x20);
2461 ASSERT_EQUAL_64(src_base, x21);
2462 ASSERT_EQUAL_64(dst_base, x22);
2463 ASSERT_EQUAL_64(src_base + 2, x23);
2464 ASSERT_EQUAL_64(dst_base + 30, x24);
2465 ASSERT_EQUAL_64(src_base, x25);
2466 ASSERT_EQUAL_64(dst_base, x26);
2467
2468 TEARDOWN();
2469}
2470
2471
2472TEST(ldr_str_largeindex) {
2473 SETUP();
2474
2475 // This value won't fit in the immediate offset field of ldr/str instructions.
2476 int largeoffset = 0xabcdef;
2477
2478 int64_t data[3] = { 0x1122334455667788, 0, 0 };
armvixlb0c8ae22014-03-21 14:03:59 +00002479 uint64_t base_addr = reinterpret_cast<uintptr_t>(data);
2480 uint64_t drifted_addr = base_addr - largeoffset;
armvixlad96eda2013-06-14 11:42:37 +01002481
2482 // This test checks that we we can use large immediate offsets when
2483 // using PreIndex or PostIndex addressing mode of the MacroAssembler
2484 // Ldr/Str instructions.
2485
2486 START();
armvixlad96eda2013-06-14 11:42:37 +01002487 __ Mov(x19, drifted_addr);
armvixlb0c8ae22014-03-21 14:03:59 +00002488 __ Ldr(x0, MemOperand(x19, largeoffset, PreIndex));
armvixlad96eda2013-06-14 11:42:37 +01002489
armvixlb0c8ae22014-03-21 14:03:59 +00002490 __ Mov(x20, base_addr);
2491 __ Ldr(x1, MemOperand(x20, largeoffset, PostIndex));
2492
2493 __ Mov(x21, drifted_addr);
2494 __ Str(x0, MemOperand(x21, largeoffset + 8, PreIndex));
2495
2496 __ Mov(x22, base_addr + 16);
2497 __ Str(x0, MemOperand(x22, largeoffset, PostIndex));
armvixlad96eda2013-06-14 11:42:37 +01002498 END();
2499
2500 RUN();
2501
2502 ASSERT_EQUAL_64(0x1122334455667788, data[0]);
2503 ASSERT_EQUAL_64(0x1122334455667788, data[1]);
2504 ASSERT_EQUAL_64(0x1122334455667788, data[2]);
2505 ASSERT_EQUAL_64(0x1122334455667788, x0);
2506 ASSERT_EQUAL_64(0x1122334455667788, x1);
2507
armvixlb0c8ae22014-03-21 14:03:59 +00002508 ASSERT_EQUAL_64(base_addr, x19);
2509 ASSERT_EQUAL_64(base_addr + largeoffset, x20);
2510 ASSERT_EQUAL_64(base_addr + 8, x21);
2511 ASSERT_EQUAL_64(base_addr + 16 + largeoffset, x22);
armvixlad96eda2013-06-14 11:42:37 +01002512
2513 TEARDOWN();
2514}
2515
2516
2517TEST(load_signed) {
2518 SETUP();
2519
2520 uint32_t src[2] = {0x80008080, 0x7fff7f7f};
2521 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2522
2523 START();
2524 __ Mov(x24, src_base);
2525 __ Ldrsb(w0, MemOperand(x24));
2526 __ Ldrsb(w1, MemOperand(x24, 4));
2527 __ Ldrsh(w2, MemOperand(x24));
2528 __ Ldrsh(w3, MemOperand(x24, 4));
2529 __ Ldrsb(x4, MemOperand(x24));
2530 __ Ldrsb(x5, MemOperand(x24, 4));
2531 __ Ldrsh(x6, MemOperand(x24));
2532 __ Ldrsh(x7, MemOperand(x24, 4));
2533 __ Ldrsw(x8, MemOperand(x24));
2534 __ Ldrsw(x9, MemOperand(x24, 4));
2535 END();
2536
2537 RUN();
2538
2539 ASSERT_EQUAL_64(0xffffff80, x0);
2540 ASSERT_EQUAL_64(0x0000007f, x1);
2541 ASSERT_EQUAL_64(0xffff8080, x2);
2542 ASSERT_EQUAL_64(0x00007f7f, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00002543 ASSERT_EQUAL_64(0xffffffffffffff80, x4);
2544 ASSERT_EQUAL_64(0x000000000000007f, x5);
2545 ASSERT_EQUAL_64(0xffffffffffff8080, x6);
2546 ASSERT_EQUAL_64(0x0000000000007f7f, x7);
2547 ASSERT_EQUAL_64(0xffffffff80008080, x8);
2548 ASSERT_EQUAL_64(0x000000007fff7f7f, x9);
armvixlad96eda2013-06-14 11:42:37 +01002549
2550 TEARDOWN();
2551}
2552
2553
2554TEST(load_store_regoffset) {
2555 SETUP();
2556
2557 uint32_t src[3] = {1, 2, 3};
2558 uint32_t dst[4] = {0, 0, 0, 0};
2559 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2560 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2561
2562 START();
2563 __ Mov(x16, src_base);
2564 __ Mov(x17, dst_base);
2565 __ Mov(x18, src_base + 3 * sizeof(src[0]));
2566 __ Mov(x19, dst_base + 3 * sizeof(dst[0]));
2567 __ Mov(x20, dst_base + 4 * sizeof(dst[0]));
2568 __ Mov(x24, 0);
2569 __ Mov(x25, 4);
2570 __ Mov(x26, -4);
2571 __ Mov(x27, 0xfffffffc); // 32-bit -4.
2572 __ Mov(x28, 0xfffffffe); // 32-bit -2.
2573 __ Mov(x29, 0xffffffff); // 32-bit -1.
2574
2575 __ Ldr(w0, MemOperand(x16, x24));
2576 __ Ldr(x1, MemOperand(x16, x25));
2577 __ Ldr(w2, MemOperand(x18, x26));
2578 __ Ldr(w3, MemOperand(x18, x27, SXTW));
2579 __ Ldr(w4, MemOperand(x18, x28, SXTW, 2));
2580 __ Str(w0, MemOperand(x17, x24));
2581 __ Str(x1, MemOperand(x17, x25));
2582 __ Str(w2, MemOperand(x20, x29, SXTW, 2));
2583 END();
2584
2585 RUN();
2586
2587 ASSERT_EQUAL_64(1, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002588 ASSERT_EQUAL_64(0x0000000300000002, x1);
armvixlad96eda2013-06-14 11:42:37 +01002589 ASSERT_EQUAL_64(3, x2);
2590 ASSERT_EQUAL_64(3, x3);
2591 ASSERT_EQUAL_64(2, x4);
2592 ASSERT_EQUAL_32(1, dst[0]);
2593 ASSERT_EQUAL_32(2, dst[1]);
2594 ASSERT_EQUAL_32(3, dst[2]);
2595 ASSERT_EQUAL_32(3, dst[3]);
2596
2597 TEARDOWN();
2598}
2599
2600
2601TEST(load_store_float) {
2602 SETUP();
2603
2604 float src[3] = {1.0, 2.0, 3.0};
2605 float dst[3] = {0.0, 0.0, 0.0};
2606 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2607 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2608
2609 START();
2610 __ Mov(x17, src_base);
2611 __ Mov(x18, dst_base);
2612 __ Mov(x19, src_base);
2613 __ Mov(x20, dst_base);
2614 __ Mov(x21, src_base);
2615 __ Mov(x22, dst_base);
2616 __ Ldr(s0, MemOperand(x17, sizeof(src[0])));
2617 __ Str(s0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2618 __ Ldr(s1, MemOperand(x19, sizeof(src[0]), PostIndex));
2619 __ Str(s1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2620 __ Ldr(s2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2621 __ Str(s2, MemOperand(x22, sizeof(dst[0])));
2622 END();
2623
2624 RUN();
2625
2626 ASSERT_EQUAL_FP32(2.0, s0);
2627 ASSERT_EQUAL_FP32(2.0, dst[0]);
2628 ASSERT_EQUAL_FP32(1.0, s1);
2629 ASSERT_EQUAL_FP32(1.0, dst[2]);
2630 ASSERT_EQUAL_FP32(3.0, s2);
2631 ASSERT_EQUAL_FP32(3.0, dst[1]);
2632 ASSERT_EQUAL_64(src_base, x17);
2633 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2634 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2635 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2636 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2637 ASSERT_EQUAL_64(dst_base, x22);
2638
2639 TEARDOWN();
2640}
2641
2642
2643TEST(load_store_double) {
2644 SETUP();
2645
2646 double src[3] = {1.0, 2.0, 3.0};
2647 double dst[3] = {0.0, 0.0, 0.0};
2648 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2649 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2650
2651 START();
2652 __ Mov(x17, src_base);
2653 __ Mov(x18, dst_base);
2654 __ Mov(x19, src_base);
2655 __ Mov(x20, dst_base);
2656 __ Mov(x21, src_base);
2657 __ Mov(x22, dst_base);
2658 __ Ldr(d0, MemOperand(x17, sizeof(src[0])));
2659 __ Str(d0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2660 __ Ldr(d1, MemOperand(x19, sizeof(src[0]), PostIndex));
2661 __ Str(d1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2662 __ Ldr(d2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2663 __ Str(d2, MemOperand(x22, sizeof(dst[0])));
2664 END();
2665
2666 RUN();
2667
2668 ASSERT_EQUAL_FP64(2.0, d0);
2669 ASSERT_EQUAL_FP64(2.0, dst[0]);
2670 ASSERT_EQUAL_FP64(1.0, d1);
2671 ASSERT_EQUAL_FP64(1.0, dst[2]);
2672 ASSERT_EQUAL_FP64(3.0, d2);
2673 ASSERT_EQUAL_FP64(3.0, dst[1]);
2674 ASSERT_EQUAL_64(src_base, x17);
2675 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2676 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2677 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2678 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2679 ASSERT_EQUAL_64(dst_base, x22);
2680
2681 TEARDOWN();
2682}
2683
2684
armvixl5289c592015-03-02 13:52:04 +00002685TEST(load_store_b) {
2686 SETUP();
2687
2688 uint8_t src[3] = {0x12, 0x23, 0x34};
2689 uint8_t dst[3] = {0, 0, 0};
2690 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2691 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2692
2693 START();
2694 __ Mov(x17, src_base);
2695 __ Mov(x18, dst_base);
2696 __ Mov(x19, src_base);
2697 __ Mov(x20, dst_base);
2698 __ Mov(x21, src_base);
2699 __ Mov(x22, dst_base);
2700 __ Ldr(b0, MemOperand(x17, sizeof(src[0])));
2701 __ Str(b0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2702 __ Ldr(b1, MemOperand(x19, sizeof(src[0]), PostIndex));
2703 __ Str(b1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2704 __ Ldr(b2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2705 __ Str(b2, MemOperand(x22, sizeof(dst[0])));
2706 END();
2707
2708 RUN();
2709
2710 ASSERT_EQUAL_128(0, 0x23, q0);
2711 ASSERT_EQUAL_64(0x23, dst[0]);
2712 ASSERT_EQUAL_128(0, 0x12, q1);
2713 ASSERT_EQUAL_64(0x12, dst[2]);
2714 ASSERT_EQUAL_128(0, 0x34, q2);
2715 ASSERT_EQUAL_64(0x34, dst[1]);
2716 ASSERT_EQUAL_64(src_base, x17);
2717 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2718 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2719 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2720 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2721 ASSERT_EQUAL_64(dst_base, x22);
2722
2723 TEARDOWN();
2724}
2725
2726
2727TEST(load_store_h) {
2728 SETUP();
2729
2730 uint16_t src[3] = {0x1234, 0x2345, 0x3456};
2731 uint16_t dst[3] = {0, 0, 0};
2732 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2733 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2734
2735 START();
2736 __ Mov(x17, src_base);
2737 __ Mov(x18, dst_base);
2738 __ Mov(x19, src_base);
2739 __ Mov(x20, dst_base);
2740 __ Mov(x21, src_base);
2741 __ Mov(x22, dst_base);
2742 __ Ldr(h0, MemOperand(x17, sizeof(src[0])));
2743 __ Str(h0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2744 __ Ldr(h1, MemOperand(x19, sizeof(src[0]), PostIndex));
2745 __ Str(h1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2746 __ Ldr(h2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2747 __ Str(h2, MemOperand(x22, sizeof(dst[0])));
2748 END();
2749
2750 RUN();
2751
2752 ASSERT_EQUAL_128(0, 0x2345, q0);
2753 ASSERT_EQUAL_64(0x2345, dst[0]);
2754 ASSERT_EQUAL_128(0, 0x1234, q1);
2755 ASSERT_EQUAL_64(0x1234, dst[2]);
2756 ASSERT_EQUAL_128(0, 0x3456, q2);
2757 ASSERT_EQUAL_64(0x3456, dst[1]);
2758 ASSERT_EQUAL_64(src_base, x17);
2759 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2760 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2761 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2762 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2763 ASSERT_EQUAL_64(dst_base, x22);
2764
2765 TEARDOWN();
2766}
2767
2768
2769TEST(load_store_q) {
2770 SETUP();
2771
2772 uint8_t src[48] = {0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe,
2773 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
2774 0x21, 0x43, 0x65, 0x87, 0xa9, 0xcb, 0xed, 0x0f,
2775 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
2776 0x24, 0x46, 0x68, 0x8a, 0xac, 0xce, 0xe0, 0x02,
2777 0x42, 0x64, 0x86, 0xa8, 0xca, 0xec, 0x0e, 0x20};
2778
2779 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2780 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2781 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2782
2783 START();
2784 __ Mov(x17, src_base);
2785 __ Mov(x18, dst_base);
2786 __ Mov(x19, src_base);
2787 __ Mov(x20, dst_base);
2788 __ Mov(x21, src_base);
2789 __ Mov(x22, dst_base);
2790 __ Ldr(q0, MemOperand(x17, 16));
2791 __ Str(q0, MemOperand(x18, 16, PostIndex));
2792 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
2793 __ Str(q1, MemOperand(x20, 32, PreIndex));
2794 __ Ldr(q2, MemOperand(x21, 32, PreIndex));
2795 __ Str(q2, MemOperand(x22, 16));
2796 END();
2797
2798 RUN();
2799
2800 ASSERT_EQUAL_128(0xf0debc9a78563412, 0x0fedcba987654321, q0);
2801 ASSERT_EQUAL_64(0x0fedcba987654321, dst[0]);
2802 ASSERT_EQUAL_64(0xf0debc9a78563412, dst[1]);
2803 ASSERT_EQUAL_128(0xefcdab8967452301, 0xfedcba9876543210, q1);
2804 ASSERT_EQUAL_64(0xfedcba9876543210, dst[4]);
2805 ASSERT_EQUAL_64(0xefcdab8967452301, dst[5]);
2806 ASSERT_EQUAL_128(0x200eeccaa8866442, 0x02e0ceac8a684624, q2);
2807 ASSERT_EQUAL_64(0x02e0ceac8a684624, dst[2]);
2808 ASSERT_EQUAL_64(0x200eeccaa8866442, dst[3]);
2809 ASSERT_EQUAL_64(src_base, x17);
2810 ASSERT_EQUAL_64(dst_base + 16, x18);
2811 ASSERT_EQUAL_64(src_base + 16, x19);
2812 ASSERT_EQUAL_64(dst_base + 32, x20);
2813 ASSERT_EQUAL_64(src_base + 32, x21);
2814 ASSERT_EQUAL_64(dst_base, x22);
2815
2816 TEARDOWN();
2817}
2818
2819
2820TEST(load_store_v_regoffset) {
2821 SETUP();
2822
2823 uint8_t src[64];
2824 for (unsigned i = 0; i < sizeof(src); i++) {
2825 src[i] = i;
2826 }
2827 uint8_t dst[64];
2828 memset(dst, 0, sizeof(dst));
2829
2830 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2831 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2832
2833 START();
2834 __ Mov(x17, src_base + 16);
2835 __ Mov(x18, 1);
2836 __ Mov(w19, -1);
2837 __ Mov(x20, dst_base - 1);
2838
2839 __ Ldr(b0, MemOperand(x17, x18));
2840 __ Ldr(b1, MemOperand(x17, x19, SXTW));
2841
2842 __ Ldr(h2, MemOperand(x17, x18));
2843 __ Ldr(h3, MemOperand(x17, x18, UXTW, 1));
2844 __ Ldr(h4, MemOperand(x17, x19, SXTW, 1));
2845 __ Ldr(h5, MemOperand(x17, x18, LSL, 1));
2846
2847 __ Ldr(s16, MemOperand(x17, x18));
2848 __ Ldr(s17, MemOperand(x17, x18, UXTW, 2));
2849 __ Ldr(s18, MemOperand(x17, x19, SXTW, 2));
2850 __ Ldr(s19, MemOperand(x17, x18, LSL, 2));
2851
2852 __ Ldr(d20, MemOperand(x17, x18));
2853 __ Ldr(d21, MemOperand(x17, x18, UXTW, 3));
2854 __ Ldr(d22, MemOperand(x17, x19, SXTW, 3));
2855 __ Ldr(d23, MemOperand(x17, x18, LSL, 3));
2856
2857 __ Ldr(q24, MemOperand(x17, x18));
2858 __ Ldr(q25, MemOperand(x17, x18, UXTW, 4));
2859 __ Ldr(q26, MemOperand(x17, x19, SXTW, 4));
2860 __ Ldr(q27, MemOperand(x17, x18, LSL, 4));
2861
2862 // Store [bhsdq]27 to adjacent memory locations, then load again to check.
2863 __ Str(b27, MemOperand(x20, x18));
2864 __ Str(h27, MemOperand(x20, x18, UXTW, 1));
2865 __ Add(x20, x20, 8);
2866 __ Str(s27, MemOperand(x20, x19, SXTW, 2));
2867 __ Sub(x20, x20, 8);
2868 __ Str(d27, MemOperand(x20, x18, LSL, 3));
2869 __ Add(x20, x20, 32);
2870 __ Str(q27, MemOperand(x20, x19, SXTW, 4));
2871
2872 __ Sub(x20, x20, 32);
2873 __ Ldr(q6, MemOperand(x20, x18));
2874 __ Ldr(q7, MemOperand(x20, x18, LSL, 4));
2875
2876 END();
2877
2878 RUN();
2879
2880 ASSERT_EQUAL_128(0, 0x11, q0);
2881 ASSERT_EQUAL_128(0, 0x0f, q1);
2882 ASSERT_EQUAL_128(0, 0x1211, q2);
2883 ASSERT_EQUAL_128(0, 0x1312, q3);
2884 ASSERT_EQUAL_128(0, 0x0f0e, q4);
2885 ASSERT_EQUAL_128(0, 0x1312, q5);
2886 ASSERT_EQUAL_128(0, 0x14131211, q16);
2887 ASSERT_EQUAL_128(0, 0x17161514, q17);
2888 ASSERT_EQUAL_128(0, 0x0f0e0d0c, q18);
2889 ASSERT_EQUAL_128(0, 0x17161514, q19);
2890 ASSERT_EQUAL_128(0, 0x1817161514131211, q20);
2891 ASSERT_EQUAL_128(0, 0x1f1e1d1c1b1a1918, q21);
2892 ASSERT_EQUAL_128(0, 0x0f0e0d0c0b0a0908, q22);
2893 ASSERT_EQUAL_128(0, 0x1f1e1d1c1b1a1918, q23);
2894 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x1817161514131211, q24);
2895 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q25);
2896 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q26);
2897 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q27);
2898 ASSERT_EQUAL_128(0x2027262524232221, 0x2023222120212020, q6);
2899 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q7);
2900
2901 TEARDOWN();
2902}
2903
2904
2905TEST(neon_ld1_d) {
2906 SETUP();
2907
2908 uint8_t src[32 + 5];
2909 for (unsigned i = 0; i < sizeof(src); i++) {
2910 src[i] = i;
2911 }
2912 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2913
2914 START();
2915 __ Mov(x17, src_base);
2916 __ Ldr(q2, MemOperand(x17)); // Initialise top 64-bits of Q register.
2917 __ Ld1(v2.V8B(), MemOperand(x17));
2918 __ Add(x17, x17, 1);
2919 __ Ld1(v3.V8B(), v4.V8B(), MemOperand(x17));
2920 __ Add(x17, x17, 1);
2921 __ Ld1(v5.V4H(), v6.V4H(), v7.V4H(), MemOperand(x17));
2922 __ Add(x17, x17, 1);
2923 __ Ld1(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(), MemOperand(x17));
2924 __ Add(x17, x17, 1);
2925 __ Ld1(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x17));
2926 __ Add(x17, x17, 1);
2927 __ Ld1(v20.V1D(), v21.V1D(), v22.V1D(), v23.V1D(), MemOperand(x17));
2928 END();
2929
2930 RUN();
2931
2932 ASSERT_EQUAL_128(0, 0x0706050403020100, q2);
2933 ASSERT_EQUAL_128(0, 0x0807060504030201, q3);
2934 ASSERT_EQUAL_128(0, 0x100f0e0d0c0b0a09, q4);
2935 ASSERT_EQUAL_128(0, 0x0908070605040302, q5);
2936 ASSERT_EQUAL_128(0, 0x11100f0e0d0c0b0a, q6);
2937 ASSERT_EQUAL_128(0, 0x1918171615141312, q7);
2938 ASSERT_EQUAL_128(0, 0x0a09080706050403, q16);
2939 ASSERT_EQUAL_128(0, 0x1211100f0e0d0c0b, q17);
2940 ASSERT_EQUAL_128(0, 0x1a19181716151413, q18);
2941 ASSERT_EQUAL_128(0, 0x2221201f1e1d1c1b, q19);
2942 ASSERT_EQUAL_128(0, 0x0b0a090807060504, q30);
2943 ASSERT_EQUAL_128(0, 0x131211100f0e0d0c, q31);
2944 ASSERT_EQUAL_128(0, 0x1b1a191817161514, q0);
2945 ASSERT_EQUAL_128(0, 0x232221201f1e1d1c, q1);
2946 ASSERT_EQUAL_128(0, 0x0c0b0a0908070605, q20);
2947 ASSERT_EQUAL_128(0, 0x14131211100f0e0d, q21);
2948 ASSERT_EQUAL_128(0, 0x1c1b1a1918171615, q22);
2949 ASSERT_EQUAL_128(0, 0x24232221201f1e1d, q23);
2950
2951 TEARDOWN();
2952}
2953
2954
2955TEST(neon_ld1_d_postindex) {
2956 SETUP();
2957
2958 uint8_t src[32 + 5];
2959 for (unsigned i = 0; i < sizeof(src); i++) {
2960 src[i] = i;
2961 }
2962 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2963
2964 START();
2965 __ Mov(x17, src_base);
2966 __ Mov(x18, src_base + 1);
2967 __ Mov(x19, src_base + 2);
2968 __ Mov(x20, src_base + 3);
2969 __ Mov(x21, src_base + 4);
2970 __ Mov(x22, src_base + 5);
2971 __ Mov(x23, 1);
2972 __ Ldr(q2, MemOperand(x17)); // Initialise top 64-bits of Q register.
2973 __ Ld1(v2.V8B(), MemOperand(x17, x23, PostIndex));
2974 __ Ld1(v3.V8B(), v4.V8B(), MemOperand(x18, 16, PostIndex));
2975 __ Ld1(v5.V4H(), v6.V4H(), v7.V4H(), MemOperand(x19, 24, PostIndex));
2976 __ Ld1(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(),
2977 MemOperand(x20, 32, PostIndex));
2978 __ Ld1(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(),
2979 MemOperand(x21, 32, PostIndex));
2980 __ Ld1(v20.V1D(), v21.V1D(), v22.V1D(), v23.V1D(),
2981 MemOperand(x22, 32, PostIndex));
2982 END();
2983
2984 RUN();
2985
2986 ASSERT_EQUAL_128(0, 0x0706050403020100, q2);
2987 ASSERT_EQUAL_128(0, 0x0807060504030201, q3);
2988 ASSERT_EQUAL_128(0, 0x100f0e0d0c0b0a09, q4);
2989 ASSERT_EQUAL_128(0, 0x0908070605040302, q5);
2990 ASSERT_EQUAL_128(0, 0x11100f0e0d0c0b0a, q6);
2991 ASSERT_EQUAL_128(0, 0x1918171615141312, q7);
2992 ASSERT_EQUAL_128(0, 0x0a09080706050403, q16);
2993 ASSERT_EQUAL_128(0, 0x1211100f0e0d0c0b, q17);
2994 ASSERT_EQUAL_128(0, 0x1a19181716151413, q18);
2995 ASSERT_EQUAL_128(0, 0x2221201f1e1d1c1b, q19);
2996 ASSERT_EQUAL_128(0, 0x0b0a090807060504, q30);
2997 ASSERT_EQUAL_128(0, 0x131211100f0e0d0c, q31);
2998 ASSERT_EQUAL_128(0, 0x1b1a191817161514, q0);
2999 ASSERT_EQUAL_128(0, 0x232221201f1e1d1c, q1);
3000 ASSERT_EQUAL_128(0, 0x0c0b0a0908070605, q20);
3001 ASSERT_EQUAL_128(0, 0x14131211100f0e0d, q21);
3002 ASSERT_EQUAL_128(0, 0x1c1b1a1918171615, q22);
3003 ASSERT_EQUAL_128(0, 0x24232221201f1e1d, q23);
3004 ASSERT_EQUAL_64(src_base + 1, x17);
3005 ASSERT_EQUAL_64(src_base + 1 + 16, x18);
3006 ASSERT_EQUAL_64(src_base + 2 + 24, x19);
3007 ASSERT_EQUAL_64(src_base + 3 + 32, x20);
3008 ASSERT_EQUAL_64(src_base + 4 + 32, x21);
3009 ASSERT_EQUAL_64(src_base + 5 + 32, x22);
3010
3011 TEARDOWN();
3012}
3013
3014
3015TEST(neon_ld1_q) {
3016 SETUP();
3017
3018 uint8_t src[64 + 4];
3019 for (unsigned i = 0; i < sizeof(src); i++) {
3020 src[i] = i;
3021 }
3022 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3023
3024 START();
3025 __ Mov(x17, src_base);
3026 __ Ld1(v2.V16B(), MemOperand(x17));
3027 __ Add(x17, x17, 1);
3028 __ Ld1(v3.V16B(), v4.V16B(), MemOperand(x17));
3029 __ Add(x17, x17, 1);
3030 __ Ld1(v5.V8H(), v6.V8H(), v7.V8H(), MemOperand(x17));
3031 __ Add(x17, x17, 1);
3032 __ Ld1(v16.V4S(), v17.V4S(), v18.V4S(), v19.V4S(), MemOperand(x17));
3033 __ Add(x17, x17, 1);
3034 __ Ld1(v30.V2D(), v31.V2D(), v0.V2D(), v1.V2D(), MemOperand(x17));
3035 END();
3036
3037 RUN();
3038
3039 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q2);
3040 ASSERT_EQUAL_128(0x100f0e0d0c0b0a09, 0x0807060504030201, q3);
3041 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x1817161514131211, q4);
3042 ASSERT_EQUAL_128(0x11100f0e0d0c0b0a, 0x0908070605040302, q5);
3043 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x1918171615141312, q6);
3044 ASSERT_EQUAL_128(0x31302f2e2d2c2b2a, 0x2928272625242322, q7);
3045 ASSERT_EQUAL_128(0x1211100f0e0d0c0b, 0x0a09080706050403, q16);
3046 ASSERT_EQUAL_128(0x2221201f1e1d1c1b, 0x1a19181716151413, q17);
3047 ASSERT_EQUAL_128(0x3231302f2e2d2c2b, 0x2a29282726252423, q18);
3048 ASSERT_EQUAL_128(0x4241403f3e3d3c3b, 0x3a39383736353433, q19);
3049 ASSERT_EQUAL_128(0x131211100f0e0d0c, 0x0b0a090807060504, q30);
3050 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x1b1a191817161514, q31);
3051 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x2b2a292827262524, q0);
3052 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x3b3a393837363534, q1);
3053
3054 TEARDOWN();
3055}
3056
3057
3058TEST(neon_ld1_q_postindex) {
3059 SETUP();
3060
3061 uint8_t src[64 + 4];
3062 for (unsigned i = 0; i < sizeof(src); i++) {
3063 src[i] = i;
3064 }
3065 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3066
3067 START();
3068 __ Mov(x17, src_base);
3069 __ Mov(x18, src_base + 1);
3070 __ Mov(x19, src_base + 2);
3071 __ Mov(x20, src_base + 3);
3072 __ Mov(x21, src_base + 4);
3073 __ Mov(x22, 1);
3074 __ Ld1(v2.V16B(), MemOperand(x17, x22, PostIndex));
3075 __ Ld1(v3.V16B(), v4.V16B(), MemOperand(x18, 32, PostIndex));
3076 __ Ld1(v5.V8H(), v6.V8H(), v7.V8H(), MemOperand(x19, 48, PostIndex));
3077 __ Ld1(v16.V4S(), v17.V4S(), v18.V4S(), v19.V4S(),
3078 MemOperand(x20, 64, PostIndex));
3079 __ Ld1(v30.V2D(), v31.V2D(), v0.V2D(), v1.V2D(),
3080 MemOperand(x21, 64, PostIndex));
3081 END();
3082
3083 RUN();
3084
3085 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q2);
3086 ASSERT_EQUAL_128(0x100f0e0d0c0b0a09, 0x0807060504030201, q3);
3087 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x1817161514131211, q4);
3088 ASSERT_EQUAL_128(0x11100f0e0d0c0b0a, 0x0908070605040302, q5);
3089 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x1918171615141312, q6);
3090 ASSERT_EQUAL_128(0x31302f2e2d2c2b2a, 0x2928272625242322, q7);
3091 ASSERT_EQUAL_128(0x1211100f0e0d0c0b, 0x0a09080706050403, q16);
3092 ASSERT_EQUAL_128(0x2221201f1e1d1c1b, 0x1a19181716151413, q17);
3093 ASSERT_EQUAL_128(0x3231302f2e2d2c2b, 0x2a29282726252423, q18);
3094 ASSERT_EQUAL_128(0x4241403f3e3d3c3b, 0x3a39383736353433, q19);
3095 ASSERT_EQUAL_128(0x131211100f0e0d0c, 0x0b0a090807060504, q30);
3096 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x1b1a191817161514, q31);
3097 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x2b2a292827262524, q0);
3098 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x3b3a393837363534, q1);
3099 ASSERT_EQUAL_64(src_base + 1, x17);
3100 ASSERT_EQUAL_64(src_base + 1 + 32, x18);
3101 ASSERT_EQUAL_64(src_base + 2 + 48, x19);
3102 ASSERT_EQUAL_64(src_base + 3 + 64, x20);
3103 ASSERT_EQUAL_64(src_base + 4 + 64, x21);
3104
3105 TEARDOWN();
3106}
3107
3108
3109TEST(neon_ld1_lane) {
3110 SETUP();
3111
3112 uint8_t src[64];
3113 for (unsigned i = 0; i < sizeof(src); i++) {
3114 src[i] = i;
3115 }
3116 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3117
3118 START();
3119
3120 // Test loading whole register by element.
3121 __ Mov(x17, src_base);
3122 for (int i = 15; i >= 0; i--) {
3123 __ Ld1(v0.B(), i, MemOperand(x17));
3124 __ Add(x17, x17, 1);
3125 }
3126
3127 __ Mov(x17, src_base);
3128 for (int i = 7; i >= 0; i--) {
3129 __ Ld1(v1.H(), i, MemOperand(x17));
3130 __ Add(x17, x17, 1);
3131 }
3132
3133 __ Mov(x17, src_base);
3134 for (int i = 3; i >= 0; i--) {
3135 __ Ld1(v2.S(), i, MemOperand(x17));
3136 __ Add(x17, x17, 1);
3137 }
3138
3139 __ Mov(x17, src_base);
3140 for (int i = 1; i >= 0; i--) {
3141 __ Ld1(v3.D(), i, MemOperand(x17));
3142 __ Add(x17, x17, 1);
3143 }
3144
3145 // Test loading a single element into an initialised register.
3146 __ Mov(x17, src_base);
3147 __ Ldr(q4, MemOperand(x17));
3148 __ Ld1(v4.B(), 4, MemOperand(x17));
3149 __ Ldr(q5, MemOperand(x17));
3150 __ Ld1(v5.H(), 3, MemOperand(x17));
3151 __ Ldr(q6, MemOperand(x17));
3152 __ Ld1(v6.S(), 2, MemOperand(x17));
3153 __ Ldr(q7, MemOperand(x17));
3154 __ Ld1(v7.D(), 1, MemOperand(x17));
3155
3156 END();
3157
3158 RUN();
3159
3160 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
3161 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q1);
3162 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q2);
3163 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q3);
3164 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q4);
3165 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q5);
3166 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q6);
3167 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q7);
3168
3169 TEARDOWN();
3170}
3171
3172TEST(neon_ld2_d) {
3173 SETUP();
3174
3175 uint8_t src[64 + 4];
3176 for (unsigned i = 0; i < sizeof(src); i++) {
3177 src[i] = i;
3178 }
3179 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3180
3181 START();
3182 __ Mov(x17, src_base);
3183 __ Ld2(v2.V8B(), v3.V8B(), MemOperand(x17));
3184 __ Add(x17, x17, 1);
3185 __ Ld2(v4.V8B(), v5.V8B(), MemOperand(x17));
3186 __ Add(x17, x17, 1);
3187 __ Ld2(v6.V4H(), v7.V4H(), MemOperand(x17));
3188 __ Add(x17, x17, 1);
3189 __ Ld2(v31.V2S(), v0.V2S(), MemOperand(x17));
3190 END();
3191
3192 RUN();
3193
3194 ASSERT_EQUAL_128(0, 0x0e0c0a0806040200, q2);
3195 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q3);
3196 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q4);
3197 ASSERT_EQUAL_128(0, 0x100e0c0a08060402, q5);
3198 ASSERT_EQUAL_128(0, 0x0f0e0b0a07060302, q6);
3199 ASSERT_EQUAL_128(0, 0x11100d0c09080504, q7);
3200 ASSERT_EQUAL_128(0, 0x0e0d0c0b06050403, q31);
3201 ASSERT_EQUAL_128(0, 0x1211100f0a090807, q0);
3202
3203 TEARDOWN();
3204}
3205
3206TEST(neon_ld2_d_postindex) {
3207 SETUP();
3208
3209 uint8_t src[32 + 4];
3210 for (unsigned i = 0; i < sizeof(src); i++) {
3211 src[i] = i;
3212 }
3213 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3214
3215 START();
3216 __ Mov(x17, src_base);
3217 __ Mov(x18, src_base + 1);
3218 __ Mov(x19, src_base + 2);
3219 __ Mov(x20, src_base + 3);
3220 __ Mov(x21, src_base + 4);
3221 __ Mov(x22, 1);
3222 __ Ld2(v2.V8B(), v3.V8B(), MemOperand(x17, x22, PostIndex));
3223 __ Ld2(v4.V8B(), v5.V8B(), MemOperand(x18, 16, PostIndex));
3224 __ Ld2(v5.V4H(), v6.V4H(), MemOperand(x19, 16, PostIndex));
3225 __ Ld2(v16.V2S(), v17.V2S(), MemOperand(x20, 16, PostIndex));
3226 __ Ld2(v31.V2S(), v0.V2S(), MemOperand(x21, 16, PostIndex));
3227 END();
3228
3229 RUN();
3230
3231 ASSERT_EQUAL_128(0, 0x0e0c0a0806040200, q2);
3232 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q3);
3233 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q4);
3234 ASSERT_EQUAL_128(0, 0x0f0e0b0a07060302, q5);
3235 ASSERT_EQUAL_128(0, 0x11100d0c09080504, q6);
3236 ASSERT_EQUAL_128(0, 0x0e0d0c0b06050403, q16);
3237 ASSERT_EQUAL_128(0, 0x1211100f0a090807, q17);
3238 ASSERT_EQUAL_128(0, 0x0f0e0d0c07060504, q31);
3239 ASSERT_EQUAL_128(0, 0x131211100b0a0908, q0);
3240
3241 ASSERT_EQUAL_64(src_base + 1, x17);
3242 ASSERT_EQUAL_64(src_base + 1 + 16, x18);
3243 ASSERT_EQUAL_64(src_base + 2 + 16, x19);
3244 ASSERT_EQUAL_64(src_base + 3 + 16, x20);
3245 ASSERT_EQUAL_64(src_base + 4 + 16, x21);
3246
3247 TEARDOWN();
3248}
3249
3250
3251TEST(neon_ld2_q) {
3252 SETUP();
3253
3254 uint8_t src[64 + 4];
3255 for (unsigned i = 0; i < sizeof(src); i++) {
3256 src[i] = i;
3257 }
3258 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3259
3260 START();
3261 __ Mov(x17, src_base);
3262 __ Ld2(v2.V16B(), v3.V16B(), MemOperand(x17));
3263 __ Add(x17, x17, 1);
3264 __ Ld2(v4.V16B(), v5.V16B(), MemOperand(x17));
3265 __ Add(x17, x17, 1);
3266 __ Ld2(v6.V8H(), v7.V8H(), MemOperand(x17));
3267 __ Add(x17, x17, 1);
3268 __ Ld2(v16.V4S(), v17.V4S(), MemOperand(x17));
3269 __ Add(x17, x17, 1);
3270 __ Ld2(v31.V2D(), v0.V2D(), MemOperand(x17));
3271 END();
3272
3273 RUN();
3274
3275 ASSERT_EQUAL_128(0x1e1c1a1816141210, 0x0e0c0a0806040200, q2);
3276 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q3);
3277 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q4);
3278 ASSERT_EQUAL_128(0x201e1c1a18161412, 0x100e0c0a08060402, q5);
3279 ASSERT_EQUAL_128(0x1f1e1b1a17161312, 0x0f0e0b0a07060302, q6);
3280 ASSERT_EQUAL_128(0x21201d1c19181514, 0x11100d0c09080504, q7);
3281 ASSERT_EQUAL_128(0x1e1d1c1b16151413, 0x0e0d0c0b06050403, q16);
3282 ASSERT_EQUAL_128(0x2221201f1a191817, 0x1211100f0a090807, q17);
3283 ASSERT_EQUAL_128(0x1b1a191817161514, 0x0b0a090807060504, q31);
3284 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x131211100f0e0d0c, q0);
3285
3286 TEARDOWN();
3287}
3288
3289
3290TEST(neon_ld2_q_postindex) {
3291 SETUP();
3292
3293 uint8_t src[64 + 4];
3294 for (unsigned i = 0; i < sizeof(src); i++) {
3295 src[i] = i;
3296 }
3297 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3298
3299 START();
3300 __ Mov(x17, src_base);
3301 __ Mov(x18, src_base + 1);
3302 __ Mov(x19, src_base + 2);
3303 __ Mov(x20, src_base + 3);
3304 __ Mov(x21, src_base + 4);
3305 __ Mov(x22, 1);
3306 __ Ld2(v2.V16B(), v3.V16B(), MemOperand(x17, x22, PostIndex));
3307 __ Ld2(v4.V16B(), v5.V16B(), MemOperand(x18, 32, PostIndex));
3308 __ Ld2(v6.V8H(), v7.V8H(), MemOperand(x19, 32, PostIndex));
3309 __ Ld2(v16.V4S(), v17.V4S(), MemOperand(x20, 32, PostIndex));
3310 __ Ld2(v31.V2D(), v0.V2D(), MemOperand(x21, 32, PostIndex));
3311 END();
3312
3313 RUN();
3314
3315 ASSERT_EQUAL_128(0x1e1c1a1816141210, 0x0e0c0a0806040200, q2);
3316 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q3);
3317 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q4);
3318 ASSERT_EQUAL_128(0x201e1c1a18161412, 0x100e0c0a08060402, q5);
3319 ASSERT_EQUAL_128(0x1f1e1b1a17161312, 0x0f0e0b0a07060302, q6);
3320 ASSERT_EQUAL_128(0x21201d1c19181514, 0x11100d0c09080504, q7);
3321 ASSERT_EQUAL_128(0x1e1d1c1b16151413, 0x0e0d0c0b06050403, q16);
3322 ASSERT_EQUAL_128(0x2221201f1a191817, 0x1211100f0a090807, q17);
3323 ASSERT_EQUAL_128(0x1b1a191817161514, 0x0b0a090807060504, q31);
3324 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x131211100f0e0d0c, q0);
3325
3326
3327
3328 ASSERT_EQUAL_64(src_base + 1, x17);
3329 ASSERT_EQUAL_64(src_base + 1 + 32, x18);
3330 ASSERT_EQUAL_64(src_base + 2 + 32, x19);
3331 ASSERT_EQUAL_64(src_base + 3 + 32, x20);
3332 ASSERT_EQUAL_64(src_base + 4 + 32, x21);
3333
3334 TEARDOWN();
3335}
3336
3337
3338TEST(neon_ld2_lane) {
3339 SETUP();
3340
3341 uint8_t src[64];
3342 for (unsigned i = 0; i < sizeof(src); i++) {
3343 src[i] = i;
3344 }
3345 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3346
3347 START();
3348
3349 // Test loading whole register by element.
3350 __ Mov(x17, src_base);
3351 for (int i = 15; i >= 0; i--) {
3352 __ Ld2(v0.B(), v1.B(), i, MemOperand(x17));
3353 __ Add(x17, x17, 1);
3354 }
3355
3356 __ Mov(x17, src_base);
3357 for (int i = 7; i >= 0; i--) {
3358 __ Ld2(v2.H(), v3.H(), i, MemOperand(x17));
3359 __ Add(x17, x17, 1);
3360 }
3361
3362 __ Mov(x17, src_base);
3363 for (int i = 3; i >= 0; i--) {
3364 __ Ld2(v4.S(), v5.S(), i, MemOperand(x17));
3365 __ Add(x17, x17, 1);
3366 }
3367
3368 __ Mov(x17, src_base);
3369 for (int i = 1; i >= 0; i--) {
3370 __ Ld2(v6.D(), v7.D(), i, MemOperand(x17));
3371 __ Add(x17, x17, 1);
3372 }
3373
3374 // Test loading a single element into an initialised register.
3375 __ Mov(x17, src_base);
3376 __ Mov(x4, x17);
3377 __ Ldr(q8, MemOperand(x4, 16, PostIndex));
3378 __ Ldr(q9, MemOperand(x4));
3379 __ Ld2(v8.B(), v9.B(), 4, MemOperand(x17));
3380 __ Mov(x5, x17);
3381 __ Ldr(q10, MemOperand(x5, 16, PostIndex));
3382 __ Ldr(q11, MemOperand(x5));
3383 __ Ld2(v10.H(), v11.H(), 3, MemOperand(x17));
3384 __ Mov(x6, x17);
3385 __ Ldr(q12, MemOperand(x6, 16, PostIndex));
3386 __ Ldr(q13, MemOperand(x6));
3387 __ Ld2(v12.S(), v13.S(), 2, MemOperand(x17));
3388 __ Mov(x7, x17);
3389 __ Ldr(q14, MemOperand(x7, 16, PostIndex));
3390 __ Ldr(q15, MemOperand(x7));
3391 __ Ld2(v14.D(), v15.D(), 1, MemOperand(x17));
3392
3393 END();
3394
3395 RUN();
3396
3397 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
3398 ASSERT_EQUAL_128(0x0102030405060708, 0x090a0b0c0d0e0f10, q1);
3399 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q2);
3400 ASSERT_EQUAL_128(0x0302040305040605, 0x0706080709080a09, q3);
3401 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q4);
3402 ASSERT_EQUAL_128(0x0706050408070605, 0x090807060a090807, q5);
3403 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q6);
3404 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x100f0e0d0c0b0a09, q7);
3405 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q8);
3406 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q9);
3407 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q10);
3408 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q11);
3409 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q12);
3410 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q13);
3411 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q14);
3412 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q15);
3413
3414 TEARDOWN();
3415}
3416
3417
3418TEST(neon_ld2_lane_postindex) {
3419 SETUP();
3420
3421 uint8_t src[64];
3422 for (unsigned i = 0; i < sizeof(src); i++) {
3423 src[i] = i;
3424 }
3425 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3426
3427 START();
3428 __ Mov(x17, src_base);
3429 __ Mov(x18, src_base);
3430 __ Mov(x19, src_base);
3431 __ Mov(x20, src_base);
3432 __ Mov(x21, src_base);
3433 __ Mov(x22, src_base);
3434 __ Mov(x23, src_base);
3435 __ Mov(x24, src_base);
3436
3437 // Test loading whole register by element.
3438 for (int i = 15; i >= 0; i--) {
3439 __ Ld2(v0.B(), v1.B(), i, MemOperand(x17, 2, PostIndex));
3440 }
3441
3442 for (int i = 7; i >= 0; i--) {
3443 __ Ld2(v2.H(), v3.H(), i, MemOperand(x18, 4, PostIndex));
3444 }
3445
3446 for (int i = 3; i >= 0; i--) {
3447 __ Ld2(v4.S(), v5.S(), i, MemOperand(x19, 8, PostIndex));
3448 }
3449
3450 for (int i = 1; i >= 0; i--) {
3451 __ Ld2(v6.D(), v7.D(), i, MemOperand(x20, 16, PostIndex));
3452 }
3453
3454 // Test loading a single element into an initialised register.
3455 __ Mov(x25, 1);
3456 __ Mov(x4, x21);
3457 __ Ldr(q8, MemOperand(x4, 16, PostIndex));
3458 __ Ldr(q9, MemOperand(x4));
3459 __ Ld2(v8.B(), v9.B(), 4, MemOperand(x21, x25, PostIndex));
3460 __ Add(x25, x25, 1);
3461
3462 __ Mov(x5, x22);
3463 __ Ldr(q10, MemOperand(x5, 16, PostIndex));
3464 __ Ldr(q11, MemOperand(x5));
3465 __ Ld2(v10.H(), v11.H(), 3, MemOperand(x22, x25, PostIndex));
3466 __ Add(x25, x25, 1);
3467
3468 __ Mov(x6, x23);
3469 __ Ldr(q12, MemOperand(x6, 16, PostIndex));
3470 __ Ldr(q13, MemOperand(x6));
3471 __ Ld2(v12.S(), v13.S(), 2, MemOperand(x23, x25, PostIndex));
3472 __ Add(x25, x25, 1);
3473
3474 __ Mov(x7, x24);
3475 __ Ldr(q14, MemOperand(x7, 16, PostIndex));
3476 __ Ldr(q15, MemOperand(x7));
3477 __ Ld2(v14.D(), v15.D(), 1, MemOperand(x24, x25, PostIndex));
3478
3479 END();
3480
3481 RUN();
3482
3483 ASSERT_EQUAL_128(0x00020406080a0c0e, 0x10121416181a1c1e, q0);
3484 ASSERT_EQUAL_128(0x01030507090b0d0f, 0x11131517191b1d1f, q1);
3485 ASSERT_EQUAL_128(0x0100050409080d0c, 0x1110151419181d1c, q2);
3486 ASSERT_EQUAL_128(0x030207060b0a0f0e, 0x131217161b1a1f1e, q3);
3487 ASSERT_EQUAL_128(0x030201000b0a0908, 0x131211101b1a1918, q4);
3488 ASSERT_EQUAL_128(0x070605040f0e0d0c, 0x171615141f1e1d1c, q5);
3489 ASSERT_EQUAL_128(0x0706050403020100, 0x1716151413121110, q6);
3490 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1f1e1d1c1b1a1918, q7);
3491 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q8);
3492 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q9);
3493 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q10);
3494 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q11);
3495 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q12);
3496 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q13);
3497 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q14);
3498 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q15);
3499
3500
3501
3502
3503 ASSERT_EQUAL_64(src_base + 32, x17);
3504 ASSERT_EQUAL_64(src_base + 32, x18);
3505 ASSERT_EQUAL_64(src_base + 32, x19);
3506 ASSERT_EQUAL_64(src_base + 32, x20);
3507 ASSERT_EQUAL_64(src_base + 1, x21);
3508 ASSERT_EQUAL_64(src_base + 2, x22);
3509 ASSERT_EQUAL_64(src_base + 3, x23);
3510 ASSERT_EQUAL_64(src_base + 4, x24);
3511
3512 TEARDOWN();
3513}
3514
3515
3516TEST(neon_ld2_alllanes) {
3517 SETUP();
3518
3519 uint8_t src[64];
3520 for (unsigned i = 0; i < sizeof(src); i++) {
3521 src[i] = i;
3522 }
3523 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3524
3525 START();
3526 __ Mov(x17, src_base + 1);
3527 __ Mov(x18, 1);
3528 __ Ld2r(v0.V8B(), v1.V8B(), MemOperand(x17));
3529 __ Add(x17, x17, 2);
3530 __ Ld2r(v2.V16B(), v3.V16B(), MemOperand(x17));
3531 __ Add(x17, x17, 1);
3532 __ Ld2r(v4.V4H(), v5.V4H(), MemOperand(x17));
3533 __ Add(x17, x17, 1);
3534 __ Ld2r(v6.V8H(), v7.V8H(), MemOperand(x17));
3535 __ Add(x17, x17, 4);
3536 __ Ld2r(v8.V2S(), v9.V2S(), MemOperand(x17));
3537 __ Add(x17, x17, 1);
3538 __ Ld2r(v10.V4S(), v11.V4S(), MemOperand(x17));
3539 __ Add(x17, x17, 8);
3540 __ Ld2r(v12.V2D(), v13.V2D(), MemOperand(x17));
3541 END();
3542
3543 RUN();
3544
3545 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
3546 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
3547 ASSERT_EQUAL_128(0x0303030303030303, 0x0303030303030303, q2);
3548 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
3549 ASSERT_EQUAL_128(0x0000000000000000, 0x0504050405040504, q4);
3550 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q5);
3551 ASSERT_EQUAL_128(0x0605060506050605, 0x0605060506050605, q6);
3552 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q7);
3553 ASSERT_EQUAL_128(0x0000000000000000, 0x0c0b0a090c0b0a09, q8);
3554 ASSERT_EQUAL_128(0x0000000000000000, 0x100f0e0d100f0e0d, q9);
3555 ASSERT_EQUAL_128(0x0d0c0b0a0d0c0b0a, 0x0d0c0b0a0d0c0b0a, q10);
3556 ASSERT_EQUAL_128(0x11100f0e11100f0e, 0x11100f0e11100f0e, q11);
3557 ASSERT_EQUAL_128(0x1918171615141312, 0x1918171615141312, q12);
3558 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x21201f1e1d1c1b1a, q13);
3559
3560 TEARDOWN();
3561}
3562
3563
3564TEST(neon_ld2_alllanes_postindex) {
3565 SETUP();
3566
3567 uint8_t src[64];
3568 for (unsigned i = 0; i < sizeof(src); i++) {
3569 src[i] = i;
3570 }
3571 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3572
3573 START();
3574 __ Mov(x17, src_base + 1);
3575 __ Mov(x18, 1);
3576 __ Ld2r(v0.V8B(), v1.V8B(), MemOperand(x17, 2, PostIndex));
3577 __ Ld2r(v2.V16B(), v3.V16B(), MemOperand(x17, x18, PostIndex));
3578 __ Ld2r(v4.V4H(), v5.V4H(), MemOperand(x17, x18, PostIndex));
3579 __ Ld2r(v6.V8H(), v7.V8H(), MemOperand(x17, 4, PostIndex));
3580 __ Ld2r(v8.V2S(), v9.V2S(), MemOperand(x17, x18, PostIndex));
3581 __ Ld2r(v10.V4S(), v11.V4S(), MemOperand(x17, 8, PostIndex));
3582 __ Ld2r(v12.V2D(), v13.V2D(), MemOperand(x17, 16, PostIndex));
3583 END();
3584
3585 RUN();
3586
3587 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
3588 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
3589 ASSERT_EQUAL_128(0x0303030303030303, 0x0303030303030303, q2);
3590 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
3591 ASSERT_EQUAL_128(0x0000000000000000, 0x0504050405040504, q4);
3592 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q5);
3593 ASSERT_EQUAL_128(0x0605060506050605, 0x0605060506050605, q6);
3594 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q7);
3595 ASSERT_EQUAL_128(0x0000000000000000, 0x0c0b0a090c0b0a09, q8);
3596 ASSERT_EQUAL_128(0x0000000000000000, 0x100f0e0d100f0e0d, q9);
3597 ASSERT_EQUAL_128(0x0d0c0b0a0d0c0b0a, 0x0d0c0b0a0d0c0b0a, q10);
3598 ASSERT_EQUAL_128(0x11100f0e11100f0e, 0x11100f0e11100f0e, q11);
3599 ASSERT_EQUAL_128(0x1918171615141312, 0x1918171615141312, q12);
3600 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x21201f1e1d1c1b1a, q13);
3601 ASSERT_EQUAL_64(src_base + 34, x17);
3602
3603 TEARDOWN();
3604}
3605
3606
3607TEST(neon_ld3_d) {
3608 SETUP();
3609
3610 uint8_t src[64 + 4];
3611 for (unsigned i = 0; i < sizeof(src); i++) {
3612 src[i] = i;
3613 }
3614 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3615
3616 START();
3617 __ Mov(x17, src_base);
3618 __ Ld3(v2.V8B(), v3.V8B(), v4.V8B(), MemOperand(x17));
3619 __ Add(x17, x17, 1);
3620 __ Ld3(v5.V8B(), v6.V8B(), v7.V8B(), MemOperand(x17));
3621 __ Add(x17, x17, 1);
3622 __ Ld3(v8.V4H(), v9.V4H(), v10.V4H(), MemOperand(x17));
3623 __ Add(x17, x17, 1);
3624 __ Ld3(v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x17));
3625 END();
3626
3627 RUN();
3628
3629 ASSERT_EQUAL_128(0, 0x15120f0c09060300, q2);
3630 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q3);
3631 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q4);
3632 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q5);
3633 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q6);
3634 ASSERT_EQUAL_128(0, 0x1815120f0c090603, q7);
3635 ASSERT_EQUAL_128(0, 0x15140f0e09080302, q8);
3636 ASSERT_EQUAL_128(0, 0x171611100b0a0504, q9);
3637 ASSERT_EQUAL_128(0, 0x191813120d0c0706, q10);
3638 ASSERT_EQUAL_128(0, 0x1211100f06050403, q31);
3639 ASSERT_EQUAL_128(0, 0x161514130a090807, q0);
3640 ASSERT_EQUAL_128(0, 0x1a1918170e0d0c0b, q1);
3641
3642 TEARDOWN();
3643}
3644
3645
3646TEST(neon_ld3_d_postindex) {
3647 SETUP();
3648
3649 uint8_t src[32 + 4];
3650 for (unsigned i = 0; i < sizeof(src); i++) {
3651 src[i] = i;
3652 }
3653 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3654
3655 START();
3656 __ Mov(x17, src_base);
3657 __ Mov(x18, src_base + 1);
3658 __ Mov(x19, src_base + 2);
3659 __ Mov(x20, src_base + 3);
3660 __ Mov(x21, src_base + 4);
3661 __ Mov(x22, 1);
3662 __ Ld3(v2.V8B(), v3.V8B(), v4.V8B(), MemOperand(x17, x22, PostIndex));
3663 __ Ld3(v5.V8B(), v6.V8B(), v7.V8B(), MemOperand(x18, 24, PostIndex));
3664 __ Ld3(v8.V4H(), v9.V4H(), v10.V4H(), MemOperand(x19, 24, PostIndex));
3665 __ Ld3(v11.V2S(), v12.V2S(), v13.V2S(), MemOperand(x20, 24, PostIndex));
3666 __ Ld3(v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x21, 24, PostIndex));
3667 END();
3668
3669 RUN();
3670
3671 ASSERT_EQUAL_128(0, 0x15120f0c09060300, q2);
3672 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q3);
3673 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q4);
3674 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q5);
3675 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q6);
3676 ASSERT_EQUAL_128(0, 0x1815120f0c090603, q7);
3677 ASSERT_EQUAL_128(0, 0x15140f0e09080302, q8);
3678 ASSERT_EQUAL_128(0, 0x171611100b0a0504, q9);
3679 ASSERT_EQUAL_128(0, 0x191813120d0c0706, q10);
3680 ASSERT_EQUAL_128(0, 0x1211100f06050403, q11);
3681 ASSERT_EQUAL_128(0, 0x161514130a090807, q12);
3682 ASSERT_EQUAL_128(0, 0x1a1918170e0d0c0b, q13);
3683 ASSERT_EQUAL_128(0, 0x1312111007060504, q31);
3684 ASSERT_EQUAL_128(0, 0x171615140b0a0908, q0);
3685 ASSERT_EQUAL_128(0, 0x1b1a19180f0e0d0c, q1);
3686
3687 ASSERT_EQUAL_64(src_base + 1, x17);
3688 ASSERT_EQUAL_64(src_base + 1 + 24, x18);
3689 ASSERT_EQUAL_64(src_base + 2 + 24, x19);
3690 ASSERT_EQUAL_64(src_base + 3 + 24, x20);
3691 ASSERT_EQUAL_64(src_base + 4 + 24, x21);
3692
3693 TEARDOWN();
3694}
3695
3696
3697TEST(neon_ld3_q) {
3698 SETUP();
3699
3700 uint8_t src[64 + 4];
3701 for (unsigned i = 0; i < sizeof(src); i++) {
3702 src[i] = i;
3703 }
3704 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3705
3706 START();
3707 __ Mov(x17, src_base);
3708 __ Ld3(v2.V16B(), v3.V16B(), v4.V16B(), MemOperand(x17));
3709 __ Add(x17, x17, 1);
3710 __ Ld3(v5.V16B(), v6.V16B(), v7.V16B(), MemOperand(x17));
3711 __ Add(x17, x17, 1);
3712 __ Ld3(v8.V8H(), v9.V8H(), v10.V8H(), MemOperand(x17));
3713 __ Add(x17, x17, 1);
3714 __ Ld3(v11.V4S(), v12.V4S(), v13.V4S(), MemOperand(x17));
3715 __ Add(x17, x17, 1);
3716 __ Ld3(v31.V2D(), v0.V2D(), v1.V2D(), MemOperand(x17));
3717 END();
3718
3719 RUN();
3720
3721 ASSERT_EQUAL_128(0x2d2a2724211e1b18, 0x15120f0c09060300, q2);
3722 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q3);
3723 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q4);
3724 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q5);
3725 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q6);
3726 ASSERT_EQUAL_128(0x302d2a2724211e1b, 0x1815120f0c090603, q7);
3727 ASSERT_EQUAL_128(0x2d2c272621201b1a, 0x15140f0e09080302, q8);
3728 ASSERT_EQUAL_128(0x2f2e292823221d1c, 0x171611100b0a0504, q9);
3729 ASSERT_EQUAL_128(0x31302b2a25241f1e, 0x191813120d0c0706, q10);
3730 ASSERT_EQUAL_128(0x2a2928271e1d1c1b, 0x1211100f06050403, q11);
3731 ASSERT_EQUAL_128(0x2e2d2c2b2221201f, 0x161514130a090807, q12);
3732 ASSERT_EQUAL_128(0x3231302f26252423, 0x1a1918170e0d0c0b, q13);
3733 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x0b0a090807060504, q31);
3734 ASSERT_EQUAL_128(0x2b2a292827262524, 0x131211100f0e0d0c, q0);
3735 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x1b1a191817161514, q1);
3736
3737 TEARDOWN();
3738}
3739
3740
3741TEST(neon_ld3_q_postindex) {
3742 SETUP();
3743
3744 uint8_t src[64 + 4];
3745 for (unsigned i = 0; i < sizeof(src); i++) {
3746 src[i] = i;
3747 }
3748 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3749
3750 START();
3751 __ Mov(x17, src_base);
3752 __ Mov(x18, src_base + 1);
3753 __ Mov(x19, src_base + 2);
3754 __ Mov(x20, src_base + 3);
3755 __ Mov(x21, src_base + 4);
3756 __ Mov(x22, 1);
3757
3758 __ Ld3(v2.V16B(), v3.V16B(), v4.V16B(), MemOperand(x17, x22, PostIndex));
3759 __ Ld3(v5.V16B(), v6.V16B(), v7.V16B(), MemOperand(x18, 48, PostIndex));
3760 __ Ld3(v8.V8H(), v9.V8H(), v10.V8H(), MemOperand(x19, 48, PostIndex));
3761 __ Ld3(v11.V4S(), v12.V4S(), v13.V4S(), MemOperand(x20, 48, PostIndex));
3762 __ Ld3(v31.V2D(), v0.V2D(), v1.V2D(), MemOperand(x21, 48, PostIndex));
3763 END();
3764
3765 RUN();
3766
3767 ASSERT_EQUAL_128(0x2d2a2724211e1b18, 0x15120f0c09060300, q2);
3768 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q3);
3769 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q4);
3770 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q5);
3771 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q6);
3772 ASSERT_EQUAL_128(0x302d2a2724211e1b, 0x1815120f0c090603, q7);
3773 ASSERT_EQUAL_128(0x2d2c272621201b1a, 0x15140f0e09080302, q8);
3774 ASSERT_EQUAL_128(0x2f2e292823221d1c, 0x171611100b0a0504, q9);
3775 ASSERT_EQUAL_128(0x31302b2a25241f1e, 0x191813120d0c0706, q10);
3776 ASSERT_EQUAL_128(0x2a2928271e1d1c1b, 0x1211100f06050403, q11);
3777 ASSERT_EQUAL_128(0x2e2d2c2b2221201f, 0x161514130a090807, q12);
3778 ASSERT_EQUAL_128(0x3231302f26252423, 0x1a1918170e0d0c0b, q13);
3779 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x0b0a090807060504, q31);
3780 ASSERT_EQUAL_128(0x2b2a292827262524, 0x131211100f0e0d0c, q0);
3781 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x1b1a191817161514, q1);
3782
3783 ASSERT_EQUAL_64(src_base + 1, x17);
3784 ASSERT_EQUAL_64(src_base + 1 + 48, x18);
3785 ASSERT_EQUAL_64(src_base + 2 + 48, x19);
3786 ASSERT_EQUAL_64(src_base + 3 + 48, x20);
3787 ASSERT_EQUAL_64(src_base + 4 + 48, x21);
3788
3789 TEARDOWN();
3790}
3791
3792
3793TEST(neon_ld3_lane) {
3794 SETUP();
3795
3796 uint8_t src[64];
3797 for (unsigned i = 0; i < sizeof(src); i++) {
3798 src[i] = i;
3799 }
3800 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3801
3802 START();
3803
3804 // Test loading whole register by element.
3805 __ Mov(x17, src_base);
3806 for (int i = 15; i >= 0; i--) {
3807 __ Ld3(v0.B(), v1.B(), v2.B(), i, MemOperand(x17));
3808 __ Add(x17, x17, 1);
3809 }
3810
3811 __ Mov(x17, src_base);
3812 for (int i = 7; i >= 0; i--) {
3813 __ Ld3(v3.H(), v4.H(), v5.H(), i, MemOperand(x17));
3814 __ Add(x17, x17, 1);
3815 }
3816
3817 __ Mov(x17, src_base);
3818 for (int i = 3; i >= 0; i--) {
3819 __ Ld3(v6.S(), v7.S(), v8.S(), i, MemOperand(x17));
3820 __ Add(x17, x17, 1);
3821 }
3822
3823 __ Mov(x17, src_base);
3824 for (int i = 1; i >= 0; i--) {
3825 __ Ld3(v9.D(), v10.D(), v11.D(), i, MemOperand(x17));
3826 __ Add(x17, x17, 1);
3827 }
3828
3829 // Test loading a single element into an initialised register.
3830 __ Mov(x17, src_base);
3831 __ Mov(x4, x17);
3832 __ Ldr(q12, MemOperand(x4, 16, PostIndex));
3833 __ Ldr(q13, MemOperand(x4, 16, PostIndex));
3834 __ Ldr(q14, MemOperand(x4));
3835 __ Ld3(v12.B(), v13.B(), v14.B(), 4, MemOperand(x17));
3836 __ Mov(x5, x17);
3837 __ Ldr(q15, MemOperand(x5, 16, PostIndex));
3838 __ Ldr(q16, MemOperand(x5, 16, PostIndex));
3839 __ Ldr(q17, MemOperand(x5));
3840 __ Ld3(v15.H(), v16.H(), v17.H(), 3, MemOperand(x17));
3841 __ Mov(x6, x17);
3842 __ Ldr(q18, MemOperand(x6, 16, PostIndex));
3843 __ Ldr(q19, MemOperand(x6, 16, PostIndex));
3844 __ Ldr(q20, MemOperand(x6));
3845 __ Ld3(v18.S(), v19.S(), v20.S(), 2, MemOperand(x17));
3846 __ Mov(x7, x17);
3847 __ Ldr(q21, MemOperand(x7, 16, PostIndex));
3848 __ Ldr(q22, MemOperand(x7, 16, PostIndex));
3849 __ Ldr(q23, MemOperand(x7));
3850 __ Ld3(v21.D(), v22.D(), v23.D(), 1, MemOperand(x17));
3851
3852 END();
3853
3854 RUN();
3855
3856 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
3857 ASSERT_EQUAL_128(0x0102030405060708, 0x090a0b0c0d0e0f10, q1);
3858 ASSERT_EQUAL_128(0x0203040506070809, 0x0a0b0c0d0e0f1011, q2);
3859 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q3);
3860 ASSERT_EQUAL_128(0x0302040305040605, 0x0706080709080a09, q4);
3861 ASSERT_EQUAL_128(0x0504060507060807, 0x09080a090b0a0c0b, q5);
3862 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q6);
3863 ASSERT_EQUAL_128(0x0706050408070605, 0x090807060a090807, q7);
3864 ASSERT_EQUAL_128(0x0b0a09080c0b0a09, 0x0d0c0b0a0e0d0c0b, q8);
3865 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q9);
3866 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x100f0e0d0c0b0a09, q10);
3867 ASSERT_EQUAL_128(0x1716151413121110, 0x1817161514131211, q11);
3868 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q12);
3869 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q13);
3870 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q14);
3871 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q15);
3872 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q16);
3873 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q17);
3874
3875 TEARDOWN();
3876}
3877
3878
3879TEST(neon_ld3_lane_postindex) {
3880 SETUP();
3881
3882 uint8_t src[64];
3883 for (unsigned i = 0; i < sizeof(src); i++) {
3884 src[i] = i;
3885 }
3886 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3887
3888 START();
3889
3890 // Test loading whole register by element.
3891 __ Mov(x17, src_base);
3892 __ Mov(x18, src_base);
3893 __ Mov(x19, src_base);
3894 __ Mov(x20, src_base);
3895 __ Mov(x21, src_base);
3896 __ Mov(x22, src_base);
3897 __ Mov(x23, src_base);
3898 __ Mov(x24, src_base);
3899 for (int i = 15; i >= 0; i--) {
3900 __ Ld3(v0.B(), v1.B(), v2.B(), i, MemOperand(x17, 3, PostIndex));
3901 }
3902
3903 for (int i = 7; i >= 0; i--) {
3904 __ Ld3(v3.H(), v4.H(), v5.H(), i, MemOperand(x18, 6, PostIndex));
3905 }
3906
3907 for (int i = 3; i >= 0; i--) {
3908 __ Ld3(v6.S(), v7.S(), v8.S(), i, MemOperand(x19, 12, PostIndex));
3909 }
3910
3911 for (int i = 1; i >= 0; i--) {
3912 __ Ld3(v9.D(), v10.D(), v11.D(), i, MemOperand(x20, 24, PostIndex));
3913 }
3914
3915
3916 // Test loading a single element into an initialised register.
3917 __ Mov(x25, 1);
3918 __ Mov(x4, x21);
3919 __ Ldr(q12, MemOperand(x4, 16, PostIndex));
3920 __ Ldr(q13, MemOperand(x4, 16, PostIndex));
3921 __ Ldr(q14, MemOperand(x4));
3922 __ Ld3(v12.B(), v13.B(), v14.B(), 4, MemOperand(x21, x25, PostIndex));
3923 __ Add(x25, x25, 1);
3924
3925 __ Mov(x5, x22);
3926 __ Ldr(q15, MemOperand(x5, 16, PostIndex));
3927 __ Ldr(q16, MemOperand(x5, 16, PostIndex));
3928 __ Ldr(q17, MemOperand(x5));
3929 __ Ld3(v15.H(), v16.H(), v17.H(), 3, MemOperand(x22, x25, PostIndex));
3930 __ Add(x25, x25, 1);
3931
3932 __ Mov(x6, x23);
3933 __ Ldr(q18, MemOperand(x6, 16, PostIndex));
3934 __ Ldr(q19, MemOperand(x6, 16, PostIndex));
3935 __ Ldr(q20, MemOperand(x6));
3936 __ Ld3(v18.S(), v19.S(), v20.S(), 2, MemOperand(x23, x25, PostIndex));
3937 __ Add(x25, x25, 1);
3938
3939 __ Mov(x7, x24);
3940 __ Ldr(q21, MemOperand(x7, 16, PostIndex));
3941 __ Ldr(q22, MemOperand(x7, 16, PostIndex));
3942 __ Ldr(q23, MemOperand(x7));
3943 __ Ld3(v21.D(), v22.D(), v23.D(), 1, MemOperand(x24, x25, PostIndex));
3944
3945 END();
3946
3947 RUN();
3948
3949 ASSERT_EQUAL_128(0x000306090c0f1215, 0x181b1e2124272a2d, q0);
3950 ASSERT_EQUAL_128(0x0104070a0d101316, 0x191c1f2225282b2e, q1);
3951 ASSERT_EQUAL_128(0x0205080b0e111417, 0x1a1d202326292c2f, q2);
3952 ASSERT_EQUAL_128(0x010007060d0c1312, 0x19181f1e25242b2a, q3);
3953 ASSERT_EQUAL_128(0x030209080f0e1514, 0x1b1a212027262d2c, q4);
3954 ASSERT_EQUAL_128(0x05040b0a11101716, 0x1d1c232229282f2e, q5);
3955 ASSERT_EQUAL_128(0x030201000f0e0d0c, 0x1b1a191827262524, q6);
3956 ASSERT_EQUAL_128(0x0706050413121110, 0x1f1e1d1c2b2a2928, q7);
3957 ASSERT_EQUAL_128(0x0b0a090817161514, 0x232221202f2e2d2c, q8);
3958 ASSERT_EQUAL_128(0x0706050403020100, 0x1f1e1d1c1b1a1918, q9);
3959 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x2726252423222120, q10);
3960 ASSERT_EQUAL_128(0x1716151413121110, 0x2f2e2d2c2b2a2928, q11);
3961 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q12);
3962 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q13);
3963 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q14);
3964 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q15);
3965 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q16);
3966 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q17);
3967 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q18);
3968 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q19);
3969 ASSERT_EQUAL_128(0x2f2e2d2c0b0a0908, 0x2726252423222120, q20);
3970 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q21);
3971 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q22);
3972 ASSERT_EQUAL_128(0x1716151413121110, 0x2726252423222120, q23);
3973
3974 ASSERT_EQUAL_64(src_base + 48, x17);
3975 ASSERT_EQUAL_64(src_base + 48, x18);
3976 ASSERT_EQUAL_64(src_base + 48, x19);
3977 ASSERT_EQUAL_64(src_base + 48, x20);
3978 ASSERT_EQUAL_64(src_base + 1, x21);
3979 ASSERT_EQUAL_64(src_base + 2, x22);
3980 ASSERT_EQUAL_64(src_base + 3, x23);
3981 ASSERT_EQUAL_64(src_base + 4, x24);
3982
3983 TEARDOWN();
3984}
3985
3986
3987TEST(neon_ld3_alllanes) {
3988 SETUP();
3989
3990 uint8_t src[64];
3991 for (unsigned i = 0; i < sizeof(src); i++) {
3992 src[i] = i;
3993 }
3994 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3995
3996 START();
3997 __ Mov(x17, src_base + 1);
3998 __ Mov(x18, 1);
3999 __ Ld3r(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x17));
4000 __ Add(x17, x17, 3);
4001 __ Ld3r(v3.V16B(), v4.V16B(), v5.V16B(), MemOperand(x17));
4002 __ Add(x17, x17, 1);
4003 __ Ld3r(v6.V4H(), v7.V4H(), v8.V4H(), MemOperand(x17));
4004 __ Add(x17, x17, 1);
4005 __ Ld3r(v9.V8H(), v10.V8H(), v11.V8H(), MemOperand(x17));
4006 __ Add(x17, x17, 6);
4007 __ Ld3r(v12.V2S(), v13.V2S(), v14.V2S(), MemOperand(x17));
4008 __ Add(x17, x17, 1);
4009 __ Ld3r(v15.V4S(), v16.V4S(), v17.V4S(), MemOperand(x17));
4010 __ Add(x17, x17, 12);
4011 __ Ld3r(v18.V2D(), v19.V2D(), v20.V2D(), MemOperand(x17));
4012 END();
4013
4014 RUN();
4015
4016 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4017 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4018 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4019 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
4020 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4021 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4022 ASSERT_EQUAL_128(0x0000000000000000, 0x0605060506050605, q6);
4023 ASSERT_EQUAL_128(0x0000000000000000, 0x0807080708070807, q7);
4024 ASSERT_EQUAL_128(0x0000000000000000, 0x0a090a090a090a09, q8);
4025 ASSERT_EQUAL_128(0x0706070607060706, 0x0706070607060706, q9);
4026 ASSERT_EQUAL_128(0x0908090809080908, 0x0908090809080908, q10);
4027 ASSERT_EQUAL_128(0x0b0a0b0a0b0a0b0a, 0x0b0a0b0a0b0a0b0a, q11);
4028 ASSERT_EQUAL_128(0x0000000000000000, 0x0f0e0d0c0f0e0d0c, q12);
4029 ASSERT_EQUAL_128(0x0000000000000000, 0x1312111013121110, q13);
4030 ASSERT_EQUAL_128(0x0000000000000000, 0x1716151417161514, q14);
4031 ASSERT_EQUAL_128(0x100f0e0d100f0e0d, 0x100f0e0d100f0e0d, q15);
4032 ASSERT_EQUAL_128(0x1413121114131211, 0x1413121114131211, q16);
4033 ASSERT_EQUAL_128(0x1817161518171615, 0x1817161518171615, q17);
4034 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x201f1e1d1c1b1a19, q18);
4035 ASSERT_EQUAL_128(0x2827262524232221, 0x2827262524232221, q19);
4036 ASSERT_EQUAL_128(0x302f2e2d2c2b2a29, 0x302f2e2d2c2b2a29, q20);
4037
4038 TEARDOWN();
4039}
4040
4041
4042TEST(neon_ld3_alllanes_postindex) {
4043 SETUP();
4044
4045 uint8_t src[64];
4046 for (unsigned i = 0; i < sizeof(src); i++) {
4047 src[i] = i;
4048 }
4049 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4050 __ Mov(x17, src_base + 1);
4051 __ Mov(x18, 1);
4052
4053 START();
4054 __ Mov(x17, src_base + 1);
4055 __ Mov(x18, 1);
4056 __ Ld3r(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x17, 3, PostIndex));
4057 __ Ld3r(v3.V16B(), v4.V16B(), v5.V16B(), MemOperand(x17, x18, PostIndex));
4058 __ Ld3r(v6.V4H(), v7.V4H(), v8.V4H(), MemOperand(x17, x18, PostIndex));
4059 __ Ld3r(v9.V8H(), v10.V8H(), v11.V8H(), MemOperand(x17, 6, PostIndex));
4060 __ Ld3r(v12.V2S(), v13.V2S(), v14.V2S(), MemOperand(x17, x18, PostIndex));
4061 __ Ld3r(v15.V4S(), v16.V4S(), v17.V4S(), MemOperand(x17, 12, PostIndex));
4062 __ Ld3r(v18.V2D(), v19.V2D(), v20.V2D(), MemOperand(x17, 24, PostIndex));
4063 END();
4064
4065 RUN();
4066
4067 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4068 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4069 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4070 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
4071 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4072 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4073 ASSERT_EQUAL_128(0x0000000000000000, 0x0605060506050605, q6);
4074 ASSERT_EQUAL_128(0x0000000000000000, 0x0807080708070807, q7);
4075 ASSERT_EQUAL_128(0x0000000000000000, 0x0a090a090a090a09, q8);
4076 ASSERT_EQUAL_128(0x0706070607060706, 0x0706070607060706, q9);
4077 ASSERT_EQUAL_128(0x0908090809080908, 0x0908090809080908, q10);
4078 ASSERT_EQUAL_128(0x0b0a0b0a0b0a0b0a, 0x0b0a0b0a0b0a0b0a, q11);
4079 ASSERT_EQUAL_128(0x0000000000000000, 0x0f0e0d0c0f0e0d0c, q12);
4080 ASSERT_EQUAL_128(0x0000000000000000, 0x1312111013121110, q13);
4081 ASSERT_EQUAL_128(0x0000000000000000, 0x1716151417161514, q14);
4082 ASSERT_EQUAL_128(0x100f0e0d100f0e0d, 0x100f0e0d100f0e0d, q15);
4083 ASSERT_EQUAL_128(0x1413121114131211, 0x1413121114131211, q16);
4084 ASSERT_EQUAL_128(0x1817161518171615, 0x1817161518171615, q17);
4085 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x201f1e1d1c1b1a19, q18);
4086 ASSERT_EQUAL_128(0x2827262524232221, 0x2827262524232221, q19);
4087 ASSERT_EQUAL_128(0x302f2e2d2c2b2a29, 0x302f2e2d2c2b2a29, q20);
4088
4089 TEARDOWN();
4090}
4091
4092
4093TEST(neon_ld4_d) {
4094 SETUP();
4095
4096 uint8_t src[64 + 4];
4097 for (unsigned i = 0; i < sizeof(src); i++) {
4098 src[i] = i;
4099 }
4100 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4101
4102 START();
4103 __ Mov(x17, src_base);
4104 __ Ld4(v2.V8B(), v3.V8B(), v4.V8B(), v5.V8B(), MemOperand(x17));
4105 __ Add(x17, x17, 1);
4106 __ Ld4(v6.V8B(), v7.V8B(), v8.V8B(), v9.V8B(), MemOperand(x17));
4107 __ Add(x17, x17, 1);
4108 __ Ld4(v10.V4H(), v11.V4H(), v12.V4H(), v13.V4H(), MemOperand(x17));
4109 __ Add(x17, x17, 1);
4110 __ Ld4(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x17));
4111 END();
4112
4113 RUN();
4114
4115 ASSERT_EQUAL_128(0, 0x1c1814100c080400, q2);
4116 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q3);
4117 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q4);
4118 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q5);
4119 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q6);
4120 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q7);
4121 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q8);
4122 ASSERT_EQUAL_128(0, 0x201c1814100c0804, q9);
4123 ASSERT_EQUAL_128(0, 0x1b1a13120b0a0302, q10);
4124 ASSERT_EQUAL_128(0, 0x1d1c15140d0c0504, q11);
4125 ASSERT_EQUAL_128(0, 0x1f1e17160f0e0706, q12);
4126 ASSERT_EQUAL_128(0, 0x2120191811100908, q13);
4127 ASSERT_EQUAL_128(0, 0x1615141306050403, q30);
4128 ASSERT_EQUAL_128(0, 0x1a1918170a090807, q31);
4129 ASSERT_EQUAL_128(0, 0x1e1d1c1b0e0d0c0b, q0);
4130 ASSERT_EQUAL_128(0, 0x2221201f1211100f, q1);
4131
4132 TEARDOWN();
4133}
4134
4135
4136TEST(neon_ld4_d_postindex) {
4137 SETUP();
4138
4139 uint8_t src[32 + 4];
4140 for (unsigned i = 0; i < sizeof(src); i++) {
4141 src[i] = i;
4142 }
4143 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4144
4145 START();
4146 __ Mov(x17, src_base);
4147 __ Mov(x18, src_base + 1);
4148 __ Mov(x19, src_base + 2);
4149 __ Mov(x20, src_base + 3);
4150 __ Mov(x21, src_base + 4);
4151 __ Mov(x22, 1);
4152 __ Ld4(v2.V8B(), v3.V8B(), v4.V8B(), v5.V8B(),
4153 MemOperand(x17, x22, PostIndex));
4154 __ Ld4(v6.V8B(), v7.V8B(), v8.V8B(), v9.V8B(),
4155 MemOperand(x18, 32, PostIndex));
4156 __ Ld4(v10.V4H(), v11.V4H(), v12.V4H(), v13.V4H(),
4157 MemOperand(x19, 32, PostIndex));
4158 __ Ld4(v14.V2S(), v15.V2S(), v16.V2S(), v17.V2S(),
4159 MemOperand(x20, 32, PostIndex));
4160 __ Ld4(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(),
4161 MemOperand(x21, 32, PostIndex));
4162 END();
4163
4164 RUN();
4165
4166 ASSERT_EQUAL_128(0, 0x1c1814100c080400, q2);
4167 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q3);
4168 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q4);
4169 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q5);
4170 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q6);
4171 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q7);
4172 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q8);
4173 ASSERT_EQUAL_128(0, 0x201c1814100c0804, q9);
4174 ASSERT_EQUAL_128(0, 0x1b1a13120b0a0302, q10);
4175 ASSERT_EQUAL_128(0, 0x1d1c15140d0c0504, q11);
4176 ASSERT_EQUAL_128(0, 0x1f1e17160f0e0706, q12);
4177 ASSERT_EQUAL_128(0, 0x2120191811100908, q13);
4178 ASSERT_EQUAL_128(0, 0x1615141306050403, q14);
4179 ASSERT_EQUAL_128(0, 0x1a1918170a090807, q15);
4180 ASSERT_EQUAL_128(0, 0x1e1d1c1b0e0d0c0b, q16);
4181 ASSERT_EQUAL_128(0, 0x2221201f1211100f, q17);
4182 ASSERT_EQUAL_128(0, 0x1716151407060504, q30);
4183 ASSERT_EQUAL_128(0, 0x1b1a19180b0a0908, q31);
4184 ASSERT_EQUAL_128(0, 0x1f1e1d1c0f0e0d0c, q0);
4185 ASSERT_EQUAL_128(0, 0x2322212013121110, q1);
4186
4187
4188 ASSERT_EQUAL_64(src_base + 1, x17);
4189 ASSERT_EQUAL_64(src_base + 1 + 32, x18);
4190 ASSERT_EQUAL_64(src_base + 2 + 32, x19);
4191 ASSERT_EQUAL_64(src_base + 3 + 32, x20);
4192 ASSERT_EQUAL_64(src_base + 4 + 32, x21);
4193 TEARDOWN();
4194}
4195
4196
4197TEST(neon_ld4_q) {
4198 SETUP();
4199
4200 uint8_t src[64 + 4];
4201 for (unsigned i = 0; i < sizeof(src); i++) {
4202 src[i] = i;
4203 }
4204 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4205
4206 START();
4207 __ Mov(x17, src_base);
4208 __ Ld4(v2.V16B(), v3.V16B(), v4.V16B(), v5.V16B(), MemOperand(x17));
4209 __ Add(x17, x17, 1);
4210 __ Ld4(v6.V16B(), v7.V16B(), v8.V16B(), v9.V16B(), MemOperand(x17));
4211 __ Add(x17, x17, 1);
4212 __ Ld4(v10.V8H(), v11.V8H(), v12.V8H(), v13.V8H(), MemOperand(x17));
4213 __ Add(x17, x17, 1);
4214 __ Ld4(v14.V4S(), v15.V4S(), v16.V4S(), v17.V4S(), MemOperand(x17));
4215 __ Add(x17, x17, 1);
4216 __ Ld4(v18.V2D(), v19.V2D(), v20.V2D(), v21.V2D(), MemOperand(x17));
4217 END();
4218
4219 RUN();
4220
4221 ASSERT_EQUAL_128(0x3c3834302c282420, 0x1c1814100c080400, q2);
4222 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q3);
4223 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q4);
4224 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q5);
4225 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q6);
4226 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q7);
4227 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q8);
4228 ASSERT_EQUAL_128(0x403c3834302c2824, 0x201c1814100c0804, q9);
4229 ASSERT_EQUAL_128(0x3b3a33322b2a2322, 0x1b1a13120b0a0302, q10);
4230 ASSERT_EQUAL_128(0x3d3c35342d2c2524, 0x1d1c15140d0c0504, q11);
4231 ASSERT_EQUAL_128(0x3f3e37362f2e2726, 0x1f1e17160f0e0706, q12);
4232 ASSERT_EQUAL_128(0x4140393831302928, 0x2120191811100908, q13);
4233 ASSERT_EQUAL_128(0x3635343326252423, 0x1615141306050403, q14);
4234 ASSERT_EQUAL_128(0x3a3938372a292827, 0x1a1918170a090807, q15);
4235 ASSERT_EQUAL_128(0x3e3d3c3b2e2d2c2b, 0x1e1d1c1b0e0d0c0b, q16);
4236 ASSERT_EQUAL_128(0x4241403f3231302f, 0x2221201f1211100f, q17);
4237 ASSERT_EQUAL_128(0x2b2a292827262524, 0x0b0a090807060504, q18);
4238 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x131211100f0e0d0c, q19);
4239 ASSERT_EQUAL_128(0x3b3a393837363534, 0x1b1a191817161514, q20);
4240 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x232221201f1e1d1c, q21);
4241 TEARDOWN();
4242}
4243
4244
4245TEST(neon_ld4_q_postindex) {
4246 SETUP();
4247
4248 uint8_t src[64 + 4];
4249 for (unsigned i = 0; i < sizeof(src); i++) {
4250 src[i] = i;
4251 }
4252 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4253
4254 START();
4255 __ Mov(x17, src_base);
4256 __ Mov(x18, src_base + 1);
4257 __ Mov(x19, src_base + 2);
4258 __ Mov(x20, src_base + 3);
4259 __ Mov(x21, src_base + 4);
4260 __ Mov(x22, 1);
4261
4262 __ Ld4(v2.V16B(), v3.V16B(), v4.V16B(), v5.V16B(),
4263 MemOperand(x17, x22, PostIndex));
4264 __ Ld4(v6.V16B(), v7.V16B(), v8.V16B(), v9.V16B(),
4265 MemOperand(x18, 64, PostIndex));
4266 __ Ld4(v10.V8H(), v11.V8H(), v12.V8H(), v13.V8H(),
4267 MemOperand(x19, 64, PostIndex));
4268 __ Ld4(v14.V4S(), v15.V4S(), v16.V4S(), v17.V4S(),
4269 MemOperand(x20, 64, PostIndex));
4270 __ Ld4(v30.V2D(), v31.V2D(), v0.V2D(), v1.V2D(),
4271 MemOperand(x21, 64, PostIndex));
4272 END();
4273
4274 RUN();
4275
4276 ASSERT_EQUAL_128(0x3c3834302c282420, 0x1c1814100c080400, q2);
4277 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q3);
4278 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q4);
4279 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q5);
4280 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q6);
4281 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q7);
4282 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q8);
4283 ASSERT_EQUAL_128(0x403c3834302c2824, 0x201c1814100c0804, q9);
4284 ASSERT_EQUAL_128(0x3b3a33322b2a2322, 0x1b1a13120b0a0302, q10);
4285 ASSERT_EQUAL_128(0x3d3c35342d2c2524, 0x1d1c15140d0c0504, q11);
4286 ASSERT_EQUAL_128(0x3f3e37362f2e2726, 0x1f1e17160f0e0706, q12);
4287 ASSERT_EQUAL_128(0x4140393831302928, 0x2120191811100908, q13);
4288 ASSERT_EQUAL_128(0x3635343326252423, 0x1615141306050403, q14);
4289 ASSERT_EQUAL_128(0x3a3938372a292827, 0x1a1918170a090807, q15);
4290 ASSERT_EQUAL_128(0x3e3d3c3b2e2d2c2b, 0x1e1d1c1b0e0d0c0b, q16);
4291 ASSERT_EQUAL_128(0x4241403f3231302f, 0x2221201f1211100f, q17);
4292 ASSERT_EQUAL_128(0x2b2a292827262524, 0x0b0a090807060504, q30);
4293 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x131211100f0e0d0c, q31);
4294 ASSERT_EQUAL_128(0x3b3a393837363534, 0x1b1a191817161514, q0);
4295 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x232221201f1e1d1c, q1);
4296
4297
4298
4299 ASSERT_EQUAL_64(src_base + 1, x17);
4300 ASSERT_EQUAL_64(src_base + 1 + 64, x18);
4301 ASSERT_EQUAL_64(src_base + 2 + 64, x19);
4302 ASSERT_EQUAL_64(src_base + 3 + 64, x20);
4303 ASSERT_EQUAL_64(src_base + 4 + 64, x21);
4304
4305 TEARDOWN();
4306}
4307
4308
4309TEST(neon_ld4_lane) {
4310 SETUP();
4311
4312 uint8_t src[64];
4313 for (unsigned i = 0; i < sizeof(src); i++) {
4314 src[i] = i;
4315 }
4316 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4317
4318 START();
4319
4320 // Test loading whole register by element.
4321 __ Mov(x17, src_base);
4322 for (int i = 15; i >= 0; i--) {
4323 __ Ld4(v0.B(), v1.B(), v2.B(), v3.B(), i, MemOperand(x17));
4324 __ Add(x17, x17, 1);
4325 }
4326
4327 __ Mov(x17, src_base);
4328 for (int i = 7; i >= 0; i--) {
4329 __ Ld4(v4.H(), v5.H(), v6.H(), v7.H(), i, MemOperand(x17));
4330 __ Add(x17, x17, 1);
4331 }
4332
4333 __ Mov(x17, src_base);
4334 for (int i = 3; i >= 0; i--) {
4335 __ Ld4(v8.S(), v9.S(), v10.S(), v11.S(), i, MemOperand(x17));
4336 __ Add(x17, x17, 1);
4337 }
4338
4339 __ Mov(x17, src_base);
4340 for (int i = 1; i >= 0; i--) {
4341 __ Ld4(v12.D(), v13.D(), v14.D(), v15.D(), i, MemOperand(x17));
4342 __ Add(x17, x17, 1);
4343 }
4344
4345 // Test loading a single element into an initialised register.
4346 __ Mov(x17, src_base);
4347 __ Mov(x4, x17);
4348 __ Ldr(q16, MemOperand(x4, 16, PostIndex));
4349 __ Ldr(q17, MemOperand(x4, 16, PostIndex));
4350 __ Ldr(q18, MemOperand(x4, 16, PostIndex));
4351 __ Ldr(q19, MemOperand(x4));
4352 __ Ld4(v16.B(), v17.B(), v18.B(), v19.B(), 4, MemOperand(x17));
4353
4354 __ Mov(x5, x17);
4355 __ Ldr(q20, MemOperand(x5, 16, PostIndex));
4356 __ Ldr(q21, MemOperand(x5, 16, PostIndex));
4357 __ Ldr(q22, MemOperand(x5, 16, PostIndex));
4358 __ Ldr(q23, MemOperand(x5));
4359 __ Ld4(v20.H(), v21.H(), v22.H(), v23.H(), 3, MemOperand(x17));
4360
4361 __ Mov(x6, x17);
4362 __ Ldr(q24, MemOperand(x6, 16, PostIndex));
4363 __ Ldr(q25, MemOperand(x6, 16, PostIndex));
4364 __ Ldr(q26, MemOperand(x6, 16, PostIndex));
4365 __ Ldr(q27, MemOperand(x6));
4366 __ Ld4(v24.S(), v25.S(), v26.S(), v27.S(), 2, MemOperand(x17));
4367
4368 __ Mov(x7, x17);
4369 __ Ldr(q28, MemOperand(x7, 16, PostIndex));
4370 __ Ldr(q29, MemOperand(x7, 16, PostIndex));
4371 __ Ldr(q30, MemOperand(x7, 16, PostIndex));
4372 __ Ldr(q31, MemOperand(x7));
4373 __ Ld4(v28.D(), v29.D(), v30.D(), v31.D(), 1, MemOperand(x17));
4374
4375 END();
4376
4377 RUN();
4378
4379 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
4380 ASSERT_EQUAL_128(0x0102030405060708, 0x090a0b0c0d0e0f10, q1);
4381 ASSERT_EQUAL_128(0x0203040506070809, 0x0a0b0c0d0e0f1011, q2);
4382 ASSERT_EQUAL_128(0x030405060708090a, 0x0b0c0d0e0f101112, q3);
4383 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q4);
4384 ASSERT_EQUAL_128(0x0302040305040605, 0x0706080709080a09, q5);
4385 ASSERT_EQUAL_128(0x0504060507060807, 0x09080a090b0a0c0b, q6);
4386 ASSERT_EQUAL_128(0x0706080709080a09, 0x0b0a0c0b0d0c0e0d, q7);
4387 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q8);
4388 ASSERT_EQUAL_128(0x0706050408070605, 0x090807060a090807, q9);
4389 ASSERT_EQUAL_128(0x0b0a09080c0b0a09, 0x0d0c0b0a0e0d0c0b, q10);
4390 ASSERT_EQUAL_128(0x0f0e0d0c100f0e0d, 0x11100f0e1211100f, q11);
4391 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q12);
4392 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x100f0e0d0c0b0a09, q13);
4393 ASSERT_EQUAL_128(0x1716151413121110, 0x1817161514131211, q14);
4394 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x201f1e1d1c1b1a19, q15);
4395 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q16);
4396 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q17);
4397 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q18);
4398 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736350333323130, q19);
4399 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q20);
4400 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q21);
4401 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q22);
4402 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x0706353433323130, q23);
4403 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q24);
4404 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q25);
4405 ASSERT_EQUAL_128(0x2f2e2d2c0b0a0908, 0x2726252423222120, q26);
4406 ASSERT_EQUAL_128(0x3f3e3d3c0f0e0d0c, 0x3736353433323130, q27);
4407 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q28);
4408 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q29);
4409 ASSERT_EQUAL_128(0x1716151413121110, 0x2726252423222120, q30);
4410 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x3736353433323130, q31);
4411
4412 TEARDOWN();
4413}
4414
4415
4416
4417TEST(neon_ld4_lane_postindex) {
4418 SETUP();
4419
4420 uint8_t src[64];
4421 for (unsigned i = 0; i < sizeof(src); i++) {
4422 src[i] = i;
4423 }
4424 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4425
4426 START();
4427
4428 // Test loading whole register by element.
4429 __ Mov(x17, src_base);
4430 for (int i = 15; i >= 0; i--) {
4431 __ Ld4(v0.B(), v1.B(), v2.B(), v3.B(), i,
4432 MemOperand(x17, 4, PostIndex));
4433 }
4434
4435 __ Mov(x18, src_base);
4436 for (int i = 7; i >= 0; i--) {
4437 __ Ld4(v4.H(), v5.H(), v6.H(), v7.H(), i,
4438 MemOperand(x18, 8, PostIndex));
4439 }
4440
4441 __ Mov(x19, src_base);
4442 for (int i = 3; i >= 0; i--) {
4443 __ Ld4(v8.S(), v9.S(), v10.S(), v11.S(), i,
4444 MemOperand(x19, 16, PostIndex));
4445 }
4446
4447 __ Mov(x20, src_base);
4448 for (int i = 1; i >= 0; i--) {
4449 __ Ld4(v12.D(), v13.D(), v14.D(), v15.D(), i,
4450 MemOperand(x20, 32, PostIndex));
4451 }
4452
4453 // Test loading a single element into an initialised register.
4454 __ Mov(x25, 1);
4455 __ Mov(x21, src_base);
4456 __ Mov(x22, src_base);
4457 __ Mov(x23, src_base);
4458 __ Mov(x24, src_base);
4459
4460 __ Mov(x4, x21);
4461 __ Ldr(q16, MemOperand(x4, 16, PostIndex));
4462 __ Ldr(q17, MemOperand(x4, 16, PostIndex));
4463 __ Ldr(q18, MemOperand(x4, 16, PostIndex));
4464 __ Ldr(q19, MemOperand(x4));
4465 __ Ld4(v16.B(), v17.B(), v18.B(), v19.B(), 4,
4466 MemOperand(x21, x25, PostIndex));
4467 __ Add(x25, x25, 1);
4468
4469 __ Mov(x5, x22);
4470 __ Ldr(q20, MemOperand(x5, 16, PostIndex));
4471 __ Ldr(q21, MemOperand(x5, 16, PostIndex));
4472 __ Ldr(q22, MemOperand(x5, 16, PostIndex));
4473 __ Ldr(q23, MemOperand(x5));
4474 __ Ld4(v20.H(), v21.H(), v22.H(), v23.H(), 3,
4475 MemOperand(x22, x25, PostIndex));
4476 __ Add(x25, x25, 1);
4477
4478 __ Mov(x6, x23);
4479 __ Ldr(q24, MemOperand(x6, 16, PostIndex));
4480 __ Ldr(q25, MemOperand(x6, 16, PostIndex));
4481 __ Ldr(q26, MemOperand(x6, 16, PostIndex));
4482 __ Ldr(q27, MemOperand(x6));
4483 __ Ld4(v24.S(), v25.S(), v26.S(), v27.S(), 2,
4484 MemOperand(x23, x25, PostIndex));
4485 __ Add(x25, x25, 1);
4486
4487 __ Mov(x7, x24);
4488 __ Ldr(q28, MemOperand(x7, 16, PostIndex));
4489 __ Ldr(q29, MemOperand(x7, 16, PostIndex));
4490 __ Ldr(q30, MemOperand(x7, 16, PostIndex));
4491 __ Ldr(q31, MemOperand(x7));
4492 __ Ld4(v28.D(), v29.D(), v30.D(), v31.D(), 1,
4493 MemOperand(x24, x25, PostIndex));
4494
4495 END();
4496
4497 RUN();
4498
4499 ASSERT_EQUAL_128(0x0004080c1014181c, 0x2024282c3034383c, q0);
4500 ASSERT_EQUAL_128(0x0105090d1115191d, 0x2125292d3135393d, q1);
4501 ASSERT_EQUAL_128(0x02060a0e12161a1e, 0x22262a2e32363a3e, q2);
4502 ASSERT_EQUAL_128(0x03070b0f13171b1f, 0x23272b2f33373b3f, q3);
4503 ASSERT_EQUAL_128(0x0100090811101918, 0x2120292831303938, q4);
4504 ASSERT_EQUAL_128(0x03020b0a13121b1a, 0x23222b2a33323b3a, q5);
4505 ASSERT_EQUAL_128(0x05040d0c15141d1c, 0x25242d2c35343d3c, q6);
4506 ASSERT_EQUAL_128(0x07060f0e17161f1e, 0x27262f2e37363f3e, q7);
4507 ASSERT_EQUAL_128(0x0302010013121110, 0x2322212033323130, q8);
4508 ASSERT_EQUAL_128(0x0706050417161514, 0x2726252437363534, q9);
4509 ASSERT_EQUAL_128(0x0b0a09081b1a1918, 0x2b2a29283b3a3938, q10);
4510 ASSERT_EQUAL_128(0x0f0e0d0c1f1e1d1c, 0x2f2e2d2c3f3e3d3c, q11);
4511 ASSERT_EQUAL_128(0x0706050403020100, 0x2726252423222120, q12);
4512 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x2f2e2d2c2b2a2928, q13);
4513 ASSERT_EQUAL_128(0x1716151413121110, 0x3736353433323130, q14);
4514 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x3f3e3d3c3b3a3938, q15);
4515 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q16);
4516 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q17);
4517 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q18);
4518 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736350333323130, q19);
4519 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q20);
4520 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q21);
4521 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q22);
4522 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x0706353433323130, q23);
4523 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q24);
4524 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q25);
4525 ASSERT_EQUAL_128(0x2f2e2d2c0b0a0908, 0x2726252423222120, q26);
4526 ASSERT_EQUAL_128(0x3f3e3d3c0f0e0d0c, 0x3736353433323130, q27);
4527 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q28);
4528 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q29);
4529 ASSERT_EQUAL_128(0x1716151413121110, 0x2726252423222120, q30);
4530 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x3736353433323130, q31);
4531
4532 ASSERT_EQUAL_64(src_base + 64, x17);
4533 ASSERT_EQUAL_64(src_base + 64, x18);
4534 ASSERT_EQUAL_64(src_base + 64, x19);
4535 ASSERT_EQUAL_64(src_base + 64, x20);
4536 ASSERT_EQUAL_64(src_base + 1, x21);
4537 ASSERT_EQUAL_64(src_base + 2, x22);
4538 ASSERT_EQUAL_64(src_base + 3, x23);
4539 ASSERT_EQUAL_64(src_base + 4, x24);
4540
4541 TEARDOWN();
4542}
4543
4544
4545TEST(neon_ld4_alllanes) {
4546 SETUP();
4547
4548 uint8_t src[64];
4549 for (unsigned i = 0; i < sizeof(src); i++) {
4550 src[i] = i;
4551 }
4552 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4553
4554 START();
4555 __ Mov(x17, src_base + 1);
4556 __ Mov(x18, 1);
4557 __ Ld4r(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(), MemOperand(x17));
4558 __ Add(x17, x17, 4);
4559 __ Ld4r(v4.V16B(), v5.V16B(), v6.V16B(), v7.V16B(), MemOperand(x17));
4560 __ Add(x17, x17, 1);
4561 __ Ld4r(v8.V4H(), v9.V4H(), v10.V4H(), v11.V4H(), MemOperand(x17));
4562 __ Add(x17, x17, 1);
4563 __ Ld4r(v12.V8H(), v13.V8H(), v14.V8H(), v15.V8H(), MemOperand(x17));
4564 __ Add(x17, x17, 8);
4565 __ Ld4r(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(), MemOperand(x17));
4566 __ Add(x17, x17, 1);
4567 __ Ld4r(v20.V4S(), v21.V4S(), v22.V4S(), v23.V4S(), MemOperand(x17));
4568 __ Add(x17, x17, 16);
4569 __ Ld4r(v24.V2D(), v25.V2D(), v26.V2D(), v27.V2D(), MemOperand(x17));
4570
4571
4572 END();
4573
4574 RUN();
4575
4576 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4577 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4578 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4579 ASSERT_EQUAL_128(0x0000000000000000, 0x0404040404040404, q3);
4580 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4581 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4582 ASSERT_EQUAL_128(0x0707070707070707, 0x0707070707070707, q6);
4583 ASSERT_EQUAL_128(0x0808080808080808, 0x0808080808080808, q7);
4584 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q8);
4585 ASSERT_EQUAL_128(0x0000000000000000, 0x0908090809080908, q9);
4586 ASSERT_EQUAL_128(0x0000000000000000, 0x0b0a0b0a0b0a0b0a, q10);
4587 ASSERT_EQUAL_128(0x0000000000000000, 0x0d0c0d0c0d0c0d0c, q11);
4588 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q12);
4589 ASSERT_EQUAL_128(0x0a090a090a090a09, 0x0a090a090a090a09, q13);
4590 ASSERT_EQUAL_128(0x0c0b0c0b0c0b0c0b, 0x0c0b0c0b0c0b0c0b, q14);
4591 ASSERT_EQUAL_128(0x0e0d0e0d0e0d0e0d, 0x0e0d0e0d0e0d0e0d, q15);
4592 ASSERT_EQUAL_128(0x0000000000000000, 0x1211100f1211100f, q16);
4593 ASSERT_EQUAL_128(0x0000000000000000, 0x1615141316151413, q17);
4594 ASSERT_EQUAL_128(0x0000000000000000, 0x1a1918171a191817, q18);
4595 ASSERT_EQUAL_128(0x0000000000000000, 0x1e1d1c1b1e1d1c1b, q19);
4596 ASSERT_EQUAL_128(0x1312111013121110, 0x1312111013121110, q20);
4597 ASSERT_EQUAL_128(0x1716151417161514, 0x1716151417161514, q21);
4598 ASSERT_EQUAL_128(0x1b1a19181b1a1918, 0x1b1a19181b1a1918, q22);
4599 ASSERT_EQUAL_128(0x1f1e1d1c1f1e1d1c, 0x1f1e1d1c1f1e1d1c, q23);
4600 ASSERT_EQUAL_128(0x2726252423222120, 0x2726252423222120, q24);
4601 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2f2e2d2c2b2a2928, q25);
4602 ASSERT_EQUAL_128(0x3736353433323130, 0x3736353433323130, q26);
4603 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3f3e3d3c3b3a3938, q27);
4604
4605 TEARDOWN();
4606}
4607
4608
4609TEST(neon_ld4_alllanes_postindex) {
4610 SETUP();
4611
4612 uint8_t src[64];
4613 for (unsigned i = 0; i < sizeof(src); i++) {
4614 src[i] = i;
4615 }
4616 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4617 __ Mov(x17, src_base + 1);
4618 __ Mov(x18, 1);
4619
4620 START();
4621 __ Mov(x17, src_base + 1);
4622 __ Mov(x18, 1);
4623 __ Ld4r(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(),
4624 MemOperand(x17, 4, PostIndex));
4625 __ Ld4r(v4.V16B(), v5.V16B(), v6.V16B(), v7.V16B(),
4626 MemOperand(x17, x18, PostIndex));
4627 __ Ld4r(v8.V4H(), v9.V4H(), v10.V4H(), v11.V4H(),
4628 MemOperand(x17, x18, PostIndex));
4629 __ Ld4r(v12.V8H(), v13.V8H(), v14.V8H(), v15.V8H(),
4630 MemOperand(x17, 8, PostIndex));
4631 __ Ld4r(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(),
4632 MemOperand(x17, x18, PostIndex));
4633 __ Ld4r(v20.V4S(), v21.V4S(), v22.V4S(), v23.V4S(),
4634 MemOperand(x17, 16, PostIndex));
4635 __ Ld4r(v24.V2D(), v25.V2D(), v26.V2D(), v27.V2D(),
4636 MemOperand(x17, 32, PostIndex));
4637 END();
4638
4639 RUN();
4640
4641 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4642 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4643 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4644 ASSERT_EQUAL_128(0x0000000000000000, 0x0404040404040404, q3);
4645 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4646 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4647 ASSERT_EQUAL_128(0x0707070707070707, 0x0707070707070707, q6);
4648 ASSERT_EQUAL_128(0x0808080808080808, 0x0808080808080808, q7);
4649 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q8);
4650 ASSERT_EQUAL_128(0x0000000000000000, 0x0908090809080908, q9);
4651 ASSERT_EQUAL_128(0x0000000000000000, 0x0b0a0b0a0b0a0b0a, q10);
4652 ASSERT_EQUAL_128(0x0000000000000000, 0x0d0c0d0c0d0c0d0c, q11);
4653 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q12);
4654 ASSERT_EQUAL_128(0x0a090a090a090a09, 0x0a090a090a090a09, q13);
4655 ASSERT_EQUAL_128(0x0c0b0c0b0c0b0c0b, 0x0c0b0c0b0c0b0c0b, q14);
4656 ASSERT_EQUAL_128(0x0e0d0e0d0e0d0e0d, 0x0e0d0e0d0e0d0e0d, q15);
4657 ASSERT_EQUAL_128(0x0000000000000000, 0x1211100f1211100f, q16);
4658 ASSERT_EQUAL_128(0x0000000000000000, 0x1615141316151413, q17);
4659 ASSERT_EQUAL_128(0x0000000000000000, 0x1a1918171a191817, q18);
4660 ASSERT_EQUAL_128(0x0000000000000000, 0x1e1d1c1b1e1d1c1b, q19);
4661 ASSERT_EQUAL_128(0x1312111013121110, 0x1312111013121110, q20);
4662 ASSERT_EQUAL_128(0x1716151417161514, 0x1716151417161514, q21);
4663 ASSERT_EQUAL_128(0x1b1a19181b1a1918, 0x1b1a19181b1a1918, q22);
4664 ASSERT_EQUAL_128(0x1f1e1d1c1f1e1d1c, 0x1f1e1d1c1f1e1d1c, q23);
4665 ASSERT_EQUAL_128(0x2726252423222120, 0x2726252423222120, q24);
4666 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2f2e2d2c2b2a2928, q25);
4667 ASSERT_EQUAL_128(0x3736353433323130, 0x3736353433323130, q26);
4668 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3f3e3d3c3b3a3938, q27);
4669 ASSERT_EQUAL_64(src_base + 64, x17);
4670
4671 TEARDOWN();
4672}
4673
4674
4675TEST(neon_st1_lane) {
4676 SETUP();
4677
4678 uint8_t src[64];
4679 for (unsigned i = 0; i < sizeof(src); i++) {
4680 src[i] = i;
4681 }
4682 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4683
4684 START();
4685 __ Mov(x17, src_base);
4686 __ Mov(x18, -16);
4687 __ Ldr(q0, MemOperand(x17));
4688
4689 for (int i = 15; i >= 0; i--) {
4690 __ St1(v0.B(), i, MemOperand(x17));
4691 __ Add(x17, x17, 1);
4692 }
4693 __ Ldr(q1, MemOperand(x17, x18));
4694
4695 for (int i = 7; i >= 0; i--) {
4696 __ St1(v0.H(), i, MemOperand(x17));
4697 __ Add(x17, x17, 2);
4698 }
4699 __ Ldr(q2, MemOperand(x17, x18));
4700
4701 for (int i = 3; i >= 0; i--) {
4702 __ St1(v0.S(), i, MemOperand(x17));
4703 __ Add(x17, x17, 4);
4704 }
4705 __ Ldr(q3, MemOperand(x17, x18));
4706
4707 for (int i = 1; i >= 0; i--) {
4708 __ St1(v0.D(), i, MemOperand(x17));
4709 __ Add(x17, x17, 8);
4710 }
4711 __ Ldr(q4, MemOperand(x17, x18));
4712
4713 END();
4714
4715 RUN();
4716
4717 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q1);
4718 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q2);
4719 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q3);
4720 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q4);
4721
4722 TEARDOWN();
4723}
4724
4725
4726TEST(neon_st2_lane) {
4727 SETUP();
4728
4729 // Struct size * addressing modes * element sizes * vector size.
4730 uint8_t dst[2 * 2 * 4 * 16];
4731 memset(dst, 0, sizeof(dst));
4732 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4733
4734 START();
4735 __ Mov(x17, dst_base);
4736 __ Mov(x18, dst_base);
4737 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
4738 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
4739
4740 // Test B stores with and without post index.
4741 for (int i = 15; i >= 0; i--) {
4742 __ St2(v0.B(), v1.B(), i, MemOperand(x18));
4743 __ Add(x18, x18, 2);
4744 }
4745 for (int i = 15; i >= 0; i--) {
4746 __ St2(v0.B(), v1.B(), i, MemOperand(x18, 2, PostIndex));
4747 }
4748 __ Ldr(q2, MemOperand(x17, 0 * 16));
4749 __ Ldr(q3, MemOperand(x17, 1 * 16));
4750 __ Ldr(q4, MemOperand(x17, 2 * 16));
4751 __ Ldr(q5, MemOperand(x17, 3 * 16));
4752
4753 // Test H stores with and without post index.
4754 __ Mov(x0, 4);
4755 for (int i = 7; i >= 0; i--) {
4756 __ St2(v0.H(), v1.H(), i, MemOperand(x18));
4757 __ Add(x18, x18, 4);
4758 }
4759 for (int i = 7; i >= 0; i--) {
4760 __ St2(v0.H(), v1.H(), i, MemOperand(x18, x0, PostIndex));
4761 }
4762 __ Ldr(q6, MemOperand(x17, 4 * 16));
4763 __ Ldr(q7, MemOperand(x17, 5 * 16));
4764 __ Ldr(q16, MemOperand(x17, 6 * 16));
4765 __ Ldr(q17, MemOperand(x17, 7 * 16));
4766
4767 // Test S stores with and without post index.
4768 for (int i = 3; i >= 0; i--) {
4769 __ St2(v0.S(), v1.S(), i, MemOperand(x18));
4770 __ Add(x18, x18, 8);
4771 }
4772 for (int i = 3; i >= 0; i--) {
4773 __ St2(v0.S(), v1.S(), i, MemOperand(x18, 8, PostIndex));
4774 }
4775 __ Ldr(q18, MemOperand(x17, 8 * 16));
4776 __ Ldr(q19, MemOperand(x17, 9 * 16));
4777 __ Ldr(q20, MemOperand(x17, 10 * 16));
4778 __ Ldr(q21, MemOperand(x17, 11 * 16));
4779
4780 // Test D stores with and without post index.
4781 __ Mov(x0, 16);
4782 __ St2(v0.D(), v1.D(), 1, MemOperand(x18));
4783 __ Add(x18, x18, 16);
4784 __ St2(v0.D(), v1.D(), 0, MemOperand(x18, 16, PostIndex));
4785 __ St2(v0.D(), v1.D(), 1, MemOperand(x18, x0, PostIndex));
4786 __ St2(v0.D(), v1.D(), 0, MemOperand(x18, x0, PostIndex));
4787 __ Ldr(q22, MemOperand(x17, 12 * 16));
4788 __ Ldr(q23, MemOperand(x17, 13 * 16));
4789 __ Ldr(q24, MemOperand(x17, 14 * 16));
4790 __ Ldr(q25, MemOperand(x17, 15 * 16));
4791 END();
4792
4793 RUN();
4794
4795 ASSERT_EQUAL_128(0x1707160615051404, 0x1303120211011000, q2);
4796 ASSERT_EQUAL_128(0x1f0f1e0e1d0d1c0c, 0x1b0b1a0a19091808, q3);
4797 ASSERT_EQUAL_128(0x1707160615051404, 0x1303120211011000, q4);
4798 ASSERT_EQUAL_128(0x1f0f1e0e1d0d1c0c, 0x1b0b1a0a19091808, q5);
4799
4800 ASSERT_EQUAL_128(0x1617060714150405, 0x1213020310110001, q6);
4801 ASSERT_EQUAL_128(0x1e1f0e0f1c1d0c0d, 0x1a1b0a0b18190809, q7);
4802 ASSERT_EQUAL_128(0x1617060714150405, 0x1213020310110001, q16);
4803 ASSERT_EQUAL_128(0x1e1f0e0f1c1d0c0d, 0x1a1b0a0b18190809, q17);
4804
4805 ASSERT_EQUAL_128(0x1415161704050607, 0x1011121300010203, q18);
4806 ASSERT_EQUAL_128(0x1c1d1e1f0c0d0e0f, 0x18191a1b08090a0b, q19);
4807 ASSERT_EQUAL_128(0x1415161704050607, 0x1011121300010203, q20);
4808 ASSERT_EQUAL_128(0x1c1d1e1f0c0d0e0f, 0x18191a1b08090a0b, q21);
4809
4810 ASSERT_EQUAL_128(0x1011121314151617, 0x0001020304050607, q22);
4811 ASSERT_EQUAL_128(0x18191a1b1c1d1e1f, 0x08090a0b0c0d0e0f, q23);
4812 ASSERT_EQUAL_128(0x1011121314151617, 0x0001020304050607, q22);
4813 ASSERT_EQUAL_128(0x18191a1b1c1d1e1f, 0x08090a0b0c0d0e0f, q23);
4814
4815 TEARDOWN();
4816}
4817
4818
4819TEST(neon_st3_lane) {
4820 SETUP();
4821
4822 // Struct size * addressing modes * element sizes * vector size.
4823 uint8_t dst[3 * 2 * 4 * 16];
4824 memset(dst, 0, sizeof(dst));
4825 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4826
4827 START();
4828 __ Mov(x17, dst_base);
4829 __ Mov(x18, dst_base);
4830 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
4831 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
4832 __ Movi(v2.V2D(), 0x2021222324252627, 0x28292a2b2c2d2e2f);
4833
4834 // Test B stores with and without post index.
4835 for (int i = 15; i >= 0; i--) {
4836 __ St3(v0.B(), v1.B(), v2.B(), i, MemOperand(x18));
4837 __ Add(x18, x18, 3);
4838 }
4839 for (int i = 15; i >= 0; i--) {
4840 __ St3(v0.B(), v1.B(), v2.B(), i, MemOperand(x18, 3, PostIndex));
4841 }
4842 __ Ldr(q3, MemOperand(x17, 0 * 16));
4843 __ Ldr(q4, MemOperand(x17, 1 * 16));
4844 __ Ldr(q5, MemOperand(x17, 2 * 16));
4845 __ Ldr(q6, MemOperand(x17, 3 * 16));
4846 __ Ldr(q7, MemOperand(x17, 4 * 16));
4847 __ Ldr(q16, MemOperand(x17, 5 * 16));
4848
4849 // Test H stores with and without post index.
4850 __ Mov(x0, 6);
4851 for (int i = 7; i >= 0; i--) {
4852 __ St3(v0.H(), v1.H(), v2.H(), i, MemOperand(x18));
4853 __ Add(x18, x18, 6);
4854 }
4855 for (int i = 7; i >= 0; i--) {
4856 __ St3(v0.H(), v1.H(), v2.H(), i, MemOperand(x18, x0, PostIndex));
4857 }
4858 __ Ldr(q17, MemOperand(x17, 6 * 16));
4859 __ Ldr(q18, MemOperand(x17, 7 * 16));
4860 __ Ldr(q19, MemOperand(x17, 8 * 16));
4861 __ Ldr(q20, MemOperand(x17, 9 * 16));
4862 __ Ldr(q21, MemOperand(x17, 10 * 16));
4863 __ Ldr(q22, MemOperand(x17, 11 * 16));
4864
4865 // Test S stores with and without post index.
4866 for (int i = 3; i >= 0; i--) {
4867 __ St3(v0.S(), v1.S(), v2.S(), i, MemOperand(x18));
4868 __ Add(x18, x18, 12);
4869 }
4870 for (int i = 3; i >= 0; i--) {
4871 __ St3(v0.S(), v1.S(), v2.S(), i, MemOperand(x18, 12, PostIndex));
4872 }
4873 __ Ldr(q23, MemOperand(x17, 12 * 16));
4874 __ Ldr(q24, MemOperand(x17, 13 * 16));
4875 __ Ldr(q25, MemOperand(x17, 14 * 16));
4876 __ Ldr(q26, MemOperand(x17, 15 * 16));
4877 __ Ldr(q27, MemOperand(x17, 16 * 16));
4878 __ Ldr(q28, MemOperand(x17, 17 * 16));
4879
4880 // Test D stores with and without post index.
4881 __ Mov(x0, 24);
4882 __ St3(v0.D(), v1.D(), v2.D(), 1, MemOperand(x18));
4883 __ Add(x18, x18, 24);
4884 __ St3(v0.D(), v1.D(), v2.D(), 0, MemOperand(x18, 24, PostIndex));
4885 __ St3(v0.D(), v1.D(), v2.D(), 1, MemOperand(x18, x0, PostIndex));
4886 __ Ldr(q29, MemOperand(x17, 18 * 16));
4887 __ Ldr(q30, MemOperand(x17, 19 * 16));
4888 __ Ldr(q31, MemOperand(x17, 20 * 16));
4889 END();
4890
4891 RUN();
4892
4893 ASSERT_EQUAL_128(0x0524140423130322, 0x1202211101201000, q3);
4894 ASSERT_EQUAL_128(0x1a0a291909281808, 0x2717072616062515, q4);
4895 ASSERT_EQUAL_128(0x2f1f0f2e1e0e2d1d, 0x0d2c1c0c2b1b0b2a, q5);
4896 ASSERT_EQUAL_128(0x0524140423130322, 0x1202211101201000, q6);
4897 ASSERT_EQUAL_128(0x1a0a291909281808, 0x2717072616062515, q7);
4898 ASSERT_EQUAL_128(0x2f1f0f2e1e0e2d1d, 0x0d2c1c0c2b1b0b2a, q16);
4899
4900 ASSERT_EQUAL_128(0x1415040522231213, 0x0203202110110001, q17);
4901 ASSERT_EQUAL_128(0x0a0b282918190809, 0x2627161706072425, q18);
4902 ASSERT_EQUAL_128(0x2e2f1e1f0e0f2c2d, 0x1c1d0c0d2a2b1a1b, q19);
4903 ASSERT_EQUAL_128(0x1415040522231213, 0x0203202110110001, q20);
4904 ASSERT_EQUAL_128(0x0a0b282918190809, 0x2627161706072425, q21);
4905 ASSERT_EQUAL_128(0x2e2f1e1f0e0f2c2d, 0x1c1d0c0d2a2b1a1b, q22);
4906
4907 ASSERT_EQUAL_128(0x0405060720212223, 0x1011121300010203, q23);
4908 ASSERT_EQUAL_128(0x18191a1b08090a0b, 0x2425262714151617, q24);
4909 ASSERT_EQUAL_128(0x2c2d2e2f1c1d1e1f, 0x0c0d0e0f28292a2b, q25);
4910 ASSERT_EQUAL_128(0x0405060720212223, 0x1011121300010203, q26);
4911 ASSERT_EQUAL_128(0x18191a1b08090a0b, 0x2425262714151617, q27);
4912 ASSERT_EQUAL_128(0x2c2d2e2f1c1d1e1f, 0x0c0d0e0f28292a2b, q28);
4913
4914 TEARDOWN();
4915}
4916
4917
4918TEST(neon_st4_lane) {
4919 SETUP();
4920
4921 // Struct size * element sizes * vector size.
4922 uint8_t dst[4 * 4 * 16];
4923 memset(dst, 0, sizeof(dst));
4924 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4925
4926 START();
4927 __ Mov(x17, dst_base);
4928 __ Mov(x18, dst_base);
4929 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
4930 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
4931 __ Movi(v2.V2D(), 0x2021222324252627, 0x28292a2b2c2d2e2f);
4932 __ Movi(v3.V2D(), 0x2021222324252627, 0x28292a2b2c2d2e2f);
4933
4934 // Test B stores without post index.
4935 for (int i = 15; i >= 0; i--) {
4936 __ St4(v0.B(), v1.B(), v2.B(), v3.B(), i, MemOperand(x18));
4937 __ Add(x18, x18, 4);
4938 }
4939 __ Ldr(q4, MemOperand(x17, 0 * 16));
4940 __ Ldr(q5, MemOperand(x17, 1 * 16));
4941 __ Ldr(q6, MemOperand(x17, 2 * 16));
4942 __ Ldr(q7, MemOperand(x17, 3 * 16));
4943
4944 // Test H stores with post index.
4945 __ Mov(x0, 8);
4946 for (int i = 7; i >= 0; i--) {
4947 __ St4(v0.H(), v1.H(), v2.H(), v3.H(), i, MemOperand(x18, x0, PostIndex));
4948 }
4949 __ Ldr(q16, MemOperand(x17, 4 * 16));
4950 __ Ldr(q17, MemOperand(x17, 5 * 16));
4951 __ Ldr(q18, MemOperand(x17, 6 * 16));
4952 __ Ldr(q19, MemOperand(x17, 7 * 16));
4953
4954 // Test S stores without post index.
4955 for (int i = 3; i >= 0; i--) {
4956 __ St4(v0.S(), v1.S(), v2.S(), v3.S(), i, MemOperand(x18));
4957 __ Add(x18, x18, 16);
4958 }
4959 __ Ldr(q20, MemOperand(x17, 8 * 16));
4960 __ Ldr(q21, MemOperand(x17, 9 * 16));
4961 __ Ldr(q22, MemOperand(x17, 10 * 16));
4962 __ Ldr(q23, MemOperand(x17, 11 * 16));
4963
4964 // Test D stores with post index.
4965 __ Mov(x0, 32);
4966 __ St4(v0.D(), v1.D(), v2.D(), v3.D(), 0, MemOperand(x18, 32, PostIndex));
4967 __ St4(v0.D(), v1.D(), v2.D(), v3.D(), 1, MemOperand(x18, x0, PostIndex));
4968
4969 __ Ldr(q24, MemOperand(x17, 12 * 16));
4970 __ Ldr(q25, MemOperand(x17, 13 * 16));
4971 __ Ldr(q26, MemOperand(x17, 14 * 16));
4972 __ Ldr(q27, MemOperand(x17, 15 * 16));
4973 END();
4974
4975 RUN();
4976
4977 ASSERT_EQUAL_128(0x2323130322221202, 0x2121110120201000, q4);
4978 ASSERT_EQUAL_128(0x2727170726261606, 0x2525150524241404, q5);
4979 ASSERT_EQUAL_128(0x2b2b1b0b2a2a1a0a, 0x2929190928281808, q6);
4980 ASSERT_EQUAL_128(0x2f2f1f0f2e2e1e0e, 0x2d2d1d0d2c2c1c0c, q7);
4981
4982 ASSERT_EQUAL_128(0x2223222312130203, 0x2021202110110001, q16);
4983 ASSERT_EQUAL_128(0x2627262716170607, 0x2425242514150405, q17);
4984 ASSERT_EQUAL_128(0x2a2b2a2b1a1b0a0b, 0x2829282918190809, q18);
4985 ASSERT_EQUAL_128(0x2e2f2e2f1e1f0e0f, 0x2c2d2c2d1c1d0c0d, q19);
4986
4987 ASSERT_EQUAL_128(0x2021222320212223, 0x1011121300010203, q20);
4988 ASSERT_EQUAL_128(0x2425262724252627, 0x1415161704050607, q21);
4989 ASSERT_EQUAL_128(0x28292a2b28292a2b, 0x18191a1b08090a0b, q22);
4990 ASSERT_EQUAL_128(0x2c2d2e2f2c2d2e2f, 0x1c1d1e1f0c0d0e0f, q23);
4991
4992 ASSERT_EQUAL_128(0x18191a1b1c1d1e1f, 0x08090a0b0c0d0e0f, q24);
4993 ASSERT_EQUAL_128(0x28292a2b2c2d2e2f, 0x28292a2b2c2d2e2f, q25);
4994 ASSERT_EQUAL_128(0x1011121314151617, 0x0001020304050607, q26);
4995 ASSERT_EQUAL_128(0x2021222324252627, 0x2021222324252627, q27);
4996
4997 TEARDOWN();
4998}
4999
5000
5001TEST(neon_ld1_lane_postindex) {
5002 SETUP();
5003
5004 uint8_t src[64];
5005 for (unsigned i = 0; i < sizeof(src); i++) {
5006 src[i] = i;
5007 }
5008 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5009
5010 START();
5011 __ Mov(x17, src_base);
5012 __ Mov(x18, src_base);
5013 __ Mov(x19, src_base);
5014 __ Mov(x20, src_base);
5015 __ Mov(x21, src_base);
5016 __ Mov(x22, src_base);
5017 __ Mov(x23, src_base);
5018 __ Mov(x24, src_base);
5019
5020 // Test loading whole register by element.
5021 for (int i = 15; i >= 0; i--) {
5022 __ Ld1(v0.B(), i, MemOperand(x17, 1, PostIndex));
5023 }
5024
5025 for (int i = 7; i >= 0; i--) {
5026 __ Ld1(v1.H(), i, MemOperand(x18, 2, PostIndex));
5027 }
5028
5029 for (int i = 3; i >= 0; i--) {
5030 __ Ld1(v2.S(), i, MemOperand(x19, 4, PostIndex));
5031 }
5032
5033 for (int i = 1; i >= 0; i--) {
5034 __ Ld1(v3.D(), i, MemOperand(x20, 8, PostIndex));
5035 }
5036
5037 // Test loading a single element into an initialised register.
5038 __ Mov(x25, 1);
5039 __ Ldr(q4, MemOperand(x21));
5040 __ Ld1(v4.B(), 4, MemOperand(x21, x25, PostIndex));
5041 __ Add(x25, x25, 1);
5042
5043 __ Ldr(q5, MemOperand(x22));
5044 __ Ld1(v5.H(), 3, MemOperand(x22, x25, PostIndex));
5045 __ Add(x25, x25, 1);
5046
5047 __ Ldr(q6, MemOperand(x23));
5048 __ Ld1(v6.S(), 2, MemOperand(x23, x25, PostIndex));
5049 __ Add(x25, x25, 1);
5050
5051 __ Ldr(q7, MemOperand(x24));
5052 __ Ld1(v7.D(), 1, MemOperand(x24, x25, PostIndex));
5053
5054 END();
5055
5056 RUN();
5057
5058 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
5059 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q1);
5060 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q2);
5061 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q3);
5062 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q4);
5063 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q5);
5064 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q6);
5065 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q7);
5066 ASSERT_EQUAL_64(src_base + 16, x17);
5067 ASSERT_EQUAL_64(src_base + 16, x18);
5068 ASSERT_EQUAL_64(src_base + 16, x19);
5069 ASSERT_EQUAL_64(src_base + 16, x20);
5070 ASSERT_EQUAL_64(src_base + 1, x21);
5071 ASSERT_EQUAL_64(src_base + 2, x22);
5072 ASSERT_EQUAL_64(src_base + 3, x23);
5073 ASSERT_EQUAL_64(src_base + 4, x24);
5074
5075 TEARDOWN();
5076}
5077
5078
5079TEST(neon_st1_lane_postindex) {
5080 SETUP();
5081
5082 uint8_t src[64];
5083 for (unsigned i = 0; i < sizeof(src); i++) {
5084 src[i] = i;
5085 }
5086 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5087
5088 START();
5089 __ Mov(x17, src_base);
5090 __ Mov(x18, -16);
5091 __ Ldr(q0, MemOperand(x17));
5092
5093 for (int i = 15; i >= 0; i--) {
5094 __ St1(v0.B(), i, MemOperand(x17, 1, PostIndex));
5095 }
5096 __ Ldr(q1, MemOperand(x17, x18));
5097
5098 for (int i = 7; i >= 0; i--) {
5099 __ St1(v0.H(), i, MemOperand(x17, 2, PostIndex));
5100 }
5101 __ Ldr(q2, MemOperand(x17, x18));
5102
5103 for (int i = 3; i >= 0; i--) {
5104 __ St1(v0.S(), i, MemOperand(x17, 4, PostIndex));
5105 }
5106 __ Ldr(q3, MemOperand(x17, x18));
5107
5108 for (int i = 1; i >= 0; i--) {
5109 __ St1(v0.D(), i, MemOperand(x17, 8, PostIndex));
5110 }
5111 __ Ldr(q4, MemOperand(x17, x18));
5112
5113 END();
5114
5115 RUN();
5116
5117 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q1);
5118 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q2);
5119 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q3);
5120 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q4);
5121
5122 TEARDOWN();
5123}
5124
5125
5126TEST(neon_ld1_alllanes) {
5127 SETUP();
5128
5129 uint8_t src[64];
5130 for (unsigned i = 0; i < sizeof(src); i++) {
5131 src[i] = i;
5132 }
5133 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5134
5135 START();
5136 __ Mov(x17, src_base + 1);
5137 __ Ld1r(v0.V8B(), MemOperand(x17));
5138 __ Add(x17, x17, 1);
5139 __ Ld1r(v1.V16B(), MemOperand(x17));
5140 __ Add(x17, x17, 1);
5141 __ Ld1r(v2.V4H(), MemOperand(x17));
5142 __ Add(x17, x17, 1);
5143 __ Ld1r(v3.V8H(), MemOperand(x17));
5144 __ Add(x17, x17, 1);
5145 __ Ld1r(v4.V2S(), MemOperand(x17));
5146 __ Add(x17, x17, 1);
5147 __ Ld1r(v5.V4S(), MemOperand(x17));
5148 __ Add(x17, x17, 1);
5149 __ Ld1r(v6.V1D(), MemOperand(x17));
5150 __ Add(x17, x17, 1);
5151 __ Ld1r(v7.V2D(), MemOperand(x17));
5152 END();
5153
5154 RUN();
5155
5156 ASSERT_EQUAL_128(0, 0x0101010101010101, q0);
5157 ASSERT_EQUAL_128(0x0202020202020202, 0x0202020202020202, q1);
5158 ASSERT_EQUAL_128(0, 0x0403040304030403, q2);
5159 ASSERT_EQUAL_128(0x0504050405040504, 0x0504050405040504, q3);
5160 ASSERT_EQUAL_128(0, 0x0807060508070605, q4);
5161 ASSERT_EQUAL_128(0x0908070609080706, 0x0908070609080706, q5);
5162 ASSERT_EQUAL_128(0, 0x0e0d0c0b0a090807, q6);
5163 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0f0e0d0c0b0a0908, q7);
5164
5165 TEARDOWN();
5166}
5167
5168
5169TEST(neon_ld1_alllanes_postindex) {
5170 SETUP();
5171
5172 uint8_t src[64];
5173 for (unsigned i = 0; i < sizeof(src); i++) {
5174 src[i] = i;
5175 }
5176 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5177
5178 START();
5179 __ Mov(x17, src_base + 1);
5180 __ Mov(x18, 1);
5181 __ Ld1r(v0.V8B(), MemOperand(x17, 1, PostIndex));
5182 __ Ld1r(v1.V16B(), MemOperand(x17, x18, PostIndex));
5183 __ Ld1r(v2.V4H(), MemOperand(x17, x18, PostIndex));
5184 __ Ld1r(v3.V8H(), MemOperand(x17, 2, PostIndex));
5185 __ Ld1r(v4.V2S(), MemOperand(x17, x18, PostIndex));
5186 __ Ld1r(v5.V4S(), MemOperand(x17, 4, PostIndex));
5187 __ Ld1r(v6.V2D(), MemOperand(x17, 8, PostIndex));
5188 END();
5189
5190 RUN();
5191
5192 ASSERT_EQUAL_128(0, 0x0101010101010101, q0);
5193 ASSERT_EQUAL_128(0x0202020202020202, 0x0202020202020202, q1);
5194 ASSERT_EQUAL_128(0, 0x0403040304030403, q2);
5195 ASSERT_EQUAL_128(0x0504050405040504, 0x0504050405040504, q3);
5196 ASSERT_EQUAL_128(0, 0x0908070609080706, q4);
5197 ASSERT_EQUAL_128(0x0a0908070a090807, 0x0a0908070a090807, q5);
5198 ASSERT_EQUAL_128(0x1211100f0e0d0c0b, 0x1211100f0e0d0c0b, q6);
5199 ASSERT_EQUAL_64(src_base + 19, x17);
5200
5201 TEARDOWN();
5202}
5203
5204
5205TEST(neon_st1_d) {
5206 SETUP();
5207
5208 uint8_t src[14 * kDRegSizeInBytes];
5209 for (unsigned i = 0; i < sizeof(src); i++) {
5210 src[i] = i;
5211 }
5212 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5213
5214 START();
5215 __ Mov(x17, src_base);
5216 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5217 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5218 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5219 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5220 __ Mov(x17, src_base);
5221
5222 __ St1(v0.V8B(), MemOperand(x17));
5223 __ Ldr(d16, MemOperand(x17, 8, PostIndex));
5224
5225 __ St1(v0.V8B(), v1.V8B(), MemOperand(x17));
5226 __ Ldr(q17, MemOperand(x17, 16, PostIndex));
5227
5228 __ St1(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x17));
5229 __ Ldr(d18, MemOperand(x17, 8, PostIndex));
5230 __ Ldr(d19, MemOperand(x17, 8, PostIndex));
5231 __ Ldr(d20, MemOperand(x17, 8, PostIndex));
5232
5233 __ St1(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(), MemOperand(x17));
5234 __ Ldr(q21, MemOperand(x17, 16, PostIndex));
5235 __ Ldr(q22, MemOperand(x17, 16, PostIndex));
5236
5237 __ St1(v0.V1D(), v1.V1D(), v2.V1D(), v3.V1D(), MemOperand(x17));
5238 __ Ldr(q23, MemOperand(x17, 16, PostIndex));
5239 __ Ldr(q24, MemOperand(x17));
5240 END();
5241
5242 RUN();
5243
5244 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q0);
5245 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q1);
5246 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q2);
5247 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323130, q3);
5248 ASSERT_EQUAL_128(0, 0x0706050403020100, q16);
5249 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q17);
5250 ASSERT_EQUAL_128(0, 0x0706050403020100, q18);
5251 ASSERT_EQUAL_128(0, 0x1716151413121110, q19);
5252 ASSERT_EQUAL_128(0, 0x2726252423222120, q20);
5253 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q21);
5254 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q22);
5255 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q23);
5256 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q24);
5257
5258 TEARDOWN();
5259}
5260
5261
5262TEST(neon_st1_d_postindex) {
5263 SETUP();
5264
5265 uint8_t src[64 + 14 * kDRegSizeInBytes];
5266 for (unsigned i = 0; i < sizeof(src); i++) {
5267 src[i] = i;
5268 }
5269 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5270
5271 START();
5272 __ Mov(x17, src_base);
5273 __ Mov(x18, -8);
5274 __ Mov(x19, -16);
5275 __ Mov(x20, -24);
5276 __ Mov(x21, -32);
5277 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5278 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5279 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5280 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5281 __ Mov(x17, src_base);
5282
5283 __ St1(v0.V8B(), MemOperand(x17, 8, PostIndex));
5284 __ Ldr(d16, MemOperand(x17, x18));
5285
5286 __ St1(v0.V8B(), v1.V8B(), MemOperand(x17, 16, PostIndex));
5287 __ Ldr(q17, MemOperand(x17, x19));
5288
5289 __ St1(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x17, 24, PostIndex));
5290 __ Ldr(d18, MemOperand(x17, x20));
5291 __ Ldr(d19, MemOperand(x17, x19));
5292 __ Ldr(d20, MemOperand(x17, x18));
5293
5294 __ St1(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(),
5295 MemOperand(x17, 32, PostIndex));
5296 __ Ldr(q21, MemOperand(x17, x21));
5297 __ Ldr(q22, MemOperand(x17, x19));
5298
5299 __ St1(v0.V1D(), v1.V1D(), v2.V1D(), v3.V1D(),
5300 MemOperand(x17, 32, PostIndex));
5301 __ Ldr(q23, MemOperand(x17, x21));
5302 __ Ldr(q24, MemOperand(x17, x19));
5303 END();
5304
5305 RUN();
5306
5307 ASSERT_EQUAL_128(0, 0x0706050403020100, q16);
5308 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q17);
5309 ASSERT_EQUAL_128(0, 0x0706050403020100, q18);
5310 ASSERT_EQUAL_128(0, 0x1716151413121110, q19);
5311 ASSERT_EQUAL_128(0, 0x2726252423222120, q20);
5312 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q21);
5313 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q22);
5314 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q23);
5315 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q24);
5316
5317 TEARDOWN();
5318}
5319
5320
5321TEST(neon_st1_q) {
5322 SETUP();
5323
5324 uint8_t src[64 + 160];
5325 for (unsigned i = 0; i < sizeof(src); i++) {
5326 src[i] = i;
5327 }
5328 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5329
5330 START();
5331 __ Mov(x17, src_base);
5332 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5333 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5334 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5335 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5336
5337 __ St1(v0.V16B(), MemOperand(x17));
5338 __ Ldr(q16, MemOperand(x17, 16, PostIndex));
5339
5340 __ St1(v0.V8H(), v1.V8H(), MemOperand(x17));
5341 __ Ldr(q17, MemOperand(x17, 16, PostIndex));
5342 __ Ldr(q18, MemOperand(x17, 16, PostIndex));
5343
5344 __ St1(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x17));
5345 __ Ldr(q19, MemOperand(x17, 16, PostIndex));
5346 __ Ldr(q20, MemOperand(x17, 16, PostIndex));
5347 __ Ldr(q21, MemOperand(x17, 16, PostIndex));
5348
5349 __ St1(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(), MemOperand(x17));
5350 __ Ldr(q22, MemOperand(x17, 16, PostIndex));
5351 __ Ldr(q23, MemOperand(x17, 16, PostIndex));
5352 __ Ldr(q24, MemOperand(x17, 16, PostIndex));
5353 __ Ldr(q25, MemOperand(x17));
5354 END();
5355
5356 RUN();
5357
5358 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q16);
5359 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q17);
5360 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q18);
5361 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q19);
5362 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q20);
5363 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q21);
5364 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q22);
5365 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q23);
5366 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q24);
5367 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323130, q25);
5368
5369 TEARDOWN();
5370}
5371
5372
5373TEST(neon_st1_q_postindex) {
5374 SETUP();
5375
5376 uint8_t src[64 + 160];
5377 for (unsigned i = 0; i < sizeof(src); i++) {
5378 src[i] = i;
5379 }
5380 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5381
5382 START();
5383 __ Mov(x17, src_base);
5384 __ Mov(x18, -16);
5385 __ Mov(x19, -32);
5386 __ Mov(x20, -48);
5387 __ Mov(x21, -64);
5388 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5389 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5390 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5391 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5392
5393 __ St1(v0.V16B(), MemOperand(x17, 16, PostIndex));
5394 __ Ldr(q16, MemOperand(x17, x18));
5395
5396 __ St1(v0.V8H(), v1.V8H(), MemOperand(x17, 32, PostIndex));
5397 __ Ldr(q17, MemOperand(x17, x19));
5398 __ Ldr(q18, MemOperand(x17, x18));
5399
5400 __ St1(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x17, 48, PostIndex));
5401 __ Ldr(q19, MemOperand(x17, x20));
5402 __ Ldr(q20, MemOperand(x17, x19));
5403 __ Ldr(q21, MemOperand(x17, x18));
5404
5405 __ St1(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(),
5406 MemOperand(x17, 64, PostIndex));
5407 __ Ldr(q22, MemOperand(x17, x21));
5408 __ Ldr(q23, MemOperand(x17, x20));
5409 __ Ldr(q24, MemOperand(x17, x19));
5410 __ Ldr(q25, MemOperand(x17, x18));
5411
5412 END();
5413
5414 RUN();
5415
5416 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q16);
5417 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q17);
5418 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q18);
5419 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q19);
5420 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q20);
5421 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q21);
5422 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q22);
5423 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q23);
5424 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q24);
5425 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323130, q25);
5426
5427 TEARDOWN();
5428}
5429
5430
5431TEST(neon_st2_d) {
5432 SETUP();
5433
5434 uint8_t src[4*16];
5435 for (unsigned i = 0; i < sizeof(src); i++) {
5436 src[i] = i;
5437 }
5438 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5439
5440 START();
5441 __ Mov(x17, src_base);
5442 __ Mov(x18, src_base);
5443 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5444 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5445
5446 __ St2(v0.V8B(), v1.V8B(), MemOperand(x18));
5447 __ Add(x18, x18, 22);
5448 __ St2(v0.V4H(), v1.V4H(), MemOperand(x18));
5449 __ Add(x18, x18, 11);
5450 __ St2(v0.V2S(), v1.V2S(), MemOperand(x18));
5451
5452 __ Mov(x19, src_base);
5453 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5454 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5455 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5456 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5457
5458 END();
5459
5460 RUN();
5461
5462 ASSERT_EQUAL_128(0x1707160615051404, 0x1303120211011000, q0);
5463 ASSERT_EQUAL_128(0x0504131203021110, 0x0100151413121110, q1);
5464 ASSERT_EQUAL_128(0x1615140706050413, 0x1211100302010014, q2);
5465 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323117, q3);
5466
5467 TEARDOWN();
5468}
5469
5470
5471TEST(neon_st2_d_postindex) {
5472 SETUP();
5473
5474 uint8_t src[4*16];
5475 for (unsigned i = 0; i < sizeof(src); i++) {
5476 src[i] = i;
5477 }
5478 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5479
5480 START();
5481 __ Mov(x22, 5);
5482 __ Mov(x17, src_base);
5483 __ Mov(x18, src_base);
5484 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5485 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5486
5487 __ St2(v0.V8B(), v1.V8B(), MemOperand(x18, x22, PostIndex));
5488 __ St2(v0.V4H(), v1.V4H(), MemOperand(x18, 16, PostIndex));
5489 __ St2(v0.V2S(), v1.V2S(), MemOperand(x18));
5490
5491
5492 __ Mov(x19, src_base);
5493 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5494 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5495 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5496
5497 END();
5498
5499 RUN();
5500
5501 ASSERT_EQUAL_128(0x1405041312030211, 0x1001000211011000, q0);
5502 ASSERT_EQUAL_128(0x0605041312111003, 0x0201001716070615, q1);
5503 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726251716151407, q2);
5504
5505 TEARDOWN();
5506}
5507
5508
5509TEST(neon_st2_q) {
5510 SETUP();
5511
5512 uint8_t src[5*16];
5513 for (unsigned i = 0; i < sizeof(src); i++) {
5514 src[i] = i;
5515 }
5516 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5517
5518 START();
5519 __ Mov(x17, src_base);
5520 __ Mov(x18, src_base);
5521 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5522 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5523
5524 __ St2(v0.V16B(), v1.V16B(), MemOperand(x18));
5525 __ Add(x18, x18, 8);
5526 __ St2(v0.V8H(), v1.V8H(), MemOperand(x18));
5527 __ Add(x18, x18, 22);
5528 __ St2(v0.V4S(), v1.V4S(), MemOperand(x18));
5529 __ Add(x18, x18, 2);
5530 __ St2(v0.V2D(), v1.V2D(), MemOperand(x18));
5531
5532 __ Mov(x19, src_base);
5533 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5534 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5535 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5536 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5537
5538 END();
5539
5540 RUN();
5541
5542 ASSERT_EQUAL_128(0x1312030211100100, 0x1303120211011000, q0);
5543 ASSERT_EQUAL_128(0x01000b0a19180908, 0x1716070615140504, q1);
5544 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q2);
5545 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0f0e0d0c0b0a0908, q3);
5546 TEARDOWN();
5547}
5548
5549
5550TEST(neon_st2_q_postindex) {
5551 SETUP();
5552
5553 uint8_t src[5*16];
5554 for (unsigned i = 0; i < sizeof(src); i++) {
5555 src[i] = i;
5556 }
5557 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5558
5559 START();
5560 __ Mov(x22, 5);
5561 __ Mov(x17, src_base);
5562 __ Mov(x18, src_base);
5563 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5564 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5565
5566 __ St2(v0.V16B(), v1.V16B(), MemOperand(x18, x22, PostIndex));
5567 __ St2(v0.V8H(), v1.V8H(), MemOperand(x18, 32, PostIndex));
5568 __ St2(v0.V4S(), v1.V4S(), MemOperand(x18, x22, PostIndex));
5569 __ St2(v0.V2D(), v1.V2D(), MemOperand(x18));
5570
5571 __ Mov(x19, src_base);
5572 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5573 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5574 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5575 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5576 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5577
5578 END();
5579
5580 RUN();
5581
5582 ASSERT_EQUAL_128(0x1405041312030211, 0x1001000211011000, q0);
5583 ASSERT_EQUAL_128(0x1c0d0c1b1a0b0a19, 0x1809081716070615, q1);
5584 ASSERT_EQUAL_128(0x0504030201001003, 0x0201001f1e0f0e1d, q2);
5585 ASSERT_EQUAL_128(0x0d0c0b0a09081716, 0x1514131211100706, q3);
5586 ASSERT_EQUAL_128(0x4f4e4d4c4b4a1f1e, 0x1d1c1b1a19180f0e, q4);
5587
5588 TEARDOWN();
5589}
5590
5591
5592TEST(neon_st3_d) {
5593 SETUP();
5594
5595 uint8_t src[3*16];
5596 for (unsigned i = 0; i < sizeof(src); i++) {
5597 src[i] = i;
5598 }
5599 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5600
5601 START();
5602 __ Mov(x17, src_base);
5603 __ Mov(x18, src_base);
5604 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5605 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5606 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5607
5608 __ St3(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x18));
5609 __ Add(x18, x18, 3);
5610 __ St3(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x18));
5611 __ Add(x18, x18, 2);
5612 __ St3(v0.V2S(), v1.V2S(), v2.V2S(), MemOperand(x18));
5613
5614
5615 __ Mov(x19, src_base);
5616 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5617 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5618
5619 END();
5620
5621 RUN();
5622
5623 ASSERT_EQUAL_128(0x2221201312111003, 0x0201000100201000, q0);
5624 ASSERT_EQUAL_128(0x1f1e1d2726252417, 0x1615140706050423, q1);
5625
5626 TEARDOWN();
5627}
5628
5629
5630TEST(neon_st3_d_postindex) {
5631 SETUP();
5632
5633 uint8_t src[4*16];
5634 for (unsigned i = 0; i < sizeof(src); i++) {
5635 src[i] = i;
5636 }
5637 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5638
5639 START();
5640 __ Mov(x22, 5);
5641 __ Mov(x17, src_base);
5642 __ Mov(x18, src_base);
5643 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5644 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5645 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5646
5647 __ St3(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x18, x22, PostIndex));
5648 __ St3(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x18, 24, PostIndex));
5649 __ St3(v0.V2S(), v1.V2S(), v2.V2S(), MemOperand(x18));
5650
5651
5652 __ Mov(x19, src_base);
5653 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5654 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5655 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5656 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5657
5658 END();
5659
5660 RUN();
5661
5662 ASSERT_EQUAL_128(0x2213120302212011, 0x1001001101201000, q0);
5663 ASSERT_EQUAL_128(0x0201002726171607, 0x0625241514050423, q1);
5664 ASSERT_EQUAL_128(0x1615140706050423, 0x2221201312111003, q2);
5665 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736352726252417, q3);
5666
5667 TEARDOWN();
5668}
5669
5670
5671TEST(neon_st3_q) {
5672 SETUP();
5673
5674 uint8_t src[6*16];
5675 for (unsigned i = 0; i < sizeof(src); i++) {
5676 src[i] = i;
5677 }
5678 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5679
5680 START();
5681 __ Mov(x17, src_base);
5682 __ Mov(x18, src_base);
5683 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5684 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5685 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5686
5687 __ St3(v0.V16B(), v1.V16B(), v2.V16B(), MemOperand(x18));
5688 __ Add(x18, x18, 5);
5689 __ St3(v0.V8H(), v1.V8H(), v2.V8H(), MemOperand(x18));
5690 __ Add(x18, x18, 12);
5691 __ St3(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x18));
5692 __ Add(x18, x18, 22);
5693 __ St3(v0.V2D(), v1.V2D(), v2.V2D(), MemOperand(x18));
5694
5695 __ Mov(x19, src_base);
5696 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5697 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5698 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5699 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5700 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5701 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5702
5703 END();
5704
5705 RUN();
5706
5707 ASSERT_EQUAL_128(0x2213120302212011, 0x1001001101201000, q0);
5708 ASSERT_EQUAL_128(0x0605042322212013, 0x1211100302010023, q1);
5709 ASSERT_EQUAL_128(0x1007060504030201, 0x0025241716151407, q2);
5710 ASSERT_EQUAL_128(0x0827262524232221, 0x2017161514131211, q3);
5711 ASSERT_EQUAL_128(0x281f1e1d1c1b1a19, 0x180f0e0d0c0b0a09, q4);
5712 ASSERT_EQUAL_128(0x5f5e5d5c5b5a5958, 0x572f2e2d2c2b2a29, q5);
5713
5714 TEARDOWN();
5715}
5716
5717
5718TEST(neon_st3_q_postindex) {
5719 SETUP();
5720
5721 uint8_t src[7*16];
5722 for (unsigned i = 0; i < sizeof(src); i++) {
5723 src[i] = i;
5724 }
5725 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5726
5727 START();
5728 __ Mov(x22, 5);
5729 __ Mov(x17, src_base);
5730 __ Mov(x18, src_base);
5731 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5732 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5733 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5734
5735 __ St3(v0.V16B(), v1.V16B(), v2.V16B(), MemOperand(x18, x22, PostIndex));
5736 __ St3(v0.V8H(), v1.V8H(), v2.V8H(), MemOperand(x18, 48, PostIndex));
5737 __ St3(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x18, x22, PostIndex));
5738 __ St3(v0.V2D(), v1.V2D(), v2.V2D(), MemOperand(x18));
5739
5740 __ Mov(x19, src_base);
5741 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5742 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5743 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5744 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5745 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5746 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5747 __ Ldr(q6, MemOperand(x19, 16, PostIndex));
5748
5749 END();
5750
5751 RUN();
5752
5753 ASSERT_EQUAL_128(0x2213120302212011, 0x1001001101201000, q0);
5754 ASSERT_EQUAL_128(0x1809082726171607, 0x0625241514050423, q1);
5755 ASSERT_EQUAL_128(0x0e2d2c1d1c0d0c2b, 0x2a1b1a0b0a292819, q2);
5756 ASSERT_EQUAL_128(0x0504030201001003, 0x0201002f2e1f1e0f, q3);
5757 ASSERT_EQUAL_128(0x2524232221201716, 0x1514131211100706, q4);
5758 ASSERT_EQUAL_128(0x1d1c1b1a19180f0e, 0x0d0c0b0a09082726, q5);
5759 ASSERT_EQUAL_128(0x6f6e6d6c6b6a2f2e, 0x2d2c2b2a29281f1e, q6);
5760
5761 TEARDOWN();
5762}
5763
5764
5765TEST(neon_st4_d) {
5766 SETUP();
5767
5768 uint8_t src[4*16];
5769 for (unsigned i = 0; i < sizeof(src); i++) {
5770 src[i] = i;
5771 }
5772 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5773
5774 START();
5775 __ Mov(x17, src_base);
5776 __ Mov(x18, src_base);
5777 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5778 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5779 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5780 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5781
5782 __ St4(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(), MemOperand(x18));
5783 __ Add(x18, x18, 12);
5784 __ St4(v0.V4H(), v1.V4H(), v2.V4H(), v3.V4H(), MemOperand(x18));
5785 __ Add(x18, x18, 15);
5786 __ St4(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(), MemOperand(x18));
5787
5788
5789 __ Mov(x19, src_base);
5790 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5791 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5792 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5793 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5794
5795 END();
5796
5797 RUN();
5798
5799 ASSERT_EQUAL_128(0x1110010032221202, 0X3121110130201000, q0);
5800 ASSERT_EQUAL_128(0x1003020100322322, 0X1312030231302120, q1);
5801 ASSERT_EQUAL_128(0x1407060504333231, 0X3023222120131211, q2);
5802 ASSERT_EQUAL_128(0x3f3e3d3c3b373635, 0x3427262524171615, q3);
5803
5804 TEARDOWN();
5805}
5806
5807
5808TEST(neon_st4_d_postindex) {
5809 SETUP();
5810
5811 uint8_t src[5*16];
5812 for (unsigned i = 0; i < sizeof(src); i++) {
5813 src[i] = i;
5814 }
5815 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5816
5817 START();
5818 __ Mov(x22, 5);
5819 __ Mov(x17, src_base);
5820 __ Mov(x18, src_base);
5821 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5822 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5823 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5824 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5825
5826 __ St4(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(),
5827 MemOperand(x18, x22, PostIndex));
5828 __ St4(v0.V4H(), v1.V4H(), v2.V4H(), v3.V4H(),
5829 MemOperand(x18, 32, PostIndex));
5830 __ St4(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(),
5831 MemOperand(x18));
5832
5833
5834 __ Mov(x19, src_base);
5835 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5836 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5837 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5838 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5839 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5840
5841 END();
5842
5843 RUN();
5844
5845 ASSERT_EQUAL_128(0x1203023130212011, 0x1001000130201000, q0);
5846 ASSERT_EQUAL_128(0x1607063534252415, 0x1405043332232213, q1);
5847 ASSERT_EQUAL_128(0x2221201312111003, 0x0201003736272617, q2);
5848 ASSERT_EQUAL_128(0x2625241716151407, 0x0605043332313023, q3);
5849 ASSERT_EQUAL_128(0x4f4e4d4c4b4a4948, 0x4746453736353427, q4);
5850
5851 TEARDOWN();
5852}
5853
5854
5855TEST(neon_st4_q) {
5856 SETUP();
5857
5858 uint8_t src[7*16];
5859 for (unsigned i = 0; i < sizeof(src); i++) {
5860 src[i] = i;
5861 }
5862 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5863
5864 START();
5865 __ Mov(x17, src_base);
5866 __ Mov(x18, src_base);
5867 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5868 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5869 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5870 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5871
5872 __ St4(v0.V16B(), v1.V16B(), v2.V16B(), v3.V16B(), MemOperand(x18));
5873 __ Add(x18, x18, 5);
5874 __ St4(v0.V8H(), v1.V8H(), v2.V8H(), v3.V8H(), MemOperand(x18));
5875 __ Add(x18, x18, 12);
5876 __ St4(v0.V4S(), v1.V4S(), v2.V4S(), v3.V4S(), MemOperand(x18));
5877 __ Add(x18, x18, 22);
5878 __ St4(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(), MemOperand(x18));
5879 __ Add(x18, x18, 10);
5880
5881 __ Mov(x19, src_base);
5882 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5883 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5884 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5885 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5886 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5887 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5888 __ Ldr(q6, MemOperand(x19, 16, PostIndex));
5889
5890 END();
5891
5892 RUN();
5893
5894 ASSERT_EQUAL_128(0x1203023130212011, 0x1001000130201000, q0);
5895 ASSERT_EQUAL_128(0x3231302322212013, 0x1211100302010013, q1);
5896 ASSERT_EQUAL_128(0x1007060504030201, 0x0015140706050433, q2);
5897 ASSERT_EQUAL_128(0x3027262524232221, 0x2017161514131211, q3);
5898 ASSERT_EQUAL_128(0x180f0e0d0c0b0a09, 0x0837363534333231, q4);
5899 ASSERT_EQUAL_128(0x382f2e2d2c2b2a29, 0x281f1e1d1c1b1a19, q5);
5900 ASSERT_EQUAL_128(0x6f6e6d6c6b6a6968, 0x673f3e3d3c3b3a39, q6);
5901
5902 TEARDOWN();
5903}
5904
5905
5906TEST(neon_st4_q_postindex) {
5907 SETUP();
5908
5909 uint8_t src[9*16];
5910 for (unsigned i = 0; i < sizeof(src); i++) {
5911 src[i] = i;
5912 }
5913 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5914
5915 START();
5916 __ Mov(x22, 5);
5917 __ Mov(x17, src_base);
5918 __ Mov(x18, src_base);
5919 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5920 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5921 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5922 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5923
5924 __ St4(v0.V16B(), v1.V16B(), v2.V16B(), v3.V16B(),
5925 MemOperand(x18, x22, PostIndex));
5926 __ St4(v0.V8H(), v1.V8H(), v2.V8H(), v3.V8H(),
5927 MemOperand(x18, 64, PostIndex));
5928 __ St4(v0.V4S(), v1.V4S(), v2.V4S(), v3.V4S(),
5929 MemOperand(x18, x22, PostIndex));
5930 __ St4(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(),
5931 MemOperand(x18));
5932
5933 __ Mov(x19, src_base);
5934 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5935 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5936 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5937 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5938 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5939 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5940 __ Ldr(q6, MemOperand(x19, 16, PostIndex));
5941 __ Ldr(q7, MemOperand(x19, 16, PostIndex));
5942 __ Ldr(q8, MemOperand(x19, 16, PostIndex));
5943
5944 END();
5945
5946 RUN();
5947
5948 ASSERT_EQUAL_128(0x1203023130212011, 0x1001000130201000, q0);
5949 ASSERT_EQUAL_128(0x1607063534252415, 0x1405043332232213, q1);
5950 ASSERT_EQUAL_128(0x1a0b0a3938292819, 0x1809083736272617, q2);
5951 ASSERT_EQUAL_128(0x1e0f0e3d3c2d2c1d, 0x1c0d0c3b3a2b2a1b, q3);
5952 ASSERT_EQUAL_128(0x0504030201001003, 0x0201003f3e2f2e1f, q4);
5953 ASSERT_EQUAL_128(0x2524232221201716, 0x1514131211100706, q5);
5954 ASSERT_EQUAL_128(0x0d0c0b0a09083736, 0x3534333231302726, q6);
5955 ASSERT_EQUAL_128(0x2d2c2b2a29281f1e, 0x1d1c1b1a19180f0e, q7);
5956 ASSERT_EQUAL_128(0x8f8e8d8c8b8a3f3e, 0x3d3c3b3a39382f2e, q8);
5957
5958 TEARDOWN();
5959}
5960
5961
armvixlad96eda2013-06-14 11:42:37 +01005962TEST(ldp_stp_float) {
5963 SETUP();
5964
5965 float src[2] = {1.0, 2.0};
5966 float dst[3] = {0.0, 0.0, 0.0};
5967 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5968 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
5969
5970 START();
5971 __ Mov(x16, src_base);
5972 __ Mov(x17, dst_base);
5973 __ Ldp(s31, s0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
5974 __ Stp(s0, s31, MemOperand(x17, sizeof(dst[1]), PreIndex));
5975 END();
5976
5977 RUN();
5978
5979 ASSERT_EQUAL_FP32(1.0, s31);
5980 ASSERT_EQUAL_FP32(2.0, s0);
5981 ASSERT_EQUAL_FP32(0.0, dst[0]);
5982 ASSERT_EQUAL_FP32(2.0, dst[1]);
5983 ASSERT_EQUAL_FP32(1.0, dst[2]);
5984 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
5985 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
5986
5987 TEARDOWN();
5988}
5989
5990
5991TEST(ldp_stp_double) {
5992 SETUP();
5993
5994 double src[2] = {1.0, 2.0};
5995 double dst[3] = {0.0, 0.0, 0.0};
5996 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5997 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
5998
5999 START();
6000 __ Mov(x16, src_base);
6001 __ Mov(x17, dst_base);
6002 __ Ldp(d31, d0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
6003 __ Stp(d0, d31, MemOperand(x17, sizeof(dst[1]), PreIndex));
6004 END();
6005
6006 RUN();
6007
6008 ASSERT_EQUAL_FP64(1.0, d31);
6009 ASSERT_EQUAL_FP64(2.0, d0);
6010 ASSERT_EQUAL_FP64(0.0, dst[0]);
6011 ASSERT_EQUAL_FP64(2.0, dst[1]);
6012 ASSERT_EQUAL_FP64(1.0, dst[2]);
6013 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
6014 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
6015
6016 TEARDOWN();
6017}
6018
6019
armvixl5289c592015-03-02 13:52:04 +00006020TEST(ldp_stp_quad) {
6021 SETUP();
6022
6023 uint64_t src[4] = {0x0123456789abcdef, 0xaaaaaaaa55555555,
6024 0xfedcba9876543210, 0x55555555aaaaaaaa};
6025 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
6026 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6027 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6028
6029 START();
6030 __ Mov(x16, src_base);
6031 __ Mov(x17, dst_base);
6032 __ Ldp(q31, q0, MemOperand(x16, 4 * sizeof(src[0]), PostIndex));
6033 __ Stp(q0, q31, MemOperand(x17, 2 * sizeof(dst[1]), PreIndex));
6034 END();
6035
6036 RUN();
6037
6038 ASSERT_EQUAL_128(0xaaaaaaaa55555555, 0x0123456789abcdef, q31);
6039 ASSERT_EQUAL_128(0x55555555aaaaaaaa, 0xfedcba9876543210, q0);
6040 ASSERT_EQUAL_64(0, dst[0]);
6041 ASSERT_EQUAL_64(0, dst[1]);
6042 ASSERT_EQUAL_64(0xfedcba9876543210, dst[2]);
6043 ASSERT_EQUAL_64(0x55555555aaaaaaaa, dst[3]);
6044 ASSERT_EQUAL_64(0x0123456789abcdef, dst[4]);
6045 ASSERT_EQUAL_64(0xaaaaaaaa55555555, dst[5]);
6046 ASSERT_EQUAL_64(src_base + 4 * sizeof(src[0]), x16);
6047 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[1]), x17);
6048
6049 TEARDOWN();
6050}
6051
6052
armvixlad96eda2013-06-14 11:42:37 +01006053TEST(ldp_stp_offset) {
6054 SETUP();
6055
armvixlb0c8ae22014-03-21 14:03:59 +00006056 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6057 0xffeeddccbbaa9988};
armvixlad96eda2013-06-14 11:42:37 +01006058 uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
6059 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6060 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6061
6062 START();
6063 __ Mov(x16, src_base);
6064 __ Mov(x17, dst_base);
6065 __ Mov(x18, src_base + 24);
6066 __ Mov(x19, dst_base + 56);
6067 __ Ldp(w0, w1, MemOperand(x16));
6068 __ Ldp(w2, w3, MemOperand(x16, 4));
6069 __ Ldp(x4, x5, MemOperand(x16, 8));
6070 __ Ldp(w6, w7, MemOperand(x18, -12));
6071 __ Ldp(x8, x9, MemOperand(x18, -16));
6072 __ Stp(w0, w1, MemOperand(x17));
6073 __ Stp(w2, w3, MemOperand(x17, 8));
6074 __ Stp(x4, x5, MemOperand(x17, 16));
6075 __ Stp(w6, w7, MemOperand(x19, -24));
6076 __ Stp(x8, x9, MemOperand(x19, -16));
6077 END();
6078
6079 RUN();
6080
6081 ASSERT_EQUAL_64(0x44556677, x0);
6082 ASSERT_EQUAL_64(0x00112233, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00006083 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
armvixlad96eda2013-06-14 11:42:37 +01006084 ASSERT_EQUAL_64(0x00112233, x2);
6085 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006086 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
6087 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6088 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
6089 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6090 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01006091 ASSERT_EQUAL_64(0x8899aabb, x6);
6092 ASSERT_EQUAL_64(0xbbaa9988, x7);
armvixlb0c8ae22014-03-21 14:03:59 +00006093 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
6094 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
6095 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
6096 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
6097 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
armvixlad96eda2013-06-14 11:42:37 +01006098 ASSERT_EQUAL_64(src_base, x16);
6099 ASSERT_EQUAL_64(dst_base, x17);
6100 ASSERT_EQUAL_64(src_base + 24, x18);
6101 ASSERT_EQUAL_64(dst_base + 56, x19);
6102
6103 TEARDOWN();
6104}
6105
6106
armvixlc68cb642014-09-25 18:49:30 +01006107TEST(ldp_stp_offset_wide) {
6108 SETUP();
6109
6110 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6111 0xffeeddccbbaa9988};
6112 uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
6113 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6114 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6115 // Move base too far from the array to force multiple instructions
6116 // to be emitted.
6117 const int64_t base_offset = 1024;
6118
6119 START();
6120 __ Mov(x20, src_base - base_offset);
6121 __ Mov(x21, dst_base - base_offset);
6122 __ Mov(x18, src_base + base_offset + 24);
6123 __ Mov(x19, dst_base + base_offset + 56);
6124 __ Ldp(w0, w1, MemOperand(x20, base_offset));
6125 __ Ldp(w2, w3, MemOperand(x20, base_offset + 4));
6126 __ Ldp(x4, x5, MemOperand(x20, base_offset + 8));
6127 __ Ldp(w6, w7, MemOperand(x18, -12 - base_offset));
6128 __ Ldp(x8, x9, MemOperand(x18, -16 - base_offset));
6129 __ Stp(w0, w1, MemOperand(x21, base_offset));
6130 __ Stp(w2, w3, MemOperand(x21, base_offset + 8));
6131 __ Stp(x4, x5, MemOperand(x21, base_offset + 16));
6132 __ Stp(w6, w7, MemOperand(x19, -24 - base_offset));
6133 __ Stp(x8, x9, MemOperand(x19, -16 - base_offset));
6134 END();
6135
6136 RUN();
6137
6138 ASSERT_EQUAL_64(0x44556677, x0);
6139 ASSERT_EQUAL_64(0x00112233, x1);
6140 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
6141 ASSERT_EQUAL_64(0x00112233, x2);
6142 ASSERT_EQUAL_64(0xccddeeff, x3);
6143 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
6144 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6145 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
6146 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6147 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
6148 ASSERT_EQUAL_64(0x8899aabb, x6);
6149 ASSERT_EQUAL_64(0xbbaa9988, x7);
6150 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
6151 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
6152 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
6153 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
6154 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
6155 ASSERT_EQUAL_64(src_base - base_offset, x20);
6156 ASSERT_EQUAL_64(dst_base - base_offset, x21);
6157 ASSERT_EQUAL_64(src_base + base_offset + 24, x18);
6158 ASSERT_EQUAL_64(dst_base + base_offset + 56, x19);
6159
6160 TEARDOWN();
6161}
6162
6163
armvixlad96eda2013-06-14 11:42:37 +01006164TEST(ldnp_stnp_offset) {
6165 SETUP();
6166
armvixl5289c592015-03-02 13:52:04 +00006167 uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
6168 0xffeeddccbbaa9988, 0x7766554433221100};
6169 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 +01006170 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6171 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6172
6173 START();
6174 __ Mov(x16, src_base);
6175 __ Mov(x17, dst_base);
6176 __ Mov(x18, src_base + 24);
armvixl5289c592015-03-02 13:52:04 +00006177 __ Mov(x19, dst_base + 64);
6178 __ Mov(x20, src_base + 32);
6179
6180 // Ensure address set up has happened before executing non-temporal ops.
6181 __ Dmb(InnerShareable, BarrierAll);
6182
armvixlad96eda2013-06-14 11:42:37 +01006183 __ Ldnp(w0, w1, MemOperand(x16));
6184 __ Ldnp(w2, w3, MemOperand(x16, 4));
6185 __ Ldnp(x4, x5, MemOperand(x16, 8));
6186 __ Ldnp(w6, w7, MemOperand(x18, -12));
6187 __ Ldnp(x8, x9, MemOperand(x18, -16));
armvixl5289c592015-03-02 13:52:04 +00006188 __ Ldnp(q16, q17, MemOperand(x16));
6189 __ Ldnp(q19, q18, MemOperand(x20, -32));
armvixlad96eda2013-06-14 11:42:37 +01006190 __ Stnp(w0, w1, MemOperand(x17));
6191 __ Stnp(w2, w3, MemOperand(x17, 8));
6192 __ Stnp(x4, x5, MemOperand(x17, 16));
armvixl5289c592015-03-02 13:52:04 +00006193 __ Stnp(w6, w7, MemOperand(x19, -32));
6194 __ Stnp(x8, x9, MemOperand(x19, -24));
6195 __ Stnp(q17, q16, MemOperand(x19));
6196 __ Stnp(q18, q19, MemOperand(x19, 32));
armvixlad96eda2013-06-14 11:42:37 +01006197 END();
6198
6199 RUN();
6200
6201 ASSERT_EQUAL_64(0x44556677, x0);
6202 ASSERT_EQUAL_64(0x00112233, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00006203 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
armvixlad96eda2013-06-14 11:42:37 +01006204 ASSERT_EQUAL_64(0x00112233, x2);
6205 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006206 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
6207 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6208 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
6209 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6210 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01006211 ASSERT_EQUAL_64(0x8899aabb, x6);
6212 ASSERT_EQUAL_64(0xbbaa9988, x7);
armvixlb0c8ae22014-03-21 14:03:59 +00006213 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
6214 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
6215 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
6216 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
6217 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
armvixl5289c592015-03-02 13:52:04 +00006218 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x0011223344556677, q16);
6219 ASSERT_EQUAL_128(0x7766554433221100, 0xffeeddccbbaa9988, q17);
6220 ASSERT_EQUAL_128(0x7766554433221100, 0xffeeddccbbaa9988, q18);
6221 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x0011223344556677, q19);
6222 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[8]);
6223 ASSERT_EQUAL_64(0x7766554433221100, dst[9]);
6224 ASSERT_EQUAL_64(0x0011223344556677, dst[10]);
6225 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[11]);
6226 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[12]);
6227 ASSERT_EQUAL_64(0x7766554433221100, dst[13]);
6228 ASSERT_EQUAL_64(0x0011223344556677, dst[14]);
6229 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[15]);
armvixlad96eda2013-06-14 11:42:37 +01006230 ASSERT_EQUAL_64(src_base, x16);
6231 ASSERT_EQUAL_64(dst_base, x17);
6232 ASSERT_EQUAL_64(src_base + 24, x18);
armvixl5289c592015-03-02 13:52:04 +00006233 ASSERT_EQUAL_64(dst_base + 64, x19);
6234 ASSERT_EQUAL_64(src_base + 32, x20);
6235
6236 TEARDOWN();
6237}
6238
6239
6240TEST(ldnp_stnp_offset_float) {
6241 SETUP();
6242
6243 float src[3] = {1.2, 2.3, 3.4};
6244 float dst[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6245 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6246 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6247
6248 START();
6249 __ Mov(x16, src_base);
6250 __ Mov(x17, dst_base);
6251 __ Mov(x18, src_base + 12);
6252 __ Mov(x19, dst_base + 24);
6253
6254 // Ensure address set up has happened before executing non-temporal ops.
6255 __ Dmb(InnerShareable, BarrierAll);
6256
6257 __ Ldnp(s0, s1, MemOperand(x16));
6258 __ Ldnp(s2, s3, MemOperand(x16, 4));
6259 __ Ldnp(s5, s4, MemOperand(x18, -8));
6260 __ Stnp(s1, s0, MemOperand(x17));
6261 __ Stnp(s3, s2, MemOperand(x17, 8));
6262 __ Stnp(s4, s5, MemOperand(x19, -8));
6263 END();
6264
6265 RUN();
6266
6267 ASSERT_EQUAL_FP32(1.2, s0);
6268 ASSERT_EQUAL_FP32(2.3, s1);
6269 ASSERT_EQUAL_FP32(2.3, dst[0]);
6270 ASSERT_EQUAL_FP32(1.2, dst[1]);
6271 ASSERT_EQUAL_FP32(2.3, s2);
6272 ASSERT_EQUAL_FP32(3.4, s3);
6273 ASSERT_EQUAL_FP32(3.4, dst[2]);
6274 ASSERT_EQUAL_FP32(2.3, dst[3]);
6275 ASSERT_EQUAL_FP32(3.4, s4);
6276 ASSERT_EQUAL_FP32(2.3, s5);
6277 ASSERT_EQUAL_FP32(3.4, dst[4]);
6278 ASSERT_EQUAL_FP32(2.3, dst[5]);
6279 ASSERT_EQUAL_64(src_base, x16);
6280 ASSERT_EQUAL_64(dst_base, x17);
6281 ASSERT_EQUAL_64(src_base + 12, x18);
6282 ASSERT_EQUAL_64(dst_base + 24, x19);
6283
6284 TEARDOWN();
6285}
6286
6287
6288TEST(ldnp_stnp_offset_double) {
6289 SETUP();
6290
6291 double src[3] = {1.2, 2.3, 3.4};
6292 double dst[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6293 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6294 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6295
6296 START();
6297 __ Mov(x16, src_base);
6298 __ Mov(x17, dst_base);
6299 __ Mov(x18, src_base + 24);
6300 __ Mov(x19, dst_base + 48);
6301
6302 // Ensure address set up has happened before executing non-temporal ops.
6303 __ Dmb(InnerShareable, BarrierAll);
6304
6305 __ Ldnp(d0, d1, MemOperand(x16));
6306 __ Ldnp(d2, d3, MemOperand(x16, 8));
6307 __ Ldnp(d5, d4, MemOperand(x18, -16));
6308 __ Stnp(d1, d0, MemOperand(x17));
6309 __ Stnp(d3, d2, MemOperand(x17, 16));
6310 __ Stnp(d4, d5, MemOperand(x19, -16));
6311 END();
6312
6313 RUN();
6314
6315 ASSERT_EQUAL_FP64(1.2, d0);
6316 ASSERT_EQUAL_FP64(2.3, d1);
6317 ASSERT_EQUAL_FP64(2.3, dst[0]);
6318 ASSERT_EQUAL_FP64(1.2, dst[1]);
6319 ASSERT_EQUAL_FP64(2.3, d2);
6320 ASSERT_EQUAL_FP64(3.4, d3);
6321 ASSERT_EQUAL_FP64(3.4, dst[2]);
6322 ASSERT_EQUAL_FP64(2.3, dst[3]);
6323 ASSERT_EQUAL_FP64(3.4, d4);
6324 ASSERT_EQUAL_FP64(2.3, d5);
6325 ASSERT_EQUAL_FP64(3.4, dst[4]);
6326 ASSERT_EQUAL_FP64(2.3, dst[5]);
6327 ASSERT_EQUAL_64(src_base, x16);
6328 ASSERT_EQUAL_64(dst_base, x17);
6329 ASSERT_EQUAL_64(src_base + 24, x18);
6330 ASSERT_EQUAL_64(dst_base + 48, x19);
armvixlad96eda2013-06-14 11:42:37 +01006331
6332 TEARDOWN();
6333}
6334
6335
6336TEST(ldp_stp_preindex) {
6337 SETUP();
6338
armvixlb0c8ae22014-03-21 14:03:59 +00006339 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6340 0xffeeddccbbaa9988};
armvixlad96eda2013-06-14 11:42:37 +01006341 uint64_t dst[5] = {0, 0, 0, 0, 0};
6342 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6343 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6344
6345 START();
6346 __ Mov(x16, src_base);
6347 __ Mov(x17, dst_base);
6348 __ Mov(x18, dst_base + 16);
6349 __ Ldp(w0, w1, MemOperand(x16, 4, PreIndex));
6350 __ Mov(x19, x16);
6351 __ Ldp(w2, w3, MemOperand(x16, -4, PreIndex));
6352 __ Stp(w2, w3, MemOperand(x17, 4, PreIndex));
6353 __ Mov(x20, x17);
6354 __ Stp(w0, w1, MemOperand(x17, -4, PreIndex));
6355 __ Ldp(x4, x5, MemOperand(x16, 8, PreIndex));
6356 __ Mov(x21, x16);
6357 __ Ldp(x6, x7, MemOperand(x16, -8, PreIndex));
6358 __ Stp(x7, x6, MemOperand(x18, 8, PreIndex));
6359 __ Mov(x22, x18);
6360 __ Stp(x5, x4, MemOperand(x18, -8, PreIndex));
6361 END();
6362
6363 RUN();
6364
6365 ASSERT_EQUAL_64(0x00112233, x0);
6366 ASSERT_EQUAL_64(0xccddeeff, x1);
6367 ASSERT_EQUAL_64(0x44556677, x2);
6368 ASSERT_EQUAL_64(0x00112233, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006369 ASSERT_EQUAL_64(0xccddeeff00112233, dst[0]);
6370 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6371 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6372 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6373 ASSERT_EQUAL_64(0x0011223344556677, x6);
6374 ASSERT_EQUAL_64(0x8899aabbccddeeff, x7);
6375 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6376 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6377 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01006378 ASSERT_EQUAL_64(src_base, x16);
6379 ASSERT_EQUAL_64(dst_base, x17);
6380 ASSERT_EQUAL_64(dst_base + 16, x18);
6381 ASSERT_EQUAL_64(src_base + 4, x19);
6382 ASSERT_EQUAL_64(dst_base + 4, x20);
6383 ASSERT_EQUAL_64(src_base + 8, x21);
6384 ASSERT_EQUAL_64(dst_base + 24, x22);
6385
6386 TEARDOWN();
6387}
6388
6389
armvixlc68cb642014-09-25 18:49:30 +01006390TEST(ldp_stp_preindex_wide) {
6391 SETUP();
6392
6393 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6394 0xffeeddccbbaa9988};
6395 uint64_t dst[5] = {0, 0, 0, 0, 0};
6396 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6397 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6398 // Move base too far from the array to force multiple instructions
6399 // to be emitted.
6400 const int64_t base_offset = 1024;
6401
6402 START();
6403 __ Mov(x24, src_base - base_offset);
6404 __ Mov(x25, dst_base + base_offset);
6405 __ Mov(x18, dst_base + base_offset + 16);
6406 __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PreIndex));
6407 __ Mov(x19, x24);
6408 __ Mov(x24, src_base - base_offset + 4);
6409 __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PreIndex));
6410 __ Stp(w2, w3, MemOperand(x25, 4 - base_offset , PreIndex));
6411 __ Mov(x20, x25);
6412 __ Mov(x25, dst_base + base_offset + 4);
6413 __ Mov(x24, src_base - base_offset);
6414 __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PreIndex));
6415 __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PreIndex));
6416 __ Mov(x21, x24);
6417 __ Mov(x24, src_base - base_offset + 8);
6418 __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PreIndex));
6419 __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PreIndex));
6420 __ Mov(x22, x18);
6421 __ Mov(x18, dst_base + base_offset + 16 + 8);
6422 __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PreIndex));
6423 END();
6424
6425 RUN();
6426
6427 ASSERT_EQUAL_64(0x00112233, x0);
6428 ASSERT_EQUAL_64(0xccddeeff, x1);
6429 ASSERT_EQUAL_64(0x44556677, x2);
6430 ASSERT_EQUAL_64(0x00112233, x3);
6431 ASSERT_EQUAL_64(0xccddeeff00112233, dst[0]);
6432 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6433 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6434 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6435 ASSERT_EQUAL_64(0x0011223344556677, x6);
6436 ASSERT_EQUAL_64(0x8899aabbccddeeff, x7);
6437 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6438 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6439 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
6440 ASSERT_EQUAL_64(src_base, x24);
6441 ASSERT_EQUAL_64(dst_base, x25);
6442 ASSERT_EQUAL_64(dst_base + 16, x18);
6443 ASSERT_EQUAL_64(src_base + 4, x19);
6444 ASSERT_EQUAL_64(dst_base + 4, x20);
6445 ASSERT_EQUAL_64(src_base + 8, x21);
6446 ASSERT_EQUAL_64(dst_base + 24, x22);
6447
6448 TEARDOWN();
6449}
6450
6451
armvixlad96eda2013-06-14 11:42:37 +01006452TEST(ldp_stp_postindex) {
6453 SETUP();
6454
armvixlb0c8ae22014-03-21 14:03:59 +00006455 uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
6456 0xffeeddccbbaa9988, 0x7766554433221100};
armvixlad96eda2013-06-14 11:42:37 +01006457 uint64_t dst[5] = {0, 0, 0, 0, 0};
6458 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6459 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6460
6461 START();
6462 __ Mov(x16, src_base);
6463 __ Mov(x17, dst_base);
6464 __ Mov(x18, dst_base + 16);
6465 __ Ldp(w0, w1, MemOperand(x16, 4, PostIndex));
6466 __ Mov(x19, x16);
6467 __ Ldp(w2, w3, MemOperand(x16, -4, PostIndex));
6468 __ Stp(w2, w3, MemOperand(x17, 4, PostIndex));
6469 __ Mov(x20, x17);
6470 __ Stp(w0, w1, MemOperand(x17, -4, PostIndex));
6471 __ Ldp(x4, x5, MemOperand(x16, 8, PostIndex));
6472 __ Mov(x21, x16);
6473 __ Ldp(x6, x7, MemOperand(x16, -8, PostIndex));
6474 __ Stp(x7, x6, MemOperand(x18, 8, PostIndex));
6475 __ Mov(x22, x18);
6476 __ Stp(x5, x4, MemOperand(x18, -8, PostIndex));
6477 END();
6478
6479 RUN();
6480
6481 ASSERT_EQUAL_64(0x44556677, x0);
6482 ASSERT_EQUAL_64(0x00112233, x1);
6483 ASSERT_EQUAL_64(0x00112233, x2);
6484 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006485 ASSERT_EQUAL_64(0x4455667700112233, dst[0]);
6486 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6487 ASSERT_EQUAL_64(0x0011223344556677, x4);
6488 ASSERT_EQUAL_64(0x8899aabbccddeeff, x5);
6489 ASSERT_EQUAL_64(0x8899aabbccddeeff, x6);
6490 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x7);
6491 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6492 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6493 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01006494 ASSERT_EQUAL_64(src_base, x16);
6495 ASSERT_EQUAL_64(dst_base, x17);
6496 ASSERT_EQUAL_64(dst_base + 16, x18);
6497 ASSERT_EQUAL_64(src_base + 4, x19);
6498 ASSERT_EQUAL_64(dst_base + 4, x20);
6499 ASSERT_EQUAL_64(src_base + 8, x21);
6500 ASSERT_EQUAL_64(dst_base + 24, x22);
6501
6502 TEARDOWN();
6503}
6504
6505
armvixlc68cb642014-09-25 18:49:30 +01006506TEST(ldp_stp_postindex_wide) {
6507 SETUP();
6508
6509 uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
6510 0xffeeddccbbaa9988, 0x7766554433221100};
6511 uint64_t dst[5] = {0, 0, 0, 0, 0};
6512 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6513 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6514 // Move base too far from the array to force multiple instructions
6515 // to be emitted.
6516 const int64_t base_offset = 1024;
6517
6518 START();
6519 __ Mov(x24, src_base);
6520 __ Mov(x25, dst_base);
6521 __ Mov(x18, dst_base + 16);
6522 __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PostIndex));
6523 __ Mov(x19, x24);
6524 __ Sub(x24, x24, base_offset);
6525 __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PostIndex));
6526 __ Stp(w2, w3, MemOperand(x25, 4 - base_offset, PostIndex));
6527 __ Mov(x20, x25);
6528 __ Sub(x24, x24, base_offset);
6529 __ Add(x25, x25, base_offset);
6530 __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PostIndex));
6531 __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PostIndex));
6532 __ Mov(x21, x24);
6533 __ Sub(x24, x24, base_offset);
6534 __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PostIndex));
6535 __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PostIndex));
6536 __ Mov(x22, x18);
6537 __ Add(x18, x18, base_offset);
6538 __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PostIndex));
6539 END();
6540
6541 RUN();
6542
6543 ASSERT_EQUAL_64(0x44556677, x0);
6544 ASSERT_EQUAL_64(0x00112233, x1);
6545 ASSERT_EQUAL_64(0x00112233, x2);
6546 ASSERT_EQUAL_64(0xccddeeff, x3);
6547 ASSERT_EQUAL_64(0x4455667700112233, dst[0]);
6548 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6549 ASSERT_EQUAL_64(0x0011223344556677, x4);
6550 ASSERT_EQUAL_64(0x8899aabbccddeeff, x5);
6551 ASSERT_EQUAL_64(0x8899aabbccddeeff, x6);
6552 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x7);
6553 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6554 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6555 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
6556 ASSERT_EQUAL_64(src_base + base_offset, x24);
6557 ASSERT_EQUAL_64(dst_base - base_offset, x25);
6558 ASSERT_EQUAL_64(dst_base - base_offset + 16, x18);
6559 ASSERT_EQUAL_64(src_base + base_offset + 4, x19);
6560 ASSERT_EQUAL_64(dst_base - base_offset + 4, x20);
6561 ASSERT_EQUAL_64(src_base + base_offset + 8, x21);
6562 ASSERT_EQUAL_64(dst_base - base_offset + 24, x22);
6563
6564 TEARDOWN();
6565}
6566
6567
armvixlad96eda2013-06-14 11:42:37 +01006568TEST(ldp_sign_extend) {
6569 SETUP();
6570
6571 uint32_t src[2] = {0x80000000, 0x7fffffff};
6572 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6573
6574 START();
6575 __ Mov(x24, src_base);
6576 __ Ldpsw(x0, x1, MemOperand(x24));
6577 END();
6578
6579 RUN();
6580
armvixlb0c8ae22014-03-21 14:03:59 +00006581 ASSERT_EQUAL_64(0xffffffff80000000, x0);
6582 ASSERT_EQUAL_64(0x000000007fffffff, x1);
armvixlad96eda2013-06-14 11:42:37 +01006583
6584 TEARDOWN();
6585}
6586
6587
6588TEST(ldur_stur) {
6589 SETUP();
6590
armvixlb0c8ae22014-03-21 14:03:59 +00006591 int64_t src[2] = {0x0123456789abcdef, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01006592 int64_t dst[5] = {0, 0, 0, 0, 0};
6593 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6594 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6595
6596 START();
6597 __ Mov(x17, src_base);
6598 __ Mov(x18, dst_base);
6599 __ Mov(x19, src_base + 16);
6600 __ Mov(x20, dst_base + 32);
6601 __ Mov(x21, dst_base + 40);
6602 __ Ldr(w0, MemOperand(x17, 1));
6603 __ Str(w0, MemOperand(x18, 2));
6604 __ Ldr(x1, MemOperand(x17, 3));
6605 __ Str(x1, MemOperand(x18, 9));
6606 __ Ldr(w2, MemOperand(x19, -9));
6607 __ Str(w2, MemOperand(x20, -5));
6608 __ Ldrb(w3, MemOperand(x19, -1));
6609 __ Strb(w3, MemOperand(x21, -1));
6610 END();
6611
6612 RUN();
6613
6614 ASSERT_EQUAL_64(0x6789abcd, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00006615 ASSERT_EQUAL_64(0x00006789abcd0000, dst[0]);
6616 ASSERT_EQUAL_64(0xabcdef0123456789, x1);
6617 ASSERT_EQUAL_64(0xcdef012345678900, dst[1]);
armvixlad96eda2013-06-14 11:42:37 +01006618 ASSERT_EQUAL_64(0x000000ab, dst[2]);
6619 ASSERT_EQUAL_64(0xabcdef01, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00006620 ASSERT_EQUAL_64(0x00abcdef01000000, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01006621 ASSERT_EQUAL_64(0x00000001, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006622 ASSERT_EQUAL_64(0x0100000000000000, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01006623 ASSERT_EQUAL_64(src_base, x17);
6624 ASSERT_EQUAL_64(dst_base, x18);
6625 ASSERT_EQUAL_64(src_base + 16, x19);
6626 ASSERT_EQUAL_64(dst_base + 32, x20);
6627
6628 TEARDOWN();
6629}
6630
6631
armvixl5289c592015-03-02 13:52:04 +00006632TEST(ldur_stur_fp) {
6633 SETUP();
6634
6635 int64_t src[3] = {0x0123456789abcdef, 0x0123456789abcdef,
6636 0x0123456789abcdef};
6637 int64_t dst[5] = {0, 0, 0, 0, 0};
6638 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6639 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6640
6641 START();
6642 __ Mov(x17, src_base);
6643 __ Mov(x18, dst_base);
6644 __ Ldr(b0, MemOperand(x17));
6645 __ Str(b0, MemOperand(x18));
6646 __ Ldr(h1, MemOperand(x17, 1));
6647 __ Str(h1, MemOperand(x18, 1));
6648 __ Ldr(s2, MemOperand(x17, 2));
6649 __ Str(s2, MemOperand(x18, 3));
6650 __ Ldr(d3, MemOperand(x17, 3));
6651 __ Str(d3, MemOperand(x18, 7));
6652 __ Ldr(q4, MemOperand(x17, 4));
6653 __ Str(q4, MemOperand(x18, 15));
6654 END();
6655
6656 RUN();
6657
6658 ASSERT_EQUAL_128(0, 0xef, q0);
6659 ASSERT_EQUAL_128(0, 0xabcd, q1);
6660 ASSERT_EQUAL_128(0, 0x456789ab, q2);
6661 ASSERT_EQUAL_128(0, 0xabcdef0123456789, q3);
6662 ASSERT_EQUAL_128(0x89abcdef01234567, 0x89abcdef01234567, q4);
6663 ASSERT_EQUAL_64(0x89456789ababcdef, dst[0]);
6664 ASSERT_EQUAL_64(0x67abcdef01234567, dst[1]);
6665 ASSERT_EQUAL_64(0x6789abcdef012345, dst[2]);
6666 ASSERT_EQUAL_64(0x0089abcdef012345, dst[3]);
6667
6668 TEARDOWN();
6669}
6670
6671
armvixlad96eda2013-06-14 11:42:37 +01006672TEST(ldr_literal) {
6673 SETUP();
6674
6675 START();
armvixlb0c8ae22014-03-21 14:03:59 +00006676 __ Ldr(x2, 0x1234567890abcdef);
armvixlad96eda2013-06-14 11:42:37 +01006677 __ Ldr(w3, 0xfedcba09);
armvixlc68cb642014-09-25 18:49:30 +01006678 __ Ldrsw(x4, 0x7fffffff);
6679 __ Ldrsw(x5, 0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006680 __ Ldr(q11, 0x1234000056780000, 0xabcd0000ef000000);
armvixlad96eda2013-06-14 11:42:37 +01006681 __ Ldr(d13, 1.234);
6682 __ Ldr(s25, 2.5);
6683 END();
6684
6685 RUN();
6686
armvixlb0c8ae22014-03-21 14:03:59 +00006687 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
armvixlad96eda2013-06-14 11:42:37 +01006688 ASSERT_EQUAL_64(0xfedcba09, x3);
armvixlc68cb642014-09-25 18:49:30 +01006689 ASSERT_EQUAL_64(0x7fffffff, x4);
6690 ASSERT_EQUAL_64(0xffffffff80000000, x5);
armvixl5289c592015-03-02 13:52:04 +00006691 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
armvixlad96eda2013-06-14 11:42:37 +01006692 ASSERT_EQUAL_FP64(1.234, d13);
6693 ASSERT_EQUAL_FP32(2.5, s25);
6694
6695 TEARDOWN();
6696}
6697
6698
armvixlc68cb642014-09-25 18:49:30 +01006699TEST(ldr_literal_range) {
6700 SETUP();
armvixlad96eda2013-06-14 11:42:37 +01006701
6702 START();
armvixlc68cb642014-09-25 18:49:30 +01006703 // Make sure the pool is empty;
6704 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
armvixlad96eda2013-06-14 11:42:37 +01006705 ASSERT_LITERAL_POOL_SIZE(0);
6706
armvixlc68cb642014-09-25 18:49:30 +01006707 // Create some literal pool entries.
armvixlb0c8ae22014-03-21 14:03:59 +00006708 __ Ldr(x0, 0x1234567890abcdef);
armvixlad96eda2013-06-14 11:42:37 +01006709 __ Ldr(w1, 0xfedcba09);
armvixlc68cb642014-09-25 18:49:30 +01006710 __ Ldrsw(x2, 0x7fffffff);
6711 __ Ldrsw(x3, 0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006712 __ Ldr(q2, 0x1234000056780000, 0xabcd0000ef000000);
armvixlad96eda2013-06-14 11:42:37 +01006713 __ Ldr(d0, 1.234);
6714 __ Ldr(s1, 2.5);
armvixl5289c592015-03-02 13:52:04 +00006715 ASSERT_LITERAL_POOL_SIZE(48);
armvixlad96eda2013-06-14 11:42:37 +01006716
armvixlc68cb642014-09-25 18:49:30 +01006717 // Emit more code than the maximum literal load range to ensure the pool
6718 // should be emitted.
armvixl330dc712014-11-25 10:38:32 +00006719 const ptrdiff_t end = masm.CursorOffset() + 2 * kMaxLoadLiteralRange;
6720 while (masm.CursorOffset() < end) {
armvixlad96eda2013-06-14 11:42:37 +01006721 __ Nop();
armvixlad96eda2013-06-14 11:42:37 +01006722 }
6723
armvixlc68cb642014-09-25 18:49:30 +01006724 // The pool should have been emitted.
armvixlad96eda2013-06-14 11:42:37 +01006725 ASSERT_LITERAL_POOL_SIZE(0);
6726
6727 // These loads should be after the pool (and will require a new one).
armvixlb0c8ae22014-03-21 14:03:59 +00006728 __ Ldr(x4, 0x34567890abcdef12);
armvixlad96eda2013-06-14 11:42:37 +01006729 __ Ldr(w5, 0xdcba09fe);
armvixlc68cb642014-09-25 18:49:30 +01006730 __ Ldrsw(x6, 0x7fffffff);
6731 __ Ldrsw(x7, 0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006732 __ Ldr(q6, 0x1234000056780000, 0xabcd0000ef000000);
armvixlad96eda2013-06-14 11:42:37 +01006733 __ Ldr(d4, 123.4);
6734 __ Ldr(s5, 250.0);
armvixl5289c592015-03-02 13:52:04 +00006735 ASSERT_LITERAL_POOL_SIZE(48);
armvixlad96eda2013-06-14 11:42:37 +01006736 END();
6737
6738 RUN();
6739
6740 // Check that the literals loaded correctly.
armvixlb0c8ae22014-03-21 14:03:59 +00006741 ASSERT_EQUAL_64(0x1234567890abcdef, x0);
armvixlad96eda2013-06-14 11:42:37 +01006742 ASSERT_EQUAL_64(0xfedcba09, x1);
armvixlc68cb642014-09-25 18:49:30 +01006743 ASSERT_EQUAL_64(0x7fffffff, x2);
6744 ASSERT_EQUAL_64(0xffffffff80000000, x3);
armvixl5289c592015-03-02 13:52:04 +00006745 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q2);
armvixlad96eda2013-06-14 11:42:37 +01006746 ASSERT_EQUAL_FP64(1.234, d0);
6747 ASSERT_EQUAL_FP32(2.5, s1);
armvixlb0c8ae22014-03-21 14:03:59 +00006748 ASSERT_EQUAL_64(0x34567890abcdef12, x4);
armvixlad96eda2013-06-14 11:42:37 +01006749 ASSERT_EQUAL_64(0xdcba09fe, x5);
armvixlc68cb642014-09-25 18:49:30 +01006750 ASSERT_EQUAL_64(0x7fffffff, x6);
6751 ASSERT_EQUAL_64(0xffffffff80000000, x7);
armvixl5289c592015-03-02 13:52:04 +00006752 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q6);
armvixlad96eda2013-06-14 11:42:37 +01006753 ASSERT_EQUAL_FP64(123.4, d4);
6754 ASSERT_EQUAL_FP32(250.0, s5);
6755
6756 TEARDOWN();
6757}
6758
6759
armvixl5289c592015-03-02 13:52:04 +00006760TEST(ldr_literal_values_q) {
6761 SETUP();
6762
6763 static const uint64_t kHalfValues[] = {
6764 0x8000000000000000, 0x7fffffffffffffff, 0x0000000000000000,
6765 0xffffffffffffffff, 0x00ff00ff00ff00ff, 0x1234567890abcdef
6766 };
6767 const int card = sizeof(kHalfValues) / sizeof(kHalfValues[0]);
6768 const Register& ref_low64 = x1;
6769 const Register& ref_high64 = x2;
6770 const Register& loaded_low64 = x3;
6771 const Register& loaded_high64 = x4;
6772 const VRegister& tgt = q0;
6773
6774 START();
6775 __ Mov(x0, 0);
6776
6777 for (int i = 0; i < card; i++) {
6778 __ Mov(ref_low64, kHalfValues[i]);
6779 for (int j = 0; j < card; j++) {
6780 __ Mov(ref_high64, kHalfValues[j]);
6781 __ Ldr(tgt, kHalfValues[j], kHalfValues[i]);
6782 __ Mov(loaded_low64, tgt.V2D(), 0);
6783 __ Mov(loaded_high64, tgt.V2D(), 1);
6784 __ Cmp(loaded_low64, ref_low64);
6785 __ Ccmp(loaded_high64, ref_high64, NoFlag, eq);
6786 __ Cset(x0, ne);
6787 }
6788 }
6789 END();
6790
6791 RUN();
6792
6793 // If one of the values differs, the trace can be used to identify which one.
6794 ASSERT_EQUAL_64(0, x0);
6795
6796 TEARDOWN();
6797}
6798
6799
armvixlc68cb642014-09-25 18:49:30 +01006800template <typename T>
6801void LoadIntValueHelper(T values[], int card) {
6802 SETUP();
6803
6804 const bool is_32bits = (sizeof(T) == 4);
6805 const Register& tgt1 = is_32bits ? w1 : x1;
6806 const Register& tgt2 = is_32bits ? w2 : x2;
6807
6808 START();
6809 __ Mov(x0, 0);
6810
6811 // If one of the values differ then x0 will be one.
6812 for (int i = 0; i < card; ++i) {
6813 __ Mov(tgt1, values[i]);
6814 __ Ldr(tgt2, values[i]);
6815 __ Cmp(tgt1, tgt2);
6816 __ Cset(x0, ne);
6817 }
6818 END();
6819
6820 RUN();
6821
6822 // If one of the values differs, the trace can be used to identify which one.
6823 ASSERT_EQUAL_64(0, x0);
6824
6825 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +01006826}
6827
6828
armvixlc68cb642014-09-25 18:49:30 +01006829TEST(ldr_literal_values_x) {
6830 static const uint64_t kValues[] = {
6831 0x8000000000000000, 0x7fffffffffffffff, 0x0000000000000000,
6832 0xffffffffffffffff, 0x00ff00ff00ff00ff, 0x1234567890abcdef
6833 };
6834
6835 LoadIntValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006836}
6837
6838
armvixlc68cb642014-09-25 18:49:30 +01006839TEST(ldr_literal_values_w) {
6840 static const uint32_t kValues[] = {
6841 0x80000000, 0x7fffffff, 0x00000000, 0xffffffff, 0x00ff00ff, 0x12345678,
6842 0x90abcdef
6843 };
6844
6845 LoadIntValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006846}
6847
6848
armvixlc68cb642014-09-25 18:49:30 +01006849template <typename T>
6850void LoadFPValueHelper(T values[], int card) {
6851 SETUP();
6852
6853 const bool is_32bits = (sizeof(T) == 4);
6854 const FPRegister& fp_tgt = is_32bits ? s2 : d2;
6855 const Register& tgt1 = is_32bits ? w1 : x1;
6856 const Register& tgt2 = is_32bits ? w2 : x2;
6857
6858 START();
6859 __ Mov(x0, 0);
6860
6861 // If one of the values differ then x0 will be one.
6862 for (int i = 0; i < card; ++i) {
6863 __ Mov(tgt1, is_32bits ? float_to_rawbits(values[i])
6864 : double_to_rawbits(values[i]));
6865 __ Ldr(fp_tgt, values[i]);
6866 __ Fmov(tgt2, fp_tgt);
6867 __ Cmp(tgt1, tgt2);
6868 __ Cset(x0, ne);
6869 }
6870 END();
6871
6872 RUN();
6873
6874 // If one of the values differs, the trace can be used to identify which one.
6875 ASSERT_EQUAL_64(0, x0);
6876
6877 TEARDOWN();
6878}
6879
6880TEST(ldr_literal_values_d) {
6881 static const double kValues[] = {
6882 -0.0, 0.0, -1.0, 1.0, -1e10, 1e10
6883 };
6884
6885 LoadFPValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006886}
6887
6888
armvixlc68cb642014-09-25 18:49:30 +01006889TEST(ldr_literal_values_s) {
6890 static const float kValues[] = {
6891 -0.0, 0.0, -1.0, 1.0, -1e10, 1e10
6892 };
6893
6894 LoadFPValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006895}
6896
6897
armvixlc68cb642014-09-25 18:49:30 +01006898TEST(ldr_literal_custom) {
armvixlc68cb642014-09-25 18:49:30 +01006899 SETUP();
6900 ALLOW_ASM();
6901
armvixl330dc712014-11-25 10:38:32 +00006902 Label end_of_pool_before;
6903 Label end_of_pool_after;
6904 Literal<uint64_t> before_x(0x1234567890abcdef);
6905 Literal<uint32_t> before_w(0xfedcba09);
6906 Literal<uint32_t> before_sx(0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006907 Literal<uint64_t> before_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006908 Literal<double> before_d(1.234);
6909 Literal<float> before_s(2.5);
6910 Literal<uint64_t> after_x(0x1234567890abcdef);
6911 Literal<uint32_t> after_w(0xfedcba09);
6912 Literal<uint32_t> after_sx(0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006913 Literal<uint64_t> after_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006914 Literal<double> after_d(1.234);
6915 Literal<float> after_s(2.5);
armvixlc68cb642014-09-25 18:49:30 +01006916
6917 START();
armvixlc68cb642014-09-25 18:49:30 +01006918
armvixl330dc712014-11-25 10:38:32 +00006919 // Manually generate a pool.
6920 __ B(&end_of_pool_before);
6921 __ place(&before_x);
6922 __ place(&before_w);
6923 __ place(&before_sx);
armvixl5289c592015-03-02 13:52:04 +00006924 __ place(&before_q);
armvixl330dc712014-11-25 10:38:32 +00006925 __ place(&before_d);
6926 __ place(&before_s);
6927 __ Bind(&end_of_pool_before);
6928
6929 __ ldr(x2, &before_x);
6930 __ ldr(w3, &before_w);
6931 __ ldrsw(x5, &before_sx);
armvixl5289c592015-03-02 13:52:04 +00006932 __ ldr(q11, &before_q);
armvixl330dc712014-11-25 10:38:32 +00006933 __ ldr(d13, &before_d);
6934 __ ldr(s25, &before_s);
6935
6936 __ ldr(x6, &after_x);
6937 __ ldr(w7, &after_w);
6938 __ ldrsw(x8, &after_sx);
armvixl5289c592015-03-02 13:52:04 +00006939 __ ldr(q18, &after_q);
armvixl330dc712014-11-25 10:38:32 +00006940 __ ldr(d14, &after_d);
6941 __ ldr(s26, &after_s);
6942
6943 // Manually generate a pool.
6944 __ B(&end_of_pool_after);
6945 __ place(&after_x);
6946 __ place(&after_w);
6947 __ place(&after_sx);
armvixl5289c592015-03-02 13:52:04 +00006948 __ place(&after_q);
armvixl330dc712014-11-25 10:38:32 +00006949 __ place(&after_d);
6950 __ place(&after_s);
6951 __ Bind(&end_of_pool_after);
6952
armvixlc68cb642014-09-25 18:49:30 +01006953 END();
6954
6955 RUN();
6956
6957 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
6958 ASSERT_EQUAL_64(0xfedcba09, x3);
6959 ASSERT_EQUAL_64(0xffffffff80000000, x5);
armvixl5289c592015-03-02 13:52:04 +00006960 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
armvixlc68cb642014-09-25 18:49:30 +01006961 ASSERT_EQUAL_FP64(1.234, d13);
6962 ASSERT_EQUAL_FP32(2.5, s25);
6963
armvixl330dc712014-11-25 10:38:32 +00006964 ASSERT_EQUAL_64(0x1234567890abcdef, x6);
6965 ASSERT_EQUAL_64(0xfedcba09, x7);
6966 ASSERT_EQUAL_64(0xffffffff80000000, x8);
armvixl5289c592015-03-02 13:52:04 +00006967 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q18);
armvixl330dc712014-11-25 10:38:32 +00006968 ASSERT_EQUAL_FP64(1.234, d14);
6969 ASSERT_EQUAL_FP32(2.5, s26);
6970
6971 TEARDOWN();
6972}
6973
6974
6975TEST(ldr_literal_custom_shared) {
6976 SETUP();
6977 ALLOW_ASM();
6978
6979 Label end_of_pool_before;
6980 Label end_of_pool_after;
6981 Literal<uint64_t> before_x(0x1234567890abcdef);
6982 Literal<uint32_t> before_w(0xfedcba09);
armvixl5289c592015-03-02 13:52:04 +00006983 Literal<uint64_t> before_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006984 Literal<double> before_d(1.234);
6985 Literal<float> before_s(2.5);
6986 Literal<uint64_t> after_x(0x1234567890abcdef);
6987 Literal<uint32_t> after_w(0xfedcba09);
armvixl5289c592015-03-02 13:52:04 +00006988 Literal<uint64_t> after_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006989 Literal<double> after_d(1.234);
6990 Literal<float> after_s(2.5);
6991
6992 START();
6993
6994 // Manually generate a pool.
6995 __ B(&end_of_pool_before);
6996 __ place(&before_x);
6997 __ place(&before_w);
armvixl5289c592015-03-02 13:52:04 +00006998 __ place(&before_q);
armvixl330dc712014-11-25 10:38:32 +00006999 __ place(&before_d);
7000 __ place(&before_s);
7001 __ Bind(&end_of_pool_before);
7002
7003 // Load the entries several times to test that literals can be shared.
7004 for (int i = 0; i < 50; i++) {
7005 __ ldr(x2, &before_x);
7006 __ ldr(w3, &before_w);
7007 __ ldrsw(x5, &before_w); // Re-use before_w.
armvixl5289c592015-03-02 13:52:04 +00007008 __ ldr(q11, &before_q);
armvixl330dc712014-11-25 10:38:32 +00007009 __ ldr(d13, &before_d);
7010 __ ldr(s25, &before_s);
7011
7012 __ ldr(x6, &after_x);
7013 __ ldr(w7, &after_w);
7014 __ ldrsw(x8, &after_w); // Re-use after_w.
armvixl5289c592015-03-02 13:52:04 +00007015 __ ldr(q18, &after_q);
armvixl330dc712014-11-25 10:38:32 +00007016 __ ldr(d14, &after_d);
7017 __ ldr(s26, &after_s);
7018 }
7019
7020 // Manually generate a pool.
7021 __ B(&end_of_pool_after);
7022 __ place(&after_x);
7023 __ place(&after_w);
armvixl5289c592015-03-02 13:52:04 +00007024 __ place(&after_q);
armvixl330dc712014-11-25 10:38:32 +00007025 __ place(&after_d);
7026 __ place(&after_s);
7027 __ Bind(&end_of_pool_after);
7028
7029 END();
7030
7031 RUN();
7032
7033 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
7034 ASSERT_EQUAL_64(0xfedcba09, x3);
7035 ASSERT_EQUAL_64(0xfffffffffedcba09, x5);
armvixl5289c592015-03-02 13:52:04 +00007036 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
armvixl330dc712014-11-25 10:38:32 +00007037 ASSERT_EQUAL_FP64(1.234, d13);
7038 ASSERT_EQUAL_FP32(2.5, s25);
7039
7040 ASSERT_EQUAL_64(0x1234567890abcdef, x6);
7041 ASSERT_EQUAL_64(0xfedcba09, x7);
7042 ASSERT_EQUAL_64(0xfffffffffedcba09, x8);
armvixl5289c592015-03-02 13:52:04 +00007043 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q18);
armvixl330dc712014-11-25 10:38:32 +00007044 ASSERT_EQUAL_FP64(1.234, d14);
7045 ASSERT_EQUAL_FP32(2.5, s26);
7046
7047 TEARDOWN();
7048}
7049
7050
7051TEST(prfm_offset) {
7052 SETUP();
7053
7054 START();
7055 // The address used in prfm doesn't have to be valid.
7056 __ Mov(x0, 0x0123456789abcdef);
7057
7058 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7059 // Unallocated prefetch operations are ignored, so test all of them.
7060 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7061
7062 __ Prfm(op, MemOperand(x0));
7063 __ Prfm(op, MemOperand(x0, 8));
7064 __ Prfm(op, MemOperand(x0, 32760));
7065 __ Prfm(op, MemOperand(x0, 32768));
7066
7067 __ Prfm(op, MemOperand(x0, 1));
7068 __ Prfm(op, MemOperand(x0, 9));
7069 __ Prfm(op, MemOperand(x0, 255));
7070 __ Prfm(op, MemOperand(x0, 257));
7071 __ Prfm(op, MemOperand(x0, -1));
7072 __ Prfm(op, MemOperand(x0, -9));
7073 __ Prfm(op, MemOperand(x0, -255));
7074 __ Prfm(op, MemOperand(x0, -257));
7075
7076 __ Prfm(op, MemOperand(x0, 0xfedcba9876543210));
7077 }
7078
7079 END();
7080 RUN();
7081 TEARDOWN();
7082}
7083
7084
7085TEST(prfm_regoffset) {
7086 SETUP();
7087
7088 START();
7089 // The address used in prfm doesn't have to be valid.
7090 __ Mov(x0, 0x0123456789abcdef);
7091
7092 CPURegList inputs(CPURegister::kRegister, kXRegSize, 10, 18);
7093 __ Mov(x10, 0);
7094 __ Mov(x11, 1);
7095 __ Mov(x12, 8);
7096 __ Mov(x13, 255);
7097 __ Mov(x14, -0);
7098 __ Mov(x15, -1);
7099 __ Mov(x16, -8);
7100 __ Mov(x17, -255);
7101 __ Mov(x18, 0xfedcba9876543210);
7102
7103 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7104 // Unallocated prefetch operations are ignored, so test all of them.
7105 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7106
7107 CPURegList loop = inputs;
7108 while (!loop.IsEmpty()) {
7109 Register input(loop.PopLowestIndex());
7110 __ Prfm(op, MemOperand(x0, input));
7111 __ Prfm(op, MemOperand(x0, input, UXTW));
7112 __ Prfm(op, MemOperand(x0, input, UXTW, 3));
7113 __ Prfm(op, MemOperand(x0, input, LSL));
7114 __ Prfm(op, MemOperand(x0, input, LSL, 3));
7115 __ Prfm(op, MemOperand(x0, input, SXTW));
7116 __ Prfm(op, MemOperand(x0, input, SXTW, 3));
7117 __ Prfm(op, MemOperand(x0, input, SXTX));
7118 __ Prfm(op, MemOperand(x0, input, SXTX, 3));
7119 }
7120 }
7121
7122 END();
7123 RUN();
7124 TEARDOWN();
7125}
7126
7127
7128TEST(prfm_literal_imm19) {
7129 SETUP();
7130 ALLOW_ASM();
7131 START();
7132
7133 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7134 // Unallocated prefetch operations are ignored, so test all of them.
7135 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7136
7137 // The address used in prfm doesn't have to be valid.
7138 __ prfm(op, 0);
7139 __ prfm(op, 1);
7140 __ prfm(op, -1);
7141 __ prfm(op, 1000);
7142 __ prfm(op, -1000);
7143 __ prfm(op, 0x3ffff);
7144 __ prfm(op, -0x40000);
7145 }
7146
7147 END();
7148 RUN();
7149 TEARDOWN();
7150}
7151
7152
7153TEST(prfm_literal) {
7154 SETUP();
7155 ALLOW_ASM();
7156
7157 Label end_of_pool_before;
7158 Label end_of_pool_after;
7159 Literal<uint64_t> before(0);
7160 Literal<uint64_t> after(0);
7161
7162 START();
7163
7164 // Manually generate a pool.
7165 __ B(&end_of_pool_before);
7166 __ place(&before);
7167 __ Bind(&end_of_pool_before);
7168
7169 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7170 // Unallocated prefetch operations are ignored, so test all of them.
7171 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7172
7173 CodeBufferCheckScope guard(&masm, 2 * kInstructionSize);
7174 __ prfm(op, &before);
7175 __ prfm(op, &after);
7176 }
7177
7178 // Manually generate a pool.
7179 __ B(&end_of_pool_after);
7180 __ place(&after);
7181 __ Bind(&end_of_pool_after);
7182
7183 END();
7184 RUN();
7185 TEARDOWN();
7186}
7187
7188
7189TEST(prfm_wide) {
7190 SETUP();
7191
7192 START();
7193 // The address used in prfm doesn't have to be valid.
7194 __ Mov(x0, 0x0123456789abcdef);
7195
7196 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7197 // Unallocated prefetch operations are ignored, so test all of them.
7198 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7199
7200 __ Prfm(op, MemOperand(x0, 0x40000));
7201 __ Prfm(op, MemOperand(x0, -0x40001));
7202 __ Prfm(op, MemOperand(x0, UINT64_C(0x5555555555555555)));
7203 __ Prfm(op, MemOperand(x0, UINT64_C(0xfedcba9876543210)));
7204 }
7205
7206 END();
7207 RUN();
7208 TEARDOWN();
7209}
7210
7211
7212TEST(load_prfm_literal) {
7213 // Test literals shared between both prfm and ldr.
7214 SETUP();
7215 ALLOW_ASM();
7216
7217 Label end_of_pool_before;
7218 Label end_of_pool_after;
7219 Literal<uint64_t> before_x(0x1234567890abcdef);
7220 Literal<uint32_t> before_w(0xfedcba09);
7221 Literal<uint32_t> before_sx(0x80000000);
7222 Literal<double> before_d(1.234);
7223 Literal<float> before_s(2.5);
7224 Literal<uint64_t> after_x(0x1234567890abcdef);
7225 Literal<uint32_t> after_w(0xfedcba09);
7226 Literal<uint32_t> after_sx(0x80000000);
7227 Literal<double> after_d(1.234);
7228 Literal<float> after_s(2.5);
7229
7230 START();
7231
7232 // Manually generate a pool.
7233 __ B(&end_of_pool_before);
7234 __ place(&before_x);
7235 __ place(&before_w);
7236 __ place(&before_sx);
7237 __ place(&before_d);
7238 __ place(&before_s);
7239 __ Bind(&end_of_pool_before);
7240
7241 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7242 // Unallocated prefetch operations are ignored, so test all of them.
7243 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7244
7245 __ prfm(op, &before_x);
7246 __ prfm(op, &before_w);
7247 __ prfm(op, &before_sx);
7248 __ prfm(op, &before_d);
7249 __ prfm(op, &before_s);
7250
7251 __ prfm(op, &after_x);
7252 __ prfm(op, &after_w);
7253 __ prfm(op, &after_sx);
7254 __ prfm(op, &after_d);
7255 __ prfm(op, &after_s);
7256 }
7257
7258 __ ldr(x2, &before_x);
7259 __ ldr(w3, &before_w);
7260 __ ldrsw(x5, &before_sx);
7261 __ ldr(d13, &before_d);
7262 __ ldr(s25, &before_s);
7263
7264 __ ldr(x6, &after_x);
7265 __ ldr(w7, &after_w);
7266 __ ldrsw(x8, &after_sx);
7267 __ ldr(d14, &after_d);
7268 __ ldr(s26, &after_s);
7269
7270 // Manually generate a pool.
7271 __ B(&end_of_pool_after);
7272 __ place(&after_x);
7273 __ place(&after_w);
7274 __ place(&after_sx);
7275 __ place(&after_d);
7276 __ place(&after_s);
7277 __ Bind(&end_of_pool_after);
7278
7279 END();
7280
7281 RUN();
7282
7283 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
7284 ASSERT_EQUAL_64(0xfedcba09, x3);
7285 ASSERT_EQUAL_64(0xffffffff80000000, x5);
7286 ASSERT_EQUAL_FP64(1.234, d13);
7287 ASSERT_EQUAL_FP32(2.5, s25);
7288
7289 ASSERT_EQUAL_64(0x1234567890abcdef, x6);
7290 ASSERT_EQUAL_64(0xfedcba09, x7);
7291 ASSERT_EQUAL_64(0xffffffff80000000, x8);
7292 ASSERT_EQUAL_FP64(1.234, d14);
7293 ASSERT_EQUAL_FP32(2.5, s26);
7294
armvixlc68cb642014-09-25 18:49:30 +01007295 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +01007296}
7297
7298
7299TEST(add_sub_imm) {
7300 SETUP();
7301
7302 START();
7303 __ Mov(x0, 0x0);
7304 __ Mov(x1, 0x1111);
armvixlb0c8ae22014-03-21 14:03:59 +00007305 __ Mov(x2, 0xffffffffffffffff);
7306 __ Mov(x3, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01007307
7308 __ Add(x10, x0, Operand(0x123));
7309 __ Add(x11, x1, Operand(0x122000));
7310 __ Add(x12, x0, Operand(0xabc << 12));
7311 __ Add(x13, x2, Operand(1));
7312
7313 __ Add(w14, w0, Operand(0x123));
7314 __ Add(w15, w1, Operand(0x122000));
7315 __ Add(w16, w0, Operand(0xabc << 12));
7316 __ Add(w17, w2, Operand(1));
7317
7318 __ Sub(x20, x0, Operand(0x1));
7319 __ Sub(x21, x1, Operand(0x111));
7320 __ Sub(x22, x1, Operand(0x1 << 12));
7321 __ Sub(x23, x3, Operand(1));
7322
7323 __ Sub(w24, w0, Operand(0x1));
7324 __ Sub(w25, w1, Operand(0x111));
7325 __ Sub(w26, w1, Operand(0x1 << 12));
7326 __ Sub(w27, w3, Operand(1));
7327 END();
7328
7329 RUN();
7330
7331 ASSERT_EQUAL_64(0x123, x10);
7332 ASSERT_EQUAL_64(0x123111, x11);
7333 ASSERT_EQUAL_64(0xabc000, x12);
7334 ASSERT_EQUAL_64(0x0, x13);
7335
7336 ASSERT_EQUAL_32(0x123, w14);
7337 ASSERT_EQUAL_32(0x123111, w15);
7338 ASSERT_EQUAL_32(0xabc000, w16);
7339 ASSERT_EQUAL_32(0x0, w17);
7340
armvixlb0c8ae22014-03-21 14:03:59 +00007341 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlad96eda2013-06-14 11:42:37 +01007342 ASSERT_EQUAL_64(0x1000, x21);
7343 ASSERT_EQUAL_64(0x111, x22);
armvixlb0c8ae22014-03-21 14:03:59 +00007344 ASSERT_EQUAL_64(0x7fffffffffffffff, x23);
armvixlad96eda2013-06-14 11:42:37 +01007345
7346 ASSERT_EQUAL_32(0xffffffff, w24);
7347 ASSERT_EQUAL_32(0x1000, w25);
7348 ASSERT_EQUAL_32(0x111, w26);
7349 ASSERT_EQUAL_32(0xffffffff, w27);
7350
7351 TEARDOWN();
7352}
7353
7354
7355TEST(add_sub_wide_imm) {
7356 SETUP();
7357
7358 START();
7359 __ Mov(x0, 0x0);
7360 __ Mov(x1, 0x1);
7361
armvixlb0c8ae22014-03-21 14:03:59 +00007362 __ Add(x10, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01007363 __ Add(x11, x1, Operand(0xffffffff));
7364
7365 __ Add(w12, w0, Operand(0x12345678));
7366 __ Add(w13, w1, Operand(0xffffffff));
7367
armvixl4a102ba2014-07-14 09:02:40 +01007368 __ Add(w18, w0, Operand(kWMinInt));
7369 __ Sub(w19, w0, Operand(kWMinInt));
armvixlad96eda2013-06-14 11:42:37 +01007370
armvixl4a102ba2014-07-14 09:02:40 +01007371 __ Sub(x20, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01007372 __ Sub(w21, w0, Operand(0x12345678));
armvixl4a102ba2014-07-14 09:02:40 +01007373
armvixlad96eda2013-06-14 11:42:37 +01007374 END();
7375
7376 RUN();
7377
armvixlb0c8ae22014-03-21 14:03:59 +00007378 ASSERT_EQUAL_64(0x1234567890abcdef, x10);
7379 ASSERT_EQUAL_64(0x100000000, x11);
armvixlad96eda2013-06-14 11:42:37 +01007380
7381 ASSERT_EQUAL_32(0x12345678, w12);
7382 ASSERT_EQUAL_64(0x0, x13);
7383
armvixl4a102ba2014-07-14 09:02:40 +01007384 ASSERT_EQUAL_32(kWMinInt, w18);
7385 ASSERT_EQUAL_32(kWMinInt, w19);
armvixlad96eda2013-06-14 11:42:37 +01007386
armvixl4a102ba2014-07-14 09:02:40 +01007387 ASSERT_EQUAL_64(-0x1234567890abcdef, x20);
armvixlad96eda2013-06-14 11:42:37 +01007388 ASSERT_EQUAL_32(-0x12345678, w21);
7389
7390 TEARDOWN();
7391}
7392
7393
7394TEST(add_sub_shifted) {
7395 SETUP();
7396
7397 START();
7398 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00007399 __ Mov(x1, 0x0123456789abcdef);
7400 __ Mov(x2, 0xfedcba9876543210);
7401 __ Mov(x3, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007402
7403 __ Add(x10, x1, Operand(x2));
7404 __ Add(x11, x0, Operand(x1, LSL, 8));
7405 __ Add(x12, x0, Operand(x1, LSR, 8));
7406 __ Add(x13, x0, Operand(x1, ASR, 8));
7407 __ Add(x14, x0, Operand(x2, ASR, 8));
7408 __ Add(w15, w0, Operand(w1, ASR, 8));
7409 __ Add(w18, w3, Operand(w1, ROR, 8));
7410 __ Add(x19, x3, Operand(x1, ROR, 8));
7411
7412 __ Sub(x20, x3, Operand(x2));
7413 __ Sub(x21, x3, Operand(x1, LSL, 8));
7414 __ Sub(x22, x3, Operand(x1, LSR, 8));
7415 __ Sub(x23, x3, Operand(x1, ASR, 8));
7416 __ Sub(x24, x3, Operand(x2, ASR, 8));
7417 __ Sub(w25, w3, Operand(w1, ASR, 8));
7418 __ Sub(w26, w3, Operand(w1, ROR, 8));
7419 __ Sub(x27, x3, Operand(x1, ROR, 8));
7420 END();
7421
7422 RUN();
7423
armvixlb0c8ae22014-03-21 14:03:59 +00007424 ASSERT_EQUAL_64(0xffffffffffffffff, x10);
7425 ASSERT_EQUAL_64(0x23456789abcdef00, x11);
7426 ASSERT_EQUAL_64(0x000123456789abcd, x12);
7427 ASSERT_EQUAL_64(0x000123456789abcd, x13);
7428 ASSERT_EQUAL_64(0xfffedcba98765432, x14);
armvixlad96eda2013-06-14 11:42:37 +01007429 ASSERT_EQUAL_64(0xff89abcd, x15);
7430 ASSERT_EQUAL_64(0xef89abcc, x18);
armvixlb0c8ae22014-03-21 14:03:59 +00007431 ASSERT_EQUAL_64(0xef0123456789abcc, x19);
armvixlad96eda2013-06-14 11:42:37 +01007432
armvixlb0c8ae22014-03-21 14:03:59 +00007433 ASSERT_EQUAL_64(0x0123456789abcdef, x20);
7434 ASSERT_EQUAL_64(0xdcba9876543210ff, x21);
7435 ASSERT_EQUAL_64(0xfffedcba98765432, x22);
7436 ASSERT_EQUAL_64(0xfffedcba98765432, x23);
7437 ASSERT_EQUAL_64(0x000123456789abcd, x24);
armvixlad96eda2013-06-14 11:42:37 +01007438 ASSERT_EQUAL_64(0x00765432, x25);
7439 ASSERT_EQUAL_64(0x10765432, x26);
armvixlb0c8ae22014-03-21 14:03:59 +00007440 ASSERT_EQUAL_64(0x10fedcba98765432, x27);
armvixlad96eda2013-06-14 11:42:37 +01007441
7442 TEARDOWN();
7443}
7444
7445
7446TEST(add_sub_extended) {
7447 SETUP();
7448
7449 START();
7450 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00007451 __ Mov(x1, 0x0123456789abcdef);
7452 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01007453 __ Mov(w3, 0x80);
7454
7455 __ Add(x10, x0, Operand(x1, UXTB, 0));
7456 __ Add(x11, x0, Operand(x1, UXTB, 1));
7457 __ Add(x12, x0, Operand(x1, UXTH, 2));
7458 __ Add(x13, x0, Operand(x1, UXTW, 4));
7459
7460 __ Add(x14, x0, Operand(x1, SXTB, 0));
7461 __ Add(x15, x0, Operand(x1, SXTB, 1));
7462 __ Add(x16, x0, Operand(x1, SXTH, 2));
7463 __ Add(x17, x0, Operand(x1, SXTW, 3));
7464 __ Add(x18, x0, Operand(x2, SXTB, 0));
7465 __ Add(x19, x0, Operand(x2, SXTB, 1));
7466 __ Add(x20, x0, Operand(x2, SXTH, 2));
7467 __ Add(x21, x0, Operand(x2, SXTW, 3));
7468
7469 __ Add(x22, x1, Operand(x2, SXTB, 1));
7470 __ Sub(x23, x1, Operand(x2, SXTB, 1));
7471
7472 __ Add(w24, w1, Operand(w2, UXTB, 2));
7473 __ Add(w25, w0, Operand(w1, SXTB, 0));
7474 __ Add(w26, w0, Operand(w1, SXTB, 1));
7475 __ Add(w27, w2, Operand(w1, SXTW, 3));
7476
7477 __ Add(w28, w0, Operand(w1, SXTW, 3));
7478 __ Add(x29, x0, Operand(w1, SXTW, 3));
7479
7480 __ Sub(x30, x0, Operand(w3, SXTB, 1));
7481 END();
7482
7483 RUN();
7484
armvixlb0c8ae22014-03-21 14:03:59 +00007485 ASSERT_EQUAL_64(0xef, x10);
7486 ASSERT_EQUAL_64(0x1de, x11);
7487 ASSERT_EQUAL_64(0x337bc, x12);
7488 ASSERT_EQUAL_64(0x89abcdef0, x13);
armvixlad96eda2013-06-14 11:42:37 +01007489
armvixlb0c8ae22014-03-21 14:03:59 +00007490 ASSERT_EQUAL_64(0xffffffffffffffef, x14);
7491 ASSERT_EQUAL_64(0xffffffffffffffde, x15);
7492 ASSERT_EQUAL_64(0xffffffffffff37bc, x16);
7493 ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x17);
7494 ASSERT_EQUAL_64(0x10, x18);
7495 ASSERT_EQUAL_64(0x20, x19);
7496 ASSERT_EQUAL_64(0xc840, x20);
7497 ASSERT_EQUAL_64(0x3b2a19080, x21);
armvixlad96eda2013-06-14 11:42:37 +01007498
armvixlb0c8ae22014-03-21 14:03:59 +00007499 ASSERT_EQUAL_64(0x0123456789abce0f, x22);
7500 ASSERT_EQUAL_64(0x0123456789abcdcf, x23);
armvixlad96eda2013-06-14 11:42:37 +01007501
7502 ASSERT_EQUAL_32(0x89abce2f, w24);
7503 ASSERT_EQUAL_32(0xffffffef, w25);
7504 ASSERT_EQUAL_32(0xffffffde, w26);
7505 ASSERT_EQUAL_32(0xc3b2a188, w27);
7506
7507 ASSERT_EQUAL_32(0x4d5e6f78, w28);
armvixlb0c8ae22014-03-21 14:03:59 +00007508 ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x29);
armvixlad96eda2013-06-14 11:42:37 +01007509
7510 ASSERT_EQUAL_64(256, x30);
7511
7512 TEARDOWN();
7513}
7514
7515
7516TEST(add_sub_negative) {
7517 SETUP();
7518
7519 START();
7520 __ Mov(x0, 0);
7521 __ Mov(x1, 4687);
7522 __ Mov(x2, 0x1122334455667788);
7523 __ Mov(w3, 0x11223344);
7524 __ Mov(w4, 400000);
7525
7526 __ Add(x10, x0, -42);
7527 __ Add(x11, x1, -687);
7528 __ Add(x12, x2, -0x88);
7529
7530 __ Sub(x13, x0, -600);
7531 __ Sub(x14, x1, -313);
7532 __ Sub(x15, x2, -0x555);
7533
7534 __ Add(w19, w3, -0x344);
7535 __ Add(w20, w4, -2000);
7536
7537 __ Sub(w21, w3, -0xbc);
7538 __ Sub(w22, w4, -2000);
7539 END();
7540
7541 RUN();
7542
7543 ASSERT_EQUAL_64(-42, x10);
7544 ASSERT_EQUAL_64(4000, x11);
7545 ASSERT_EQUAL_64(0x1122334455667700, x12);
7546
7547 ASSERT_EQUAL_64(600, x13);
7548 ASSERT_EQUAL_64(5000, x14);
7549 ASSERT_EQUAL_64(0x1122334455667cdd, x15);
7550
7551 ASSERT_EQUAL_32(0x11223000, w19);
7552 ASSERT_EQUAL_32(398000, w20);
7553
7554 ASSERT_EQUAL_32(0x11223400, w21);
7555 ASSERT_EQUAL_32(402000, w22);
7556
7557 TEARDOWN();
7558}
7559
7560
armvixlf37fdc02014-02-05 13:22:16 +00007561TEST(add_sub_zero) {
7562 SETUP();
7563
7564 START();
7565 __ Mov(x0, 0);
7566 __ Mov(x1, 0);
7567 __ Mov(x2, 0);
7568
7569 Label blob1;
7570 __ Bind(&blob1);
7571 __ Add(x0, x0, 0);
7572 __ Sub(x1, x1, 0);
7573 __ Sub(x2, x2, xzr);
armvixlb0c8ae22014-03-21 14:03:59 +00007574 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob1) == 0);
armvixlf37fdc02014-02-05 13:22:16 +00007575
7576 Label blob2;
7577 __ Bind(&blob2);
7578 __ Add(w3, w3, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00007579 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob2) != 0);
armvixlf37fdc02014-02-05 13:22:16 +00007580
7581 Label blob3;
7582 __ Bind(&blob3);
7583 __ Sub(w3, w3, wzr);
armvixlb0c8ae22014-03-21 14:03:59 +00007584 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob3) != 0);
armvixlf37fdc02014-02-05 13:22:16 +00007585
7586 END();
7587
7588 RUN();
7589
7590 ASSERT_EQUAL_64(0, x0);
7591 ASSERT_EQUAL_64(0, x1);
7592 ASSERT_EQUAL_64(0, x2);
7593
7594 TEARDOWN();
7595}
7596
7597
7598TEST(claim_drop_zero) {
7599 SETUP();
7600
7601 START();
7602
7603 Label start;
7604 __ Bind(&start);
7605 __ Claim(Operand(0));
7606 __ Drop(Operand(0));
7607 __ Claim(Operand(xzr));
7608 __ Drop(Operand(xzr));
armvixlb0c8ae22014-03-21 14:03:59 +00007609 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlf37fdc02014-02-05 13:22:16 +00007610
7611 END();
7612
7613 RUN();
7614
7615 TEARDOWN();
7616}
7617
7618
armvixlad96eda2013-06-14 11:42:37 +01007619TEST(neg) {
7620 SETUP();
7621
7622 START();
armvixlb0c8ae22014-03-21 14:03:59 +00007623 __ Mov(x0, 0xf123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01007624
7625 // Immediate.
7626 __ Neg(x1, 0x123);
7627 __ Neg(w2, 0x123);
7628
7629 // Shifted.
7630 __ Neg(x3, Operand(x0, LSL, 1));
7631 __ Neg(w4, Operand(w0, LSL, 2));
7632 __ Neg(x5, Operand(x0, LSR, 3));
7633 __ Neg(w6, Operand(w0, LSR, 4));
7634 __ Neg(x7, Operand(x0, ASR, 5));
7635 __ Neg(w8, Operand(w0, ASR, 6));
7636
7637 // Extended.
7638 __ Neg(w9, Operand(w0, UXTB));
7639 __ Neg(x10, Operand(x0, SXTB, 1));
7640 __ Neg(w11, Operand(w0, UXTH, 2));
7641 __ Neg(x12, Operand(x0, SXTH, 3));
7642 __ Neg(w13, Operand(w0, UXTW, 4));
7643 __ Neg(x14, Operand(x0, SXTW, 4));
7644 END();
7645
7646 RUN();
7647
armvixlb0c8ae22014-03-21 14:03:59 +00007648 ASSERT_EQUAL_64(0xfffffffffffffedd, x1);
armvixlad96eda2013-06-14 11:42:37 +01007649 ASSERT_EQUAL_64(0xfffffedd, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00007650 ASSERT_EQUAL_64(0x1db97530eca86422, x3);
armvixlad96eda2013-06-14 11:42:37 +01007651 ASSERT_EQUAL_64(0xd950c844, x4);
armvixlb0c8ae22014-03-21 14:03:59 +00007652 ASSERT_EQUAL_64(0xe1db97530eca8643, x5);
armvixlad96eda2013-06-14 11:42:37 +01007653 ASSERT_EQUAL_64(0xf7654322, x6);
armvixlb0c8ae22014-03-21 14:03:59 +00007654 ASSERT_EQUAL_64(0x0076e5d4c3b2a191, x7);
armvixlad96eda2013-06-14 11:42:37 +01007655 ASSERT_EQUAL_64(0x01d950c9, x8);
7656 ASSERT_EQUAL_64(0xffffff11, x9);
armvixlb0c8ae22014-03-21 14:03:59 +00007657 ASSERT_EQUAL_64(0x0000000000000022, x10);
armvixlad96eda2013-06-14 11:42:37 +01007658 ASSERT_EQUAL_64(0xfffcc844, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00007659 ASSERT_EQUAL_64(0x0000000000019088, x12);
armvixlad96eda2013-06-14 11:42:37 +01007660 ASSERT_EQUAL_64(0x65432110, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00007661 ASSERT_EQUAL_64(0x0000000765432110, x14);
armvixlad96eda2013-06-14 11:42:37 +01007662
7663 TEARDOWN();
7664}
7665
7666
7667TEST(adc_sbc_shift) {
7668 SETUP();
7669
7670 START();
7671 __ Mov(x0, 0);
7672 __ Mov(x1, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00007673 __ Mov(x2, 0x0123456789abcdef);
7674 __ Mov(x3, 0xfedcba9876543210);
7675 __ Mov(x4, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007676
7677 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007678 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01007679
7680 __ Adc(x5, x2, Operand(x3));
7681 __ Adc(x6, x0, Operand(x1, LSL, 60));
7682 __ Sbc(x7, x4, Operand(x3, LSR, 4));
7683 __ Adc(x8, x2, Operand(x3, ASR, 4));
7684 __ Adc(x9, x2, Operand(x3, ROR, 8));
7685
7686 __ Adc(w10, w2, Operand(w3));
7687 __ Adc(w11, w0, Operand(w1, LSL, 30));
7688 __ Sbc(w12, w4, Operand(w3, LSR, 4));
7689 __ Adc(w13, w2, Operand(w3, ASR, 4));
7690 __ Adc(w14, w2, Operand(w3, ROR, 8));
7691
7692 // Set the C flag.
7693 __ Cmp(w0, Operand(w0));
7694
7695 __ Adc(x18, x2, Operand(x3));
7696 __ Adc(x19, x0, Operand(x1, LSL, 60));
7697 __ Sbc(x20, x4, Operand(x3, LSR, 4));
7698 __ Adc(x21, x2, Operand(x3, ASR, 4));
7699 __ Adc(x22, x2, Operand(x3, ROR, 8));
7700
7701 __ Adc(w23, w2, Operand(w3));
7702 __ Adc(w24, w0, Operand(w1, LSL, 30));
7703 __ Sbc(w25, w4, Operand(w3, LSR, 4));
7704 __ Adc(w26, w2, Operand(w3, ASR, 4));
7705 __ Adc(w27, w2, Operand(w3, ROR, 8));
7706 END();
7707
7708 RUN();
7709
armvixlb0c8ae22014-03-21 14:03:59 +00007710 ASSERT_EQUAL_64(0xffffffffffffffff, x5);
7711 ASSERT_EQUAL_64(INT64_C(1) << 60, x6);
7712 ASSERT_EQUAL_64(0xf0123456789abcdd, x7);
7713 ASSERT_EQUAL_64(0x0111111111111110, x8);
7714 ASSERT_EQUAL_64(0x1222222222222221, x9);
armvixlad96eda2013-06-14 11:42:37 +01007715
7716 ASSERT_EQUAL_32(0xffffffff, w10);
armvixlb0c8ae22014-03-21 14:03:59 +00007717 ASSERT_EQUAL_32(INT32_C(1) << 30, w11);
armvixlad96eda2013-06-14 11:42:37 +01007718 ASSERT_EQUAL_32(0xf89abcdd, w12);
7719 ASSERT_EQUAL_32(0x91111110, w13);
7720 ASSERT_EQUAL_32(0x9a222221, w14);
7721
armvixlb0c8ae22014-03-21 14:03:59 +00007722 ASSERT_EQUAL_64(0xffffffffffffffff + 1, x18);
7723 ASSERT_EQUAL_64((INT64_C(1) << 60) + 1, x19);
7724 ASSERT_EQUAL_64(0xf0123456789abcdd + 1, x20);
7725 ASSERT_EQUAL_64(0x0111111111111110 + 1, x21);
7726 ASSERT_EQUAL_64(0x1222222222222221 + 1, x22);
armvixlad96eda2013-06-14 11:42:37 +01007727
7728 ASSERT_EQUAL_32(0xffffffff + 1, w23);
armvixlb0c8ae22014-03-21 14:03:59 +00007729 ASSERT_EQUAL_32((INT32_C(1) << 30) + 1, w24);
armvixlad96eda2013-06-14 11:42:37 +01007730 ASSERT_EQUAL_32(0xf89abcdd + 1, w25);
7731 ASSERT_EQUAL_32(0x91111110 + 1, w26);
7732 ASSERT_EQUAL_32(0x9a222221 + 1, w27);
7733
7734 // Check that adc correctly sets the condition flags.
7735 START();
7736 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00007737 __ Mov(x1, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007738 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007739 __ Adds(x0, x0, Operand(0));
7740 __ Adcs(x10, x0, Operand(x1));
armvixlad96eda2013-06-14 11:42:37 +01007741 END();
7742
7743 RUN();
7744
7745 ASSERT_EQUAL_NZCV(ZCFlag);
armvixlf37fdc02014-02-05 13:22:16 +00007746 ASSERT_EQUAL_64(0, x10);
armvixlad96eda2013-06-14 11:42:37 +01007747
7748 START();
7749 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00007750 __ Mov(x1, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01007751 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007752 __ Adds(x0, x0, Operand(0));
7753 __ Adcs(x10, x0, Operand(x1, ASR, 63));
armvixlad96eda2013-06-14 11:42:37 +01007754 END();
7755
7756 RUN();
7757
7758 ASSERT_EQUAL_NZCV(ZCFlag);
armvixlf37fdc02014-02-05 13:22:16 +00007759 ASSERT_EQUAL_64(0, x10);
armvixlad96eda2013-06-14 11:42:37 +01007760
7761 START();
7762 __ Mov(x0, 0x10);
armvixlb0c8ae22014-03-21 14:03:59 +00007763 __ Mov(x1, 0x07ffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007764 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007765 __ Adds(x0, x0, Operand(0));
7766 __ Adcs(x10, x0, Operand(x1, LSL, 4));
armvixlad96eda2013-06-14 11:42:37 +01007767 END();
7768
7769 RUN();
7770
7771 ASSERT_EQUAL_NZCV(NVFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00007772 ASSERT_EQUAL_64(0x8000000000000000, x10);
armvixlf37fdc02014-02-05 13:22:16 +00007773
7774 // Check that sbc correctly sets the condition flags.
7775 START();
7776 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00007777 __ Mov(x1, 0xffffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00007778 // Clear the C flag.
7779 __ Adds(x0, x0, Operand(0));
7780 __ Sbcs(x10, x0, Operand(x1));
7781 END();
7782
7783 RUN();
7784
7785 ASSERT_EQUAL_NZCV(ZFlag);
7786 ASSERT_EQUAL_64(0, x10);
7787
7788 START();
7789 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00007790 __ Mov(x1, 0xffffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00007791 // Clear the C flag.
7792 __ Adds(x0, x0, Operand(0));
7793 __ Sbcs(x10, x0, Operand(x1, LSR, 1));
7794 END();
7795
7796 RUN();
7797
7798 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00007799 ASSERT_EQUAL_64(0x8000000000000001, x10);
armvixlf37fdc02014-02-05 13:22:16 +00007800
7801 START();
7802 __ Mov(x0, 0);
7803 // Clear the C flag.
7804 __ Adds(x0, x0, Operand(0));
armvixlb0c8ae22014-03-21 14:03:59 +00007805 __ Sbcs(x10, x0, Operand(0xffffffffffffffff));
armvixlf37fdc02014-02-05 13:22:16 +00007806 END();
7807
7808 RUN();
7809
7810 ASSERT_EQUAL_NZCV(ZFlag);
7811 ASSERT_EQUAL_64(0, x10);
7812
armvixlb0c8ae22014-03-21 14:03:59 +00007813 START();
armvixlf37fdc02014-02-05 13:22:16 +00007814 __ Mov(w0, 0x7fffffff);
7815 // Clear the C flag.
7816 __ Adds(x0, x0, Operand(0));
7817 __ Ngcs(w10, w0);
7818 END();
7819
7820 RUN();
7821
7822 ASSERT_EQUAL_NZCV(NFlag);
7823 ASSERT_EQUAL_64(0x80000000, x10);
7824
7825 START();
7826 // Clear the C flag.
7827 __ Adds(x0, x0, Operand(0));
armvixlb0c8ae22014-03-21 14:03:59 +00007828 __ Ngcs(x10, 0x7fffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00007829 END();
7830
7831 RUN();
7832
7833 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00007834 ASSERT_EQUAL_64(0x8000000000000000, x10);
armvixlf37fdc02014-02-05 13:22:16 +00007835
armvixlb0c8ae22014-03-21 14:03:59 +00007836 START();
armvixlf37fdc02014-02-05 13:22:16 +00007837 __ Mov(x0, 0);
7838 // Set the C flag.
7839 __ Cmp(x0, Operand(x0));
7840 __ Sbcs(x10, x0, Operand(1));
7841 END();
7842
7843 RUN();
7844
7845 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00007846 ASSERT_EQUAL_64(0xffffffffffffffff, x10);
armvixlf37fdc02014-02-05 13:22:16 +00007847
armvixlb0c8ae22014-03-21 14:03:59 +00007848 START();
armvixlf37fdc02014-02-05 13:22:16 +00007849 __ Mov(x0, 0);
7850 // Set the C flag.
7851 __ Cmp(x0, Operand(x0));
armvixlb0c8ae22014-03-21 14:03:59 +00007852 __ Ngcs(x10, 0x7fffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00007853 END();
7854
7855 RUN();
7856
7857 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00007858 ASSERT_EQUAL_64(0x8000000000000001, x10);
armvixlad96eda2013-06-14 11:42:37 +01007859
7860 TEARDOWN();
7861}
7862
7863
7864TEST(adc_sbc_extend) {
7865 SETUP();
7866
7867 START();
7868 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007869 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01007870
7871 __ Mov(x0, 0);
7872 __ Mov(x1, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00007873 __ Mov(x2, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01007874
7875 __ Adc(x10, x1, Operand(w2, UXTB, 1));
7876 __ Adc(x11, x1, Operand(x2, SXTH, 2));
7877 __ Sbc(x12, x1, Operand(w2, UXTW, 4));
7878 __ Adc(x13, x1, Operand(x2, UXTX, 4));
7879
7880 __ Adc(w14, w1, Operand(w2, UXTB, 1));
7881 __ Adc(w15, w1, Operand(w2, SXTH, 2));
7882 __ Adc(w9, w1, Operand(w2, UXTW, 4));
7883
7884 // Set the C flag.
7885 __ Cmp(w0, Operand(w0));
7886
7887 __ Adc(x20, x1, Operand(w2, UXTB, 1));
7888 __ Adc(x21, x1, Operand(x2, SXTH, 2));
7889 __ Sbc(x22, x1, Operand(w2, UXTW, 4));
7890 __ Adc(x23, x1, Operand(x2, UXTX, 4));
7891
7892 __ Adc(w24, w1, Operand(w2, UXTB, 1));
7893 __ Adc(w25, w1, Operand(w2, SXTH, 2));
7894 __ Adc(w26, w1, Operand(w2, UXTW, 4));
7895 END();
7896
7897 RUN();
7898
7899 ASSERT_EQUAL_64(0x1df, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00007900 ASSERT_EQUAL_64(0xffffffffffff37bd, x11);
7901 ASSERT_EQUAL_64(0xfffffff765432110, x12);
7902 ASSERT_EQUAL_64(0x123456789abcdef1, x13);
armvixlad96eda2013-06-14 11:42:37 +01007903
7904 ASSERT_EQUAL_32(0x1df, w14);
7905 ASSERT_EQUAL_32(0xffff37bd, w15);
7906 ASSERT_EQUAL_32(0x9abcdef1, w9);
7907
7908 ASSERT_EQUAL_64(0x1df + 1, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00007909 ASSERT_EQUAL_64(0xffffffffffff37bd + 1, x21);
7910 ASSERT_EQUAL_64(0xfffffff765432110 + 1, x22);
7911 ASSERT_EQUAL_64(0x123456789abcdef1 + 1, x23);
armvixlad96eda2013-06-14 11:42:37 +01007912
7913 ASSERT_EQUAL_32(0x1df + 1, w24);
7914 ASSERT_EQUAL_32(0xffff37bd + 1, w25);
7915 ASSERT_EQUAL_32(0x9abcdef1 + 1, w26);
7916
7917 // Check that adc correctly sets the condition flags.
7918 START();
7919 __ Mov(x0, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00007920 __ Mov(x1, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007921 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007922 __ Adds(x0, x0, Operand(0));
7923 __ Adcs(x10, x0, Operand(x1, SXTX, 1));
armvixlad96eda2013-06-14 11:42:37 +01007924 END();
7925
7926 RUN();
7927
7928 ASSERT_EQUAL_NZCV(CFlag);
7929
7930 START();
armvixlb0c8ae22014-03-21 14:03:59 +00007931 __ Mov(x0, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007932 __ Mov(x1, 1);
7933 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007934 __ Adds(x0, x0, Operand(0));
7935 __ Adcs(x10, x0, Operand(x1, UXTB, 2));
armvixlad96eda2013-06-14 11:42:37 +01007936 END();
7937
7938 RUN();
7939
7940 ASSERT_EQUAL_NZCV(NVFlag);
7941
7942 START();
armvixlb0c8ae22014-03-21 14:03:59 +00007943 __ Mov(x0, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007944 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007945 __ Adds(x0, x0, Operand(0));
7946 __ Adcs(x10, x0, Operand(1));
armvixlad96eda2013-06-14 11:42:37 +01007947 END();
7948
7949 RUN();
7950
7951 ASSERT_EQUAL_NZCV(NVFlag);
7952
7953 TEARDOWN();
7954}
7955
7956
7957TEST(adc_sbc_wide_imm) {
7958 SETUP();
7959
7960 START();
7961 __ Mov(x0, 0);
7962
7963 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00007964 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01007965
armvixlb0c8ae22014-03-21 14:03:59 +00007966 __ Adc(x7, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01007967 __ Adc(w8, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00007968 __ Sbc(x9, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00007969 __ Sbc(w10, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00007970 __ Ngc(x11, Operand(0xffffffff00000000));
armvixlf37fdc02014-02-05 13:22:16 +00007971 __ Ngc(w12, Operand(0xffff0000));
armvixlad96eda2013-06-14 11:42:37 +01007972
7973 // Set the C flag.
7974 __ Cmp(w0, Operand(w0));
7975
armvixlb0c8ae22014-03-21 14:03:59 +00007976 __ Adc(x18, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00007977 __ Adc(w19, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00007978 __ Sbc(x20, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00007979 __ Sbc(w21, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00007980 __ Ngc(x22, Operand(0xffffffff00000000));
armvixlf37fdc02014-02-05 13:22:16 +00007981 __ Ngc(w23, Operand(0xffff0000));
armvixlad96eda2013-06-14 11:42:37 +01007982 END();
7983
7984 RUN();
7985
armvixlb0c8ae22014-03-21 14:03:59 +00007986 ASSERT_EQUAL_64(0x1234567890abcdef, x7);
armvixlad96eda2013-06-14 11:42:37 +01007987 ASSERT_EQUAL_64(0xffffffff, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00007988 ASSERT_EQUAL_64(0xedcba9876f543210, x9);
armvixlf37fdc02014-02-05 13:22:16 +00007989 ASSERT_EQUAL_64(0, x10);
7990 ASSERT_EQUAL_64(0xffffffff, x11);
7991 ASSERT_EQUAL_64(0xffff, x12);
7992
armvixlb0c8ae22014-03-21 14:03:59 +00007993 ASSERT_EQUAL_64(0x1234567890abcdef + 1, x18);
armvixlf37fdc02014-02-05 13:22:16 +00007994 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +00007995 ASSERT_EQUAL_64(0xedcba9876f543211, x20);
armvixlf37fdc02014-02-05 13:22:16 +00007996 ASSERT_EQUAL_64(1, x21);
armvixlb0c8ae22014-03-21 14:03:59 +00007997 ASSERT_EQUAL_64(0x0000000100000000, x22);
7998 ASSERT_EQUAL_64(0x0000000000010000, x23);
armvixlad96eda2013-06-14 11:42:37 +01007999
8000 TEARDOWN();
8001}
8002
8003TEST(flags) {
8004 SETUP();
8005
8006 START();
8007 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00008008 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01008009 __ Neg(x10, Operand(x0));
8010 __ Neg(x11, Operand(x1));
8011 __ Neg(w12, Operand(w1));
8012 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008013 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01008014 __ Ngc(x13, Operand(x0));
8015 // Set the C flag.
8016 __ Cmp(x0, Operand(x0));
8017 __ Ngc(w14, Operand(w0));
8018 END();
8019
8020 RUN();
8021
8022 ASSERT_EQUAL_64(0, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00008023 ASSERT_EQUAL_64(-0x1111111111111111, x11);
armvixlad96eda2013-06-14 11:42:37 +01008024 ASSERT_EQUAL_32(-0x11111111, w12);
armvixlb0c8ae22014-03-21 14:03:59 +00008025 ASSERT_EQUAL_64(-1, x13);
armvixlad96eda2013-06-14 11:42:37 +01008026 ASSERT_EQUAL_32(0, w14);
8027
8028 START();
8029 __ Mov(x0, 0);
8030 __ Cmp(x0, Operand(x0));
8031 END();
8032
8033 RUN();
8034
8035 ASSERT_EQUAL_NZCV(ZCFlag);
8036
8037 START();
8038 __ Mov(w0, 0);
8039 __ Cmp(w0, Operand(w0));
8040 END();
8041
8042 RUN();
8043
8044 ASSERT_EQUAL_NZCV(ZCFlag);
8045
8046 START();
8047 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00008048 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01008049 __ Cmp(x0, Operand(x1));
8050 END();
8051
8052 RUN();
8053
8054 ASSERT_EQUAL_NZCV(NFlag);
8055
8056 START();
8057 __ Mov(w0, 0);
8058 __ Mov(w1, 0x11111111);
8059 __ Cmp(w0, Operand(w1));
8060 END();
8061
8062 RUN();
8063
8064 ASSERT_EQUAL_NZCV(NFlag);
8065
8066 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008067 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01008068 __ Cmp(x1, Operand(0));
8069 END();
8070
8071 RUN();
8072
8073 ASSERT_EQUAL_NZCV(CFlag);
8074
8075 START();
8076 __ Mov(w1, 0x11111111);
8077 __ Cmp(w1, Operand(0));
8078 END();
8079
8080 RUN();
8081
8082 ASSERT_EQUAL_NZCV(CFlag);
8083
8084 START();
8085 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00008086 __ Mov(x1, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008087 __ Cmn(x1, Operand(x0));
8088 END();
8089
8090 RUN();
8091
8092 ASSERT_EQUAL_NZCV(NVFlag);
8093
8094 START();
8095 __ Mov(w0, 1);
8096 __ Mov(w1, 0x7fffffff);
8097 __ Cmn(w1, Operand(w0));
8098 END();
8099
8100 RUN();
8101
8102 ASSERT_EQUAL_NZCV(NVFlag);
8103
8104 START();
8105 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00008106 __ Mov(x1, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008107 __ Cmn(x1, Operand(x0));
8108 END();
8109
8110 RUN();
8111
8112 ASSERT_EQUAL_NZCV(ZCFlag);
8113
8114 START();
8115 __ Mov(w0, 1);
8116 __ Mov(w1, 0xffffffff);
8117 __ Cmn(w1, Operand(w0));
8118 END();
8119
8120 RUN();
8121
8122 ASSERT_EQUAL_NZCV(ZCFlag);
8123
8124 START();
8125 __ Mov(w0, 0);
8126 __ Mov(w1, 1);
8127 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008128 __ Adds(w0, w0, Operand(0));
8129 __ Ngcs(w0, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +01008130 END();
8131
8132 RUN();
8133
8134 ASSERT_EQUAL_NZCV(NFlag);
8135
8136 START();
8137 __ Mov(w0, 0);
8138 __ Mov(w1, 0);
8139 // Set the C flag.
8140 __ Cmp(w0, Operand(w0));
armvixlf37fdc02014-02-05 13:22:16 +00008141 __ Ngcs(w0, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +01008142 END();
8143
8144 RUN();
8145
8146 ASSERT_EQUAL_NZCV(ZCFlag);
8147
8148 TEARDOWN();
8149}
8150
8151
8152TEST(cmp_shift) {
8153 SETUP();
8154
8155 START();
8156 __ Mov(x18, 0xf0000000);
armvixlb0c8ae22014-03-21 14:03:59 +00008157 __ Mov(x19, 0xf000000010000000);
8158 __ Mov(x20, 0xf0000000f0000000);
8159 __ Mov(x21, 0x7800000078000000);
8160 __ Mov(x22, 0x3c0000003c000000);
8161 __ Mov(x23, 0x8000000780000000);
8162 __ Mov(x24, 0x0000000f00000000);
8163 __ Mov(x25, 0x00000003c0000000);
8164 __ Mov(x26, 0x8000000780000000);
armvixlad96eda2013-06-14 11:42:37 +01008165 __ Mov(x27, 0xc0000003);
8166
8167 __ Cmp(w20, Operand(w21, LSL, 1));
8168 __ Mrs(x0, NZCV);
8169
8170 __ Cmp(x20, Operand(x22, LSL, 2));
8171 __ Mrs(x1, NZCV);
8172
8173 __ Cmp(w19, Operand(w23, LSR, 3));
8174 __ Mrs(x2, NZCV);
8175
8176 __ Cmp(x18, Operand(x24, LSR, 4));
8177 __ Mrs(x3, NZCV);
8178
8179 __ Cmp(w20, Operand(w25, ASR, 2));
8180 __ Mrs(x4, NZCV);
8181
8182 __ Cmp(x20, Operand(x26, ASR, 3));
8183 __ Mrs(x5, NZCV);
8184
8185 __ Cmp(w27, Operand(w22, ROR, 28));
8186 __ Mrs(x6, NZCV);
8187
8188 __ Cmp(x20, Operand(x21, ROR, 31));
8189 __ Mrs(x7, NZCV);
8190 END();
8191
8192 RUN();
8193
8194 ASSERT_EQUAL_32(ZCFlag, w0);
8195 ASSERT_EQUAL_32(ZCFlag, w1);
8196 ASSERT_EQUAL_32(ZCFlag, w2);
8197 ASSERT_EQUAL_32(ZCFlag, w3);
8198 ASSERT_EQUAL_32(ZCFlag, w4);
8199 ASSERT_EQUAL_32(ZCFlag, w5);
8200 ASSERT_EQUAL_32(ZCFlag, w6);
8201 ASSERT_EQUAL_32(ZCFlag, w7);
8202
8203 TEARDOWN();
8204}
8205
8206
8207TEST(cmp_extend) {
8208 SETUP();
8209
8210 START();
8211 __ Mov(w20, 0x2);
8212 __ Mov(w21, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00008213 __ Mov(x22, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008214 __ Mov(x23, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00008215 __ Mov(x24, 0xfffffffffffffffe);
armvixlad96eda2013-06-14 11:42:37 +01008216 __ Mov(x25, 0xffff);
8217 __ Mov(x26, 0xffffffff);
8218
8219 __ Cmp(w20, Operand(w21, LSL, 1));
8220 __ Mrs(x0, NZCV);
8221
8222 __ Cmp(x22, Operand(x23, SXTB, 0));
8223 __ Mrs(x1, NZCV);
8224
8225 __ Cmp(x24, Operand(x23, SXTB, 1));
8226 __ Mrs(x2, NZCV);
8227
8228 __ Cmp(x24, Operand(x23, UXTB, 1));
8229 __ Mrs(x3, NZCV);
8230
8231 __ Cmp(w22, Operand(w25, UXTH));
8232 __ Mrs(x4, NZCV);
8233
8234 __ Cmp(x22, Operand(x25, SXTH));
8235 __ Mrs(x5, NZCV);
8236
8237 __ Cmp(x22, Operand(x26, UXTW));
8238 __ Mrs(x6, NZCV);
8239
8240 __ Cmp(x24, Operand(x26, SXTW, 1));
8241 __ Mrs(x7, NZCV);
8242 END();
8243
8244 RUN();
8245
8246 ASSERT_EQUAL_32(ZCFlag, w0);
8247 ASSERT_EQUAL_32(ZCFlag, w1);
8248 ASSERT_EQUAL_32(ZCFlag, w2);
8249 ASSERT_EQUAL_32(NCFlag, w3);
8250 ASSERT_EQUAL_32(NCFlag, w4);
8251 ASSERT_EQUAL_32(ZCFlag, w5);
8252 ASSERT_EQUAL_32(NCFlag, w6);
8253 ASSERT_EQUAL_32(ZCFlag, w7);
8254
8255 TEARDOWN();
8256}
8257
8258
8259TEST(ccmp) {
8260 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008261 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008262
8263 START();
8264 __ Mov(w16, 0);
8265 __ Mov(w17, 1);
armvixl578645f2013-08-15 17:21:42 +01008266 __ Cmp(w16, w16);
8267 __ Ccmp(w16, w17, NCFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01008268 __ Mrs(x0, NZCV);
8269
armvixl578645f2013-08-15 17:21:42 +01008270 __ Cmp(w16, w16);
8271 __ Ccmp(w16, w17, NCFlag, ne);
armvixlad96eda2013-06-14 11:42:37 +01008272 __ Mrs(x1, NZCV);
8273
armvixl578645f2013-08-15 17:21:42 +01008274 __ Cmp(x16, x16);
8275 __ Ccmn(x16, 2, NZCVFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01008276 __ Mrs(x2, NZCV);
8277
armvixl578645f2013-08-15 17:21:42 +01008278 __ Cmp(x16, x16);
8279 __ Ccmn(x16, 2, NZCVFlag, ne);
armvixlad96eda2013-06-14 11:42:37 +01008280 __ Mrs(x3, NZCV);
armvixl578645f2013-08-15 17:21:42 +01008281
armvixlc68cb642014-09-25 18:49:30 +01008282 // The MacroAssembler does not allow al as a condition.
armvixl578645f2013-08-15 17:21:42 +01008283 __ ccmp(x16, x16, NZCVFlag, al);
8284 __ Mrs(x4, NZCV);
8285
armvixlc68cb642014-09-25 18:49:30 +01008286 // The MacroAssembler does not allow nv as a condition.
armvixl578645f2013-08-15 17:21:42 +01008287 __ ccmp(x16, x16, NZCVFlag, nv);
8288 __ Mrs(x5, NZCV);
8289
armvixlad96eda2013-06-14 11:42:37 +01008290 END();
8291
8292 RUN();
8293
8294 ASSERT_EQUAL_32(NFlag, w0);
8295 ASSERT_EQUAL_32(NCFlag, w1);
8296 ASSERT_EQUAL_32(NoFlag, w2);
8297 ASSERT_EQUAL_32(NZCVFlag, w3);
armvixl578645f2013-08-15 17:21:42 +01008298 ASSERT_EQUAL_32(ZCFlag, w4);
8299 ASSERT_EQUAL_32(ZCFlag, w5);
armvixlad96eda2013-06-14 11:42:37 +01008300
8301 TEARDOWN();
8302}
8303
8304
8305TEST(ccmp_wide_imm) {
8306 SETUP();
8307
8308 START();
8309 __ Mov(w20, 0);
8310
8311 __ Cmp(w20, Operand(w20));
8312 __ Ccmp(w20, Operand(0x12345678), NZCVFlag, eq);
8313 __ Mrs(x0, NZCV);
8314
8315 __ Cmp(w20, Operand(w20));
armvixlb0c8ae22014-03-21 14:03:59 +00008316 __ Ccmp(x20, Operand(0xffffffffffffffff), NZCVFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01008317 __ Mrs(x1, NZCV);
8318 END();
8319
8320 RUN();
8321
8322 ASSERT_EQUAL_32(NFlag, w0);
8323 ASSERT_EQUAL_32(NoFlag, w1);
8324
8325 TEARDOWN();
8326}
8327
8328
8329TEST(ccmp_shift_extend) {
8330 SETUP();
8331
8332 START();
8333 __ Mov(w20, 0x2);
8334 __ Mov(w21, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00008335 __ Mov(x22, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008336 __ Mov(x23, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00008337 __ Mov(x24, 0xfffffffffffffffe);
armvixlad96eda2013-06-14 11:42:37 +01008338
8339 __ Cmp(w20, Operand(w20));
8340 __ Ccmp(w20, Operand(w21, LSL, 1), NZCVFlag, eq);
8341 __ Mrs(x0, NZCV);
8342
8343 __ Cmp(w20, Operand(w20));
8344 __ Ccmp(x22, Operand(x23, SXTB, 0), NZCVFlag, eq);
8345 __ Mrs(x1, NZCV);
8346
8347 __ Cmp(w20, Operand(w20));
8348 __ Ccmp(x24, Operand(x23, SXTB, 1), NZCVFlag, eq);
8349 __ Mrs(x2, NZCV);
8350
8351 __ Cmp(w20, Operand(w20));
8352 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, eq);
8353 __ Mrs(x3, NZCV);
8354
8355 __ Cmp(w20, Operand(w20));
8356 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, ne);
8357 __ Mrs(x4, NZCV);
8358 END();
8359
8360 RUN();
8361
8362 ASSERT_EQUAL_32(ZCFlag, w0);
8363 ASSERT_EQUAL_32(ZCFlag, w1);
8364 ASSERT_EQUAL_32(ZCFlag, w2);
8365 ASSERT_EQUAL_32(NCFlag, w3);
8366 ASSERT_EQUAL_32(NZCVFlag, w4);
8367
8368 TEARDOWN();
8369}
8370
8371
8372TEST(csel) {
8373 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008374 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008375
8376 START();
8377 __ Mov(x16, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00008378 __ Mov(x24, 0x0000000f0000000f);
8379 __ Mov(x25, 0x0000001f0000001f);
armvixlad96eda2013-06-14 11:42:37 +01008380
8381 __ Cmp(w16, Operand(0));
8382 __ Csel(w0, w24, w25, eq);
8383 __ Csel(w1, w24, w25, ne);
8384 __ Csinc(w2, w24, w25, mi);
8385 __ Csinc(w3, w24, w25, pl);
8386
armvixlc68cb642014-09-25 18:49:30 +01008387 // The MacroAssembler does not allow al or nv as a condition.
armvixl578645f2013-08-15 17:21:42 +01008388 __ csel(w13, w24, w25, al);
8389 __ csel(x14, x24, x25, nv);
8390
armvixlad96eda2013-06-14 11:42:37 +01008391 __ Cmp(x16, Operand(1));
8392 __ Csinv(x4, x24, x25, gt);
8393 __ Csinv(x5, x24, x25, le);
8394 __ Csneg(x6, x24, x25, hs);
8395 __ Csneg(x7, x24, x25, lo);
8396
8397 __ Cset(w8, ne);
8398 __ Csetm(w9, ne);
8399 __ Cinc(x10, x25, ne);
8400 __ Cinv(x11, x24, ne);
8401 __ Cneg(x12, x24, ne);
armvixl578645f2013-08-15 17:21:42 +01008402
armvixlc68cb642014-09-25 18:49:30 +01008403 // The MacroAssembler does not allow al or nv as a condition.
armvixl578645f2013-08-15 17:21:42 +01008404 __ csel(w15, w24, w25, al);
8405 __ csel(x17, x24, x25, nv);
8406
armvixlad96eda2013-06-14 11:42:37 +01008407 END();
8408
8409 RUN();
8410
8411 ASSERT_EQUAL_64(0x0000000f, x0);
8412 ASSERT_EQUAL_64(0x0000001f, x1);
8413 ASSERT_EQUAL_64(0x00000020, x2);
8414 ASSERT_EQUAL_64(0x0000000f, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00008415 ASSERT_EQUAL_64(0xffffffe0ffffffe0, x4);
8416 ASSERT_EQUAL_64(0x0000000f0000000f, x5);
8417 ASSERT_EQUAL_64(0xffffffe0ffffffe1, x6);
8418 ASSERT_EQUAL_64(0x0000000f0000000f, x7);
armvixlad96eda2013-06-14 11:42:37 +01008419 ASSERT_EQUAL_64(0x00000001, x8);
8420 ASSERT_EQUAL_64(0xffffffff, x9);
armvixlb0c8ae22014-03-21 14:03:59 +00008421 ASSERT_EQUAL_64(0x0000001f00000020, x10);
8422 ASSERT_EQUAL_64(0xfffffff0fffffff0, x11);
8423 ASSERT_EQUAL_64(0xfffffff0fffffff1, x12);
armvixl578645f2013-08-15 17:21:42 +01008424 ASSERT_EQUAL_64(0x0000000f, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00008425 ASSERT_EQUAL_64(0x0000000f0000000f, x14);
armvixl578645f2013-08-15 17:21:42 +01008426 ASSERT_EQUAL_64(0x0000000f, x15);
armvixlb0c8ae22014-03-21 14:03:59 +00008427 ASSERT_EQUAL_64(0x0000000f0000000f, x17);
armvixlad96eda2013-06-14 11:42:37 +01008428
8429 TEARDOWN();
8430}
8431
8432
armvixlf37fdc02014-02-05 13:22:16 +00008433TEST(csel_imm) {
8434 SETUP();
8435
8436 START();
8437 __ Mov(x18, 0);
8438 __ Mov(x19, 0x80000000);
armvixlb0c8ae22014-03-21 14:03:59 +00008439 __ Mov(x20, 0x8000000000000000);
armvixlf37fdc02014-02-05 13:22:16 +00008440
8441 __ Cmp(x18, Operand(0));
8442 __ Csel(w0, w19, -2, ne);
8443 __ Csel(w1, w19, -1, ne);
8444 __ Csel(w2, w19, 0, ne);
8445 __ Csel(w3, w19, 1, ne);
8446 __ Csel(w4, w19, 2, ne);
8447 __ Csel(w5, w19, Operand(w19, ASR, 31), ne);
8448 __ Csel(w6, w19, Operand(w19, ROR, 1), ne);
8449 __ Csel(w7, w19, 3, eq);
8450
8451 __ Csel(x8, x20, -2, ne);
8452 __ Csel(x9, x20, -1, ne);
8453 __ Csel(x10, x20, 0, ne);
8454 __ Csel(x11, x20, 1, ne);
8455 __ Csel(x12, x20, 2, ne);
8456 __ Csel(x13, x20, Operand(x20, ASR, 63), ne);
8457 __ Csel(x14, x20, Operand(x20, ROR, 1), ne);
8458 __ Csel(x15, x20, 3, eq);
8459
8460 END();
8461
8462 RUN();
8463
8464 ASSERT_EQUAL_32(-2, w0);
8465 ASSERT_EQUAL_32(-1, w1);
8466 ASSERT_EQUAL_32(0, w2);
8467 ASSERT_EQUAL_32(1, w3);
8468 ASSERT_EQUAL_32(2, w4);
8469 ASSERT_EQUAL_32(-1, w5);
8470 ASSERT_EQUAL_32(0x40000000, w6);
8471 ASSERT_EQUAL_32(0x80000000, w7);
8472
8473 ASSERT_EQUAL_64(-2, x8);
8474 ASSERT_EQUAL_64(-1, x9);
8475 ASSERT_EQUAL_64(0, x10);
8476 ASSERT_EQUAL_64(1, x11);
8477 ASSERT_EQUAL_64(2, x12);
8478 ASSERT_EQUAL_64(-1, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00008479 ASSERT_EQUAL_64(0x4000000000000000, x14);
8480 ASSERT_EQUAL_64(0x8000000000000000, x15);
armvixlf37fdc02014-02-05 13:22:16 +00008481
8482 TEARDOWN();
8483}
8484
8485
armvixlad96eda2013-06-14 11:42:37 +01008486TEST(lslv) {
8487 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008488 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008489
armvixlb0c8ae22014-03-21 14:03:59 +00008490 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01008491 int shift[] = {1, 3, 5, 9, 17, 33};
8492
8493 START();
8494 __ Mov(x0, value);
8495 __ Mov(w1, shift[0]);
8496 __ Mov(w2, shift[1]);
8497 __ Mov(w3, shift[2]);
8498 __ Mov(w4, shift[3]);
8499 __ Mov(w5, shift[4]);
8500 __ Mov(w6, shift[5]);
8501
armvixlc68cb642014-09-25 18:49:30 +01008502 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008503 __ lslv(x0, x0, xzr);
8504
8505 __ Lsl(x16, x0, x1);
8506 __ Lsl(x17, x0, x2);
8507 __ Lsl(x18, x0, x3);
8508 __ Lsl(x19, x0, x4);
8509 __ Lsl(x20, x0, x5);
8510 __ Lsl(x21, x0, x6);
8511
8512 __ Lsl(w22, w0, w1);
8513 __ Lsl(w23, w0, w2);
8514 __ Lsl(w24, w0, w3);
8515 __ Lsl(w25, w0, w4);
8516 __ Lsl(w26, w0, w5);
8517 __ Lsl(w27, w0, w6);
8518 END();
8519
8520 RUN();
8521
8522 ASSERT_EQUAL_64(value, x0);
8523 ASSERT_EQUAL_64(value << (shift[0] & 63), x16);
8524 ASSERT_EQUAL_64(value << (shift[1] & 63), x17);
8525 ASSERT_EQUAL_64(value << (shift[2] & 63), x18);
8526 ASSERT_EQUAL_64(value << (shift[3] & 63), x19);
8527 ASSERT_EQUAL_64(value << (shift[4] & 63), x20);
8528 ASSERT_EQUAL_64(value << (shift[5] & 63), x21);
8529 ASSERT_EQUAL_32(value << (shift[0] & 31), w22);
8530 ASSERT_EQUAL_32(value << (shift[1] & 31), w23);
8531 ASSERT_EQUAL_32(value << (shift[2] & 31), w24);
8532 ASSERT_EQUAL_32(value << (shift[3] & 31), w25);
8533 ASSERT_EQUAL_32(value << (shift[4] & 31), w26);
8534 ASSERT_EQUAL_32(value << (shift[5] & 31), w27);
8535
8536 TEARDOWN();
8537}
8538
8539
8540TEST(lsrv) {
8541 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008542 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008543
armvixlb0c8ae22014-03-21 14:03:59 +00008544 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01008545 int shift[] = {1, 3, 5, 9, 17, 33};
8546
8547 START();
8548 __ Mov(x0, value);
8549 __ Mov(w1, shift[0]);
8550 __ Mov(w2, shift[1]);
8551 __ Mov(w3, shift[2]);
8552 __ Mov(w4, shift[3]);
8553 __ Mov(w5, shift[4]);
8554 __ Mov(w6, shift[5]);
8555
armvixlc68cb642014-09-25 18:49:30 +01008556 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008557 __ lsrv(x0, x0, xzr);
8558
8559 __ Lsr(x16, x0, x1);
8560 __ Lsr(x17, x0, x2);
8561 __ Lsr(x18, x0, x3);
8562 __ Lsr(x19, x0, x4);
8563 __ Lsr(x20, x0, x5);
8564 __ Lsr(x21, x0, x6);
8565
8566 __ Lsr(w22, w0, w1);
8567 __ Lsr(w23, w0, w2);
8568 __ Lsr(w24, w0, w3);
8569 __ Lsr(w25, w0, w4);
8570 __ Lsr(w26, w0, w5);
8571 __ Lsr(w27, w0, w6);
8572 END();
8573
8574 RUN();
8575
8576 ASSERT_EQUAL_64(value, x0);
8577 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
8578 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
8579 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
8580 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
8581 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
8582 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
8583
armvixlb0c8ae22014-03-21 14:03:59 +00008584 value &= 0xffffffff;
armvixlad96eda2013-06-14 11:42:37 +01008585 ASSERT_EQUAL_32(value >> (shift[0] & 31), w22);
8586 ASSERT_EQUAL_32(value >> (shift[1] & 31), w23);
8587 ASSERT_EQUAL_32(value >> (shift[2] & 31), w24);
8588 ASSERT_EQUAL_32(value >> (shift[3] & 31), w25);
8589 ASSERT_EQUAL_32(value >> (shift[4] & 31), w26);
8590 ASSERT_EQUAL_32(value >> (shift[5] & 31), w27);
8591
8592 TEARDOWN();
8593}
8594
8595
8596TEST(asrv) {
8597 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008598 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008599
armvixlb0c8ae22014-03-21 14:03:59 +00008600 int64_t value = 0xfedcba98fedcba98;
armvixlad96eda2013-06-14 11:42:37 +01008601 int shift[] = {1, 3, 5, 9, 17, 33};
8602
8603 START();
8604 __ Mov(x0, value);
8605 __ Mov(w1, shift[0]);
8606 __ Mov(w2, shift[1]);
8607 __ Mov(w3, shift[2]);
8608 __ Mov(w4, shift[3]);
8609 __ Mov(w5, shift[4]);
8610 __ Mov(w6, shift[5]);
8611
armvixlc68cb642014-09-25 18:49:30 +01008612 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008613 __ asrv(x0, x0, xzr);
8614
8615 __ Asr(x16, x0, x1);
8616 __ Asr(x17, x0, x2);
8617 __ Asr(x18, x0, x3);
8618 __ Asr(x19, x0, x4);
8619 __ Asr(x20, x0, x5);
8620 __ Asr(x21, x0, x6);
8621
8622 __ Asr(w22, w0, w1);
8623 __ Asr(w23, w0, w2);
8624 __ Asr(w24, w0, w3);
8625 __ Asr(w25, w0, w4);
8626 __ Asr(w26, w0, w5);
8627 __ Asr(w27, w0, w6);
8628 END();
8629
8630 RUN();
8631
8632 ASSERT_EQUAL_64(value, x0);
8633 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
8634 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
8635 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
8636 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
8637 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
8638 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
8639
armvixlb0c8ae22014-03-21 14:03:59 +00008640 int32_t value32 = static_cast<int32_t>(value & 0xffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008641 ASSERT_EQUAL_32(value32 >> (shift[0] & 31), w22);
8642 ASSERT_EQUAL_32(value32 >> (shift[1] & 31), w23);
8643 ASSERT_EQUAL_32(value32 >> (shift[2] & 31), w24);
8644 ASSERT_EQUAL_32(value32 >> (shift[3] & 31), w25);
8645 ASSERT_EQUAL_32(value32 >> (shift[4] & 31), w26);
8646 ASSERT_EQUAL_32(value32 >> (shift[5] & 31), w27);
8647
8648 TEARDOWN();
8649}
8650
8651
8652TEST(rorv) {
8653 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008654 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008655
armvixlb0c8ae22014-03-21 14:03:59 +00008656 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01008657 int shift[] = {4, 8, 12, 16, 24, 36};
8658
8659 START();
8660 __ Mov(x0, value);
8661 __ Mov(w1, shift[0]);
8662 __ Mov(w2, shift[1]);
8663 __ Mov(w3, shift[2]);
8664 __ Mov(w4, shift[3]);
8665 __ Mov(w5, shift[4]);
8666 __ Mov(w6, shift[5]);
8667
armvixlc68cb642014-09-25 18:49:30 +01008668 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008669 __ rorv(x0, x0, xzr);
8670
8671 __ Ror(x16, x0, x1);
8672 __ Ror(x17, x0, x2);
8673 __ Ror(x18, x0, x3);
8674 __ Ror(x19, x0, x4);
8675 __ Ror(x20, x0, x5);
8676 __ Ror(x21, x0, x6);
8677
8678 __ Ror(w22, w0, w1);
8679 __ Ror(w23, w0, w2);
8680 __ Ror(w24, w0, w3);
8681 __ Ror(w25, w0, w4);
8682 __ Ror(w26, w0, w5);
8683 __ Ror(w27, w0, w6);
8684 END();
8685
8686 RUN();
8687
8688 ASSERT_EQUAL_64(value, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00008689 ASSERT_EQUAL_64(0xf0123456789abcde, x16);
8690 ASSERT_EQUAL_64(0xef0123456789abcd, x17);
8691 ASSERT_EQUAL_64(0xdef0123456789abc, x18);
8692 ASSERT_EQUAL_64(0xcdef0123456789ab, x19);
8693 ASSERT_EQUAL_64(0xabcdef0123456789, x20);
8694 ASSERT_EQUAL_64(0x789abcdef0123456, x21);
armvixlad96eda2013-06-14 11:42:37 +01008695 ASSERT_EQUAL_32(0xf89abcde, w22);
8696 ASSERT_EQUAL_32(0xef89abcd, w23);
8697 ASSERT_EQUAL_32(0xdef89abc, w24);
8698 ASSERT_EQUAL_32(0xcdef89ab, w25);
8699 ASSERT_EQUAL_32(0xabcdef89, w26);
8700 ASSERT_EQUAL_32(0xf89abcde, w27);
8701
8702 TEARDOWN();
8703}
8704
8705
8706TEST(bfm) {
8707 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008708 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008709
8710 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008711 __ Mov(x1, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01008712
armvixlb0c8ae22014-03-21 14:03:59 +00008713 __ Mov(x10, 0x8888888888888888);
8714 __ Mov(x11, 0x8888888888888888);
8715 __ Mov(x12, 0x8888888888888888);
8716 __ Mov(x13, 0x8888888888888888);
armvixlad96eda2013-06-14 11:42:37 +01008717 __ Mov(w20, 0x88888888);
8718 __ Mov(w21, 0x88888888);
8719
armvixlc68cb642014-09-25 18:49:30 +01008720 // There are no macro instruction for bfm.
armvixl5289c592015-03-02 13:52:04 +00008721 __ Bfm(x10, x1, 16, 31);
8722 __ Bfm(x11, x1, 32, 15);
armvixlad96eda2013-06-14 11:42:37 +01008723
armvixl5289c592015-03-02 13:52:04 +00008724 __ Bfm(w20, w1, 16, 23);
8725 __ Bfm(w21, w1, 24, 15);
armvixlad96eda2013-06-14 11:42:37 +01008726
8727 // Aliases.
8728 __ Bfi(x12, x1, 16, 8);
8729 __ Bfxil(x13, x1, 16, 8);
8730 END();
8731
8732 RUN();
8733
8734
armvixlb0c8ae22014-03-21 14:03:59 +00008735 ASSERT_EQUAL_64(0x88888888888889ab, x10);
8736 ASSERT_EQUAL_64(0x8888cdef88888888, x11);
armvixlad96eda2013-06-14 11:42:37 +01008737
8738 ASSERT_EQUAL_32(0x888888ab, w20);
8739 ASSERT_EQUAL_32(0x88cdef88, w21);
8740
armvixlb0c8ae22014-03-21 14:03:59 +00008741 ASSERT_EQUAL_64(0x8888888888ef8888, x12);
8742 ASSERT_EQUAL_64(0x88888888888888ab, x13);
armvixlad96eda2013-06-14 11:42:37 +01008743
8744 TEARDOWN();
8745}
8746
8747
8748TEST(sbfm) {
8749 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008750 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008751
8752 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008753 __ Mov(x1, 0x0123456789abcdef);
8754 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01008755
armvixlc68cb642014-09-25 18:49:30 +01008756 // There are no macro instruction for sbfm.
armvixl5289c592015-03-02 13:52:04 +00008757 __ Sbfm(x10, x1, 16, 31);
8758 __ Sbfm(x11, x1, 32, 15);
8759 __ Sbfm(x12, x1, 32, 47);
8760 __ Sbfm(x13, x1, 48, 35);
armvixlad96eda2013-06-14 11:42:37 +01008761
armvixl5289c592015-03-02 13:52:04 +00008762 __ Sbfm(w14, w1, 16, 23);
8763 __ Sbfm(w15, w1, 24, 15);
8764 __ Sbfm(w16, w2, 16, 23);
8765 __ Sbfm(w17, w2, 24, 15);
armvixlad96eda2013-06-14 11:42:37 +01008766
8767 // Aliases.
8768 __ Asr(x18, x1, 32);
8769 __ Asr(x19, x2, 32);
8770 __ Sbfiz(x20, x1, 8, 16);
8771 __ Sbfiz(x21, x2, 8, 16);
8772 __ Sbfx(x22, x1, 8, 16);
8773 __ Sbfx(x23, x2, 8, 16);
armvixlf37fdc02014-02-05 13:22:16 +00008774 __ Sxtb(x24, w1);
armvixlad96eda2013-06-14 11:42:37 +01008775 __ Sxtb(x25, x2);
armvixlf37fdc02014-02-05 13:22:16 +00008776 __ Sxth(x26, w1);
armvixlad96eda2013-06-14 11:42:37 +01008777 __ Sxth(x27, x2);
armvixlf37fdc02014-02-05 13:22:16 +00008778 __ Sxtw(x28, w1);
armvixlad96eda2013-06-14 11:42:37 +01008779 __ Sxtw(x29, x2);
8780 END();
8781
8782 RUN();
8783
8784
armvixlb0c8ae22014-03-21 14:03:59 +00008785 ASSERT_EQUAL_64(0xffffffffffff89ab, x10);
8786 ASSERT_EQUAL_64(0xffffcdef00000000, x11);
8787 ASSERT_EQUAL_64(0x0000000000004567, x12);
8788 ASSERT_EQUAL_64(0x000789abcdef0000, x13);
armvixlad96eda2013-06-14 11:42:37 +01008789
8790 ASSERT_EQUAL_32(0xffffffab, w14);
8791 ASSERT_EQUAL_32(0xffcdef00, w15);
armvixlb0c8ae22014-03-21 14:03:59 +00008792 ASSERT_EQUAL_32(0x00000054, w16);
armvixlad96eda2013-06-14 11:42:37 +01008793 ASSERT_EQUAL_32(0x00321000, w17);
8794
armvixlb0c8ae22014-03-21 14:03:59 +00008795 ASSERT_EQUAL_64(0x0000000001234567, x18);
8796 ASSERT_EQUAL_64(0xfffffffffedcba98, x19);
8797 ASSERT_EQUAL_64(0xffffffffffcdef00, x20);
8798 ASSERT_EQUAL_64(0x0000000000321000, x21);
8799 ASSERT_EQUAL_64(0xffffffffffffabcd, x22);
8800 ASSERT_EQUAL_64(0x0000000000005432, x23);
8801 ASSERT_EQUAL_64(0xffffffffffffffef, x24);
8802 ASSERT_EQUAL_64(0x0000000000000010, x25);
8803 ASSERT_EQUAL_64(0xffffffffffffcdef, x26);
8804 ASSERT_EQUAL_64(0x0000000000003210, x27);
8805 ASSERT_EQUAL_64(0xffffffff89abcdef, x28);
8806 ASSERT_EQUAL_64(0x0000000076543210, x29);
armvixlad96eda2013-06-14 11:42:37 +01008807
8808 TEARDOWN();
8809}
8810
8811
8812TEST(ubfm) {
8813 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008814 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008815
8816 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008817 __ Mov(x1, 0x0123456789abcdef);
8818 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01008819
armvixlb0c8ae22014-03-21 14:03:59 +00008820 __ Mov(x10, 0x8888888888888888);
8821 __ Mov(x11, 0x8888888888888888);
armvixlad96eda2013-06-14 11:42:37 +01008822
armvixlc68cb642014-09-25 18:49:30 +01008823 // There are no macro instruction for ubfm.
armvixl5289c592015-03-02 13:52:04 +00008824 __ Ubfm(x10, x1, 16, 31);
8825 __ Ubfm(x11, x1, 32, 15);
8826 __ Ubfm(x12, x1, 32, 47);
8827 __ Ubfm(x13, x1, 48, 35);
armvixlad96eda2013-06-14 11:42:37 +01008828
armvixl5289c592015-03-02 13:52:04 +00008829 __ Ubfm(w25, w1, 16, 23);
8830 __ Ubfm(w26, w1, 24, 15);
8831 __ Ubfm(w27, w2, 16, 23);
8832 __ Ubfm(w28, w2, 24, 15);
armvixlad96eda2013-06-14 11:42:37 +01008833
8834 // Aliases
8835 __ Lsl(x15, x1, 63);
8836 __ Lsl(x16, x1, 0);
8837 __ Lsr(x17, x1, 32);
8838 __ Ubfiz(x18, x1, 8, 16);
8839 __ Ubfx(x19, x1, 8, 16);
8840 __ Uxtb(x20, x1);
8841 __ Uxth(x21, x1);
8842 __ Uxtw(x22, x1);
8843 END();
8844
8845 RUN();
8846
armvixlb0c8ae22014-03-21 14:03:59 +00008847 ASSERT_EQUAL_64(0x00000000000089ab, x10);
8848 ASSERT_EQUAL_64(0x0000cdef00000000, x11);
8849 ASSERT_EQUAL_64(0x0000000000004567, x12);
8850 ASSERT_EQUAL_64(0x000789abcdef0000, x13);
armvixlad96eda2013-06-14 11:42:37 +01008851
8852 ASSERT_EQUAL_32(0x000000ab, w25);
8853 ASSERT_EQUAL_32(0x00cdef00, w26);
armvixlb0c8ae22014-03-21 14:03:59 +00008854 ASSERT_EQUAL_32(0x00000054, w27);
armvixlad96eda2013-06-14 11:42:37 +01008855 ASSERT_EQUAL_32(0x00321000, w28);
8856
armvixlb0c8ae22014-03-21 14:03:59 +00008857 ASSERT_EQUAL_64(0x8000000000000000, x15);
8858 ASSERT_EQUAL_64(0x0123456789abcdef, x16);
8859 ASSERT_EQUAL_64(0x0000000001234567, x17);
8860 ASSERT_EQUAL_64(0x0000000000cdef00, x18);
8861 ASSERT_EQUAL_64(0x000000000000abcd, x19);
8862 ASSERT_EQUAL_64(0x00000000000000ef, x20);
8863 ASSERT_EQUAL_64(0x000000000000cdef, x21);
8864 ASSERT_EQUAL_64(0x0000000089abcdef, x22);
armvixlad96eda2013-06-14 11:42:37 +01008865
8866 TEARDOWN();
8867}
8868
8869
8870TEST(extr) {
8871 SETUP();
8872
8873 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008874 __ Mov(x1, 0x0123456789abcdef);
8875 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01008876
8877 __ Extr(w10, w1, w2, 0);
8878 __ Extr(w11, w1, w2, 1);
8879 __ Extr(x12, x2, x1, 2);
8880
8881 __ Ror(w13, w1, 0);
8882 __ Ror(w14, w2, 17);
8883 __ Ror(w15, w1, 31);
armvixl4a102ba2014-07-14 09:02:40 +01008884 __ Ror(x18, x2, 0);
8885 __ Ror(x19, x2, 1);
8886 __ Ror(x20, x1, 63);
armvixlad96eda2013-06-14 11:42:37 +01008887 END();
8888
8889 RUN();
8890
8891 ASSERT_EQUAL_64(0x76543210, x10);
8892 ASSERT_EQUAL_64(0xbb2a1908, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00008893 ASSERT_EQUAL_64(0x0048d159e26af37b, x12);
armvixlad96eda2013-06-14 11:42:37 +01008894 ASSERT_EQUAL_64(0x89abcdef, x13);
8895 ASSERT_EQUAL_64(0x19083b2a, x14);
8896 ASSERT_EQUAL_64(0x13579bdf, x15);
armvixl4a102ba2014-07-14 09:02:40 +01008897 ASSERT_EQUAL_64(0xfedcba9876543210, x18);
8898 ASSERT_EQUAL_64(0x7f6e5d4c3b2a1908, x19);
8899 ASSERT_EQUAL_64(0x02468acf13579bde, x20);
armvixlad96eda2013-06-14 11:42:37 +01008900
8901 TEARDOWN();
8902}
8903
8904
8905TEST(fmov_imm) {
8906 SETUP();
8907
8908 START();
8909 __ Fmov(s11, 1.0);
8910 __ Fmov(d22, -13.0);
8911 __ Fmov(s1, 255.0);
8912 __ Fmov(d2, 12.34567);
8913 __ Fmov(s3, 0.0);
8914 __ Fmov(d4, 0.0);
8915 __ Fmov(s5, kFP32PositiveInfinity);
8916 __ Fmov(d6, kFP64NegativeInfinity);
8917 END();
8918
8919 RUN();
8920
8921 ASSERT_EQUAL_FP32(1.0, s11);
8922 ASSERT_EQUAL_FP64(-13.0, d22);
8923 ASSERT_EQUAL_FP32(255.0, s1);
8924 ASSERT_EQUAL_FP64(12.34567, d2);
8925 ASSERT_EQUAL_FP32(0.0, s3);
8926 ASSERT_EQUAL_FP64(0.0, d4);
8927 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
8928 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d6);
8929
8930 TEARDOWN();
8931}
8932
8933
8934TEST(fmov_reg) {
8935 SETUP();
8936
8937 START();
8938 __ Fmov(s20, 1.0);
8939 __ Fmov(w10, s20);
8940 __ Fmov(s30, w10);
8941 __ Fmov(s5, s20);
8942 __ Fmov(d1, -13.0);
8943 __ Fmov(x1, d1);
8944 __ Fmov(d2, x1);
8945 __ Fmov(d4, d1);
armvixlb0c8ae22014-03-21 14:03:59 +00008946 __ Fmov(d6, rawbits_to_double(0x0123456789abcdef));
armvixlad96eda2013-06-14 11:42:37 +01008947 __ Fmov(s6, s6);
armvixl5289c592015-03-02 13:52:04 +00008948
8949 __ Fmov(d0, 0.0);
8950 __ Fmov(v0.D(), 1, x1);
8951 __ Fmov(x2, v0.D(), 1);
8952
armvixlad96eda2013-06-14 11:42:37 +01008953 END();
8954
8955 RUN();
8956
8957 ASSERT_EQUAL_32(float_to_rawbits(1.0), w10);
8958 ASSERT_EQUAL_FP32(1.0, s30);
8959 ASSERT_EQUAL_FP32(1.0, s5);
8960 ASSERT_EQUAL_64(double_to_rawbits(-13.0), x1);
8961 ASSERT_EQUAL_FP64(-13.0, d2);
8962 ASSERT_EQUAL_FP64(-13.0, d4);
8963 ASSERT_EQUAL_FP32(rawbits_to_float(0x89abcdef), s6);
armvixl5289c592015-03-02 13:52:04 +00008964 ASSERT_EQUAL_128(double_to_rawbits(-13.0), 0x0000000000000000, q0);
8965 ASSERT_EQUAL_64(double_to_rawbits(-13.0), x2);
armvixlad96eda2013-06-14 11:42:37 +01008966 TEARDOWN();
8967}
8968
8969
8970TEST(fadd) {
8971 SETUP();
8972
8973 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008974 __ Fmov(s14, -0.0f);
8975 __ Fmov(s15, kFP32PositiveInfinity);
8976 __ Fmov(s16, kFP32NegativeInfinity);
8977 __ Fmov(s17, 3.25f);
8978 __ Fmov(s18, 1.0f);
8979 __ Fmov(s19, 0.0f);
armvixlad96eda2013-06-14 11:42:37 +01008980
8981 __ Fmov(d26, -0.0);
8982 __ Fmov(d27, kFP64PositiveInfinity);
8983 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00008984 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01008985 __ Fmov(d30, -2.0);
8986 __ Fmov(d31, 2.25);
8987
armvixlb0c8ae22014-03-21 14:03:59 +00008988 __ Fadd(s0, s17, s18);
8989 __ Fadd(s1, s18, s19);
8990 __ Fadd(s2, s14, s18);
8991 __ Fadd(s3, s15, s18);
8992 __ Fadd(s4, s16, s18);
8993 __ Fadd(s5, s15, s16);
8994 __ Fadd(s6, s16, s15);
armvixlad96eda2013-06-14 11:42:37 +01008995
armvixlb0c8ae22014-03-21 14:03:59 +00008996 __ Fadd(d7, d30, d31);
8997 __ Fadd(d8, d29, d31);
8998 __ Fadd(d9, d26, d31);
8999 __ Fadd(d10, d27, d31);
9000 __ Fadd(d11, d28, d31);
9001 __ Fadd(d12, d27, d28);
9002 __ Fadd(d13, d28, d27);
armvixlad96eda2013-06-14 11:42:37 +01009003 END();
9004
9005 RUN();
9006
9007 ASSERT_EQUAL_FP32(4.25, s0);
9008 ASSERT_EQUAL_FP32(1.0, s1);
9009 ASSERT_EQUAL_FP32(1.0, s2);
9010 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
9011 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00009012 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9013 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9014 ASSERT_EQUAL_FP64(0.25, d7);
9015 ASSERT_EQUAL_FP64(2.25, d8);
9016 ASSERT_EQUAL_FP64(2.25, d9);
9017 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d10);
9018 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d11);
9019 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9020 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009021
9022 TEARDOWN();
9023}
9024
9025
9026TEST(fsub) {
9027 SETUP();
9028
9029 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009030 __ Fmov(s14, -0.0f);
9031 __ Fmov(s15, kFP32PositiveInfinity);
9032 __ Fmov(s16, kFP32NegativeInfinity);
9033 __ Fmov(s17, 3.25f);
9034 __ Fmov(s18, 1.0f);
9035 __ Fmov(s19, 0.0f);
armvixlad96eda2013-06-14 11:42:37 +01009036
9037 __ Fmov(d26, -0.0);
9038 __ Fmov(d27, kFP64PositiveInfinity);
9039 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009040 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01009041 __ Fmov(d30, -2.0);
9042 __ Fmov(d31, 2.25);
9043
armvixlb0c8ae22014-03-21 14:03:59 +00009044 __ Fsub(s0, s17, s18);
9045 __ Fsub(s1, s18, s19);
9046 __ Fsub(s2, s14, s18);
9047 __ Fsub(s3, s18, s15);
9048 __ Fsub(s4, s18, s16);
9049 __ Fsub(s5, s15, s15);
9050 __ Fsub(s6, s16, s16);
armvixlad96eda2013-06-14 11:42:37 +01009051
armvixlb0c8ae22014-03-21 14:03:59 +00009052 __ Fsub(d7, d30, d31);
9053 __ Fsub(d8, d29, d31);
9054 __ Fsub(d9, d26, d31);
9055 __ Fsub(d10, d31, d27);
9056 __ Fsub(d11, d31, d28);
9057 __ Fsub(d12, d27, d27);
9058 __ Fsub(d13, d28, d28);
armvixlad96eda2013-06-14 11:42:37 +01009059 END();
9060
9061 RUN();
9062
9063 ASSERT_EQUAL_FP32(2.25, s0);
9064 ASSERT_EQUAL_FP32(1.0, s1);
9065 ASSERT_EQUAL_FP32(-1.0, s2);
9066 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
9067 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00009068 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9069 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9070 ASSERT_EQUAL_FP64(-4.25, d7);
9071 ASSERT_EQUAL_FP64(-2.25, d8);
9072 ASSERT_EQUAL_FP64(-2.25, d9);
9073 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
9074 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
9075 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9076 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009077
9078 TEARDOWN();
9079}
9080
9081
9082TEST(fmul) {
9083 SETUP();
9084
9085 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009086 __ Fmov(s14, -0.0f);
9087 __ Fmov(s15, kFP32PositiveInfinity);
9088 __ Fmov(s16, kFP32NegativeInfinity);
9089 __ Fmov(s17, 3.25f);
9090 __ Fmov(s18, 2.0f);
9091 __ Fmov(s19, 0.0f);
9092 __ Fmov(s20, -2.0f);
armvixlad96eda2013-06-14 11:42:37 +01009093
9094 __ Fmov(d26, -0.0);
9095 __ Fmov(d27, kFP64PositiveInfinity);
9096 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009097 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01009098 __ Fmov(d30, -2.0);
9099 __ Fmov(d31, 2.25);
9100
armvixlb0c8ae22014-03-21 14:03:59 +00009101 __ Fmul(s0, s17, s18);
9102 __ Fmul(s1, s18, s19);
9103 __ Fmul(s2, s14, s14);
9104 __ Fmul(s3, s15, s20);
9105 __ Fmul(s4, s16, s20);
9106 __ Fmul(s5, s15, s19);
9107 __ Fmul(s6, s19, s16);
armvixlad96eda2013-06-14 11:42:37 +01009108
armvixlb0c8ae22014-03-21 14:03:59 +00009109 __ Fmul(d7, d30, d31);
9110 __ Fmul(d8, d29, d31);
9111 __ Fmul(d9, d26, d26);
9112 __ Fmul(d10, d27, d30);
9113 __ Fmul(d11, d28, d30);
9114 __ Fmul(d12, d27, d29);
9115 __ Fmul(d13, d29, d28);
armvixlad96eda2013-06-14 11:42:37 +01009116 END();
9117
9118 RUN();
9119
9120 ASSERT_EQUAL_FP32(6.5, s0);
9121 ASSERT_EQUAL_FP32(0.0, s1);
9122 ASSERT_EQUAL_FP32(0.0, s2);
9123 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
9124 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00009125 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9126 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9127 ASSERT_EQUAL_FP64(-4.5, d7);
9128 ASSERT_EQUAL_FP64(0.0, d8);
9129 ASSERT_EQUAL_FP64(0.0, d9);
9130 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
9131 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
9132 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9133 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009134
9135 TEARDOWN();
9136}
9137
9138
armvixlb0c8ae22014-03-21 14:03:59 +00009139static void FmaddFmsubHelper(double n, double m, double a,
9140 double fmadd, double fmsub,
9141 double fnmadd, double fnmsub) {
armvixlad96eda2013-06-14 11:42:37 +01009142 SETUP();
armvixlad96eda2013-06-14 11:42:37 +01009143 START();
armvixlad96eda2013-06-14 11:42:37 +01009144
armvixlf37fdc02014-02-05 13:22:16 +00009145 __ Fmov(d0, n);
9146 __ Fmov(d1, m);
9147 __ Fmov(d2, a);
9148 __ Fmadd(d28, d0, d1, d2);
9149 __ Fmsub(d29, d0, d1, d2);
9150 __ Fnmadd(d30, d0, d1, d2);
9151 __ Fnmsub(d31, d0, d1, d2);
armvixlad96eda2013-06-14 11:42:37 +01009152
armvixlad96eda2013-06-14 11:42:37 +01009153 END();
armvixlad96eda2013-06-14 11:42:37 +01009154 RUN();
9155
armvixlf37fdc02014-02-05 13:22:16 +00009156 ASSERT_EQUAL_FP64(fmadd, d28);
9157 ASSERT_EQUAL_FP64(fmsub, d29);
armvixlb0c8ae22014-03-21 14:03:59 +00009158 ASSERT_EQUAL_FP64(fnmadd, d30);
9159 ASSERT_EQUAL_FP64(fnmsub, d31);
armvixlad96eda2013-06-14 11:42:37 +01009160
9161 TEARDOWN();
9162}
9163
9164
armvixlf37fdc02014-02-05 13:22:16 +00009165TEST(fmadd_fmsub_double) {
armvixlb0c8ae22014-03-21 14:03:59 +00009166 // It's hard to check the result of fused operations because the only way to
9167 // calculate the result is using fma, which is what the simulator uses anyway.
armvixlf37fdc02014-02-05 13:22:16 +00009168
armvixlb0c8ae22014-03-21 14:03:59 +00009169 // Basic operation.
9170 FmaddFmsubHelper(1.0, 2.0, 3.0, 5.0, 1.0, -5.0, -1.0);
9171 FmaddFmsubHelper(-1.0, 2.0, 3.0, 1.0, 5.0, -1.0, -5.0);
armvixlf37fdc02014-02-05 13:22:16 +00009172
armvixlb0c8ae22014-03-21 14:03:59 +00009173 // Check the sign of exact zeroes.
9174 // n m a fmadd fmsub fnmadd fnmsub
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 FmaddFmsubHelper(+0.0, -0.0, +0.0, +0.0, +0.0, +0.0, -0.0);
9183
9184 // Check NaN generation.
9185 FmaddFmsubHelper(kFP64PositiveInfinity, 0.0, 42.0,
9186 kFP64DefaultNaN, kFP64DefaultNaN,
9187 kFP64DefaultNaN, kFP64DefaultNaN);
9188 FmaddFmsubHelper(0.0, kFP64PositiveInfinity, 42.0,
9189 kFP64DefaultNaN, kFP64DefaultNaN,
9190 kFP64DefaultNaN, kFP64DefaultNaN);
9191 FmaddFmsubHelper(kFP64PositiveInfinity, 1.0, kFP64PositiveInfinity,
9192 kFP64PositiveInfinity, // inf + ( inf * 1) = inf
9193 kFP64DefaultNaN, // inf + (-inf * 1) = NaN
9194 kFP64NegativeInfinity, // -inf + (-inf * 1) = -inf
9195 kFP64DefaultNaN); // -inf + ( inf * 1) = NaN
9196 FmaddFmsubHelper(kFP64NegativeInfinity, 1.0, kFP64PositiveInfinity,
9197 kFP64DefaultNaN, // inf + (-inf * 1) = NaN
9198 kFP64PositiveInfinity, // inf + ( inf * 1) = inf
9199 kFP64DefaultNaN, // -inf + ( inf * 1) = NaN
9200 kFP64NegativeInfinity); // -inf + (-inf * 1) = -inf
armvixlf37fdc02014-02-05 13:22:16 +00009201}
9202
9203
armvixlb0c8ae22014-03-21 14:03:59 +00009204static void FmaddFmsubHelper(float n, float m, float a,
9205 float fmadd, float fmsub,
9206 float fnmadd, float fnmsub) {
armvixlf37fdc02014-02-05 13:22:16 +00009207 SETUP();
9208 START();
9209
9210 __ Fmov(s0, n);
9211 __ Fmov(s1, m);
9212 __ Fmov(s2, a);
armvixlb0c8ae22014-03-21 14:03:59 +00009213 __ Fmadd(s28, s0, s1, s2);
9214 __ Fmsub(s29, s0, s1, s2);
9215 __ Fnmadd(s30, s0, s1, s2);
9216 __ Fnmsub(s31, s0, s1, s2);
armvixlf37fdc02014-02-05 13:22:16 +00009217
9218 END();
9219 RUN();
9220
armvixlb0c8ae22014-03-21 14:03:59 +00009221 ASSERT_EQUAL_FP32(fmadd, s28);
9222 ASSERT_EQUAL_FP32(fmsub, s29);
9223 ASSERT_EQUAL_FP32(fnmadd, s30);
9224 ASSERT_EQUAL_FP32(fnmsub, s31);
armvixlf37fdc02014-02-05 13:22:16 +00009225
9226 TEARDOWN();
9227}
9228
9229
9230TEST(fmadd_fmsub_float) {
armvixlb0c8ae22014-03-21 14:03:59 +00009231 // It's hard to check the result of fused operations because the only way to
9232 // calculate the result is using fma, which is what the simulator uses anyway.
armvixlf37fdc02014-02-05 13:22:16 +00009233
armvixlb0c8ae22014-03-21 14:03:59 +00009234 // Basic operation.
9235 FmaddFmsubHelper(1.0f, 2.0f, 3.0f, 5.0f, 1.0f, -5.0f, -1.0f);
9236 FmaddFmsubHelper(-1.0f, 2.0f, 3.0f, 1.0f, 5.0f, -1.0f, -5.0f);
armvixlf37fdc02014-02-05 13:22:16 +00009237
armvixlb0c8ae22014-03-21 14:03:59 +00009238 // Check the sign of exact zeroes.
9239 // n m a fmadd fmsub fnmadd fnmsub
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 FmaddFmsubHelper(+0.0f, -0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
9248
9249 // Check NaN generation.
9250 FmaddFmsubHelper(kFP32PositiveInfinity, 0.0f, 42.0f,
9251 kFP32DefaultNaN, kFP32DefaultNaN,
9252 kFP32DefaultNaN, kFP32DefaultNaN);
9253 FmaddFmsubHelper(0.0f, kFP32PositiveInfinity, 42.0f,
9254 kFP32DefaultNaN, kFP32DefaultNaN,
9255 kFP32DefaultNaN, kFP32DefaultNaN);
9256 FmaddFmsubHelper(kFP32PositiveInfinity, 1.0f, kFP32PositiveInfinity,
9257 kFP32PositiveInfinity, // inf + ( inf * 1) = inf
9258 kFP32DefaultNaN, // inf + (-inf * 1) = NaN
9259 kFP32NegativeInfinity, // -inf + (-inf * 1) = -inf
9260 kFP32DefaultNaN); // -inf + ( inf * 1) = NaN
9261 FmaddFmsubHelper(kFP32NegativeInfinity, 1.0f, kFP32PositiveInfinity,
9262 kFP32DefaultNaN, // inf + (-inf * 1) = NaN
9263 kFP32PositiveInfinity, // inf + ( inf * 1) = inf
9264 kFP32DefaultNaN, // -inf + ( inf * 1) = NaN
9265 kFP32NegativeInfinity); // -inf + (-inf * 1) = -inf
armvixlf37fdc02014-02-05 13:22:16 +00009266}
9267
9268
armvixlb0c8ae22014-03-21 14:03:59 +00009269TEST(fmadd_fmsub_double_nans) {
9270 // Make sure that NaN propagation works correctly.
9271 double s1 = rawbits_to_double(0x7ff5555511111111);
9272 double s2 = rawbits_to_double(0x7ff5555522222222);
9273 double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
9274 double q1 = rawbits_to_double(0x7ffaaaaa11111111);
9275 double q2 = rawbits_to_double(0x7ffaaaaa22222222);
9276 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
9277 VIXL_ASSERT(IsSignallingNaN(s1));
9278 VIXL_ASSERT(IsSignallingNaN(s2));
9279 VIXL_ASSERT(IsSignallingNaN(sa));
9280 VIXL_ASSERT(IsQuietNaN(q1));
9281 VIXL_ASSERT(IsQuietNaN(q2));
9282 VIXL_ASSERT(IsQuietNaN(qa));
armvixlf37fdc02014-02-05 13:22:16 +00009283
armvixlb0c8ae22014-03-21 14:03:59 +00009284 // The input NaNs after passing through ProcessNaN.
9285 double s1_proc = rawbits_to_double(0x7ffd555511111111);
9286 double s2_proc = rawbits_to_double(0x7ffd555522222222);
9287 double sa_proc = rawbits_to_double(0x7ffd5555aaaaaaaa);
9288 double q1_proc = q1;
9289 double q2_proc = q2;
9290 double qa_proc = qa;
9291 VIXL_ASSERT(IsQuietNaN(s1_proc));
9292 VIXL_ASSERT(IsQuietNaN(s2_proc));
9293 VIXL_ASSERT(IsQuietNaN(sa_proc));
9294 VIXL_ASSERT(IsQuietNaN(q1_proc));
9295 VIXL_ASSERT(IsQuietNaN(q2_proc));
9296 VIXL_ASSERT(IsQuietNaN(qa_proc));
armvixlf37fdc02014-02-05 13:22:16 +00009297
armvixl5799d6c2014-05-01 11:05:00 +01009298 // Negated NaNs as it would be done on ARMv8 hardware.
9299 double s1_proc_neg = rawbits_to_double(0xfffd555511111111);
9300 double sa_proc_neg = rawbits_to_double(0xfffd5555aaaaaaaa);
9301 double q1_proc_neg = rawbits_to_double(0xfffaaaaa11111111);
9302 double qa_proc_neg = rawbits_to_double(0xfffaaaaaaaaaaaaa);
9303 VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
9304 VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
9305 VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
9306 VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
9307
armvixlb0c8ae22014-03-21 14:03:59 +00009308 // Quiet NaNs are propagated.
armvixl5799d6c2014-05-01 11:05:00 +01009309 FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009310 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009311 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9312 FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
9313 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9314 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9315 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00009316
armvixlb0c8ae22014-03-21 14:03:59 +00009317 // Signalling NaNs are propagated, and made quiet.
armvixl5799d6c2014-05-01 11:05:00 +01009318 FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009319 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009320 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9321 FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9322 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9323 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9324 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00009325
armvixlb0c8ae22014-03-21 14:03:59 +00009326 // Signalling NaNs take precedence over quiet NaNs.
armvixl5799d6c2014-05-01 11:05:00 +01009327 FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009328 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009329 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9330 FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9331 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9332 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9333 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00009334
armvixlb0c8ae22014-03-21 14:03:59 +00009335 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
9336 FmaddFmsubHelper(0, kFP64PositiveInfinity, qa,
9337 kFP64DefaultNaN, kFP64DefaultNaN,
9338 kFP64DefaultNaN, kFP64DefaultNaN);
9339 FmaddFmsubHelper(kFP64PositiveInfinity, 0, qa,
9340 kFP64DefaultNaN, kFP64DefaultNaN,
9341 kFP64DefaultNaN, kFP64DefaultNaN);
9342 FmaddFmsubHelper(0, kFP64NegativeInfinity, qa,
9343 kFP64DefaultNaN, kFP64DefaultNaN,
9344 kFP64DefaultNaN, kFP64DefaultNaN);
9345 FmaddFmsubHelper(kFP64NegativeInfinity, 0, qa,
9346 kFP64DefaultNaN, kFP64DefaultNaN,
9347 kFP64DefaultNaN, kFP64DefaultNaN);
9348}
armvixlf37fdc02014-02-05 13:22:16 +00009349
armvixlf37fdc02014-02-05 13:22:16 +00009350
armvixlb0c8ae22014-03-21 14:03:59 +00009351TEST(fmadd_fmsub_float_nans) {
9352 // Make sure that NaN propagation works correctly.
9353 float s1 = rawbits_to_float(0x7f951111);
9354 float s2 = rawbits_to_float(0x7f952222);
9355 float sa = rawbits_to_float(0x7f95aaaa);
9356 float q1 = rawbits_to_float(0x7fea1111);
9357 float q2 = rawbits_to_float(0x7fea2222);
9358 float qa = rawbits_to_float(0x7feaaaaa);
9359 VIXL_ASSERT(IsSignallingNaN(s1));
9360 VIXL_ASSERT(IsSignallingNaN(s2));
9361 VIXL_ASSERT(IsSignallingNaN(sa));
9362 VIXL_ASSERT(IsQuietNaN(q1));
9363 VIXL_ASSERT(IsQuietNaN(q2));
9364 VIXL_ASSERT(IsQuietNaN(qa));
armvixlf37fdc02014-02-05 13:22:16 +00009365
armvixlb0c8ae22014-03-21 14:03:59 +00009366 // The input NaNs after passing through ProcessNaN.
9367 float s1_proc = rawbits_to_float(0x7fd51111);
9368 float s2_proc = rawbits_to_float(0x7fd52222);
9369 float sa_proc = rawbits_to_float(0x7fd5aaaa);
9370 float q1_proc = q1;
9371 float q2_proc = q2;
9372 float qa_proc = qa;
9373 VIXL_ASSERT(IsQuietNaN(s1_proc));
9374 VIXL_ASSERT(IsQuietNaN(s2_proc));
9375 VIXL_ASSERT(IsQuietNaN(sa_proc));
9376 VIXL_ASSERT(IsQuietNaN(q1_proc));
9377 VIXL_ASSERT(IsQuietNaN(q2_proc));
9378 VIXL_ASSERT(IsQuietNaN(qa_proc));
9379
armvixl5799d6c2014-05-01 11:05:00 +01009380 // Negated NaNs as it would be done on ARMv8 hardware.
9381 float s1_proc_neg = rawbits_to_float(0xffd51111);
9382 float sa_proc_neg = rawbits_to_float(0xffd5aaaa);
9383 float q1_proc_neg = rawbits_to_float(0xffea1111);
9384 float qa_proc_neg = rawbits_to_float(0xffeaaaaa);
9385 VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
9386 VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
9387 VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
9388 VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
9389
armvixlb0c8ae22014-03-21 14:03:59 +00009390 // Quiet NaNs are propagated.
armvixl5799d6c2014-05-01 11:05:00 +01009391 FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009392 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009393 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9394 FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
9395 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9396 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9397 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00009398
9399 // Signalling NaNs are propagated, and made quiet.
armvixl5799d6c2014-05-01 11:05:00 +01009400 FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009401 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009402 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9403 FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9404 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9405 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9406 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00009407
9408 // Signalling NaNs take precedence over quiet NaNs.
armvixl5799d6c2014-05-01 11:05:00 +01009409 FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009410 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009411 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9412 FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9413 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9414 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9415 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00009416
9417 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
9418 FmaddFmsubHelper(0, kFP32PositiveInfinity, qa,
9419 kFP32DefaultNaN, kFP32DefaultNaN,
9420 kFP32DefaultNaN, kFP32DefaultNaN);
9421 FmaddFmsubHelper(kFP32PositiveInfinity, 0, qa,
9422 kFP32DefaultNaN, kFP32DefaultNaN,
9423 kFP32DefaultNaN, kFP32DefaultNaN);
9424 FmaddFmsubHelper(0, kFP32NegativeInfinity, qa,
9425 kFP32DefaultNaN, kFP32DefaultNaN,
9426 kFP32DefaultNaN, kFP32DefaultNaN);
9427 FmaddFmsubHelper(kFP32NegativeInfinity, 0, qa,
9428 kFP32DefaultNaN, kFP32DefaultNaN,
9429 kFP32DefaultNaN, kFP32DefaultNaN);
armvixlf37fdc02014-02-05 13:22:16 +00009430}
9431
9432
armvixlad96eda2013-06-14 11:42:37 +01009433TEST(fdiv) {
9434 SETUP();
9435
9436 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009437 __ Fmov(s14, -0.0f);
9438 __ Fmov(s15, kFP32PositiveInfinity);
9439 __ Fmov(s16, kFP32NegativeInfinity);
9440 __ Fmov(s17, 3.25f);
9441 __ Fmov(s18, 2.0f);
9442 __ Fmov(s19, 2.0f);
9443 __ Fmov(s20, -2.0f);
armvixlad96eda2013-06-14 11:42:37 +01009444
9445 __ Fmov(d26, -0.0);
9446 __ Fmov(d27, kFP64PositiveInfinity);
9447 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009448 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01009449 __ Fmov(d30, -2.0);
9450 __ Fmov(d31, 2.25);
9451
armvixlb0c8ae22014-03-21 14:03:59 +00009452 __ Fdiv(s0, s17, s18);
9453 __ Fdiv(s1, s18, s19);
9454 __ Fdiv(s2, s14, s18);
9455 __ Fdiv(s3, s18, s15);
9456 __ Fdiv(s4, s18, s16);
9457 __ Fdiv(s5, s15, s16);
9458 __ Fdiv(s6, s14, s14);
9459
9460 __ Fdiv(d7, d31, d30);
9461 __ Fdiv(d8, d29, d31);
9462 __ Fdiv(d9, d26, d31);
9463 __ Fdiv(d10, d31, d27);
9464 __ Fdiv(d11, d31, d28);
9465 __ Fdiv(d12, d28, d27);
9466 __ Fdiv(d13, d29, d29);
armvixlad96eda2013-06-14 11:42:37 +01009467 END();
9468
9469 RUN();
9470
armvixlb0c8ae22014-03-21 14:03:59 +00009471 ASSERT_EQUAL_FP32(1.625f, s0);
9472 ASSERT_EQUAL_FP32(1.0f, s1);
9473 ASSERT_EQUAL_FP32(-0.0f, s2);
9474 ASSERT_EQUAL_FP32(0.0f, s3);
9475 ASSERT_EQUAL_FP32(-0.0f, s4);
9476 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9477 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9478 ASSERT_EQUAL_FP64(-1.125, d7);
armvixlad96eda2013-06-14 11:42:37 +01009479 ASSERT_EQUAL_FP64(0.0, d8);
9480 ASSERT_EQUAL_FP64(-0.0, d9);
armvixlb0c8ae22014-03-21 14:03:59 +00009481 ASSERT_EQUAL_FP64(0.0, d10);
9482 ASSERT_EQUAL_FP64(-0.0, d11);
9483 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9484 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009485
9486 TEARDOWN();
9487}
9488
9489
armvixlf37fdc02014-02-05 13:22:16 +00009490static float MinMaxHelper(float n,
9491 float m,
9492 bool min,
9493 float quiet_nan_substitute = 0.0) {
armvixlb0c8ae22014-03-21 14:03:59 +00009494 const uint64_t kFP32QuietNaNMask = 0x00400000;
armvixlf37fdc02014-02-05 13:22:16 +00009495 uint32_t raw_n = float_to_rawbits(n);
9496 uint32_t raw_m = float_to_rawbits(m);
armvixlad96eda2013-06-14 11:42:37 +01009497
armvixl6e2c8272015-03-31 11:04:14 +01009498 if (std::isnan(n) && ((raw_n & kFP32QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009499 // n is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009500 return rawbits_to_float(raw_n | kFP32QuietNaNMask);
armvixl6e2c8272015-03-31 11:04:14 +01009501 } else if (std::isnan(m) && ((raw_m & kFP32QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009502 // m is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009503 return rawbits_to_float(raw_m | kFP32QuietNaNMask);
armvixlf37fdc02014-02-05 13:22:16 +00009504 } else if (quiet_nan_substitute == 0.0) {
armvixl6e2c8272015-03-31 11:04:14 +01009505 if (std::isnan(n)) {
armvixlf37fdc02014-02-05 13:22:16 +00009506 // n is quiet NaN.
9507 return n;
armvixl6e2c8272015-03-31 11:04:14 +01009508 } else if (std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009509 // m is quiet NaN.
9510 return m;
9511 }
9512 } else {
9513 // Substitute n or m if one is quiet, but not both.
armvixl6e2c8272015-03-31 11:04:14 +01009514 if (std::isnan(n) && !std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009515 // n is quiet NaN: replace with substitute.
9516 n = quiet_nan_substitute;
armvixl6e2c8272015-03-31 11:04:14 +01009517 } else if (!std::isnan(n) && std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009518 // m is quiet NaN: replace with substitute.
9519 m = quiet_nan_substitute;
armvixlad96eda2013-06-14 11:42:37 +01009520 }
9521 }
armvixlad96eda2013-06-14 11:42:37 +01009522
armvixlf37fdc02014-02-05 13:22:16 +00009523 if ((n == 0.0) && (m == 0.0) &&
9524 (copysign(1.0, n) != copysign(1.0, m))) {
9525 return min ? -0.0 : 0.0;
9526 }
armvixlad96eda2013-06-14 11:42:37 +01009527
armvixlf37fdc02014-02-05 13:22:16 +00009528 return min ? fminf(n, m) : fmaxf(n, m);
armvixlad96eda2013-06-14 11:42:37 +01009529}
9530
9531
armvixlf37fdc02014-02-05 13:22:16 +00009532static double MinMaxHelper(double n,
9533 double m,
9534 bool min,
9535 double quiet_nan_substitute = 0.0) {
armvixlb0c8ae22014-03-21 14:03:59 +00009536 const uint64_t kFP64QuietNaNMask = 0x0008000000000000;
armvixlf37fdc02014-02-05 13:22:16 +00009537 uint64_t raw_n = double_to_rawbits(n);
9538 uint64_t raw_m = double_to_rawbits(m);
armvixlad96eda2013-06-14 11:42:37 +01009539
armvixl6e2c8272015-03-31 11:04:14 +01009540 if (std::isnan(n) && ((raw_n & kFP64QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009541 // n is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009542 return rawbits_to_double(raw_n | kFP64QuietNaNMask);
armvixl6e2c8272015-03-31 11:04:14 +01009543 } else if (std::isnan(m) && ((raw_m & kFP64QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009544 // m is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009545 return rawbits_to_double(raw_m | kFP64QuietNaNMask);
armvixlf37fdc02014-02-05 13:22:16 +00009546 } else if (quiet_nan_substitute == 0.0) {
armvixl6e2c8272015-03-31 11:04:14 +01009547 if (std::isnan(n)) {
armvixlf37fdc02014-02-05 13:22:16 +00009548 // n is quiet NaN.
9549 return n;
armvixl6e2c8272015-03-31 11:04:14 +01009550 } else if (std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009551 // m is quiet NaN.
9552 return m;
9553 }
9554 } else {
9555 // Substitute n or m if one is quiet, but not both.
armvixl6e2c8272015-03-31 11:04:14 +01009556 if (std::isnan(n) && !std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009557 // n is quiet NaN: replace with substitute.
9558 n = quiet_nan_substitute;
armvixl6e2c8272015-03-31 11:04:14 +01009559 } else if (!std::isnan(n) && std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009560 // m is quiet NaN: replace with substitute.
9561 m = quiet_nan_substitute;
armvixlad96eda2013-06-14 11:42:37 +01009562 }
9563 }
armvixlf37fdc02014-02-05 13:22:16 +00009564
9565 if ((n == 0.0) && (m == 0.0) &&
9566 (copysign(1.0, n) != copysign(1.0, m))) {
9567 return min ? -0.0 : 0.0;
9568 }
9569
9570 return min ? fmin(n, m) : fmax(n, m);
9571}
9572
9573
9574static void FminFmaxDoubleHelper(double n, double m, double min, double max,
9575 double minnm, double maxnm) {
9576 SETUP();
9577
9578 START();
9579 __ Fmov(d0, n);
9580 __ Fmov(d1, m);
9581 __ Fmin(d28, d0, d1);
9582 __ Fmax(d29, d0, d1);
9583 __ Fminnm(d30, d0, d1);
9584 __ Fmaxnm(d31, d0, d1);
armvixlad96eda2013-06-14 11:42:37 +01009585 END();
9586
9587 RUN();
9588
armvixlf37fdc02014-02-05 13:22:16 +00009589 ASSERT_EQUAL_FP64(min, d28);
9590 ASSERT_EQUAL_FP64(max, d29);
9591 ASSERT_EQUAL_FP64(minnm, d30);
9592 ASSERT_EQUAL_FP64(maxnm, d31);
armvixlad96eda2013-06-14 11:42:37 +01009593
9594 TEARDOWN();
9595}
9596
9597
armvixlf37fdc02014-02-05 13:22:16 +00009598TEST(fmax_fmin_d) {
armvixlb0c8ae22014-03-21 14:03:59 +00009599 // Use non-standard NaNs to check that the payload bits are preserved.
9600 double snan = rawbits_to_double(0x7ff5555512345678);
9601 double qnan = rawbits_to_double(0x7ffaaaaa87654321);
9602
9603 double snan_processed = rawbits_to_double(0x7ffd555512345678);
9604 double qnan_processed = qnan;
9605
9606 VIXL_ASSERT(IsSignallingNaN(snan));
9607 VIXL_ASSERT(IsQuietNaN(qnan));
9608 VIXL_ASSERT(IsQuietNaN(snan_processed));
9609 VIXL_ASSERT(IsQuietNaN(qnan_processed));
9610
armvixlf37fdc02014-02-05 13:22:16 +00009611 // Bootstrap tests.
9612 FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0);
9613 FminFmaxDoubleHelper(0, 1, 0, 1, 0, 1);
9614 FminFmaxDoubleHelper(kFP64PositiveInfinity, kFP64NegativeInfinity,
9615 kFP64NegativeInfinity, kFP64PositiveInfinity,
9616 kFP64NegativeInfinity, kFP64PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009617 FminFmaxDoubleHelper(snan, 0,
9618 snan_processed, snan_processed,
9619 snan_processed, snan_processed);
9620 FminFmaxDoubleHelper(0, snan,
9621 snan_processed, snan_processed,
9622 snan_processed, snan_processed);
9623 FminFmaxDoubleHelper(qnan, 0,
9624 qnan_processed, qnan_processed,
armvixlf37fdc02014-02-05 13:22:16 +00009625 0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00009626 FminFmaxDoubleHelper(0, qnan,
9627 qnan_processed, qnan_processed,
9628 0, 0);
9629 FminFmaxDoubleHelper(qnan, snan,
9630 snan_processed, snan_processed,
9631 snan_processed, snan_processed);
9632 FminFmaxDoubleHelper(snan, qnan,
9633 snan_processed, snan_processed,
9634 snan_processed, snan_processed);
armvixlf37fdc02014-02-05 13:22:16 +00009635
9636 // Iterate over all combinations of inputs.
9637 double inputs[] = { DBL_MAX, DBL_MIN, 1.0, 0.0,
9638 -DBL_MAX, -DBL_MIN, -1.0, -0.0,
9639 kFP64PositiveInfinity, kFP64NegativeInfinity,
9640 kFP64QuietNaN, kFP64SignallingNaN };
9641
9642 const int count = sizeof(inputs) / sizeof(inputs[0]);
9643
9644 for (int in = 0; in < count; in++) {
9645 double n = inputs[in];
9646 for (int im = 0; im < count; im++) {
9647 double m = inputs[im];
9648 FminFmaxDoubleHelper(n, m,
9649 MinMaxHelper(n, m, true),
9650 MinMaxHelper(n, m, false),
9651 MinMaxHelper(n, m, true, kFP64PositiveInfinity),
9652 MinMaxHelper(n, m, false, kFP64NegativeInfinity));
9653 }
9654 }
9655}
9656
9657
9658static void FminFmaxFloatHelper(float n, float m, float min, float max,
9659 float minnm, float maxnm) {
9660 SETUP();
9661
9662 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009663 __ Fmov(s0, n);
9664 __ Fmov(s1, m);
armvixlf37fdc02014-02-05 13:22:16 +00009665 __ Fmin(s28, s0, s1);
9666 __ Fmax(s29, s0, s1);
9667 __ Fminnm(s30, s0, s1);
9668 __ Fmaxnm(s31, s0, s1);
9669 END();
9670
9671 RUN();
9672
9673 ASSERT_EQUAL_FP32(min, s28);
9674 ASSERT_EQUAL_FP32(max, s29);
9675 ASSERT_EQUAL_FP32(minnm, s30);
9676 ASSERT_EQUAL_FP32(maxnm, s31);
9677
9678 TEARDOWN();
9679}
9680
9681
9682TEST(fmax_fmin_s) {
armvixlb0c8ae22014-03-21 14:03:59 +00009683 // Use non-standard NaNs to check that the payload bits are preserved.
9684 float snan = rawbits_to_float(0x7f951234);
9685 float qnan = rawbits_to_float(0x7fea8765);
9686
9687 float snan_processed = rawbits_to_float(0x7fd51234);
9688 float qnan_processed = qnan;
9689
9690 VIXL_ASSERT(IsSignallingNaN(snan));
9691 VIXL_ASSERT(IsQuietNaN(qnan));
9692 VIXL_ASSERT(IsQuietNaN(snan_processed));
9693 VIXL_ASSERT(IsQuietNaN(qnan_processed));
9694
armvixlf37fdc02014-02-05 13:22:16 +00009695 // Bootstrap tests.
9696 FminFmaxFloatHelper(0, 0, 0, 0, 0, 0);
9697 FminFmaxFloatHelper(0, 1, 0, 1, 0, 1);
9698 FminFmaxFloatHelper(kFP32PositiveInfinity, kFP32NegativeInfinity,
9699 kFP32NegativeInfinity, kFP32PositiveInfinity,
9700 kFP32NegativeInfinity, kFP32PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009701 FminFmaxFloatHelper(snan, 0,
9702 snan_processed, snan_processed,
9703 snan_processed, snan_processed);
9704 FminFmaxFloatHelper(0, snan,
9705 snan_processed, snan_processed,
9706 snan_processed, snan_processed);
9707 FminFmaxFloatHelper(qnan, 0,
9708 qnan_processed, qnan_processed,
armvixlf37fdc02014-02-05 13:22:16 +00009709 0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00009710 FminFmaxFloatHelper(0, qnan,
9711 qnan_processed, qnan_processed,
9712 0, 0);
9713 FminFmaxFloatHelper(qnan, snan,
9714 snan_processed, snan_processed,
9715 snan_processed, snan_processed);
9716 FminFmaxFloatHelper(snan, qnan,
9717 snan_processed, snan_processed,
9718 snan_processed, snan_processed);
armvixlf37fdc02014-02-05 13:22:16 +00009719
9720 // Iterate over all combinations of inputs.
9721 float inputs[] = { FLT_MAX, FLT_MIN, 1.0, 0.0,
9722 -FLT_MAX, -FLT_MIN, -1.0, -0.0,
9723 kFP32PositiveInfinity, kFP32NegativeInfinity,
9724 kFP32QuietNaN, kFP32SignallingNaN };
9725
9726 const int count = sizeof(inputs) / sizeof(inputs[0]);
9727
9728 for (int in = 0; in < count; in++) {
9729 float n = inputs[in];
9730 for (int im = 0; im < count; im++) {
9731 float m = inputs[im];
9732 FminFmaxFloatHelper(n, m,
9733 MinMaxHelper(n, m, true),
9734 MinMaxHelper(n, m, false),
9735 MinMaxHelper(n, m, true, kFP32PositiveInfinity),
9736 MinMaxHelper(n, m, false, kFP32NegativeInfinity));
9737 }
9738 }
9739}
9740
9741
armvixlad96eda2013-06-14 11:42:37 +01009742TEST(fccmp) {
9743 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01009744 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01009745
9746 START();
9747 __ Fmov(s16, 0.0);
9748 __ Fmov(s17, 0.5);
9749 __ Fmov(d18, -0.5);
9750 __ Fmov(d19, -1.0);
9751 __ Mov(x20, 0);
armvixl6e2c8272015-03-31 11:04:14 +01009752 __ Mov(x21, 0x7ff0000000000001); // Double precision NaN.
9753 __ Fmov(d21, x21);
9754 __ Mov(w22, 0x7f800001); // Single precision NaN.
9755 __ Fmov(s22, w22);
armvixlad96eda2013-06-14 11:42:37 +01009756
armvixl578645f2013-08-15 17:21:42 +01009757 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009758 __ Fccmp(s16, s16, NoFlag, eq);
9759 __ Mrs(x0, NZCV);
9760
armvixl578645f2013-08-15 17:21:42 +01009761 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009762 __ Fccmp(s16, s16, VFlag, ne);
9763 __ Mrs(x1, NZCV);
9764
armvixl578645f2013-08-15 17:21:42 +01009765 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009766 __ Fccmp(s16, s17, CFlag, ge);
9767 __ Mrs(x2, NZCV);
9768
armvixl578645f2013-08-15 17:21:42 +01009769 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009770 __ Fccmp(s16, s17, CVFlag, lt);
9771 __ Mrs(x3, NZCV);
9772
armvixl578645f2013-08-15 17:21:42 +01009773 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009774 __ Fccmp(d18, d18, ZFlag, le);
9775 __ Mrs(x4, NZCV);
9776
armvixl578645f2013-08-15 17:21:42 +01009777 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009778 __ Fccmp(d18, d18, ZVFlag, gt);
9779 __ Mrs(x5, NZCV);
9780
armvixl578645f2013-08-15 17:21:42 +01009781 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009782 __ Fccmp(d18, d19, ZCVFlag, ls);
9783 __ Mrs(x6, NZCV);
9784
armvixl578645f2013-08-15 17:21:42 +01009785 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01009786 __ Fccmp(d18, d19, NFlag, hi);
9787 __ Mrs(x7, NZCV);
armvixl578645f2013-08-15 17:21:42 +01009788
armvixlc68cb642014-09-25 18:49:30 +01009789 // The Macro Assembler does not allow al or nv as condition.
armvixl578645f2013-08-15 17:21:42 +01009790 __ fccmp(s16, s16, NFlag, al);
9791 __ Mrs(x8, NZCV);
9792
9793 __ fccmp(d18, d18, NFlag, nv);
9794 __ Mrs(x9, NZCV);
armvixl6e2c8272015-03-31 11:04:14 +01009795
9796 __ Cmp(x20, 0);
9797 __ Fccmpe(s16, s16, NoFlag, eq);
9798 __ Mrs(x10, NZCV);
9799
9800 __ Cmp(x20, 0);
9801 __ Fccmpe(d18, d19, ZCVFlag, ls);
9802 __ Mrs(x11, NZCV);
9803
9804 __ Cmp(x20, 0);
9805 __ Fccmpe(d21, d21, NoFlag, eq);
9806 __ Mrs(x12, NZCV);
9807
9808 __ Cmp(x20, 0);
9809 __ Fccmpe(s22, s22, NoFlag, eq);
9810 __ Mrs(x13, NZCV);
armvixlad96eda2013-06-14 11:42:37 +01009811 END();
9812
9813 RUN();
9814
9815 ASSERT_EQUAL_32(ZCFlag, w0);
9816 ASSERT_EQUAL_32(VFlag, w1);
9817 ASSERT_EQUAL_32(NFlag, w2);
9818 ASSERT_EQUAL_32(CVFlag, w3);
9819 ASSERT_EQUAL_32(ZCFlag, w4);
9820 ASSERT_EQUAL_32(ZVFlag, w5);
9821 ASSERT_EQUAL_32(CFlag, w6);
9822 ASSERT_EQUAL_32(NFlag, w7);
armvixl578645f2013-08-15 17:21:42 +01009823 ASSERT_EQUAL_32(ZCFlag, w8);
9824 ASSERT_EQUAL_32(ZCFlag, w9);
armvixl6e2c8272015-03-31 11:04:14 +01009825 ASSERT_EQUAL_32(ZCFlag, w10);
9826 ASSERT_EQUAL_32(CFlag, w11);
9827 ASSERT_EQUAL_32(CVFlag, w12);
9828 ASSERT_EQUAL_32(CVFlag, w13);
armvixlad96eda2013-06-14 11:42:37 +01009829
9830 TEARDOWN();
9831}
9832
9833
9834TEST(fcmp) {
9835 SETUP();
9836
9837 START();
armvixlf37fdc02014-02-05 13:22:16 +00009838
9839 // Some of these tests require a floating-point scratch register assigned to
9840 // the macro assembler, but most do not.
armvixlb0c8ae22014-03-21 14:03:59 +00009841 {
9842 UseScratchRegisterScope temps(&masm);
9843 temps.ExcludeAll();
9844 temps.Include(ip0, ip1);
armvixlf37fdc02014-02-05 13:22:16 +00009845
armvixlb0c8ae22014-03-21 14:03:59 +00009846 __ Fmov(s8, 0.0);
9847 __ Fmov(s9, 0.5);
9848 __ Mov(w18, 0x7f800001); // Single precision NaN.
9849 __ Fmov(s18, w18);
armvixlad96eda2013-06-14 11:42:37 +01009850
armvixlb0c8ae22014-03-21 14:03:59 +00009851 __ Fcmp(s8, s8);
9852 __ Mrs(x0, NZCV);
9853 __ Fcmp(s8, s9);
9854 __ Mrs(x1, NZCV);
9855 __ Fcmp(s9, s8);
9856 __ Mrs(x2, NZCV);
9857 __ Fcmp(s8, s18);
9858 __ Mrs(x3, NZCV);
9859 __ Fcmp(s18, s18);
9860 __ Mrs(x4, NZCV);
9861 __ Fcmp(s8, 0.0);
9862 __ Mrs(x5, NZCV);
9863 temps.Include(d0);
9864 __ Fcmp(s8, 255.0);
9865 temps.Exclude(d0);
9866 __ Mrs(x6, NZCV);
armvixlad96eda2013-06-14 11:42:37 +01009867
armvixlb0c8ae22014-03-21 14:03:59 +00009868 __ Fmov(d19, 0.0);
9869 __ Fmov(d20, 0.5);
9870 __ Mov(x21, 0x7ff0000000000001); // Double precision NaN.
9871 __ Fmov(d21, x21);
armvixlad96eda2013-06-14 11:42:37 +01009872
armvixlb0c8ae22014-03-21 14:03:59 +00009873 __ Fcmp(d19, d19);
9874 __ Mrs(x10, NZCV);
9875 __ Fcmp(d19, d20);
9876 __ Mrs(x11, NZCV);
9877 __ Fcmp(d20, d19);
9878 __ Mrs(x12, NZCV);
9879 __ Fcmp(d19, d21);
9880 __ Mrs(x13, NZCV);
9881 __ Fcmp(d21, d21);
9882 __ Mrs(x14, NZCV);
9883 __ Fcmp(d19, 0.0);
9884 __ Mrs(x15, NZCV);
9885 temps.Include(d0);
9886 __ Fcmp(d19, 12.3456);
9887 temps.Exclude(d0);
9888 __ Mrs(x16, NZCV);
armvixl6e2c8272015-03-31 11:04:14 +01009889
9890 __ Fcmpe(s8, s8);
9891 __ Mrs(x22, NZCV);
9892 __ Fcmpe(s8, 0.0);
9893 __ Mrs(x23, NZCV);
9894 __ Fcmpe(d19, d19);
9895 __ Mrs(x24, NZCV);
9896 __ Fcmpe(d19, 0.0);
9897 __ Mrs(x25, NZCV);
9898 __ Fcmpe(s18, s18);
9899 __ Mrs(x26, NZCV);
9900 __ Fcmpe(d21, d21);
9901 __ Mrs(x27, NZCV);
armvixlb0c8ae22014-03-21 14:03:59 +00009902 }
9903
armvixlad96eda2013-06-14 11:42:37 +01009904 END();
9905
9906 RUN();
9907
9908 ASSERT_EQUAL_32(ZCFlag, w0);
9909 ASSERT_EQUAL_32(NFlag, w1);
9910 ASSERT_EQUAL_32(CFlag, w2);
9911 ASSERT_EQUAL_32(CVFlag, w3);
9912 ASSERT_EQUAL_32(CVFlag, w4);
9913 ASSERT_EQUAL_32(ZCFlag, w5);
9914 ASSERT_EQUAL_32(NFlag, w6);
9915 ASSERT_EQUAL_32(ZCFlag, w10);
9916 ASSERT_EQUAL_32(NFlag, w11);
9917 ASSERT_EQUAL_32(CFlag, w12);
9918 ASSERT_EQUAL_32(CVFlag, w13);
9919 ASSERT_EQUAL_32(CVFlag, w14);
9920 ASSERT_EQUAL_32(ZCFlag, w15);
9921 ASSERT_EQUAL_32(NFlag, w16);
armvixl6e2c8272015-03-31 11:04:14 +01009922 ASSERT_EQUAL_32(ZCFlag, w22);
9923 ASSERT_EQUAL_32(ZCFlag, w23);
9924 ASSERT_EQUAL_32(ZCFlag, w24);
9925 ASSERT_EQUAL_32(ZCFlag, w25);
9926 ASSERT_EQUAL_32(CVFlag, w26);
9927 ASSERT_EQUAL_32(CVFlag, w27);
armvixlad96eda2013-06-14 11:42:37 +01009928
9929 TEARDOWN();
9930}
9931
9932
9933TEST(fcsel) {
9934 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01009935 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01009936
9937 START();
9938 __ Mov(x16, 0);
9939 __ Fmov(s16, 1.0);
9940 __ Fmov(s17, 2.0);
9941 __ Fmov(d18, 3.0);
9942 __ Fmov(d19, 4.0);
9943
armvixl578645f2013-08-15 17:21:42 +01009944 __ Cmp(x16, 0);
armvixlad96eda2013-06-14 11:42:37 +01009945 __ Fcsel(s0, s16, s17, eq);
9946 __ Fcsel(s1, s16, s17, ne);
9947 __ Fcsel(d2, d18, d19, eq);
9948 __ Fcsel(d3, d18, d19, ne);
armvixlc68cb642014-09-25 18:49:30 +01009949 // The Macro Assembler does not allow al or nv as condition.
armvixl578645f2013-08-15 17:21:42 +01009950 __ fcsel(s4, s16, s17, al);
9951 __ fcsel(d5, d18, d19, nv);
armvixlad96eda2013-06-14 11:42:37 +01009952 END();
9953
9954 RUN();
9955
9956 ASSERT_EQUAL_FP32(1.0, s0);
9957 ASSERT_EQUAL_FP32(2.0, s1);
9958 ASSERT_EQUAL_FP64(3.0, d2);
9959 ASSERT_EQUAL_FP64(4.0, d3);
armvixl578645f2013-08-15 17:21:42 +01009960 ASSERT_EQUAL_FP32(1.0, s4);
9961 ASSERT_EQUAL_FP64(3.0, d5);
armvixlad96eda2013-06-14 11:42:37 +01009962
9963 TEARDOWN();
9964}
9965
9966
9967TEST(fneg) {
9968 SETUP();
9969
9970 START();
9971 __ Fmov(s16, 1.0);
9972 __ Fmov(s17, 0.0);
9973 __ Fmov(s18, kFP32PositiveInfinity);
9974 __ Fmov(d19, 1.0);
9975 __ Fmov(d20, 0.0);
9976 __ Fmov(d21, kFP64PositiveInfinity);
9977
9978 __ Fneg(s0, s16);
9979 __ Fneg(s1, s0);
9980 __ Fneg(s2, s17);
9981 __ Fneg(s3, s2);
9982 __ Fneg(s4, s18);
9983 __ Fneg(s5, s4);
9984 __ Fneg(d6, d19);
9985 __ Fneg(d7, d6);
9986 __ Fneg(d8, d20);
9987 __ Fneg(d9, d8);
9988 __ Fneg(d10, d21);
9989 __ Fneg(d11, d10);
9990 END();
9991
9992 RUN();
9993
9994 ASSERT_EQUAL_FP32(-1.0, s0);
9995 ASSERT_EQUAL_FP32(1.0, s1);
9996 ASSERT_EQUAL_FP32(-0.0, s2);
9997 ASSERT_EQUAL_FP32(0.0, s3);
9998 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
9999 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
10000 ASSERT_EQUAL_FP64(-1.0, d6);
10001 ASSERT_EQUAL_FP64(1.0, d7);
10002 ASSERT_EQUAL_FP64(-0.0, d8);
10003 ASSERT_EQUAL_FP64(0.0, d9);
10004 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
10005 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
10006
10007 TEARDOWN();
10008}
10009
10010
10011TEST(fabs) {
10012 SETUP();
10013
10014 START();
10015 __ Fmov(s16, -1.0);
10016 __ Fmov(s17, -0.0);
10017 __ Fmov(s18, kFP32NegativeInfinity);
10018 __ Fmov(d19, -1.0);
10019 __ Fmov(d20, -0.0);
10020 __ Fmov(d21, kFP64NegativeInfinity);
10021
10022 __ Fabs(s0, s16);
10023 __ Fabs(s1, s0);
10024 __ Fabs(s2, s17);
10025 __ Fabs(s3, s18);
10026 __ Fabs(d4, d19);
10027 __ Fabs(d5, d4);
10028 __ Fabs(d6, d20);
10029 __ Fabs(d7, d21);
10030 END();
10031
10032 RUN();
10033
10034 ASSERT_EQUAL_FP32(1.0, s0);
10035 ASSERT_EQUAL_FP32(1.0, s1);
10036 ASSERT_EQUAL_FP32(0.0, s2);
10037 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
10038 ASSERT_EQUAL_FP64(1.0, d4);
10039 ASSERT_EQUAL_FP64(1.0, d5);
10040 ASSERT_EQUAL_FP64(0.0, d6);
10041 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
10042
10043 TEARDOWN();
10044}
10045
10046
10047TEST(fsqrt) {
10048 SETUP();
10049
10050 START();
10051 __ Fmov(s16, 0.0);
10052 __ Fmov(s17, 1.0);
10053 __ Fmov(s18, 0.25);
10054 __ Fmov(s19, 65536.0);
10055 __ Fmov(s20, -0.0);
10056 __ Fmov(s21, kFP32PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000010057 __ Fmov(s22, -1.0);
10058 __ Fmov(d23, 0.0);
10059 __ Fmov(d24, 1.0);
10060 __ Fmov(d25, 0.25);
10061 __ Fmov(d26, 4294967296.0);
10062 __ Fmov(d27, -0.0);
10063 __ Fmov(d28, kFP64PositiveInfinity);
10064 __ Fmov(d29, -1.0);
armvixlad96eda2013-06-14 11:42:37 +010010065
10066 __ Fsqrt(s0, s16);
10067 __ Fsqrt(s1, s17);
10068 __ Fsqrt(s2, s18);
10069 __ Fsqrt(s3, s19);
10070 __ Fsqrt(s4, s20);
10071 __ Fsqrt(s5, s21);
armvixlb0c8ae22014-03-21 14:03:59 +000010072 __ Fsqrt(s6, s22);
armvixlad96eda2013-06-14 11:42:37 +010010073 __ Fsqrt(d7, d23);
10074 __ Fsqrt(d8, d24);
10075 __ Fsqrt(d9, d25);
10076 __ Fsqrt(d10, d26);
10077 __ Fsqrt(d11, d27);
armvixlb0c8ae22014-03-21 14:03:59 +000010078 __ Fsqrt(d12, d28);
10079 __ Fsqrt(d13, d29);
armvixlad96eda2013-06-14 11:42:37 +010010080 END();
10081
10082 RUN();
10083
10084 ASSERT_EQUAL_FP32(0.0, s0);
10085 ASSERT_EQUAL_FP32(1.0, s1);
10086 ASSERT_EQUAL_FP32(0.5, s2);
10087 ASSERT_EQUAL_FP32(256.0, s3);
10088 ASSERT_EQUAL_FP32(-0.0, s4);
10089 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
armvixlb0c8ae22014-03-21 14:03:59 +000010090 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
10091 ASSERT_EQUAL_FP64(0.0, d7);
10092 ASSERT_EQUAL_FP64(1.0, d8);
10093 ASSERT_EQUAL_FP64(0.5, d9);
10094 ASSERT_EQUAL_FP64(65536.0, d10);
10095 ASSERT_EQUAL_FP64(-0.0, d11);
10096 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d12);
10097 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +010010098
10099 TEARDOWN();
10100}
10101
10102
armvixlf37fdc02014-02-05 13:22:16 +000010103TEST(frinta) {
10104 SETUP();
10105
10106 START();
10107 __ Fmov(s16, 1.0);
10108 __ Fmov(s17, 1.1);
10109 __ Fmov(s18, 1.5);
10110 __ Fmov(s19, 1.9);
10111 __ Fmov(s20, 2.5);
10112 __ Fmov(s21, -1.5);
10113 __ Fmov(s22, -2.5);
10114 __ Fmov(s23, kFP32PositiveInfinity);
10115 __ Fmov(s24, kFP32NegativeInfinity);
10116 __ Fmov(s25, 0.0);
10117 __ Fmov(s26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010118 __ Fmov(s27, -0.2);
armvixlf37fdc02014-02-05 13:22:16 +000010119
10120 __ Frinta(s0, s16);
10121 __ Frinta(s1, s17);
10122 __ Frinta(s2, s18);
10123 __ Frinta(s3, s19);
10124 __ Frinta(s4, s20);
10125 __ Frinta(s5, s21);
10126 __ Frinta(s6, s22);
10127 __ Frinta(s7, s23);
10128 __ Frinta(s8, s24);
10129 __ Frinta(s9, s25);
10130 __ Frinta(s10, s26);
armvixl5799d6c2014-05-01 11:05:00 +010010131 __ Frinta(s11, s27);
armvixlf37fdc02014-02-05 13:22:16 +000010132
10133 __ Fmov(d16, 1.0);
10134 __ Fmov(d17, 1.1);
10135 __ Fmov(d18, 1.5);
10136 __ Fmov(d19, 1.9);
10137 __ Fmov(d20, 2.5);
10138 __ Fmov(d21, -1.5);
10139 __ Fmov(d22, -2.5);
10140 __ Fmov(d23, kFP32PositiveInfinity);
10141 __ Fmov(d24, kFP32NegativeInfinity);
10142 __ Fmov(d25, 0.0);
10143 __ Fmov(d26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010144 __ Fmov(d27, -0.2);
armvixlf37fdc02014-02-05 13:22:16 +000010145
armvixl5799d6c2014-05-01 11:05:00 +010010146 __ Frinta(d12, d16);
10147 __ Frinta(d13, d17);
10148 __ Frinta(d14, d18);
10149 __ Frinta(d15, d19);
10150 __ Frinta(d16, d20);
10151 __ Frinta(d17, d21);
10152 __ Frinta(d18, d22);
10153 __ Frinta(d19, d23);
10154 __ Frinta(d20, d24);
10155 __ Frinta(d21, d25);
10156 __ Frinta(d22, d26);
10157 __ Frinta(d23, d27);
armvixlf37fdc02014-02-05 13:22:16 +000010158 END();
10159
10160 RUN();
10161
10162 ASSERT_EQUAL_FP32(1.0, s0);
10163 ASSERT_EQUAL_FP32(1.0, s1);
10164 ASSERT_EQUAL_FP32(2.0, s2);
10165 ASSERT_EQUAL_FP32(2.0, s3);
10166 ASSERT_EQUAL_FP32(3.0, s4);
10167 ASSERT_EQUAL_FP32(-2.0, s5);
10168 ASSERT_EQUAL_FP32(-3.0, s6);
10169 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10170 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10171 ASSERT_EQUAL_FP32(0.0, s9);
10172 ASSERT_EQUAL_FP32(-0.0, s10);
armvixl5799d6c2014-05-01 11:05:00 +010010173 ASSERT_EQUAL_FP32(-0.0, s11);
armvixlf37fdc02014-02-05 13:22:16 +000010174 ASSERT_EQUAL_FP64(1.0, d12);
armvixl5799d6c2014-05-01 11:05:00 +010010175 ASSERT_EQUAL_FP64(1.0, d13);
armvixlf37fdc02014-02-05 13:22:16 +000010176 ASSERT_EQUAL_FP64(2.0, d14);
armvixl5799d6c2014-05-01 11:05:00 +010010177 ASSERT_EQUAL_FP64(2.0, d15);
10178 ASSERT_EQUAL_FP64(3.0, d16);
10179 ASSERT_EQUAL_FP64(-2.0, d17);
10180 ASSERT_EQUAL_FP64(-3.0, d18);
10181 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10182 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10183 ASSERT_EQUAL_FP64(0.0, d21);
10184 ASSERT_EQUAL_FP64(-0.0, d22);
10185 ASSERT_EQUAL_FP64(-0.0, d23);
10186
10187 TEARDOWN();
10188}
10189
10190
armvixl330dc712014-11-25 10:38:32 +000010191TEST(frinti) {
10192 // VIXL only supports the round-to-nearest FPCR mode, so this test has the
10193 // same results as frintn.
10194 SETUP();
10195
10196 START();
10197 __ Fmov(s16, 1.0);
10198 __ Fmov(s17, 1.1);
10199 __ Fmov(s18, 1.5);
10200 __ Fmov(s19, 1.9);
10201 __ Fmov(s20, 2.5);
10202 __ Fmov(s21, -1.5);
10203 __ Fmov(s22, -2.5);
10204 __ Fmov(s23, kFP32PositiveInfinity);
10205 __ Fmov(s24, kFP32NegativeInfinity);
10206 __ Fmov(s25, 0.0);
10207 __ Fmov(s26, -0.0);
10208 __ Fmov(s27, -0.2);
10209
10210 __ Frinti(s0, s16);
10211 __ Frinti(s1, s17);
10212 __ Frinti(s2, s18);
10213 __ Frinti(s3, s19);
10214 __ Frinti(s4, s20);
10215 __ Frinti(s5, s21);
10216 __ Frinti(s6, s22);
10217 __ Frinti(s7, s23);
10218 __ Frinti(s8, s24);
10219 __ Frinti(s9, s25);
10220 __ Frinti(s10, s26);
10221 __ Frinti(s11, s27);
10222
10223 __ Fmov(d16, 1.0);
10224 __ Fmov(d17, 1.1);
10225 __ Fmov(d18, 1.5);
10226 __ Fmov(d19, 1.9);
10227 __ Fmov(d20, 2.5);
10228 __ Fmov(d21, -1.5);
10229 __ Fmov(d22, -2.5);
10230 __ Fmov(d23, kFP32PositiveInfinity);
10231 __ Fmov(d24, kFP32NegativeInfinity);
10232 __ Fmov(d25, 0.0);
10233 __ Fmov(d26, -0.0);
10234 __ Fmov(d27, -0.2);
10235
10236 __ Frinti(d12, d16);
10237 __ Frinti(d13, d17);
10238 __ Frinti(d14, d18);
10239 __ Frinti(d15, d19);
10240 __ Frinti(d16, d20);
10241 __ Frinti(d17, d21);
10242 __ Frinti(d18, d22);
10243 __ Frinti(d19, d23);
10244 __ Frinti(d20, d24);
10245 __ Frinti(d21, d25);
10246 __ Frinti(d22, d26);
10247 __ Frinti(d23, d27);
10248 END();
10249
10250 RUN();
10251
10252 ASSERT_EQUAL_FP32(1.0, s0);
10253 ASSERT_EQUAL_FP32(1.0, s1);
10254 ASSERT_EQUAL_FP32(2.0, s2);
10255 ASSERT_EQUAL_FP32(2.0, s3);
10256 ASSERT_EQUAL_FP32(2.0, s4);
10257 ASSERT_EQUAL_FP32(-2.0, s5);
10258 ASSERT_EQUAL_FP32(-2.0, s6);
10259 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10260 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10261 ASSERT_EQUAL_FP32(0.0, s9);
10262 ASSERT_EQUAL_FP32(-0.0, s10);
10263 ASSERT_EQUAL_FP32(-0.0, s11);
10264 ASSERT_EQUAL_FP64(1.0, d12);
10265 ASSERT_EQUAL_FP64(1.0, d13);
10266 ASSERT_EQUAL_FP64(2.0, d14);
10267 ASSERT_EQUAL_FP64(2.0, d15);
10268 ASSERT_EQUAL_FP64(2.0, d16);
10269 ASSERT_EQUAL_FP64(-2.0, d17);
10270 ASSERT_EQUAL_FP64(-2.0, d18);
10271 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10272 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10273 ASSERT_EQUAL_FP64(0.0, d21);
10274 ASSERT_EQUAL_FP64(-0.0, d22);
10275 ASSERT_EQUAL_FP64(-0.0, d23);
10276
10277 TEARDOWN();
10278}
10279
10280
armvixl5799d6c2014-05-01 11:05:00 +010010281TEST(frintm) {
10282 SETUP();
10283
10284 START();
10285 __ Fmov(s16, 1.0);
10286 __ Fmov(s17, 1.1);
10287 __ Fmov(s18, 1.5);
10288 __ Fmov(s19, 1.9);
10289 __ Fmov(s20, 2.5);
10290 __ Fmov(s21, -1.5);
10291 __ Fmov(s22, -2.5);
10292 __ Fmov(s23, kFP32PositiveInfinity);
10293 __ Fmov(s24, kFP32NegativeInfinity);
10294 __ Fmov(s25, 0.0);
10295 __ Fmov(s26, -0.0);
10296 __ Fmov(s27, -0.2);
10297
10298 __ Frintm(s0, s16);
10299 __ Frintm(s1, s17);
10300 __ Frintm(s2, s18);
10301 __ Frintm(s3, s19);
10302 __ Frintm(s4, s20);
10303 __ Frintm(s5, s21);
10304 __ Frintm(s6, s22);
10305 __ Frintm(s7, s23);
10306 __ Frintm(s8, s24);
10307 __ Frintm(s9, s25);
10308 __ Frintm(s10, s26);
10309 __ Frintm(s11, s27);
10310
10311 __ Fmov(d16, 1.0);
10312 __ Fmov(d17, 1.1);
10313 __ Fmov(d18, 1.5);
10314 __ Fmov(d19, 1.9);
10315 __ Fmov(d20, 2.5);
10316 __ Fmov(d21, -1.5);
10317 __ Fmov(d22, -2.5);
10318 __ Fmov(d23, kFP32PositiveInfinity);
10319 __ Fmov(d24, kFP32NegativeInfinity);
10320 __ Fmov(d25, 0.0);
10321 __ Fmov(d26, -0.0);
10322 __ Fmov(d27, -0.2);
10323
10324 __ Frintm(d12, d16);
10325 __ Frintm(d13, d17);
10326 __ Frintm(d14, d18);
10327 __ Frintm(d15, d19);
10328 __ Frintm(d16, d20);
10329 __ Frintm(d17, d21);
10330 __ Frintm(d18, d22);
10331 __ Frintm(d19, d23);
10332 __ Frintm(d20, d24);
10333 __ Frintm(d21, d25);
10334 __ Frintm(d22, d26);
10335 __ Frintm(d23, d27);
10336 END();
10337
10338 RUN();
10339
10340 ASSERT_EQUAL_FP32(1.0, s0);
10341 ASSERT_EQUAL_FP32(1.0, s1);
10342 ASSERT_EQUAL_FP32(1.0, s2);
10343 ASSERT_EQUAL_FP32(1.0, s3);
10344 ASSERT_EQUAL_FP32(2.0, s4);
10345 ASSERT_EQUAL_FP32(-2.0, s5);
10346 ASSERT_EQUAL_FP32(-3.0, s6);
10347 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10348 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10349 ASSERT_EQUAL_FP32(0.0, s9);
10350 ASSERT_EQUAL_FP32(-0.0, s10);
10351 ASSERT_EQUAL_FP32(-1.0, s11);
10352 ASSERT_EQUAL_FP64(1.0, d12);
10353 ASSERT_EQUAL_FP64(1.0, d13);
10354 ASSERT_EQUAL_FP64(1.0, d14);
10355 ASSERT_EQUAL_FP64(1.0, d15);
10356 ASSERT_EQUAL_FP64(2.0, d16);
10357 ASSERT_EQUAL_FP64(-2.0, d17);
10358 ASSERT_EQUAL_FP64(-3.0, d18);
10359 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10360 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10361 ASSERT_EQUAL_FP64(0.0, d21);
10362 ASSERT_EQUAL_FP64(-0.0, d22);
10363 ASSERT_EQUAL_FP64(-1.0, d23);
armvixlf37fdc02014-02-05 13:22:16 +000010364
10365 TEARDOWN();
10366}
10367
10368
armvixlad96eda2013-06-14 11:42:37 +010010369TEST(frintn) {
10370 SETUP();
10371
10372 START();
10373 __ Fmov(s16, 1.0);
10374 __ Fmov(s17, 1.1);
10375 __ Fmov(s18, 1.5);
10376 __ Fmov(s19, 1.9);
10377 __ Fmov(s20, 2.5);
10378 __ Fmov(s21, -1.5);
10379 __ Fmov(s22, -2.5);
10380 __ Fmov(s23, kFP32PositiveInfinity);
10381 __ Fmov(s24, kFP32NegativeInfinity);
10382 __ Fmov(s25, 0.0);
10383 __ Fmov(s26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010384 __ Fmov(s27, -0.2);
armvixlad96eda2013-06-14 11:42:37 +010010385
10386 __ Frintn(s0, s16);
10387 __ Frintn(s1, s17);
10388 __ Frintn(s2, s18);
10389 __ Frintn(s3, s19);
10390 __ Frintn(s4, s20);
10391 __ Frintn(s5, s21);
10392 __ Frintn(s6, s22);
10393 __ Frintn(s7, s23);
10394 __ Frintn(s8, s24);
10395 __ Frintn(s9, s25);
10396 __ Frintn(s10, s26);
armvixl5799d6c2014-05-01 11:05:00 +010010397 __ Frintn(s11, s27);
armvixlad96eda2013-06-14 11:42:37 +010010398
10399 __ Fmov(d16, 1.0);
10400 __ Fmov(d17, 1.1);
10401 __ Fmov(d18, 1.5);
10402 __ Fmov(d19, 1.9);
10403 __ Fmov(d20, 2.5);
10404 __ Fmov(d21, -1.5);
10405 __ Fmov(d22, -2.5);
10406 __ Fmov(d23, kFP32PositiveInfinity);
10407 __ Fmov(d24, kFP32NegativeInfinity);
10408 __ Fmov(d25, 0.0);
10409 __ Fmov(d26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010410 __ Fmov(d27, -0.2);
armvixlad96eda2013-06-14 11:42:37 +010010411
armvixl5799d6c2014-05-01 11:05:00 +010010412 __ Frintn(d12, d16);
10413 __ Frintn(d13, d17);
10414 __ Frintn(d14, d18);
10415 __ Frintn(d15, d19);
10416 __ Frintn(d16, d20);
10417 __ Frintn(d17, d21);
10418 __ Frintn(d18, d22);
10419 __ Frintn(d19, d23);
10420 __ Frintn(d20, d24);
10421 __ Frintn(d21, d25);
10422 __ Frintn(d22, d26);
10423 __ Frintn(d23, d27);
armvixlad96eda2013-06-14 11:42:37 +010010424 END();
10425
10426 RUN();
10427
10428 ASSERT_EQUAL_FP32(1.0, s0);
10429 ASSERT_EQUAL_FP32(1.0, s1);
10430 ASSERT_EQUAL_FP32(2.0, s2);
10431 ASSERT_EQUAL_FP32(2.0, s3);
10432 ASSERT_EQUAL_FP32(2.0, s4);
10433 ASSERT_EQUAL_FP32(-2.0, s5);
10434 ASSERT_EQUAL_FP32(-2.0, s6);
10435 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10436 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10437 ASSERT_EQUAL_FP32(0.0, s9);
10438 ASSERT_EQUAL_FP32(-0.0, s10);
armvixl5799d6c2014-05-01 11:05:00 +010010439 ASSERT_EQUAL_FP32(-0.0, s11);
armvixlad96eda2013-06-14 11:42:37 +010010440 ASSERT_EQUAL_FP64(1.0, d12);
armvixl5799d6c2014-05-01 11:05:00 +010010441 ASSERT_EQUAL_FP64(1.0, d13);
armvixlad96eda2013-06-14 11:42:37 +010010442 ASSERT_EQUAL_FP64(2.0, d14);
10443 ASSERT_EQUAL_FP64(2.0, d15);
armvixl5799d6c2014-05-01 11:05:00 +010010444 ASSERT_EQUAL_FP64(2.0, d16);
armvixlad96eda2013-06-14 11:42:37 +010010445 ASSERT_EQUAL_FP64(-2.0, d17);
armvixl5799d6c2014-05-01 11:05:00 +010010446 ASSERT_EQUAL_FP64(-2.0, d18);
10447 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10448 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10449 ASSERT_EQUAL_FP64(0.0, d21);
10450 ASSERT_EQUAL_FP64(-0.0, d22);
10451 ASSERT_EQUAL_FP64(-0.0, d23);
armvixlad96eda2013-06-14 11:42:37 +010010452
10453 TEARDOWN();
10454}
10455
10456
armvixl330dc712014-11-25 10:38:32 +000010457TEST(frintp) {
10458 SETUP();
10459
10460 START();
10461 __ Fmov(s16, 1.0);
10462 __ Fmov(s17, 1.1);
10463 __ Fmov(s18, 1.5);
10464 __ Fmov(s19, 1.9);
10465 __ Fmov(s20, 2.5);
10466 __ Fmov(s21, -1.5);
10467 __ Fmov(s22, -2.5);
10468 __ Fmov(s23, kFP32PositiveInfinity);
10469 __ Fmov(s24, kFP32NegativeInfinity);
10470 __ Fmov(s25, 0.0);
10471 __ Fmov(s26, -0.0);
10472 __ Fmov(s27, -0.2);
10473
10474 __ Frintp(s0, s16);
10475 __ Frintp(s1, s17);
10476 __ Frintp(s2, s18);
10477 __ Frintp(s3, s19);
10478 __ Frintp(s4, s20);
10479 __ Frintp(s5, s21);
10480 __ Frintp(s6, s22);
10481 __ Frintp(s7, s23);
10482 __ Frintp(s8, s24);
10483 __ Frintp(s9, s25);
10484 __ Frintp(s10, s26);
10485 __ Frintp(s11, s27);
10486
10487 __ Fmov(d16, 1.0);
10488 __ Fmov(d17, 1.1);
10489 __ Fmov(d18, 1.5);
10490 __ Fmov(d19, 1.9);
10491 __ Fmov(d20, 2.5);
10492 __ Fmov(d21, -1.5);
10493 __ Fmov(d22, -2.5);
10494 __ Fmov(d23, kFP32PositiveInfinity);
10495 __ Fmov(d24, kFP32NegativeInfinity);
10496 __ Fmov(d25, 0.0);
10497 __ Fmov(d26, -0.0);
10498 __ Fmov(d27, -0.2);
10499
10500 __ Frintp(d12, d16);
10501 __ Frintp(d13, d17);
10502 __ Frintp(d14, d18);
10503 __ Frintp(d15, d19);
10504 __ Frintp(d16, d20);
10505 __ Frintp(d17, d21);
10506 __ Frintp(d18, d22);
10507 __ Frintp(d19, d23);
10508 __ Frintp(d20, d24);
10509 __ Frintp(d21, d25);
10510 __ Frintp(d22, d26);
10511 __ Frintp(d23, d27);
10512 END();
10513
10514 RUN();
10515
10516 ASSERT_EQUAL_FP32(1.0, s0);
10517 ASSERT_EQUAL_FP32(2.0, s1);
10518 ASSERT_EQUAL_FP32(2.0, s2);
10519 ASSERT_EQUAL_FP32(2.0, s3);
10520 ASSERT_EQUAL_FP32(3.0, s4);
10521 ASSERT_EQUAL_FP32(-1.0, s5);
10522 ASSERT_EQUAL_FP32(-2.0, s6);
10523 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10524 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10525 ASSERT_EQUAL_FP32(0.0, s9);
10526 ASSERT_EQUAL_FP32(-0.0, s10);
10527 ASSERT_EQUAL_FP32(-0.0, s11);
10528 ASSERT_EQUAL_FP64(1.0, d12);
10529 ASSERT_EQUAL_FP64(2.0, d13);
10530 ASSERT_EQUAL_FP64(2.0, d14);
10531 ASSERT_EQUAL_FP64(2.0, d15);
10532 ASSERT_EQUAL_FP64(3.0, d16);
10533 ASSERT_EQUAL_FP64(-1.0, d17);
10534 ASSERT_EQUAL_FP64(-2.0, d18);
10535 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10536 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10537 ASSERT_EQUAL_FP64(0.0, d21);
10538 ASSERT_EQUAL_FP64(-0.0, d22);
10539 ASSERT_EQUAL_FP64(-0.0, d23);
10540
10541 TEARDOWN();
10542}
10543
10544
10545TEST(frintx) {
10546 // VIXL only supports the round-to-nearest FPCR mode, and it doesn't support
10547 // FP exceptions, so this test has the same results as frintn (and frinti).
10548 SETUP();
10549
10550 START();
10551 __ Fmov(s16, 1.0);
10552 __ Fmov(s17, 1.1);
10553 __ Fmov(s18, 1.5);
10554 __ Fmov(s19, 1.9);
10555 __ Fmov(s20, 2.5);
10556 __ Fmov(s21, -1.5);
10557 __ Fmov(s22, -2.5);
10558 __ Fmov(s23, kFP32PositiveInfinity);
10559 __ Fmov(s24, kFP32NegativeInfinity);
10560 __ Fmov(s25, 0.0);
10561 __ Fmov(s26, -0.0);
10562 __ Fmov(s27, -0.2);
10563
10564 __ Frintx(s0, s16);
10565 __ Frintx(s1, s17);
10566 __ Frintx(s2, s18);
10567 __ Frintx(s3, s19);
10568 __ Frintx(s4, s20);
10569 __ Frintx(s5, s21);
10570 __ Frintx(s6, s22);
10571 __ Frintx(s7, s23);
10572 __ Frintx(s8, s24);
10573 __ Frintx(s9, s25);
10574 __ Frintx(s10, s26);
10575 __ Frintx(s11, s27);
10576
10577 __ Fmov(d16, 1.0);
10578 __ Fmov(d17, 1.1);
10579 __ Fmov(d18, 1.5);
10580 __ Fmov(d19, 1.9);
10581 __ Fmov(d20, 2.5);
10582 __ Fmov(d21, -1.5);
10583 __ Fmov(d22, -2.5);
10584 __ Fmov(d23, kFP32PositiveInfinity);
10585 __ Fmov(d24, kFP32NegativeInfinity);
10586 __ Fmov(d25, 0.0);
10587 __ Fmov(d26, -0.0);
10588 __ Fmov(d27, -0.2);
10589
10590 __ Frintx(d12, d16);
10591 __ Frintx(d13, d17);
10592 __ Frintx(d14, d18);
10593 __ Frintx(d15, d19);
10594 __ Frintx(d16, d20);
10595 __ Frintx(d17, d21);
10596 __ Frintx(d18, d22);
10597 __ Frintx(d19, d23);
10598 __ Frintx(d20, d24);
10599 __ Frintx(d21, d25);
10600 __ Frintx(d22, d26);
10601 __ Frintx(d23, d27);
10602 END();
10603
10604 RUN();
10605
10606 ASSERT_EQUAL_FP32(1.0, s0);
10607 ASSERT_EQUAL_FP32(1.0, s1);
10608 ASSERT_EQUAL_FP32(2.0, s2);
10609 ASSERT_EQUAL_FP32(2.0, s3);
10610 ASSERT_EQUAL_FP32(2.0, s4);
10611 ASSERT_EQUAL_FP32(-2.0, s5);
10612 ASSERT_EQUAL_FP32(-2.0, s6);
10613 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10614 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10615 ASSERT_EQUAL_FP32(0.0, s9);
10616 ASSERT_EQUAL_FP32(-0.0, s10);
10617 ASSERT_EQUAL_FP32(-0.0, s11);
10618 ASSERT_EQUAL_FP64(1.0, d12);
10619 ASSERT_EQUAL_FP64(1.0, d13);
10620 ASSERT_EQUAL_FP64(2.0, d14);
10621 ASSERT_EQUAL_FP64(2.0, d15);
10622 ASSERT_EQUAL_FP64(2.0, d16);
10623 ASSERT_EQUAL_FP64(-2.0, d17);
10624 ASSERT_EQUAL_FP64(-2.0, d18);
10625 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10626 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10627 ASSERT_EQUAL_FP64(0.0, d21);
10628 ASSERT_EQUAL_FP64(-0.0, d22);
10629 ASSERT_EQUAL_FP64(-0.0, d23);
10630
10631 TEARDOWN();
10632}
10633
10634
armvixlad96eda2013-06-14 11:42:37 +010010635TEST(frintz) {
10636 SETUP();
10637
10638 START();
10639 __ Fmov(s16, 1.0);
10640 __ Fmov(s17, 1.1);
10641 __ Fmov(s18, 1.5);
10642 __ Fmov(s19, 1.9);
10643 __ Fmov(s20, 2.5);
10644 __ Fmov(s21, -1.5);
10645 __ Fmov(s22, -2.5);
10646 __ Fmov(s23, kFP32PositiveInfinity);
10647 __ Fmov(s24, kFP32NegativeInfinity);
10648 __ Fmov(s25, 0.0);
10649 __ Fmov(s26, -0.0);
10650
10651 __ Frintz(s0, s16);
10652 __ Frintz(s1, s17);
10653 __ Frintz(s2, s18);
10654 __ Frintz(s3, s19);
10655 __ Frintz(s4, s20);
10656 __ Frintz(s5, s21);
10657 __ Frintz(s6, s22);
10658 __ Frintz(s7, s23);
10659 __ Frintz(s8, s24);
10660 __ Frintz(s9, s25);
10661 __ Frintz(s10, s26);
10662
10663 __ Fmov(d16, 1.0);
10664 __ Fmov(d17, 1.1);
10665 __ Fmov(d18, 1.5);
10666 __ Fmov(d19, 1.9);
10667 __ Fmov(d20, 2.5);
10668 __ Fmov(d21, -1.5);
10669 __ Fmov(d22, -2.5);
10670 __ Fmov(d23, kFP32PositiveInfinity);
10671 __ Fmov(d24, kFP32NegativeInfinity);
10672 __ Fmov(d25, 0.0);
10673 __ Fmov(d26, -0.0);
10674
10675 __ Frintz(d11, d16);
10676 __ Frintz(d12, d17);
10677 __ Frintz(d13, d18);
10678 __ Frintz(d14, d19);
10679 __ Frintz(d15, d20);
10680 __ Frintz(d16, d21);
10681 __ Frintz(d17, d22);
10682 __ Frintz(d18, d23);
10683 __ Frintz(d19, d24);
10684 __ Frintz(d20, d25);
10685 __ Frintz(d21, d26);
10686 END();
10687
10688 RUN();
10689
10690 ASSERT_EQUAL_FP32(1.0, s0);
10691 ASSERT_EQUAL_FP32(1.0, s1);
10692 ASSERT_EQUAL_FP32(1.0, s2);
10693 ASSERT_EQUAL_FP32(1.0, s3);
10694 ASSERT_EQUAL_FP32(2.0, s4);
10695 ASSERT_EQUAL_FP32(-1.0, s5);
10696 ASSERT_EQUAL_FP32(-2.0, s6);
10697 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10698 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10699 ASSERT_EQUAL_FP32(0.0, s9);
10700 ASSERT_EQUAL_FP32(-0.0, s10);
10701 ASSERT_EQUAL_FP64(1.0, d11);
10702 ASSERT_EQUAL_FP64(1.0, d12);
10703 ASSERT_EQUAL_FP64(1.0, d13);
10704 ASSERT_EQUAL_FP64(1.0, d14);
10705 ASSERT_EQUAL_FP64(2.0, d15);
10706 ASSERT_EQUAL_FP64(-1.0, d16);
10707 ASSERT_EQUAL_FP64(-2.0, d17);
10708 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
10709 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
10710 ASSERT_EQUAL_FP64(0.0, d20);
10711 ASSERT_EQUAL_FP64(-0.0, d21);
10712
10713 TEARDOWN();
10714}
10715
10716
armvixl578645f2013-08-15 17:21:42 +010010717TEST(fcvt_ds) {
armvixlad96eda2013-06-14 11:42:37 +010010718 SETUP();
10719
10720 START();
10721 __ Fmov(s16, 1.0);
10722 __ Fmov(s17, 1.1);
10723 __ Fmov(s18, 1.5);
10724 __ Fmov(s19, 1.9);
10725 __ Fmov(s20, 2.5);
10726 __ Fmov(s21, -1.5);
10727 __ Fmov(s22, -2.5);
10728 __ Fmov(s23, kFP32PositiveInfinity);
10729 __ Fmov(s24, kFP32NegativeInfinity);
10730 __ Fmov(s25, 0.0);
10731 __ Fmov(s26, -0.0);
armvixl578645f2013-08-15 17:21:42 +010010732 __ Fmov(s27, FLT_MAX);
10733 __ Fmov(s28, FLT_MIN);
10734 __ Fmov(s29, rawbits_to_float(0x7fc12345)); // Quiet NaN.
10735 __ Fmov(s30, rawbits_to_float(0x7f812345)); // Signalling NaN.
armvixlad96eda2013-06-14 11:42:37 +010010736
10737 __ Fcvt(d0, s16);
10738 __ Fcvt(d1, s17);
10739 __ Fcvt(d2, s18);
10740 __ Fcvt(d3, s19);
10741 __ Fcvt(d4, s20);
10742 __ Fcvt(d5, s21);
10743 __ Fcvt(d6, s22);
10744 __ Fcvt(d7, s23);
10745 __ Fcvt(d8, s24);
10746 __ Fcvt(d9, s25);
10747 __ Fcvt(d10, s26);
armvixl578645f2013-08-15 17:21:42 +010010748 __ Fcvt(d11, s27);
10749 __ Fcvt(d12, s28);
10750 __ Fcvt(d13, s29);
10751 __ Fcvt(d14, s30);
armvixlad96eda2013-06-14 11:42:37 +010010752 END();
10753
10754 RUN();
10755
10756 ASSERT_EQUAL_FP64(1.0f, d0);
10757 ASSERT_EQUAL_FP64(1.1f, d1);
10758 ASSERT_EQUAL_FP64(1.5f, d2);
10759 ASSERT_EQUAL_FP64(1.9f, d3);
10760 ASSERT_EQUAL_FP64(2.5f, d4);
10761 ASSERT_EQUAL_FP64(-1.5f, d5);
10762 ASSERT_EQUAL_FP64(-2.5f, d6);
10763 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
10764 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8);
10765 ASSERT_EQUAL_FP64(0.0f, d9);
10766 ASSERT_EQUAL_FP64(-0.0f, d10);
armvixl578645f2013-08-15 17:21:42 +010010767 ASSERT_EQUAL_FP64(FLT_MAX, d11);
10768 ASSERT_EQUAL_FP64(FLT_MIN, d12);
10769
10770 // Check that the NaN payload is preserved according to A64 conversion rules:
10771 // - The sign bit is preserved.
10772 // - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
10773 // - The remaining mantissa bits are copied until they run out.
10774 // - The low-order bits that haven't already been assigned are set to 0.
10775 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d13);
10776 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d14);
armvixlad96eda2013-06-14 11:42:37 +010010777
10778 TEARDOWN();
10779}
10780
10781
armvixl578645f2013-08-15 17:21:42 +010010782TEST(fcvt_sd) {
armvixl5799d6c2014-05-01 11:05:00 +010010783 // Test simple conversions here. Complex behaviour (such as rounding
10784 // specifics) are tested in the simulator tests.
armvixl578645f2013-08-15 17:21:42 +010010785
armvixl5799d6c2014-05-01 11:05:00 +010010786 SETUP();
armvixl578645f2013-08-15 17:21:42 +010010787
armvixl5799d6c2014-05-01 11:05:00 +010010788 START();
10789 __ Fmov(d16, 1.0);
10790 __ Fmov(d17, 1.1);
10791 __ Fmov(d18, 1.5);
10792 __ Fmov(d19, 1.9);
10793 __ Fmov(d20, 2.5);
10794 __ Fmov(d21, -1.5);
10795 __ Fmov(d22, -2.5);
10796 __ Fmov(d23, kFP32PositiveInfinity);
10797 __ Fmov(d24, kFP32NegativeInfinity);
10798 __ Fmov(d25, 0.0);
10799 __ Fmov(d26, -0.0);
10800 __ Fmov(d27, FLT_MAX);
10801 __ Fmov(d28, FLT_MIN);
10802 __ Fmov(d29, rawbits_to_double(0x7ff82468a0000000)); // Quiet NaN.
10803 __ Fmov(d30, rawbits_to_double(0x7ff02468a0000000)); // Signalling NaN.
armvixl578645f2013-08-15 17:21:42 +010010804
armvixl5799d6c2014-05-01 11:05:00 +010010805 __ Fcvt(s0, d16);
10806 __ Fcvt(s1, d17);
10807 __ Fcvt(s2, d18);
10808 __ Fcvt(s3, d19);
10809 __ Fcvt(s4, d20);
10810 __ Fcvt(s5, d21);
10811 __ Fcvt(s6, d22);
10812 __ Fcvt(s7, d23);
10813 __ Fcvt(s8, d24);
10814 __ Fcvt(s9, d25);
10815 __ Fcvt(s10, d26);
10816 __ Fcvt(s11, d27);
10817 __ Fcvt(s12, d28);
10818 __ Fcvt(s13, d29);
10819 __ Fcvt(s14, d30);
10820 END();
armvixl578645f2013-08-15 17:21:42 +010010821
armvixl5799d6c2014-05-01 11:05:00 +010010822 RUN();
armvixl578645f2013-08-15 17:21:42 +010010823
armvixl5799d6c2014-05-01 11:05:00 +010010824 ASSERT_EQUAL_FP32(1.0f, s0);
10825 ASSERT_EQUAL_FP32(1.1f, s1);
10826 ASSERT_EQUAL_FP32(1.5f, s2);
10827 ASSERT_EQUAL_FP32(1.9f, s3);
10828 ASSERT_EQUAL_FP32(2.5f, s4);
10829 ASSERT_EQUAL_FP32(-1.5f, s5);
10830 ASSERT_EQUAL_FP32(-2.5f, s6);
10831 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10832 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10833 ASSERT_EQUAL_FP32(0.0f, s9);
10834 ASSERT_EQUAL_FP32(-0.0f, s10);
10835 ASSERT_EQUAL_FP32(FLT_MAX, s11);
10836 ASSERT_EQUAL_FP32(FLT_MIN, s12);
armvixl578645f2013-08-15 17:21:42 +010010837
armvixl5799d6c2014-05-01 11:05:00 +010010838 // Check that the NaN payload is preserved according to A64 conversion rules:
10839 // - The sign bit is preserved.
10840 // - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
10841 // - The remaining mantissa bits are copied until they run out.
10842 // - The low-order bits that haven't already been assigned are set to 0.
10843 ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s13);
10844 ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s14);
armvixl578645f2013-08-15 17:21:42 +010010845
armvixl5799d6c2014-05-01 11:05:00 +010010846 TEARDOWN();
armvixl578645f2013-08-15 17:21:42 +010010847}
10848
10849
armvixl5289c592015-03-02 13:52:04 +000010850TEST(fcvt_half) {
10851 SETUP();
10852
10853 START();
10854 Label done;
10855 {
10856 // Check all exact conversions from half to float and back.
10857 Label ok, fail;
10858 __ Mov(w0, 0);
10859 for (int i = 0; i < 0xffff; i += 3) {
10860 if ((i & 0x7c00) == 0x7c00) continue;
10861 __ Mov(w1, i);
10862 __ Fmov(s1, w1);
10863 __ Fcvt(s2, h1);
10864 __ Fcvt(h2, s2);
10865 __ Fmov(w2, s2);
10866 __ Cmp(w1, w2);
10867 __ B(&fail, ne);
10868 }
10869 __ B(&ok);
10870 __ Bind(&fail);
10871 __ Mov(w0, 1);
10872 __ B(&done);
10873 __ Bind(&ok);
10874 }
10875 {
10876 // Check all exact conversions from half to double and back.
10877 Label ok, fail;
10878 for (int i = 0; i < 0xffff; i += 3) {
10879 if ((i & 0x7c00) == 0x7c00) continue;
10880 __ Mov(w1, i);
10881 __ Fmov(s1, w1);
10882 __ Fcvt(d2, h1);
10883 __ Fcvt(h2, d2);
10884 __ Mov(w2, v2.S(), 0);
10885 __ Cmp(w1, w2);
10886 __ B(&fail, ne);
10887 }
10888 __ B(&ok);
10889 __ Bind(&fail);
10890 __ Mov(w0, 2);
10891 __ Bind(&ok);
10892 }
10893 __ Bind(&done);
10894
10895 // Check some other interesting values.
10896 __ Fmov(s0, kFP32PositiveInfinity);
10897 __ Fmov(s1, kFP32NegativeInfinity);
10898 __ Fmov(s2, 65504); // Max half precision.
10899 __ Fmov(s3, 6.10352e-5); // Min positive normal.
10900 __ Fmov(s4, 6.09756e-5); // Max subnormal.
10901 __ Fmov(s5, 5.96046e-8); // Min positive subnormal.
10902 __ Fmov(s6, 5e-9); // Not representable -> zero.
10903 __ Fmov(s7, -0.0);
10904 __ Fcvt(h0, s0);
10905 __ Fcvt(h1, s1);
10906 __ Fcvt(h2, s2);
10907 __ Fcvt(h3, s3);
10908 __ Fcvt(h4, s4);
10909 __ Fcvt(h5, s5);
10910 __ Fcvt(h6, s6);
10911 __ Fcvt(h7, s7);
10912
10913 __ Fmov(d20, kFP64PositiveInfinity);
10914 __ Fmov(d21, kFP64NegativeInfinity);
10915 __ Fmov(d22, 65504); // Max half precision.
10916 __ Fmov(d23, 6.10352e-5); // Min positive normal.
10917 __ Fmov(d24, 6.09756e-5); // Max subnormal.
10918 __ Fmov(d25, 5.96046e-8); // Min positive subnormal.
10919 __ Fmov(d26, 5e-9); // Not representable -> zero.
10920 __ Fmov(d27, -0.0);
10921 __ Fcvt(h20, d20);
10922 __ Fcvt(h21, d21);
10923 __ Fcvt(h22, d22);
10924 __ Fcvt(h23, d23);
10925 __ Fcvt(h24, d24);
10926 __ Fcvt(h25, d25);
10927 __ Fcvt(h26, d26);
10928 __ Fcvt(h27, d27);
10929 END();
10930
10931 RUN();
10932
10933 ASSERT_EQUAL_32(0, w0); // 1 => float failed, 2 => double failed.
10934 ASSERT_EQUAL_128(0, kFP16PositiveInfinity, q0);
10935 ASSERT_EQUAL_128(0, kFP16NegativeInfinity, q1);
10936 ASSERT_EQUAL_128(0, 0x7bff, q2);
10937 ASSERT_EQUAL_128(0, 0x0400, q3);
10938 ASSERT_EQUAL_128(0, 0x03ff, q4);
10939 ASSERT_EQUAL_128(0, 0x0001, q5);
10940 ASSERT_EQUAL_128(0, 0, q6);
10941 ASSERT_EQUAL_128(0, 0x8000, q7);
10942 ASSERT_EQUAL_128(0, kFP16PositiveInfinity, q20);
10943 ASSERT_EQUAL_128(0, kFP16NegativeInfinity, q21);
10944 ASSERT_EQUAL_128(0, 0x7bff, q22);
10945 ASSERT_EQUAL_128(0, 0x0400, q23);
10946 ASSERT_EQUAL_128(0, 0x03ff, q24);
10947 ASSERT_EQUAL_128(0, 0x0001, q25);
10948 ASSERT_EQUAL_128(0, 0, q26);
10949 ASSERT_EQUAL_128(0, 0x8000, q27);
10950 TEARDOWN();
10951}
10952
10953
armvixlf37fdc02014-02-05 13:22:16 +000010954TEST(fcvtas) {
10955 SETUP();
10956
10957 START();
10958 __ Fmov(s0, 1.0);
10959 __ Fmov(s1, 1.1);
10960 __ Fmov(s2, 2.5);
10961 __ Fmov(s3, -2.5);
10962 __ Fmov(s4, kFP32PositiveInfinity);
10963 __ Fmov(s5, kFP32NegativeInfinity);
10964 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
10965 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
10966 __ Fmov(d8, 1.0);
10967 __ Fmov(d9, 1.1);
10968 __ Fmov(d10, 2.5);
10969 __ Fmov(d11, -2.5);
10970 __ Fmov(d12, kFP64PositiveInfinity);
10971 __ Fmov(d13, kFP64NegativeInfinity);
10972 __ Fmov(d14, kWMaxInt - 1);
10973 __ Fmov(d15, kWMinInt + 1);
10974 __ Fmov(s17, 1.1);
10975 __ Fmov(s18, 2.5);
10976 __ Fmov(s19, -2.5);
10977 __ Fmov(s20, kFP32PositiveInfinity);
10978 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000010979 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +000010980 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
10981 __ Fmov(d24, 1.1);
10982 __ Fmov(d25, 2.5);
10983 __ Fmov(d26, -2.5);
10984 __ Fmov(d27, kFP64PositiveInfinity);
10985 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000010986 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +000010987 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
10988
10989 __ Fcvtas(w0, s0);
10990 __ Fcvtas(w1, s1);
10991 __ Fcvtas(w2, s2);
10992 __ Fcvtas(w3, s3);
10993 __ Fcvtas(w4, s4);
10994 __ Fcvtas(w5, s5);
10995 __ Fcvtas(w6, s6);
10996 __ Fcvtas(w7, s7);
10997 __ Fcvtas(w8, d8);
10998 __ Fcvtas(w9, d9);
10999 __ Fcvtas(w10, d10);
11000 __ Fcvtas(w11, d11);
11001 __ Fcvtas(w12, d12);
11002 __ Fcvtas(w13, d13);
11003 __ Fcvtas(w14, d14);
11004 __ Fcvtas(w15, d15);
11005 __ Fcvtas(x17, s17);
11006 __ Fcvtas(x18, s18);
11007 __ Fcvtas(x19, s19);
11008 __ Fcvtas(x20, s20);
11009 __ Fcvtas(x21, s21);
11010 __ Fcvtas(x22, s22);
11011 __ Fcvtas(x23, s23);
11012 __ Fcvtas(x24, d24);
11013 __ Fcvtas(x25, d25);
11014 __ Fcvtas(x26, d26);
11015 __ Fcvtas(x27, d27);
11016 __ Fcvtas(x28, d28);
11017 __ Fcvtas(x29, d29);
11018 __ Fcvtas(x30, d30);
11019 END();
11020
11021 RUN();
11022
11023 ASSERT_EQUAL_64(1, x0);
11024 ASSERT_EQUAL_64(1, x1);
11025 ASSERT_EQUAL_64(3, x2);
11026 ASSERT_EQUAL_64(0xfffffffd, x3);
11027 ASSERT_EQUAL_64(0x7fffffff, x4);
11028 ASSERT_EQUAL_64(0x80000000, x5);
11029 ASSERT_EQUAL_64(0x7fffff80, x6);
11030 ASSERT_EQUAL_64(0x80000080, x7);
11031 ASSERT_EQUAL_64(1, x8);
11032 ASSERT_EQUAL_64(1, x9);
11033 ASSERT_EQUAL_64(3, x10);
11034 ASSERT_EQUAL_64(0xfffffffd, x11);
11035 ASSERT_EQUAL_64(0x7fffffff, x12);
11036 ASSERT_EQUAL_64(0x80000000, x13);
11037 ASSERT_EQUAL_64(0x7ffffffe, x14);
11038 ASSERT_EQUAL_64(0x80000001, x15);
11039 ASSERT_EQUAL_64(1, x17);
11040 ASSERT_EQUAL_64(3, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011041 ASSERT_EQUAL_64(0xfffffffffffffffd, x19);
11042 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11043 ASSERT_EQUAL_64(0x8000000000000000, x21);
11044 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11045 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlf37fdc02014-02-05 13:22:16 +000011046 ASSERT_EQUAL_64(1, x24);
11047 ASSERT_EQUAL_64(3, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011048 ASSERT_EQUAL_64(0xfffffffffffffffd, x26);
11049 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11050 ASSERT_EQUAL_64(0x8000000000000000, x28);
11051 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11052 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlf37fdc02014-02-05 13:22:16 +000011053
11054 TEARDOWN();
11055}
11056
11057
11058TEST(fcvtau) {
11059 SETUP();
11060
11061 START();
11062 __ Fmov(s0, 1.0);
11063 __ Fmov(s1, 1.1);
11064 __ Fmov(s2, 2.5);
11065 __ Fmov(s3, -2.5);
11066 __ Fmov(s4, kFP32PositiveInfinity);
11067 __ Fmov(s5, kFP32NegativeInfinity);
11068 __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX.
11069 __ Fmov(d8, 1.0);
11070 __ Fmov(d9, 1.1);
11071 __ Fmov(d10, 2.5);
11072 __ Fmov(d11, -2.5);
11073 __ Fmov(d12, kFP64PositiveInfinity);
11074 __ Fmov(d13, kFP64NegativeInfinity);
11075 __ Fmov(d14, 0xfffffffe);
11076 __ Fmov(s16, 1.0);
11077 __ Fmov(s17, 1.1);
11078 __ Fmov(s18, 2.5);
11079 __ Fmov(s19, -2.5);
11080 __ Fmov(s20, kFP32PositiveInfinity);
11081 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011082 __ Fmov(s22, 0xffffff0000000000); // Largest float < UINT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +000011083 __ Fmov(d24, 1.1);
11084 __ Fmov(d25, 2.5);
11085 __ Fmov(d26, -2.5);
11086 __ Fmov(d27, kFP64PositiveInfinity);
11087 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011088 __ Fmov(d29, 0xfffffffffffff800); // Largest double < UINT64_MAX.
11089 __ Fmov(s30, 0x100000000);
armvixlf37fdc02014-02-05 13:22:16 +000011090
11091 __ Fcvtau(w0, s0);
11092 __ Fcvtau(w1, s1);
11093 __ Fcvtau(w2, s2);
11094 __ Fcvtau(w3, s3);
11095 __ Fcvtau(w4, s4);
11096 __ Fcvtau(w5, s5);
11097 __ Fcvtau(w6, s6);
11098 __ Fcvtau(w8, d8);
11099 __ Fcvtau(w9, d9);
11100 __ Fcvtau(w10, d10);
11101 __ Fcvtau(w11, d11);
11102 __ Fcvtau(w12, d12);
11103 __ Fcvtau(w13, d13);
11104 __ Fcvtau(w14, d14);
11105 __ Fcvtau(w15, d15);
11106 __ Fcvtau(x16, s16);
11107 __ Fcvtau(x17, s17);
11108 __ Fcvtau(x18, s18);
11109 __ Fcvtau(x19, s19);
11110 __ Fcvtau(x20, s20);
11111 __ Fcvtau(x21, s21);
11112 __ Fcvtau(x22, s22);
11113 __ Fcvtau(x24, d24);
11114 __ Fcvtau(x25, d25);
11115 __ Fcvtau(x26, d26);
11116 __ Fcvtau(x27, d27);
11117 __ Fcvtau(x28, d28);
11118 __ Fcvtau(x29, d29);
11119 __ Fcvtau(w30, s30);
11120 END();
11121
11122 RUN();
11123
11124 ASSERT_EQUAL_64(1, x0);
11125 ASSERT_EQUAL_64(1, x1);
11126 ASSERT_EQUAL_64(3, x2);
11127 ASSERT_EQUAL_64(0, x3);
11128 ASSERT_EQUAL_64(0xffffffff, x4);
11129 ASSERT_EQUAL_64(0, x5);
11130 ASSERT_EQUAL_64(0xffffff00, x6);
11131 ASSERT_EQUAL_64(1, x8);
11132 ASSERT_EQUAL_64(1, x9);
11133 ASSERT_EQUAL_64(3, x10);
11134 ASSERT_EQUAL_64(0, x11);
11135 ASSERT_EQUAL_64(0xffffffff, x12);
11136 ASSERT_EQUAL_64(0, x13);
11137 ASSERT_EQUAL_64(0xfffffffe, x14);
11138 ASSERT_EQUAL_64(1, x16);
11139 ASSERT_EQUAL_64(1, x17);
11140 ASSERT_EQUAL_64(3, x18);
11141 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +000011142 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlf37fdc02014-02-05 13:22:16 +000011143 ASSERT_EQUAL_64(0, x21);
armvixlb0c8ae22014-03-21 14:03:59 +000011144 ASSERT_EQUAL_64(0xffffff0000000000, x22);
armvixlf37fdc02014-02-05 13:22:16 +000011145 ASSERT_EQUAL_64(1, x24);
11146 ASSERT_EQUAL_64(3, x25);
11147 ASSERT_EQUAL_64(0, x26);
armvixlb0c8ae22014-03-21 14:03:59 +000011148 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
armvixlf37fdc02014-02-05 13:22:16 +000011149 ASSERT_EQUAL_64(0, x28);
armvixlb0c8ae22014-03-21 14:03:59 +000011150 ASSERT_EQUAL_64(0xfffffffffffff800, x29);
armvixlf37fdc02014-02-05 13:22:16 +000011151 ASSERT_EQUAL_64(0xffffffff, x30);
11152
11153 TEARDOWN();
11154}
11155
11156
armvixlad96eda2013-06-14 11:42:37 +010011157TEST(fcvtms) {
11158 SETUP();
11159
11160 START();
11161 __ Fmov(s0, 1.0);
11162 __ Fmov(s1, 1.1);
11163 __ Fmov(s2, 1.5);
11164 __ Fmov(s3, -1.5);
11165 __ Fmov(s4, kFP32PositiveInfinity);
11166 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011167 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11168 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011169 __ Fmov(d8, 1.0);
11170 __ Fmov(d9, 1.1);
11171 __ Fmov(d10, 1.5);
11172 __ Fmov(d11, -1.5);
11173 __ Fmov(d12, kFP64PositiveInfinity);
11174 __ Fmov(d13, kFP64NegativeInfinity);
11175 __ Fmov(d14, kWMaxInt - 1);
11176 __ Fmov(d15, kWMinInt + 1);
11177 __ Fmov(s17, 1.1);
11178 __ Fmov(s18, 1.5);
11179 __ Fmov(s19, -1.5);
11180 __ Fmov(s20, kFP32PositiveInfinity);
11181 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011182 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11183 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011184 __ Fmov(d24, 1.1);
11185 __ Fmov(d25, 1.5);
11186 __ Fmov(d26, -1.5);
11187 __ Fmov(d27, kFP64PositiveInfinity);
11188 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011189 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11190 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011191
11192 __ Fcvtms(w0, s0);
11193 __ Fcvtms(w1, s1);
11194 __ Fcvtms(w2, s2);
11195 __ Fcvtms(w3, s3);
11196 __ Fcvtms(w4, s4);
11197 __ Fcvtms(w5, s5);
11198 __ Fcvtms(w6, s6);
11199 __ Fcvtms(w7, s7);
11200 __ Fcvtms(w8, d8);
11201 __ Fcvtms(w9, d9);
11202 __ Fcvtms(w10, d10);
11203 __ Fcvtms(w11, d11);
11204 __ Fcvtms(w12, d12);
11205 __ Fcvtms(w13, d13);
11206 __ Fcvtms(w14, d14);
11207 __ Fcvtms(w15, d15);
11208 __ Fcvtms(x17, s17);
11209 __ Fcvtms(x18, s18);
11210 __ Fcvtms(x19, s19);
11211 __ Fcvtms(x20, s20);
11212 __ Fcvtms(x21, s21);
11213 __ Fcvtms(x22, s22);
11214 __ Fcvtms(x23, s23);
11215 __ Fcvtms(x24, d24);
11216 __ Fcvtms(x25, d25);
11217 __ Fcvtms(x26, d26);
11218 __ Fcvtms(x27, d27);
11219 __ Fcvtms(x28, d28);
11220 __ Fcvtms(x29, d29);
11221 __ Fcvtms(x30, d30);
11222 END();
11223
11224 RUN();
11225
11226 ASSERT_EQUAL_64(1, x0);
11227 ASSERT_EQUAL_64(1, x1);
11228 ASSERT_EQUAL_64(1, x2);
11229 ASSERT_EQUAL_64(0xfffffffe, x3);
11230 ASSERT_EQUAL_64(0x7fffffff, x4);
11231 ASSERT_EQUAL_64(0x80000000, x5);
11232 ASSERT_EQUAL_64(0x7fffff80, x6);
11233 ASSERT_EQUAL_64(0x80000080, x7);
11234 ASSERT_EQUAL_64(1, x8);
11235 ASSERT_EQUAL_64(1, x9);
11236 ASSERT_EQUAL_64(1, x10);
11237 ASSERT_EQUAL_64(0xfffffffe, x11);
11238 ASSERT_EQUAL_64(0x7fffffff, x12);
11239 ASSERT_EQUAL_64(0x80000000, x13);
11240 ASSERT_EQUAL_64(0x7ffffffe, x14);
11241 ASSERT_EQUAL_64(0x80000001, x15);
11242 ASSERT_EQUAL_64(1, x17);
11243 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011244 ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
11245 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11246 ASSERT_EQUAL_64(0x8000000000000000, x21);
11247 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11248 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010011249 ASSERT_EQUAL_64(1, x24);
11250 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011251 ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
11252 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11253 ASSERT_EQUAL_64(0x8000000000000000, x28);
11254 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11255 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +010011256
11257 TEARDOWN();
11258}
11259
11260
11261TEST(fcvtmu) {
11262 SETUP();
11263
11264 START();
11265 __ Fmov(s0, 1.0);
11266 __ Fmov(s1, 1.1);
11267 __ Fmov(s2, 1.5);
11268 __ Fmov(s3, -1.5);
11269 __ Fmov(s4, kFP32PositiveInfinity);
11270 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011271 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11272 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011273 __ Fmov(d8, 1.0);
11274 __ Fmov(d9, 1.1);
11275 __ Fmov(d10, 1.5);
11276 __ Fmov(d11, -1.5);
11277 __ Fmov(d12, kFP64PositiveInfinity);
11278 __ Fmov(d13, kFP64NegativeInfinity);
11279 __ Fmov(d14, kWMaxInt - 1);
11280 __ Fmov(d15, kWMinInt + 1);
11281 __ Fmov(s17, 1.1);
11282 __ Fmov(s18, 1.5);
11283 __ Fmov(s19, -1.5);
11284 __ Fmov(s20, kFP32PositiveInfinity);
11285 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011286 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11287 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011288 __ Fmov(d24, 1.1);
11289 __ Fmov(d25, 1.5);
11290 __ Fmov(d26, -1.5);
11291 __ Fmov(d27, kFP64PositiveInfinity);
11292 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011293 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11294 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011295
11296 __ Fcvtmu(w0, s0);
11297 __ Fcvtmu(w1, s1);
11298 __ Fcvtmu(w2, s2);
11299 __ Fcvtmu(w3, s3);
11300 __ Fcvtmu(w4, s4);
11301 __ Fcvtmu(w5, s5);
11302 __ Fcvtmu(w6, s6);
11303 __ Fcvtmu(w7, s7);
11304 __ Fcvtmu(w8, d8);
11305 __ Fcvtmu(w9, d9);
11306 __ Fcvtmu(w10, d10);
11307 __ Fcvtmu(w11, d11);
11308 __ Fcvtmu(w12, d12);
11309 __ Fcvtmu(w13, d13);
11310 __ Fcvtmu(w14, d14);
11311 __ Fcvtmu(x17, s17);
11312 __ Fcvtmu(x18, s18);
11313 __ Fcvtmu(x19, s19);
11314 __ Fcvtmu(x20, s20);
11315 __ Fcvtmu(x21, s21);
11316 __ Fcvtmu(x22, s22);
11317 __ Fcvtmu(x23, s23);
11318 __ Fcvtmu(x24, d24);
11319 __ Fcvtmu(x25, d25);
11320 __ Fcvtmu(x26, d26);
11321 __ Fcvtmu(x27, d27);
11322 __ Fcvtmu(x28, d28);
11323 __ Fcvtmu(x29, d29);
11324 __ Fcvtmu(x30, d30);
11325 END();
11326
11327 RUN();
11328
11329 ASSERT_EQUAL_64(1, x0);
11330 ASSERT_EQUAL_64(1, x1);
11331 ASSERT_EQUAL_64(1, x2);
11332 ASSERT_EQUAL_64(0, x3);
11333 ASSERT_EQUAL_64(0xffffffff, x4);
11334 ASSERT_EQUAL_64(0, x5);
11335 ASSERT_EQUAL_64(0x7fffff80, x6);
11336 ASSERT_EQUAL_64(0, x7);
11337 ASSERT_EQUAL_64(1, x8);
11338 ASSERT_EQUAL_64(1, x9);
11339 ASSERT_EQUAL_64(1, x10);
11340 ASSERT_EQUAL_64(0, x11);
11341 ASSERT_EQUAL_64(0xffffffff, x12);
11342 ASSERT_EQUAL_64(0, x13);
11343 ASSERT_EQUAL_64(0x7ffffffe, x14);
11344 ASSERT_EQUAL_64(1, x17);
11345 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011346 ASSERT_EQUAL_64(0, x19);
11347 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
11348 ASSERT_EQUAL_64(0, x21);
11349 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11350 ASSERT_EQUAL_64(0, x23);
armvixlad96eda2013-06-14 11:42:37 +010011351 ASSERT_EQUAL_64(1, x24);
11352 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011353 ASSERT_EQUAL_64(0, x26);
11354 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
11355 ASSERT_EQUAL_64(0, x28);
11356 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11357 ASSERT_EQUAL_64(0, x30);
armvixlad96eda2013-06-14 11:42:37 +010011358
11359 TEARDOWN();
11360}
11361
11362
11363TEST(fcvtns) {
11364 SETUP();
11365
11366 START();
11367 __ Fmov(s0, 1.0);
11368 __ Fmov(s1, 1.1);
11369 __ Fmov(s2, 1.5);
11370 __ Fmov(s3, -1.5);
11371 __ Fmov(s4, kFP32PositiveInfinity);
11372 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011373 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11374 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011375 __ Fmov(d8, 1.0);
11376 __ Fmov(d9, 1.1);
11377 __ Fmov(d10, 1.5);
11378 __ Fmov(d11, -1.5);
11379 __ Fmov(d12, kFP64PositiveInfinity);
11380 __ Fmov(d13, kFP64NegativeInfinity);
11381 __ Fmov(d14, kWMaxInt - 1);
11382 __ Fmov(d15, kWMinInt + 1);
11383 __ Fmov(s17, 1.1);
11384 __ Fmov(s18, 1.5);
11385 __ Fmov(s19, -1.5);
11386 __ Fmov(s20, kFP32PositiveInfinity);
11387 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011388 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11389 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011390 __ Fmov(d24, 1.1);
11391 __ Fmov(d25, 1.5);
11392 __ Fmov(d26, -1.5);
11393 __ Fmov(d27, kFP64PositiveInfinity);
11394 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011395 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11396 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011397
11398 __ Fcvtns(w0, s0);
11399 __ Fcvtns(w1, s1);
11400 __ Fcvtns(w2, s2);
11401 __ Fcvtns(w3, s3);
11402 __ Fcvtns(w4, s4);
11403 __ Fcvtns(w5, s5);
11404 __ Fcvtns(w6, s6);
11405 __ Fcvtns(w7, s7);
11406 __ Fcvtns(w8, d8);
11407 __ Fcvtns(w9, d9);
11408 __ Fcvtns(w10, d10);
11409 __ Fcvtns(w11, d11);
11410 __ Fcvtns(w12, d12);
11411 __ Fcvtns(w13, d13);
11412 __ Fcvtns(w14, d14);
11413 __ Fcvtns(w15, d15);
11414 __ Fcvtns(x17, s17);
11415 __ Fcvtns(x18, s18);
11416 __ Fcvtns(x19, s19);
11417 __ Fcvtns(x20, s20);
11418 __ Fcvtns(x21, s21);
11419 __ Fcvtns(x22, s22);
11420 __ Fcvtns(x23, s23);
11421 __ Fcvtns(x24, d24);
11422 __ Fcvtns(x25, d25);
11423 __ Fcvtns(x26, d26);
11424 __ Fcvtns(x27, d27);
11425 __ Fcvtns(x28, d28);
11426 __ Fcvtns(x29, d29);
11427 __ Fcvtns(x30, d30);
11428 END();
11429
11430 RUN();
11431
11432 ASSERT_EQUAL_64(1, x0);
11433 ASSERT_EQUAL_64(1, x1);
11434 ASSERT_EQUAL_64(2, x2);
11435 ASSERT_EQUAL_64(0xfffffffe, x3);
11436 ASSERT_EQUAL_64(0x7fffffff, x4);
11437 ASSERT_EQUAL_64(0x80000000, x5);
11438 ASSERT_EQUAL_64(0x7fffff80, x6);
11439 ASSERT_EQUAL_64(0x80000080, x7);
11440 ASSERT_EQUAL_64(1, x8);
11441 ASSERT_EQUAL_64(1, x9);
11442 ASSERT_EQUAL_64(2, x10);
11443 ASSERT_EQUAL_64(0xfffffffe, x11);
11444 ASSERT_EQUAL_64(0x7fffffff, x12);
11445 ASSERT_EQUAL_64(0x80000000, x13);
11446 ASSERT_EQUAL_64(0x7ffffffe, x14);
11447 ASSERT_EQUAL_64(0x80000001, x15);
11448 ASSERT_EQUAL_64(1, x17);
11449 ASSERT_EQUAL_64(2, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011450 ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
11451 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11452 ASSERT_EQUAL_64(0x8000000000000000, x21);
11453 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11454 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010011455 ASSERT_EQUAL_64(1, x24);
11456 ASSERT_EQUAL_64(2, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011457 ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
11458 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11459 ASSERT_EQUAL_64(0x8000000000000000, x28);
11460 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11461 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +010011462
11463 TEARDOWN();
11464}
11465
11466
11467TEST(fcvtnu) {
11468 SETUP();
11469
11470 START();
11471 __ Fmov(s0, 1.0);
11472 __ Fmov(s1, 1.1);
11473 __ Fmov(s2, 1.5);
11474 __ Fmov(s3, -1.5);
11475 __ Fmov(s4, kFP32PositiveInfinity);
11476 __ Fmov(s5, kFP32NegativeInfinity);
11477 __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX.
11478 __ Fmov(d8, 1.0);
11479 __ Fmov(d9, 1.1);
11480 __ Fmov(d10, 1.5);
11481 __ Fmov(d11, -1.5);
11482 __ Fmov(d12, kFP64PositiveInfinity);
11483 __ Fmov(d13, kFP64NegativeInfinity);
11484 __ Fmov(d14, 0xfffffffe);
11485 __ Fmov(s16, 1.0);
11486 __ Fmov(s17, 1.1);
11487 __ Fmov(s18, 1.5);
11488 __ Fmov(s19, -1.5);
11489 __ Fmov(s20, kFP32PositiveInfinity);
11490 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011491 __ Fmov(s22, 0xffffff0000000000); // Largest float < UINT64_MAX.
armvixlad96eda2013-06-14 11:42:37 +010011492 __ Fmov(d24, 1.1);
11493 __ Fmov(d25, 1.5);
11494 __ Fmov(d26, -1.5);
11495 __ Fmov(d27, kFP64PositiveInfinity);
11496 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011497 __ Fmov(d29, 0xfffffffffffff800); // Largest double < UINT64_MAX.
11498 __ Fmov(s30, 0x100000000);
armvixlad96eda2013-06-14 11:42:37 +010011499
11500 __ Fcvtnu(w0, s0);
11501 __ Fcvtnu(w1, s1);
11502 __ Fcvtnu(w2, s2);
11503 __ Fcvtnu(w3, s3);
11504 __ Fcvtnu(w4, s4);
11505 __ Fcvtnu(w5, s5);
11506 __ Fcvtnu(w6, s6);
11507 __ Fcvtnu(w8, d8);
11508 __ Fcvtnu(w9, d9);
11509 __ Fcvtnu(w10, d10);
11510 __ Fcvtnu(w11, d11);
11511 __ Fcvtnu(w12, d12);
11512 __ Fcvtnu(w13, d13);
11513 __ Fcvtnu(w14, d14);
11514 __ Fcvtnu(w15, d15);
11515 __ Fcvtnu(x16, s16);
11516 __ Fcvtnu(x17, s17);
11517 __ Fcvtnu(x18, s18);
11518 __ Fcvtnu(x19, s19);
11519 __ Fcvtnu(x20, s20);
11520 __ Fcvtnu(x21, s21);
11521 __ Fcvtnu(x22, s22);
11522 __ Fcvtnu(x24, d24);
11523 __ Fcvtnu(x25, d25);
11524 __ Fcvtnu(x26, d26);
11525 __ Fcvtnu(x27, d27);
11526 __ Fcvtnu(x28, d28);
11527 __ Fcvtnu(x29, d29);
11528 __ Fcvtnu(w30, s30);
11529 END();
11530
11531 RUN();
11532
11533 ASSERT_EQUAL_64(1, x0);
11534 ASSERT_EQUAL_64(1, x1);
11535 ASSERT_EQUAL_64(2, x2);
11536 ASSERT_EQUAL_64(0, x3);
11537 ASSERT_EQUAL_64(0xffffffff, x4);
11538 ASSERT_EQUAL_64(0, x5);
11539 ASSERT_EQUAL_64(0xffffff00, x6);
11540 ASSERT_EQUAL_64(1, x8);
11541 ASSERT_EQUAL_64(1, x9);
11542 ASSERT_EQUAL_64(2, x10);
11543 ASSERT_EQUAL_64(0, x11);
11544 ASSERT_EQUAL_64(0xffffffff, x12);
11545 ASSERT_EQUAL_64(0, x13);
11546 ASSERT_EQUAL_64(0xfffffffe, x14);
11547 ASSERT_EQUAL_64(1, x16);
11548 ASSERT_EQUAL_64(1, x17);
11549 ASSERT_EQUAL_64(2, x18);
11550 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +000011551 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlad96eda2013-06-14 11:42:37 +010011552 ASSERT_EQUAL_64(0, x21);
armvixlb0c8ae22014-03-21 14:03:59 +000011553 ASSERT_EQUAL_64(0xffffff0000000000, x22);
armvixlad96eda2013-06-14 11:42:37 +010011554 ASSERT_EQUAL_64(1, x24);
11555 ASSERT_EQUAL_64(2, x25);
11556 ASSERT_EQUAL_64(0, x26);
armvixlb0c8ae22014-03-21 14:03:59 +000011557 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
armvixlad96eda2013-06-14 11:42:37 +010011558 ASSERT_EQUAL_64(0, x28);
armvixlb0c8ae22014-03-21 14:03:59 +000011559 ASSERT_EQUAL_64(0xfffffffffffff800, x29);
armvixlad96eda2013-06-14 11:42:37 +010011560 ASSERT_EQUAL_64(0xffffffff, x30);
11561
11562 TEARDOWN();
11563}
11564
11565
11566TEST(fcvtzs) {
11567 SETUP();
11568
11569 START();
11570 __ Fmov(s0, 1.0);
11571 __ Fmov(s1, 1.1);
11572 __ Fmov(s2, 1.5);
11573 __ Fmov(s3, -1.5);
11574 __ Fmov(s4, kFP32PositiveInfinity);
11575 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011576 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11577 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011578 __ Fmov(d8, 1.0);
11579 __ Fmov(d9, 1.1);
11580 __ Fmov(d10, 1.5);
11581 __ Fmov(d11, -1.5);
11582 __ Fmov(d12, kFP64PositiveInfinity);
11583 __ Fmov(d13, kFP64NegativeInfinity);
11584 __ Fmov(d14, kWMaxInt - 1);
11585 __ Fmov(d15, kWMinInt + 1);
11586 __ Fmov(s17, 1.1);
11587 __ Fmov(s18, 1.5);
11588 __ Fmov(s19, -1.5);
11589 __ Fmov(s20, kFP32PositiveInfinity);
11590 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011591 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11592 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011593 __ Fmov(d24, 1.1);
11594 __ Fmov(d25, 1.5);
11595 __ Fmov(d26, -1.5);
11596 __ Fmov(d27, kFP64PositiveInfinity);
11597 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011598 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11599 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011600
11601 __ Fcvtzs(w0, s0);
11602 __ Fcvtzs(w1, s1);
11603 __ Fcvtzs(w2, s2);
11604 __ Fcvtzs(w3, s3);
11605 __ Fcvtzs(w4, s4);
11606 __ Fcvtzs(w5, s5);
11607 __ Fcvtzs(w6, s6);
11608 __ Fcvtzs(w7, s7);
11609 __ Fcvtzs(w8, d8);
11610 __ Fcvtzs(w9, d9);
11611 __ Fcvtzs(w10, d10);
11612 __ Fcvtzs(w11, d11);
11613 __ Fcvtzs(w12, d12);
11614 __ Fcvtzs(w13, d13);
11615 __ Fcvtzs(w14, d14);
11616 __ Fcvtzs(w15, d15);
11617 __ Fcvtzs(x17, s17);
11618 __ Fcvtzs(x18, s18);
11619 __ Fcvtzs(x19, s19);
11620 __ Fcvtzs(x20, s20);
11621 __ Fcvtzs(x21, s21);
11622 __ Fcvtzs(x22, s22);
11623 __ Fcvtzs(x23, s23);
11624 __ Fcvtzs(x24, d24);
11625 __ Fcvtzs(x25, d25);
11626 __ Fcvtzs(x26, d26);
11627 __ Fcvtzs(x27, d27);
11628 __ Fcvtzs(x28, d28);
11629 __ Fcvtzs(x29, d29);
11630 __ Fcvtzs(x30, d30);
11631 END();
11632
11633 RUN();
11634
11635 ASSERT_EQUAL_64(1, x0);
11636 ASSERT_EQUAL_64(1, x1);
11637 ASSERT_EQUAL_64(1, x2);
11638 ASSERT_EQUAL_64(0xffffffff, x3);
11639 ASSERT_EQUAL_64(0x7fffffff, x4);
11640 ASSERT_EQUAL_64(0x80000000, x5);
11641 ASSERT_EQUAL_64(0x7fffff80, x6);
11642 ASSERT_EQUAL_64(0x80000080, x7);
11643 ASSERT_EQUAL_64(1, x8);
11644 ASSERT_EQUAL_64(1, x9);
11645 ASSERT_EQUAL_64(1, x10);
11646 ASSERT_EQUAL_64(0xffffffff, x11);
11647 ASSERT_EQUAL_64(0x7fffffff, x12);
11648 ASSERT_EQUAL_64(0x80000000, x13);
11649 ASSERT_EQUAL_64(0x7ffffffe, x14);
11650 ASSERT_EQUAL_64(0x80000001, x15);
11651 ASSERT_EQUAL_64(1, x17);
11652 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011653 ASSERT_EQUAL_64(0xffffffffffffffff, x19);
11654 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11655 ASSERT_EQUAL_64(0x8000000000000000, x21);
11656 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11657 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010011658 ASSERT_EQUAL_64(1, x24);
11659 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011660 ASSERT_EQUAL_64(0xffffffffffffffff, x26);
11661 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11662 ASSERT_EQUAL_64(0x8000000000000000, x28);
11663 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11664 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +010011665
11666 TEARDOWN();
11667}
11668
11669TEST(fcvtzu) {
11670 SETUP();
11671
11672 START();
11673 __ Fmov(s0, 1.0);
11674 __ Fmov(s1, 1.1);
11675 __ Fmov(s2, 1.5);
11676 __ Fmov(s3, -1.5);
11677 __ Fmov(s4, kFP32PositiveInfinity);
11678 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011679 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11680 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011681 __ Fmov(d8, 1.0);
11682 __ Fmov(d9, 1.1);
11683 __ Fmov(d10, 1.5);
11684 __ Fmov(d11, -1.5);
11685 __ Fmov(d12, kFP64PositiveInfinity);
11686 __ Fmov(d13, kFP64NegativeInfinity);
11687 __ Fmov(d14, kWMaxInt - 1);
11688 __ Fmov(d15, kWMinInt + 1);
11689 __ Fmov(s17, 1.1);
11690 __ Fmov(s18, 1.5);
11691 __ Fmov(s19, -1.5);
11692 __ Fmov(s20, kFP32PositiveInfinity);
11693 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011694 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11695 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011696 __ Fmov(d24, 1.1);
11697 __ Fmov(d25, 1.5);
11698 __ Fmov(d26, -1.5);
11699 __ Fmov(d27, kFP64PositiveInfinity);
11700 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011701 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11702 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011703
11704 __ Fcvtzu(w0, s0);
11705 __ Fcvtzu(w1, s1);
11706 __ Fcvtzu(w2, s2);
11707 __ Fcvtzu(w3, s3);
11708 __ Fcvtzu(w4, s4);
11709 __ Fcvtzu(w5, s5);
11710 __ Fcvtzu(w6, s6);
11711 __ Fcvtzu(w7, s7);
11712 __ Fcvtzu(w8, d8);
11713 __ Fcvtzu(w9, d9);
11714 __ Fcvtzu(w10, d10);
11715 __ Fcvtzu(w11, d11);
11716 __ Fcvtzu(w12, d12);
11717 __ Fcvtzu(w13, d13);
11718 __ Fcvtzu(w14, d14);
11719 __ Fcvtzu(x17, s17);
11720 __ Fcvtzu(x18, s18);
11721 __ Fcvtzu(x19, s19);
11722 __ Fcvtzu(x20, s20);
11723 __ Fcvtzu(x21, s21);
11724 __ Fcvtzu(x22, s22);
11725 __ Fcvtzu(x23, s23);
11726 __ Fcvtzu(x24, d24);
11727 __ Fcvtzu(x25, d25);
11728 __ Fcvtzu(x26, d26);
11729 __ Fcvtzu(x27, d27);
11730 __ Fcvtzu(x28, d28);
11731 __ Fcvtzu(x29, d29);
11732 __ Fcvtzu(x30, d30);
11733 END();
11734
11735 RUN();
11736
11737 ASSERT_EQUAL_64(1, x0);
11738 ASSERT_EQUAL_64(1, x1);
11739 ASSERT_EQUAL_64(1, x2);
11740 ASSERT_EQUAL_64(0, x3);
11741 ASSERT_EQUAL_64(0xffffffff, x4);
11742 ASSERT_EQUAL_64(0, x5);
11743 ASSERT_EQUAL_64(0x7fffff80, x6);
11744 ASSERT_EQUAL_64(0, x7);
11745 ASSERT_EQUAL_64(1, x8);
11746 ASSERT_EQUAL_64(1, x9);
11747 ASSERT_EQUAL_64(1, x10);
11748 ASSERT_EQUAL_64(0, x11);
11749 ASSERT_EQUAL_64(0xffffffff, x12);
11750 ASSERT_EQUAL_64(0, x13);
11751 ASSERT_EQUAL_64(0x7ffffffe, x14);
11752 ASSERT_EQUAL_64(1, x17);
11753 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011754 ASSERT_EQUAL_64(0, x19);
11755 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
11756 ASSERT_EQUAL_64(0, x21);
11757 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11758 ASSERT_EQUAL_64(0, x23);
armvixlad96eda2013-06-14 11:42:37 +010011759 ASSERT_EQUAL_64(1, x24);
11760 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011761 ASSERT_EQUAL_64(0, x26);
11762 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
11763 ASSERT_EQUAL_64(0, x28);
11764 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11765 ASSERT_EQUAL_64(0, x30);
armvixlad96eda2013-06-14 11:42:37 +010011766
11767 TEARDOWN();
11768}
11769
11770
armvixl5289c592015-03-02 13:52:04 +000011771TEST(neon_fcvtl) {
11772 SETUP();
11773
11774 START();
11775
11776 __ Movi(v0.V2D(), 0x000080007efffeff, 0x3100b1007c00fc00);
11777 __ Movi(v1.V2D(), 0x03ff83ff00038003, 0x000180017c01fc01);
11778 __ Movi(v2.V2D(), 0x3e200000be200000, 0x7f800000ff800000);
11779 __ Movi(v3.V2D(), 0x0000000080000000, 0x7f8fffffff8fffff);
11780 __ Movi(v4.V2D(), 0x7fcfffffffcfffff, 0x0000000180000001);
11781 __ Fcvtl(v16.V4S(), v0.V4H());
11782 __ Fcvtl2(v17.V4S(), v0.V8H());
11783 __ Fcvtl(v18.V4S(), v1.V4H());
11784 __ Fcvtl2(v19.V4S(), v1.V8H());
11785
11786 __ Fcvtl(v20.V2D(), v2.V2S());
11787 __ Fcvtl2(v21.V2D(), v2.V4S());
11788 __ Fcvtl(v22.V2D(), v3.V2S());
11789 __ Fcvtl2(v23.V2D(), v3.V4S());
11790 __ Fcvtl(v24.V2D(), v4.V2S());
11791 __ Fcvtl2(v25.V2D(), v4.V4S());
11792
11793 END();
11794
11795 RUN();
11796 ASSERT_EQUAL_128(0x3e200000be200000, 0x7f800000ff800000, q16);
11797 ASSERT_EQUAL_128(0x0000000080000000, 0x7fdfe000ffdfe000, q17);
11798 ASSERT_EQUAL_128(0x33800000b3800000, 0x7fc02000ffc02000, q18);
11799 ASSERT_EQUAL_128(0x387fc000b87fc000, 0x34400000b4400000, q19);
11800 ASSERT_EQUAL_128(0x7ff0000000000000, 0xfff0000000000000, q20);
11801 ASSERT_EQUAL_128(0x3fc4000000000000, 0xbfc4000000000000, q21);
11802 ASSERT_EQUAL_128(0x7ff9ffffe0000000, 0xfff9ffffe0000000, q22);
11803 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000000000, q23);
11804 ASSERT_EQUAL_128(0x36a0000000000000, 0xb6a0000000000000, q24);
11805 ASSERT_EQUAL_128(0x7ff9ffffe0000000, 0xfff9ffffe0000000, q25);
11806 TEARDOWN();
11807}
11808
11809
11810TEST(neon_fcvtn) {
11811 SETUP();
11812
11813 START();
11814
11815 __ Movi(v0.V2D(), 0x3e200000be200000, 0x7f800000ff800000);
11816 __ Movi(v1.V2D(), 0x0000000080000000, 0x7f8fffffff8fffff);
11817 __ Movi(v2.V2D(), 0x7fcfffffffcfffff, 0x0000000180000001);
11818 __ Movi(v3.V2D(), 0x3fc4000000000000, 0xbfc4000000000000);
11819 __ Movi(v4.V2D(), 0x7ff0000000000000, 0xfff0000000000000);
11820 __ Movi(v5.V2D(), 0x0000000000000000, 0x8000000000000000);
11821 __ Movi(v6.V2D(), 0x7ff0ffffffffffff, 0xfff0ffffffffffff);
11822 __ Movi(v7.V2D(), 0x7ff8ffffffffffff, 0xfff8ffffffffffff);
11823 __ Movi(v8.V2D(), 0x0000000000000001, 0x8000000000000001);
11824
11825 __ Fcvtn(v16.V4H(), v0.V4S());
11826 __ Fcvtn2(v16.V8H(), v1.V4S());
11827 __ Fcvtn(v17.V4H(), v2.V4S());
11828 __ Fcvtn(v18.V2S(), v3.V2D());
11829 __ Fcvtn2(v18.V4S(), v4.V2D());
11830 __ Fcvtn(v19.V2S(), v5.V2D());
11831 __ Fcvtn2(v19.V4S(), v6.V2D());
11832 __ Fcvtn(v20.V2S(), v7.V2D());
11833 __ Fcvtn2(v20.V4S(), v8.V2D());
11834 END();
11835
11836 RUN();
11837 ASSERT_EQUAL_128(0x000080007e7ffe7f, 0x3100b1007c00fc00, q16);
11838 ASSERT_EQUAL_128(0, 0x7e7ffe7f00008000, q17);
11839 ASSERT_EQUAL_128(0x7f800000ff800000, 0x3e200000be200000, q18);
11840 ASSERT_EQUAL_128(0x7fc7ffffffc7ffff, 0x0000000080000000, q19);
11841 ASSERT_EQUAL_128(0x0000000080000000, 0x7fc7ffffffc7ffff, q20);
11842 TEARDOWN();
11843}
11844
11845
11846TEST(neon_fcvtxn) {
11847 SETUP();
11848
11849 START();
11850 __ Movi(v0.V2D(), 0x3e200000be200000, 0x7f800000ff800000);
11851 __ Movi(v1.V2D(), 0x0000000080000000, 0x7f8fffffff8fffff);
11852 __ Movi(v2.V2D(), 0x7fcfffffffcfffff, 0x0000000180000001);
11853 __ Movi(v3.V2D(), 0x3fc4000000000000, 0xbfc4000000000000);
11854 __ Movi(v4.V2D(), 0x7ff0000000000000, 0xfff0000000000000);
11855 __ Movi(v5.V2D(), 0x0000000000000000, 0x8000000000000000);
11856 __ Movi(v6.V2D(), 0x7ff0ffffffffffff, 0xfff0ffffffffffff);
11857 __ Movi(v7.V2D(), 0x7ff8ffffffffffff, 0xfff8ffffffffffff);
11858 __ Movi(v8.V2D(), 0x0000000000000001, 0x8000000000000001);
11859 __ Movi(v9.V2D(), 0x41ed000000000000, 0x41efffffffefffff);
11860 __ Fcvtxn(v16.V2S(), v0.V2D());
11861 __ Fcvtxn2(v16.V4S(), v1.V2D());
11862 __ Fcvtxn(v17.V2S(), v2.V2D());
11863 __ Fcvtxn2(v17.V4S(), v3.V2D());
11864 __ Fcvtxn(v18.V2S(), v4.V2D());
11865 __ Fcvtxn2(v18.V4S(), v5.V2D());
11866 __ Fcvtxn(v19.V2S(), v6.V2D());
11867 __ Fcvtxn2(v19.V4S(), v7.V2D());
11868 __ Fcvtxn(v20.V2S(), v8.V2D());
11869 __ Fcvtxn2(v20.V4S(), v9.V2D());
11870 __ Fcvtxn(s21, d0);
11871 END();
11872
11873 RUN();
11874 ASSERT_EQUAL_128(0x000000017f7fffff, 0x310000057f7fffff, q16);
11875 ASSERT_EQUAL_128(0x3e200000be200000, 0x7f7fffff00000001, q17);
11876 ASSERT_EQUAL_128(0x0000000080000000, 0x7f800000ff800000, q18);
11877 ASSERT_EQUAL_128(0x7fc7ffffffc7ffff, 0x7fc7ffffffc7ffff, q19);
11878 ASSERT_EQUAL_128(0x4f6800004f7fffff, 0x0000000180000001, q20);
11879 ASSERT_EQUAL_128(0, 0x7f7fffff, q21);
11880 TEARDOWN();
11881}
11882
11883
armvixl578645f2013-08-15 17:21:42 +010011884// Test that scvtf and ucvtf can convert the 64-bit input into the expected
11885// value. All possible values of 'fbits' are tested. The expected value is
11886// modified accordingly in each case.
11887//
11888// The expected value is specified as the bit encoding of the expected double
11889// produced by scvtf (expected_scvtf_bits) as well as ucvtf
11890// (expected_ucvtf_bits).
11891//
11892// Where the input value is representable by int32_t or uint32_t, conversions
11893// from W registers will also be tested.
11894static void TestUScvtfHelper(uint64_t in,
11895 uint64_t expected_scvtf_bits,
11896 uint64_t expected_ucvtf_bits) {
11897 uint64_t u64 = in;
11898 uint32_t u32 = u64 & 0xffffffff;
11899 int64_t s64 = static_cast<int64_t>(in);
11900 int32_t s32 = s64 & 0x7fffffff;
11901
11902 bool cvtf_s32 = (s64 == s32);
11903 bool cvtf_u32 = (u64 == u32);
11904
11905 double results_scvtf_x[65];
11906 double results_ucvtf_x[65];
11907 double results_scvtf_w[33];
11908 double results_ucvtf_w[33];
11909
armvixlad96eda2013-06-14 11:42:37 +010011910 SETUP();
armvixlad96eda2013-06-14 11:42:37 +010011911 START();
armvixlad96eda2013-06-14 11:42:37 +010011912
armvixlb0c8ae22014-03-21 14:03:59 +000011913 __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
11914 __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
11915 __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
11916 __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
armvixl578645f2013-08-15 17:21:42 +010011917
11918 __ Mov(x10, s64);
11919
11920 // Corrupt the top word, in case it is accidentally used during W-register
11921 // conversions.
11922 __ Mov(x11, 0x5555555555555555);
11923 __ Bfi(x11, x10, 0, kWRegSize);
11924
11925 // Test integer conversions.
11926 __ Scvtf(d0, x10);
11927 __ Ucvtf(d1, x10);
11928 __ Scvtf(d2, w11);
11929 __ Ucvtf(d3, w11);
11930 __ Str(d0, MemOperand(x0));
11931 __ Str(d1, MemOperand(x1));
11932 __ Str(d2, MemOperand(x2));
11933 __ Str(d3, MemOperand(x3));
11934
11935 // Test all possible values of fbits.
11936 for (int fbits = 1; fbits <= 32; fbits++) {
11937 __ Scvtf(d0, x10, fbits);
11938 __ Ucvtf(d1, x10, fbits);
11939 __ Scvtf(d2, w11, fbits);
11940 __ Ucvtf(d3, w11, fbits);
11941 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
11942 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
11943 __ Str(d2, MemOperand(x2, fbits * kDRegSizeInBytes));
11944 __ Str(d3, MemOperand(x3, fbits * kDRegSizeInBytes));
11945 }
11946
11947 // Conversions from W registers can only handle fbits values <= 32, so just
11948 // test conversions from X registers for 32 < fbits <= 64.
11949 for (int fbits = 33; fbits <= 64; fbits++) {
11950 __ Scvtf(d0, x10, fbits);
11951 __ Ucvtf(d1, x10, fbits);
11952 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
11953 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
11954 }
11955
11956 END();
armvixlad96eda2013-06-14 11:42:37 +010011957 RUN();
11958
armvixl578645f2013-08-15 17:21:42 +010011959 // Check the results.
11960 double expected_scvtf_base = rawbits_to_double(expected_scvtf_bits);
11961 double expected_ucvtf_base = rawbits_to_double(expected_ucvtf_bits);
11962
11963 for (int fbits = 0; fbits <= 32; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010011964 double expected_scvtf = expected_scvtf_base / std::pow(2, fbits);
11965 double expected_ucvtf = expected_ucvtf_base / std::pow(2, fbits);
armvixl578645f2013-08-15 17:21:42 +010011966 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
11967 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
11968 if (cvtf_s32) ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_w[fbits]);
11969 if (cvtf_u32) ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_w[fbits]);
11970 }
11971 for (int fbits = 33; fbits <= 64; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010011972 double expected_scvtf = expected_scvtf_base / std::pow(2, fbits);
11973 double expected_ucvtf = expected_ucvtf_base / std::pow(2, fbits);
armvixl578645f2013-08-15 17:21:42 +010011974 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
11975 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
11976 }
armvixlad96eda2013-06-14 11:42:37 +010011977
11978 TEARDOWN();
11979}
11980
11981
armvixl578645f2013-08-15 17:21:42 +010011982TEST(scvtf_ucvtf_double) {
11983 // Simple conversions of positive numbers which require no rounding; the
11984 // results should not depened on the rounding mode, and ucvtf and scvtf should
11985 // produce the same result.
11986 TestUScvtfHelper(0x0000000000000000, 0x0000000000000000, 0x0000000000000000);
11987 TestUScvtfHelper(0x0000000000000001, 0x3ff0000000000000, 0x3ff0000000000000);
11988 TestUScvtfHelper(0x0000000040000000, 0x41d0000000000000, 0x41d0000000000000);
11989 TestUScvtfHelper(0x0000000100000000, 0x41f0000000000000, 0x41f0000000000000);
11990 TestUScvtfHelper(0x4000000000000000, 0x43d0000000000000, 0x43d0000000000000);
11991 // Test mantissa extremities.
11992 TestUScvtfHelper(0x4000000000000400, 0x43d0000000000001, 0x43d0000000000001);
11993 // The largest int32_t that fits in a double.
11994 TestUScvtfHelper(0x000000007fffffff, 0x41dfffffffc00000, 0x41dfffffffc00000);
11995 // Values that would be negative if treated as an int32_t.
11996 TestUScvtfHelper(0x00000000ffffffff, 0x41efffffffe00000, 0x41efffffffe00000);
11997 TestUScvtfHelper(0x0000000080000000, 0x41e0000000000000, 0x41e0000000000000);
11998 TestUScvtfHelper(0x0000000080000001, 0x41e0000000200000, 0x41e0000000200000);
11999 // The largest int64_t that fits in a double.
12000 TestUScvtfHelper(0x7ffffffffffffc00, 0x43dfffffffffffff, 0x43dfffffffffffff);
12001 // Check for bit pattern reproduction.
12002 TestUScvtfHelper(0x0123456789abcde0, 0x43723456789abcde, 0x43723456789abcde);
12003 TestUScvtfHelper(0x0000000012345678, 0x41b2345678000000, 0x41b2345678000000);
12004
12005 // Simple conversions of negative int64_t values. These require no rounding,
12006 // and the results should not depend on the rounding mode.
12007 TestUScvtfHelper(0xffffffffc0000000, 0xc1d0000000000000, 0x43effffffff80000);
12008 TestUScvtfHelper(0xffffffff00000000, 0xc1f0000000000000, 0x43efffffffe00000);
12009 TestUScvtfHelper(0xc000000000000000, 0xc3d0000000000000, 0x43e8000000000000);
12010
12011 // Conversions which require rounding.
12012 TestUScvtfHelper(0x1000000000000000, 0x43b0000000000000, 0x43b0000000000000);
12013 TestUScvtfHelper(0x1000000000000001, 0x43b0000000000000, 0x43b0000000000000);
12014 TestUScvtfHelper(0x1000000000000080, 0x43b0000000000000, 0x43b0000000000000);
12015 TestUScvtfHelper(0x1000000000000081, 0x43b0000000000001, 0x43b0000000000001);
12016 TestUScvtfHelper(0x1000000000000100, 0x43b0000000000001, 0x43b0000000000001);
12017 TestUScvtfHelper(0x1000000000000101, 0x43b0000000000001, 0x43b0000000000001);
12018 TestUScvtfHelper(0x1000000000000180, 0x43b0000000000002, 0x43b0000000000002);
12019 TestUScvtfHelper(0x1000000000000181, 0x43b0000000000002, 0x43b0000000000002);
12020 TestUScvtfHelper(0x1000000000000200, 0x43b0000000000002, 0x43b0000000000002);
12021 TestUScvtfHelper(0x1000000000000201, 0x43b0000000000002, 0x43b0000000000002);
12022 TestUScvtfHelper(0x1000000000000280, 0x43b0000000000002, 0x43b0000000000002);
12023 TestUScvtfHelper(0x1000000000000281, 0x43b0000000000003, 0x43b0000000000003);
12024 TestUScvtfHelper(0x1000000000000300, 0x43b0000000000003, 0x43b0000000000003);
12025 // Check rounding of negative int64_t values (and large uint64_t values).
12026 TestUScvtfHelper(0x8000000000000000, 0xc3e0000000000000, 0x43e0000000000000);
12027 TestUScvtfHelper(0x8000000000000001, 0xc3e0000000000000, 0x43e0000000000000);
12028 TestUScvtfHelper(0x8000000000000200, 0xc3e0000000000000, 0x43e0000000000000);
12029 TestUScvtfHelper(0x8000000000000201, 0xc3dfffffffffffff, 0x43e0000000000000);
12030 TestUScvtfHelper(0x8000000000000400, 0xc3dfffffffffffff, 0x43e0000000000000);
12031 TestUScvtfHelper(0x8000000000000401, 0xc3dfffffffffffff, 0x43e0000000000001);
12032 TestUScvtfHelper(0x8000000000000600, 0xc3dffffffffffffe, 0x43e0000000000001);
12033 TestUScvtfHelper(0x8000000000000601, 0xc3dffffffffffffe, 0x43e0000000000001);
12034 TestUScvtfHelper(0x8000000000000800, 0xc3dffffffffffffe, 0x43e0000000000001);
12035 TestUScvtfHelper(0x8000000000000801, 0xc3dffffffffffffe, 0x43e0000000000001);
12036 TestUScvtfHelper(0x8000000000000a00, 0xc3dffffffffffffe, 0x43e0000000000001);
12037 TestUScvtfHelper(0x8000000000000a01, 0xc3dffffffffffffd, 0x43e0000000000001);
12038 TestUScvtfHelper(0x8000000000000c00, 0xc3dffffffffffffd, 0x43e0000000000002);
12039 // Round up to produce a result that's too big for the input to represent.
12040 TestUScvtfHelper(0x7ffffffffffffe00, 0x43e0000000000000, 0x43e0000000000000);
12041 TestUScvtfHelper(0x7fffffffffffffff, 0x43e0000000000000, 0x43e0000000000000);
12042 TestUScvtfHelper(0xfffffffffffffc00, 0xc090000000000000, 0x43f0000000000000);
12043 TestUScvtfHelper(0xffffffffffffffff, 0xbff0000000000000, 0x43f0000000000000);
12044}
12045
12046
12047// The same as TestUScvtfHelper, but convert to floats.
12048static void TestUScvtf32Helper(uint64_t in,
12049 uint32_t expected_scvtf_bits,
12050 uint32_t expected_ucvtf_bits) {
12051 uint64_t u64 = in;
12052 uint32_t u32 = u64 & 0xffffffff;
12053 int64_t s64 = static_cast<int64_t>(in);
12054 int32_t s32 = s64 & 0x7fffffff;
12055
12056 bool cvtf_s32 = (s64 == s32);
12057 bool cvtf_u32 = (u64 == u32);
12058
12059 float results_scvtf_x[65];
12060 float results_ucvtf_x[65];
12061 float results_scvtf_w[33];
12062 float results_ucvtf_w[33];
12063
armvixlad96eda2013-06-14 11:42:37 +010012064 SETUP();
armvixlad96eda2013-06-14 11:42:37 +010012065 START();
armvixlad96eda2013-06-14 11:42:37 +010012066
armvixlb0c8ae22014-03-21 14:03:59 +000012067 __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
12068 __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
12069 __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
12070 __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
armvixl578645f2013-08-15 17:21:42 +010012071
12072 __ Mov(x10, s64);
12073
12074 // Corrupt the top word, in case it is accidentally used during W-register
12075 // conversions.
12076 __ Mov(x11, 0x5555555555555555);
12077 __ Bfi(x11, x10, 0, kWRegSize);
12078
12079 // Test integer conversions.
12080 __ Scvtf(s0, x10);
12081 __ Ucvtf(s1, x10);
12082 __ Scvtf(s2, w11);
12083 __ Ucvtf(s3, w11);
12084 __ Str(s0, MemOperand(x0));
12085 __ Str(s1, MemOperand(x1));
12086 __ Str(s2, MemOperand(x2));
12087 __ Str(s3, MemOperand(x3));
12088
12089 // Test all possible values of fbits.
12090 for (int fbits = 1; fbits <= 32; fbits++) {
12091 __ Scvtf(s0, x10, fbits);
12092 __ Ucvtf(s1, x10, fbits);
12093 __ Scvtf(s2, w11, fbits);
12094 __ Ucvtf(s3, w11, fbits);
12095 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
12096 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
12097 __ Str(s2, MemOperand(x2, fbits * kSRegSizeInBytes));
12098 __ Str(s3, MemOperand(x3, fbits * kSRegSizeInBytes));
12099 }
12100
12101 // Conversions from W registers can only handle fbits values <= 32, so just
12102 // test conversions from X registers for 32 < fbits <= 64.
12103 for (int fbits = 33; fbits <= 64; fbits++) {
12104 __ Scvtf(s0, x10, fbits);
12105 __ Ucvtf(s1, x10, fbits);
12106 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
12107 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
12108 }
armvixlad96eda2013-06-14 11:42:37 +010012109
12110 END();
armvixlad96eda2013-06-14 11:42:37 +010012111 RUN();
12112
armvixl578645f2013-08-15 17:21:42 +010012113 // Check the results.
12114 float expected_scvtf_base = rawbits_to_float(expected_scvtf_bits);
12115 float expected_ucvtf_base = rawbits_to_float(expected_ucvtf_bits);
armvixlad96eda2013-06-14 11:42:37 +010012116
armvixl578645f2013-08-15 17:21:42 +010012117 for (int fbits = 0; fbits <= 32; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010012118 float expected_scvtf = expected_scvtf_base / std::pow(2.0f, fbits);
12119 float expected_ucvtf = expected_ucvtf_base / std::pow(2.0f, fbits);
armvixl578645f2013-08-15 17:21:42 +010012120 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
12121 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
12122 if (cvtf_s32) ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_w[fbits]);
12123 if (cvtf_u32) ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_w[fbits]);
armvixl578645f2013-08-15 17:21:42 +010012124 }
12125 for (int fbits = 33; fbits <= 64; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010012126 float expected_scvtf = expected_scvtf_base / std::pow(2.0f, fbits);
12127 float expected_ucvtf = expected_ucvtf_base / std::pow(2.0f, fbits);
armvixl578645f2013-08-15 17:21:42 +010012128 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
12129 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
12130 }
armvixlad96eda2013-06-14 11:42:37 +010012131
12132 TEARDOWN();
12133}
12134
12135
armvixl578645f2013-08-15 17:21:42 +010012136TEST(scvtf_ucvtf_float) {
12137 // Simple conversions of positive numbers which require no rounding; the
12138 // results should not depened on the rounding mode, and ucvtf and scvtf should
12139 // produce the same result.
12140 TestUScvtf32Helper(0x0000000000000000, 0x00000000, 0x00000000);
12141 TestUScvtf32Helper(0x0000000000000001, 0x3f800000, 0x3f800000);
12142 TestUScvtf32Helper(0x0000000040000000, 0x4e800000, 0x4e800000);
12143 TestUScvtf32Helper(0x0000000100000000, 0x4f800000, 0x4f800000);
12144 TestUScvtf32Helper(0x4000000000000000, 0x5e800000, 0x5e800000);
12145 // Test mantissa extremities.
12146 TestUScvtf32Helper(0x0000000000800001, 0x4b000001, 0x4b000001);
12147 TestUScvtf32Helper(0x4000008000000000, 0x5e800001, 0x5e800001);
12148 // The largest int32_t that fits in a float.
12149 TestUScvtf32Helper(0x000000007fffff80, 0x4effffff, 0x4effffff);
12150 // Values that would be negative if treated as an int32_t.
12151 TestUScvtf32Helper(0x00000000ffffff00, 0x4f7fffff, 0x4f7fffff);
12152 TestUScvtf32Helper(0x0000000080000000, 0x4f000000, 0x4f000000);
12153 TestUScvtf32Helper(0x0000000080000100, 0x4f000001, 0x4f000001);
12154 // The largest int64_t that fits in a float.
12155 TestUScvtf32Helper(0x7fffff8000000000, 0x5effffff, 0x5effffff);
12156 // Check for bit pattern reproduction.
12157 TestUScvtf32Helper(0x0000000000876543, 0x4b076543, 0x4b076543);
12158
12159 // Simple conversions of negative int64_t values. These require no rounding,
12160 // and the results should not depend on the rounding mode.
12161 TestUScvtf32Helper(0xfffffc0000000000, 0xd4800000, 0x5f7ffffc);
12162 TestUScvtf32Helper(0xc000000000000000, 0xde800000, 0x5f400000);
12163
12164 // Conversions which require rounding.
12165 TestUScvtf32Helper(0x0000800000000000, 0x57000000, 0x57000000);
12166 TestUScvtf32Helper(0x0000800000000001, 0x57000000, 0x57000000);
12167 TestUScvtf32Helper(0x0000800000800000, 0x57000000, 0x57000000);
12168 TestUScvtf32Helper(0x0000800000800001, 0x57000001, 0x57000001);
12169 TestUScvtf32Helper(0x0000800001000000, 0x57000001, 0x57000001);
12170 TestUScvtf32Helper(0x0000800001000001, 0x57000001, 0x57000001);
12171 TestUScvtf32Helper(0x0000800001800000, 0x57000002, 0x57000002);
12172 TestUScvtf32Helper(0x0000800001800001, 0x57000002, 0x57000002);
12173 TestUScvtf32Helper(0x0000800002000000, 0x57000002, 0x57000002);
12174 TestUScvtf32Helper(0x0000800002000001, 0x57000002, 0x57000002);
12175 TestUScvtf32Helper(0x0000800002800000, 0x57000002, 0x57000002);
12176 TestUScvtf32Helper(0x0000800002800001, 0x57000003, 0x57000003);
12177 TestUScvtf32Helper(0x0000800003000000, 0x57000003, 0x57000003);
12178 // Check rounding of negative int64_t values (and large uint64_t values).
12179 TestUScvtf32Helper(0x8000000000000000, 0xdf000000, 0x5f000000);
12180 TestUScvtf32Helper(0x8000000000000001, 0xdf000000, 0x5f000000);
12181 TestUScvtf32Helper(0x8000004000000000, 0xdf000000, 0x5f000000);
12182 TestUScvtf32Helper(0x8000004000000001, 0xdeffffff, 0x5f000000);
12183 TestUScvtf32Helper(0x8000008000000000, 0xdeffffff, 0x5f000000);
12184 TestUScvtf32Helper(0x8000008000000001, 0xdeffffff, 0x5f000001);
12185 TestUScvtf32Helper(0x800000c000000000, 0xdefffffe, 0x5f000001);
12186 TestUScvtf32Helper(0x800000c000000001, 0xdefffffe, 0x5f000001);
12187 TestUScvtf32Helper(0x8000010000000000, 0xdefffffe, 0x5f000001);
12188 TestUScvtf32Helper(0x8000010000000001, 0xdefffffe, 0x5f000001);
12189 TestUScvtf32Helper(0x8000014000000000, 0xdefffffe, 0x5f000001);
12190 TestUScvtf32Helper(0x8000014000000001, 0xdefffffd, 0x5f000001);
12191 TestUScvtf32Helper(0x8000018000000000, 0xdefffffd, 0x5f000002);
12192 // Round up to produce a result that's too big for the input to represent.
12193 TestUScvtf32Helper(0x000000007fffffc0, 0x4f000000, 0x4f000000);
12194 TestUScvtf32Helper(0x000000007fffffff, 0x4f000000, 0x4f000000);
12195 TestUScvtf32Helper(0x00000000ffffff80, 0x4f800000, 0x4f800000);
12196 TestUScvtf32Helper(0x00000000ffffffff, 0x4f800000, 0x4f800000);
12197 TestUScvtf32Helper(0x7fffffc000000000, 0x5f000000, 0x5f000000);
12198 TestUScvtf32Helper(0x7fffffffffffffff, 0x5f000000, 0x5f000000);
12199 TestUScvtf32Helper(0xffffff8000000000, 0xd3000000, 0x5f800000);
12200 TestUScvtf32Helper(0xffffffffffffffff, 0xbf800000, 0x5f800000);
12201}
12202
12203
armvixlad96eda2013-06-14 11:42:37 +010012204TEST(system_mrs) {
12205 SETUP();
12206
12207 START();
12208 __ Mov(w0, 0);
12209 __ Mov(w1, 1);
12210 __ Mov(w2, 0x80000000);
12211
12212 // Set the Z and C flags.
12213 __ Cmp(w0, w0);
12214 __ Mrs(x3, NZCV);
12215
12216 // Set the N flag.
12217 __ Cmp(w0, w1);
12218 __ Mrs(x4, NZCV);
12219
12220 // Set the Z, C and V flags.
armvixlf37fdc02014-02-05 13:22:16 +000012221 __ Adds(w0, w2, w2);
armvixlad96eda2013-06-14 11:42:37 +010012222 __ Mrs(x5, NZCV);
armvixl578645f2013-08-15 17:21:42 +010012223
12224 // Read the default FPCR.
12225 __ Mrs(x6, FPCR);
armvixlad96eda2013-06-14 11:42:37 +010012226 END();
12227
12228 RUN();
12229
armvixl578645f2013-08-15 17:21:42 +010012230 // NZCV
armvixlad96eda2013-06-14 11:42:37 +010012231 ASSERT_EQUAL_32(ZCFlag, w3);
12232 ASSERT_EQUAL_32(NFlag, w4);
12233 ASSERT_EQUAL_32(ZCVFlag, w5);
12234
armvixl578645f2013-08-15 17:21:42 +010012235 // FPCR
12236 // The default FPCR on Linux-based platforms is 0.
12237 ASSERT_EQUAL_32(0, w6);
12238
armvixlad96eda2013-06-14 11:42:37 +010012239 TEARDOWN();
12240}
12241
12242
12243TEST(system_msr) {
armvixl578645f2013-08-15 17:21:42 +010012244 // All FPCR fields that must be implemented: AHP, DN, FZ, RMode
12245 const uint64_t fpcr_core = 0x07c00000;
12246
12247 // All FPCR fields (including fields which may be read-as-zero):
12248 // Stride, Len
12249 // IDE, IXE, UFE, OFE, DZE, IOE
12250 const uint64_t fpcr_all = fpcr_core | 0x00379f00;
12251
armvixlad96eda2013-06-14 11:42:37 +010012252 SETUP();
12253
12254 START();
12255 __ Mov(w0, 0);
12256 __ Mov(w1, 0x7fffffff);
12257
12258 __ Mov(x7, 0);
12259
12260 __ Mov(x10, NVFlag);
12261 __ Cmp(w0, w0); // Set Z and C.
12262 __ Msr(NZCV, x10); // Set N and V.
12263 // The Msr should have overwritten every flag set by the Cmp.
12264 __ Cinc(x7, x7, mi); // N
12265 __ Cinc(x7, x7, ne); // !Z
12266 __ Cinc(x7, x7, lo); // !C
12267 __ Cinc(x7, x7, vs); // V
12268
12269 __ Mov(x10, ZCFlag);
12270 __ Cmn(w1, w1); // Set N and V.
12271 __ Msr(NZCV, x10); // Set Z and C.
12272 // The Msr should have overwritten every flag set by the Cmn.
12273 __ Cinc(x7, x7, pl); // !N
12274 __ Cinc(x7, x7, eq); // Z
12275 __ Cinc(x7, x7, hs); // C
12276 __ Cinc(x7, x7, vc); // !V
12277
armvixl578645f2013-08-15 17:21:42 +010012278 // All core FPCR fields must be writable.
12279 __ Mov(x8, fpcr_core);
12280 __ Msr(FPCR, x8);
12281 __ Mrs(x8, FPCR);
12282
12283 // All FPCR fields, including optional ones. This part of the test doesn't
12284 // achieve much other than ensuring that supported fields can be cleared by
12285 // the next test.
12286 __ Mov(x9, fpcr_all);
12287 __ Msr(FPCR, x9);
12288 __ Mrs(x9, FPCR);
12289 __ And(x9, x9, fpcr_core);
12290
12291 // The undefined bits must ignore writes.
12292 // It's conceivable that a future version of the architecture could use these
12293 // fields (making this test fail), but in the meantime this is a useful test
12294 // for the simulator.
12295 __ Mov(x10, ~fpcr_all);
12296 __ Msr(FPCR, x10);
12297 __ Mrs(x10, FPCR);
12298
armvixlad96eda2013-06-14 11:42:37 +010012299 END();
12300
12301 RUN();
12302
12303 // We should have incremented x7 (from 0) exactly 8 times.
12304 ASSERT_EQUAL_64(8, x7);
12305
armvixl578645f2013-08-15 17:21:42 +010012306 ASSERT_EQUAL_64(fpcr_core, x8);
12307 ASSERT_EQUAL_64(fpcr_core, x9);
12308 ASSERT_EQUAL_64(0, x10);
12309
armvixlad96eda2013-06-14 11:42:37 +010012310 TEARDOWN();
12311}
12312
12313
12314TEST(system_nop) {
12315 SETUP();
12316 RegisterDump before;
12317
12318 START();
12319 before.Dump(&masm);
12320 __ Nop();
12321 END();
12322
12323 RUN();
12324
12325 ASSERT_EQUAL_REGISTERS(before);
12326 ASSERT_EQUAL_NZCV(before.flags_nzcv());
12327
12328 TEARDOWN();
12329}
12330
12331
12332TEST(zero_dest) {
12333 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010012334 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +010012335 RegisterDump before;
12336
12337 START();
12338 // Preserve the stack pointer, in case we clobber it.
12339 __ Mov(x30, sp);
12340 // Initialize the other registers used in this test.
armvixlb0c8ae22014-03-21 14:03:59 +000012341 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012342 __ Mov(x0, 0);
12343 __ Mov(x1, literal_base);
12344 for (unsigned i = 2; i < x30.code(); i++) {
12345 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
12346 }
12347 before.Dump(&masm);
12348
12349 // All of these instructions should be NOPs in these forms, but have
12350 // alternate forms which can write into the stack pointer.
12351 __ add(xzr, x0, x1);
12352 __ add(xzr, x1, xzr);
12353 __ add(xzr, xzr, x1);
12354
12355 __ and_(xzr, x0, x2);
12356 __ and_(xzr, x2, xzr);
12357 __ and_(xzr, xzr, x2);
12358
12359 __ bic(xzr, x0, x3);
12360 __ bic(xzr, x3, xzr);
12361 __ bic(xzr, xzr, x3);
12362
12363 __ eon(xzr, x0, x4);
12364 __ eon(xzr, x4, xzr);
12365 __ eon(xzr, xzr, x4);
12366
12367 __ eor(xzr, x0, x5);
12368 __ eor(xzr, x5, xzr);
12369 __ eor(xzr, xzr, x5);
12370
12371 __ orr(xzr, x0, x6);
12372 __ orr(xzr, x6, xzr);
12373 __ orr(xzr, xzr, x6);
12374
12375 __ sub(xzr, x0, x7);
12376 __ sub(xzr, x7, xzr);
12377 __ sub(xzr, xzr, x7);
12378
12379 // Swap the saved stack pointer with the real one. If sp was written
12380 // during the test, it will show up in x30. This is done because the test
12381 // framework assumes that sp will be valid at the end of the test.
12382 __ Mov(x29, x30);
12383 __ Mov(x30, sp);
12384 __ Mov(sp, x29);
12385 // We used x29 as a scratch register, so reset it to make sure it doesn't
12386 // trigger a test failure.
12387 __ Add(x29, x28, x1);
12388 END();
12389
12390 RUN();
12391
12392 ASSERT_EQUAL_REGISTERS(before);
12393 ASSERT_EQUAL_NZCV(before.flags_nzcv());
12394
12395 TEARDOWN();
12396}
12397
12398
12399TEST(zero_dest_setflags) {
12400 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010012401 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +010012402 RegisterDump before;
12403
12404 START();
12405 // Preserve the stack pointer, in case we clobber it.
12406 __ Mov(x30, sp);
12407 // Initialize the other registers used in this test.
armvixlb0c8ae22014-03-21 14:03:59 +000012408 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012409 __ Mov(x0, 0);
12410 __ Mov(x1, literal_base);
12411 for (int i = 2; i < 30; i++) {
12412 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
12413 }
12414 before.Dump(&masm);
12415
12416 // All of these instructions should only write to the flags in these forms,
12417 // but have alternate forms which can write into the stack pointer.
armvixlf37fdc02014-02-05 13:22:16 +000012418 __ adds(xzr, x0, Operand(x1, UXTX));
12419 __ adds(xzr, x1, Operand(xzr, UXTX));
12420 __ adds(xzr, x1, 1234);
12421 __ adds(xzr, x0, x1);
12422 __ adds(xzr, x1, xzr);
12423 __ adds(xzr, xzr, x1);
armvixlad96eda2013-06-14 11:42:37 +010012424
armvixlf37fdc02014-02-05 13:22:16 +000012425 __ ands(xzr, x2, ~0xf);
12426 __ ands(xzr, xzr, ~0xf);
12427 __ ands(xzr, x0, x2);
12428 __ ands(xzr, x2, xzr);
12429 __ ands(xzr, xzr, x2);
armvixlad96eda2013-06-14 11:42:37 +010012430
armvixlf37fdc02014-02-05 13:22:16 +000012431 __ bics(xzr, x3, ~0xf);
12432 __ bics(xzr, xzr, ~0xf);
12433 __ bics(xzr, x0, x3);
12434 __ bics(xzr, x3, xzr);
12435 __ bics(xzr, xzr, x3);
armvixlad96eda2013-06-14 11:42:37 +010012436
armvixlf37fdc02014-02-05 13:22:16 +000012437 __ subs(xzr, x0, Operand(x3, UXTX));
12438 __ subs(xzr, x3, Operand(xzr, UXTX));
12439 __ subs(xzr, x3, 1234);
12440 __ subs(xzr, x0, x3);
12441 __ subs(xzr, x3, xzr);
12442 __ subs(xzr, xzr, x3);
armvixlad96eda2013-06-14 11:42:37 +010012443
12444 // Swap the saved stack pointer with the real one. If sp was written
12445 // during the test, it will show up in x30. This is done because the test
12446 // framework assumes that sp will be valid at the end of the test.
12447 __ Mov(x29, x30);
12448 __ Mov(x30, sp);
12449 __ Mov(sp, x29);
12450 // We used x29 as a scratch register, so reset it to make sure it doesn't
12451 // trigger a test failure.
12452 __ Add(x29, x28, x1);
12453 END();
12454
12455 RUN();
12456
12457 ASSERT_EQUAL_REGISTERS(before);
12458
12459 TEARDOWN();
12460}
12461
12462
12463TEST(register_bit) {
12464 // No code generation takes place in this test, so no need to setup and
12465 // teardown.
12466
12467 // Simple tests.
armvixlb0c8ae22014-03-21 14:03:59 +000012468 assert(x0.Bit() == (UINT64_C(1) << 0));
12469 assert(x1.Bit() == (UINT64_C(1) << 1));
12470 assert(x10.Bit() == (UINT64_C(1) << 10));
armvixlad96eda2013-06-14 11:42:37 +010012471
12472 // AAPCS64 definitions.
armvixlb0c8ae22014-03-21 14:03:59 +000012473 assert(lr.Bit() == (UINT64_C(1) << kLinkRegCode));
armvixlad96eda2013-06-14 11:42:37 +010012474
12475 // Fixed (hardware) definitions.
armvixlb0c8ae22014-03-21 14:03:59 +000012476 assert(xzr.Bit() == (UINT64_C(1) << kZeroRegCode));
armvixlad96eda2013-06-14 11:42:37 +010012477
12478 // Internal ABI definitions.
armvixlb0c8ae22014-03-21 14:03:59 +000012479 assert(sp.Bit() == (UINT64_C(1) << kSPRegInternalCode));
armvixlad96eda2013-06-14 11:42:37 +010012480 assert(sp.Bit() != xzr.Bit());
12481
12482 // xn.Bit() == wn.Bit() at all times, for the same n.
12483 assert(x0.Bit() == w0.Bit());
12484 assert(x1.Bit() == w1.Bit());
12485 assert(x10.Bit() == w10.Bit());
12486 assert(xzr.Bit() == wzr.Bit());
12487 assert(sp.Bit() == wsp.Bit());
12488}
12489
12490
12491TEST(stack_pointer_override) {
12492 // This test generates some stack maintenance code, but the test only checks
12493 // the reported state.
12494 SETUP();
12495 START();
12496
12497 // The default stack pointer in VIXL is sp.
12498 assert(sp.Is(__ StackPointer()));
12499 __ SetStackPointer(x0);
12500 assert(x0.Is(__ StackPointer()));
12501 __ SetStackPointer(x28);
12502 assert(x28.Is(__ StackPointer()));
12503 __ SetStackPointer(sp);
12504 assert(sp.Is(__ StackPointer()));
12505
12506 END();
12507 RUN();
12508 TEARDOWN();
12509}
12510
12511
12512TEST(peek_poke_simple) {
12513 SETUP();
12514 START();
12515
12516 static const RegList x0_to_x3 = x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit();
12517 static const RegList x10_to_x13 = x10.Bit() | x11.Bit() |
12518 x12.Bit() | x13.Bit();
12519
12520 // The literal base is chosen to have two useful properties:
12521 // * When multiplied by small values (such as a register index), this value
12522 // is clearly readable in the result.
12523 // * The value is not formed from repeating fixed-size smaller values, so it
12524 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000012525 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012526
12527 // Initialize the registers.
12528 __ Mov(x0, literal_base);
12529 __ Add(x1, x0, x0);
12530 __ Add(x2, x1, x0);
12531 __ Add(x3, x2, x0);
12532
12533 __ Claim(32);
12534
12535 // Simple exchange.
12536 // After this test:
12537 // x0-x3 should be unchanged.
12538 // w10-w13 should contain the lower words of x0-x3.
12539 __ Poke(x0, 0);
12540 __ Poke(x1, 8);
12541 __ Poke(x2, 16);
12542 __ Poke(x3, 24);
12543 Clobber(&masm, x0_to_x3);
12544 __ Peek(x0, 0);
12545 __ Peek(x1, 8);
12546 __ Peek(x2, 16);
12547 __ Peek(x3, 24);
12548
12549 __ Poke(w0, 0);
12550 __ Poke(w1, 4);
12551 __ Poke(w2, 8);
12552 __ Poke(w3, 12);
12553 Clobber(&masm, x10_to_x13);
12554 __ Peek(w10, 0);
12555 __ Peek(w11, 4);
12556 __ Peek(w12, 8);
12557 __ Peek(w13, 12);
12558
12559 __ Drop(32);
12560
12561 END();
12562 RUN();
12563
12564 ASSERT_EQUAL_64(literal_base * 1, x0);
12565 ASSERT_EQUAL_64(literal_base * 2, x1);
12566 ASSERT_EQUAL_64(literal_base * 3, x2);
12567 ASSERT_EQUAL_64(literal_base * 4, x3);
12568
12569 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
12570 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
12571 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
12572 ASSERT_EQUAL_64((literal_base * 4) & 0xffffffff, x13);
12573
12574 TEARDOWN();
12575}
12576
12577
12578TEST(peek_poke_unaligned) {
12579 SETUP();
12580 START();
12581
12582 // The literal base is chosen to have two useful properties:
12583 // * When multiplied by small values (such as a register index), this value
12584 // is clearly readable in the result.
12585 // * The value is not formed from repeating fixed-size smaller values, so it
12586 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000012587 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012588
12589 // Initialize the registers.
12590 __ Mov(x0, literal_base);
12591 __ Add(x1, x0, x0);
12592 __ Add(x2, x1, x0);
12593 __ Add(x3, x2, x0);
12594 __ Add(x4, x3, x0);
12595 __ Add(x5, x4, x0);
12596 __ Add(x6, x5, x0);
12597
12598 __ Claim(32);
12599
12600 // Unaligned exchanges.
12601 // After this test:
12602 // x0-x6 should be unchanged.
12603 // w10-w12 should contain the lower words of x0-x2.
12604 __ Poke(x0, 1);
12605 Clobber(&masm, x0.Bit());
12606 __ Peek(x0, 1);
12607 __ Poke(x1, 2);
12608 Clobber(&masm, x1.Bit());
12609 __ Peek(x1, 2);
12610 __ Poke(x2, 3);
12611 Clobber(&masm, x2.Bit());
12612 __ Peek(x2, 3);
12613 __ Poke(x3, 4);
12614 Clobber(&masm, x3.Bit());
12615 __ Peek(x3, 4);
12616 __ Poke(x4, 5);
12617 Clobber(&masm, x4.Bit());
12618 __ Peek(x4, 5);
12619 __ Poke(x5, 6);
12620 Clobber(&masm, x5.Bit());
12621 __ Peek(x5, 6);
12622 __ Poke(x6, 7);
12623 Clobber(&masm, x6.Bit());
12624 __ Peek(x6, 7);
12625
12626 __ Poke(w0, 1);
12627 Clobber(&masm, w10.Bit());
12628 __ Peek(w10, 1);
12629 __ Poke(w1, 2);
12630 Clobber(&masm, w11.Bit());
12631 __ Peek(w11, 2);
12632 __ Poke(w2, 3);
12633 Clobber(&masm, w12.Bit());
12634 __ Peek(w12, 3);
12635
12636 __ Drop(32);
12637
12638 END();
12639 RUN();
12640
12641 ASSERT_EQUAL_64(literal_base * 1, x0);
12642 ASSERT_EQUAL_64(literal_base * 2, x1);
12643 ASSERT_EQUAL_64(literal_base * 3, x2);
12644 ASSERT_EQUAL_64(literal_base * 4, x3);
12645 ASSERT_EQUAL_64(literal_base * 5, x4);
12646 ASSERT_EQUAL_64(literal_base * 6, x5);
12647 ASSERT_EQUAL_64(literal_base * 7, x6);
12648
12649 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
12650 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
12651 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
12652
12653 TEARDOWN();
12654}
12655
12656
12657TEST(peek_poke_endianness) {
12658 SETUP();
12659 START();
12660
12661 // The literal base is chosen to have two useful properties:
12662 // * When multiplied by small values (such as a register index), this value
12663 // is clearly readable in the result.
12664 // * The value is not formed from repeating fixed-size smaller values, so it
12665 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000012666 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012667
12668 // Initialize the registers.
12669 __ Mov(x0, literal_base);
12670 __ Add(x1, x0, x0);
12671
12672 __ Claim(32);
12673
12674 // Endianness tests.
12675 // After this section:
12676 // x4 should match x0[31:0]:x0[63:32]
12677 // w5 should match w1[15:0]:w1[31:16]
12678 __ Poke(x0, 0);
12679 __ Poke(x0, 8);
12680 __ Peek(x4, 4);
12681
12682 __ Poke(w1, 0);
12683 __ Poke(w1, 4);
12684 __ Peek(w5, 2);
12685
12686 __ Drop(32);
12687
12688 END();
12689 RUN();
12690
12691 uint64_t x0_expected = literal_base * 1;
12692 uint64_t x1_expected = literal_base * 2;
12693 uint64_t x4_expected = (x0_expected << 32) | (x0_expected >> 32);
12694 uint64_t x5_expected = ((x1_expected << 16) & 0xffff0000) |
12695 ((x1_expected >> 16) & 0x0000ffff);
12696
12697 ASSERT_EQUAL_64(x0_expected, x0);
12698 ASSERT_EQUAL_64(x1_expected, x1);
12699 ASSERT_EQUAL_64(x4_expected, x4);
12700 ASSERT_EQUAL_64(x5_expected, x5);
12701
12702 TEARDOWN();
12703}
12704
12705
12706TEST(peek_poke_mixed) {
12707 SETUP();
12708 START();
12709
armvixl6e2c8272015-03-31 11:04:14 +010012710 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
12711 UseScratchRegisterScope temps(&masm);
12712 temps.ExcludeAll();
12713
armvixlad96eda2013-06-14 11:42:37 +010012714 // The literal base is chosen to have two useful properties:
12715 // * When multiplied by small values (such as a register index), this value
12716 // is clearly readable in the result.
12717 // * The value is not formed from repeating fixed-size smaller values, so it
12718 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000012719 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012720
12721 // Initialize the registers.
12722 __ Mov(x0, literal_base);
12723 __ Add(x1, x0, x0);
12724 __ Add(x2, x1, x0);
12725 __ Add(x3, x2, x0);
12726
12727 __ Claim(32);
12728
12729 // Mix with other stack operations.
12730 // After this section:
12731 // x0-x3 should be unchanged.
12732 // x6 should match x1[31:0]:x0[63:32]
12733 // w7 should match x1[15:0]:x0[63:48]
12734 __ Poke(x1, 8);
12735 __ Poke(x0, 0);
12736 {
armvixlb0c8ae22014-03-21 14:03:59 +000012737 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010012738 __ Mov(x4, __ StackPointer());
12739 __ SetStackPointer(x4);
12740
12741 __ Poke(wzr, 0); // Clobber the space we're about to drop.
12742 __ Drop(4);
12743 __ Peek(x6, 0);
12744 __ Claim(8);
12745 __ Peek(w7, 10);
12746 __ Poke(x3, 28);
12747 __ Poke(xzr, 0); // Clobber the space we're about to drop.
12748 __ Drop(8);
12749 __ Poke(x2, 12);
12750 __ Push(w0);
12751
12752 __ Mov(sp, __ StackPointer());
12753 __ SetStackPointer(sp);
12754 }
12755
12756 __ Pop(x0, x1, x2, x3);
12757
12758 END();
12759 RUN();
12760
12761 uint64_t x0_expected = literal_base * 1;
12762 uint64_t x1_expected = literal_base * 2;
12763 uint64_t x2_expected = literal_base * 3;
12764 uint64_t x3_expected = literal_base * 4;
12765 uint64_t x6_expected = (x1_expected << 32) | (x0_expected >> 32);
12766 uint64_t x7_expected = ((x1_expected << 16) & 0xffff0000) |
12767 ((x0_expected >> 48) & 0x0000ffff);
12768
12769 ASSERT_EQUAL_64(x0_expected, x0);
12770 ASSERT_EQUAL_64(x1_expected, x1);
12771 ASSERT_EQUAL_64(x2_expected, x2);
12772 ASSERT_EQUAL_64(x3_expected, x3);
12773 ASSERT_EQUAL_64(x6_expected, x6);
12774 ASSERT_EQUAL_64(x7_expected, x7);
12775
12776 TEARDOWN();
12777}
12778
12779
armvixlc68cb642014-09-25 18:49:30 +010012780TEST(peek_poke_reglist) {
12781 SETUP();
12782 START();
12783
armvixl6e2c8272015-03-31 11:04:14 +010012784 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
12785 UseScratchRegisterScope temps(&masm);
12786 temps.ExcludeAll();
12787
armvixlc68cb642014-09-25 18:49:30 +010012788 // The literal base is chosen to have two useful properties:
12789 // * When multiplied by small values (such as a register index), this value
12790 // is clearly readable in the result.
12791 // * The value is not formed from repeating fixed-size smaller values, so it
12792 // can be used to detect endianness-related errors.
12793 uint64_t base = 0x0100001000100101;
12794
12795 // Initialize the registers.
12796 __ Mov(x1, base);
12797 __ Add(x2, x1, x1);
12798 __ Add(x3, x2, x1);
12799 __ Add(x4, x3, x1);
12800
12801 CPURegList list_1(x1, x2, x3, x4);
12802 CPURegList list_2(x11, x12, x13, x14);
12803 int list_1_size = list_1.TotalSizeInBytes();
12804
12805 __ Claim(2 * list_1_size);
12806
12807 __ PokeCPURegList(list_1, 0);
12808 __ PokeXRegList(list_1.list(), list_1_size);
12809 __ PeekCPURegList(list_2, 2 * kXRegSizeInBytes);
12810 __ PeekXRegList(x15.Bit(), kWRegSizeInBytes);
12811 __ PeekWRegList(w16.Bit() | w17.Bit(), 3 * kXRegSizeInBytes);
12812
12813 __ Drop(2 * list_1_size);
12814
12815
12816 uint64_t base_d = 0x1010010001000010;
12817
12818 // Initialize the registers.
12819 __ Mov(x1, base_d);
12820 __ Add(x2, x1, x1);
12821 __ Add(x3, x2, x1);
12822 __ Add(x4, x3, x1);
12823 __ Fmov(d1, x1);
12824 __ Fmov(d2, x2);
12825 __ Fmov(d3, x3);
12826 __ Fmov(d4, x4);
12827
12828 CPURegList list_d_1(d1, d2, d3, d4);
12829 CPURegList list_d_2(d11, d12, d13, d14);
12830 int list_d_1_size = list_d_1.TotalSizeInBytes();
12831
12832 __ Claim(2 * list_d_1_size);
12833
12834 __ PokeCPURegList(list_d_1, 0);
12835 __ PokeDRegList(list_d_1.list(), list_d_1_size);
12836 __ PeekCPURegList(list_d_2, 2 * kDRegSizeInBytes);
12837 __ PeekDRegList(d15.Bit(), kSRegSizeInBytes);
12838 __ PeekSRegList(s16.Bit() | s17.Bit(), 3 * kDRegSizeInBytes);
12839
12840 __ Drop(2 * list_d_1_size);
12841
12842
12843 END();
12844 RUN();
12845
12846 ASSERT_EQUAL_64(3 * base, x11);
12847 ASSERT_EQUAL_64(4 * base, x12);
12848 ASSERT_EQUAL_64(1 * base, x13);
12849 ASSERT_EQUAL_64(2 * base, x14);
12850 ASSERT_EQUAL_64(((1 * base) >> kWRegSize) | ((2 * base) << kWRegSize), x15);
12851 ASSERT_EQUAL_64(2 * base, x14);
12852 ASSERT_EQUAL_32((4 * base) & kWRegMask, w16);
12853 ASSERT_EQUAL_32((4 * base) >> kWRegSize, w17);
12854
12855 ASSERT_EQUAL_FP64(rawbits_to_double(3 * base_d), d11);
12856 ASSERT_EQUAL_FP64(rawbits_to_double(4 * base_d), d12);
12857 ASSERT_EQUAL_FP64(rawbits_to_double(1 * base_d), d13);
12858 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base_d), d14);
12859 ASSERT_EQUAL_FP64(
12860 rawbits_to_double((base_d >> kSRegSize) | ((2 * base_d) << kSRegSize)),
12861 d15);
12862 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base_d), d14);
12863 ASSERT_EQUAL_FP32(rawbits_to_float((4 * base_d) & kSRegMask), s16);
12864 ASSERT_EQUAL_FP32(rawbits_to_float((4 * base_d) >> kSRegSize), s17);
12865
12866 TEARDOWN();
12867}
12868
12869
armvixl6e2c8272015-03-31 11:04:14 +010012870TEST(load_store_reglist) {
12871 SETUP();
12872 START();
12873
12874 // The literal base is chosen to have two useful properties:
12875 // * When multiplied by small values (such as a register index), this value
12876 // is clearly readable in the result.
12877 // * The value is not formed from repeating fixed-size smaller values, so it
12878 // can be used to detect endianness-related errors.
12879 uint64_t high_base = UINT32_C(0x01000010);
12880 uint64_t low_base = UINT32_C(0x00100101);
12881 uint64_t base = (high_base << 32) | low_base;
12882 uint64_t array[21];
12883 memset(array, 0, sizeof(array));
12884
12885 // Initialize the registers.
12886 __ Mov(x1, base);
12887 __ Add(x2, x1, x1);
12888 __ Add(x3, x2, x1);
12889 __ Add(x4, x3, x1);
12890 __ Fmov(d1, x1);
12891 __ Fmov(d2, x2);
12892 __ Fmov(d3, x3);
12893 __ Fmov(d4, x4);
12894 __ Fmov(d5, x1);
12895 __ Fmov(d6, x2);
12896 __ Fmov(d7, x3);
12897 __ Fmov(d8, x4);
12898
12899 Register reg_base = x20;
12900 Register reg_index = x21;
12901 int size_stored = 0;
12902
12903 __ Mov(reg_base, reinterpret_cast<uintptr_t>(&array));
12904
12905 // Test aligned accesses.
12906 CPURegList list_src(w1, w2, w3, w4);
12907 CPURegList list_dst(w11, w12, w13, w14);
12908 CPURegList list_fp_src_1(d1, d2, d3, d4);
12909 CPURegList list_fp_dst_1(d11, d12, d13, d14);
12910
12911 __ StoreCPURegList(list_src, MemOperand(reg_base, 0 * sizeof(uint64_t)));
12912 __ LoadCPURegList(list_dst, MemOperand(reg_base, 0 * sizeof(uint64_t)));
12913 size_stored += 4 * kWRegSizeInBytes;
12914
12915 __ Mov(reg_index, size_stored);
12916 __ StoreCPURegList(list_src, MemOperand(reg_base, reg_index));
12917 __ LoadCPURegList(list_dst, MemOperand(reg_base, reg_index));
12918 size_stored += 4 * kWRegSizeInBytes;
12919
12920 __ StoreCPURegList(list_fp_src_1, MemOperand(reg_base, size_stored));
12921 __ LoadCPURegList(list_fp_dst_1, MemOperand(reg_base, size_stored));
12922 size_stored += 4 * kDRegSizeInBytes;
12923
12924 __ Mov(reg_index, size_stored);
12925 __ StoreCPURegList(list_fp_src_1, MemOperand(reg_base, reg_index));
12926 __ LoadCPURegList(list_fp_dst_1, MemOperand(reg_base, reg_index));
12927 size_stored += 4 * kDRegSizeInBytes;
12928
12929 // Test unaligned accesses.
12930 CPURegList list_fp_src_2(d5, d6, d7, d8);
12931 CPURegList list_fp_dst_2(d15, d16, d17, d18);
12932
12933 __ Str(wzr, MemOperand(reg_base, size_stored));
12934 size_stored += 1 * kWRegSizeInBytes;
12935 __ StoreCPURegList(list_fp_src_2, MemOperand(reg_base, size_stored));
12936 __ LoadCPURegList(list_fp_dst_2, MemOperand(reg_base, size_stored));
12937 size_stored += 4 * kDRegSizeInBytes;
12938
12939 __ Mov(reg_index, size_stored);
12940 __ StoreCPURegList(list_fp_src_2, MemOperand(reg_base, reg_index));
12941 __ LoadCPURegList(list_fp_dst_2, MemOperand(reg_base, reg_index));
12942
12943 END();
12944 RUN();
12945
12946 VIXL_CHECK(array[0] == (1 * low_base) + (2 * low_base << kWRegSize));
12947 VIXL_CHECK(array[1] == (3 * low_base) + (4 * low_base << kWRegSize));
12948 VIXL_CHECK(array[2] == (1 * low_base) + (2 * low_base << kWRegSize));
12949 VIXL_CHECK(array[3] == (3 * low_base) + (4 * low_base << kWRegSize));
12950 VIXL_CHECK(array[4] == 1 * base);
12951 VIXL_CHECK(array[5] == 2 * base);
12952 VIXL_CHECK(array[6] == 3 * base);
12953 VIXL_CHECK(array[7] == 4 * base);
12954 VIXL_CHECK(array[8] == 1 * base);
12955 VIXL_CHECK(array[9] == 2 * base);
12956 VIXL_CHECK(array[10] == 3 * base);
12957 VIXL_CHECK(array[11] == 4 * base);
12958 VIXL_CHECK(array[12] == ((1 * low_base) << kSRegSize));
12959 VIXL_CHECK(array[13] == (((2 * low_base) << kSRegSize) | (1 * high_base)));
12960 VIXL_CHECK(array[14] == (((3 * low_base) << kSRegSize) | (2 * high_base)));
12961 VIXL_CHECK(array[15] == (((4 * low_base) << kSRegSize) | (3 * high_base)));
12962 VIXL_CHECK(array[16] == (((1 * low_base) << kSRegSize) | (4 * high_base)));
12963 VIXL_CHECK(array[17] == (((2 * low_base) << kSRegSize) | (1 * high_base)));
12964 VIXL_CHECK(array[18] == (((3 * low_base) << kSRegSize) | (2 * high_base)));
12965 VIXL_CHECK(array[19] == (((4 * low_base) << kSRegSize) | (3 * high_base)));
12966 VIXL_CHECK(array[20] == (4 * high_base));
12967
12968 ASSERT_EQUAL_64(1 * low_base, x11);
12969 ASSERT_EQUAL_64(2 * low_base, x12);
12970 ASSERT_EQUAL_64(3 * low_base, x13);
12971 ASSERT_EQUAL_64(4 * low_base, x14);
12972 ASSERT_EQUAL_FP64(rawbits_to_double(1 * base), d11);
12973 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base), d12);
12974 ASSERT_EQUAL_FP64(rawbits_to_double(3 * base), d13);
12975 ASSERT_EQUAL_FP64(rawbits_to_double(4 * base), d14);
12976 ASSERT_EQUAL_FP64(rawbits_to_double(1 * base), d15);
12977 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base), d16);
12978 ASSERT_EQUAL_FP64(rawbits_to_double(3 * base), d17);
12979 ASSERT_EQUAL_FP64(rawbits_to_double(4 * base), d18);
12980
12981 TEARDOWN();
12982}
12983
12984
armvixlad96eda2013-06-14 11:42:37 +010012985// This enum is used only as an argument to the push-pop test helpers.
12986enum PushPopMethod {
12987 // Push or Pop using the Push and Pop methods, with blocks of up to four
12988 // registers. (Smaller blocks will be used if necessary.)
12989 PushPopByFour,
12990
12991 // Use Push<Size>RegList and Pop<Size>RegList to transfer the registers.
12992 PushPopRegList
12993};
12994
12995
12996// The maximum number of registers that can be used by the PushPopXReg* tests,
12997// where a reg_count field is provided.
12998static int const kPushPopXRegMaxRegCount = -1;
12999
13000// Test a simple push-pop pattern:
13001// * Claim <claim> bytes to set the stack alignment.
13002// * Push <reg_count> registers with size <reg_size>.
13003// * Clobber the register contents.
13004// * Pop <reg_count> registers to restore the original contents.
13005// * Drop <claim> bytes to restore the original stack pointer.
13006//
13007// Different push and pop methods can be specified independently to test for
13008// proper word-endian behaviour.
13009static void PushPopXRegSimpleHelper(int reg_count,
13010 int claim,
13011 int reg_size,
13012 PushPopMethod push_method,
13013 PushPopMethod pop_method) {
13014 SETUP();
13015
13016 START();
13017
13018 // Arbitrarily pick a register to use as a stack pointer.
13019 const Register& stack_pointer = x20;
13020 const RegList allowed = ~stack_pointer.Bit();
13021 if (reg_count == kPushPopXRegMaxRegCount) {
13022 reg_count = CountSetBits(allowed, kNumberOfRegisters);
13023 }
13024 // Work out which registers to use, based on reg_size.
13025 Register r[kNumberOfRegisters];
13026 Register x[kNumberOfRegisters];
13027 RegList list = PopulateRegisterArray(NULL, x, r, reg_size, reg_count,
13028 allowed);
13029
armvixl6e2c8272015-03-31 11:04:14 +010013030 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13031 UseScratchRegisterScope temps(&masm);
13032 temps.ExcludeAll();
13033
armvixlad96eda2013-06-14 11:42:37 +010013034 // The literal base is chosen to have two useful properties:
13035 // * When multiplied by small values (such as a register index), this value
13036 // is clearly readable in the result.
13037 // * The value is not formed from repeating fixed-size smaller values, so it
13038 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000013039 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013040
13041 {
armvixlb0c8ae22014-03-21 14:03:59 +000013042 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013043 __ Mov(stack_pointer, __ StackPointer());
13044 __ SetStackPointer(stack_pointer);
13045
13046 int i;
13047
13048 // Initialize the registers.
13049 for (i = 0; i < reg_count; i++) {
13050 // Always write into the X register, to ensure that the upper word is
13051 // properly ignored by Push when testing W registers.
13052 __ Mov(x[i], literal_base * i);
13053 }
13054
13055 // Claim memory first, as requested.
13056 __ Claim(claim);
13057
13058 switch (push_method) {
13059 case PushPopByFour:
13060 // Push high-numbered registers first (to the highest addresses).
13061 for (i = reg_count; i >= 4; i -= 4) {
13062 __ Push(r[i-1], r[i-2], r[i-3], r[i-4]);
13063 }
13064 // Finish off the leftovers.
13065 switch (i) {
13066 case 3: __ Push(r[2], r[1], r[0]); break;
13067 case 2: __ Push(r[1], r[0]); break;
13068 case 1: __ Push(r[0]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013069 default: VIXL_ASSERT(i == 0); break;
armvixlad96eda2013-06-14 11:42:37 +010013070 }
13071 break;
13072 case PushPopRegList:
13073 __ PushSizeRegList(list, reg_size);
13074 break;
13075 }
13076
13077 // Clobber all the registers, to ensure that they get repopulated by Pop.
13078 Clobber(&masm, list);
13079
13080 switch (pop_method) {
13081 case PushPopByFour:
13082 // Pop low-numbered registers first (from the lowest addresses).
13083 for (i = 0; i <= (reg_count-4); i += 4) {
13084 __ Pop(r[i], r[i+1], r[i+2], r[i+3]);
13085 }
13086 // Finish off the leftovers.
13087 switch (reg_count - i) {
13088 case 3: __ Pop(r[i], r[i+1], r[i+2]); break;
13089 case 2: __ Pop(r[i], r[i+1]); break;
13090 case 1: __ Pop(r[i]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013091 default: VIXL_ASSERT(i == reg_count); break;
armvixlad96eda2013-06-14 11:42:37 +010013092 }
13093 break;
13094 case PushPopRegList:
13095 __ PopSizeRegList(list, reg_size);
13096 break;
13097 }
13098
13099 // Drop memory to restore stack_pointer.
13100 __ Drop(claim);
13101
13102 __ Mov(sp, __ StackPointer());
13103 __ SetStackPointer(sp);
13104 }
13105
13106 END();
13107
13108 RUN();
13109
13110 // Check that the register contents were preserved.
13111 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
13112 // that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +000013113 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +010013114 for (int i = 0; i < reg_count; i++) {
13115 if (x[i].Is(xzr)) {
13116 ASSERT_EQUAL_64(0, x[i]);
13117 } else {
13118 ASSERT_EQUAL_64(literal_base * i, x[i]);
13119 }
13120 }
13121
13122 TEARDOWN();
13123}
13124
13125
13126TEST(push_pop_xreg_simple_32) {
13127 for (int claim = 0; claim <= 8; claim++) {
13128 for (int count = 0; count <= 8; count++) {
13129 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13130 PushPopByFour, PushPopByFour);
13131 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13132 PushPopByFour, PushPopRegList);
13133 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13134 PushPopRegList, PushPopByFour);
13135 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13136 PushPopRegList, PushPopRegList);
13137 }
13138 // Test with the maximum number of registers.
13139 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13140 claim, kWRegSize, PushPopByFour, PushPopByFour);
13141 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13142 claim, kWRegSize, PushPopByFour, PushPopRegList);
13143 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13144 claim, kWRegSize, PushPopRegList, PushPopByFour);
13145 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13146 claim, kWRegSize, PushPopRegList, PushPopRegList);
13147 }
13148}
13149
13150
13151TEST(push_pop_xreg_simple_64) {
13152 for (int claim = 0; claim <= 8; claim++) {
13153 for (int count = 0; count <= 8; count++) {
13154 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13155 PushPopByFour, PushPopByFour);
13156 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13157 PushPopByFour, PushPopRegList);
13158 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13159 PushPopRegList, PushPopByFour);
13160 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13161 PushPopRegList, PushPopRegList);
13162 }
13163 // Test with the maximum number of registers.
13164 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13165 claim, kXRegSize, PushPopByFour, PushPopByFour);
13166 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13167 claim, kXRegSize, PushPopByFour, PushPopRegList);
13168 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13169 claim, kXRegSize, PushPopRegList, PushPopByFour);
13170 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13171 claim, kXRegSize, PushPopRegList, PushPopRegList);
13172 }
13173}
13174
13175
13176// The maximum number of registers that can be used by the PushPopFPXReg* tests,
13177// where a reg_count field is provided.
13178static int const kPushPopFPXRegMaxRegCount = -1;
13179
13180// Test a simple push-pop pattern:
13181// * Claim <claim> bytes to set the stack alignment.
13182// * Push <reg_count> FP registers with size <reg_size>.
13183// * Clobber the register contents.
13184// * Pop <reg_count> FP registers to restore the original contents.
13185// * Drop <claim> bytes to restore the original stack pointer.
13186//
13187// Different push and pop methods can be specified independently to test for
13188// proper word-endian behaviour.
13189static void PushPopFPXRegSimpleHelper(int reg_count,
13190 int claim,
13191 int reg_size,
13192 PushPopMethod push_method,
13193 PushPopMethod pop_method) {
13194 SETUP();
13195
13196 START();
13197
13198 // We can use any floating-point register. None of them are reserved for
13199 // debug code, for example.
13200 static RegList const allowed = ~0;
13201 if (reg_count == kPushPopFPXRegMaxRegCount) {
13202 reg_count = CountSetBits(allowed, kNumberOfFPRegisters);
13203 }
13204 // Work out which registers to use, based on reg_size.
13205 FPRegister v[kNumberOfRegisters];
13206 FPRegister d[kNumberOfRegisters];
13207 RegList list = PopulateFPRegisterArray(NULL, d, v, reg_size, reg_count,
13208 allowed);
13209
13210 // Arbitrarily pick a register to use as a stack pointer.
13211 const Register& stack_pointer = x10;
13212
armvixl6e2c8272015-03-31 11:04:14 +010013213 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13214 UseScratchRegisterScope temps(&masm);
13215 temps.ExcludeAll();
13216
armvixlad96eda2013-06-14 11:42:37 +010013217 // The literal base is chosen to have two useful properties:
13218 // * When multiplied (using an integer) by small values (such as a register
13219 // index), this value is clearly readable in the result.
13220 // * The value is not formed from repeating fixed-size smaller values, so it
13221 // can be used to detect endianness-related errors.
13222 // * It is never a floating-point NaN, and will therefore always compare
13223 // equal to itself.
armvixlb0c8ae22014-03-21 14:03:59 +000013224 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013225
13226 {
armvixlb0c8ae22014-03-21 14:03:59 +000013227 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013228 __ Mov(stack_pointer, __ StackPointer());
13229 __ SetStackPointer(stack_pointer);
13230
13231 int i;
13232
13233 // Initialize the registers, using X registers to load the literal.
13234 __ Mov(x0, 0);
13235 __ Mov(x1, literal_base);
13236 for (i = 0; i < reg_count; i++) {
13237 // Always write into the D register, to ensure that the upper word is
13238 // properly ignored by Push when testing S registers.
13239 __ Fmov(d[i], x0);
13240 // Calculate the next literal.
13241 __ Add(x0, x0, x1);
13242 }
13243
13244 // Claim memory first, as requested.
13245 __ Claim(claim);
13246
13247 switch (push_method) {
13248 case PushPopByFour:
13249 // Push high-numbered registers first (to the highest addresses).
13250 for (i = reg_count; i >= 4; i -= 4) {
13251 __ Push(v[i-1], v[i-2], v[i-3], v[i-4]);
13252 }
13253 // Finish off the leftovers.
13254 switch (i) {
13255 case 3: __ Push(v[2], v[1], v[0]); break;
13256 case 2: __ Push(v[1], v[0]); break;
13257 case 1: __ Push(v[0]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013258 default: VIXL_ASSERT(i == 0); break;
armvixlad96eda2013-06-14 11:42:37 +010013259 }
13260 break;
13261 case PushPopRegList:
armvixl5289c592015-03-02 13:52:04 +000013262 __ PushSizeRegList(list, reg_size, CPURegister::kVRegister);
armvixlad96eda2013-06-14 11:42:37 +010013263 break;
13264 }
13265
13266 // Clobber all the registers, to ensure that they get repopulated by Pop.
13267 ClobberFP(&masm, list);
13268
13269 switch (pop_method) {
13270 case PushPopByFour:
13271 // Pop low-numbered registers first (from the lowest addresses).
13272 for (i = 0; i <= (reg_count-4); i += 4) {
13273 __ Pop(v[i], v[i+1], v[i+2], v[i+3]);
13274 }
13275 // Finish off the leftovers.
13276 switch (reg_count - i) {
13277 case 3: __ Pop(v[i], v[i+1], v[i+2]); break;
13278 case 2: __ Pop(v[i], v[i+1]); break;
13279 case 1: __ Pop(v[i]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013280 default: VIXL_ASSERT(i == reg_count); break;
armvixlad96eda2013-06-14 11:42:37 +010013281 }
13282 break;
13283 case PushPopRegList:
armvixl5289c592015-03-02 13:52:04 +000013284 __ PopSizeRegList(list, reg_size, CPURegister::kVRegister);
armvixlad96eda2013-06-14 11:42:37 +010013285 break;
13286 }
13287
13288 // Drop memory to restore the stack pointer.
13289 __ Drop(claim);
13290
13291 __ Mov(sp, __ StackPointer());
13292 __ SetStackPointer(sp);
13293 }
13294
13295 END();
13296
13297 RUN();
13298
13299 // Check that the register contents were preserved.
13300 // Always use ASSERT_EQUAL_FP64, even when testing S registers, so we can
13301 // test that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +000013302 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +010013303 for (int i = 0; i < reg_count; i++) {
13304 uint64_t literal = literal_base * i;
13305 double expected;
13306 memcpy(&expected, &literal, sizeof(expected));
13307 ASSERT_EQUAL_FP64(expected, d[i]);
13308 }
13309
13310 TEARDOWN();
13311}
13312
13313
13314TEST(push_pop_fp_xreg_simple_32) {
13315 for (int claim = 0; claim <= 8; claim++) {
13316 for (int count = 0; count <= 8; count++) {
13317 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13318 PushPopByFour, PushPopByFour);
13319 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13320 PushPopByFour, PushPopRegList);
13321 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13322 PushPopRegList, PushPopByFour);
13323 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13324 PushPopRegList, PushPopRegList);
13325 }
13326 // Test with the maximum number of registers.
13327 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13328 PushPopByFour, PushPopByFour);
13329 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13330 PushPopByFour, PushPopRegList);
13331 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13332 PushPopRegList, PushPopByFour);
13333 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13334 PushPopRegList, PushPopRegList);
13335 }
13336}
13337
13338
13339TEST(push_pop_fp_xreg_simple_64) {
13340 for (int claim = 0; claim <= 8; claim++) {
13341 for (int count = 0; count <= 8; count++) {
13342 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13343 PushPopByFour, PushPopByFour);
13344 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13345 PushPopByFour, PushPopRegList);
13346 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13347 PushPopRegList, PushPopByFour);
13348 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13349 PushPopRegList, PushPopRegList);
13350 }
13351 // Test with the maximum number of registers.
13352 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13353 PushPopByFour, PushPopByFour);
13354 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13355 PushPopByFour, PushPopRegList);
13356 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13357 PushPopRegList, PushPopByFour);
13358 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13359 PushPopRegList, PushPopRegList);
13360 }
13361}
13362
13363
13364// Push and pop data using an overlapping combination of Push/Pop and
13365// RegList-based methods.
13366static void PushPopXRegMixedMethodsHelper(int claim, int reg_size) {
13367 SETUP();
13368
13369 // Arbitrarily pick a register to use as a stack pointer.
13370 const Register& stack_pointer = x5;
13371 const RegList allowed = ~stack_pointer.Bit();
13372 // Work out which registers to use, based on reg_size.
13373 Register r[10];
13374 Register x[10];
13375 PopulateRegisterArray(NULL, x, r, reg_size, 10, allowed);
13376
13377 // Calculate some handy register lists.
13378 RegList r0_to_r3 = 0;
13379 for (int i = 0; i <= 3; i++) {
13380 r0_to_r3 |= x[i].Bit();
13381 }
13382 RegList r4_to_r5 = 0;
13383 for (int i = 4; i <= 5; i++) {
13384 r4_to_r5 |= x[i].Bit();
13385 }
13386 RegList r6_to_r9 = 0;
13387 for (int i = 6; i <= 9; i++) {
13388 r6_to_r9 |= x[i].Bit();
13389 }
13390
armvixl6e2c8272015-03-31 11:04:14 +010013391 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13392 UseScratchRegisterScope temps(&masm);
13393 temps.ExcludeAll();
13394
armvixlad96eda2013-06-14 11:42:37 +010013395 // The literal base is chosen to have two useful properties:
13396 // * When multiplied by small values (such as a register index), this value
13397 // is clearly readable in the result.
13398 // * The value is not formed from repeating fixed-size smaller values, so it
13399 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000013400 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013401
13402 START();
13403 {
armvixlb0c8ae22014-03-21 14:03:59 +000013404 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013405 __ Mov(stack_pointer, __ StackPointer());
13406 __ SetStackPointer(stack_pointer);
13407
13408 // Claim memory first, as requested.
13409 __ Claim(claim);
13410
13411 __ Mov(x[3], literal_base * 3);
13412 __ Mov(x[2], literal_base * 2);
13413 __ Mov(x[1], literal_base * 1);
13414 __ Mov(x[0], literal_base * 0);
13415
13416 __ PushSizeRegList(r0_to_r3, reg_size);
13417 __ Push(r[3], r[2]);
13418
13419 Clobber(&masm, r0_to_r3);
13420 __ PopSizeRegList(r0_to_r3, reg_size);
13421
13422 __ Push(r[2], r[1], r[3], r[0]);
13423
13424 Clobber(&masm, r4_to_r5);
13425 __ Pop(r[4], r[5]);
13426 Clobber(&masm, r6_to_r9);
13427 __ Pop(r[6], r[7], r[8], r[9]);
13428
13429 // Drop memory to restore stack_pointer.
13430 __ Drop(claim);
13431
13432 __ Mov(sp, __ StackPointer());
13433 __ SetStackPointer(sp);
13434 }
13435
13436 END();
13437
13438 RUN();
13439
13440 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
13441 // that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +000013442 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +010013443
13444 ASSERT_EQUAL_64(literal_base * 3, x[9]);
13445 ASSERT_EQUAL_64(literal_base * 2, x[8]);
13446 ASSERT_EQUAL_64(literal_base * 0, x[7]);
13447 ASSERT_EQUAL_64(literal_base * 3, x[6]);
13448 ASSERT_EQUAL_64(literal_base * 1, x[5]);
13449 ASSERT_EQUAL_64(literal_base * 2, x[4]);
13450
13451 TEARDOWN();
13452}
13453
13454
13455TEST(push_pop_xreg_mixed_methods_64) {
13456 for (int claim = 0; claim <= 8; claim++) {
13457 PushPopXRegMixedMethodsHelper(claim, kXRegSize);
13458 }
13459}
13460
13461
13462TEST(push_pop_xreg_mixed_methods_32) {
13463 for (int claim = 0; claim <= 8; claim++) {
13464 PushPopXRegMixedMethodsHelper(claim, kWRegSize);
13465 }
13466}
13467
13468
13469// Push and pop data using overlapping X- and W-sized quantities.
13470static void PushPopXRegWXOverlapHelper(int reg_count, int claim) {
13471 SETUP();
13472
13473 // Arbitrarily pick a register to use as a stack pointer.
13474 const Register& stack_pointer = x10;
13475 const RegList allowed = ~stack_pointer.Bit();
13476 if (reg_count == kPushPopXRegMaxRegCount) {
13477 reg_count = CountSetBits(allowed, kNumberOfRegisters);
13478 }
13479 // Work out which registers to use, based on reg_size.
13480 Register w[kNumberOfRegisters];
13481 Register x[kNumberOfRegisters];
13482 RegList list = PopulateRegisterArray(w, x, NULL, 0, reg_count, allowed);
13483
13484 // The number of W-sized slots we expect to pop. When we pop, we alternate
13485 // between W and X registers, so we need reg_count*1.5 W-sized slots.
13486 int const requested_w_slots = reg_count + reg_count / 2;
13487
13488 // Track what _should_ be on the stack, using W-sized slots.
13489 static int const kMaxWSlots = kNumberOfRegisters + kNumberOfRegisters / 2;
13490 uint32_t stack[kMaxWSlots];
13491 for (int i = 0; i < kMaxWSlots; i++) {
13492 stack[i] = 0xdeadbeef;
13493 }
13494
armvixl6e2c8272015-03-31 11:04:14 +010013495 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13496 UseScratchRegisterScope temps(&masm);
13497 temps.ExcludeAll();
13498
armvixlad96eda2013-06-14 11:42:37 +010013499 // The literal base is chosen to have two useful properties:
13500 // * When multiplied by small values (such as a register index), this value
13501 // is clearly readable in the result.
13502 // * The value is not formed from repeating fixed-size smaller values, so it
13503 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000013504 static uint64_t const literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013505 static uint64_t const literal_base_hi = literal_base >> 32;
13506 static uint64_t const literal_base_lo = literal_base & 0xffffffff;
13507 static uint64_t const literal_base_w = literal_base & 0xffffffff;
13508
13509 START();
13510 {
armvixlb0c8ae22014-03-21 14:03:59 +000013511 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013512 __ Mov(stack_pointer, __ StackPointer());
13513 __ SetStackPointer(stack_pointer);
13514
13515 // Initialize the registers.
13516 for (int i = 0; i < reg_count; i++) {
13517 // Always write into the X register, to ensure that the upper word is
13518 // properly ignored by Push when testing W registers.
13519 __ Mov(x[i], literal_base * i);
13520 }
13521
13522 // Claim memory first, as requested.
13523 __ Claim(claim);
13524
13525 // The push-pop pattern is as follows:
13526 // Push: Pop:
13527 // x[0](hi) -> w[0]
13528 // x[0](lo) -> x[1](hi)
13529 // w[1] -> x[1](lo)
13530 // w[1] -> w[2]
13531 // x[2](hi) -> x[2](hi)
13532 // x[2](lo) -> x[2](lo)
13533 // x[2](hi) -> w[3]
13534 // x[2](lo) -> x[4](hi)
13535 // x[2](hi) -> x[4](lo)
13536 // x[2](lo) -> w[5]
13537 // w[3] -> x[5](hi)
13538 // w[3] -> x[6](lo)
13539 // w[3] -> w[7]
13540 // w[3] -> x[8](hi)
13541 // x[4](hi) -> x[8](lo)
13542 // x[4](lo) -> w[9]
13543 // ... pattern continues ...
13544 //
13545 // That is, registers are pushed starting with the lower numbers,
13546 // alternating between x and w registers, and pushing i%4+1 copies of each,
13547 // where i is the register number.
13548 // Registers are popped starting with the higher numbers one-by-one,
13549 // alternating between x and w registers, but only popping one at a time.
13550 //
13551 // This pattern provides a wide variety of alignment effects and overlaps.
13552
13553 // ---- Push ----
13554
13555 int active_w_slots = 0;
13556 for (int i = 0; active_w_slots < requested_w_slots; i++) {
armvixlb0c8ae22014-03-21 14:03:59 +000013557 VIXL_ASSERT(i < reg_count);
armvixlad96eda2013-06-14 11:42:37 +010013558 // In order to test various arguments to PushMultipleTimes, and to try to
13559 // exercise different alignment and overlap effects, we push each
13560 // register a different number of times.
13561 int times = i % 4 + 1;
13562 if (i & 1) {
13563 // Push odd-numbered registers as W registers.
13564 __ PushMultipleTimes(times, w[i]);
13565 // Fill in the expected stack slots.
13566 for (int j = 0; j < times; j++) {
13567 if (w[i].Is(wzr)) {
13568 // The zero register always writes zeroes.
13569 stack[active_w_slots++] = 0;
13570 } else {
13571 stack[active_w_slots++] = literal_base_w * i;
13572 }
13573 }
13574 } else {
13575 // Push even-numbered registers as X registers.
13576 __ PushMultipleTimes(times, x[i]);
13577 // Fill in the expected stack slots.
13578 for (int j = 0; j < times; j++) {
13579 if (x[i].Is(xzr)) {
13580 // The zero register always writes zeroes.
13581 stack[active_w_slots++] = 0;
13582 stack[active_w_slots++] = 0;
13583 } else {
13584 stack[active_w_slots++] = literal_base_hi * i;
13585 stack[active_w_slots++] = literal_base_lo * i;
13586 }
13587 }
13588 }
13589 }
13590 // Because we were pushing several registers at a time, we probably pushed
13591 // more than we needed to.
13592 if (active_w_slots > requested_w_slots) {
13593 __ Drop((active_w_slots - requested_w_slots) * kWRegSizeInBytes);
13594 // Bump the number of active W-sized slots back to where it should be,
13595 // and fill the empty space with a dummy value.
13596 do {
13597 stack[active_w_slots--] = 0xdeadbeef;
13598 } while (active_w_slots > requested_w_slots);
13599 }
13600
13601 // ---- Pop ----
13602
13603 Clobber(&masm, list);
13604
13605 // If popping an even number of registers, the first one will be X-sized.
13606 // Otherwise, the first one will be W-sized.
13607 bool next_is_64 = !(reg_count & 1);
13608 for (int i = reg_count-1; i >= 0; i--) {
13609 if (next_is_64) {
13610 __ Pop(x[i]);
13611 active_w_slots -= 2;
13612 } else {
13613 __ Pop(w[i]);
13614 active_w_slots -= 1;
13615 }
13616 next_is_64 = !next_is_64;
13617 }
armvixlb0c8ae22014-03-21 14:03:59 +000013618 VIXL_ASSERT(active_w_slots == 0);
armvixlad96eda2013-06-14 11:42:37 +010013619
13620 // Drop memory to restore stack_pointer.
13621 __ Drop(claim);
13622
13623 __ Mov(sp, __ StackPointer());
13624 __ SetStackPointer(sp);
13625 }
13626
13627 END();
13628
13629 RUN();
13630
13631 int slot = 0;
13632 for (int i = 0; i < reg_count; i++) {
13633 // Even-numbered registers were written as W registers.
13634 // Odd-numbered registers were written as X registers.
13635 bool expect_64 = (i & 1);
13636 uint64_t expected;
13637
13638 if (expect_64) {
13639 uint64_t hi = stack[slot++];
13640 uint64_t lo = stack[slot++];
13641 expected = (hi << 32) | lo;
13642 } else {
13643 expected = stack[slot++];
13644 }
13645
13646 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can
13647 // test that the upper word was properly cleared by Pop.
13648 if (x[i].Is(xzr)) {
13649 ASSERT_EQUAL_64(0, x[i]);
13650 } else {
13651 ASSERT_EQUAL_64(expected, x[i]);
13652 }
13653 }
armvixlb0c8ae22014-03-21 14:03:59 +000013654 VIXL_ASSERT(slot == requested_w_slots);
armvixlad96eda2013-06-14 11:42:37 +010013655
13656 TEARDOWN();
13657}
13658
13659
13660TEST(push_pop_xreg_wx_overlap) {
13661 for (int claim = 0; claim <= 8; claim++) {
13662 for (int count = 1; count <= 8; count++) {
13663 PushPopXRegWXOverlapHelper(count, claim);
13664 }
13665 // Test with the maximum number of registers.
13666 PushPopXRegWXOverlapHelper(kPushPopXRegMaxRegCount, claim);
13667 }
13668}
13669
13670
13671TEST(push_pop_sp) {
13672 SETUP();
13673
13674 START();
13675
armvixlb0c8ae22014-03-21 14:03:59 +000013676 VIXL_ASSERT(sp.Is(__ StackPointer()));
armvixlad96eda2013-06-14 11:42:37 +010013677
armvixl6e2c8272015-03-31 11:04:14 +010013678 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13679 UseScratchRegisterScope temps(&masm);
13680 temps.ExcludeAll();
13681
armvixlb0c8ae22014-03-21 14:03:59 +000013682 __ Mov(x3, 0x3333333333333333);
13683 __ Mov(x2, 0x2222222222222222);
13684 __ Mov(x1, 0x1111111111111111);
13685 __ Mov(x0, 0x0000000000000000);
armvixlad96eda2013-06-14 11:42:37 +010013686 __ Claim(2 * kXRegSizeInBytes);
13687 __ PushXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
13688 __ Push(x3, x2);
13689 __ PopXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
13690 __ Push(x2, x1, x3, x0);
13691 __ Pop(x4, x5);
13692 __ Pop(x6, x7, x8, x9);
13693
13694 __ Claim(2 * kXRegSizeInBytes);
13695 __ PushWRegList(w0.Bit() | w1.Bit() | w2.Bit() | w3.Bit());
13696 __ Push(w3, w1, w2, w0);
13697 __ PopWRegList(w10.Bit() | w11.Bit() | w12.Bit() | w13.Bit());
13698 __ Pop(w14, w15, w16, w17);
13699
13700 __ Claim(2 * kXRegSizeInBytes);
13701 __ Push(w2, w2, w1, w1);
13702 __ Push(x3, x3);
13703 __ Pop(w18, w19, w20, w21);
13704 __ Pop(x22, x23);
13705
13706 __ Claim(2 * kXRegSizeInBytes);
13707 __ PushXRegList(x1.Bit() | x22.Bit());
13708 __ PopXRegList(x24.Bit() | x26.Bit());
13709
13710 __ Claim(2 * kXRegSizeInBytes);
13711 __ PushWRegList(w1.Bit() | w2.Bit() | w4.Bit() | w22.Bit());
13712 __ PopWRegList(w25.Bit() | w27.Bit() | w28.Bit() | w29.Bit());
13713
13714 __ Claim(2 * kXRegSizeInBytes);
13715 __ PushXRegList(0);
13716 __ PopXRegList(0);
13717 __ PushXRegList(0xffffffff);
13718 __ PopXRegList(0xffffffff);
13719 __ Drop(12 * kXRegSizeInBytes);
13720 END();
13721
13722 RUN();
13723
armvixlb0c8ae22014-03-21 14:03:59 +000013724 ASSERT_EQUAL_64(0x1111111111111111, x3);
13725 ASSERT_EQUAL_64(0x0000000000000000, x2);
13726 ASSERT_EQUAL_64(0x3333333333333333, x1);
13727 ASSERT_EQUAL_64(0x2222222222222222, x0);
13728 ASSERT_EQUAL_64(0x3333333333333333, x9);
13729 ASSERT_EQUAL_64(0x2222222222222222, x8);
13730 ASSERT_EQUAL_64(0x0000000000000000, x7);
13731 ASSERT_EQUAL_64(0x3333333333333333, x6);
13732 ASSERT_EQUAL_64(0x1111111111111111, x5);
13733 ASSERT_EQUAL_64(0x2222222222222222, x4);
armvixlad96eda2013-06-14 11:42:37 +010013734
13735 ASSERT_EQUAL_32(0x11111111U, w13);
13736 ASSERT_EQUAL_32(0x33333333U, w12);
13737 ASSERT_EQUAL_32(0x00000000U, w11);
13738 ASSERT_EQUAL_32(0x22222222U, w10);
13739 ASSERT_EQUAL_32(0x11111111U, w17);
13740 ASSERT_EQUAL_32(0x00000000U, w16);
13741 ASSERT_EQUAL_32(0x33333333U, w15);
13742 ASSERT_EQUAL_32(0x22222222U, w14);
13743
13744 ASSERT_EQUAL_32(0x11111111U, w18);
13745 ASSERT_EQUAL_32(0x11111111U, w19);
13746 ASSERT_EQUAL_32(0x11111111U, w20);
13747 ASSERT_EQUAL_32(0x11111111U, w21);
armvixlb0c8ae22014-03-21 14:03:59 +000013748 ASSERT_EQUAL_64(0x3333333333333333, x22);
13749 ASSERT_EQUAL_64(0x0000000000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010013750
armvixlb0c8ae22014-03-21 14:03:59 +000013751 ASSERT_EQUAL_64(0x3333333333333333, x24);
13752 ASSERT_EQUAL_64(0x3333333333333333, x26);
armvixlad96eda2013-06-14 11:42:37 +010013753
13754 ASSERT_EQUAL_32(0x33333333U, w25);
13755 ASSERT_EQUAL_32(0x00000000U, w27);
13756 ASSERT_EQUAL_32(0x22222222U, w28);
13757 ASSERT_EQUAL_32(0x33333333U, w29);
13758 TEARDOWN();
13759}
13760
13761
13762TEST(noreg) {
13763 // This test doesn't generate any code, but it verifies some invariants
13764 // related to NoReg.
armvixlb0c8ae22014-03-21 14:03:59 +000013765 VIXL_CHECK(NoReg.Is(NoFPReg));
13766 VIXL_CHECK(NoFPReg.Is(NoReg));
armvixl5289c592015-03-02 13:52:04 +000013767
13768 VIXL_CHECK(NoVReg.Is(NoReg));
13769 VIXL_CHECK(NoReg.Is(NoVReg));
13770
armvixlb0c8ae22014-03-21 14:03:59 +000013771 VIXL_CHECK(NoReg.Is(NoCPUReg));
13772 VIXL_CHECK(NoCPUReg.Is(NoReg));
armvixl5289c592015-03-02 13:52:04 +000013773
armvixlb0c8ae22014-03-21 14:03:59 +000013774 VIXL_CHECK(NoFPReg.Is(NoCPUReg));
13775 VIXL_CHECK(NoCPUReg.Is(NoFPReg));
armvixlad96eda2013-06-14 11:42:37 +010013776
armvixl5289c592015-03-02 13:52:04 +000013777 VIXL_CHECK(NoVReg.Is(NoCPUReg));
13778 VIXL_CHECK(NoCPUReg.Is(NoVReg));
13779
armvixlb0c8ae22014-03-21 14:03:59 +000013780 VIXL_CHECK(NoReg.IsNone());
13781 VIXL_CHECK(NoFPReg.IsNone());
armvixl5289c592015-03-02 13:52:04 +000013782 VIXL_CHECK(NoVReg.IsNone());
armvixlb0c8ae22014-03-21 14:03:59 +000013783 VIXL_CHECK(NoCPUReg.IsNone());
armvixlad96eda2013-06-14 11:42:37 +010013784}
13785
13786
13787TEST(isvalid) {
13788 // This test doesn't generate any code, but it verifies some invariants
13789 // related to IsValid().
armvixlb0c8ae22014-03-21 14:03:59 +000013790 VIXL_CHECK(!NoReg.IsValid());
13791 VIXL_CHECK(!NoFPReg.IsValid());
armvixl5289c592015-03-02 13:52:04 +000013792 VIXL_CHECK(!NoVReg.IsValid());
armvixlb0c8ae22014-03-21 14:03:59 +000013793 VIXL_CHECK(!NoCPUReg.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013794
armvixlb0c8ae22014-03-21 14:03:59 +000013795 VIXL_CHECK(x0.IsValid());
13796 VIXL_CHECK(w0.IsValid());
13797 VIXL_CHECK(x30.IsValid());
13798 VIXL_CHECK(w30.IsValid());
13799 VIXL_CHECK(xzr.IsValid());
13800 VIXL_CHECK(wzr.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013801
armvixlb0c8ae22014-03-21 14:03:59 +000013802 VIXL_CHECK(sp.IsValid());
13803 VIXL_CHECK(wsp.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013804
armvixlb0c8ae22014-03-21 14:03:59 +000013805 VIXL_CHECK(d0.IsValid());
13806 VIXL_CHECK(s0.IsValid());
13807 VIXL_CHECK(d31.IsValid());
13808 VIXL_CHECK(s31.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013809
armvixlb0c8ae22014-03-21 14:03:59 +000013810 VIXL_CHECK(x0.IsValidRegister());
13811 VIXL_CHECK(w0.IsValidRegister());
13812 VIXL_CHECK(xzr.IsValidRegister());
13813 VIXL_CHECK(wzr.IsValidRegister());
13814 VIXL_CHECK(sp.IsValidRegister());
13815 VIXL_CHECK(wsp.IsValidRegister());
13816 VIXL_CHECK(!x0.IsValidFPRegister());
13817 VIXL_CHECK(!w0.IsValidFPRegister());
13818 VIXL_CHECK(!xzr.IsValidFPRegister());
13819 VIXL_CHECK(!wzr.IsValidFPRegister());
13820 VIXL_CHECK(!sp.IsValidFPRegister());
13821 VIXL_CHECK(!wsp.IsValidFPRegister());
armvixlad96eda2013-06-14 11:42:37 +010013822
armvixlb0c8ae22014-03-21 14:03:59 +000013823 VIXL_CHECK(d0.IsValidFPRegister());
13824 VIXL_CHECK(s0.IsValidFPRegister());
13825 VIXL_CHECK(!d0.IsValidRegister());
13826 VIXL_CHECK(!s0.IsValidRegister());
armvixlad96eda2013-06-14 11:42:37 +010013827
13828 // Test the same as before, but using CPURegister types. This shouldn't make
13829 // any difference.
armvixlb0c8ae22014-03-21 14:03:59 +000013830 VIXL_CHECK(static_cast<CPURegister>(x0).IsValid());
13831 VIXL_CHECK(static_cast<CPURegister>(w0).IsValid());
13832 VIXL_CHECK(static_cast<CPURegister>(x30).IsValid());
13833 VIXL_CHECK(static_cast<CPURegister>(w30).IsValid());
13834 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValid());
13835 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013836
armvixlb0c8ae22014-03-21 14:03:59 +000013837 VIXL_CHECK(static_cast<CPURegister>(sp).IsValid());
13838 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013839
armvixlb0c8ae22014-03-21 14:03:59 +000013840 VIXL_CHECK(static_cast<CPURegister>(d0).IsValid());
13841 VIXL_CHECK(static_cast<CPURegister>(s0).IsValid());
13842 VIXL_CHECK(static_cast<CPURegister>(d31).IsValid());
13843 VIXL_CHECK(static_cast<CPURegister>(s31).IsValid());
armvixlad96eda2013-06-14 11:42:37 +010013844
armvixlb0c8ae22014-03-21 14:03:59 +000013845 VIXL_CHECK(static_cast<CPURegister>(x0).IsValidRegister());
13846 VIXL_CHECK(static_cast<CPURegister>(w0).IsValidRegister());
13847 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValidRegister());
13848 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValidRegister());
13849 VIXL_CHECK(static_cast<CPURegister>(sp).IsValidRegister());
13850 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValidRegister());
13851 VIXL_CHECK(!static_cast<CPURegister>(x0).IsValidFPRegister());
13852 VIXL_CHECK(!static_cast<CPURegister>(w0).IsValidFPRegister());
13853 VIXL_CHECK(!static_cast<CPURegister>(xzr).IsValidFPRegister());
13854 VIXL_CHECK(!static_cast<CPURegister>(wzr).IsValidFPRegister());
13855 VIXL_CHECK(!static_cast<CPURegister>(sp).IsValidFPRegister());
13856 VIXL_CHECK(!static_cast<CPURegister>(wsp).IsValidFPRegister());
armvixlad96eda2013-06-14 11:42:37 +010013857
armvixlb0c8ae22014-03-21 14:03:59 +000013858 VIXL_CHECK(static_cast<CPURegister>(d0).IsValidFPRegister());
13859 VIXL_CHECK(static_cast<CPURegister>(s0).IsValidFPRegister());
13860 VIXL_CHECK(!static_cast<CPURegister>(d0).IsValidRegister());
13861 VIXL_CHECK(!static_cast<CPURegister>(s0).IsValidRegister());
armvixlad96eda2013-06-14 11:42:37 +010013862}
13863
13864
13865TEST(printf) {
armvixlc68cb642014-09-25 18:49:30 +010013866 SETUP();
armvixlad96eda2013-06-14 11:42:37 +010013867 START();
13868
13869 char const * test_plain_string = "Printf with no arguments.\n";
13870 char const * test_substring = "'This is a substring.'";
13871 RegisterDump before;
13872
13873 // Initialize x29 to the value of the stack pointer. We will use x29 as a
13874 // temporary stack pointer later, and initializing it in this way allows the
13875 // RegisterDump check to pass.
13876 __ Mov(x29, __ StackPointer());
13877
13878 // Test simple integer arguments.
13879 __ Mov(x0, 1234);
13880 __ Mov(x1, 0x1234);
13881
13882 // Test simple floating-point arguments.
13883 __ Fmov(d0, 1.234);
13884
13885 // Test pointer (string) arguments.
13886 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
13887
13888 // Test the maximum number of arguments, and sign extension.
13889 __ Mov(w3, 0xffffffff);
13890 __ Mov(w4, 0xffffffff);
13891 __ Mov(x5, 0xffffffffffffffff);
13892 __ Mov(x6, 0xffffffffffffffff);
13893 __ Fmov(s1, 1.234);
13894 __ Fmov(s2, 2.345);
13895 __ Fmov(d3, 3.456);
13896 __ Fmov(d4, 4.567);
13897
13898 // Test printing callee-saved registers.
13899 __ Mov(x28, 0x123456789abcdef);
13900 __ Fmov(d10, 42.0);
13901
13902 // Test with three arguments.
13903 __ Mov(x10, 3);
13904 __ Mov(x11, 40);
13905 __ Mov(x12, 500);
13906
armvixl5799d6c2014-05-01 11:05:00 +010013907 // A single character.
13908 __ Mov(w13, 'x');
13909
13910 // Check that we don't clobber any registers.
armvixlad96eda2013-06-14 11:42:37 +010013911 before.Dump(&masm);
13912
13913 __ Printf(test_plain_string); // NOLINT(runtime/printf)
armvixl5799d6c2014-05-01 11:05:00 +010013914 __ Printf("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1);
13915 __ Printf("w5: %" PRId32 ", x5: %" PRId64"\n", w5, x5);
armvixlad96eda2013-06-14 11:42:37 +010013916 __ Printf("d0: %f\n", d0);
13917 __ Printf("Test %%s: %s\n", x2);
13918 __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
13919 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
13920 w3, w4, x5, x6);
13921 __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
armvixl5799d6c2014-05-01 11:05:00 +010013922 __ Printf("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
armvixlad96eda2013-06-14 11:42:37 +010013923 __ Printf("%g\n", d10);
armvixl5799d6c2014-05-01 11:05:00 +010013924 __ Printf("%%%%%s%%%c%%\n", x2, w13);
13925
13926 // Print the stack pointer (sp).
13927 __ Printf("StackPointer(sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
13928 __ StackPointer(), __ StackPointer().W());
armvixlad96eda2013-06-14 11:42:37 +010013929
13930 // Test with a different stack pointer.
13931 const Register old_stack_pointer = __ StackPointer();
armvixl5799d6c2014-05-01 11:05:00 +010013932 __ Mov(x29, old_stack_pointer);
armvixlad96eda2013-06-14 11:42:37 +010013933 __ SetStackPointer(x29);
armvixl5799d6c2014-05-01 11:05:00 +010013934 // Print the stack pointer (not sp).
13935 __ Printf("StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
13936 __ StackPointer(), __ StackPointer().W());
13937 __ Mov(old_stack_pointer, __ StackPointer());
armvixlad96eda2013-06-14 11:42:37 +010013938 __ SetStackPointer(old_stack_pointer);
13939
armvixl5799d6c2014-05-01 11:05:00 +010013940 // Test with three arguments.
armvixlad96eda2013-06-14 11:42:37 +010013941 __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12);
13942
armvixl5799d6c2014-05-01 11:05:00 +010013943 // Mixed argument types.
13944 __ Printf("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
13945 w3, s1, x5, d3);
13946 __ Printf("s1: %f, d3: %f, w3: %" PRId32 ", x5: %" PRId64 "\n",
13947 s1, d3, w3, x5);
13948
armvixlad96eda2013-06-14 11:42:37 +010013949 END();
13950 RUN();
13951
13952 // We cannot easily test the output of the Printf sequences, and because
13953 // Printf preserves all registers by default, we can't look at the number of
13954 // bytes that were printed. However, the printf_no_preserve test should check
13955 // that, and here we just test that we didn't clobber any registers.
13956 ASSERT_EQUAL_REGISTERS(before);
13957
13958 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +010013959}
13960
13961
13962TEST(printf_no_preserve) {
armvixlad96eda2013-06-14 11:42:37 +010013963 SETUP();
13964 START();
13965
13966 char const * test_plain_string = "Printf with no arguments.\n";
13967 char const * test_substring = "'This is a substring.'";
13968
13969 __ PrintfNoPreserve(test_plain_string);
13970 __ Mov(x19, x0);
13971
13972 // Test simple integer arguments.
13973 __ Mov(x0, 1234);
13974 __ Mov(x1, 0x1234);
13975 __ PrintfNoPreserve("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1);
13976 __ Mov(x20, x0);
13977
13978 // Test simple floating-point arguments.
13979 __ Fmov(d0, 1.234);
13980 __ PrintfNoPreserve("d0: %f\n", d0);
13981 __ Mov(x21, x0);
13982
13983 // Test pointer (string) arguments.
13984 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
13985 __ PrintfNoPreserve("Test %%s: %s\n", x2);
13986 __ Mov(x22, x0);
13987
13988 // Test the maximum number of arguments, and sign extension.
13989 __ Mov(w3, 0xffffffff);
13990 __ Mov(w4, 0xffffffff);
13991 __ Mov(x5, 0xffffffffffffffff);
13992 __ Mov(x6, 0xffffffffffffffff);
13993 __ PrintfNoPreserve("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
13994 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
13995 w3, w4, x5, x6);
13996 __ Mov(x23, x0);
13997
13998 __ Fmov(s1, 1.234);
13999 __ Fmov(s2, 2.345);
14000 __ Fmov(d3, 3.456);
14001 __ Fmov(d4, 4.567);
14002 __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
14003 __ Mov(x24, x0);
14004
14005 // Test printing callee-saved registers.
14006 __ Mov(x28, 0x123456789abcdef);
armvixl5799d6c2014-05-01 11:05:00 +010014007 __ PrintfNoPreserve("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
armvixlad96eda2013-06-14 11:42:37 +010014008 __ Mov(x25, x0);
14009
14010 __ Fmov(d10, 42.0);
14011 __ PrintfNoPreserve("%g\n", d10);
14012 __ Mov(x26, x0);
14013
14014 // Test with a different stack pointer.
14015 const Register old_stack_pointer = __ StackPointer();
14016 __ Mov(x29, old_stack_pointer);
14017 __ SetStackPointer(x29);
armvixl5799d6c2014-05-01 11:05:00 +010014018 // Print the stack pointer (not sp).
14019 __ PrintfNoPreserve(
14020 "StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
14021 __ StackPointer(), __ StackPointer().W());
armvixlad96eda2013-06-14 11:42:37 +010014022 __ Mov(x27, x0);
armvixlad96eda2013-06-14 11:42:37 +010014023 __ Mov(old_stack_pointer, __ StackPointer());
14024 __ SetStackPointer(old_stack_pointer);
14025
14026 // Test with three arguments.
14027 __ Mov(x3, 3);
14028 __ Mov(x4, 40);
14029 __ Mov(x5, 500);
14030 __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5);
14031 __ Mov(x28, x0);
14032
armvixl5799d6c2014-05-01 11:05:00 +010014033 // Mixed argument types.
14034 __ Mov(w3, 0xffffffff);
14035 __ Fmov(s1, 1.234);
14036 __ Mov(x5, 0xffffffffffffffff);
14037 __ Fmov(d3, 3.456);
14038 __ PrintfNoPreserve("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
14039 w3, s1, x5, d3);
14040 __ Mov(x29, x0);
14041
armvixlad96eda2013-06-14 11:42:37 +010014042 END();
14043 RUN();
14044
14045 // We cannot easily test the exact output of the Printf sequences, but we can
14046 // use the return code to check that the string length was correct.
14047
14048 // Printf with no arguments.
14049 ASSERT_EQUAL_64(strlen(test_plain_string), x19);
14050 // x0: 1234, x1: 0x00001234
14051 ASSERT_EQUAL_64(25, x20);
14052 // d0: 1.234000
14053 ASSERT_EQUAL_64(13, x21);
14054 // Test %s: 'This is a substring.'
14055 ASSERT_EQUAL_64(32, x22);
14056 // w3(uint32): 4294967295
14057 // w4(int32): -1
14058 // x5(uint64): 18446744073709551615
14059 // x6(int64): -1
14060 ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23);
14061 // %f: 1.234000
14062 // %g: 2.345
14063 // %e: 3.456000e+00
14064 // %E: 4.567000E+00
14065 ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24);
armvixl5799d6c2014-05-01 11:05:00 +010014066 // 0x89abcdef, 0x123456789abcdef
14067 ASSERT_EQUAL_64(30, x25);
armvixlad96eda2013-06-14 11:42:37 +010014068 // 42
14069 ASSERT_EQUAL_64(3, x26);
armvixl5799d6c2014-05-01 11:05:00 +010014070 // StackPointer(not sp): 0x00007fb037ae2370, 0x37ae2370
armvixlad96eda2013-06-14 11:42:37 +010014071 // Note: This is an example value, but the field width is fixed here so the
14072 // string length is still predictable.
armvixl5799d6c2014-05-01 11:05:00 +010014073 ASSERT_EQUAL_64(53, x27);
armvixlad96eda2013-06-14 11:42:37 +010014074 // 3=3, 4=40, 5=500
14075 ASSERT_EQUAL_64(17, x28);
armvixl5799d6c2014-05-01 11:05:00 +010014076 // w3: 4294967295, s1: 1.234000, x5: 18446744073709551615, d3: 3.456000
14077 ASSERT_EQUAL_64(69, x29);
armvixlad96eda2013-06-14 11:42:37 +010014078
14079 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +010014080}
14081
14082
14083#ifndef USE_SIMULATOR
14084TEST(trace) {
14085 // The Trace helper should not generate any code unless the simulator (or
14086 // debugger) is being used.
14087 SETUP();
14088 START();
14089
14090 Label start;
14091 __ Bind(&start);
14092 __ Trace(LOG_ALL, TRACE_ENABLE);
14093 __ Trace(LOG_ALL, TRACE_DISABLE);
armvixlb0c8ae22014-03-21 14:03:59 +000014094 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlad96eda2013-06-14 11:42:37 +010014095
14096 END();
14097 TEARDOWN();
14098}
14099#endif
14100
14101
14102#ifndef USE_SIMULATOR
14103TEST(log) {
14104 // The Log helper should not generate any code unless the simulator (or
14105 // debugger) is being used.
14106 SETUP();
14107 START();
14108
14109 Label start;
14110 __ Bind(&start);
14111 __ Log(LOG_ALL);
armvixlb0c8ae22014-03-21 14:03:59 +000014112 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlad96eda2013-06-14 11:42:37 +010014113
14114 END();
14115 TEARDOWN();
14116}
14117#endif
14118
14119
14120TEST(instruction_accurate_scope) {
14121 SETUP();
14122 START();
14123
14124 // By default macro instructions are allowed.
armvixlb0c8ae22014-03-21 14:03:59 +000014125 VIXL_ASSERT(masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +010014126 {
armvixlc68cb642014-09-25 18:49:30 +010014127 InstructionAccurateScope scope1(&masm, 2);
armvixlb0c8ae22014-03-21 14:03:59 +000014128 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlc68cb642014-09-25 18:49:30 +010014129 __ nop();
armvixlad96eda2013-06-14 11:42:37 +010014130 {
armvixlc68cb642014-09-25 18:49:30 +010014131 InstructionAccurateScope scope2(&masm, 1);
armvixlb0c8ae22014-03-21 14:03:59 +000014132 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlc68cb642014-09-25 18:49:30 +010014133 __ nop();
armvixlad96eda2013-06-14 11:42:37 +010014134 }
armvixlb0c8ae22014-03-21 14:03:59 +000014135 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +010014136 }
armvixlb0c8ae22014-03-21 14:03:59 +000014137 VIXL_ASSERT(masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +010014138
14139 {
14140 InstructionAccurateScope scope(&masm, 2);
14141 __ add(x0, x0, x0);
14142 __ sub(x0, x0, x0);
14143 }
14144
14145 END();
14146 RUN();
14147 TEARDOWN();
14148}
14149
14150
14151TEST(blr_lr) {
14152 // A simple test to check that the simulator correcty handle "blr lr".
14153 SETUP();
14154
14155 START();
14156 Label target;
14157 Label end;
14158
14159 __ Mov(x0, 0x0);
14160 __ Adr(lr, &target);
14161
14162 __ Blr(lr);
14163 __ Mov(x0, 0xdeadbeef);
14164 __ B(&end);
14165
14166 __ Bind(&target);
14167 __ Mov(x0, 0xc001c0de);
14168
14169 __ Bind(&end);
14170 END();
14171
14172 RUN();
14173
14174 ASSERT_EQUAL_64(0xc001c0de, x0);
14175
14176 TEARDOWN();
14177}
14178
armvixlf37fdc02014-02-05 13:22:16 +000014179
14180TEST(barriers) {
14181 // Generate all supported barriers, this is just a smoke test
14182 SETUP();
14183
14184 START();
14185
14186 // DMB
14187 __ Dmb(FullSystem, BarrierAll);
14188 __ Dmb(FullSystem, BarrierReads);
14189 __ Dmb(FullSystem, BarrierWrites);
14190 __ Dmb(FullSystem, BarrierOther);
14191
14192 __ Dmb(InnerShareable, BarrierAll);
14193 __ Dmb(InnerShareable, BarrierReads);
14194 __ Dmb(InnerShareable, BarrierWrites);
14195 __ Dmb(InnerShareable, BarrierOther);
14196
14197 __ Dmb(NonShareable, BarrierAll);
14198 __ Dmb(NonShareable, BarrierReads);
14199 __ Dmb(NonShareable, BarrierWrites);
14200 __ Dmb(NonShareable, BarrierOther);
14201
14202 __ Dmb(OuterShareable, BarrierAll);
14203 __ Dmb(OuterShareable, BarrierReads);
14204 __ Dmb(OuterShareable, BarrierWrites);
14205 __ Dmb(OuterShareable, BarrierOther);
14206
14207 // DSB
14208 __ Dsb(FullSystem, BarrierAll);
14209 __ Dsb(FullSystem, BarrierReads);
14210 __ Dsb(FullSystem, BarrierWrites);
14211 __ Dsb(FullSystem, BarrierOther);
14212
14213 __ Dsb(InnerShareable, BarrierAll);
14214 __ Dsb(InnerShareable, BarrierReads);
14215 __ Dsb(InnerShareable, BarrierWrites);
14216 __ Dsb(InnerShareable, BarrierOther);
14217
14218 __ Dsb(NonShareable, BarrierAll);
14219 __ Dsb(NonShareable, BarrierReads);
14220 __ Dsb(NonShareable, BarrierWrites);
14221 __ Dsb(NonShareable, BarrierOther);
14222
14223 __ Dsb(OuterShareable, BarrierAll);
14224 __ Dsb(OuterShareable, BarrierReads);
14225 __ Dsb(OuterShareable, BarrierWrites);
14226 __ Dsb(OuterShareable, BarrierOther);
14227
14228 // ISB
14229 __ Isb();
14230
14231 END();
14232
14233 RUN();
14234
14235 TEARDOWN();
14236}
14237
armvixlb0c8ae22014-03-21 14:03:59 +000014238
14239TEST(process_nan_double) {
14240 // Make sure that NaN propagation works correctly.
14241 double sn = rawbits_to_double(0x7ff5555511111111);
14242 double qn = rawbits_to_double(0x7ffaaaaa11111111);
14243 VIXL_ASSERT(IsSignallingNaN(sn));
14244 VIXL_ASSERT(IsQuietNaN(qn));
14245
14246 // The input NaNs after passing through ProcessNaN.
14247 double sn_proc = rawbits_to_double(0x7ffd555511111111);
14248 double qn_proc = qn;
14249 VIXL_ASSERT(IsQuietNaN(sn_proc));
14250 VIXL_ASSERT(IsQuietNaN(qn_proc));
14251
14252 SETUP();
14253 START();
14254
14255 // Execute a number of instructions which all use ProcessNaN, and check that
14256 // they all handle the NaN correctly.
14257 __ Fmov(d0, sn);
14258 __ Fmov(d10, qn);
14259
14260 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14261 // - Signalling NaN
14262 __ Fmov(d1, d0);
14263 __ Fabs(d2, d0);
14264 __ Fneg(d3, d0);
14265 // - Quiet NaN
14266 __ Fmov(d11, d10);
14267 __ Fabs(d12, d10);
14268 __ Fneg(d13, d10);
14269
14270 // Operations that use ProcessNaN.
14271 // - Signalling NaN
14272 __ Fsqrt(d4, d0);
14273 __ Frinta(d5, d0);
14274 __ Frintn(d6, d0);
14275 __ Frintz(d7, d0);
14276 // - Quiet NaN
14277 __ Fsqrt(d14, d10);
14278 __ Frinta(d15, d10);
14279 __ Frintn(d16, d10);
14280 __ Frintz(d17, d10);
14281
14282 // The behaviour of fcvt is checked in TEST(fcvt_sd).
14283
14284 END();
14285 RUN();
14286
14287 uint64_t qn_raw = double_to_rawbits(qn);
14288 uint64_t sn_raw = double_to_rawbits(sn);
14289
14290 // - Signalling NaN
14291 ASSERT_EQUAL_FP64(sn, d1);
14292 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw & ~kDSignMask), d2);
14293 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw ^ kDSignMask), d3);
14294 // - Quiet NaN
14295 ASSERT_EQUAL_FP64(qn, d11);
14296 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw & ~kDSignMask), d12);
14297 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw ^ kDSignMask), d13);
14298
14299 // - Signalling NaN
14300 ASSERT_EQUAL_FP64(sn_proc, d4);
14301 ASSERT_EQUAL_FP64(sn_proc, d5);
14302 ASSERT_EQUAL_FP64(sn_proc, d6);
14303 ASSERT_EQUAL_FP64(sn_proc, d7);
14304 // - Quiet NaN
14305 ASSERT_EQUAL_FP64(qn_proc, d14);
14306 ASSERT_EQUAL_FP64(qn_proc, d15);
14307 ASSERT_EQUAL_FP64(qn_proc, d16);
14308 ASSERT_EQUAL_FP64(qn_proc, d17);
14309
14310 TEARDOWN();
14311}
14312
14313
14314TEST(process_nan_float) {
14315 // Make sure that NaN propagation works correctly.
14316 float sn = rawbits_to_float(0x7f951111);
14317 float qn = rawbits_to_float(0x7fea1111);
14318 VIXL_ASSERT(IsSignallingNaN(sn));
14319 VIXL_ASSERT(IsQuietNaN(qn));
14320
14321 // The input NaNs after passing through ProcessNaN.
14322 float sn_proc = rawbits_to_float(0x7fd51111);
14323 float qn_proc = qn;
14324 VIXL_ASSERT(IsQuietNaN(sn_proc));
14325 VIXL_ASSERT(IsQuietNaN(qn_proc));
14326
14327 SETUP();
14328 START();
14329
14330 // Execute a number of instructions which all use ProcessNaN, and check that
14331 // they all handle the NaN correctly.
14332 __ Fmov(s0, sn);
14333 __ Fmov(s10, qn);
14334
14335 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14336 // - Signalling NaN
14337 __ Fmov(s1, s0);
14338 __ Fabs(s2, s0);
14339 __ Fneg(s3, s0);
14340 // - Quiet NaN
14341 __ Fmov(s11, s10);
14342 __ Fabs(s12, s10);
14343 __ Fneg(s13, s10);
14344
14345 // Operations that use ProcessNaN.
14346 // - Signalling NaN
14347 __ Fsqrt(s4, s0);
14348 __ Frinta(s5, s0);
14349 __ Frintn(s6, s0);
14350 __ Frintz(s7, s0);
14351 // - Quiet NaN
14352 __ Fsqrt(s14, s10);
14353 __ Frinta(s15, s10);
14354 __ Frintn(s16, s10);
14355 __ Frintz(s17, s10);
14356
14357 // The behaviour of fcvt is checked in TEST(fcvt_sd).
14358
14359 END();
14360 RUN();
14361
14362 uint32_t qn_raw = float_to_rawbits(qn);
14363 uint32_t sn_raw = float_to_rawbits(sn);
14364
14365 // - Signalling NaN
14366 ASSERT_EQUAL_FP32(sn, s1);
14367 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw & ~kSSignMask), s2);
14368 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw ^ kSSignMask), s3);
14369 // - Quiet NaN
14370 ASSERT_EQUAL_FP32(qn, s11);
14371 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw & ~kSSignMask), s12);
14372 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw ^ kSSignMask), s13);
14373
14374 // - Signalling NaN
14375 ASSERT_EQUAL_FP32(sn_proc, s4);
14376 ASSERT_EQUAL_FP32(sn_proc, s5);
14377 ASSERT_EQUAL_FP32(sn_proc, s6);
14378 ASSERT_EQUAL_FP32(sn_proc, s7);
14379 // - Quiet NaN
14380 ASSERT_EQUAL_FP32(qn_proc, s14);
14381 ASSERT_EQUAL_FP32(qn_proc, s15);
14382 ASSERT_EQUAL_FP32(qn_proc, s16);
14383 ASSERT_EQUAL_FP32(qn_proc, s17);
14384
14385 TEARDOWN();
14386}
14387
14388
14389static void ProcessNaNsHelper(double n, double m, double expected) {
armvixl6e2c8272015-03-31 11:04:14 +010014390 VIXL_ASSERT(std::isnan(n) || std::isnan(m));
14391 VIXL_ASSERT(std::isnan(expected));
armvixlb0c8ae22014-03-21 14:03:59 +000014392
14393 SETUP();
14394 START();
14395
14396 // Execute a number of instructions which all use ProcessNaNs, and check that
14397 // they all propagate NaNs correctly.
14398 __ Fmov(d0, n);
14399 __ Fmov(d1, m);
14400
14401 __ Fadd(d2, d0, d1);
14402 __ Fsub(d3, d0, d1);
14403 __ Fmul(d4, d0, d1);
14404 __ Fdiv(d5, d0, d1);
14405 __ Fmax(d6, d0, d1);
14406 __ Fmin(d7, d0, d1);
14407
14408 END();
14409 RUN();
14410
14411 ASSERT_EQUAL_FP64(expected, d2);
14412 ASSERT_EQUAL_FP64(expected, d3);
14413 ASSERT_EQUAL_FP64(expected, d4);
14414 ASSERT_EQUAL_FP64(expected, d5);
14415 ASSERT_EQUAL_FP64(expected, d6);
14416 ASSERT_EQUAL_FP64(expected, d7);
14417
14418 TEARDOWN();
14419}
14420
14421
14422TEST(process_nans_double) {
14423 // Make sure that NaN propagation works correctly.
14424 double sn = rawbits_to_double(0x7ff5555511111111);
14425 double sm = rawbits_to_double(0x7ff5555522222222);
14426 double qn = rawbits_to_double(0x7ffaaaaa11111111);
14427 double qm = rawbits_to_double(0x7ffaaaaa22222222);
14428 VIXL_ASSERT(IsSignallingNaN(sn));
14429 VIXL_ASSERT(IsSignallingNaN(sm));
14430 VIXL_ASSERT(IsQuietNaN(qn));
14431 VIXL_ASSERT(IsQuietNaN(qm));
14432
14433 // The input NaNs after passing through ProcessNaN.
14434 double sn_proc = rawbits_to_double(0x7ffd555511111111);
14435 double sm_proc = rawbits_to_double(0x7ffd555522222222);
14436 double qn_proc = qn;
14437 double qm_proc = qm;
14438 VIXL_ASSERT(IsQuietNaN(sn_proc));
14439 VIXL_ASSERT(IsQuietNaN(sm_proc));
14440 VIXL_ASSERT(IsQuietNaN(qn_proc));
14441 VIXL_ASSERT(IsQuietNaN(qm_proc));
14442
14443 // Quiet NaNs are propagated.
14444 ProcessNaNsHelper(qn, 0, qn_proc);
14445 ProcessNaNsHelper(0, qm, qm_proc);
14446 ProcessNaNsHelper(qn, qm, qn_proc);
14447
14448 // Signalling NaNs are propagated, and made quiet.
14449 ProcessNaNsHelper(sn, 0, sn_proc);
14450 ProcessNaNsHelper(0, sm, sm_proc);
14451 ProcessNaNsHelper(sn, sm, sn_proc);
14452
14453 // Signalling NaNs take precedence over quiet NaNs.
14454 ProcessNaNsHelper(sn, qm, sn_proc);
14455 ProcessNaNsHelper(qn, sm, sm_proc);
14456 ProcessNaNsHelper(sn, sm, sn_proc);
14457}
14458
14459
14460static void ProcessNaNsHelper(float n, float m, float expected) {
armvixl6e2c8272015-03-31 11:04:14 +010014461 VIXL_ASSERT(std::isnan(n) || std::isnan(m));
14462 VIXL_ASSERT(std::isnan(expected));
armvixlb0c8ae22014-03-21 14:03:59 +000014463
14464 SETUP();
14465 START();
14466
14467 // Execute a number of instructions which all use ProcessNaNs, and check that
14468 // they all propagate NaNs correctly.
14469 __ Fmov(s0, n);
14470 __ Fmov(s1, m);
14471
14472 __ Fadd(s2, s0, s1);
14473 __ Fsub(s3, s0, s1);
14474 __ Fmul(s4, s0, s1);
14475 __ Fdiv(s5, s0, s1);
14476 __ Fmax(s6, s0, s1);
14477 __ Fmin(s7, s0, s1);
14478
14479 END();
14480 RUN();
14481
14482 ASSERT_EQUAL_FP32(expected, s2);
14483 ASSERT_EQUAL_FP32(expected, s3);
14484 ASSERT_EQUAL_FP32(expected, s4);
14485 ASSERT_EQUAL_FP32(expected, s5);
14486 ASSERT_EQUAL_FP32(expected, s6);
14487 ASSERT_EQUAL_FP32(expected, s7);
14488
14489 TEARDOWN();
14490}
14491
14492
14493TEST(process_nans_float) {
14494 // Make sure that NaN propagation works correctly.
14495 float sn = rawbits_to_float(0x7f951111);
14496 float sm = rawbits_to_float(0x7f952222);
14497 float qn = rawbits_to_float(0x7fea1111);
14498 float qm = rawbits_to_float(0x7fea2222);
14499 VIXL_ASSERT(IsSignallingNaN(sn));
14500 VIXL_ASSERT(IsSignallingNaN(sm));
14501 VIXL_ASSERT(IsQuietNaN(qn));
14502 VIXL_ASSERT(IsQuietNaN(qm));
14503
14504 // The input NaNs after passing through ProcessNaN.
14505 float sn_proc = rawbits_to_float(0x7fd51111);
14506 float sm_proc = rawbits_to_float(0x7fd52222);
14507 float qn_proc = qn;
14508 float qm_proc = qm;
14509 VIXL_ASSERT(IsQuietNaN(sn_proc));
14510 VIXL_ASSERT(IsQuietNaN(sm_proc));
14511 VIXL_ASSERT(IsQuietNaN(qn_proc));
14512 VIXL_ASSERT(IsQuietNaN(qm_proc));
14513
14514 // Quiet NaNs are propagated.
14515 ProcessNaNsHelper(qn, 0, qn_proc);
14516 ProcessNaNsHelper(0, qm, qm_proc);
14517 ProcessNaNsHelper(qn, qm, qn_proc);
14518
14519 // Signalling NaNs are propagated, and made quiet.
14520 ProcessNaNsHelper(sn, 0, sn_proc);
14521 ProcessNaNsHelper(0, sm, sm_proc);
14522 ProcessNaNsHelper(sn, sm, sn_proc);
14523
14524 // Signalling NaNs take precedence over quiet NaNs.
14525 ProcessNaNsHelper(sn, qm, sn_proc);
14526 ProcessNaNsHelper(qn, sm, sm_proc);
14527 ProcessNaNsHelper(sn, sm, sn_proc);
14528}
14529
14530
14531static void DefaultNaNHelper(float n, float m, float a) {
armvixl6e2c8272015-03-31 11:04:14 +010014532 VIXL_ASSERT(std::isnan(n) || std::isnan(m) || std::isnan(a));
armvixlb0c8ae22014-03-21 14:03:59 +000014533
armvixl6e2c8272015-03-31 11:04:14 +010014534 bool test_1op = std::isnan(n);
14535 bool test_2op = std::isnan(n) || std::isnan(m);
armvixlb0c8ae22014-03-21 14:03:59 +000014536
14537 SETUP();
14538 START();
14539
14540 // Enable Default-NaN mode in the FPCR.
14541 __ Mrs(x0, FPCR);
14542 __ Orr(x1, x0, DN_mask);
14543 __ Msr(FPCR, x1);
14544
14545 // Execute a number of instructions which all use ProcessNaNs, and check that
14546 // they all produce the default NaN.
14547 __ Fmov(s0, n);
14548 __ Fmov(s1, m);
14549 __ Fmov(s2, a);
14550
14551 if (test_1op) {
14552 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14553 __ Fmov(s10, s0);
14554 __ Fabs(s11, s0);
14555 __ Fneg(s12, s0);
14556
14557 // Operations that use ProcessNaN.
14558 __ Fsqrt(s13, s0);
14559 __ Frinta(s14, s0);
14560 __ Frintn(s15, s0);
14561 __ Frintz(s16, s0);
14562
14563 // Fcvt usually has special NaN handling, but it respects default-NaN mode.
14564 __ Fcvt(d17, s0);
14565 }
14566
14567 if (test_2op) {
14568 __ Fadd(s18, s0, s1);
14569 __ Fsub(s19, s0, s1);
14570 __ Fmul(s20, s0, s1);
14571 __ Fdiv(s21, s0, s1);
14572 __ Fmax(s22, s0, s1);
14573 __ Fmin(s23, s0, s1);
14574 }
14575
14576 __ Fmadd(s24, s0, s1, s2);
14577 __ Fmsub(s25, s0, s1, s2);
14578 __ Fnmadd(s26, s0, s1, s2);
14579 __ Fnmsub(s27, s0, s1, s2);
14580
14581 // Restore FPCR.
14582 __ Msr(FPCR, x0);
14583
14584 END();
14585 RUN();
14586
14587 if (test_1op) {
14588 uint32_t n_raw = float_to_rawbits(n);
14589 ASSERT_EQUAL_FP32(n, s10);
14590 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw & ~kSSignMask), s11);
14591 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw ^ kSSignMask), s12);
14592 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s13);
14593 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s14);
14594 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s15);
14595 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s16);
14596 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d17);
14597 }
14598
14599 if (test_2op) {
14600 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s18);
14601 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s19);
14602 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s20);
14603 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s21);
14604 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s22);
14605 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s23);
14606 }
14607
14608 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s24);
14609 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s25);
14610 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s26);
14611 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s27);
14612
14613 TEARDOWN();
14614}
14615
14616
14617TEST(default_nan_float) {
14618 float sn = rawbits_to_float(0x7f951111);
14619 float sm = rawbits_to_float(0x7f952222);
14620 float sa = rawbits_to_float(0x7f95aaaa);
14621 float qn = rawbits_to_float(0x7fea1111);
14622 float qm = rawbits_to_float(0x7fea2222);
14623 float qa = rawbits_to_float(0x7feaaaaa);
14624 VIXL_ASSERT(IsSignallingNaN(sn));
14625 VIXL_ASSERT(IsSignallingNaN(sm));
14626 VIXL_ASSERT(IsSignallingNaN(sa));
14627 VIXL_ASSERT(IsQuietNaN(qn));
14628 VIXL_ASSERT(IsQuietNaN(qm));
14629 VIXL_ASSERT(IsQuietNaN(qa));
14630
14631 // - Signalling NaNs
14632 DefaultNaNHelper(sn, 0.0f, 0.0f);
14633 DefaultNaNHelper(0.0f, sm, 0.0f);
14634 DefaultNaNHelper(0.0f, 0.0f, sa);
14635 DefaultNaNHelper(sn, sm, 0.0f);
14636 DefaultNaNHelper(0.0f, sm, sa);
14637 DefaultNaNHelper(sn, 0.0f, sa);
14638 DefaultNaNHelper(sn, sm, sa);
14639 // - Quiet NaNs
14640 DefaultNaNHelper(qn, 0.0f, 0.0f);
14641 DefaultNaNHelper(0.0f, qm, 0.0f);
14642 DefaultNaNHelper(0.0f, 0.0f, qa);
14643 DefaultNaNHelper(qn, qm, 0.0f);
14644 DefaultNaNHelper(0.0f, qm, qa);
14645 DefaultNaNHelper(qn, 0.0f, qa);
14646 DefaultNaNHelper(qn, qm, qa);
14647 // - Mixed NaNs
14648 DefaultNaNHelper(qn, sm, sa);
14649 DefaultNaNHelper(sn, qm, sa);
14650 DefaultNaNHelper(sn, sm, qa);
14651 DefaultNaNHelper(qn, qm, sa);
14652 DefaultNaNHelper(sn, qm, qa);
14653 DefaultNaNHelper(qn, sm, qa);
14654 DefaultNaNHelper(qn, qm, qa);
14655}
14656
14657
14658static void DefaultNaNHelper(double n, double m, double a) {
armvixl6e2c8272015-03-31 11:04:14 +010014659 VIXL_ASSERT(std::isnan(n) || std::isnan(m) || std::isnan(a));
armvixlb0c8ae22014-03-21 14:03:59 +000014660
armvixl6e2c8272015-03-31 11:04:14 +010014661 bool test_1op = std::isnan(n);
14662 bool test_2op = std::isnan(n) || std::isnan(m);
armvixlb0c8ae22014-03-21 14:03:59 +000014663
14664 SETUP();
14665 START();
14666
14667 // Enable Default-NaN mode in the FPCR.
14668 __ Mrs(x0, FPCR);
14669 __ Orr(x1, x0, DN_mask);
14670 __ Msr(FPCR, x1);
14671
14672 // Execute a number of instructions which all use ProcessNaNs, and check that
14673 // they all produce the default NaN.
14674 __ Fmov(d0, n);
14675 __ Fmov(d1, m);
14676 __ Fmov(d2, a);
14677
14678 if (test_1op) {
14679 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14680 __ Fmov(d10, d0);
14681 __ Fabs(d11, d0);
14682 __ Fneg(d12, d0);
14683
14684 // Operations that use ProcessNaN.
14685 __ Fsqrt(d13, d0);
14686 __ Frinta(d14, d0);
14687 __ Frintn(d15, d0);
14688 __ Frintz(d16, d0);
14689
14690 // Fcvt usually has special NaN handling, but it respects default-NaN mode.
14691 __ Fcvt(s17, d0);
14692 }
14693
14694 if (test_2op) {
14695 __ Fadd(d18, d0, d1);
14696 __ Fsub(d19, d0, d1);
14697 __ Fmul(d20, d0, d1);
14698 __ Fdiv(d21, d0, d1);
14699 __ Fmax(d22, d0, d1);
14700 __ Fmin(d23, d0, d1);
14701 }
14702
14703 __ Fmadd(d24, d0, d1, d2);
14704 __ Fmsub(d25, d0, d1, d2);
14705 __ Fnmadd(d26, d0, d1, d2);
14706 __ Fnmsub(d27, d0, d1, d2);
14707
14708 // Restore FPCR.
14709 __ Msr(FPCR, x0);
14710
14711 END();
14712 RUN();
14713
14714 if (test_1op) {
14715 uint64_t n_raw = double_to_rawbits(n);
14716 ASSERT_EQUAL_FP64(n, d10);
14717 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw & ~kDSignMask), d11);
14718 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw ^ kDSignMask), d12);
14719 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
14720 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d14);
14721 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d15);
14722 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d16);
14723 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s17);
14724 }
14725
14726 if (test_2op) {
14727 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d18);
14728 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d19);
14729 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d20);
14730 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d21);
14731 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d22);
14732 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d23);
14733 }
14734
14735 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d24);
14736 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d25);
14737 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d26);
14738 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d27);
14739
14740 TEARDOWN();
14741}
14742
14743
14744TEST(default_nan_double) {
14745 double sn = rawbits_to_double(0x7ff5555511111111);
14746 double sm = rawbits_to_double(0x7ff5555522222222);
14747 double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
14748 double qn = rawbits_to_double(0x7ffaaaaa11111111);
14749 double qm = rawbits_to_double(0x7ffaaaaa22222222);
14750 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
14751 VIXL_ASSERT(IsSignallingNaN(sn));
14752 VIXL_ASSERT(IsSignallingNaN(sm));
14753 VIXL_ASSERT(IsSignallingNaN(sa));
14754 VIXL_ASSERT(IsQuietNaN(qn));
14755 VIXL_ASSERT(IsQuietNaN(qm));
14756 VIXL_ASSERT(IsQuietNaN(qa));
14757
14758 // - Signalling NaNs
14759 DefaultNaNHelper(sn, 0.0, 0.0);
14760 DefaultNaNHelper(0.0, sm, 0.0);
14761 DefaultNaNHelper(0.0, 0.0, sa);
14762 DefaultNaNHelper(sn, sm, 0.0);
14763 DefaultNaNHelper(0.0, sm, sa);
14764 DefaultNaNHelper(sn, 0.0, sa);
14765 DefaultNaNHelper(sn, sm, sa);
14766 // - Quiet NaNs
14767 DefaultNaNHelper(qn, 0.0, 0.0);
14768 DefaultNaNHelper(0.0, qm, 0.0);
14769 DefaultNaNHelper(0.0, 0.0, qa);
14770 DefaultNaNHelper(qn, qm, 0.0);
14771 DefaultNaNHelper(0.0, qm, qa);
14772 DefaultNaNHelper(qn, 0.0, qa);
14773 DefaultNaNHelper(qn, qm, qa);
14774 // - Mixed NaNs
14775 DefaultNaNHelper(qn, sm, sa);
14776 DefaultNaNHelper(sn, qm, sa);
14777 DefaultNaNHelper(sn, sm, qa);
14778 DefaultNaNHelper(qn, qm, sa);
14779 DefaultNaNHelper(sn, qm, qa);
14780 DefaultNaNHelper(qn, sm, qa);
14781 DefaultNaNHelper(qn, qm, qa);
14782}
14783
14784
armvixl4a102ba2014-07-14 09:02:40 +010014785TEST(ldar_stlr) {
14786 // The middle value is read, modified, and written. The padding exists only to
14787 // check for over-write.
14788 uint8_t b[] = {0, 0x12, 0};
14789 uint16_t h[] = {0, 0x1234, 0};
14790 uint32_t w[] = {0, 0x12345678, 0};
14791 uint64_t x[] = {0, 0x123456789abcdef0, 0};
14792
14793 SETUP();
14794 START();
14795
14796 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
14797 __ Ldarb(w0, MemOperand(x10));
14798 __ Add(w0, w0, 1);
14799 __ Stlrb(w0, MemOperand(x10));
14800
14801 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
14802 __ Ldarh(w0, MemOperand(x10));
14803 __ Add(w0, w0, 1);
14804 __ Stlrh(w0, MemOperand(x10));
14805
14806 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
14807 __ Ldar(w0, MemOperand(x10));
14808 __ Add(w0, w0, 1);
14809 __ Stlr(w0, MemOperand(x10));
14810
14811 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
14812 __ Ldar(x0, MemOperand(x10));
14813 __ Add(x0, x0, 1);
14814 __ Stlr(x0, MemOperand(x10));
14815
14816 END();
14817 RUN();
14818
14819 ASSERT_EQUAL_32(0x13, b[1]);
14820 ASSERT_EQUAL_32(0x1235, h[1]);
14821 ASSERT_EQUAL_32(0x12345679, w[1]);
14822 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
14823
14824 // Check for over-write.
14825 ASSERT_EQUAL_32(0, b[0]);
14826 ASSERT_EQUAL_32(0, b[2]);
14827 ASSERT_EQUAL_32(0, h[0]);
14828 ASSERT_EQUAL_32(0, h[2]);
14829 ASSERT_EQUAL_32(0, w[0]);
14830 ASSERT_EQUAL_32(0, w[2]);
armvixldb644342015-07-21 11:37:10 +010014831 ASSERT_EQUAL_64(0, x[0]);
14832 ASSERT_EQUAL_64(0, x[2]);
armvixl4a102ba2014-07-14 09:02:40 +010014833
14834 TEARDOWN();
14835}
14836
14837
14838TEST(ldxr_stxr) {
14839 // The middle value is read, modified, and written. The padding exists only to
14840 // check for over-write.
14841 uint8_t b[] = {0, 0x12, 0};
14842 uint16_t h[] = {0, 0x1234, 0};
14843 uint32_t w[] = {0, 0x12345678, 0};
14844 uint64_t x[] = {0, 0x123456789abcdef0, 0};
14845
14846 // As above, but get suitably-aligned values for ldxp and stxp.
14847 uint32_t wp_data[] = {0, 0, 0, 0, 0};
14848 uint32_t * wp = AlignUp(wp_data + 1, kWRegSizeInBytes * 2) - 1;
14849 wp[1] = 0x12345678; // wp[1] is 64-bit-aligned.
14850 wp[2] = 0x87654321;
14851 uint64_t xp_data[] = {0, 0, 0, 0, 0};
14852 uint64_t * xp = AlignUp(xp_data + 1, kXRegSizeInBytes * 2) - 1;
14853 xp[1] = 0x123456789abcdef0; // xp[1] is 128-bit-aligned.
14854 xp[2] = 0x0fedcba987654321;
14855
14856 SETUP();
14857 START();
14858
14859 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
14860 Label try_b;
14861 __ Bind(&try_b);
14862 __ Ldxrb(w0, MemOperand(x10));
14863 __ Add(w0, w0, 1);
14864 __ Stxrb(w5, w0, MemOperand(x10));
14865 __ Cbnz(w5, &try_b);
14866
14867 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
14868 Label try_h;
14869 __ Bind(&try_h);
14870 __ Ldxrh(w0, MemOperand(x10));
14871 __ Add(w0, w0, 1);
14872 __ Stxrh(w5, w0, MemOperand(x10));
14873 __ Cbnz(w5, &try_h);
14874
14875 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
14876 Label try_w;
14877 __ Bind(&try_w);
14878 __ Ldxr(w0, MemOperand(x10));
14879 __ Add(w0, w0, 1);
14880 __ Stxr(w5, w0, MemOperand(x10));
14881 __ Cbnz(w5, &try_w);
14882
14883 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
14884 Label try_x;
14885 __ Bind(&try_x);
14886 __ Ldxr(x0, MemOperand(x10));
14887 __ Add(x0, x0, 1);
14888 __ Stxr(w5, x0, MemOperand(x10));
14889 __ Cbnz(w5, &try_x);
14890
14891 __ Mov(x10, reinterpret_cast<uintptr_t>(&wp[1]));
14892 Label try_wp;
14893 __ Bind(&try_wp);
14894 __ Ldxp(w0, w1, MemOperand(x10));
14895 __ Add(w0, w0, 1);
14896 __ Add(w1, w1, 1);
14897 __ Stxp(w5, w0, w1, MemOperand(x10));
14898 __ Cbnz(w5, &try_wp);
14899
14900 __ Mov(x10, reinterpret_cast<uintptr_t>(&xp[1]));
14901 Label try_xp;
14902 __ Bind(&try_xp);
14903 __ Ldxp(x0, x1, MemOperand(x10));
14904 __ Add(x0, x0, 1);
14905 __ Add(x1, x1, 1);
14906 __ Stxp(w5, x0, x1, MemOperand(x10));
14907 __ Cbnz(w5, &try_xp);
14908
14909 END();
14910 RUN();
14911
14912 ASSERT_EQUAL_32(0x13, b[1]);
14913 ASSERT_EQUAL_32(0x1235, h[1]);
14914 ASSERT_EQUAL_32(0x12345679, w[1]);
14915 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
14916 ASSERT_EQUAL_32(0x12345679, wp[1]);
14917 ASSERT_EQUAL_32(0x87654322, wp[2]);
14918 ASSERT_EQUAL_64(0x123456789abcdef1, xp[1]);
14919 ASSERT_EQUAL_64(0x0fedcba987654322, xp[2]);
14920
14921 // Check for over-write.
14922 ASSERT_EQUAL_32(0, b[0]);
14923 ASSERT_EQUAL_32(0, b[2]);
14924 ASSERT_EQUAL_32(0, h[0]);
14925 ASSERT_EQUAL_32(0, h[2]);
14926 ASSERT_EQUAL_32(0, w[0]);
14927 ASSERT_EQUAL_32(0, w[2]);
14928 ASSERT_EQUAL_64(0, x[0]);
14929 ASSERT_EQUAL_64(0, x[2]);
14930 ASSERT_EQUAL_32(0, wp[0]);
14931 ASSERT_EQUAL_32(0, wp[3]);
14932 ASSERT_EQUAL_64(0, xp[0]);
14933 ASSERT_EQUAL_64(0, xp[3]);
14934
14935 TEARDOWN();
14936}
14937
14938
14939TEST(ldaxr_stlxr) {
14940 // The middle value is read, modified, and written. The padding exists only to
14941 // check for over-write.
14942 uint8_t b[] = {0, 0x12, 0};
14943 uint16_t h[] = {0, 0x1234, 0};
14944 uint32_t w[] = {0, 0x12345678, 0};
14945 uint64_t x[] = {0, 0x123456789abcdef0, 0};
14946
14947 // As above, but get suitably-aligned values for ldxp and stxp.
14948 uint32_t wp_data[] = {0, 0, 0, 0, 0};
14949 uint32_t * wp = AlignUp(wp_data + 1, kWRegSizeInBytes * 2) - 1;
14950 wp[1] = 0x12345678; // wp[1] is 64-bit-aligned.
14951 wp[2] = 0x87654321;
14952 uint64_t xp_data[] = {0, 0, 0, 0, 0};
14953 uint64_t * xp = AlignUp(xp_data + 1, kXRegSizeInBytes * 2) - 1;
14954 xp[1] = 0x123456789abcdef0; // xp[1] is 128-bit-aligned.
14955 xp[2] = 0x0fedcba987654321;
14956
14957 SETUP();
14958 START();
14959
14960 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
14961 Label try_b;
14962 __ Bind(&try_b);
14963 __ Ldaxrb(w0, MemOperand(x10));
14964 __ Add(w0, w0, 1);
14965 __ Stlxrb(w5, w0, MemOperand(x10));
14966 __ Cbnz(w5, &try_b);
14967
14968 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
14969 Label try_h;
14970 __ Bind(&try_h);
14971 __ Ldaxrh(w0, MemOperand(x10));
14972 __ Add(w0, w0, 1);
14973 __ Stlxrh(w5, w0, MemOperand(x10));
14974 __ Cbnz(w5, &try_h);
14975
14976 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
14977 Label try_w;
14978 __ Bind(&try_w);
14979 __ Ldaxr(w0, MemOperand(x10));
14980 __ Add(w0, w0, 1);
14981 __ Stlxr(w5, w0, MemOperand(x10));
14982 __ Cbnz(w5, &try_w);
14983
14984 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
14985 Label try_x;
14986 __ Bind(&try_x);
14987 __ Ldaxr(x0, MemOperand(x10));
14988 __ Add(x0, x0, 1);
14989 __ Stlxr(w5, x0, MemOperand(x10));
14990 __ Cbnz(w5, &try_x);
14991
14992 __ Mov(x10, reinterpret_cast<uintptr_t>(&wp[1]));
14993 Label try_wp;
14994 __ Bind(&try_wp);
14995 __ Ldaxp(w0, w1, MemOperand(x10));
14996 __ Add(w0, w0, 1);
14997 __ Add(w1, w1, 1);
14998 __ Stlxp(w5, w0, w1, MemOperand(x10));
14999 __ Cbnz(w5, &try_wp);
15000
15001 __ Mov(x10, reinterpret_cast<uintptr_t>(&xp[1]));
15002 Label try_xp;
15003 __ Bind(&try_xp);
15004 __ Ldaxp(x0, x1, MemOperand(x10));
15005 __ Add(x0, x0, 1);
15006 __ Add(x1, x1, 1);
15007 __ Stlxp(w5, x0, x1, MemOperand(x10));
15008 __ Cbnz(w5, &try_xp);
15009
15010 END();
15011 RUN();
15012
15013 ASSERT_EQUAL_32(0x13, b[1]);
15014 ASSERT_EQUAL_32(0x1235, h[1]);
15015 ASSERT_EQUAL_32(0x12345679, w[1]);
15016 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
15017 ASSERT_EQUAL_32(0x12345679, wp[1]);
15018 ASSERT_EQUAL_32(0x87654322, wp[2]);
15019 ASSERT_EQUAL_64(0x123456789abcdef1, xp[1]);
15020 ASSERT_EQUAL_64(0x0fedcba987654322, xp[2]);
15021
15022 // Check for over-write.
15023 ASSERT_EQUAL_32(0, b[0]);
15024 ASSERT_EQUAL_32(0, b[2]);
15025 ASSERT_EQUAL_32(0, h[0]);
15026 ASSERT_EQUAL_32(0, h[2]);
15027 ASSERT_EQUAL_32(0, w[0]);
15028 ASSERT_EQUAL_32(0, w[2]);
15029 ASSERT_EQUAL_64(0, x[0]);
15030 ASSERT_EQUAL_64(0, x[2]);
15031 ASSERT_EQUAL_32(0, wp[0]);
15032 ASSERT_EQUAL_32(0, wp[3]);
15033 ASSERT_EQUAL_64(0, xp[0]);
15034 ASSERT_EQUAL_64(0, xp[3]);
15035
15036 TEARDOWN();
15037}
15038
15039
15040TEST(clrex) {
15041 // This data should never be written.
15042 uint64_t data[] = {0, 0, 0};
15043 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
15044
15045 SETUP();
15046 START();
15047
15048 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
15049 __ Mov(w6, 0);
15050
15051 __ Ldxrb(w0, MemOperand(x10));
15052 __ Clrex();
15053 __ Add(w0, w0, 1);
15054 __ Stxrb(w5, w0, MemOperand(x10));
15055 __ Add(w6, w6, w5);
15056
15057 __ Ldxrh(w0, MemOperand(x10));
15058 __ Clrex();
15059 __ Add(w0, w0, 1);
15060 __ Stxrh(w5, w0, MemOperand(x10));
15061 __ Add(w6, w6, w5);
15062
15063 __ Ldxr(w0, MemOperand(x10));
15064 __ Clrex();
15065 __ Add(w0, w0, 1);
15066 __ Stxr(w5, w0, MemOperand(x10));
15067 __ Add(w6, w6, w5);
15068
15069 __ Ldxr(x0, MemOperand(x10));
15070 __ Clrex();
15071 __ Add(x0, x0, 1);
15072 __ Stxr(w5, x0, MemOperand(x10));
15073 __ Add(w6, w6, w5);
15074
15075 __ Ldxp(w0, w1, MemOperand(x10));
15076 __ Clrex();
15077 __ Add(w0, w0, 1);
15078 __ Add(w1, w1, 1);
15079 __ Stxp(w5, w0, w1, MemOperand(x10));
15080 __ Add(w6, w6, w5);
15081
15082 __ Ldxp(x0, x1, MemOperand(x10));
15083 __ Clrex();
15084 __ Add(x0, x0, 1);
15085 __ Add(x1, x1, 1);
15086 __ Stxp(w5, x0, x1, MemOperand(x10));
15087 __ Add(w6, w6, w5);
15088
15089 // Acquire-release variants.
15090
15091 __ Ldaxrb(w0, MemOperand(x10));
15092 __ Clrex();
15093 __ Add(w0, w0, 1);
15094 __ Stlxrb(w5, w0, MemOperand(x10));
15095 __ Add(w6, w6, w5);
15096
15097 __ Ldaxrh(w0, MemOperand(x10));
15098 __ Clrex();
15099 __ Add(w0, w0, 1);
15100 __ Stlxrh(w5, w0, MemOperand(x10));
15101 __ Add(w6, w6, w5);
15102
15103 __ Ldaxr(w0, MemOperand(x10));
15104 __ Clrex();
15105 __ Add(w0, w0, 1);
15106 __ Stlxr(w5, w0, MemOperand(x10));
15107 __ Add(w6, w6, w5);
15108
15109 __ Ldaxr(x0, MemOperand(x10));
15110 __ Clrex();
15111 __ Add(x0, x0, 1);
15112 __ Stlxr(w5, x0, MemOperand(x10));
15113 __ Add(w6, w6, w5);
15114
15115 __ Ldaxp(w0, w1, MemOperand(x10));
15116 __ Clrex();
15117 __ Add(w0, w0, 1);
15118 __ Add(w1, w1, 1);
15119 __ Stlxp(w5, w0, w1, MemOperand(x10));
15120 __ Add(w6, w6, w5);
15121
15122 __ Ldaxp(x0, x1, MemOperand(x10));
15123 __ Clrex();
15124 __ Add(x0, x0, 1);
15125 __ Add(x1, x1, 1);
15126 __ Stlxp(w5, x0, x1, MemOperand(x10));
15127 __ Add(w6, w6, w5);
15128
15129 END();
15130 RUN();
15131
15132 // None of the 12 store-exclusives should have succeeded.
15133 ASSERT_EQUAL_32(12, w6);
15134
15135 ASSERT_EQUAL_64(0, data[0]);
15136 ASSERT_EQUAL_64(0, data[1]);
15137 ASSERT_EQUAL_64(0, data[2]);
armvixldb644342015-07-21 11:37:10 +010015138
15139 TEARDOWN();
armvixl4a102ba2014-07-14 09:02:40 +010015140}
15141
15142
15143#ifdef USE_SIMULATOR
15144// Check that the simulator occasionally makes store-exclusive fail.
15145TEST(ldxr_stxr_fail) {
15146 uint64_t data[] = {0, 0, 0};
15147 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
15148
15149 // Impose a hard limit on the number of attempts, so the test cannot hang.
15150 static const uint64_t kWatchdog = 10000;
15151 Label done;
15152
15153 SETUP();
15154 START();
15155
15156 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
15157 __ Mov(x11, kWatchdog);
15158
15159 // This loop is the opposite of what we normally do with ldxr and stxr; we
15160 // keep trying until we fail (or the watchdog counter runs out).
15161 Label try_b;
15162 __ Bind(&try_b);
15163 __ Ldxrb(w0, MemOperand(x10));
15164 __ Stxrb(w5, w0, MemOperand(x10));
15165 // Check the watchdog counter.
15166 __ Sub(x11, x11, 1);
15167 __ Cbz(x11, &done);
15168 // Check the exclusive-store result.
15169 __ Cbz(w5, &try_b);
15170
15171 Label try_h;
15172 __ Bind(&try_h);
15173 __ Ldxrh(w0, MemOperand(x10));
15174 __ Stxrh(w5, w0, MemOperand(x10));
15175 __ Sub(x11, x11, 1);
15176 __ Cbz(x11, &done);
15177 __ Cbz(w5, &try_h);
15178
15179 Label try_w;
15180 __ Bind(&try_w);
15181 __ Ldxr(w0, MemOperand(x10));
15182 __ Stxr(w5, w0, MemOperand(x10));
15183 __ Sub(x11, x11, 1);
15184 __ Cbz(x11, &done);
15185 __ Cbz(w5, &try_w);
15186
15187 Label try_x;
15188 __ Bind(&try_x);
15189 __ Ldxr(x0, MemOperand(x10));
15190 __ Stxr(w5, x0, MemOperand(x10));
15191 __ Sub(x11, x11, 1);
15192 __ Cbz(x11, &done);
15193 __ Cbz(w5, &try_x);
15194
15195 Label try_wp;
15196 __ Bind(&try_wp);
15197 __ Ldxp(w0, w1, MemOperand(x10));
15198 __ Stxp(w5, w0, w1, MemOperand(x10));
15199 __ Sub(x11, x11, 1);
15200 __ Cbz(x11, &done);
15201 __ Cbz(w5, &try_wp);
15202
15203 Label try_xp;
15204 __ Bind(&try_xp);
15205 __ Ldxp(x0, x1, MemOperand(x10));
15206 __ Stxp(w5, x0, x1, MemOperand(x10));
15207 __ Sub(x11, x11, 1);
15208 __ Cbz(x11, &done);
15209 __ Cbz(w5, &try_xp);
15210
15211 __ Bind(&done);
15212 // Trigger an error if x11 (watchdog) is zero.
15213 __ Cmp(x11, 0);
15214 __ Cset(x12, eq);
15215
15216 END();
15217 RUN();
15218
15219 // Check that the watchdog counter didn't run out.
15220 ASSERT_EQUAL_64(0, x12);
armvixldb644342015-07-21 11:37:10 +010015221
15222 TEARDOWN();
armvixl4a102ba2014-07-14 09:02:40 +010015223}
15224#endif
15225
15226
15227#ifdef USE_SIMULATOR
15228// Check that the simulator occasionally makes store-exclusive fail.
15229TEST(ldaxr_stlxr_fail) {
15230 uint64_t data[] = {0, 0, 0};
15231 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
15232
15233 // Impose a hard limit on the number of attempts, so the test cannot hang.
15234 static const uint64_t kWatchdog = 10000;
15235 Label done;
15236
15237 SETUP();
15238 START();
15239
15240 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
15241 __ Mov(x11, kWatchdog);
15242
15243 // This loop is the opposite of what we normally do with ldxr and stxr; we
15244 // keep trying until we fail (or the watchdog counter runs out).
15245 Label try_b;
15246 __ Bind(&try_b);
15247 __ Ldxrb(w0, MemOperand(x10));
15248 __ Stxrb(w5, w0, MemOperand(x10));
15249 // Check the watchdog counter.
15250 __ Sub(x11, x11, 1);
15251 __ Cbz(x11, &done);
15252 // Check the exclusive-store result.
15253 __ Cbz(w5, &try_b);
15254
15255 Label try_h;
15256 __ Bind(&try_h);
15257 __ Ldaxrh(w0, MemOperand(x10));
15258 __ Stlxrh(w5, w0, MemOperand(x10));
15259 __ Sub(x11, x11, 1);
15260 __ Cbz(x11, &done);
15261 __ Cbz(w5, &try_h);
15262
15263 Label try_w;
15264 __ Bind(&try_w);
15265 __ Ldaxr(w0, MemOperand(x10));
15266 __ Stlxr(w5, w0, MemOperand(x10));
15267 __ Sub(x11, x11, 1);
15268 __ Cbz(x11, &done);
15269 __ Cbz(w5, &try_w);
15270
15271 Label try_x;
15272 __ Bind(&try_x);
15273 __ Ldaxr(x0, MemOperand(x10));
15274 __ Stlxr(w5, x0, MemOperand(x10));
15275 __ Sub(x11, x11, 1);
15276 __ Cbz(x11, &done);
15277 __ Cbz(w5, &try_x);
15278
15279 Label try_wp;
15280 __ Bind(&try_wp);
15281 __ Ldaxp(w0, w1, MemOperand(x10));
15282 __ Stlxp(w5, w0, w1, MemOperand(x10));
15283 __ Sub(x11, x11, 1);
15284 __ Cbz(x11, &done);
15285 __ Cbz(w5, &try_wp);
15286
15287 Label try_xp;
15288 __ Bind(&try_xp);
15289 __ Ldaxp(x0, x1, MemOperand(x10));
15290 __ Stlxp(w5, x0, x1, MemOperand(x10));
15291 __ Sub(x11, x11, 1);
15292 __ Cbz(x11, &done);
15293 __ Cbz(w5, &try_xp);
15294
15295 __ Bind(&done);
15296 // Trigger an error if x11 (watchdog) is zero.
15297 __ Cmp(x11, 0);
15298 __ Cset(x12, eq);
15299
15300 END();
15301 RUN();
15302
15303 // Check that the watchdog counter didn't run out.
15304 ASSERT_EQUAL_64(0, x12);
armvixldb644342015-07-21 11:37:10 +010015305
15306 TEARDOWN();
armvixl4a102ba2014-07-14 09:02:40 +010015307}
15308#endif
15309
15310
15311TEST(load_store_tagged_immediate_offset) {
15312 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15313 int tag_count = sizeof(tags) / sizeof(tags[0]);
15314
armvixl5289c592015-03-02 13:52:04 +000015315 const int kMaxDataLength = 160;
armvixl4a102ba2014-07-14 09:02:40 +010015316
15317 for (int i = 0; i < tag_count; i++) {
15318 unsigned char src[kMaxDataLength];
15319 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
15320 uint64_t src_tag = tags[i];
15321 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
15322
15323 for (int k = 0; k < kMaxDataLength; k++) {
15324 src[k] = k + 1;
15325 }
15326
15327 for (int j = 0; j < tag_count; j++) {
15328 unsigned char dst[kMaxDataLength];
15329 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
15330 uint64_t dst_tag = tags[j];
15331 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
15332
15333 memset(dst, 0, kMaxDataLength);
15334
15335 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015336 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010015337 START();
15338
15339 __ Mov(x0, src_tagged);
15340 __ Mov(x1, dst_tagged);
15341
15342 int offset = 0;
15343
15344 // Scaled-immediate offsets.
armvixl5289c592015-03-02 13:52:04 +000015345 __ ldp(q0, q1, MemOperand(x0, offset));
15346 __ stp(q0, q1, MemOperand(x1, offset));
15347 offset += 2 * kQRegSizeInBytes;
armvixl4a102ba2014-07-14 09:02:40 +010015348
15349 __ ldp(x2, x3, MemOperand(x0, offset));
15350 __ stp(x2, x3, MemOperand(x1, offset));
15351 offset += 2 * kXRegSizeInBytes;
15352
15353 __ ldpsw(x2, x3, MemOperand(x0, offset));
15354 __ stp(w2, w3, MemOperand(x1, offset));
15355 offset += 2 * kWRegSizeInBytes;
15356
15357 __ ldp(d0, d1, MemOperand(x0, offset));
15358 __ stp(d0, d1, MemOperand(x1, offset));
15359 offset += 2 * kDRegSizeInBytes;
15360
15361 __ ldp(w2, w3, MemOperand(x0, offset));
15362 __ stp(w2, w3, MemOperand(x1, offset));
15363 offset += 2 * kWRegSizeInBytes;
15364
15365 __ ldp(s0, s1, MemOperand(x0, offset));
15366 __ stp(s0, s1, MemOperand(x1, offset));
15367 offset += 2 * kSRegSizeInBytes;
15368
15369 __ ldr(x2, MemOperand(x0, offset), RequireScaledOffset);
15370 __ str(x2, MemOperand(x1, offset), RequireScaledOffset);
15371 offset += kXRegSizeInBytes;
15372
15373 __ ldr(d0, MemOperand(x0, offset), RequireScaledOffset);
15374 __ str(d0, MemOperand(x1, offset), RequireScaledOffset);
15375 offset += kDRegSizeInBytes;
15376
15377 __ ldr(w2, MemOperand(x0, offset), RequireScaledOffset);
15378 __ str(w2, MemOperand(x1, offset), RequireScaledOffset);
15379 offset += kWRegSizeInBytes;
15380
15381 __ ldr(s0, MemOperand(x0, offset), RequireScaledOffset);
15382 __ str(s0, MemOperand(x1, offset), RequireScaledOffset);
15383 offset += kSRegSizeInBytes;
15384
15385 __ ldrh(w2, MemOperand(x0, offset), RequireScaledOffset);
15386 __ strh(w2, MemOperand(x1, offset), RequireScaledOffset);
15387 offset += 2;
15388
15389 __ ldrsh(w2, MemOperand(x0, offset), RequireScaledOffset);
15390 __ strh(w2, MemOperand(x1, offset), RequireScaledOffset);
15391 offset += 2;
15392
15393 __ ldrb(w2, MemOperand(x0, offset), RequireScaledOffset);
15394 __ strb(w2, MemOperand(x1, offset), RequireScaledOffset);
15395 offset += 1;
15396
15397 __ ldrsb(w2, MemOperand(x0, offset), RequireScaledOffset);
15398 __ strb(w2, MemOperand(x1, offset), RequireScaledOffset);
15399 offset += 1;
15400
15401 // Unscaled-immediate offsets.
15402
15403 __ ldur(x2, MemOperand(x0, offset), RequireUnscaledOffset);
15404 __ stur(x2, MemOperand(x1, offset), RequireUnscaledOffset);
15405 offset += kXRegSizeInBytes;
15406
15407 __ ldur(d0, MemOperand(x0, offset), RequireUnscaledOffset);
15408 __ stur(d0, MemOperand(x1, offset), RequireUnscaledOffset);
15409 offset += kDRegSizeInBytes;
15410
15411 __ ldur(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15412 __ stur(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15413 offset += kWRegSizeInBytes;
15414
15415 __ ldur(s0, MemOperand(x0, offset), RequireUnscaledOffset);
15416 __ stur(s0, MemOperand(x1, offset), RequireUnscaledOffset);
15417 offset += kSRegSizeInBytes;
15418
15419 __ ldurh(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15420 __ sturh(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15421 offset += 2;
15422
15423 __ ldursh(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15424 __ sturh(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15425 offset += 2;
15426
15427 __ ldurb(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15428 __ sturb(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15429 offset += 1;
15430
15431 __ ldursb(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15432 __ sturb(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15433 offset += 1;
15434
15435 // Extract the tag (so we can test that it was preserved correctly).
15436 __ Ubfx(x0, x0, kAddressTagOffset, kAddressTagWidth);
15437 __ Ubfx(x1, x1, kAddressTagOffset, kAddressTagWidth);
15438
15439 VIXL_ASSERT(kMaxDataLength >= offset);
15440
15441 END();
15442 RUN();
15443
15444 ASSERT_EQUAL_64(src_tag, x0);
15445 ASSERT_EQUAL_64(dst_tag, x1);
15446
15447 for (int k = 0; k < offset; k++) {
15448 VIXL_CHECK(src[k] == dst[k]);
15449 }
15450
15451 TEARDOWN();
15452 }
15453 }
15454}
15455
15456
15457TEST(load_store_tagged_immediate_preindex) {
15458 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15459 int tag_count = sizeof(tags) / sizeof(tags[0]);
15460
15461 const int kMaxDataLength = 128;
15462
15463 for (int i = 0; i < tag_count; i++) {
15464 unsigned char src[kMaxDataLength];
15465 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
15466 uint64_t src_tag = tags[i];
15467 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
15468
15469 for (int k = 0; k < kMaxDataLength; k++) {
15470 src[k] = k + 1;
15471 }
15472
15473 for (int j = 0; j < tag_count; j++) {
15474 unsigned char dst[kMaxDataLength];
15475 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
15476 uint64_t dst_tag = tags[j];
15477 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
15478
15479 for (int k = 0; k < kMaxDataLength; k++) {
15480 dst[k] = 0;
15481 }
15482
15483 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015484 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010015485 START();
15486
15487 // Each MemOperand must apply a pre-index equal to the size of the
15488 // previous access.
15489
15490 // Start with a non-zero preindex.
armvixl5289c592015-03-02 13:52:04 +000015491 int preindex = 62 * kXRegSizeInBytes;
armvixlc68cb642014-09-25 18:49:30 +010015492 int data_length = 0;
armvixl4a102ba2014-07-14 09:02:40 +010015493
15494 __ Mov(x0, src_tagged - preindex);
15495 __ Mov(x1, dst_tagged - preindex);
15496
armvixl5289c592015-03-02 13:52:04 +000015497 __ ldp(q0, q1, MemOperand(x0, preindex, PreIndex));
15498 __ stp(q0, q1, MemOperand(x1, preindex, PreIndex));
15499 preindex = 2 * kQRegSizeInBytes;
15500 data_length = preindex;
15501
armvixl4a102ba2014-07-14 09:02:40 +010015502 __ ldp(x2, x3, MemOperand(x0, preindex, PreIndex));
15503 __ stp(x2, x3, MemOperand(x1, preindex, PreIndex));
15504 preindex = 2 * kXRegSizeInBytes;
armvixl5289c592015-03-02 13:52:04 +000015505 data_length += preindex;
armvixl4a102ba2014-07-14 09:02:40 +010015506
15507 __ ldpsw(x2, x3, MemOperand(x0, preindex, PreIndex));
15508 __ stp(w2, w3, MemOperand(x1, preindex, PreIndex));
15509 preindex = 2 * kWRegSizeInBytes;
15510 data_length += preindex;
15511
15512 __ ldp(d0, d1, MemOperand(x0, preindex, PreIndex));
15513 __ stp(d0, d1, MemOperand(x1, preindex, PreIndex));
15514 preindex = 2 * kDRegSizeInBytes;
15515 data_length += preindex;
15516
15517 __ ldp(w2, w3, MemOperand(x0, preindex, PreIndex));
15518 __ stp(w2, w3, MemOperand(x1, preindex, PreIndex));
15519 preindex = 2 * kWRegSizeInBytes;
15520 data_length += preindex;
15521
15522 __ ldp(s0, s1, MemOperand(x0, preindex, PreIndex));
15523 __ stp(s0, s1, MemOperand(x1, preindex, PreIndex));
15524 preindex = 2 * kSRegSizeInBytes;
15525 data_length += preindex;
15526
15527 __ ldr(x2, MemOperand(x0, preindex, PreIndex));
15528 __ str(x2, MemOperand(x1, preindex, PreIndex));
15529 preindex = kXRegSizeInBytes;
15530 data_length += preindex;
15531
15532 __ ldr(d0, MemOperand(x0, preindex, PreIndex));
15533 __ str(d0, MemOperand(x1, preindex, PreIndex));
15534 preindex = kDRegSizeInBytes;
15535 data_length += preindex;
15536
15537 __ ldr(w2, MemOperand(x0, preindex, PreIndex));
15538 __ str(w2, MemOperand(x1, preindex, PreIndex));
15539 preindex = kWRegSizeInBytes;
15540 data_length += preindex;
15541
15542 __ ldr(s0, MemOperand(x0, preindex, PreIndex));
15543 __ str(s0, MemOperand(x1, preindex, PreIndex));
15544 preindex = kSRegSizeInBytes;
15545 data_length += preindex;
15546
15547 __ ldrh(w2, MemOperand(x0, preindex, PreIndex));
15548 __ strh(w2, MemOperand(x1, preindex, PreIndex));
15549 preindex = 2;
15550 data_length += preindex;
15551
15552 __ ldrsh(w2, MemOperand(x0, preindex, PreIndex));
15553 __ strh(w2, MemOperand(x1, preindex, PreIndex));
15554 preindex = 2;
15555 data_length += preindex;
15556
15557 __ ldrb(w2, MemOperand(x0, preindex, PreIndex));
15558 __ strb(w2, MemOperand(x1, preindex, PreIndex));
15559 preindex = 1;
15560 data_length += preindex;
15561
15562 __ ldrsb(w2, MemOperand(x0, preindex, PreIndex));
15563 __ strb(w2, MemOperand(x1, preindex, PreIndex));
15564 preindex = 1;
15565 data_length += preindex;
15566
15567 VIXL_ASSERT(kMaxDataLength >= data_length);
15568
15569 END();
15570 RUN();
15571
15572 // Check that the preindex was correctly applied in each operation, and
15573 // that the tag was preserved.
15574 ASSERT_EQUAL_64(src_tagged + data_length - preindex, x0);
15575 ASSERT_EQUAL_64(dst_tagged + data_length - preindex, x1);
15576
15577 for (int k = 0; k < data_length; k++) {
15578 VIXL_CHECK(src[k] == dst[k]);
15579 }
15580
15581 TEARDOWN();
15582 }
15583 }
15584}
15585
15586
15587TEST(load_store_tagged_immediate_postindex) {
15588 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15589 int tag_count = sizeof(tags) / sizeof(tags[0]);
15590
15591 const int kMaxDataLength = 128;
15592
15593 for (int i = 0; i < tag_count; i++) {
15594 unsigned char src[kMaxDataLength];
15595 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
15596 uint64_t src_tag = tags[i];
15597 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
15598
15599 for (int k = 0; k < kMaxDataLength; k++) {
15600 src[k] = k + 1;
15601 }
15602
15603 for (int j = 0; j < tag_count; j++) {
15604 unsigned char dst[kMaxDataLength];
15605 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
15606 uint64_t dst_tag = tags[j];
15607 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
15608
15609 for (int k = 0; k < kMaxDataLength; k++) {
15610 dst[k] = 0;
15611 }
15612
15613 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015614 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010015615 START();
15616
armvixlc68cb642014-09-25 18:49:30 +010015617 int postindex = 2 * kXRegSizeInBytes;
15618 int data_length = 0;
15619
armvixl4a102ba2014-07-14 09:02:40 +010015620 __ Mov(x0, src_tagged);
15621 __ Mov(x1, dst_tagged);
15622
armvixl4a102ba2014-07-14 09:02:40 +010015623 __ ldp(x2, x3, MemOperand(x0, postindex, PostIndex));
15624 __ stp(x2, x3, MemOperand(x1, postindex, PostIndex));
armvixlc68cb642014-09-25 18:49:30 +010015625 data_length = postindex;
armvixl4a102ba2014-07-14 09:02:40 +010015626
armvixl5289c592015-03-02 13:52:04 +000015627 postindex = 2 * kQRegSizeInBytes;
15628 __ ldp(q0, q1, MemOperand(x0, postindex, PostIndex));
15629 __ stp(q0, q1, MemOperand(x1, postindex, PostIndex));
15630 data_length += postindex;
15631
armvixl4a102ba2014-07-14 09:02:40 +010015632 postindex = 2 * kWRegSizeInBytes;
15633 __ ldpsw(x2, x3, MemOperand(x0, postindex, PostIndex));
15634 __ stp(w2, w3, MemOperand(x1, postindex, PostIndex));
15635 data_length += postindex;
15636
15637 postindex = 2 * kDRegSizeInBytes;
15638 __ ldp(d0, d1, MemOperand(x0, postindex, PostIndex));
15639 __ stp(d0, d1, MemOperand(x1, postindex, PostIndex));
15640 data_length += postindex;
15641
15642 postindex = 2 * kWRegSizeInBytes;
15643 __ ldp(w2, w3, MemOperand(x0, postindex, PostIndex));
15644 __ stp(w2, w3, MemOperand(x1, postindex, PostIndex));
15645 data_length += postindex;
15646
15647 postindex = 2 * kSRegSizeInBytes;
15648 __ ldp(s0, s1, MemOperand(x0, postindex, PostIndex));
15649 __ stp(s0, s1, MemOperand(x1, postindex, PostIndex));
15650 data_length += postindex;
15651
15652 postindex = kXRegSizeInBytes;
15653 __ ldr(x2, MemOperand(x0, postindex, PostIndex));
15654 __ str(x2, MemOperand(x1, postindex, PostIndex));
15655 data_length += postindex;
15656
15657 postindex = kDRegSizeInBytes;
15658 __ ldr(d0, MemOperand(x0, postindex, PostIndex));
15659 __ str(d0, MemOperand(x1, postindex, PostIndex));
15660 data_length += postindex;
15661
15662 postindex = kWRegSizeInBytes;
15663 __ ldr(w2, MemOperand(x0, postindex, PostIndex));
15664 __ str(w2, MemOperand(x1, postindex, PostIndex));
15665 data_length += postindex;
15666
15667 postindex = kSRegSizeInBytes;
15668 __ ldr(s0, MemOperand(x0, postindex, PostIndex));
15669 __ str(s0, MemOperand(x1, postindex, PostIndex));
15670 data_length += postindex;
15671
15672 postindex = 2;
15673 __ ldrh(w2, MemOperand(x0, postindex, PostIndex));
15674 __ strh(w2, MemOperand(x1, postindex, PostIndex));
15675 data_length += postindex;
15676
15677 postindex = 2;
15678 __ ldrsh(w2, MemOperand(x0, postindex, PostIndex));
15679 __ strh(w2, MemOperand(x1, postindex, PostIndex));
15680 data_length += postindex;
15681
15682 postindex = 1;
15683 __ ldrb(w2, MemOperand(x0, postindex, PostIndex));
15684 __ strb(w2, MemOperand(x1, postindex, PostIndex));
15685 data_length += postindex;
15686
15687 postindex = 1;
15688 __ ldrsb(w2, MemOperand(x0, postindex, PostIndex));
15689 __ strb(w2, MemOperand(x1, postindex, PostIndex));
15690 data_length += postindex;
15691
15692 VIXL_ASSERT(kMaxDataLength >= data_length);
15693
15694 END();
15695 RUN();
15696
15697 // Check that the postindex was correctly applied in each operation, and
15698 // that the tag was preserved.
15699 ASSERT_EQUAL_64(src_tagged + data_length, x0);
15700 ASSERT_EQUAL_64(dst_tagged + data_length, x1);
15701
15702 for (int k = 0; k < data_length; k++) {
15703 VIXL_CHECK(src[k] == dst[k]);
15704 }
15705
15706 TEARDOWN();
15707 }
15708 }
15709}
15710
15711
15712TEST(load_store_tagged_register_offset) {
15713 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15714 int tag_count = sizeof(tags) / sizeof(tags[0]);
15715
15716 const int kMaxDataLength = 128;
15717
15718 for (int i = 0; i < tag_count; i++) {
15719 unsigned char src[kMaxDataLength];
15720 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
15721 uint64_t src_tag = tags[i];
15722 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
15723
15724 for (int k = 0; k < kMaxDataLength; k++) {
15725 src[k] = k + 1;
15726 }
15727
15728 for (int j = 0; j < tag_count; j++) {
15729 unsigned char dst[kMaxDataLength];
15730 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
15731 uint64_t dst_tag = tags[j];
15732 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
15733
15734 // Also tag the offset register; the operation should still succeed.
15735 for (int o = 0; o < tag_count; o++) {
15736 uint64_t offset_base = CPU::SetPointerTag(UINT64_C(0), tags[o]);
15737 int data_length = 0;
15738
15739 for (int k = 0; k < kMaxDataLength; k++) {
15740 dst[k] = 0;
15741 }
15742
15743 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015744 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010015745 START();
15746
15747 __ Mov(x0, src_tagged);
15748 __ Mov(x1, dst_tagged);
15749
15750 __ Mov(x10, offset_base + data_length);
15751 __ ldr(x2, MemOperand(x0, x10));
15752 __ str(x2, MemOperand(x1, x10));
15753 data_length += kXRegSizeInBytes;
15754
15755 __ Mov(x10, offset_base + data_length);
15756 __ ldr(d0, MemOperand(x0, x10));
15757 __ str(d0, MemOperand(x1, x10));
15758 data_length += kDRegSizeInBytes;
15759
15760 __ Mov(x10, offset_base + data_length);
15761 __ ldr(w2, MemOperand(x0, x10));
15762 __ str(w2, MemOperand(x1, x10));
15763 data_length += kWRegSizeInBytes;
15764
15765 __ Mov(x10, offset_base + data_length);
15766 __ ldr(s0, MemOperand(x0, x10));
15767 __ str(s0, MemOperand(x1, x10));
15768 data_length += kSRegSizeInBytes;
15769
15770 __ Mov(x10, offset_base + data_length);
15771 __ ldrh(w2, MemOperand(x0, x10));
15772 __ strh(w2, MemOperand(x1, x10));
15773 data_length += 2;
15774
15775 __ Mov(x10, offset_base + data_length);
15776 __ ldrsh(w2, MemOperand(x0, x10));
15777 __ strh(w2, MemOperand(x1, x10));
15778 data_length += 2;
15779
15780 __ Mov(x10, offset_base + data_length);
15781 __ ldrb(w2, MemOperand(x0, x10));
15782 __ strb(w2, MemOperand(x1, x10));
15783 data_length += 1;
15784
15785 __ Mov(x10, offset_base + data_length);
15786 __ ldrsb(w2, MemOperand(x0, x10));
15787 __ strb(w2, MemOperand(x1, x10));
15788 data_length += 1;
15789
15790 VIXL_ASSERT(kMaxDataLength >= data_length);
15791
15792 END();
15793 RUN();
15794
15795 // Check that the postindex was correctly applied in each operation, and
15796 // that the tag was preserved.
15797 ASSERT_EQUAL_64(src_tagged, x0);
15798 ASSERT_EQUAL_64(dst_tagged, x1);
15799 ASSERT_EQUAL_64(offset_base + data_length - 1, x10);
15800
15801 for (int k = 0; k < data_length; k++) {
15802 VIXL_CHECK(src[k] == dst[k]);
15803 }
15804
15805 TEARDOWN();
15806 }
15807 }
15808 }
15809}
15810
15811
armvixl5289c592015-03-02 13:52:04 +000015812TEST(load_store_tagged_register_postindex) {
15813 uint64_t src[] = { 0x0706050403020100, 0x0f0e0d0c0b0a0908 };
15814 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15815 int tag_count = sizeof(tags) / sizeof(tags[0]);
15816
15817 for (int j = 0; j < tag_count; j++) {
15818 for (int i = 0; i < tag_count; i++) {
15819 SETUP();
15820 uint64_t src_base = reinterpret_cast<uint64_t>(src);
15821 uint64_t src_tagged = CPU::SetPointerTag(src_base, tags[i]);
15822 uint64_t offset_tagged = CPU::SetPointerTag(UINT64_C(0), tags[j]);
15823
15824 START();
15825 __ Mov(x10, src_tagged);
15826 __ Mov(x11, offset_tagged);
15827 __ Ld1(v0.V16B(), MemOperand(x10, x11, PostIndex));
15828 // TODO: add other instructions (ld2-4, st1-4) as they become available.
15829 END();
15830
15831 RUN();
15832
15833 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q0);
15834 ASSERT_EQUAL_64(src_tagged + offset_tagged, x10);
15835
15836 TEARDOWN();
15837 }
15838 }
15839}
15840
15841
armvixlc68cb642014-09-25 18:49:30 +010015842TEST(branch_tagged) {
15843 SETUP();
15844 START();
15845
15846 Label loop, loop_entry, done;
15847 __ Adr(x0, &loop);
15848 __ Mov(x1, 0);
15849 __ B(&loop_entry);
15850
15851 __ Bind(&loop);
15852 __ Add(x1, x1, 1); // Count successful jumps.
15853
15854 // Advance to the next tag, then bail out if we've come back around to tag 0.
15855 __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
15856 __ Tst(x0, kAddressTagMask);
15857 __ B(eq, &done);
15858
15859 __ Bind(&loop_entry);
15860 __ Br(x0);
15861
15862 __ Bind(&done);
15863
15864 END();
15865 RUN();
15866
15867 ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
15868
15869 TEARDOWN();
15870}
15871
15872
15873TEST(branch_and_link_tagged) {
15874 SETUP();
15875 START();
15876
15877 Label loop, loop_entry, done;
15878 __ Adr(x0, &loop);
15879 __ Mov(x1, 0);
15880 __ B(&loop_entry);
15881
15882 __ Bind(&loop);
15883
15884 // Bail out (before counting a successful jump) if lr appears to be tagged.
15885 __ Tst(lr, kAddressTagMask);
15886 __ B(ne, &done);
15887
15888 __ Add(x1, x1, 1); // Count successful jumps.
15889
15890 // Advance to the next tag, then bail out if we've come back around to tag 0.
15891 __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
15892 __ Tst(x0, kAddressTagMask);
15893 __ B(eq, &done);
15894
15895 __ Bind(&loop_entry);
15896 __ Blr(x0);
15897
15898 __ Bind(&done);
15899
15900 END();
15901 RUN();
15902
15903 ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
15904
15905 TEARDOWN();
15906}
15907
15908
15909TEST(branch_tagged_and_adr_adrp) {
15910 SETUP_CUSTOM(BUF_SIZE, PageOffsetDependentCode);
15911 START();
15912
15913 Label loop, loop_entry, done;
15914 __ Adr(x0, &loop);
15915 __ Mov(x1, 0);
15916 __ B(&loop_entry);
15917
15918 __ Bind(&loop);
15919
15920 // Bail out (before counting a successful jump) if `adr x10, ...` is tagged.
15921 __ Adr(x10, &done);
15922 __ Tst(x10, kAddressTagMask);
15923 __ B(ne, &done);
15924
15925 // Bail out (before counting a successful jump) if `adrp x11, ...` is tagged.
15926 __ Adrp(x11, &done);
15927 __ Tst(x11, kAddressTagMask);
15928 __ B(ne, &done);
15929
15930 __ Add(x1, x1, 1); // Count successful iterations.
15931
15932 // Advance to the next tag, then bail out if we've come back around to tag 0.
15933 __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
15934 __ Tst(x0, kAddressTagMask);
15935 __ B(eq, &done);
15936
15937 __ Bind(&loop_entry);
15938 __ Br(x0);
15939
15940 __ Bind(&done);
15941
15942 END();
15943 RUN();
15944
15945 ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
15946
armvixldb644342015-07-21 11:37:10 +010015947 TEARDOWN_CUSTOM();
armvixlc68cb642014-09-25 18:49:30 +010015948}
15949
armvixl5289c592015-03-02 13:52:04 +000015950TEST(neon_3same_addp) {
15951 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015952
armvixl5289c592015-03-02 13:52:04 +000015953 START();
15954
15955 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
15956 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
15957 __ Addp(v16.V16B(), v0.V16B(), v1.V16B());
15958
15959 END();
15960
15961 RUN();
15962 ASSERT_EQUAL_128(0x00ff54ffff54aaff, 0xffffffffffffffff, q16);
15963 TEARDOWN();
15964}
15965
15966TEST(neon_3same_sqdmulh_sqrdmulh) {
15967 SETUP();
15968
15969 START();
15970
15971 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000040004008000);
15972 __ Movi(v1.V2D(), 0x0000000000000000, 0x0000002000108000);
15973 __ Movi(v2.V2D(), 0x0400000080000000, 0x0400000080000000);
15974 __ Movi(v3.V2D(), 0x0000002080000000, 0x0000001080000000);
15975
15976 __ Sqdmulh(v16.V4H(), v0.V4H(), v1.V4H());
15977 __ Sqdmulh(v17.V4S(), v2.V4S(), v3.V4S());
15978 __ Sqdmulh(h18, h0, h1);
15979 __ Sqdmulh(s19, s2, s3);
15980
15981 __ Sqrdmulh(v20.V4H(), v0.V4H(), v1.V4H());
15982 __ Sqrdmulh(v21.V4S(), v2.V4S(), v3.V4S());
15983 __ Sqrdmulh(h22, h0, h1);
15984 __ Sqrdmulh(s23, s2, s3);
15985
15986 END();
15987
15988 RUN();
15989 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000100007fff, q16);
15990 ASSERT_EQUAL_128(0x000000017fffffff, 0x000000007fffffff, q17);
15991 ASSERT_EQUAL_128(0, 0x7fff, q18);
15992 ASSERT_EQUAL_128(0, 0x7fffffff, q19);
15993 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000100017fff, q20);
15994 ASSERT_EQUAL_128(0x000000017fffffff, 0x000000017fffffff, q21);
15995 ASSERT_EQUAL_128(0, 0x7fff, q22);
15996 ASSERT_EQUAL_128(0, 0x7fffffff, q23);
15997 TEARDOWN();
15998}
15999
16000TEST(neon_byelement_sqdmulh_sqrdmulh) {
16001 SETUP();
16002
16003 START();
16004
16005 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000040004008000);
16006 __ Movi(v1.V2D(), 0x0000000000000000, 0x0000002000108000);
16007 __ Movi(v2.V2D(), 0x0400000080000000, 0x0400000080000000);
16008 __ Movi(v3.V2D(), 0x0000002080000000, 0x0000001080000000);
16009
16010 __ Sqdmulh(v16.V4H(), v0.V4H(), v1.H(), 1);
16011 __ Sqdmulh(v17.V4S(), v2.V4S(), v3.S(), 1);
16012 __ Sqdmulh(h18, h0, v1.H(), 0);
16013 __ Sqdmulh(s19, s2, v3.S(), 0);
16014
16015 __ Sqrdmulh(v20.V4H(), v0.V4H(), v1.H(), 1);
16016 __ Sqrdmulh(v21.V4S(), v2.V4S(), v3.S(), 1);
16017 __ Sqrdmulh(h22, h0, v1.H(), 0);
16018 __ Sqrdmulh(s23, s2, v3.S(), 0);
16019
16020 END();
16021
16022 RUN();
16023 ASSERT_EQUAL_128(0x0000000000000000, 0x000000000000fff0, q16);
16024 ASSERT_EQUAL_128(0x00000000fffffff0, 0x00000000fffffff0, q17);
16025 ASSERT_EQUAL_128(0, 0x7fff, q18);
16026 ASSERT_EQUAL_128(0, 0x7fffffff, q19);
16027 ASSERT_EQUAL_128(0x0000000000000000, 0x000000010001fff0, q20);
16028 ASSERT_EQUAL_128(0x00000001fffffff0, 0x00000001fffffff0, q21);
16029 ASSERT_EQUAL_128(0, 0x7fff, q22);
16030 ASSERT_EQUAL_128(0, 0x7fffffff, q23);
16031 TEARDOWN();
16032}
16033
16034
16035TEST(neon_2regmisc_saddlp) {
16036 SETUP();
16037
16038 START();
16039
16040 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16041
16042 __ Saddlp(v16.V8H(), v0.V16B());
16043 __ Saddlp(v17.V4H(), v0.V8B());
16044
16045 __ Saddlp(v18.V4S(), v0.V8H());
16046 __ Saddlp(v19.V2S(), v0.V4H());
16047
16048 __ Saddlp(v20.V2D(), v0.V4S());
16049 __ Saddlp(v21.V1D(), v0.V2S());
16050
16051 END();
16052
16053 RUN();
16054 ASSERT_EQUAL_128(0x0080ffffff010080, 0xff01ffff0080ff01, q16);
16055 ASSERT_EQUAL_128(0x0000000000000000, 0xff01ffff0080ff01, q17);
16056 ASSERT_EQUAL_128(0x0000800000000081, 0xffff7f81ffff8200, q18);
16057 ASSERT_EQUAL_128(0x0000000000000000, 0xffff7f81ffff8200, q19);
16058 ASSERT_EQUAL_128(0x0000000000818000, 0xffffffff82017f81, q20);
16059 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffff82017f81, q21);
16060 TEARDOWN();
16061}
16062
16063TEST(neon_2regmisc_uaddlp) {
16064 SETUP();
16065
16066 START();
16067
16068 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16069
16070 __ Uaddlp(v16.V8H(), v0.V16B());
16071 __ Uaddlp(v17.V4H(), v0.V8B());
16072
16073 __ Uaddlp(v18.V4S(), v0.V8H());
16074 __ Uaddlp(v19.V2S(), v0.V4H());
16075
16076 __ Uaddlp(v20.V2D(), v0.V4S());
16077 __ Uaddlp(v21.V1D(), v0.V2S());
16078
16079 END();
16080
16081 RUN();
16082 ASSERT_EQUAL_128(0x008000ff01010080, 0x010100ff00800101, q16);
16083 ASSERT_EQUAL_128(0x0000000000000000, 0x010100ff00800101, q17);
16084 ASSERT_EQUAL_128(0x0000800000010081, 0x00017f8100008200, q18);
16085 ASSERT_EQUAL_128(0x0000000000000000, 0x00017f8100008200, q19);
16086 ASSERT_EQUAL_128(0x0000000100818000, 0x0000000082017f81, q20);
16087 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000082017f81, q21);
16088 TEARDOWN();
16089}
16090
16091TEST(neon_2regmisc_sadalp) {
16092 SETUP();
16093
16094 START();
16095
16096 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16097 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
16098 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
16099 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
16100 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
16101
16102 __ Mov(v16.V16B(), v1.V16B());
16103 __ Mov(v17.V16B(), v1.V16B());
16104 __ Sadalp(v16.V8H(), v0.V16B());
16105 __ Sadalp(v17.V4H(), v0.V8B());
16106
16107 __ Mov(v18.V16B(), v2.V16B());
16108 __ Mov(v19.V16B(), v2.V16B());
16109 __ Sadalp(v18.V4S(), v1.V8H());
16110 __ Sadalp(v19.V2S(), v1.V4H());
16111
16112 __ Mov(v20.V16B(), v3.V16B());
16113 __ Mov(v21.V16B(), v4.V16B());
16114 __ Sadalp(v20.V2D(), v2.V4S());
16115 __ Sadalp(v21.V1D(), v2.V2S());
16116
16117 END();
16118
16119 RUN();
16120 ASSERT_EQUAL_128(0x80808000ff000080, 0xff00ffff00817f00, q16);
16121 ASSERT_EQUAL_128(0x0000000000000000, 0xff00ffff00817f00, q17);
16122 ASSERT_EQUAL_128(0x7fff0001fffffffe, 0xffffffff80007fff, q18);
16123 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffff80007fff, q19);
16124 ASSERT_EQUAL_128(0x7fffffff80000000, 0x800000007ffffffe, q20);
16125 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
16126 TEARDOWN();
16127}
16128
16129TEST(neon_2regmisc_uadalp) {
16130 SETUP();
16131
16132 START();
16133
16134 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16135 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
16136 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
16137 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
16138 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
16139
16140 __ Mov(v16.V16B(), v1.V16B());
16141 __ Mov(v17.V16B(), v1.V16B());
16142 __ Uadalp(v16.V8H(), v0.V16B());
16143 __ Uadalp(v17.V4H(), v0.V8B());
16144
16145 __ Mov(v18.V16B(), v2.V16B());
16146 __ Mov(v19.V16B(), v2.V16B());
16147 __ Uadalp(v18.V4S(), v1.V8H());
16148 __ Uadalp(v19.V2S(), v1.V4H());
16149
16150 __ Mov(v20.V16B(), v3.V16B());
16151 __ Mov(v21.V16B(), v4.V16B());
16152 __ Uadalp(v20.V2D(), v2.V4S());
16153 __ Uadalp(v21.V1D(), v2.V2S());
16154
16155 END();
16156
16157 RUN();
16158 ASSERT_EQUAL_128(0x8080810001000080, 0x010000ff00818100, q16);
16159 ASSERT_EQUAL_128(0x0000000000000000, 0x010000ff00818100, q17);
16160 ASSERT_EQUAL_128(0x800100010000fffe, 0x0000ffff80007fff, q18);
16161 ASSERT_EQUAL_128(0x0000000000000000, 0x0000ffff80007fff, q19);
16162 ASSERT_EQUAL_128(0x8000000180000000, 0x800000007ffffffe, q20);
16163 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
16164 TEARDOWN();
16165}
16166
16167TEST(neon_3same_mul) {
16168 SETUP();
16169
16170 START();
16171
16172 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16173 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16174 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16175 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16176
16177 __ Mla(v16.V16B(), v0.V16B(), v1.V16B());
16178 __ Mls(v17.V16B(), v0.V16B(), v1.V16B());
16179 __ Mul(v18.V16B(), v0.V16B(), v1.V16B());
16180
16181 END();
16182
16183 RUN();
16184 ASSERT_EQUAL_128(0x0102757605b1b208, 0x5f0a61450db90f56, q16);
16185 ASSERT_EQUAL_128(0x01029192055b5c08, 0xb30ab5d30d630faa, q17);
16186 ASSERT_EQUAL_128(0x0000727200abab00, 0x5600563900ab0056, q18);
16187 TEARDOWN();
16188}
16189
16190
16191
16192TEST(neon_3same_absdiff) {
16193 SETUP();
16194
16195 START();
16196
16197 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16198 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16199 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16200 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16201
16202 __ Saba(v16.V16B(), v0.V16B(), v1.V16B());
16203 __ Uaba(v17.V16B(), v0.V16B(), v1.V16B());
16204 __ Sabd(v18.V16B(), v0.V16B(), v1.V16B());
16205 __ Uabd(v19.V16B(), v0.V16B(), v1.V16B());
16206
16207 END();
16208
16209 RUN();
16210 ASSERT_EQUAL_128(0x0202aeaf065c5d5e, 0x5e5f600c62646455, q16);
16211 ASSERT_EQUAL_128(0x0002585904b0b1b2, 0x5e5f600c62b86455, q17);
16212 ASSERT_EQUAL_128(0x0100abab01565656, 0x5555550055565555, q18);
16213 ASSERT_EQUAL_128(0xff005555ffaaaaaa, 0x5555550055aa5555, q19);
16214 TEARDOWN();
16215}
16216
16217
16218TEST(neon_byelement_mul) {
16219 SETUP();
16220
16221 START();
16222
16223 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16224 __ Movi(v1.V2D(), 0x000155aaff55ff00, 0xaa55ff55555500ff);
16225
16226
16227 __ Mul(v16.V4H(), v0.V4H(), v1.H(), 0);
16228 __ Mul(v17.V8H(), v0.V8H(), v1.H(), 7);
16229 __ Mul(v18.V2S(), v0.V2S(), v1.S(), 0);
16230 __ Mul(v19.V4S(), v0.V4S(), v1.S(), 3);
16231
16232 __ Movi(v20.V2D(), 0x0000000000000000, 0x0001000200030004);
16233 __ Movi(v21.V2D(), 0x0005000600070008, 0x0001000200030004);
16234 __ Mla(v20.V4H(), v0.V4H(), v1.H(), 0);
16235 __ Mla(v21.V8H(), v0.V8H(), v1.H(), 7);
16236
16237 __ Movi(v22.V2D(), 0x0000000000000000, 0x0000000200000004);
16238 __ Movi(v23.V2D(), 0x0000000600000008, 0x0000000200000004);
16239 __ Mla(v22.V2S(), v0.V2S(), v1.S(), 0);
16240 __ Mla(v23.V4S(), v0.V4S(), v1.S(), 3);
16241
16242 __ Movi(v24.V2D(), 0x0000000000000000, 0x0100aaabfe015456);
16243 __ Movi(v25.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16244 __ Mls(v24.V4H(), v0.V4H(), v1.H(), 0);
16245 __ Mls(v25.V8H(), v0.V8H(), v1.H(), 7);
16246
16247 __ Movi(v26.V2D(), 0x0000000000000000, 0xc8e2aaabe1c85456);
16248 __ Movi(v27.V2D(), 0x39545572c6aa54e4, 0x39545572c6aa54e4);
16249 __ Mls(v26.V2S(), v0.V2S(), v1.S(), 0);
16250 __ Mls(v27.V4S(), v0.V4S(), v1.S(), 3);
16251
16252 END();
16253
16254 RUN();
16255 ASSERT_EQUAL_128(0x0000000000000000, 0x0100aaabfe015456, q16);
16256 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q17);
16257 ASSERT_EQUAL_128(0x0000000000000000, 0xc8e2aaabe1c85456, q18);
16258 ASSERT_EQUAL_128(0x39545572c6aa54e4, 0x39545572c6aa54e4, q19);
16259
16260 ASSERT_EQUAL_128(0x0000000000000000, 0x0101aaadfe04545a, q20);
16261 ASSERT_EQUAL_128(0xff05aa5b010655b2, 0xff01aa57010255ae, q21);
16262 ASSERT_EQUAL_128(0x0000000000000000, 0xc8e2aaade1c8545a, q22);
16263 ASSERT_EQUAL_128(0x39545578c6aa54ec, 0x39545574c6aa54e8, q23);
16264
16265 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16266 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16267 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q26);
16268 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q27);
16269 TEARDOWN();
16270}
16271
16272
16273TEST(neon_byelement_mull) {
16274 SETUP();
16275
16276 START();
16277
16278 __ Movi(v0.V2D(), 0xaa55ff55555500ff, 0xff00aa5500ff55aa);
16279 __ Movi(v1.V2D(), 0x000155aaff55ff00, 0xaa55ff55555500ff);
16280
16281
16282 __ Smull(v16.V4S(), v0.V4H(), v1.H(), 7);
16283 __ Smull2(v17.V4S(), v0.V8H(), v1.H(), 0);
16284 __ Umull(v18.V4S(), v0.V4H(), v1.H(), 7);
16285 __ Umull2(v19.V4S(), v0.V8H(), v1.H(), 0);
16286
16287 __ Movi(v20.V2D(), 0x0000000100000002, 0x0000000200000001);
16288 __ Movi(v21.V2D(), 0x0000000100000002, 0x0000000200000001);
16289 __ Movi(v22.V2D(), 0x0000000100000002, 0x0000000200000001);
16290 __ Movi(v23.V2D(), 0x0000000100000002, 0x0000000200000001);
16291
16292 __ Smlal(v20.V4S(), v0.V4H(), v1.H(), 7);
16293 __ Smlal2(v21.V4S(), v0.V8H(), v1.H(), 0);
16294 __ Umlal(v22.V4S(), v0.V4H(), v1.H(), 7);
16295 __ Umlal2(v23.V4S(), v0.V8H(), v1.H(), 0);
16296
16297 __ Movi(v24.V2D(), 0xffffff00ffffaa55, 0x000000ff000055aa);
16298 __ Movi(v25.V2D(), 0xffaaaaabffff55ab, 0x0054ffab0000fe01);
16299 __ Movi(v26.V2D(), 0x0000ff000000aa55, 0x000000ff000055aa);
16300 __ Movi(v27.V2D(), 0x00a9aaab00fe55ab, 0x0054ffab0000fe01);
16301
16302 __ Smlsl(v24.V4S(), v0.V4H(), v1.H(), 7);
16303 __ Smlsl2(v25.V4S(), v0.V8H(), v1.H(), 0);
16304 __ Umlsl(v26.V4S(), v0.V4H(), v1.H(), 7);
16305 __ Umlsl2(v27.V4S(), v0.V8H(), v1.H(), 0);
16306
16307 END();
16308
16309 RUN();
16310
16311 ASSERT_EQUAL_128(0xffffff00ffffaa55, 0x000000ff000055aa, q16);
16312 ASSERT_EQUAL_128(0xffaaaaabffff55ab, 0x0054ffab0000fe01, q17);
16313 ASSERT_EQUAL_128(0x0000ff000000aa55, 0x000000ff000055aa, q18);
16314 ASSERT_EQUAL_128(0x00a9aaab00fe55ab, 0x0054ffab0000fe01, q19);
16315
16316 ASSERT_EQUAL_128(0xffffff01ffffaa57, 0x00000101000055ab, q20);
16317 ASSERT_EQUAL_128(0xffaaaaacffff55ad, 0x0054ffad0000fe02, q21);
16318 ASSERT_EQUAL_128(0x0000ff010000aa57, 0x00000101000055ab, q22);
16319 ASSERT_EQUAL_128(0x00a9aaac00fe55ad, 0x0054ffad0000fe02, q23);
16320
16321 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16322 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16323 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q26);
16324 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q27);
16325
16326 TEARDOWN();
16327}
16328
16329
16330TEST(neon_byelement_sqdmull) {
16331 SETUP();
16332
16333 START();
16334
16335 __ Movi(v0.V2D(), 0xaa55ff55555500ff, 0xff00aa5500ff55aa);
16336 __ Movi(v1.V2D(), 0x000155aaff55ff00, 0xaa55ff55555500ff);
16337
16338 __ Sqdmull(v16.V4S(), v0.V4H(), v1.H(), 7);
16339 __ Sqdmull2(v17.V4S(), v0.V8H(), v1.H(), 0);
16340 __ Sqdmull(s18, h0, v1.H(), 7);
16341
16342 __ Movi(v20.V2D(), 0x0000000100000002, 0x0000000200000001);
16343 __ Movi(v21.V2D(), 0x0000000100000002, 0x0000000200000001);
16344 __ Movi(v22.V2D(), 0x0000000100000002, 0x0000000200000001);
16345
16346 __ Sqdmlal(v20.V4S(), v0.V4H(), v1.H(), 7);
16347 __ Sqdmlal2(v21.V4S(), v0.V8H(), v1.H(), 0);
16348 __ Sqdmlal(s22, h0, v1.H(), 7);
16349
16350 __ Movi(v24.V2D(), 0xfffffe00ffff54aa, 0x000001fe0000ab54);
16351 __ Movi(v25.V2D(), 0xff555556fffeab56, 0x00a9ff560001fc02);
16352 __ Movi(v26.V2D(), 0x0000000000000000, 0x000000000000ab54);
16353
16354 __ Sqdmlsl(v24.V4S(), v0.V4H(), v1.H(), 7);
16355 __ Sqdmlsl2(v25.V4S(), v0.V8H(), v1.H(), 0);
16356 __ Sqdmlsl(s26, h0, v1.H(), 7);
16357
16358 END();
16359
16360 RUN();
16361
16362 ASSERT_EQUAL_128(0xfffffe00ffff54aa, 0x000001fe0000ab54, q16);
16363 ASSERT_EQUAL_128(0xff555556fffeab56, 0x00a9ff560001fc02, q17);
16364 ASSERT_EQUAL_128(0, 0x0000ab54, q18);
16365
16366 ASSERT_EQUAL_128(0xfffffe01ffff54ac, 0x000002000000ab55, q20);
16367 ASSERT_EQUAL_128(0xff555557fffeab58, 0x00a9ff580001fc03, q21);
16368 ASSERT_EQUAL_128(0, 0x0000ab55, q22);
16369
16370 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16371 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16372 ASSERT_EQUAL_128(0, 0x00000000, q26);
16373
16374 TEARDOWN();
16375}
16376
16377
16378TEST(neon_3diff_absdiff) {
16379 SETUP();
16380
16381 START();
16382
16383 __ Movi(v0.V2D(), 0xff00aa5500ff55ab, 0xff00aa5500ff55aa);
16384 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16385 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16386 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16387 __ Movi(v18.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16388 __ Movi(v19.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16389
16390 __ Sabal(v16.V8H(), v0.V8B(), v1.V8B());
16391 __ Uabal(v17.V8H(), v0.V8B(), v1.V8B());
16392 __ Sabal2(v18.V8H(), v0.V16B(), v1.V16B());
16393 __ Uabal2(v19.V8H(), v0.V16B(), v1.V16B());
16394
16395 END();
16396
16397 RUN();
16398 ASSERT_EQUAL_128(0x01570359055b0708, 0x095f0b620d630f55, q16);
16399 ASSERT_EQUAL_128(0x01570359055b0708, 0x095f0bb60d630f55, q17);
16400 ASSERT_EQUAL_128(0x0103030405b107b3, 0x090b0b620d640f55, q18);
16401 ASSERT_EQUAL_128(0x02010304055b075d, 0x0a090bb60db80fab, q19);
16402 TEARDOWN();
16403}
16404
16405
16406TEST(neon_3diff_sqdmull) {
16407 SETUP();
16408
16409 START();
16410
16411 __ Movi(v0.V2D(), 0x7fff7fff80008000, 0x80007fff7fff8000);
16412 __ Movi(v1.V2D(), 0x80007fff7fff8000, 0x7fff7fff80008000);
16413 __ Movi(v2.V2D(), 0x800000007fffffff, 0x7fffffff80000000);
16414 __ Movi(v3.V2D(), 0x8000000080000000, 0x8000000080000000);
16415
16416 __ Sqdmull(v16.V4S(), v0.V4H(), v1.V4H());
16417 __ Sqdmull2(v17.V4S(), v0.V8H(), v1.V8H());
16418 __ Sqdmull(v18.V2D(), v2.V2S(), v3.V2S());
16419 __ Sqdmull2(v19.V2D(), v2.V4S(), v3.V4S());
16420 __ Sqdmull(s20, h0, h1);
16421 __ Sqdmull(d21, s2, s3);
16422
16423 END();
16424
16425 RUN();
16426 ASSERT_EQUAL_128(0x800100007ffe0002, 0x800100007fffffff, q16);
16427 ASSERT_EQUAL_128(0x800100007ffe0002, 0x800100007fffffff, q17);
16428 ASSERT_EQUAL_128(0x8000000100000000, 0x7fffffffffffffff, q18);
16429 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x8000000100000000, q19);
16430 ASSERT_EQUAL_128(0, 0x7fffffff, q20);
16431 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q21);
16432 TEARDOWN();
16433}
16434
16435
16436TEST(neon_3diff_sqdmlal) {
16437 SETUP();
16438
16439 START();
16440
16441 __ Movi(v0.V2D(), 0x7fff7fff80008000, 0x80007fff7fff8000);
16442 __ Movi(v1.V2D(), 0x80007fff7fff8000, 0x7fff7fff80008000);
16443 __ Movi(v2.V2D(), 0x800000007fffffff, 0x7fffffff80000000);
16444 __ Movi(v3.V2D(), 0x8000000080000000, 0x8000000080000000);
16445
16446 __ Movi(v16.V2D(), 0xffffffff00000001, 0x8fffffff00000001);
16447 __ Movi(v17.V2D(), 0x00000001ffffffff, 0x00000001ffffffff);
16448 __ Movi(v18.V2D(), 0x8000000000000001, 0x0000000000000001);
16449 __ Movi(v19.V2D(), 0xffffffffffffffff, 0x7fffffffffffffff);
16450 __ Movi(v20.V2D(), 0, 0x00000001);
16451 __ Movi(v21.V2D(), 0, 0x00000001);
16452
16453 __ Sqdmlal(v16.V4S(), v0.V4H(), v1.V4H());
16454 __ Sqdmlal2(v17.V4S(), v0.V8H(), v1.V8H());
16455 __ Sqdmlal(v18.V2D(), v2.V2S(), v3.V2S());
16456 __ Sqdmlal2(v19.V2D(), v2.V4S(), v3.V4S());
16457 __ Sqdmlal(s20, h0, h1);
16458 __ Sqdmlal(d21, s2, s3);
16459
16460 END();
16461
16462 RUN();
16463 ASSERT_EQUAL_128(0x8000ffff7ffe0003, 0x800000007fffffff, q16);
16464 ASSERT_EQUAL_128(0x800100017ffe0001, 0x800100017ffffffe, q17);
16465 ASSERT_EQUAL_128(0x8000000000000000, 0x7fffffffffffffff, q18);
16466 ASSERT_EQUAL_128(0x7ffffffffffffffe, 0x00000000ffffffff, q19);
16467 ASSERT_EQUAL_128(0, 0x7fffffff, q20);
16468 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q21);
16469 TEARDOWN();
16470}
16471
16472
16473TEST(neon_3diff_sqdmlsl) {
16474 SETUP();
16475
16476 START();
16477
16478 __ Movi(v0.V2D(), 0x7fff7fff80008000, 0x80007fff7fff8000);
16479 __ Movi(v1.V2D(), 0x80007fff7fff8000, 0x7fff7fff80008000);
16480 __ Movi(v2.V2D(), 0x800000007fffffff, 0x7fffffff80000000);
16481 __ Movi(v3.V2D(), 0x8000000080000000, 0x8000000080000000);
16482
16483 __ Movi(v16.V2D(), 0xffffffff00000001, 0x7ffffffe80000001);
16484 __ Movi(v17.V2D(), 0x00000001ffffffff, 0x7ffffffe00000001);
16485 __ Movi(v18.V2D(), 0x8000000000000001, 0x8000000000000001);
16486 __ Movi(v19.V2D(), 0xfffffffffffffffe, 0x7fffffffffffffff);
16487 __ Movi(v20.V2D(), 0, 0x00000001);
16488 __ Movi(v21.V2D(), 0, 0x00000001);
16489
16490 __ Sqdmlsl(v16.V4S(), v0.V4H(), v1.V4H());
16491 __ Sqdmlsl2(v17.V4S(), v0.V8H(), v1.V8H());
16492 __ Sqdmlsl(v18.V2D(), v2.V2S(), v3.V2S());
16493 __ Sqdmlsl2(v19.V2D(), v2.V4S(), v3.V4S());
16494 __ Sqdmlsl(s20, h0, h1);
16495 __ Sqdmlsl(d21, s2, s3);
16496
16497 END();
16498
16499 RUN();
16500 ASSERT_EQUAL_128(0x7ffeffff8001ffff, 0x7fffffff80000000, q16);
16501 ASSERT_EQUAL_128(0x7fff00018001fffd, 0x7fffffff80000002, q17);
16502 ASSERT_EQUAL_128(0xffffffff00000001, 0x8000000000000000, q18);
16503 ASSERT_EQUAL_128(0x8000000000000000, 0x7fffffffffffffff, q19);
16504 ASSERT_EQUAL_128(0, 0x80000002, q20);
16505 ASSERT_EQUAL_128(0, 0x8000000000000002, q21);
16506
16507 TEARDOWN();
16508}
16509
16510
16511TEST(neon_3diff_mla) {
16512 SETUP();
16513
16514 START();
16515
16516 __ Movi(v0.V2D(), 0xff00aa5500ff55ab, 0xff00aa5500ff55aa);
16517 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16518 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16519 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16520 __ Movi(v18.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16521 __ Movi(v19.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16522
16523 __ Smlal(v16.V8H(), v0.V8B(), v1.V8B());
16524 __ Umlal(v17.V8H(), v0.V8B(), v1.V8B());
16525 __ Smlal2(v18.V8H(), v0.V16B(), v1.V16B());
16526 __ Umlal2(v19.V8H(), v0.V16B(), v1.V16B());
16527
16528 END();
16529
16530 RUN();
16531 ASSERT_EQUAL_128(0x01580304055c2341, 0x090a0ab70d0e0f56, q16);
16532 ASSERT_EQUAL_128(0xaa580304ae5c2341, 0x090a5fb70d0eb856, q17);
16533 ASSERT_EQUAL_128(0x01020304e878ea7a, 0x090a0ab70cb90f00, q18);
16534 ASSERT_EQUAL_128(0x010203043d783f7a, 0x090a5fb761b90f00, q19);
16535 TEARDOWN();
16536}
16537
16538
16539TEST(neon_3diff_mls) {
16540 SETUP();
16541
16542 START();
16543
16544 __ Movi(v0.V2D(), 0xff00aa5500ff55ab, 0xff00aa5500ff55aa);
16545 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16546 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16547 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16548 __ Movi(v18.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16549 __ Movi(v19.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16550
16551 __ Smlsl(v16.V8H(), v0.V8B(), v1.V8B());
16552 __ Umlsl(v17.V8H(), v0.V8B(), v1.V8B());
16553 __ Smlsl2(v18.V8H(), v0.V16B(), v1.V16B());
16554 __ Umlsl2(v19.V8H(), v0.V16B(), v1.V16B());
16555
16556 END();
16557
16558 RUN();
16559 ASSERT_EQUAL_128(0x00ac030404b0eacf, 0x090a0b610d0e0eaa, q16);
16560 ASSERT_EQUAL_128(0x57ac03045bb0eacf, 0x090ab6610d0e65aa, q17);
16561 ASSERT_EQUAL_128(0x0102030421942396, 0x090a0b610d630f00, q18);
16562 ASSERT_EQUAL_128(0x01020304cc94ce96, 0x090ab661b8630f00, q19);
16563 TEARDOWN();
16564}
16565
16566
16567TEST(neon_3same_compare) {
16568 SETUP();
16569
16570 START();
16571
16572 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16573 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16574
16575 __ Cmeq(v16.V16B(), v0.V16B(), v0.V16B());
16576 __ Cmeq(v17.V16B(), v0.V16B(), v1.V16B());
16577 __ Cmge(v18.V16B(), v0.V16B(), v0.V16B());
16578 __ Cmge(v19.V16B(), v0.V16B(), v1.V16B());
16579 __ Cmgt(v20.V16B(), v0.V16B(), v0.V16B());
16580 __ Cmgt(v21.V16B(), v0.V16B(), v1.V16B());
16581 __ Cmhi(v22.V16B(), v0.V16B(), v0.V16B());
16582 __ Cmhi(v23.V16B(), v0.V16B(), v1.V16B());
16583 __ Cmhs(v24.V16B(), v0.V16B(), v0.V16B());
16584 __ Cmhs(v25.V16B(), v0.V16B(), v1.V16B());
16585
16586 END();
16587
16588 RUN();
16589 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q16);
16590 ASSERT_EQUAL_128(0x00ff000000000000, 0x000000ff00000000, q17);
16591 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q18);
16592 ASSERT_EQUAL_128(0x00ff00ffff00ff00, 0xff0000ff0000ff00, q19);
16593 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
16594 ASSERT_EQUAL_128(0x000000ffff00ff00, 0xff0000000000ff00, q21);
16595 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q22);
16596 ASSERT_EQUAL_128(0xff00ff0000ff00ff, 0xff00000000ffff00, q23);
16597 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q24);
16598 ASSERT_EQUAL_128(0xffffff0000ff00ff, 0xff0000ff00ffff00, q25);
16599 TEARDOWN();
16600}
16601
16602
16603TEST(neon_3same_scalar_compare) {
16604 SETUP();
16605
16606 START();
16607
16608 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16609 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16610
16611 __ Cmeq(d16, d0, d0);
16612 __ Cmeq(d17, d0, d1);
16613 __ Cmeq(d18, d1, d0);
16614 __ Cmge(d19, d0, d0);
16615 __ Cmge(d20, d0, d1);
16616 __ Cmge(d21, d1, d0);
16617 __ Cmgt(d22, d0, d0);
16618 __ Cmgt(d23, d0, d1);
16619 __ Cmhi(d24, d0, d0);
16620 __ Cmhi(d25, d0, d1);
16621 __ Cmhs(d26, d0, d0);
16622 __ Cmhs(d27, d0, d1);
16623 __ Cmhs(d28, d1, d0);
16624
16625 END();
16626
16627 RUN();
16628
16629 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q16);
16630 ASSERT_EQUAL_128(0, 0x0000000000000000, q17);
16631 ASSERT_EQUAL_128(0, 0x0000000000000000, q18);
16632 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
16633 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q20);
16634 ASSERT_EQUAL_128(0, 0x0000000000000000, q21);
16635 ASSERT_EQUAL_128(0, 0x0000000000000000, q22);
16636 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q23);
16637 ASSERT_EQUAL_128(0, 0x0000000000000000, q24);
16638 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q25);
16639 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q26);
16640 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q27);
16641 ASSERT_EQUAL_128(0, 0x0000000000000000, q28);
16642
16643 TEARDOWN();
16644}
16645
16646TEST(neon_2regmisc_fcmeq) {
16647 SETUP();
16648
16649 START();
16650
16651 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16652 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16653 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16654 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16655
16656 __ Fcmeq(s16, s0, 0.0);
16657 __ Fcmeq(s17, s1, 0.0);
16658 __ Fcmeq(s18, s2, 0.0);
16659 __ Fcmeq(d19, d0, 0.0);
16660 __ Fcmeq(d20, d1, 0.0);
16661 __ Fcmeq(d21, d2, 0.0);
16662 __ Fcmeq(v22.V2S(), v0.V2S(), 0.0);
16663 __ Fcmeq(v23.V4S(), v1.V4S(), 0.0);
16664 __ Fcmeq(v24.V2D(), v1.V2D(), 0.0);
16665 __ Fcmeq(v25.V2D(), v2.V2D(), 0.0);
16666
16667 END();
16668
16669 RUN();
16670 ASSERT_EQUAL_128(0, 0xffffffff, q16);
16671 ASSERT_EQUAL_128(0, 0x00000000, q17);
16672 ASSERT_EQUAL_128(0, 0x00000000, q18);
16673 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
16674 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16675 ASSERT_EQUAL_128(0, 0x0000000000000000, q21);
16676 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q22);
16677 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16678 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16679 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16680 TEARDOWN();
16681}
16682
16683TEST(neon_2regmisc_fcmge) {
16684 SETUP();
16685
16686 START();
16687
16688 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16689 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16690 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16691 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16692
16693 __ Fcmge(s16, s0, 0.0);
16694 __ Fcmge(s17, s1, 0.0);
16695 __ Fcmge(s18, s2, 0.0);
16696 __ Fcmge(d19, d0, 0.0);
16697 __ Fcmge(d20, d1, 0.0);
16698 __ Fcmge(d21, d3, 0.0);
16699 __ Fcmge(v22.V2S(), v0.V2S(), 0.0);
16700 __ Fcmge(v23.V4S(), v1.V4S(), 0.0);
16701 __ Fcmge(v24.V2D(), v1.V2D(), 0.0);
16702 __ Fcmge(v25.V2D(), v3.V2D(), 0.0);
16703
16704 END();
16705
16706 RUN();
16707 ASSERT_EQUAL_128(0, 0xffffffff, q16);
16708 ASSERT_EQUAL_128(0, 0x00000000, q17);
16709 ASSERT_EQUAL_128(0, 0x00000000, q18);
16710 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
16711 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16712 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
16713 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q22);
16714 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16715 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16716 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
16717 TEARDOWN();
16718}
16719
16720
16721TEST(neon_2regmisc_fcmgt) {
16722 SETUP();
16723
16724 START();
16725
16726 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16727 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16728 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16729 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16730
16731 __ Fcmgt(s16, s0, 0.0);
16732 __ Fcmgt(s17, s1, 0.0);
16733 __ Fcmgt(s18, s2, 0.0);
16734 __ Fcmgt(d19, d0, 0.0);
16735 __ Fcmgt(d20, d1, 0.0);
16736 __ Fcmgt(d21, d3, 0.0);
16737 __ Fcmgt(v22.V2S(), v0.V2S(), 0.0);
16738 __ Fcmgt(v23.V4S(), v1.V4S(), 0.0);
16739 __ Fcmgt(v24.V2D(), v1.V2D(), 0.0);
16740 __ Fcmgt(v25.V2D(), v3.V2D(), 0.0);
16741
16742 END();
16743
16744 RUN();
16745 ASSERT_EQUAL_128(0, 0x00000000, q16);
16746 ASSERT_EQUAL_128(0, 0x00000000, q17);
16747 ASSERT_EQUAL_128(0, 0x00000000, q18);
16748 ASSERT_EQUAL_128(0, 0x0000000000000000, q19);
16749 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16750 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
16751 ASSERT_EQUAL_128(0, 0x0000000000000000, q22);
16752 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16753 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16754 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
16755 TEARDOWN();
16756}
16757
16758TEST(neon_2regmisc_fcmle) {
16759 SETUP();
16760
16761 START();
16762
16763 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16764 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16765 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16766 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16767
16768 __ Fcmle(s16, s0, 0.0);
16769 __ Fcmle(s17, s1, 0.0);
16770 __ Fcmle(s18, s3, 0.0);
16771 __ Fcmle(d19, d0, 0.0);
16772 __ Fcmle(d20, d1, 0.0);
16773 __ Fcmle(d21, d2, 0.0);
16774 __ Fcmle(v22.V2S(), v0.V2S(), 0.0);
16775 __ Fcmle(v23.V4S(), v1.V4S(), 0.0);
16776 __ Fcmle(v24.V2D(), v1.V2D(), 0.0);
16777 __ Fcmle(v25.V2D(), v2.V2D(), 0.0);
16778
16779 END();
16780
16781 RUN();
16782 ASSERT_EQUAL_128(0, 0xffffffff, q16);
16783 ASSERT_EQUAL_128(0, 0x00000000, q17);
16784 ASSERT_EQUAL_128(0, 0x00000000, q18);
16785 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
16786 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16787 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
16788 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q22);
16789 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16790 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16791 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
16792 TEARDOWN();
16793}
16794
16795
16796TEST(neon_2regmisc_fcmlt) {
16797 SETUP();
16798
16799 START();
16800
16801 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16802 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16803 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16804 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16805
16806 __ Fcmlt(s16, s0, 0.0);
16807 __ Fcmlt(s17, s1, 0.0);
16808 __ Fcmlt(s18, s3, 0.0);
16809 __ Fcmlt(d19, d0, 0.0);
16810 __ Fcmlt(d20, d1, 0.0);
16811 __ Fcmlt(d21, d2, 0.0);
16812 __ Fcmlt(v22.V2S(), v0.V2S(), 0.0);
16813 __ Fcmlt(v23.V4S(), v1.V4S(), 0.0);
16814 __ Fcmlt(v24.V2D(), v1.V2D(), 0.0);
16815 __ Fcmlt(v25.V2D(), v2.V2D(), 0.0);
16816
16817 END();
16818
16819 RUN();
16820 ASSERT_EQUAL_128(0, 0x00000000, q16);
16821 ASSERT_EQUAL_128(0, 0x00000000, q17);
16822 ASSERT_EQUAL_128(0, 0x00000000, q18);
16823 ASSERT_EQUAL_128(0, 0x0000000000000000, q19);
16824 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16825 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
16826 ASSERT_EQUAL_128(0, 0x0000000000000000, q22);
16827 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16828 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16829 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
16830 TEARDOWN();
16831}
16832
16833TEST(neon_2regmisc_cmeq) {
16834 SETUP();
16835
16836 START();
16837
16838 __ Movi(v0.V2D(), 0x0001000200030004, 0x0000000000000000);
16839 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
16840
16841 __ Cmeq(v16.V8B(), v1.V8B(), 0);
16842 __ Cmeq(v17.V16B(), v1.V16B(), 0);
16843 __ Cmeq(v18.V4H(), v1.V4H(), 0);
16844 __ Cmeq(v19.V8H(), v1.V8H(), 0);
16845 __ Cmeq(v20.V2S(), v0.V2S(), 0);
16846 __ Cmeq(v21.V4S(), v0.V4S(), 0);
16847 __ Cmeq(d22, d0, 0);
16848 __ Cmeq(d23, d1, 0);
16849 __ Cmeq(v24.V2D(), v0.V2D(), 0);
16850
16851 END();
16852
16853 RUN();
16854 ASSERT_EQUAL_128(0x0000000000000000, 0xffff00000000ff00, q16);
16855 ASSERT_EQUAL_128(0xffff0000000000ff, 0xffff00000000ff00, q17);
16856 ASSERT_EQUAL_128(0x0000000000000000, 0xffff000000000000, q18);
16857 ASSERT_EQUAL_128(0xffff000000000000, 0xffff000000000000, q19);
16858 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q20);
16859 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q21);
16860 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
16861 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16862 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
16863 TEARDOWN();
16864}
16865
16866
16867TEST(neon_2regmisc_cmge) {
16868 SETUP();
16869
16870 START();
16871
16872 __ Movi(v0.V2D(), 0xff01000200030004, 0x0000000000000000);
16873 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
16874
16875 __ Cmge(v16.V8B(), v1.V8B(), 0);
16876 __ Cmge(v17.V16B(), v1.V16B(), 0);
16877 __ Cmge(v18.V4H(), v1.V4H(), 0);
16878 __ Cmge(v19.V8H(), v1.V8H(), 0);
16879 __ Cmge(v20.V2S(), v0.V2S(), 0);
16880 __ Cmge(v21.V4S(), v0.V4S(), 0);
16881 __ Cmge(d22, d0, 0);
16882 __ Cmge(d23, d1, 0);
16883 __ Cmge(v24.V2D(), v0.V2D(), 0);
16884
16885 END();
16886
16887 RUN();
16888 ASSERT_EQUAL_128(0x0000000000000000, 0xffff00ffffffff00, q16);
16889 ASSERT_EQUAL_128(0xffffff0000ff00ff, 0xffff00ffffffff00, q17);
16890 ASSERT_EQUAL_128(0x0000000000000000, 0xffff0000ffffffff, q18);
16891 ASSERT_EQUAL_128(0xffffffff00000000, 0xffff0000ffffffff, q19);
16892 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q20);
16893 ASSERT_EQUAL_128(0x00000000ffffffff, 0xffffffffffffffff, q21);
16894 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
16895 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q23);
16896 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
16897 TEARDOWN();
16898}
16899
16900
16901TEST(neon_2regmisc_cmlt) {
16902 SETUP();
16903
16904 START();
16905
16906 __ Movi(v0.V2D(), 0x0001000200030004, 0xff00000000000000);
16907 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
16908
16909 __ Cmlt(v16.V8B(), v1.V8B(), 0);
16910 __ Cmlt(v17.V16B(), v1.V16B(), 0);
16911 __ Cmlt(v18.V4H(), v1.V4H(), 0);
16912 __ Cmlt(v19.V8H(), v1.V8H(), 0);
16913 __ Cmlt(v20.V2S(), v1.V2S(), 0);
16914 __ Cmlt(v21.V4S(), v1.V4S(), 0);
16915 __ Cmlt(d22, d0, 0);
16916 __ Cmlt(d23, d1, 0);
16917 __ Cmlt(v24.V2D(), v0.V2D(), 0);
16918
16919 END();
16920
16921 RUN();
16922 ASSERT_EQUAL_128(0x0000000000000000, 0x0000ff00000000ff, q16);
16923 ASSERT_EQUAL_128(0x000000ffff00ff00, 0x0000ff00000000ff, q17);
16924 ASSERT_EQUAL_128(0x0000000000000000, 0x0000ffff00000000, q18);
16925 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000ffff00000000, q19);
16926 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
16927 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000000000000000, q21);
16928 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
16929 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16930 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
16931 TEARDOWN();
16932}
16933
16934
16935TEST(neon_2regmisc_cmle) {
16936 SETUP();
16937
16938 START();
16939
16940 __ Movi(v0.V2D(), 0x0001000200030004, 0x0000000000000000);
16941 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
16942
16943 __ Cmle(v16.V8B(), v1.V8B(), 0);
16944 __ Cmle(v17.V16B(), v1.V16B(), 0);
16945 __ Cmle(v18.V4H(), v1.V4H(), 0);
16946 __ Cmle(v19.V8H(), v1.V8H(), 0);
16947 __ Cmle(v20.V2S(), v1.V2S(), 0);
16948 __ Cmle(v21.V4S(), v1.V4S(), 0);
16949 __ Cmle(d22, d0, 0);
16950 __ Cmle(d23, d1, 0);
16951 __ Cmle(v24.V2D(), v0.V2D(), 0);
16952
16953 END();
16954
16955 RUN();
16956 ASSERT_EQUAL_128(0x0000000000000000, 0xffffff000000ffff, q16);
16957 ASSERT_EQUAL_128(0xffff00ffff00ffff, 0xffffff000000ffff, q17);
16958 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffff00000000, q18);
16959 ASSERT_EQUAL_128(0xffff0000ffffffff, 0xffffffff00000000, q19);
16960 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
16961 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000000000000000, q21);
16962 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
16963 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16964 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
16965 TEARDOWN();
16966}
16967
16968
16969TEST(neon_2regmisc_cmgt) {
16970 SETUP();
16971
16972 START();
16973
16974 __ Movi(v0.V2D(), 0x0001000200030004, 0x0000000000000000);
16975 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
16976
16977 __ Cmgt(v16.V8B(), v1.V8B(), 0);
16978 __ Cmgt(v17.V16B(), v1.V16B(), 0);
16979 __ Cmgt(v18.V4H(), v1.V4H(), 0);
16980 __ Cmgt(v19.V8H(), v1.V8H(), 0);
16981 __ Cmgt(v20.V2S(), v0.V2S(), 0);
16982 __ Cmgt(v21.V4S(), v0.V4S(), 0);
16983 __ Cmgt(d22, d0, 0);
16984 __ Cmgt(d23, d1, 0);
16985 __ Cmgt(v24.V2D(), v0.V2D(), 0);
16986
16987 END();
16988
16989 RUN();
16990 ASSERT_EQUAL_128(0x0000000000000000, 0x000000ffffff0000, q16);
16991 ASSERT_EQUAL_128(0x0000ff0000ff0000, 0x000000ffffff0000, q17);
16992 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q18);
16993 ASSERT_EQUAL_128(0x0000ffff00000000, 0x00000000ffffffff, q19);
16994 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
16995 ASSERT_EQUAL_128(0xffffffffffffffff, 0x0000000000000000, q21);
16996 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q22);
16997 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q23);
16998 ASSERT_EQUAL_128(0xffffffffffffffff, 0x0000000000000000, q24);
16999 TEARDOWN();
17000}
17001
17002
17003TEST(neon_2regmisc_neg) {
17004 SETUP();
17005
17006 START();
17007
17008 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17009 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17010 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17011 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17012 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17013
17014 __ Neg(v16.V8B(), v0.V8B());
17015 __ Neg(v17.V16B(), v0.V16B());
17016 __ Neg(v18.V4H(), v1.V4H());
17017 __ Neg(v19.V8H(), v1.V8H());
17018 __ Neg(v20.V2S(), v2.V2S());
17019 __ Neg(v21.V4S(), v2.V4S());
17020 __ Neg(d22, d3);
17021 __ Neg(v23.V2D(), v3.V2D());
17022 __ Neg(v24.V2D(), v4.V2D());
17023
17024 END();
17025
17026 RUN();
17027 ASSERT_EQUAL_128(0x0000000000000000, 0x807f0100ff81807f, q16);
17028 ASSERT_EQUAL_128(0x81ff00017f8081ff, 0x807f0100ff81807f, q17);
17029 ASSERT_EQUAL_128(0x0000000000000000, 0x00010000ffff8001, q18);
17030 ASSERT_EQUAL_128(0x80007fff00010000, 0x00010000ffff8001, q19);
17031 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000001, q20);
17032 ASSERT_EQUAL_128(0x8000000000000001, 0x0000000080000001, q21);
17033 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000000001, q22);
17034 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x8000000000000001, q23);
17035 ASSERT_EQUAL_128(0x8000000000000000, 0x0000000000000000, q24);
17036
17037 TEARDOWN();
17038}
17039
17040
17041TEST(neon_2regmisc_sqneg) {
17042 SETUP();
17043
17044 START();
17045
17046 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17047 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17048 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17049 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17050 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17051
17052 __ Sqneg(v16.V8B(), v0.V8B());
17053 __ Sqneg(v17.V16B(), v0.V16B());
17054 __ Sqneg(v18.V4H(), v1.V4H());
17055 __ Sqneg(v19.V8H(), v1.V8H());
17056 __ Sqneg(v20.V2S(), v2.V2S());
17057 __ Sqneg(v21.V4S(), v2.V4S());
17058 __ Sqneg(v22.V2D(), v3.V2D());
17059 __ Sqneg(v23.V2D(), v4.V2D());
17060
17061 __ Sqneg(b24, b0);
17062 __ Sqneg(h25, h1);
17063 __ Sqneg(s26, s2);
17064 __ Sqneg(d27, d3);
17065
17066 END();
17067
17068 RUN();
17069 ASSERT_EQUAL_128(0x0000000000000000, 0x7f7f0100ff817f7f, q16);
17070 ASSERT_EQUAL_128(0x81ff00017f7f81ff, 0x7f7f0100ff817f7f, q17);
17071 ASSERT_EQUAL_128(0x0000000000000000, 0x00010000ffff8001, q18);
17072 ASSERT_EQUAL_128(0x7fff7fff00010000, 0x00010000ffff8001, q19);
17073 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000001, q20);
17074 ASSERT_EQUAL_128(0x7fffffff00000001, 0x0000000080000001, q21);
17075 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x8000000000000001, q22);
17076 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x0000000000000000, q23);
17077
17078 ASSERT_EQUAL_128(0, 0x7f, q24);
17079 ASSERT_EQUAL_128(0, 0x8001, q25);
17080 ASSERT_EQUAL_128(0, 0x80000001, q26);
17081 ASSERT_EQUAL_128(0, 0x8000000000000001, q27);
17082
17083 TEARDOWN();
17084}
17085
17086
17087TEST(neon_2regmisc_abs) {
17088 SETUP();
17089
17090 START();
17091
17092 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17093 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17094 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17095 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17096 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17097
17098 __ Abs(v16.V8B(), v0.V8B());
17099 __ Abs(v17.V16B(), v0.V16B());
17100 __ Abs(v18.V4H(), v1.V4H());
17101 __ Abs(v19.V8H(), v1.V8H());
17102 __ Abs(v20.V2S(), v2.V2S());
17103 __ Abs(v21.V4S(), v2.V4S());
17104 __ Abs(d22, d3);
17105 __ Abs(v23.V2D(), v3.V2D());
17106 __ Abs(v24.V2D(), v4.V2D());
17107
17108 END();
17109
17110 RUN();
17111 ASSERT_EQUAL_128(0x0000000000000000, 0x807f0100017f807f, q16);
17112 ASSERT_EQUAL_128(0x7f0100017f807f01, 0x807f0100017f807f, q17);
17113 ASSERT_EQUAL_128(0x0000000000000000, 0x0001000000017fff, q18);
17114 ASSERT_EQUAL_128(0x80007fff00010000, 0x0001000000017fff, q19);
17115 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
17116 ASSERT_EQUAL_128(0x8000000000000001, 0x000000007fffffff, q21);
17117 ASSERT_EQUAL_128(0x0000000000000000, 0x7fffffffffffffff, q22);
17118 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x7fffffffffffffff, q23);
17119 ASSERT_EQUAL_128(0x8000000000000000, 0x0000000000000000, q24);
17120
17121 TEARDOWN();
17122}
17123
17124
17125TEST(neon_2regmisc_sqabs) {
17126 SETUP();
17127
17128 START();
17129
17130 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17131 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17132 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17133 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17134 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17135
17136 __ Sqabs(v16.V8B(), v0.V8B());
17137 __ Sqabs(v17.V16B(), v0.V16B());
17138 __ Sqabs(v18.V4H(), v1.V4H());
17139 __ Sqabs(v19.V8H(), v1.V8H());
17140 __ Sqabs(v20.V2S(), v2.V2S());
17141 __ Sqabs(v21.V4S(), v2.V4S());
17142 __ Sqabs(v22.V2D(), v3.V2D());
17143 __ Sqabs(v23.V2D(), v4.V2D());
17144
17145 __ Sqabs(b24, b0);
17146 __ Sqabs(h25, h1);
17147 __ Sqabs(s26, s2);
17148 __ Sqabs(d27, d3);
17149
17150 END();
17151
17152 RUN();
17153 ASSERT_EQUAL_128(0x0000000000000000, 0x7f7f0100017f7f7f, q16);
17154 ASSERT_EQUAL_128(0x7f0100017f7f7f01, 0x7f7f0100017f7f7f, q17);
17155 ASSERT_EQUAL_128(0x0000000000000000, 0x0001000000017fff, q18);
17156 ASSERT_EQUAL_128(0x7fff7fff00010000, 0x0001000000017fff, q19);
17157 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
17158 ASSERT_EQUAL_128(0x7fffffff00000001, 0x000000007fffffff, q21);
17159 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x7fffffffffffffff, q22);
17160 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x0000000000000000, q23);
17161
17162 ASSERT_EQUAL_128(0, 0x7f, q24);
17163 ASSERT_EQUAL_128(0, 0x7fff, q25);
17164 ASSERT_EQUAL_128(0, 0x7fffffff, q26);
17165 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q27);
17166
17167 TEARDOWN();
17168}
17169
17170TEST(neon_2regmisc_suqadd) {
17171 SETUP();
17172
17173 START();
17174
17175 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17176 __ Movi(v1.V2D(), 0x017f8081ff00017f, 0x010080ff7f0180ff);
17177
17178 __ Movi(v2.V2D(), 0x80008001ffff0000, 0xffff000000017ffd);
17179 __ Movi(v3.V2D(), 0xffff000080008001, 0x00017fffffff0001);
17180
17181 __ Movi(v4.V2D(), 0x80000000fffffffe, 0xfffffff17ffffffe);
17182 __ Movi(v5.V2D(), 0xffffffff80000000, 0x7fffffff00000002);
17183
17184 __ Movi(v6.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17185 __ Movi(v7.V2D(), 0x8000000000000000, 0x8000000000000002);
17186
17187 __ Mov(v16.V2D(), v0.V2D());
17188 __ Mov(v17.V2D(), v0.V2D());
17189 __ Mov(v18.V2D(), v2.V2D());
17190 __ Mov(v19.V2D(), v2.V2D());
17191 __ Mov(v20.V2D(), v4.V2D());
17192 __ Mov(v21.V2D(), v4.V2D());
17193 __ Mov(v22.V2D(), v6.V2D());
17194
17195 __ Mov(v23.V2D(), v0.V2D());
17196 __ Mov(v24.V2D(), v2.V2D());
17197 __ Mov(v25.V2D(), v4.V2D());
17198 __ Mov(v26.V2D(), v6.V2D());
17199
17200 __ Suqadd(v16.V8B(), v1.V8B());
17201 __ Suqadd(v17.V16B(), v1.V16B());
17202 __ Suqadd(v18.V4H(), v3.V4H());
17203 __ Suqadd(v19.V8H(), v3.V8H());
17204 __ Suqadd(v20.V2S(), v5.V2S());
17205 __ Suqadd(v21.V4S(), v5.V4S());
17206 __ Suqadd(v22.V2D(), v7.V2D());
17207
17208 __ Suqadd(b23, b1);
17209 __ Suqadd(h24, h3);
17210 __ Suqadd(s25, s5);
17211 __ Suqadd(d26, d7);
17212
17213 END();
17214
17215 RUN();
17216 ASSERT_EQUAL_128(0x0000000000000000, 0x81817f7f7f7f007f, q16);
17217 ASSERT_EQUAL_128(0x7f7f7f7f7f807f7f, 0x81817f7f7f7f007f, q17);
17218 ASSERT_EQUAL_128(0x0000000000000000, 0x00007fff7fff7ffe, q18);
17219 ASSERT_EQUAL_128(0x7fff80017fff7fff, 0x00007fff7fff7ffe, q19);
17220 ASSERT_EQUAL_128(0x0000000000000000, 0x7ffffff07fffffff, q20);
17221 ASSERT_EQUAL_128(0x7fffffff7ffffffe, 0x7ffffff07fffffff, q21);
17222 ASSERT_EQUAL_128(0x0000000000000001, 0x7fffffffffffffff, q22);
17223
17224 ASSERT_EQUAL_128(0, 0x7f, q23);
17225 ASSERT_EQUAL_128(0, 0x7ffe, q24);
17226 ASSERT_EQUAL_128(0, 0x7fffffff, q25);
17227 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q26);
17228 TEARDOWN();
17229}
17230
17231TEST(neon_2regmisc_usqadd) {
17232 SETUP();
17233
17234 START();
17235
17236 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f7ffe);
17237 __ Movi(v1.V2D(), 0x017f8081ff00017f, 0x010080ff7f018002);
17238
17239 __ Movi(v2.V2D(), 0x80008001fffe0000, 0xffff000000017ffd);
17240 __ Movi(v3.V2D(), 0xffff000000028001, 0x00017fffffff0001);
17241
17242 __ Movi(v4.V2D(), 0x80000000fffffffe, 0x00000001fffffffe);
17243 __ Movi(v5.V2D(), 0xffffffff80000000, 0xfffffffe00000002);
17244
17245 __ Movi(v6.V2D(), 0x8000000000000002, 0x7fffffffffffffff);
17246 __ Movi(v7.V2D(), 0x7fffffffffffffff, 0x8000000000000000);
17247
17248 __ Mov(v16.V2D(), v0.V2D());
17249 __ Mov(v17.V2D(), v0.V2D());
17250 __ Mov(v18.V2D(), v2.V2D());
17251 __ Mov(v19.V2D(), v2.V2D());
17252 __ Mov(v20.V2D(), v4.V2D());
17253 __ Mov(v21.V2D(), v4.V2D());
17254 __ Mov(v22.V2D(), v6.V2D());
17255
17256 __ Mov(v23.V2D(), v0.V2D());
17257 __ Mov(v24.V2D(), v2.V2D());
17258 __ Mov(v25.V2D(), v4.V2D());
17259 __ Mov(v26.V2D(), v6.V2D());
17260
17261 __ Usqadd(v16.V8B(), v1.V8B());
17262 __ Usqadd(v17.V16B(), v1.V16B());
17263 __ Usqadd(v18.V4H(), v3.V4H());
17264 __ Usqadd(v19.V8H(), v3.V8H());
17265 __ Usqadd(v20.V2S(), v5.V2S());
17266 __ Usqadd(v21.V4S(), v5.V4S());
17267 __ Usqadd(v22.V2D(), v7.V2D());
17268
17269 __ Usqadd(b23, b1);
17270 __ Usqadd(h24, h3);
17271 __ Usqadd(s25, s5);
17272 __ Usqadd(d26, d7);
17273
17274 END();
17275
17276 RUN();
17277 ASSERT_EQUAL_128(0x0000000000000000, 0x81817f00808000ff, q16);
17278 ASSERT_EQUAL_128(0x8080008080808080, 0x81817f00808000ff, q17);
17279 ASSERT_EQUAL_128(0x0000000000000000, 0xffff7fff00007ffe, q18);
17280 ASSERT_EQUAL_128(0x7fff8001ffff0000, 0xffff7fff00007ffe, q19);
17281 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q20);
17282 ASSERT_EQUAL_128(0x7fffffff7ffffffe, 0x00000000ffffffff, q21);
17283 ASSERT_EQUAL_128(0xffffffffffffffff, 0x0000000000000000, q22);
17284
17285 ASSERT_EQUAL_128(0, 0xff, q23);
17286 ASSERT_EQUAL_128(0, 0x7ffe, q24);
17287 ASSERT_EQUAL_128(0, 0xffffffff, q25);
17288 ASSERT_EQUAL_128(0, 0x0000000000000000, q26);
17289 TEARDOWN();
17290}
17291
17292
17293TEST(system_sys) {
17294 SETUP();
17295 const char* msg = "SYS test!";
17296 uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
17297
17298 START();
17299 __ Mov(x4, msg_addr);
17300 __ Sys(3, 0x7, 0x5, 1, x4);
17301 __ Mov(x3, x4);
17302 __ Sys(3, 0x7, 0xa, 1, x3);
17303 __ Mov(x2, x3);
17304 __ Sys(3, 0x7, 0xb, 1, x2);
17305 __ Mov(x1, x2);
17306 __ Sys(3, 0x7, 0xe, 1, x1);
17307 // TODO: Add tests to check ZVA equivalent.
17308 END();
17309
17310 RUN();
17311
17312 TEARDOWN();
17313}
17314
17315
17316TEST(system_ic) {
17317 SETUP();
17318 const char* msg = "IC test!";
17319 uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
17320
17321 START();
17322 __ Mov(x11, msg_addr);
17323 __ Ic(IVAU, x11);
17324 END();
17325
17326 RUN();
17327
17328 TEARDOWN();
17329}
17330
17331
17332TEST(system_dc) {
17333 SETUP();
17334 const char* msg = "DC test!";
17335 uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
17336
17337 START();
17338 __ Mov(x20, msg_addr);
17339 __ Dc(CVAC, x20);
17340 __ Mov(x21, x20);
17341 __ Dc(CVAU, x21);
17342 __ Mov(x22, x21);
17343 __ Dc(CIVAC, x22);
17344 // TODO: Add tests to check ZVA.
17345 END();
17346
17347 RUN();
17348
17349 TEARDOWN();
17350}
17351
17352
17353TEST(neon_2regmisc_xtn) {
17354 SETUP();
17355
17356 START();
17357
17358 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17359 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17360 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17361 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17362 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17363
17364 __ Xtn(v16.V8B(), v0.V8H());
17365 __ Xtn2(v16.V16B(), v1.V8H());
17366 __ Xtn(v17.V4H(), v1.V4S());
17367 __ Xtn2(v17.V8H(), v2.V4S());
17368 __ Xtn(v18.V2S(), v3.V2D());
17369 __ Xtn2(v18.V4S(), v4.V2D());
17370
17371 END();
17372
17373 RUN();
17374 ASSERT_EQUAL_128(0x0001ff00ff0001ff, 0x01ff800181007f81, q16);
17375 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x8001000000007fff, q17);
17376 ASSERT_EQUAL_128(0x0000000000000000, 0x00000001ffffffff, q18);
17377 TEARDOWN();
17378}
17379
17380
17381TEST(neon_2regmisc_sqxtn) {
17382 SETUP();
17383
17384 START();
17385
17386 __ Movi(v0.V2D(), 0x7f01007a81807f01, 0x8081ff00017f8081);
17387 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17388 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17389 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17390 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17391
17392 __ Sqxtn(v16.V8B(), v0.V8H());
17393 __ Sqxtn2(v16.V16B(), v1.V8H());
17394 __ Sqxtn(v17.V4H(), v1.V4S());
17395 __ Sqxtn2(v17.V8H(), v2.V4S());
17396 __ Sqxtn(v18.V2S(), v3.V2D());
17397 __ Sqxtn2(v18.V4S(), v4.V2D());
17398 __ Sqxtn(b19, h0);
17399 __ Sqxtn(h20, s0);
17400 __ Sqxtn(s21, d0);
17401
17402 END();
17403
17404 RUN();
17405 ASSERT_EQUAL_128(0x8080ff00ff00017f, 0x7f7a807f80807f80, q16);
17406 ASSERT_EQUAL_128(0x8000ffff00007fff, 0x8000800080007fff, q17);
17407 ASSERT_EQUAL_128(0x8000000000000000, 0x800000007fffffff, q18);
17408 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000080, q19);
17409 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000007fff, q20);
17410 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000000, q21);
17411 TEARDOWN();
17412}
17413
17414
17415TEST(neon_2regmisc_uqxtn) {
17416 SETUP();
17417
17418 START();
17419
17420 __ Movi(v0.V2D(), 0x7f01007a81807f01, 0x8081ff00017f8081);
17421 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17422 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17423 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17424 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17425
17426 __ Uqxtn(v16.V8B(), v0.V8H());
17427 __ Uqxtn2(v16.V16B(), v1.V8H());
17428 __ Uqxtn(v17.V4H(), v1.V4S());
17429 __ Uqxtn2(v17.V8H(), v2.V4S());
17430 __ Uqxtn(v18.V2S(), v3.V2D());
17431 __ Uqxtn2(v18.V4S(), v4.V2D());
17432 __ Uqxtn(b19, h0);
17433 __ Uqxtn(h20, s0);
17434 __ Uqxtn(s21, d0);
17435
17436 END();
17437
17438 RUN();
17439 ASSERT_EQUAL_128(0xffffff00ff0001ff, 0xff7affffffffffff, q16);
17440 ASSERT_EQUAL_128(0xffffffff0000ffff, 0xffffffffffffffff, q17);
17441 ASSERT_EQUAL_128(0xffffffff00000000, 0xffffffffffffffff, q18);
17442 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000000000ff, q19);
17443 ASSERT_EQUAL_128(0x0000000000000000, 0x000000000000ffff, q20);
17444 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q21);
17445 TEARDOWN();
17446}
17447
17448
17449TEST(neon_2regmisc_sqxtun) {
17450 SETUP();
17451
17452 START();
17453
17454 __ Movi(v0.V2D(), 0x7f01007a81807f01, 0x8081ff00017f8081);
17455 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17456 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17457 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17458 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17459
17460 __ Sqxtun(v16.V8B(), v0.V8H());
17461 __ Sqxtun2(v16.V16B(), v1.V8H());
17462 __ Sqxtun(v17.V4H(), v1.V4S());
17463 __ Sqxtun2(v17.V8H(), v2.V4S());
17464 __ Sqxtun(v18.V2S(), v3.V2D());
17465 __ Sqxtun2(v18.V4S(), v4.V2D());
17466 __ Sqxtun(b19, h0);
17467 __ Sqxtun(h20, s0);
17468 __ Sqxtun(s21, d0);
17469
17470 END();
17471
17472 RUN();
17473 ASSERT_EQUAL_128(0x00000000000001ff, 0xff7a00ff0000ff00, q16);
17474 ASSERT_EQUAL_128(0x000000000000ffff, 0x000000000000ffff, q17);
17475 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q18);
17476 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q19);
17477 ASSERT_EQUAL_128(0x0000000000000000, 0x000000000000ffff, q20);
17478 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q21);
17479 TEARDOWN();
17480}
17481
17482TEST(neon_3same_and) {
17483 SETUP();
17484
17485 START();
17486
17487 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17488 __ Movi(v1.V2D(), 0x00aa55aaff55ff00, 0xaa55ff00555500ff);
17489
17490 __ And(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17491 __ And(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17492 __ And(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17493 __ And(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17494 END();
17495
17496 RUN();
17497 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q16);
17498 ASSERT_EQUAL_128(0x0000000000555500, 0xaa00aa00005500aa, q17);
17499 ASSERT_EQUAL_128(0, 0xff00aa5500ff55aa, q24);
17500 ASSERT_EQUAL_128(0, 0xaa00aa00005500aa, q25);
17501 TEARDOWN();
17502}
17503
17504TEST(neon_3same_bic) {
17505 SETUP();
17506
17507 START();
17508
17509 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17510 __ Movi(v1.V2D(), 0x00ffaa00aa55aaff, 0xffff005500ff00ff);
17511
17512 __ Bic(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17513 __ Bic(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17514 __ Bic(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17515 __ Bic(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17516 END();
17517
17518 RUN();
17519 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q16);
17520 ASSERT_EQUAL_128(0xff00005500aa5500, 0x0000aa0000005500, q17);
17521 ASSERT_EQUAL_128(0, 0x0000000000000000, q24);
17522 ASSERT_EQUAL_128(0, 0x0000aa0000005500, q25);
17523 TEARDOWN();
17524}
17525
17526TEST(neon_3same_orr) {
17527 SETUP();
17528
17529 START();
17530
17531 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17532 __ Movi(v1.V2D(), 0x00aa55aaff55ff00, 0xaa55ff00555500ff);
17533
17534 __ Orr(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17535 __ Orr(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17536 __ Orr(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17537 __ Orr(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17538 END();
17539
17540 RUN();
17541 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q16);
17542 ASSERT_EQUAL_128(0xffaaffffffffffaa, 0xff55ff5555ff55ff, q17);
17543 ASSERT_EQUAL_128(0, 0xff00aa5500ff55aa, q24);
17544 ASSERT_EQUAL_128(0, 0xff55ff5555ff55ff, q25);
17545 TEARDOWN();
17546}
17547
17548TEST(neon_3same_mov) {
17549 SETUP();
17550
17551 START();
17552
17553 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17554
17555 __ Mov(v16.V16B(), v0.V16B());
17556 __ Mov(v17.V8H(), v0.V8H());
17557 __ Mov(v18.V4S(), v0.V4S());
17558 __ Mov(v19.V2D(), v0.V2D());
17559
17560 __ Mov(v24.V8B(), v0.V8B());
17561 __ Mov(v25.V4H(), v0.V4H());
17562 __ Mov(v26.V2S(), v0.V2S());
17563 END();
17564
17565 RUN();
17566
17567 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q16);
17568 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q17);
17569 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q18);
17570 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q19);
17571
17572 ASSERT_EQUAL_128(0x0, 0xff00aa5500ff55aa, q24);
17573 ASSERT_EQUAL_128(0x0, 0xff00aa5500ff55aa, q25);
17574 ASSERT_EQUAL_128(0x0, 0xff00aa5500ff55aa, q26);
17575
17576 TEARDOWN();
17577}
17578
17579TEST(neon_3same_orn) {
17580 SETUP();
17581
17582 START();
17583
17584 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17585 __ Movi(v1.V2D(), 0x00aa55aaff55ff00, 0xaa55ff00555500ff);
17586
17587 __ Orn(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17588 __ Orn(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17589 __ Orn(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17590 __ Orn(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17591 END();
17592
17593 RUN();
17594 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q16);
17595 ASSERT_EQUAL_128(0xff55aa5500ff55ff, 0xffaaaaffaaffffaa, q17);
17596 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q24);
17597 ASSERT_EQUAL_128(0, 0xffaaaaffaaffffaa, q25);
17598 TEARDOWN();
17599}
17600
17601TEST(neon_3same_eor) {
17602 SETUP();
17603
17604 START();
17605
17606 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17607 __ Movi(v1.V2D(), 0x00ffaa00aa55aaff, 0xffff005500ff00ff);
17608
17609 __ Eor(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17610 __ Eor(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17611 __ Eor(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17612 __ Eor(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17613 END();
17614
17615 RUN();
17616 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q16);
17617 ASSERT_EQUAL_128(0xffff0055aaaaff55, 0x00ffaa0000005555, q17);
17618 ASSERT_EQUAL_128(0, 0x0000000000000000, q24);
17619 ASSERT_EQUAL_128(0, 0x00ffaa0000005555, q25);
17620 TEARDOWN();
17621}
17622
17623TEST(neon_3same_bif) {
17624 SETUP();
17625
17626 START();
17627
17628 __ Movi(v16.V2D(), 0xffff0000ff00ffff, 0xffff00000000aaaa);
17629 __ Movi(v0.V2D(), 0xff00ff00ff005555, 0xaaaa5555aaaaaaaa);
17630 __ Movi(v1.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
17631
17632 __ Movi(v17.V2D(), 0x5555aa55cccccccc, 0x33333333f0f0f0f0);
17633 __ Movi(v2.V2D(), 0x555555aaff00ff00, 0xff00ff00ff00ff00);
17634 __ Movi(v3.V2D(), 0xaa55aa5500ffff00, 0x00ffff0000ffff00);
17635
17636 __ Movi(v18.V2D(), 0, 0xf0f0f0f00f0f0f0f);
17637 __ Movi(v4.V2D(), 0, 0xf0f0f0f0f0f0f0f0);
17638 __ Movi(v5.V2D(), 0, 0x00ffff0000ffff00);
17639
17640 __ Bif(v16.V16B(), v0.V16B(), v1.V16B());
17641 __ Bif(v17.V16B(), v2.V16B(), v3.V16B());
17642 __ Bif(v18.V8B(), v4.V8B(), v5.V8B());
17643 END();
17644
17645 RUN();
17646
17647 ASSERT_EQUAL_128(0xffffff00ff0055ff, 0xffaa0055aa00aaaa, q16);
17648 ASSERT_EQUAL_128(0x5555ffffffcccc00, 0xff333300fff0f000, q17);
17649 ASSERT_EQUAL_128(0, 0xf0f0f0f0f00f0ff0, q18);
17650 TEARDOWN();
17651}
17652
17653TEST(neon_3same_bit) {
17654 SETUP();
17655
17656 START();
17657
17658 __ Movi(v16.V2D(), 0xffff0000ff00ffff, 0xffff00000000aaaa);
17659 __ Movi(v0.V2D(), 0xff00ff00ff005555, 0xaaaa5555aaaaaaaa);
17660 __ Movi(v1.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
17661
17662 __ Movi(v17.V2D(), 0x5555aa55cccccccc, 0x33333333f0f0f0f0);
17663 __ Movi(v2.V2D(), 0x555555aaff00ff00, 0xff00ff00ff00ff00);
17664 __ Movi(v3.V2D(), 0xaa55aa5500ffff00, 0x00ffff0000ffff00);
17665
17666 __ Movi(v18.V2D(), 0, 0xf0f0f0f00f0f0f0f);
17667 __ Movi(v4.V2D(), 0, 0xf0f0f0f0f0f0f0f0);
17668 __ Movi(v5.V2D(), 0, 0x00ffff0000ffff00);
17669
17670 __ Bit(v16.V16B(), v0.V16B(), v1.V16B());
17671 __ Bit(v17.V16B(), v2.V16B(), v3.V16B());
17672 __ Bit(v18.V8B(), v4.V8B(), v5.V8B());
17673 END();
17674
17675 RUN();
17676
17677 ASSERT_EQUAL_128(0xff000000ff00ff55, 0xaaff550000aaaaaa, q16);
17678 ASSERT_EQUAL_128(0x55550000cc00ffcc, 0x3300ff33f000fff0, q17);
17679 ASSERT_EQUAL_128(0, 0xf0f0f0f00ff0f00f, q18);
17680 TEARDOWN();
17681}
17682
17683TEST(neon_3same_bsl) {
17684 SETUP();
17685
17686 START();
17687
17688 __ Movi(v16.V2D(), 0xffff0000ff00ffff, 0xffff00000000aaaa);
17689 __ Movi(v0.V2D(), 0xff00ff00ff005555, 0xaaaa5555aaaaaaaa);
17690 __ Movi(v1.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
17691
17692 __ Movi(v17.V2D(), 0x5555aa55cccccccc, 0x33333333f0f0f0f0);
17693 __ Movi(v2.V2D(), 0x555555aaff00ff00, 0xff00ff00ff00ff00);
17694 __ Movi(v3.V2D(), 0xaa55aa5500ffff00, 0x00ffff0000ffff00);
17695
17696 __ Movi(v18.V2D(), 0, 0xf0f0f0f00f0f0f0f);
17697 __ Movi(v4.V2D(), 0, 0xf0f0f0f0f0f0f0f0);
17698 __ Movi(v5.V2D(), 0, 0x00ffff0000ffff00);
17699
17700 __ Bsl(v16.V16B(), v0.V16B(), v1.V16B());
17701 __ Bsl(v17.V16B(), v2.V16B(), v3.V16B());
17702 __ Bsl(v18.V8B(), v4.V8B(), v5.V8B());
17703 END();
17704
17705 RUN();
17706
17707 ASSERT_EQUAL_128(0xff0000ffff005555, 0xaaaa55aa55aaffaa, q16);
17708 ASSERT_EQUAL_128(0xff550000cc33ff00, 0x33ccff00f00fff00, q17);
17709 ASSERT_EQUAL_128(0, 0xf0fffff000f0f000, q18);
17710 TEARDOWN();
17711}
17712
17713
17714TEST(neon_3same_smax) {
17715 SETUP();
17716
17717 START();
17718
17719 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
17720 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17721
17722 __ Smax(v16.V8B(), v0.V8B(), v1.V8B());
17723 __ Smax(v18.V4H(), v0.V4H(), v1.V4H());
17724 __ Smax(v20.V2S(), v0.V2S(), v1.V2S());
17725
17726 __ Smax(v17.V16B(), v0.V16B(), v1.V16B());
17727 __ Smax(v19.V8H(), v0.V8H(), v1.V8H());
17728 __ Smax(v21.V4S(), v0.V4S(), v1.V4S());
17729 END();
17730
17731 RUN();
17732
17733 ASSERT_EQUAL_128(0x0, 0x0000000000005555, q16);
17734 ASSERT_EQUAL_128(0x0, 0x00000000000055ff, q18);
17735 ASSERT_EQUAL_128(0x0, 0x000000000000aa55, q20);
17736 ASSERT_EQUAL_128(0x55aa555555555555, 0x0000000000005555, q17);
17737 ASSERT_EQUAL_128(0x55aa555555555555, 0x00000000000055ff, q19);
17738 ASSERT_EQUAL_128(0x55aa555555555555, 0x000000000000aa55, q21);
17739 TEARDOWN();
17740}
17741
17742
17743TEST(neon_3same_smaxp) {
17744 SETUP();
17745
17746 START();
17747
17748 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
17749 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17750
17751 __ Smaxp(v16.V8B(), v0.V8B(), v1.V8B());
17752 __ Smaxp(v18.V4H(), v0.V4H(), v1.V4H());
17753 __ Smaxp(v20.V2S(), v0.V2S(), v1.V2S());
17754
17755 __ Smaxp(v17.V16B(), v0.V16B(), v1.V16B());
17756 __ Smaxp(v19.V8H(), v0.V8H(), v1.V8H());
17757 __ Smaxp(v21.V4S(), v0.V4S(), v1.V4S());
17758 END();
17759
17760 RUN();
17761
17762 ASSERT_EQUAL_128(0x0, 0x0000ff55ffff0055, q16);
17763 ASSERT_EQUAL_128(0x0, 0x000055ffffff0000, q18);
17764 ASSERT_EQUAL_128(0x0, 0x000000000000aa55, q20);
17765 ASSERT_EQUAL_128(0x5555aaaa0000ff55, 0xaaaa5555ffff0055, q17);
17766 ASSERT_EQUAL_128(0x55aaaaaa000055ff, 0xaaaa5555ffff0000, q19);
17767 ASSERT_EQUAL_128(0x55aa555500000000, 0x555555550000aa55, q21);
17768 TEARDOWN();
17769}
17770
17771
17772TEST(neon_addp_scalar) {
17773 SETUP();
17774
17775 START();
17776
17777 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17778 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17779 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17780
17781 __ Addp(d16, v0.V2D());
17782 __ Addp(d17, v1.V2D());
17783 __ Addp(d18, v2.V2D());
17784
17785 END();
17786
17787 RUN();
17788
17789 ASSERT_EQUAL_128(0x0, 0x00224466ef66fa80, q16);
17790 ASSERT_EQUAL_128(0x0, 0x55aa5556aa5500a9, q17);
17791 ASSERT_EQUAL_128(0x0, 0xaaaaaaa96655ff55, q18);
17792 TEARDOWN();
17793}
17794
17795TEST(neon_acrosslanes_addv) {
17796 SETUP();
17797
17798 START();
17799
17800 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17801 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17802 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17803
17804 __ Addv(b16, v0.V8B());
17805 __ Addv(b17, v0.V16B());
17806 __ Addv(h18, v1.V4H());
17807 __ Addv(h19, v1.V8H());
17808 __ Addv(s20, v2.V4S());
17809
17810 END();
17811
17812 RUN();
17813
17814 ASSERT_EQUAL_128(0x0, 0xc7, q16);
17815 ASSERT_EQUAL_128(0x0, 0x99, q17);
17816 ASSERT_EQUAL_128(0x0, 0x55a9, q18);
17817 ASSERT_EQUAL_128(0x0, 0x55fc, q19);
17818 ASSERT_EQUAL_128(0x0, 0x1100a9fe, q20);
17819 TEARDOWN();
17820}
17821
17822
17823TEST(neon_acrosslanes_saddlv) {
17824 SETUP();
17825
17826 START();
17827
17828 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17829 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17830 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17831
17832 __ Saddlv(h16, v0.V8B());
17833 __ Saddlv(h17, v0.V16B());
17834 __ Saddlv(s18, v1.V4H());
17835 __ Saddlv(s19, v1.V8H());
17836 __ Saddlv(d20, v2.V4S());
17837
17838 END();
17839
17840 RUN();
17841
17842 ASSERT_EQUAL_128(0x0, 0xffc7, q16);
17843 ASSERT_EQUAL_128(0x0, 0xff99, q17);
17844 ASSERT_EQUAL_128(0x0, 0x000055a9, q18);
17845 ASSERT_EQUAL_128(0x0, 0x000055fc, q19);
17846 ASSERT_EQUAL_128(0x0, 0x0000001100a9fe, q20);
17847 TEARDOWN();
17848}
17849
17850
17851TEST(neon_acrosslanes_uaddlv) {
17852 SETUP();
17853
17854 START();
17855
17856 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17857 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17858 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17859
17860 __ Uaddlv(h16, v0.V8B());
17861 __ Uaddlv(h17, v0.V16B());
17862 __ Uaddlv(s18, v1.V4H());
17863 __ Uaddlv(s19, v1.V8H());
17864 __ Uaddlv(d20, v2.V4S());
17865
17866 END();
17867
17868 RUN();
17869
17870 ASSERT_EQUAL_128(0x0, 0x02c7, q16);
17871 ASSERT_EQUAL_128(0x0, 0x0599, q17);
17872 ASSERT_EQUAL_128(0x0, 0x000155a9, q18);
17873 ASSERT_EQUAL_128(0x0, 0x000355fc, q19);
17874 ASSERT_EQUAL_128(0x0, 0x000000021100a9fe, q20);
17875 TEARDOWN();
17876}
17877
17878
17879TEST(neon_acrosslanes_smaxv) {
17880 SETUP();
17881
17882 START();
17883
17884 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17885 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17886 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17887
17888 __ Smaxv(b16, v0.V8B());
17889 __ Smaxv(b17, v0.V16B());
17890 __ Smaxv(h18, v1.V4H());
17891 __ Smaxv(h19, v1.V8H());
17892 __ Smaxv(s20, v2.V4S());
17893
17894 END();
17895
17896 RUN();
17897
17898 ASSERT_EQUAL_128(0x0, 0x33, q16);
17899 ASSERT_EQUAL_128(0x0, 0x44, q17);
17900 ASSERT_EQUAL_128(0x0, 0x55ff, q18);
17901 ASSERT_EQUAL_128(0x0, 0x55ff, q19);
17902 ASSERT_EQUAL_128(0x0, 0x66555555, q20);
17903 TEARDOWN();
17904}
17905
17906
17907TEST(neon_acrosslanes_sminv) {
17908 SETUP();
17909
17910 START();
17911
17912 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17913 __ Movi(v1.V2D(), 0xfffa5555aaaaaaaa, 0x00000000ffaa55ff);
17914 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17915
17916 __ Sminv(b16, v0.V8B());
17917 __ Sminv(b17, v0.V16B());
17918 __ Sminv(h18, v1.V4H());
17919 __ Sminv(h19, v1.V8H());
17920 __ Sminv(s20, v2.V4S());
17921
17922 END();
17923
17924 RUN();
17925
17926 ASSERT_EQUAL_128(0x0, 0xaa, q16);
17927 ASSERT_EQUAL_128(0x0, 0x80, q17);
17928 ASSERT_EQUAL_128(0x0, 0xffaa, q18);
17929 ASSERT_EQUAL_128(0x0, 0xaaaa, q19);
17930 ASSERT_EQUAL_128(0x0, 0xaaaaaaaa, q20);
17931 TEARDOWN();
17932}
17933
17934TEST(neon_acrosslanes_umaxv) {
17935 SETUP();
17936
17937 START();
17938
17939 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
17940 __ Movi(v1.V2D(), 0x55aa5555aaaaffab, 0x00000000ffaa55ff);
17941 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17942
17943 __ Umaxv(b16, v0.V8B());
17944 __ Umaxv(b17, v0.V16B());
17945 __ Umaxv(h18, v1.V4H());
17946 __ Umaxv(h19, v1.V8H());
17947 __ Umaxv(s20, v2.V4S());
17948
17949 END();
17950
17951 RUN();
17952
17953 ASSERT_EQUAL_128(0x0, 0xfc, q16);
17954 ASSERT_EQUAL_128(0x0, 0xfe, q17);
17955 ASSERT_EQUAL_128(0x0, 0xffaa, q18);
17956 ASSERT_EQUAL_128(0x0, 0xffab, q19);
17957 ASSERT_EQUAL_128(0x0, 0xffffffff, q20);
17958 TEARDOWN();
17959}
17960
17961
17962TEST(neon_acrosslanes_uminv) {
17963 SETUP();
17964
17965 START();
17966
17967 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x02112233aabbfc01);
17968 __ Movi(v1.V2D(), 0xfffa5555aaaa0000, 0x00010003ffaa55ff);
17969 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
17970
17971 __ Uminv(b16, v0.V8B());
17972 __ Uminv(b17, v0.V16B());
17973 __ Uminv(h18, v1.V4H());
17974 __ Uminv(h19, v1.V8H());
17975 __ Uminv(s20, v2.V4S());
17976
17977 END();
17978
17979 RUN();
17980
17981 ASSERT_EQUAL_128(0x0, 0x01, q16);
17982 ASSERT_EQUAL_128(0x0, 0x00, q17);
17983 ASSERT_EQUAL_128(0x0, 0x0001, q18);
17984 ASSERT_EQUAL_128(0x0, 0x0000, q19);
17985 ASSERT_EQUAL_128(0x0, 0x0000aa00, q20);
17986 TEARDOWN();
17987}
17988
17989
17990TEST(neon_3same_smin) {
17991 SETUP();
17992
17993 START();
17994
17995 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
17996 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
17997
17998 __ Smin(v16.V8B(), v0.V8B(), v1.V8B());
17999 __ Smin(v18.V4H(), v0.V4H(), v1.V4H());
18000 __ Smin(v20.V2S(), v0.V2S(), v1.V2S());
18001
18002 __ Smin(v17.V16B(), v0.V16B(), v1.V16B());
18003 __ Smin(v19.V8H(), v0.V8H(), v1.V8H());
18004 __ Smin(v21.V4S(), v0.V4S(), v1.V4S());
18005 END();
18006
18007 RUN();
18008
18009 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaaff, q16);
18010 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaa55, q18);
18011 ASSERT_EQUAL_128(0x0, 0xffffffffffaa55ff, q20);
18012 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaaff, q17);
18013 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaa55, q19);
18014 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaa55ff, q21);
18015 TEARDOWN();
18016}
18017
18018
18019TEST(neon_3same_umax) {
18020 SETUP();
18021
18022 START();
18023
18024 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
18025 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18026
18027 __ Umax(v16.V8B(), v0.V8B(), v1.V8B());
18028 __ Umax(v18.V4H(), v0.V4H(), v1.V4H());
18029 __ Umax(v20.V2S(), v0.V2S(), v1.V2S());
18030
18031 __ Umax(v17.V16B(), v0.V16B(), v1.V16B());
18032 __ Umax(v19.V8H(), v0.V8H(), v1.V8H());
18033 __ Umax(v21.V4S(), v0.V4S(), v1.V4S());
18034 END();
18035
18036 RUN();
18037
18038 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaaff, q16);
18039 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaa55, q18);
18040 ASSERT_EQUAL_128(0x0, 0xffffffffffaa55ff, q20);
18041 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaaff, q17);
18042 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaa55, q19);
18043 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaa55ff, q21);
18044 TEARDOWN();
18045}
18046
18047
18048TEST(neon_3same_umin) {
18049 SETUP();
18050
18051 START();
18052
18053 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
18054 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18055
18056 __ Umin(v16.V8B(), v0.V8B(), v1.V8B());
18057 __ Umin(v18.V4H(), v0.V4H(), v1.V4H());
18058 __ Umin(v20.V2S(), v0.V2S(), v1.V2S());
18059
18060 __ Umin(v17.V16B(), v0.V16B(), v1.V16B());
18061 __ Umin(v19.V8H(), v0.V8H(), v1.V8H());
18062 __ Umin(v21.V4S(), v0.V4S(), v1.V4S());
18063 END();
18064
18065 RUN();
18066
18067 ASSERT_EQUAL_128(0x0, 0x0000000000005555, q16);
18068 ASSERT_EQUAL_128(0x0, 0x00000000000055ff, q18);
18069 ASSERT_EQUAL_128(0x0, 0x000000000000aa55, q20);
18070 ASSERT_EQUAL_128(0x55aa555555555555, 0x0000000000005555, q17);
18071 ASSERT_EQUAL_128(0x55aa555555555555, 0x00000000000055ff, q19);
18072 ASSERT_EQUAL_128(0x55aa555555555555, 0x000000000000aa55, q21);
18073 TEARDOWN();
18074}
18075
18076
18077TEST(neon_2regmisc_mvn) {
18078 SETUP();
18079
18080 START();
18081
18082 __ Movi(v0.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
18083
18084 __ Mvn(v16.V16B(), v0.V16B());
18085 __ Mvn(v17.V8H(), v0.V8H());
18086 __ Mvn(v18.V4S(), v0.V4S());
18087 __ Mvn(v19.V2D(), v0.V2D());
18088
18089 __ Mvn(v24.V8B(), v0.V8B());
18090 __ Mvn(v25.V4H(), v0.V4H());
18091 __ Mvn(v26.V2S(), v0.V2S());
18092
18093 END();
18094
18095 RUN();
18096
18097 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q16);
18098 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q17);
18099 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q18);
18100 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q19);
18101
18102 ASSERT_EQUAL_128(0x0, 0xaa55aa55aa55aa55, q24);
18103 ASSERT_EQUAL_128(0x0, 0xaa55aa55aa55aa55, q25);
18104 ASSERT_EQUAL_128(0x0, 0xaa55aa55aa55aa55, q26);
18105 TEARDOWN();
18106}
18107
18108
18109TEST(neon_2regmisc_not) {
18110 SETUP();
18111
18112 START();
18113
18114 __ Movi(v0.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
18115 __ Movi(v1.V2D(), 0, 0x00ffff0000ffff00);
18116
18117 __ Not(v16.V16B(), v0.V16B());
18118 __ Not(v17.V8B(), v1.V8B());
18119 END();
18120
18121 RUN();
18122
18123 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q16);
18124 ASSERT_EQUAL_128(0x0, 0xff0000ffff0000ff, q17);
18125 TEARDOWN();
18126}
18127
18128TEST(neon_2regmisc_cls_clz_cnt) {
18129 SETUP();
18130
18131 START();
18132
18133 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18134 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18135
18136 __ Cls(v16.V8B() , v1.V8B());
18137 __ Cls(v17.V16B(), v1.V16B());
18138 __ Cls(v18.V4H() , v1.V4H());
18139 __ Cls(v19.V8H() , v1.V8H());
18140 __ Cls(v20.V2S() , v1.V2S());
18141 __ Cls(v21.V4S() , v1.V4S());
18142
18143 __ Clz(v22.V8B() , v0.V8B());
18144 __ Clz(v23.V16B(), v0.V16B());
18145 __ Clz(v24.V4H() , v0.V4H());
18146 __ Clz(v25.V8H() , v0.V8H());
18147 __ Clz(v26.V2S() , v0.V2S());
18148 __ Clz(v27.V4S() , v0.V4S());
18149
18150 __ Cnt(v28.V8B() , v0.V8B());
18151 __ Cnt(v29.V16B(), v1.V16B());
18152
18153 END();
18154
18155 RUN();
18156
18157 ASSERT_EQUAL_128(0x0000000000000000, 0x0601000000000102, q16);
18158 ASSERT_EQUAL_128(0x0601000000000102, 0x0601000000000102, q17);
18159 ASSERT_EQUAL_128(0x0000000000000000, 0x0006000000000001, q18);
18160 ASSERT_EQUAL_128(0x0006000000000001, 0x0006000000000001, q19);
18161 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000600000000, q20);
18162 ASSERT_EQUAL_128(0x0000000600000000, 0x0000000600000000, q21);
18163
18164 ASSERT_EQUAL_128(0x0000000000000000, 0x0404040404040404, q22);
18165 ASSERT_EQUAL_128(0x0807060605050505, 0x0404040404040404, q23);
18166 ASSERT_EQUAL_128(0x0000000000000000, 0x0004000400040004, q24);
18167 ASSERT_EQUAL_128(0x000f000600050005, 0x0004000400040004, q25);
18168 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000400000004, q26);
18169 ASSERT_EQUAL_128(0x0000000f00000005, 0x0000000400000004, q27);
18170
18171 ASSERT_EQUAL_128(0x0000000000000000, 0x0102020302030304, q28);
18172 ASSERT_EQUAL_128(0x0705050305030301, 0x0103030503050507, q29);
18173
18174 TEARDOWN();
18175}
18176
18177TEST(neon_2regmisc_rev) {
18178 SETUP();
18179
18180 START();
18181
18182 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18183 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18184
18185 __ Rev16(v16.V8B() , v0.V8B());
18186 __ Rev16(v17.V16B(), v0.V16B());
18187
18188 __ Rev32(v18.V8B() , v0.V8B());
18189 __ Rev32(v19.V16B(), v0.V16B());
18190 __ Rev32(v20.V4H() , v0.V4H());
18191 __ Rev32(v21.V8H() , v0.V8H());
18192
18193 __ Rev64(v22.V8B() , v0.V8B());
18194 __ Rev64(v23.V16B(), v0.V16B());
18195 __ Rev64(v24.V4H() , v0.V4H());
18196 __ Rev64(v25.V8H() , v0.V8H());
18197 __ Rev64(v26.V2S() , v0.V2S());
18198 __ Rev64(v27.V4S() , v0.V4S());
18199
18200 __ Rbit(v28.V8B() , v1.V8B());
18201 __ Rbit(v29.V16B(), v1.V16B());
18202
18203 END();
18204
18205 RUN();
18206
18207 ASSERT_EQUAL_128(0x0000000000000000, 0x09080b0a0d0c0f0e, q16);
18208 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q17);
18209
18210 ASSERT_EQUAL_128(0x0000000000000000, 0x0b0a09080f0e0d0c, q18);
18211 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q19);
18212 ASSERT_EQUAL_128(0x0000000000000000, 0x0a0b08090e0f0c0d, q20);
18213 ASSERT_EQUAL_128(0x0203000106070405, 0x0a0b08090e0f0c0d, q21);
18214
18215 ASSERT_EQUAL_128(0x0000000000000000, 0x0f0e0d0c0b0a0908, q22);
18216 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q23);
18217 ASSERT_EQUAL_128(0x0000000000000000, 0x0e0f0c0d0a0b0809, q24);
18218 ASSERT_EQUAL_128(0x0607040502030001, 0x0e0f0c0d0a0b0809, q25);
18219 ASSERT_EQUAL_128(0x0000000000000000, 0x0c0d0e0f08090a0b, q26);
18220 ASSERT_EQUAL_128(0x0405060700010203, 0x0c0d0e0f08090a0b, q27);
18221
18222 ASSERT_EQUAL_128(0x0000000000000000, 0x80c4a2e691d5b3f7, q28);
18223 ASSERT_EQUAL_128(0x7f3b5d196e2a4c08, 0x80c4a2e691d5b3f7, q29);
18224
18225 TEARDOWN();
18226}
18227
18228
18229TEST(neon_sli) {
18230 SETUP();
18231
18232 START();
18233
18234 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18235 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18236
18237 __ Mov(v16.V2D(), v0.V2D());
18238 __ Mov(v17.V2D(), v0.V2D());
18239 __ Mov(v18.V2D(), v0.V2D());
18240 __ Mov(v19.V2D(), v0.V2D());
18241 __ Mov(v20.V2D(), v0.V2D());
18242 __ Mov(v21.V2D(), v0.V2D());
18243 __ Mov(v22.V2D(), v0.V2D());
18244 __ Mov(v23.V2D(), v0.V2D());
18245
18246 __ Sli(v16.V8B(), v1.V8B(), 4);
18247 __ Sli(v17.V16B(), v1.V16B(), 7);
18248 __ Sli(v18.V4H(), v1.V4H(), 8);
18249 __ Sli(v19.V8H(), v1.V8H(), 15);
18250 __ Sli(v20.V2S(), v1.V2S(), 0);
18251 __ Sli(v21.V4S(), v1.V4S(), 31);
18252 __ Sli(v22.V2D(), v1.V2D(), 48);
18253
18254 __ Sli(d23, d1, 48);
18255
18256 END();
18257
18258 RUN();
18259
18260 ASSERT_EQUAL_128(0x0000000000000000, 0x18395a7b9cbddeff, q16);
18261 ASSERT_EQUAL_128(0x0001020304050607, 0x88898a8b8c8d8e8f, q17);
18262 ASSERT_EQUAL_128(0x0000000000000000, 0x2309670bab0def0f, q18);
18263 ASSERT_EQUAL_128(0x0001020304050607, 0x88098a0b8c0d8e0f, q19);
18264 ASSERT_EQUAL_128(0x0000000000000000, 0x0123456789abcdef, q20);
18265 ASSERT_EQUAL_128(0x0001020304050607, 0x88090a0b8c0d0e0f, q21);
18266 ASSERT_EQUAL_128(0x3210020304050607, 0xcdef0a0b0c0d0e0f, q22);
18267
18268 ASSERT_EQUAL_128(0x0000000000000000, 0xcdef0a0b0c0d0e0f, q23);
18269
18270
18271 TEARDOWN();
18272}
18273
18274
18275TEST(neon_sri) {
18276 SETUP();
18277
18278 START();
18279
18280 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18281 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18282
18283 __ Mov(v16.V2D(), v0.V2D());
18284 __ Mov(v17.V2D(), v0.V2D());
18285 __ Mov(v18.V2D(), v0.V2D());
18286 __ Mov(v19.V2D(), v0.V2D());
18287 __ Mov(v20.V2D(), v0.V2D());
18288 __ Mov(v21.V2D(), v0.V2D());
18289 __ Mov(v22.V2D(), v0.V2D());
18290 __ Mov(v23.V2D(), v0.V2D());
18291
18292 __ Sri(v16.V8B(), v1.V8B(), 4);
18293 __ Sri(v17.V16B(), v1.V16B(), 7);
18294 __ Sri(v18.V4H(), v1.V4H(), 8);
18295 __ Sri(v19.V8H(), v1.V8H(), 15);
18296 __ Sri(v20.V2S(), v1.V2S(), 1);
18297 __ Sri(v21.V4S(), v1.V4S(), 31);
18298 __ Sri(v22.V2D(), v1.V2D(), 48);
18299
18300 __ Sri(d23, d1, 48);
18301
18302 END();
18303
18304 RUN();
18305
18306 ASSERT_EQUAL_128(0x0000000000000000, 0x00020406080a0c0e, q16);
18307 ASSERT_EQUAL_128(0x0101030304040606, 0x08080a0a0d0d0f0f, q17);
18308 ASSERT_EQUAL_128(0x0000000000000000, 0x08010a450c890ecd, q18);
18309 ASSERT_EQUAL_128(0x0001020304040606, 0x08080a0a0c0d0e0f, q19);
18310 ASSERT_EQUAL_128(0x0000000000000000, 0x0091a2b344d5e6f7, q20);
18311 ASSERT_EQUAL_128(0x0001020304050606, 0x08090a0a0c0d0e0f, q21);
18312 ASSERT_EQUAL_128(0x000102030405fedc, 0x08090a0b0c0d0123, q22);
18313
18314 ASSERT_EQUAL_128(0x0000000000000000, 0x08090a0b0c0d0123, q23);
18315
18316
18317 TEARDOWN();
18318}
18319
18320
18321TEST(neon_shrn) {
18322 SETUP();
18323
18324 START();
18325
18326 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18327 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18328 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18329 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18330 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18331
18332 __ Shrn(v16.V8B(), v0.V8H(), 8);
18333 __ Shrn2(v16.V16B(), v1.V8H(), 1);
18334 __ Shrn(v17.V4H(), v1.V4S(), 16);
18335 __ Shrn2(v17.V8H(), v2.V4S(), 1);
18336 __ Shrn(v18.V2S(), v3.V2D(), 32);
18337 __ Shrn2(v18.V4S(), v3.V2D(), 1);
18338
18339 END();
18340
18341 RUN();
18342 ASSERT_EQUAL_128(0x0000ff00ff0000ff, 0x7f00817f80ff0180, q16);
18343 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x8000ffffffff0001, q17);
18344 ASSERT_EQUAL_128(0x00000000ffffffff, 0x800000007fffffff, q18);
18345 TEARDOWN();
18346}
18347
18348
18349TEST(neon_rshrn) {
18350 SETUP();
18351
18352 START();
18353
18354 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18355 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18356 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18357 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18358 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18359
18360 __ Rshrn(v16.V8B(), v0.V8H(), 8);
18361 __ Rshrn2(v16.V16B(), v1.V8H(), 1);
18362 __ Rshrn(v17.V4H(), v1.V4S(), 16);
18363 __ Rshrn2(v17.V8H(), v2.V4S(), 1);
18364 __ Rshrn(v18.V2S(), v3.V2D(), 32);
18365 __ Rshrn2(v18.V4S(), v3.V2D(), 1);
18366
18367 END();
18368
18369 RUN();
18370 ASSERT_EQUAL_128(0x0001000000000100, 0x7f01827f81ff0181, q16);
18371 ASSERT_EQUAL_128(0x0000000000000000, 0x8001ffffffff0001, q17);
18372 ASSERT_EQUAL_128(0x0000000100000000, 0x8000000080000000, q18);
18373 TEARDOWN();
18374}
18375
18376
18377TEST(neon_uqshrn) {
18378 SETUP();
18379
18380 START();
18381
18382 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18383 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18384 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18385 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18386 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18387
18388 __ Uqshrn(v16.V8B(), v0.V8H(), 8);
18389 __ Uqshrn2(v16.V16B(), v1.V8H(), 1);
18390 __ Uqshrn(v17.V4H(), v1.V4S(), 16);
18391 __ Uqshrn2(v17.V8H(), v2.V4S(), 1);
18392 __ Uqshrn(v18.V2S(), v3.V2D(), 32);
18393 __ Uqshrn2(v18.V4S(), v3.V2D(), 1);
18394
18395 __ Uqshrn(b19, h0, 8);
18396 __ Uqshrn(h20, s1, 16);
18397 __ Uqshrn(s21, d3, 32);
18398
18399 END();
18400
18401 RUN();
18402 ASSERT_EQUAL_128(0xffffff00ff0000ff, 0x7f00817f80ff0180, q16);
18403 ASSERT_EQUAL_128(0xffffffff0000ffff, 0x8000ffffffff0001, q17);
18404 ASSERT_EQUAL_128(0xffffffffffffffff, 0x800000007fffffff, q18);
18405 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000080, q19);
18406 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18407 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18408 TEARDOWN();
18409}
18410
18411
18412TEST(neon_uqrshrn) {
18413 SETUP();
18414
18415 START();
18416
18417 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18418 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18419 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18420 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18421 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18422
18423 __ Uqrshrn(v16.V8B(), v0.V8H(), 8);
18424 __ Uqrshrn2(v16.V16B(), v1.V8H(), 1);
18425 __ Uqrshrn(v17.V4H(), v1.V4S(), 16);
18426 __ Uqrshrn2(v17.V8H(), v2.V4S(), 1);
18427 __ Uqrshrn(v18.V2S(), v3.V2D(), 32);
18428 __ Uqrshrn2(v18.V4S(), v3.V2D(), 1);
18429
18430 __ Uqrshrn(b19, h0, 8);
18431 __ Uqrshrn(h20, s1, 16);
18432 __ Uqrshrn(s21, d3, 32);
18433
18434 END();
18435
18436 RUN();
18437 ASSERT_EQUAL_128(0xffffff00ff0001ff, 0x7f01827f81ff0181, q16);
18438 ASSERT_EQUAL_128(0xffffffff0000ffff, 0x8001ffffffff0001, q17);
18439 ASSERT_EQUAL_128(0xffffffffffffffff, 0x8000000080000000, q18);
18440 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000081, q19);
18441 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18442 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000000, q21);
18443 TEARDOWN();
18444}
18445
18446
18447TEST(neon_sqshrn) {
18448 SETUP();
18449
18450 START();
18451
18452 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18453 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18454 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18455 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18456 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18457
18458 __ Sqshrn(v16.V8B(), v0.V8H(), 8);
18459 __ Sqshrn2(v16.V16B(), v1.V8H(), 1);
18460 __ Sqshrn(v17.V4H(), v1.V4S(), 16);
18461 __ Sqshrn2(v17.V8H(), v2.V4S(), 1);
18462 __ Sqshrn(v18.V2S(), v3.V2D(), 32);
18463 __ Sqshrn2(v18.V4S(), v3.V2D(), 1);
18464
18465 __ Sqshrn(b19, h0, 8);
18466 __ Sqshrn(h20, s1, 16);
18467 __ Sqshrn(s21, d3, 32);
18468
18469 END();
18470
18471 RUN();
18472 ASSERT_EQUAL_128(0x8080ff00ff00007f, 0x7f00817f80ff0180, q16);
18473 ASSERT_EQUAL_128(0x8000ffff00007fff, 0x8000ffffffff0001, q17);
18474 ASSERT_EQUAL_128(0x800000007fffffff, 0x800000007fffffff, q18);
18475 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000080, q19);
18476 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18477 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18478 TEARDOWN();
18479}
18480
18481
18482TEST(neon_sqrshrn) {
18483 SETUP();
18484
18485 START();
18486
18487 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18488 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18489 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18490 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18491 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18492
18493 __ Sqrshrn(v16.V8B(), v0.V8H(), 8);
18494 __ Sqrshrn2(v16.V16B(), v1.V8H(), 1);
18495 __ Sqrshrn(v17.V4H(), v1.V4S(), 16);
18496 __ Sqrshrn2(v17.V8H(), v2.V4S(), 1);
18497 __ Sqrshrn(v18.V2S(), v3.V2D(), 32);
18498 __ Sqrshrn2(v18.V4S(), v3.V2D(), 1);
18499
18500 __ Sqrshrn(b19, h0, 8);
18501 __ Sqrshrn(h20, s1, 16);
18502 __ Sqrshrn(s21, d3, 32);
18503
18504 END();
18505
18506 RUN();
18507 ASSERT_EQUAL_128(0x808000000000017f, 0x7f01827f81ff0181, q16);
18508 ASSERT_EQUAL_128(0x8000000000007fff, 0x8001ffffffff0001, q17);
18509 ASSERT_EQUAL_128(0x800000007fffffff, 0x800000007fffffff, q18);
18510 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000081, q19);
18511 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18512 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18513 TEARDOWN();
18514}
18515
18516
18517TEST(neon_sqshrun) {
18518 SETUP();
18519
18520 START();
18521
18522 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18523 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18524 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18525 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18526 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18527
18528 __ Sqshrun(v16.V8B(), v0.V8H(), 8);
18529 __ Sqshrun2(v16.V16B(), v1.V8H(), 1);
18530 __ Sqshrun(v17.V4H(), v1.V4S(), 16);
18531 __ Sqshrun2(v17.V8H(), v2.V4S(), 1);
18532 __ Sqshrun(v18.V2S(), v3.V2D(), 32);
18533 __ Sqshrun2(v18.V4S(), v3.V2D(), 1);
18534
18535 __ Sqshrun(b19, h0, 8);
18536 __ Sqshrun(h20, s1, 16);
18537 __ Sqshrun(s21, d3, 32);
18538
18539 END();
18540
18541 RUN();
18542 ASSERT_EQUAL_128(0x00000000000000ff, 0x7f00007f00000100, q16);
18543 ASSERT_EQUAL_128(0x000000000000ffff, 0x0000000000000001, q17);
18544 ASSERT_EQUAL_128(0x00000000ffffffff, 0x000000007fffffff, q18);
18545 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q19);
18546 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18547 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18548 TEARDOWN();
18549}
18550
18551
18552TEST(neon_sqrshrun) {
18553 SETUP();
18554
18555 START();
18556
18557 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18558 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18559 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18560 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18561 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18562
18563 __ Sqrshrun(v16.V8B(), v0.V8H(), 8);
18564 __ Sqrshrun2(v16.V16B(), v1.V8H(), 1);
18565 __ Sqrshrun(v17.V4H(), v1.V4S(), 16);
18566 __ Sqrshrun2(v17.V8H(), v2.V4S(), 1);
18567 __ Sqrshrun(v18.V2S(), v3.V2D(), 32);
18568 __ Sqrshrun2(v18.V4S(), v3.V2D(), 1);
18569
18570 __ Sqrshrun(b19, h0, 8);
18571 __ Sqrshrun(h20, s1, 16);
18572 __ Sqrshrun(s21, d3, 32);
18573
18574 END();
18575
18576 RUN();
18577 ASSERT_EQUAL_128(0x00000000000001ff, 0x7f01007f00000100, q16);
18578 ASSERT_EQUAL_128(0x000000000000ffff, 0x0000000000000001, q17);
18579 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000000080000000, q18);
18580 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q19);
18581 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18582 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000000, q21);
18583 TEARDOWN();
18584}
18585
18586TEST(neon_modimm_bic) {
18587 SETUP();
18588
18589 START();
18590
18591 __ Movi(v16.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18592 __ Movi(v17.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18593 __ Movi(v18.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18594 __ Movi(v19.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18595 __ Movi(v20.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18596 __ Movi(v21.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18597 __ Movi(v22.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18598 __ Movi(v23.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18599 __ Movi(v24.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18600 __ Movi(v25.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18601 __ Movi(v26.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18602 __ Movi(v27.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18603
18604 __ Bic(v16.V4H(), 0x00, 0);
18605 __ Bic(v17.V4H(), 0xff, 8);
18606 __ Bic(v18.V8H(), 0x00, 0);
18607 __ Bic(v19.V8H(), 0xff, 8);
18608
18609 __ Bic(v20.V2S(), 0x00, 0);
18610 __ Bic(v21.V2S(), 0xff, 8);
18611 __ Bic(v22.V2S(), 0x00, 16);
18612 __ Bic(v23.V2S(), 0xff, 24);
18613
18614 __ Bic(v24.V4S(), 0xff, 0);
18615 __ Bic(v25.V4S(), 0x00, 8);
18616 __ Bic(v26.V4S(), 0xff, 16);
18617 __ Bic(v27.V4S(), 0x00, 24);
18618
18619 END();
18620
18621 RUN();
18622
18623 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q16);
18624 ASSERT_EQUAL_128(0x0, 0x005500ff000000aa, q17);
18625 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q18);
18626 ASSERT_EQUAL_128(0x00aa0055000000aa, 0x005500ff000000aa, q19);
18627
18628 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q20);
18629 ASSERT_EQUAL_128(0x0, 0x555500ff000000aa, q21);
18630 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q22);
18631 ASSERT_EQUAL_128(0x0, 0x0055ffff0000aaaa, q23);
18632
18633 ASSERT_EQUAL_128(0x00aaff00ff005500, 0x5555ff000000aa00, q24);
18634 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q25);
18635 ASSERT_EQUAL_128(0x0000ff55ff0055aa, 0x5500ffff0000aaaa, q26);
18636 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q27);
18637
18638 TEARDOWN();
18639}
18640
18641
18642TEST(neon_modimm_movi_16bit_any) {
18643 SETUP();
18644
18645 START();
18646
18647 __ Movi(v0.V4H(), 0xabab);
18648 __ Movi(v1.V4H(), 0xab00);
18649 __ Movi(v2.V4H(), 0xabff);
18650 __ Movi(v3.V8H(), 0x00ab);
18651 __ Movi(v4.V8H(), 0xffab);
18652 __ Movi(v5.V8H(), 0xabcd);
18653
18654 END();
18655
18656 RUN();
18657
18658 ASSERT_EQUAL_128(0x0, 0xabababababababab, q0);
18659 ASSERT_EQUAL_128(0x0, 0xab00ab00ab00ab00, q1);
18660 ASSERT_EQUAL_128(0x0, 0xabffabffabffabff, q2);
18661 ASSERT_EQUAL_128(0x00ab00ab00ab00ab, 0x00ab00ab00ab00ab, q3);
18662 ASSERT_EQUAL_128(0xffabffabffabffab, 0xffabffabffabffab, q4);
18663 ASSERT_EQUAL_128(0xabcdabcdabcdabcd, 0xabcdabcdabcdabcd, q5);
18664
18665 TEARDOWN();
18666}
18667
18668
18669TEST(neon_modimm_movi_32bit_any) {
18670 SETUP();
18671
18672 START();
18673
18674 __ Movi(v0.V2S(), 0x000000ab);
18675 __ Movi(v1.V2S(), 0x0000ab00);
18676 __ Movi(v2.V4S(), 0x00ab0000);
18677 __ Movi(v3.V4S(), 0xab000000);
18678
18679 __ Movi(v4.V2S(), 0xffffffab);
18680 __ Movi(v5.V2S(), 0xffffabff);
18681 __ Movi(v6.V4S(), 0xffabffff);
18682 __ Movi(v7.V4S(), 0xabffffff);
18683
18684 __ Movi(v16.V2S(), 0x0000abff);
18685 __ Movi(v17.V2S(), 0x00abffff);
18686 __ Movi(v18.V4S(), 0xffab0000);
18687 __ Movi(v19.V4S(), 0xffffab00);
18688
18689 __ Movi(v20.V4S(), 0xabababab);
18690 __ Movi(v21.V4S(), 0xabcdabcd);
18691 __ Movi(v22.V4S(), 0xabcdef01);
18692 __ Movi(v23.V4S(), 0x00ffff00);
18693
18694 END();
18695
18696 RUN();
18697
18698 ASSERT_EQUAL_128(0x0, 0x000000ab000000ab, q0);
18699 ASSERT_EQUAL_128(0x0, 0x0000ab000000ab00, q1);
18700 ASSERT_EQUAL_128(0x00ab000000ab0000, 0x00ab000000ab0000, q2);
18701 ASSERT_EQUAL_128(0xab000000ab000000, 0xab000000ab000000, q3);
18702
18703 ASSERT_EQUAL_128(0x0, 0xffffffabffffffab, q4);
18704 ASSERT_EQUAL_128(0x0, 0xffffabffffffabff, q5);
18705 ASSERT_EQUAL_128(0xffabffffffabffff, 0xffabffffffabffff, q6);
18706 ASSERT_EQUAL_128(0xabffffffabffffff, 0xabffffffabffffff, q7);
18707
18708 ASSERT_EQUAL_128(0x0, 0x0000abff0000abff, q16);
18709 ASSERT_EQUAL_128(0x0, 0x00abffff00abffff, q17);
18710 ASSERT_EQUAL_128(0xffab0000ffab0000, 0xffab0000ffab0000, q18);
18711 ASSERT_EQUAL_128(0xffffab00ffffab00, 0xffffab00ffffab00, q19);
18712
18713 ASSERT_EQUAL_128(0xabababababababab, 0xabababababababab, q20);
18714 ASSERT_EQUAL_128(0xabcdabcdabcdabcd, 0xabcdabcdabcdabcd, q21);
18715 ASSERT_EQUAL_128(0xabcdef01abcdef01, 0xabcdef01abcdef01, q22);
18716 ASSERT_EQUAL_128(0x00ffff0000ffff00, 0x00ffff0000ffff00, q23);
18717 TEARDOWN();
18718}
18719
18720
18721TEST(neon_modimm_movi_64bit_any) {
18722 SETUP();
18723
18724 START();
18725
18726 __ Movi(v0.V1D(), 0x00ffff0000ffffff);
18727 __ Movi(v1.V2D(), 0xabababababababab);
18728 __ Movi(v2.V2D(), 0xabcdabcdabcdabcd);
18729 __ Movi(v3.V2D(), 0xabcdef01abcdef01);
18730 __ Movi(v4.V1D(), 0xabcdef0123456789);
18731 __ Movi(v5.V2D(), 0xabcdef0123456789);
18732
18733 END();
18734
18735 RUN();
18736
18737 ASSERT_EQUAL_128(0x0, 0x00ffff0000ffffff, q0);
18738 ASSERT_EQUAL_128(0xabababababababab, 0xabababababababab, q1);
18739 ASSERT_EQUAL_128(0xabcdabcdabcdabcd, 0xabcdabcdabcdabcd, q2);
18740 ASSERT_EQUAL_128(0xabcdef01abcdef01, 0xabcdef01abcdef01, q3);
18741 ASSERT_EQUAL_128(0x0, 0xabcdef0123456789, q4);
18742 ASSERT_EQUAL_128(0xabcdef0123456789, 0xabcdef0123456789, q5);
18743
18744 TEARDOWN();
18745}
18746
18747
18748TEST(neon_modimm_movi) {
18749 SETUP();
18750
18751 START();
18752
18753 __ Movi(v0.V8B(), 0xaa);
18754 __ Movi(v1.V16B(), 0x55);
18755
18756 __ Movi(d2, 0x00ffff0000ffffff);
18757 __ Movi(v3.V2D(), 0x00ffff0000ffffff);
18758
18759 __ Movi(v16.V4H(), 0x00, LSL, 0);
18760 __ Movi(v17.V4H(), 0xff, LSL, 8);
18761 __ Movi(v18.V8H(), 0x00, LSL, 0);
18762 __ Movi(v19.V8H(), 0xff, LSL, 8);
18763
18764 __ Movi(v20.V2S(), 0x00, LSL, 0);
18765 __ Movi(v21.V2S(), 0xff, LSL, 8);
18766 __ Movi(v22.V2S(), 0x00, LSL, 16);
18767 __ Movi(v23.V2S(), 0xff, LSL, 24);
18768
18769 __ Movi(v24.V4S(), 0xff, LSL, 0);
18770 __ Movi(v25.V4S(), 0x00, LSL, 8);
18771 __ Movi(v26.V4S(), 0xff, LSL, 16);
18772 __ Movi(v27.V4S(), 0x00, LSL, 24);
18773
18774 __ Movi(v28.V2S(), 0xaa, MSL, 8);
18775 __ Movi(v29.V2S(), 0x55, MSL, 16);
18776 __ Movi(v30.V4S(), 0xff, MSL, 8);
18777 __ Movi(v31.V4S(), 0x00, MSL, 16);
18778
18779 END();
18780
18781 RUN();
18782
18783 ASSERT_EQUAL_128(0x0, 0xaaaaaaaaaaaaaaaa, q0);
18784 ASSERT_EQUAL_128(0x5555555555555555, 0x5555555555555555, q1);
18785
18786 ASSERT_EQUAL_128(0x0, 0x00ffff0000ffffff, q2);
18787 ASSERT_EQUAL_128(0x00ffff0000ffffff, 0x00ffff0000ffffff, q3);
18788
18789 ASSERT_EQUAL_128(0x0, 0x0000000000000000, q16);
18790 ASSERT_EQUAL_128(0x0, 0xff00ff00ff00ff00, q17);
18791 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q18);
18792 ASSERT_EQUAL_128(0xff00ff00ff00ff00, 0xff00ff00ff00ff00, q19);
18793
18794 ASSERT_EQUAL_128(0x0, 0x0000000000000000, q20);
18795 ASSERT_EQUAL_128(0x0, 0x0000ff000000ff00, q21);
18796 ASSERT_EQUAL_128(0x0, 0x0000000000000000, q22);
18797 ASSERT_EQUAL_128(0x0, 0xff000000ff000000, q23);
18798
18799 ASSERT_EQUAL_128(0x000000ff000000ff, 0x000000ff000000ff, q24);
18800 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
18801 ASSERT_EQUAL_128(0x00ff000000ff0000, 0x00ff000000ff0000, q26);
18802 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q27);
18803
18804 ASSERT_EQUAL_128(0x0, 0x0000aaff0000aaff, q28);
18805 ASSERT_EQUAL_128(0x0, 0x0055ffff0055ffff, q29);
18806 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x0000ffff0000ffff, q30);
18807 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x0000ffff0000ffff, q31);
18808
18809 TEARDOWN();
18810}
18811
18812
18813TEST(neon_modimm_mvni) {
18814 SETUP();
18815
18816 START();
18817
18818 __ Mvni(v16.V4H(), 0x00, LSL, 0);
18819 __ Mvni(v17.V4H(), 0xff, LSL, 8);
18820 __ Mvni(v18.V8H(), 0x00, LSL, 0);
18821 __ Mvni(v19.V8H(), 0xff, LSL, 8);
18822
18823 __ Mvni(v20.V2S(), 0x00, LSL, 0);
18824 __ Mvni(v21.V2S(), 0xff, LSL, 8);
18825 __ Mvni(v22.V2S(), 0x00, LSL, 16);
18826 __ Mvni(v23.V2S(), 0xff, LSL, 24);
18827
18828 __ Mvni(v24.V4S(), 0xff, LSL, 0);
18829 __ Mvni(v25.V4S(), 0x00, LSL, 8);
18830 __ Mvni(v26.V4S(), 0xff, LSL, 16);
18831 __ Mvni(v27.V4S(), 0x00, LSL, 24);
18832
18833 __ Mvni(v28.V2S(), 0xaa, MSL, 8);
18834 __ Mvni(v29.V2S(), 0x55, MSL, 16);
18835 __ Mvni(v30.V4S(), 0xff, MSL, 8);
18836 __ Mvni(v31.V4S(), 0x00, MSL, 16);
18837
18838 END();
18839
18840 RUN();
18841
18842 ASSERT_EQUAL_128(0x0, 0xffffffffffffffff, q16);
18843 ASSERT_EQUAL_128(0x0, 0x00ff00ff00ff00ff, q17);
18844 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q18);
18845 ASSERT_EQUAL_128(0x00ff00ff00ff00ff, 0x00ff00ff00ff00ff, q19);
18846
18847 ASSERT_EQUAL_128(0x0, 0xffffffffffffffff, q20);
18848 ASSERT_EQUAL_128(0x0, 0xffff00ffffff00ff, q21);
18849 ASSERT_EQUAL_128(0x0, 0xffffffffffffffff, q22);
18850 ASSERT_EQUAL_128(0x0, 0x00ffffff00ffffff, q23);
18851
18852 ASSERT_EQUAL_128(0xffffff00ffffff00, 0xffffff00ffffff00, q24);
18853 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
18854 ASSERT_EQUAL_128(0xff00ffffff00ffff, 0xff00ffffff00ffff, q26);
18855 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q27);
18856
18857 ASSERT_EQUAL_128(0x0, 0xffff5500ffff5500, q28);
18858 ASSERT_EQUAL_128(0x0, 0xffaa0000ffaa0000, q29);
18859 ASSERT_EQUAL_128(0xffff0000ffff0000, 0xffff0000ffff0000, q30);
18860 ASSERT_EQUAL_128(0xffff0000ffff0000, 0xffff0000ffff0000, q31);
18861
18862 TEARDOWN();
18863}
18864
18865
18866TEST(neon_modimm_orr) {
18867 SETUP();
18868
18869 START();
18870
18871 __ Movi(v16.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18872 __ Movi(v17.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18873 __ Movi(v18.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18874 __ Movi(v19.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18875 __ Movi(v20.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18876 __ Movi(v21.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18877 __ Movi(v22.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18878 __ Movi(v23.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18879 __ Movi(v24.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18880 __ Movi(v25.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18881 __ Movi(v26.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18882 __ Movi(v27.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18883
18884 __ Orr(v16.V4H(), 0x00, 0);
18885 __ Orr(v17.V4H(), 0xff, 8);
18886 __ Orr(v18.V8H(), 0x00, 0);
18887 __ Orr(v19.V8H(), 0xff, 8);
18888
18889 __ Orr(v20.V2S(), 0x00, 0);
18890 __ Orr(v21.V2S(), 0xff, 8);
18891 __ Orr(v22.V2S(), 0x00, 16);
18892 __ Orr(v23.V2S(), 0xff, 24);
18893
18894 __ Orr(v24.V4S(), 0xff, 0);
18895 __ Orr(v25.V4S(), 0x00, 8);
18896 __ Orr(v26.V4S(), 0xff, 16);
18897 __ Orr(v27.V4S(), 0x00, 24);
18898
18899 END();
18900
18901 RUN();
18902
18903 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q16);
18904 ASSERT_EQUAL_128(0x0, 0xff55ffffff00ffaa, q17);
18905 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q18);
18906 ASSERT_EQUAL_128(0xffaaff55ff00ffaa, 0xff55ffffff00ffaa, q19);
18907
18908 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q20);
18909 ASSERT_EQUAL_128(0x0, 0x5555ffff0000ffaa, q21);
18910 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q22);
18911 ASSERT_EQUAL_128(0x0, 0xff55ffffff00aaaa, q23);
18912
18913 ASSERT_EQUAL_128(0x00aaffffff0055ff, 0x5555ffff0000aaff, q24);
18914 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q25);
18915 ASSERT_EQUAL_128(0x00ffff55ffff55aa, 0x55ffffff00ffaaaa, q26);
18916 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q27);
18917
18918 TEARDOWN();
18919}
18920
18921
18922// TODO: add arbitrary values once load literal to Q registers is supported.
18923TEST(neon_modimm_fmov) {
18924 SETUP();
18925
18926 // Immediates which can be encoded in the instructions.
18927 const float kOne = 1.0f;
18928 const float kPointFive = 0.5f;
18929 const double kMinusThirteen = -13.0;
18930 // Immediates which cannot be encoded in the instructions.
18931 const float kNonImmFP32 = 255.0f;
18932 const double kNonImmFP64 = 12.3456;
18933
18934 START();
18935 __ Fmov(v11.V2S(), kOne);
18936 __ Fmov(v12.V4S(), kPointFive);
18937 __ Fmov(v22.V2D(), kMinusThirteen);
18938 __ Fmov(v13.V2S(), kNonImmFP32);
18939 __ Fmov(v14.V4S(), kNonImmFP32);
18940 __ Fmov(v23.V2D(), kNonImmFP64);
18941 __ Fmov(v1.V2S(), 0.0);
18942 __ Fmov(v2.V4S(), 0.0);
18943 __ Fmov(v3.V2D(), 0.0);
18944 __ Fmov(v4.V2S(), kFP32PositiveInfinity);
18945 __ Fmov(v5.V4S(), kFP32PositiveInfinity);
18946 __ Fmov(v6.V2D(), kFP64PositiveInfinity);
18947 END();
18948
18949 RUN();
18950
18951 const uint64_t kOne1S = float_to_rawbits(1.0);
18952 const uint64_t kOne2S = (kOne1S << 32) | kOne1S;
18953 const uint64_t kPointFive1S = float_to_rawbits(0.5);
18954 const uint64_t kPointFive2S = (kPointFive1S << 32) | kPointFive1S;
18955 const uint64_t kMinusThirteen1D = double_to_rawbits(-13.0);
18956 const uint64_t kNonImmFP321S = float_to_rawbits(kNonImmFP32);
18957 const uint64_t kNonImmFP322S = (kNonImmFP321S << 32) | kNonImmFP321S;
18958 const uint64_t kNonImmFP641D = double_to_rawbits(kNonImmFP64);
18959 const uint64_t kFP32Inf1S = float_to_rawbits(kFP32PositiveInfinity);
18960 const uint64_t kFP32Inf2S = (kFP32Inf1S << 32) | kFP32Inf1S;
18961 const uint64_t kFP64Inf1D = double_to_rawbits(kFP64PositiveInfinity);
18962
18963 ASSERT_EQUAL_128(0x0, kOne2S, q11);
18964 ASSERT_EQUAL_128(kPointFive2S, kPointFive2S, q12);
18965 ASSERT_EQUAL_128(kMinusThirteen1D, kMinusThirteen1D, q22);
18966 ASSERT_EQUAL_128(0x0, kNonImmFP322S, q13);
18967 ASSERT_EQUAL_128(kNonImmFP322S, kNonImmFP322S, q14);
18968 ASSERT_EQUAL_128(kNonImmFP641D, kNonImmFP641D, q23);
18969 ASSERT_EQUAL_128(0x0, 0x0, q1);
18970 ASSERT_EQUAL_128(0x0, 0x0, q2);
18971 ASSERT_EQUAL_128(0x0, 0x0, q3);
18972 ASSERT_EQUAL_128(0x0, kFP32Inf2S, q4);
18973 ASSERT_EQUAL_128(kFP32Inf2S, kFP32Inf2S, q5);
18974 ASSERT_EQUAL_128(kFP64Inf1D, kFP64Inf1D, q6);
18975
18976 TEARDOWN();
18977}
18978
18979
18980TEST(neon_perm) {
18981 SETUP();
18982
18983 START();
18984
18985 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18986 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
18987
18988 __ Trn1(v16.V16B(), v0.V16B(), v1.V16B());
18989 __ Trn2(v17.V16B(), v0.V16B(), v1.V16B());
18990 __ Zip1(v18.V16B(), v0.V16B(), v1.V16B());
18991 __ Zip2(v19.V16B(), v0.V16B(), v1.V16B());
18992 __ Uzp1(v20.V16B(), v0.V16B(), v1.V16B());
18993 __ Uzp2(v21.V16B(), v0.V16B(), v1.V16B());
18994
18995 END();
18996
18997 RUN();
18998
18999 ASSERT_EQUAL_128(0x1101130315051707, 0x19091b0b1d0d1f0f, q16);
19000 ASSERT_EQUAL_128(0x1000120214041606, 0x18081a0a1c0c1e0e, q17);
19001 ASSERT_EQUAL_128(0x180819091a0a1b0b, 0x1c0c1d0d1e0e1f0f, q18);
19002 ASSERT_EQUAL_128(0x1000110112021303, 0x1404150516061707, q19);
19003 ASSERT_EQUAL_128(0x11131517191b1d1f, 0x01030507090b0d0f, q20);
19004 ASSERT_EQUAL_128(0x10121416181a1c1e, 0x00020406080a0c0e, q21);
19005
19006 TEARDOWN();
19007}
19008
19009
19010TEST(neon_copy_dup_element) {
19011 SETUP();
19012
19013 START();
19014
19015 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19016 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19017 __ Movi(v2.V2D(), 0xffeddccbbaae9988, 0x0011223344556677);
19018 __ Movi(v3.V2D(), 0x7766554433221100, 0x8899aabbccddeeff);
19019 __ Movi(v4.V2D(), 0x7766554433221100, 0x0123456789abcdef);
19020 __ Movi(v5.V2D(), 0x0011223344556677, 0x0123456789abcdef);
19021
19022 __ Dup(v16.V16B(), v0.B(), 0);
19023 __ Dup(v17.V8H(), v1.H(), 7);
19024 __ Dup(v18.V4S(), v1.S(), 3);
19025 __ Dup(v19.V2D(), v0.D(), 0);
19026
19027 __ Dup(v20.V8B(), v0.B(), 0);
19028 __ Dup(v21.V4H(), v1.H(), 7);
19029 __ Dup(v22.V2S(), v1.S(), 3);
19030
19031 __ Dup(v23.B(), v0.B(), 0);
19032 __ Dup(v24.H(), v1.H(), 7);
19033 __ Dup(v25.S(), v1.S(), 3);
19034 __ Dup(v26.D(), v0.D(), 0);
19035
19036 __ Dup(v2.V16B(), v2.B(), 0);
19037 __ Dup(v3.V8H(), v3.H(), 7);
19038 __ Dup(v4.V4S(), v4.S(), 0);
19039 __ Dup(v5.V2D(), v5.D(), 1);
19040
19041 END();
19042
19043 RUN();
19044
19045 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q16);
19046 ASSERT_EQUAL_128(0xffedffedffedffed, 0xffedffedffedffed, q17);
19047 ASSERT_EQUAL_128(0xffeddccbffeddccb, 0xffeddccbffeddccb, q18);
19048 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x8899aabbccddeeff, q19);
19049
19050 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q20);
19051 ASSERT_EQUAL_128(0, 0xffedffedffedffed, q21);
19052 ASSERT_EQUAL_128(0, 0xffeddccbffeddccb, q22);
19053
19054 ASSERT_EQUAL_128(0, 0x00000000000000ff, q23);
19055 ASSERT_EQUAL_128(0, 0x000000000000ffed, q24);
19056 ASSERT_EQUAL_128(0, 0x00000000ffeddccb, q25);
19057 ASSERT_EQUAL_128(0, 0x8899aabbccddeeff, q26);
19058
19059 ASSERT_EQUAL_128(0x7777777777777777, 0x7777777777777777, q2);
19060 ASSERT_EQUAL_128(0x7766776677667766, 0x7766776677667766, q3);
19061 ASSERT_EQUAL_128(0x89abcdef89abcdef, 0x89abcdef89abcdef, q4);
19062 ASSERT_EQUAL_128(0x0011223344556677, 0x0011223344556677, q5);
19063 TEARDOWN();
19064}
19065
19066
19067TEST(neon_copy_dup_general) {
19068 SETUP();
19069
19070 START();
19071
19072 __ Mov(x0, 0x0011223344556677);
19073
19074 __ Dup(v16.V16B(), w0);
19075 __ Dup(v17.V8H(), w0);
19076 __ Dup(v18.V4S(), w0);
19077 __ Dup(v19.V2D(), x0);
19078
19079 __ Dup(v20.V8B(), w0);
19080 __ Dup(v21.V4H(), w0);
19081 __ Dup(v22.V2S(), w0);
19082
19083 __ Dup(v2.V16B(), wzr);
19084 __ Dup(v3.V8H(), wzr);
19085 __ Dup(v4.V4S(), wzr);
19086 __ Dup(v5.V2D(), xzr);
19087
19088 END();
19089
19090 RUN();
19091
19092 ASSERT_EQUAL_128(0x7777777777777777, 0x7777777777777777, q16);
19093 ASSERT_EQUAL_128(0x6677667766776677, 0x6677667766776677, q17);
19094 ASSERT_EQUAL_128(0x4455667744556677, 0x4455667744556677, q18);
19095 ASSERT_EQUAL_128(0x0011223344556677, 0x0011223344556677, q19);
19096
19097 ASSERT_EQUAL_128(0, 0x7777777777777777, q20);
19098 ASSERT_EQUAL_128(0, 0x6677667766776677, q21);
19099 ASSERT_EQUAL_128(0, 0x4455667744556677, q22);
19100
19101 ASSERT_EQUAL_128(0, 0, q2);
19102 ASSERT_EQUAL_128(0, 0, q3);
19103 ASSERT_EQUAL_128(0, 0, q4);
19104 ASSERT_EQUAL_128(0, 0, q5);
19105 TEARDOWN();
19106}
19107
19108
19109TEST(neon_copy_ins_element) {
19110 SETUP();
19111
19112 START();
19113
19114 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19115 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19116 __ Movi(v16.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19117 __ Movi(v17.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
19118 __ Movi(v18.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19119 __ Movi(v19.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19120
19121 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19122 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19123 __ Movi(v4.V2D(), 0, 0x0123456789abcdef);
19124 __ Movi(v5.V2D(), 0, 0x0123456789abcdef);
19125
19126 __ Ins(v16.V16B(), 15, v0.V16B(), 0);
19127 __ Ins(v17.V8H(), 0, v1.V8H(), 7);
19128 __ Ins(v18.V4S(), 3, v1.V4S(), 0);
19129 __ Ins(v19.V2D(), 1, v0.V2D(), 0);
19130
19131 __ Ins(v2.V16B(), 2, v2.V16B(), 0);
19132 __ Ins(v3.V8H(), 0, v3.V8H(), 7);
19133 __ Ins(v4.V4S(), 3, v4.V4S(), 0);
19134 __ Ins(v5.V2D(), 0, v5.V2D(), 1);
19135
19136 END();
19137
19138 RUN();
19139
19140 ASSERT_EQUAL_128(0xff23456789abcdef, 0xfedcba9876543210, q16);
19141 ASSERT_EQUAL_128(0xfedcba9876543210, 0x0123456789abffed, q17);
19142 ASSERT_EQUAL_128(0x3322110044556677, 0x8899aabbccddeeff, q18);
19143 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x8899aabbccddeeff, q19);
19144
19145 ASSERT_EQUAL_128(0, 0x0011223344776677, q2);
19146 ASSERT_EQUAL_128(0, 0x8899aabbccdd0000, q3);
19147 ASSERT_EQUAL_128(0x89abcdef00000000, 0x0123456789abcdef, q4);
19148 ASSERT_EQUAL_128(0, 0, q5);
19149 TEARDOWN();
19150}
19151
19152
19153TEST(neon_copy_mov_element) {
19154 SETUP();
19155
19156 START();
19157
19158 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19159 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19160 __ Movi(v16.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19161 __ Movi(v17.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
19162 __ Movi(v18.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19163 __ Movi(v19.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19164
19165 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19166 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19167 __ Movi(v4.V2D(), 0, 0x0123456789abcdef);
19168 __ Movi(v5.V2D(), 0, 0x0123456789abcdef);
19169
19170 __ Mov(v16.V16B(), 15, v0.V16B(), 0);
19171 __ Mov(v17.V8H(), 0, v1.V8H(), 7);
19172 __ Mov(v18.V4S(), 3, v1.V4S(), 0);
19173 __ Mov(v19.V2D(), 1, v0.V2D(), 0);
19174
19175 __ Mov(v2.V16B(), 2, v2.V16B(), 0);
19176 __ Mov(v3.V8H(), 0, v3.V8H(), 7);
19177 __ Mov(v4.V4S(), 3, v4.V4S(), 0);
19178 __ Mov(v5.V2D(), 0, v5.V2D(), 1);
19179
19180 END();
19181
19182 RUN();
19183
19184 ASSERT_EQUAL_128(0xff23456789abcdef, 0xfedcba9876543210, q16);
19185 ASSERT_EQUAL_128(0xfedcba9876543210, 0x0123456789abffed, q17);
19186 ASSERT_EQUAL_128(0x3322110044556677, 0x8899aabbccddeeff, q18);
19187 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x8899aabbccddeeff, q19);
19188
19189 ASSERT_EQUAL_128(0, 0x0011223344776677, q2);
19190 ASSERT_EQUAL_128(0, 0x8899aabbccdd0000, q3);
19191 ASSERT_EQUAL_128(0x89abcdef00000000, 0x0123456789abcdef, q4);
19192 ASSERT_EQUAL_128(0, 0, q5);
19193 TEARDOWN();
19194}
19195
19196
19197TEST(neon_copy_smov) {
19198 SETUP();
19199
19200 START();
19201
19202 __ Movi(v0.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19203
19204 __ Smov(w0, v0.B(), 7);
19205 __ Smov(w1, v0.B(), 15);
19206
19207 __ Smov(w2, v0.H(), 0);
19208 __ Smov(w3, v0.H(), 3);
19209
19210 __ Smov(x4, v0.B(), 7);
19211 __ Smov(x5, v0.B(), 15);
19212
19213 __ Smov(x6, v0.H(), 0);
19214 __ Smov(x7, v0.H(), 3);
19215
19216 __ Smov(x16, v0.S(), 0);
19217 __ Smov(x17, v0.S(), 1);
19218
19219 END();
19220
19221 RUN();
19222
19223 ASSERT_EQUAL_32(0xfffffffe, w0);
19224 ASSERT_EQUAL_32(0x00000001, w1);
19225 ASSERT_EQUAL_32(0x00003210, w2);
19226 ASSERT_EQUAL_32(0xfffffedc, w3);
19227 ASSERT_EQUAL_64(0xfffffffffffffffe, x4);
19228 ASSERT_EQUAL_64(0x0000000000000001, x5);
19229 ASSERT_EQUAL_64(0x0000000000003210, x6);
19230 ASSERT_EQUAL_64(0xfffffffffffffedc, x7);
19231 ASSERT_EQUAL_64(0x0000000076543210, x16);
19232 ASSERT_EQUAL_64(0xfffffffffedcba98, x17);
19233
19234 TEARDOWN();
19235}
19236
19237
19238TEST(neon_copy_umov_mov) {
19239 SETUP();
19240
19241 START();
19242
19243 __ Movi(v0.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19244
19245 __ Umov(w0, v0.B(), 15);
19246 __ Umov(w1, v0.H(), 0);
19247 __ Umov(w2, v0.S(), 3);
19248 __ Umov(x3, v0.D(), 1);
19249
19250 __ Mov(w4, v0.S(), 3);
19251 __ Mov(x5, v0.D(), 1);
19252
19253 END();
19254
19255 RUN();
19256
19257 ASSERT_EQUAL_32(0x00000001, w0);
19258 ASSERT_EQUAL_32(0x00003210, w1);
19259 ASSERT_EQUAL_32(0x01234567, w2);
19260 ASSERT_EQUAL_64(0x0123456789abcdef, x3);
19261 ASSERT_EQUAL_32(0x01234567, w4);
19262 ASSERT_EQUAL_64(0x0123456789abcdef, x5);
19263
19264 TEARDOWN();
19265}
19266
19267
19268TEST(neon_copy_ins_general) {
19269 SETUP();
19270
19271 START();
19272
19273 __ Mov(x0, 0x0011223344556677);
19274 __ Movi(v16.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19275 __ Movi(v17.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
19276 __ Movi(v18.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19277 __ Movi(v19.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19278
19279 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19280 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19281 __ Movi(v4.V2D(), 0, 0x0123456789abcdef);
19282 __ Movi(v5.V2D(), 0, 0x0123456789abcdef);
19283
19284 __ Ins(v16.V16B(), 15, w0);
19285 __ Ins(v17.V8H(), 0, w0);
19286 __ Ins(v18.V4S(), 3, w0);
19287 __ Ins(v19.V2D(), 0, x0);
19288
19289 __ Ins(v2.V16B(), 2, w0);
19290 __ Ins(v3.V8H(), 0, w0);
19291 __ Ins(v4.V4S(), 3, w0);
19292 __ Ins(v5.V2D(), 1, x0);
19293
19294 END();
19295
19296 RUN();
19297
19298 ASSERT_EQUAL_128(0x7723456789abcdef, 0xfedcba9876543210, q16);
19299 ASSERT_EQUAL_128(0xfedcba9876543210, 0x0123456789ab6677, q17);
19300 ASSERT_EQUAL_128(0x4455667744556677, 0x8899aabbccddeeff, q18);
19301 ASSERT_EQUAL_128(0x0011223344556677, 0x0011223344556677, q19);
19302
19303 ASSERT_EQUAL_128(0, 0x0011223344776677, q2);
19304 ASSERT_EQUAL_128(0, 0x8899aabbccdd6677, q3);
19305 ASSERT_EQUAL_128(0x4455667700000000, 0x0123456789abcdef, q4);
19306 ASSERT_EQUAL_128(0x0011223344556677, 0x0123456789abcdef, q5);
19307 TEARDOWN();
19308}
19309
19310
19311TEST(neon_extract_ext) {
19312 SETUP();
19313
19314 START();
19315
19316 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19317 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19318
19319 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19320 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19321
19322 __ Ext(v16.V16B(), v0.V16B(), v1.V16B(), 0);
19323 __ Ext(v17.V16B(), v0.V16B(), v1.V16B(), 15);
19324 __ Ext(v1.V16B(), v0.V16B(), v1.V16B(), 8); // Dest is same as one Src
19325 __ Ext(v0.V16B(), v0.V16B(), v0.V16B(), 8); // All reg are the same
19326
19327 __ Ext(v18.V8B(), v2.V8B(), v3.V8B(), 0);
19328 __ Ext(v19.V8B(), v2.V8B(), v3.V8B(), 7);
19329 __ Ext(v2.V8B(), v2.V8B(), v3.V8B(), 4); // Dest is same as one Src
19330 __ Ext(v3.V8B(), v3.V8B(), v3.V8B(), 4); // All reg are the same
19331
19332 END();
19333
19334 RUN();
19335
19336 ASSERT_EQUAL_128(0x0011223344556677, 0x8899aabbccddeeff, q16);
19337 ASSERT_EQUAL_128(0xeddccbbaae998877, 0x6655443322110000, q17);
19338 ASSERT_EQUAL_128(0x7766554433221100, 0x0011223344556677, q1);
19339 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x0011223344556677, q0);
19340
19341 ASSERT_EQUAL_128(0, 0x0011223344556677, q18);
19342 ASSERT_EQUAL_128(0, 0x99aabbccddeeff00, q19);
19343 ASSERT_EQUAL_128(0, 0xccddeeff00112233, q2);
19344 ASSERT_EQUAL_128(0, 0xccddeeff8899aabb, q3);
19345 TEARDOWN();
19346}
19347
19348
19349TEST(neon_3different_uaddl) {
19350 SETUP();
19351
19352 START();
19353
19354 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000);
19355 __ Movi(v1.V2D(), 0, 0x00010280810e0fff);
19356 __ Movi(v2.V2D(), 0, 0x0101010101010101);
19357
19358 __ Movi(v3.V2D(), 0x0000000000000000, 0x0000000000000000);
19359 __ Movi(v4.V2D(), 0x0000000000000000, 0x0000000000000000);
19360 __ Movi(v5.V2D(), 0, 0x0000000180008001);
19361 __ Movi(v6.V2D(), 0, 0x000e000ff000ffff);
19362 __ Movi(v7.V2D(), 0, 0x0001000100010001);
19363
19364 __ Movi(v16.V2D(), 0x0000000000000000, 0x0000000000000000);
19365 __ Movi(v17.V2D(), 0x0000000000000000, 0x0000000000000000);
19366 __ Movi(v18.V2D(), 0, 0x0000000000000001);
19367 __ Movi(v19.V2D(), 0, 0x80000001ffffffff);
19368 __ Movi(v20.V2D(), 0, 0x0000000100000001);
19369
19370 __ Uaddl(v0.V8H(), v1.V8B(), v2.V8B());
19371
19372 __ Uaddl(v3.V4S(), v5.V4H(), v7.V4H());
19373 __ Uaddl(v4.V4S(), v6.V4H(), v7.V4H());
19374
19375 __ Uaddl(v16.V2D(), v18.V2S(), v20.V2S());
19376 __ Uaddl(v17.V2D(), v19.V2S(), v20.V2S());
19377
19378
19379 END();
19380
19381 RUN();
19382
19383 ASSERT_EQUAL_128(0x0001000200030081, 0x0082000f00100100, q0);
19384 ASSERT_EQUAL_128(0x0000000100000002, 0x0000800100008002, q3);
19385 ASSERT_EQUAL_128(0x0000000f00000010, 0x0000f00100010000, q4);
19386 ASSERT_EQUAL_128(0x0000000000000001, 0x0000000000000002, q16);
19387 ASSERT_EQUAL_128(0x0000000080000002, 0x0000000100000000, q17);
19388 TEARDOWN();
19389}
19390
19391
19392TEST(neon_3different_addhn_subhn) {
19393 SETUP();
19394
19395 START();
19396
19397 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19398 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19399 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19400 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
19401 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
19402
19403 __ Addhn(v16.V8B(), v0.V8H(), v1.V8H());
19404 __ Addhn2(v16.V16B(), v2.V8H(), v3.V8H());
19405 __ Raddhn(v17.V8B(), v0.V8H(), v1.V8H());
19406 __ Raddhn2(v17.V16B(), v2.V8H(), v3.V8H());
19407 __ Subhn(v18.V8B(), v0.V8H(), v1.V8H());
19408 __ Subhn2(v18.V16B(), v2.V8H(), v3.V8H());
19409 __ Rsubhn(v19.V8B(), v0.V8H(), v1.V8H());
19410 __ Rsubhn2(v19.V16B(), v2.V8H(), v3.V8H());
19411
19412 END();
19413
19414 RUN();
19415
19416 ASSERT_EQUAL_128(0x0000ff007fff7fff, 0xff81817f80ff0100, q16);
19417 ASSERT_EQUAL_128(0x0000000080008000, 0xff81817f81ff0201, q17);
19418 ASSERT_EQUAL_128(0x0000ffff80008000, 0xff80817f80ff0100, q18);
19419 ASSERT_EQUAL_128(0x0000000080008000, 0xff81827f81ff0101, q19);
19420 TEARDOWN();
19421}
19422
19423TEST(neon_d_only_scalar) {
19424 SETUP();
19425
19426 START();
19427
19428 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
19429 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
19430 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x1000000010001010);
19431 __ Movi(v3.V2D(), 0xffffffffffffffff, 2);
19432 __ Movi(v4.V2D(), 0xffffffffffffffff, -2);
19433
19434 __ Add(d16, d0, d0);
19435 __ Add(d17, d1, d1);
19436 __ Add(d18, d2, d2);
19437 __ Sub(d19, d0, d0);
19438 __ Sub(d20, d0, d1);
19439 __ Sub(d21, d1, d0);
19440 __ Ushl(d22, d0, d3);
19441 __ Ushl(d23, d0, d4);
19442 __ Sshl(d24, d0, d3);
19443 __ Sshl(d25, d0, d4);
19444 __ Ushr(d26, d0, 1);
19445 __ Sshr(d27, d0, 3);
19446 __ Shl(d28, d0, 0);
19447 __ Shl(d29, d0, 16);
19448
19449 END();
19450
19451 RUN();
19452
19453 ASSERT_EQUAL_128(0, 0xe0000001e001e1e0, q16);
19454 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q17);
19455 ASSERT_EQUAL_128(0, 0x2000000020002020, q18);
19456 ASSERT_EQUAL_128(0, 0, q19);
19457 ASSERT_EQUAL_128(0, 0x7000000170017171, q20);
19458 ASSERT_EQUAL_128(0, 0x8ffffffe8ffe8e8f, q21);
19459 ASSERT_EQUAL_128(0, 0xc0000003c003c3c0, q22);
19460 ASSERT_EQUAL_128(0, 0x3c0000003c003c3c, q23);
19461 ASSERT_EQUAL_128(0, 0xc0000003c003c3c0, q24);
19462 ASSERT_EQUAL_128(0, 0xfc0000003c003c3c, q25);
19463 ASSERT_EQUAL_128(0, 0x7800000078007878, q26);
19464 ASSERT_EQUAL_128(0, 0xfe0000001e001e1e, q27);
19465 ASSERT_EQUAL_128(0, 0xf0000000f000f0f0, q28);
19466 ASSERT_EQUAL_128(0, 0x0000f000f0f00000, q29);
19467
19468 TEARDOWN();
19469}
19470
19471
19472TEST(neon_sqshl_imm_scalar) {
19473 SETUP();
19474
19475 START();
19476
19477 __ Movi(v0.V2D(), 0x0, 0x7f);
19478 __ Movi(v1.V2D(), 0x0, 0x80);
19479 __ Movi(v2.V2D(), 0x0, 0x01);
19480 __ Sqshl(b16, b0, 1);
19481 __ Sqshl(b17, b1, 1);
19482 __ Sqshl(b18, b2, 1);
19483
19484 __ Movi(v0.V2D(), 0x0, 0x7fff);
19485 __ Movi(v1.V2D(), 0x0, 0x8000);
19486 __ Movi(v2.V2D(), 0x0, 0x0001);
19487 __ Sqshl(h19, h0, 1);
19488 __ Sqshl(h20, h1, 1);
19489 __ Sqshl(h21, h2, 1);
19490
19491 __ Movi(v0.V2D(), 0x0, 0x7fffffff);
19492 __ Movi(v1.V2D(), 0x0, 0x80000000);
19493 __ Movi(v2.V2D(), 0x0, 0x00000001);
19494 __ Sqshl(s22, s0, 1);
19495 __ Sqshl(s23, s1, 1);
19496 __ Sqshl(s24, s2, 1);
19497
19498 __ Movi(v0.V2D(), 0x0, 0x7fffffffffffffff);
19499 __ Movi(v1.V2D(), 0x0, 0x8000000000000000);
19500 __ Movi(v2.V2D(), 0x0, 0x0000000000000001);
19501 __ Sqshl(d25, d0, 1);
19502 __ Sqshl(d26, d1, 1);
19503 __ Sqshl(d27, d2, 1);
19504
19505 END();
19506
19507 RUN();
19508
19509 ASSERT_EQUAL_128(0, 0x7f, q16);
19510 ASSERT_EQUAL_128(0, 0x80, q17);
19511 ASSERT_EQUAL_128(0, 0x02, q18);
19512
19513 ASSERT_EQUAL_128(0, 0x7fff, q19);
19514 ASSERT_EQUAL_128(0, 0x8000, q20);
19515 ASSERT_EQUAL_128(0, 0x0002, q21);
19516
19517 ASSERT_EQUAL_128(0, 0x7fffffff, q22);
19518 ASSERT_EQUAL_128(0, 0x80000000, q23);
19519 ASSERT_EQUAL_128(0, 0x00000002, q24);
19520
19521 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q25);
19522 ASSERT_EQUAL_128(0, 0x8000000000000000, q26);
19523 ASSERT_EQUAL_128(0, 0x0000000000000002, q27);
19524
19525 TEARDOWN();
19526}
19527
19528
19529TEST(neon_uqshl_imm_scalar) {
19530 SETUP();
19531
19532 START();
19533
19534 __ Movi(v0.V2D(), 0x0, 0x7f);
19535 __ Movi(v1.V2D(), 0x0, 0x80);
19536 __ Movi(v2.V2D(), 0x0, 0x01);
19537 __ Uqshl(b16, b0, 1);
19538 __ Uqshl(b17, b1, 1);
19539 __ Uqshl(b18, b2, 1);
19540
19541 __ Movi(v0.V2D(), 0x0, 0x7fff);
19542 __ Movi(v1.V2D(), 0x0, 0x8000);
19543 __ Movi(v2.V2D(), 0x0, 0x0001);
19544 __ Uqshl(h19, h0, 1);
19545 __ Uqshl(h20, h1, 1);
19546 __ Uqshl(h21, h2, 1);
19547
19548 __ Movi(v0.V2D(), 0x0, 0x7fffffff);
19549 __ Movi(v1.V2D(), 0x0, 0x80000000);
19550 __ Movi(v2.V2D(), 0x0, 0x00000001);
19551 __ Uqshl(s22, s0, 1);
19552 __ Uqshl(s23, s1, 1);
19553 __ Uqshl(s24, s2, 1);
19554
19555 __ Movi(v0.V2D(), 0x0, 0x7fffffffffffffff);
19556 __ Movi(v1.V2D(), 0x0, 0x8000000000000000);
19557 __ Movi(v2.V2D(), 0x0, 0x0000000000000001);
19558 __ Uqshl(d25, d0, 1);
19559 __ Uqshl(d26, d1, 1);
19560 __ Uqshl(d27, d2, 1);
19561
19562 END();
19563
19564 RUN();
19565
19566 ASSERT_EQUAL_128(0, 0xfe, q16);
19567 ASSERT_EQUAL_128(0, 0xff, q17);
19568 ASSERT_EQUAL_128(0, 0x02, q18);
19569
19570 ASSERT_EQUAL_128(0, 0xfffe, q19);
19571 ASSERT_EQUAL_128(0, 0xffff, q20);
19572 ASSERT_EQUAL_128(0, 0x0002, q21);
19573
19574 ASSERT_EQUAL_128(0, 0xfffffffe, q22);
19575 ASSERT_EQUAL_128(0, 0xffffffff, q23);
19576 ASSERT_EQUAL_128(0, 0x00000002, q24);
19577
19578 ASSERT_EQUAL_128(0, 0xfffffffffffffffe, q25);
19579 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q26);
19580 ASSERT_EQUAL_128(0, 0x0000000000000002, q27);
19581
19582 TEARDOWN();
19583}
19584
19585
19586TEST(neon_sqshlu_scalar) {
19587 SETUP();
19588
19589 START();
19590
19591 __ Movi(v0.V2D(), 0x0, 0x7f);
19592 __ Movi(v1.V2D(), 0x0, 0x80);
19593 __ Movi(v2.V2D(), 0x0, 0x01);
19594 __ Sqshlu(b16, b0, 2);
19595 __ Sqshlu(b17, b1, 2);
19596 __ Sqshlu(b18, b2, 2);
19597
19598 __ Movi(v0.V2D(), 0x0, 0x7fff);
19599 __ Movi(v1.V2D(), 0x0, 0x8000);
19600 __ Movi(v2.V2D(), 0x0, 0x0001);
19601 __ Sqshlu(h19, h0, 2);
19602 __ Sqshlu(h20, h1, 2);
19603 __ Sqshlu(h21, h2, 2);
19604
19605 __ Movi(v0.V2D(), 0x0, 0x7fffffff);
19606 __ Movi(v1.V2D(), 0x0, 0x80000000);
19607 __ Movi(v2.V2D(), 0x0, 0x00000001);
19608 __ Sqshlu(s22, s0, 2);
19609 __ Sqshlu(s23, s1, 2);
19610 __ Sqshlu(s24, s2, 2);
19611
19612 __ Movi(v0.V2D(), 0x0, 0x7fffffffffffffff);
19613 __ Movi(v1.V2D(), 0x0, 0x8000000000000000);
19614 __ Movi(v2.V2D(), 0x0, 0x0000000000000001);
19615 __ Sqshlu(d25, d0, 2);
19616 __ Sqshlu(d26, d1, 2);
19617 __ Sqshlu(d27, d2, 2);
19618
19619 END();
19620
19621 RUN();
19622
19623 ASSERT_EQUAL_128(0, 0xff, q16);
19624 ASSERT_EQUAL_128(0, 0x00, q17);
19625 ASSERT_EQUAL_128(0, 0x04, q18);
19626
19627 ASSERT_EQUAL_128(0, 0xffff, q19);
19628 ASSERT_EQUAL_128(0, 0x0000, q20);
19629 ASSERT_EQUAL_128(0, 0x0004, q21);
19630
19631 ASSERT_EQUAL_128(0, 0xffffffff, q22);
19632 ASSERT_EQUAL_128(0, 0x00000000, q23);
19633 ASSERT_EQUAL_128(0, 0x00000004, q24);
19634
19635 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q25);
19636 ASSERT_EQUAL_128(0, 0x0000000000000000, q26);
19637 ASSERT_EQUAL_128(0, 0x0000000000000004, q27);
19638
19639 TEARDOWN();
19640}
19641
19642
19643TEST(neon_sshll) {
19644 SETUP();
19645
19646 START();
19647
19648 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19649 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19650 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19651
19652 __ Sshll(v16.V8H(), v0.V8B(), 4);
19653 __ Sshll2(v17.V8H(), v0.V16B(), 4);
19654
19655 __ Sshll(v18.V4S(), v1.V4H(), 8);
19656 __ Sshll2(v19.V4S(), v1.V8H(), 8);
19657
19658 __ Sshll(v20.V2D(), v2.V2S(), 16);
19659 __ Sshll2(v21.V2D(), v2.V4S(), 16);
19660
19661 END();
19662
19663 RUN();
19664
19665 ASSERT_EQUAL_128(0xf800f810fff00000, 0x001007f0f800f810, q16);
19666 ASSERT_EQUAL_128(0x07f000100000fff0, 0xf810f80007f00010, q17);
19667 ASSERT_EQUAL_128(0xffffff0000000000, 0x00000100007fff00, q18);
19668 ASSERT_EQUAL_128(0xff800000ff800100, 0xffffff0000000000, q19);
19669 ASSERT_EQUAL_128(0x0000000000000000, 0x00007fffffff0000, q20);
19670 ASSERT_EQUAL_128(0xffff800000000000, 0xffffffffffff0000, q21);
19671 TEARDOWN();
19672}
19673
19674TEST(neon_shll) {
19675 SETUP();
19676
19677 START();
19678
19679 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19680 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19681 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19682
19683 __ Shll(v16.V8H(), v0.V8B(), 8);
19684 __ Shll2(v17.V8H(), v0.V16B(), 8);
19685
19686 __ Shll(v18.V4S(), v1.V4H(), 16);
19687 __ Shll2(v19.V4S(), v1.V8H(), 16);
19688
19689 __ Shll(v20.V2D(), v2.V2S(), 32);
19690 __ Shll2(v21.V2D(), v2.V4S(), 32);
19691
19692 END();
19693
19694 RUN();
19695
19696 ASSERT_EQUAL_128(0x80008100ff000000, 0x01007f0080008100, q16);
19697 ASSERT_EQUAL_128(0x7f0001000000ff00, 0x810080007f000100, q17);
19698 ASSERT_EQUAL_128(0xffff000000000000, 0x000100007fff0000, q18);
19699 ASSERT_EQUAL_128(0x8000000080010000, 0xffff000000000000, q19);
19700 ASSERT_EQUAL_128(0x0000000000000000, 0x7fffffff00000000, q20);
19701 ASSERT_EQUAL_128(0x8000000000000000, 0xffffffff00000000, q21);
19702 TEARDOWN();
19703}
19704
19705TEST(neon_ushll) {
19706 SETUP();
19707
19708 START();
19709
19710 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19711 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19712 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19713
19714 __ Ushll(v16.V8H(), v0.V8B(), 4);
19715 __ Ushll2(v17.V8H(), v0.V16B(), 4);
19716
19717 __ Ushll(v18.V4S(), v1.V4H(), 8);
19718 __ Ushll2(v19.V4S(), v1.V8H(), 8);
19719
19720 __ Ushll(v20.V2D(), v2.V2S(), 16);
19721 __ Ushll2(v21.V2D(), v2.V4S(), 16);
19722
19723 END();
19724
19725 RUN();
19726
19727 ASSERT_EQUAL_128(0x080008100ff00000, 0x001007f008000810, q16);
19728 ASSERT_EQUAL_128(0x07f0001000000ff0, 0x0810080007f00010, q17);
19729 ASSERT_EQUAL_128(0x00ffff0000000000, 0x00000100007fff00, q18);
19730 ASSERT_EQUAL_128(0x0080000000800100, 0x00ffff0000000000, q19);
19731 ASSERT_EQUAL_128(0x0000000000000000, 0x00007fffffff0000, q20);
19732 ASSERT_EQUAL_128(0x0000800000000000, 0x0000ffffffff0000, q21);
19733 TEARDOWN();
19734}
19735
19736
19737TEST(neon_sxtl) {
19738 SETUP();
19739
19740 START();
19741
19742 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19743 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19744 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19745
19746 __ Sxtl(v16.V8H(), v0.V8B());
19747 __ Sxtl2(v17.V8H(), v0.V16B());
19748
19749 __ Sxtl(v18.V4S(), v1.V4H());
19750 __ Sxtl2(v19.V4S(), v1.V8H());
19751
19752 __ Sxtl(v20.V2D(), v2.V2S());
19753 __ Sxtl2(v21.V2D(), v2.V4S());
19754
19755 END();
19756
19757 RUN();
19758
19759 ASSERT_EQUAL_128(0xff80ff81ffff0000, 0x0001007fff80ff81, q16);
19760 ASSERT_EQUAL_128(0x007f00010000ffff, 0xff81ff80007f0001, q17);
19761 ASSERT_EQUAL_128(0xffffffff00000000, 0x0000000100007fff, q18);
19762 ASSERT_EQUAL_128(0xffff8000ffff8001, 0xffffffff00000000, q19);
19763 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
19764 ASSERT_EQUAL_128(0xffffffff80000000, 0xffffffffffffffff, q21);
19765 TEARDOWN();
19766}
19767
19768
19769TEST(neon_uxtl) {
19770 SETUP();
19771
19772 START();
19773
19774 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19775 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19776 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19777
19778 __ Uxtl(v16.V8H(), v0.V8B());
19779 __ Uxtl2(v17.V8H(), v0.V16B());
19780
19781 __ Uxtl(v18.V4S(), v1.V4H());
19782 __ Uxtl2(v19.V4S(), v1.V8H());
19783
19784 __ Uxtl(v20.V2D(), v2.V2S());
19785 __ Uxtl2(v21.V2D(), v2.V4S());
19786
19787 END();
19788
19789 RUN();
19790
19791 ASSERT_EQUAL_128(0x0080008100ff0000, 0x0001007f00800081, q16);
19792 ASSERT_EQUAL_128(0x007f0001000000ff, 0x00810080007f0001, q17);
19793 ASSERT_EQUAL_128(0x0000ffff00000000, 0x0000000100007fff, q18);
19794 ASSERT_EQUAL_128(0x0000800000008001, 0x0000ffff00000000, q19);
19795 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
19796 ASSERT_EQUAL_128(0x0000000080000000, 0x00000000ffffffff, q21);
19797 TEARDOWN();
19798}
19799
19800
19801TEST(neon_ssra) {
19802 SETUP();
19803
19804 START();
19805
19806 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19807 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19808 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19809 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
19810 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
19811
19812 __ Mov(v16.V2D(), v0.V2D());
19813 __ Mov(v17.V2D(), v0.V2D());
19814 __ Mov(v18.V2D(), v1.V2D());
19815 __ Mov(v19.V2D(), v1.V2D());
19816 __ Mov(v20.V2D(), v2.V2D());
19817 __ Mov(v21.V2D(), v2.V2D());
19818 __ Mov(v22.V2D(), v3.V2D());
19819 __ Mov(v23.V2D(), v4.V2D());
19820 __ Mov(v24.V2D(), v3.V2D());
19821 __ Mov(v25.V2D(), v4.V2D());
19822
19823 __ Ssra(v16.V8B(), v0.V8B(), 4);
19824 __ Ssra(v17.V16B(), v0.V16B(), 4);
19825
19826 __ Ssra(v18.V4H(), v1.V4H(), 8);
19827 __ Ssra(v19.V8H(), v1.V8H(), 8);
19828
19829 __ Ssra(v20.V2S(), v2.V2S(), 16);
19830 __ Ssra(v21.V4S(), v2.V4S(), 16);
19831
19832 __ Ssra(v22.V2D(), v3.V2D(), 32);
19833 __ Ssra(v23.V2D(), v4.V2D(), 32);
19834
19835 __ Ssra(d24, d3, 48);
19836
19837 END();
19838
19839 RUN();
19840
19841 ASSERT_EQUAL_128(0x0000000000000000, 0x7879fe0001867879, q16);
19842 ASSERT_EQUAL_128(0x860100fe79788601, 0x7879fe0001867879, q17);
19843 ASSERT_EQUAL_128(0x0000000000000000, 0xfffe00000001807e, q18);
19844 ASSERT_EQUAL_128(0x7f807f81fffe0000, 0xfffe00000001807e, q19);
19845 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007ffe, q20);
19846 ASSERT_EQUAL_128(0x7fff8000fffffffe, 0x0000000080007ffe, q21);
19847 ASSERT_EQUAL_128(0x7fffffff80000001, 0x800000007ffffffe, q22);
19848 ASSERT_EQUAL_128(0x7fffffff80000000, 0x0000000000000000, q23);
19849 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007ffe, q24);
19850 TEARDOWN();
19851}
19852
19853TEST(neon_srsra) {
19854 SETUP();
19855
19856 START();
19857
19858 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19859 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19860 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19861 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
19862 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
19863
19864 __ Mov(v16.V2D(), v0.V2D());
19865 __ Mov(v17.V2D(), v0.V2D());
19866 __ Mov(v18.V2D(), v1.V2D());
19867 __ Mov(v19.V2D(), v1.V2D());
19868 __ Mov(v20.V2D(), v2.V2D());
19869 __ Mov(v21.V2D(), v2.V2D());
19870 __ Mov(v22.V2D(), v3.V2D());
19871 __ Mov(v23.V2D(), v4.V2D());
19872 __ Mov(v24.V2D(), v3.V2D());
19873 __ Mov(v25.V2D(), v4.V2D());
19874
19875 __ Srsra(v16.V8B(), v0.V8B(), 4);
19876 __ Srsra(v17.V16B(), v0.V16B(), 4);
19877
19878 __ Srsra(v18.V4H(), v1.V4H(), 8);
19879 __ Srsra(v19.V8H(), v1.V8H(), 8);
19880
19881 __ Srsra(v20.V2S(), v2.V2S(), 16);
19882 __ Srsra(v21.V4S(), v2.V4S(), 16);
19883
19884 __ Srsra(v22.V2D(), v3.V2D(), 32);
19885 __ Srsra(v23.V2D(), v4.V2D(), 32);
19886
19887 __ Srsra(d24, d3, 48);
19888
19889 END();
19890
19891 RUN();
19892
19893 ASSERT_EQUAL_128(0x0000000000000000, 0x7879ff0001877879, q16);
19894 ASSERT_EQUAL_128(0x870100ff79788701, 0x7879ff0001877879, q17);
19895 ASSERT_EQUAL_128(0x0000000000000000, 0xffff00000001807f, q18);
19896 ASSERT_EQUAL_128(0x7f807f81ffff0000, 0xffff00000001807f, q19);
19897 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007fff, q20);
19898 ASSERT_EQUAL_128(0x7fff8000ffffffff, 0x0000000080007fff, q21);
19899 ASSERT_EQUAL_128(0x7fffffff80000001, 0x800000007fffffff, q22);
19900 ASSERT_EQUAL_128(0x7fffffff80000000, 0x0000000000000000, q23);
19901 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007fff, q24);
19902
19903 TEARDOWN();
19904}
19905
19906TEST(neon_usra) {
19907 SETUP();
19908
19909 START();
19910
19911 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19912 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19913 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19914 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
19915 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
19916
19917 __ Mov(v16.V2D(), v0.V2D());
19918 __ Mov(v17.V2D(), v0.V2D());
19919 __ Mov(v18.V2D(), v1.V2D());
19920 __ Mov(v19.V2D(), v1.V2D());
19921 __ Mov(v20.V2D(), v2.V2D());
19922 __ Mov(v21.V2D(), v2.V2D());
19923 __ Mov(v22.V2D(), v3.V2D());
19924 __ Mov(v23.V2D(), v4.V2D());
19925 __ Mov(v24.V2D(), v3.V2D());
19926 __ Mov(v25.V2D(), v4.V2D());
19927
19928 __ Usra(v16.V8B(), v0.V8B(), 4);
19929 __ Usra(v17.V16B(), v0.V16B(), 4);
19930
19931 __ Usra(v18.V4H(), v1.V4H(), 8);
19932 __ Usra(v19.V8H(), v1.V8H(), 8);
19933
19934 __ Usra(v20.V2S(), v2.V2S(), 16);
19935 __ Usra(v21.V4S(), v2.V4S(), 16);
19936
19937 __ Usra(v22.V2D(), v3.V2D(), 32);
19938 __ Usra(v23.V2D(), v4.V2D(), 32);
19939
19940 __ Usra(d24, d3, 48);
19941
19942 END();
19943
19944 RUN();
19945
19946 ASSERT_EQUAL_128(0x0000000000000000, 0x88890e0001868889, q16);
19947 ASSERT_EQUAL_128(0x8601000e89888601, 0x88890e0001868889, q17);
19948 ASSERT_EQUAL_128(0x0000000000000000, 0x00fe00000001807e, q18);
19949 ASSERT_EQUAL_128(0x8080808100fe0000, 0x00fe00000001807e, q19);
19950 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007ffe, q20);
19951 ASSERT_EQUAL_128(0x800080000000fffe, 0x0000000080007ffe, q21);
19952 ASSERT_EQUAL_128(0x8000000080000001, 0x800000007ffffffe, q22);
19953 ASSERT_EQUAL_128(0x8000000080000000, 0x0000000000000000, q23);
19954 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007ffe, q24);
19955
19956 TEARDOWN();
19957}
19958
19959TEST(neon_ursra) {
19960 SETUP();
19961
19962 START();
19963
19964 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19965 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19966 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19967 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
19968 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
19969
19970 __ Mov(v16.V2D(), v0.V2D());
19971 __ Mov(v17.V2D(), v0.V2D());
19972 __ Mov(v18.V2D(), v1.V2D());
19973 __ Mov(v19.V2D(), v1.V2D());
19974 __ Mov(v20.V2D(), v2.V2D());
19975 __ Mov(v21.V2D(), v2.V2D());
19976 __ Mov(v22.V2D(), v3.V2D());
19977 __ Mov(v23.V2D(), v4.V2D());
19978 __ Mov(v24.V2D(), v3.V2D());
19979 __ Mov(v25.V2D(), v4.V2D());
19980
19981 __ Ursra(v16.V8B(), v0.V8B(), 4);
19982 __ Ursra(v17.V16B(), v0.V16B(), 4);
19983
19984 __ Ursra(v18.V4H(), v1.V4H(), 8);
19985 __ Ursra(v19.V8H(), v1.V8H(), 8);
19986
19987 __ Ursra(v20.V2S(), v2.V2S(), 16);
19988 __ Ursra(v21.V4S(), v2.V4S(), 16);
19989
19990 __ Ursra(v22.V2D(), v3.V2D(), 32);
19991 __ Ursra(v23.V2D(), v4.V2D(), 32);
19992
19993 __ Ursra(d24, d3, 48);
19994
19995 END();
19996
19997 RUN();
19998
19999 ASSERT_EQUAL_128(0x0000000000000000, 0x88890f0001878889, q16);
20000 ASSERT_EQUAL_128(0x8701000f89888701, 0x88890f0001878889, q17);
20001 ASSERT_EQUAL_128(0x0000000000000000, 0x00ff00000001807f, q18);
20002 ASSERT_EQUAL_128(0x8080808100ff0000, 0x00ff00000001807f, q19);
20003 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007fff, q20);
20004 ASSERT_EQUAL_128(0x800080000000ffff, 0x0000000080007fff, q21);
20005 ASSERT_EQUAL_128(0x8000000080000001, 0x800000007fffffff, q22);
20006 ASSERT_EQUAL_128(0x8000000080000000, 0x0000000000000000, q23);
20007 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007fff, q24);
20008 TEARDOWN();
20009}
20010
20011
20012TEST(neon_uqshl_scalar) {
20013 SETUP();
20014
20015 START();
20016
20017 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20018 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20019 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20020 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20021
20022 __ Uqshl(b16, b0, b2);
20023 __ Uqshl(b17, b0, b3);
20024 __ Uqshl(b18, b1, b2);
20025 __ Uqshl(b19, b1, b3);
20026 __ Uqshl(h20, h0, h2);
20027 __ Uqshl(h21, h0, h3);
20028 __ Uqshl(h22, h1, h2);
20029 __ Uqshl(h23, h1, h3);
20030 __ Uqshl(s24, s0, s2);
20031 __ Uqshl(s25, s0, s3);
20032 __ Uqshl(s26, s1, s2);
20033 __ Uqshl(s27, s1, s3);
20034 __ Uqshl(d28, d0, d2);
20035 __ Uqshl(d29, d0, d3);
20036 __ Uqshl(d30, d1, d2);
20037 __ Uqshl(d31, d1, d3);
20038
20039 END();
20040
20041 RUN();
20042
20043 ASSERT_EQUAL_128(0, 0xff, q16);
20044 ASSERT_EQUAL_128(0, 0x78, q17);
20045 ASSERT_EQUAL_128(0, 0xfe, q18);
20046 ASSERT_EQUAL_128(0, 0x3f, q19);
20047 ASSERT_EQUAL_128(0, 0xffff, q20);
20048 ASSERT_EQUAL_128(0, 0x7878, q21);
20049 ASSERT_EQUAL_128(0, 0xfefe, q22);
20050 ASSERT_EQUAL_128(0, 0x3fbf, q23);
20051 ASSERT_EQUAL_128(0, 0xffffffff, q24);
20052 ASSERT_EQUAL_128(0, 0x78007878, q25);
20053 ASSERT_EQUAL_128(0, 0xfffefefe, q26);
20054 ASSERT_EQUAL_128(0, 0x3fffbfbf, q27);
20055 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q28);
20056 ASSERT_EQUAL_128(0, 0x7800000078007878, q29);
20057 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q30);
20058 ASSERT_EQUAL_128(0, 0x3fffffffbfffbfbf, q31);
20059
20060 TEARDOWN();
20061}
20062
20063
20064TEST(neon_sqshl_scalar) {
20065 SETUP();
20066
20067 START();
20068
20069 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xbfffffffbfffbfbf);
20070 __ Movi(v1.V2D(), 0x5555555555555555, 0x4000000040004040);
20071 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20072 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20073
20074 __ Sqshl(b16, b0, b2);
20075 __ Sqshl(b17, b0, b3);
20076 __ Sqshl(b18, b1, b2);
20077 __ Sqshl(b19, b1, b3);
20078 __ Sqshl(h20, h0, h2);
20079 __ Sqshl(h21, h0, h3);
20080 __ Sqshl(h22, h1, h2);
20081 __ Sqshl(h23, h1, h3);
20082 __ Sqshl(s24, s0, s2);
20083 __ Sqshl(s25, s0, s3);
20084 __ Sqshl(s26, s1, s2);
20085 __ Sqshl(s27, s1, s3);
20086 __ Sqshl(d28, d0, d2);
20087 __ Sqshl(d29, d0, d3);
20088 __ Sqshl(d30, d1, d2);
20089 __ Sqshl(d31, d1, d3);
20090
20091 END();
20092
20093 RUN();
20094
20095 ASSERT_EQUAL_128(0, 0x80, q16);
20096 ASSERT_EQUAL_128(0, 0xdf, q17);
20097 ASSERT_EQUAL_128(0, 0x7f, q18);
20098 ASSERT_EQUAL_128(0, 0x20, q19);
20099 ASSERT_EQUAL_128(0, 0x8000, q20);
20100 ASSERT_EQUAL_128(0, 0xdfdf, q21);
20101 ASSERT_EQUAL_128(0, 0x7fff, q22);
20102 ASSERT_EQUAL_128(0, 0x2020, q23);
20103 ASSERT_EQUAL_128(0, 0x80000000, q24);
20104 ASSERT_EQUAL_128(0, 0xdfffdfdf, q25);
20105 ASSERT_EQUAL_128(0, 0x7fffffff, q26);
20106 ASSERT_EQUAL_128(0, 0x20002020, q27);
20107 ASSERT_EQUAL_128(0, 0x8000000000000000, q28);
20108 ASSERT_EQUAL_128(0, 0xdfffffffdfffdfdf, q29);
20109 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q30);
20110 ASSERT_EQUAL_128(0, 0x2000000020002020, q31);
20111
20112 TEARDOWN();
20113}
20114
20115
20116TEST(neon_urshl_scalar) {
20117 SETUP();
20118
20119 START();
20120
20121 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20122 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20123 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20124 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20125
20126 __ Urshl(d28, d0, d2);
20127 __ Urshl(d29, d0, d3);
20128 __ Urshl(d30, d1, d2);
20129 __ Urshl(d31, d1, d3);
20130
20131 END();
20132
20133 RUN();
20134
20135 ASSERT_EQUAL_128(0, 0xe0000001e001e1e0, q28);
20136 ASSERT_EQUAL_128(0, 0x7800000078007878, q29);
20137 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q30);
20138 ASSERT_EQUAL_128(0, 0x3fffffffbfffbfc0, q31);
20139
20140 TEARDOWN();
20141}
20142
20143
20144TEST(neon_srshl_scalar) {
20145 SETUP();
20146
20147 START();
20148
20149 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xbfffffffbfffbfbf);
20150 __ Movi(v1.V2D(), 0x5555555555555555, 0x4000000040004040);
20151 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20152 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20153
20154 __ Srshl(d28, d0, d2);
20155 __ Srshl(d29, d0, d3);
20156 __ Srshl(d30, d1, d2);
20157 __ Srshl(d31, d1, d3);
20158
20159 END();
20160
20161 RUN();
20162
20163 ASSERT_EQUAL_128(0, 0x7fffffff7fff7f7e, q28);
20164 ASSERT_EQUAL_128(0, 0xdfffffffdfffdfe0, q29);
20165 ASSERT_EQUAL_128(0, 0x8000000080008080, q30);
20166 ASSERT_EQUAL_128(0, 0x2000000020002020, q31);
20167
20168 TEARDOWN();
20169}
20170
20171
20172TEST(neon_uqrshl_scalar) {
20173 SETUP();
20174
20175 START();
20176
20177 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20178 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20179 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20180 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20181
20182 __ Uqrshl(b16, b0, b2);
20183 __ Uqrshl(b17, b0, b3);
20184 __ Uqrshl(b18, b1, b2);
20185 __ Uqrshl(b19, b1, b3);
20186 __ Uqrshl(h20, h0, h2);
20187 __ Uqrshl(h21, h0, h3);
20188 __ Uqrshl(h22, h1, h2);
20189 __ Uqrshl(h23, h1, h3);
20190 __ Uqrshl(s24, s0, s2);
20191 __ Uqrshl(s25, s0, s3);
20192 __ Uqrshl(s26, s1, s2);
20193 __ Uqrshl(s27, s1, s3);
20194 __ Uqrshl(d28, d0, d2);
20195 __ Uqrshl(d29, d0, d3);
20196 __ Uqrshl(d30, d1, d2);
20197 __ Uqrshl(d31, d1, d3);
20198
20199 END();
20200
20201 RUN();
20202
20203 ASSERT_EQUAL_128(0, 0xff, q16);
20204 ASSERT_EQUAL_128(0, 0x78, q17);
20205 ASSERT_EQUAL_128(0, 0xfe, q18);
20206 ASSERT_EQUAL_128(0, 0x40, q19);
20207 ASSERT_EQUAL_128(0, 0xffff, q20);
20208 ASSERT_EQUAL_128(0, 0x7878, q21);
20209 ASSERT_EQUAL_128(0, 0xfefe, q22);
20210 ASSERT_EQUAL_128(0, 0x3fc0, q23);
20211 ASSERT_EQUAL_128(0, 0xffffffff, q24);
20212 ASSERT_EQUAL_128(0, 0x78007878, q25);
20213 ASSERT_EQUAL_128(0, 0xfffefefe, q26);
20214 ASSERT_EQUAL_128(0, 0x3fffbfc0, q27);
20215 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q28);
20216 ASSERT_EQUAL_128(0, 0x7800000078007878, q29);
20217 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q30);
20218 ASSERT_EQUAL_128(0, 0x3fffffffbfffbfc0, q31);
20219
20220 TEARDOWN();
20221}
20222
20223
20224TEST(neon_sqrshl_scalar) {
20225 SETUP();
20226
20227 START();
20228
20229 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xbfffffffbfffbfbf);
20230 __ Movi(v1.V2D(), 0x5555555555555555, 0x4000000040004040);
20231 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20232 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20233
20234 __ Sqrshl(b16, b0, b2);
20235 __ Sqrshl(b17, b0, b3);
20236 __ Sqrshl(b18, b1, b2);
20237 __ Sqrshl(b19, b1, b3);
20238 __ Sqrshl(h20, h0, h2);
20239 __ Sqrshl(h21, h0, h3);
20240 __ Sqrshl(h22, h1, h2);
20241 __ Sqrshl(h23, h1, h3);
20242 __ Sqrshl(s24, s0, s2);
20243 __ Sqrshl(s25, s0, s3);
20244 __ Sqrshl(s26, s1, s2);
20245 __ Sqrshl(s27, s1, s3);
20246 __ Sqrshl(d28, d0, d2);
20247 __ Sqrshl(d29, d0, d3);
20248 __ Sqrshl(d30, d1, d2);
20249 __ Sqrshl(d31, d1, d3);
20250
20251 END();
20252
20253 RUN();
20254
20255 ASSERT_EQUAL_128(0, 0x80, q16);
20256 ASSERT_EQUAL_128(0, 0xe0, q17);
20257 ASSERT_EQUAL_128(0, 0x7f, q18);
20258 ASSERT_EQUAL_128(0, 0x20, q19);
20259 ASSERT_EQUAL_128(0, 0x8000, q20);
20260 ASSERT_EQUAL_128(0, 0xdfe0, q21);
20261 ASSERT_EQUAL_128(0, 0x7fff, q22);
20262 ASSERT_EQUAL_128(0, 0x2020, q23);
20263 ASSERT_EQUAL_128(0, 0x80000000, q24);
20264 ASSERT_EQUAL_128(0, 0xdfffdfe0, q25);
20265 ASSERT_EQUAL_128(0, 0x7fffffff, q26);
20266 ASSERT_EQUAL_128(0, 0x20002020, q27);
20267 ASSERT_EQUAL_128(0, 0x8000000000000000, q28);
20268 ASSERT_EQUAL_128(0, 0xdfffffffdfffdfe0, q29);
20269 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q30);
20270 ASSERT_EQUAL_128(0, 0x2000000020002020, q31);
20271
20272 TEARDOWN();
20273}
20274
20275
20276TEST(neon_uqadd_scalar) {
20277 SETUP();
20278
20279 START();
20280
20281 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20282 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20283 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x1000000010001010);
20284
20285 __ Uqadd(b16, b0, b0);
20286 __ Uqadd(b17, b1, b1);
20287 __ Uqadd(b18, b2, b2);
20288 __ Uqadd(h19, h0, h0);
20289 __ Uqadd(h20, h1, h1);
20290 __ Uqadd(h21, h2, h2);
20291 __ Uqadd(s22, s0, s0);
20292 __ Uqadd(s23, s1, s1);
20293 __ Uqadd(s24, s2, s2);
20294 __ Uqadd(d25, d0, d0);
20295 __ Uqadd(d26, d1, d1);
20296 __ Uqadd(d27, d2, d2);
20297
20298 END();
20299
20300 RUN();
20301
20302 ASSERT_EQUAL_128(0, 0xff, q16);
20303 ASSERT_EQUAL_128(0, 0xfe, q17);
20304 ASSERT_EQUAL_128(0, 0x20, q18);
20305 ASSERT_EQUAL_128(0, 0xffff, q19);
20306 ASSERT_EQUAL_128(0, 0xfefe, q20);
20307 ASSERT_EQUAL_128(0, 0x2020, q21);
20308 ASSERT_EQUAL_128(0, 0xffffffff, q22);
20309 ASSERT_EQUAL_128(0, 0xfffefefe, q23);
20310 ASSERT_EQUAL_128(0, 0x20002020, q24);
20311 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q25);
20312 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q26);
20313 ASSERT_EQUAL_128(0, 0x2000000020002020, q27);
20314
20315 TEARDOWN();
20316}
20317
20318
20319TEST(neon_sqadd_scalar) {
20320 SETUP();
20321
20322 START();
20323
20324 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0x8000000180018181);
20325 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20326 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x1000000010001010);
20327
20328 __ Sqadd(b16, b0, b0);
20329 __ Sqadd(b17, b1, b1);
20330 __ Sqadd(b18, b2, b2);
20331 __ Sqadd(h19, h0, h0);
20332 __ Sqadd(h20, h1, h1);
20333 __ Sqadd(h21, h2, h2);
20334 __ Sqadd(s22, s0, s0);
20335 __ Sqadd(s23, s1, s1);
20336 __ Sqadd(s24, s2, s2);
20337 __ Sqadd(d25, d0, d0);
20338 __ Sqadd(d26, d1, d1);
20339 __ Sqadd(d27, d2, d2);
20340
20341 END();
20342
20343 RUN();
20344
20345 ASSERT_EQUAL_128(0, 0x80, q16);
20346 ASSERT_EQUAL_128(0, 0x7f, q17);
20347 ASSERT_EQUAL_128(0, 0x20, q18);
20348 ASSERT_EQUAL_128(0, 0x8000, q19);
20349 ASSERT_EQUAL_128(0, 0x7fff, q20);
20350 ASSERT_EQUAL_128(0, 0x2020, q21);
20351 ASSERT_EQUAL_128(0, 0x80000000, q22);
20352 ASSERT_EQUAL_128(0, 0x7fffffff, q23);
20353 ASSERT_EQUAL_128(0, 0x20002020, q24);
20354 ASSERT_EQUAL_128(0, 0x8000000000000000, q25);
20355 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q26);
20356 ASSERT_EQUAL_128(0, 0x2000000020002020, q27);
20357
20358 TEARDOWN();
20359}
20360
20361
20362TEST(neon_uqsub_scalar) {
20363 SETUP();
20364
20365 START();
20366
20367 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20368 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20369
20370 __ Uqsub(b16, b0, b0);
20371 __ Uqsub(b17, b0, b1);
20372 __ Uqsub(b18, b1, b0);
20373 __ Uqsub(h19, h0, h0);
20374 __ Uqsub(h20, h0, h1);
20375 __ Uqsub(h21, h1, h0);
20376 __ Uqsub(s22, s0, s0);
20377 __ Uqsub(s23, s0, s1);
20378 __ Uqsub(s24, s1, s0);
20379 __ Uqsub(d25, d0, d0);
20380 __ Uqsub(d26, d0, d1);
20381 __ Uqsub(d27, d1, d0);
20382
20383 END();
20384
20385 RUN();
20386
20387 ASSERT_EQUAL_128(0, 0, q16);
20388 ASSERT_EQUAL_128(0, 0x71, q17);
20389 ASSERT_EQUAL_128(0, 0, q18);
20390
20391 ASSERT_EQUAL_128(0, 0, q19);
20392 ASSERT_EQUAL_128(0, 0x7171, q20);
20393 ASSERT_EQUAL_128(0, 0, q21);
20394
20395 ASSERT_EQUAL_128(0, 0, q22);
20396 ASSERT_EQUAL_128(0, 0x70017171, q23);
20397 ASSERT_EQUAL_128(0, 0, q24);
20398
20399 ASSERT_EQUAL_128(0, 0, q25);
20400 ASSERT_EQUAL_128(0, 0x7000000170017171, q26);
20401 ASSERT_EQUAL_128(0, 0, q27);
20402
20403 TEARDOWN();
20404}
20405
20406
20407TEST(neon_sqsub_scalar) {
20408 SETUP();
20409
20410 START();
20411
20412 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20413 __ Movi(v1.V2D(), 0x5555555555555555, 0x7eeeeeee7eee7e7e);
20414
20415 __ Sqsub(b16, b0, b0);
20416 __ Sqsub(b17, b0, b1);
20417 __ Sqsub(b18, b1, b0);
20418 __ Sqsub(h19, h0, h0);
20419 __ Sqsub(h20, h0, h1);
20420 __ Sqsub(h21, h1, h0);
20421 __ Sqsub(s22, s0, s0);
20422 __ Sqsub(s23, s0, s1);
20423 __ Sqsub(s24, s1, s0);
20424 __ Sqsub(d25, d0, d0);
20425 __ Sqsub(d26, d0, d1);
20426 __ Sqsub(d27, d1, d0);
20427
20428 END();
20429
20430 RUN();
20431
20432 ASSERT_EQUAL_128(0, 0, q16);
20433 ASSERT_EQUAL_128(0, 0x80, q17);
20434 ASSERT_EQUAL_128(0, 0x7f, q18);
20435
20436 ASSERT_EQUAL_128(0, 0, q19);
20437 ASSERT_EQUAL_128(0, 0x8000, q20);
20438 ASSERT_EQUAL_128(0, 0x7fff, q21);
20439
20440 ASSERT_EQUAL_128(0, 0, q22);
20441 ASSERT_EQUAL_128(0, 0x80000000, q23);
20442 ASSERT_EQUAL_128(0, 0x7fffffff, q24);
20443
20444 ASSERT_EQUAL_128(0, 0, q25);
20445 ASSERT_EQUAL_128(0, 0x8000000000000000, q26);
20446 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q27);
20447
20448 TEARDOWN();
20449}
20450
20451
20452TEST(neon_fmla_fmls) {
20453 SETUP();
20454
20455 START();
20456 __ Movi(v0.V2D(), 0x3f80000040000000, 0x4100000000000000);
20457 __ Movi(v1.V2D(), 0x400000003f800000, 0x000000003f800000);
20458 __ Movi(v2.V2D(), 0x3f800000ffffffff, 0x7f800000ff800000);
20459 __ Mov(v16.V16B(), v0.V16B());
20460 __ Mov(v17.V16B(), v0.V16B());
20461 __ Mov(v18.V16B(), v0.V16B());
20462 __ Mov(v19.V16B(), v0.V16B());
20463 __ Mov(v20.V16B(), v0.V16B());
20464 __ Mov(v21.V16B(), v0.V16B());
20465
20466 __ Fmla(v16.V2S(), v1.V2S(), v2.V2S());
20467 __ Fmla(v17.V4S(), v1.V4S(), v2.V4S());
20468 __ Fmla(v18.V2D(), v1.V2D(), v2.V2D());
20469 __ Fmls(v19.V2S(), v1.V2S(), v2.V2S());
20470 __ Fmls(v20.V4S(), v1.V4S(), v2.V4S());
20471 __ Fmls(v21.V2D(), v1.V2D(), v2.V2D());
20472 END();
20473
20474 RUN();
20475
20476 ASSERT_EQUAL_128(0x0000000000000000, 0x7fc00000ff800000, q16);
20477 ASSERT_EQUAL_128(0x40400000ffffffff, 0x7fc00000ff800000, q17);
20478 ASSERT_EQUAL_128(0x3f9800015f8003f7, 0x41000000000000fe, q18);
20479 ASSERT_EQUAL_128(0x0000000000000000, 0x7fc000007f800000, q19);
20480 ASSERT_EQUAL_128(0xbf800000ffffffff, 0x7fc000007f800000, q20);
20481 ASSERT_EQUAL_128(0xbf8000023f0007ee, 0x40fffffffffffe04, q21);
20482
20483 TEARDOWN();
20484}
20485
20486
20487TEST(neon_fmulx_scalar) {
20488 SETUP();
20489
20490 START();
20491 __ Fmov(s0, 2.0);
20492 __ Fmov(s1, 0.5);
20493 __ Fmov(s2, 0.0);
20494 __ Fmov(s3, -0.0);
20495 __ Fmov(s4, kFP32PositiveInfinity);
20496 __ Fmov(s5, kFP32NegativeInfinity);
20497 __ Fmulx(s16, s0, s1);
20498 __ Fmulx(s17, s2, s4);
20499 __ Fmulx(s18, s2, s5);
20500 __ Fmulx(s19, s3, s4);
20501 __ Fmulx(s20, s3, s5);
20502
20503 __ Fmov(d21, 2.0);
20504 __ Fmov(d22, 0.5);
20505 __ Fmov(d23, 0.0);
20506 __ Fmov(d24, -0.0);
20507 __ Fmov(d25, kFP64PositiveInfinity);
20508 __ Fmov(d26, kFP64NegativeInfinity);
20509 __ Fmulx(d27, d21, d22);
20510 __ Fmulx(d28, d23, d25);
20511 __ Fmulx(d29, d23, d26);
20512 __ Fmulx(d30, d24, d25);
20513 __ Fmulx(d31, d24, d26);
20514 END();
20515
20516 RUN();
20517
20518 ASSERT_EQUAL_FP32(1.0, s16);
20519 ASSERT_EQUAL_FP32(2.0, s17);
20520 ASSERT_EQUAL_FP32(-2.0, s18);
20521 ASSERT_EQUAL_FP32(-2.0, s19);
20522 ASSERT_EQUAL_FP32(2.0, s20);
20523 ASSERT_EQUAL_FP64(1.0, d27);
20524 ASSERT_EQUAL_FP64(2.0, d28);
20525 ASSERT_EQUAL_FP64(-2.0, d29);
20526 ASSERT_EQUAL_FP64(-2.0, d30);
20527 ASSERT_EQUAL_FP64(2.0, d31);
20528
20529 TEARDOWN();
20530}
20531
20532
20533TEST(crc32b) {
20534 SETUP();
20535 START();
20536
20537 __ Mov(w0, 0);
20538 __ Mov(w1, 0);
20539 __ Crc32b(w10, w0, w1);
20540
20541 __ Mov(w0, 0x1);
20542 __ Mov(w1, 0x138);
20543 __ Crc32b(w11, w0, w1);
20544
20545 __ Mov(w0, 0x1);
20546 __ Mov(w1, 0x38);
20547 __ Crc32b(w12, w0, w1);
20548
20549 __ Mov(w0, 0);
20550 __ Mov(w1, 128);
20551 __ Crc32b(w13, w0, w1);
20552
20553 __ Mov(w0, UINT32_MAX);
20554 __ Mov(w1, 255);
20555 __ Crc32b(w14, w0, w1);
20556
20557 __ Mov(w0, 0x00010001);
20558 __ Mov(w1, 0x10001000);
20559 __ Crc32b(w15, w0, w1);
20560
20561 END();
20562 RUN();
20563
20564 ASSERT_EQUAL_64(0x0, x10);
20565 ASSERT_EQUAL_64(0x5f058808, x11);
20566 ASSERT_EQUAL_64(0x5f058808, x12);
20567 ASSERT_EQUAL_64(0xedb88320, x13);
20568 ASSERT_EQUAL_64(0x00ffffff, x14);
20569 ASSERT_EQUAL_64(0x77073196, x15);
20570
20571 TEARDOWN();
20572}
20573
20574
20575TEST(crc32h) {
20576 SETUP();
20577 START();
20578
20579 __ Mov(w0, 0);
20580 __ Mov(w1, 0);
20581 __ Crc32h(w10, w0, w1);
20582
20583 __ Mov(w0, 0x1);
20584 __ Mov(w1, 0x10038);
20585 __ Crc32h(w11, w0, w1);
20586
20587 __ Mov(w0, 0x1);
20588 __ Mov(w1, 0x38);
20589 __ Crc32h(w12, w0, w1);
20590
20591 __ Mov(w0, 0);
20592 __ Mov(w1, 128);
20593 __ Crc32h(w13, w0, w1);
20594
20595 __ Mov(w0, UINT32_MAX);
20596 __ Mov(w1, 255);
20597 __ Crc32h(w14, w0, w1);
20598
20599 __ Mov(w0, 0x00010001);
20600 __ Mov(w1, 0x10001000);
20601 __ Crc32h(w15, w0, w1);
20602
20603 END();
20604 RUN();
20605
20606 ASSERT_EQUAL_64(0x0, x10);
20607 ASSERT_EQUAL_64(0x0e848dba, x11);
20608 ASSERT_EQUAL_64(0x0e848dba, x12);
20609 ASSERT_EQUAL_64(0x3b83984b, x13);
20610 ASSERT_EQUAL_64(0x2d021072, x14);
20611 ASSERT_EQUAL_64(0x04ac2124, x15);
20612
20613 TEARDOWN();
20614}
20615
20616
20617TEST(crc32w) {
20618 SETUP();
20619 START();
20620
20621 __ Mov(w0, 0);
20622 __ Mov(w1, 0);
20623 __ Crc32w(w10, w0, w1);
20624
20625 __ Mov(w0, 0x1);
20626 __ Mov(w1, 0x80000031);
20627 __ Crc32w(w11, w0, w1);
20628
20629 __ Mov(w0, 0);
20630 __ Mov(w1, 128);
20631 __ Crc32w(w13, w0, w1);
20632
20633 __ Mov(w0, UINT32_MAX);
20634 __ Mov(w1, 255);
20635 __ Crc32w(w14, w0, w1);
20636
20637 __ Mov(w0, 0x00010001);
20638 __ Mov(w1, 0x10001000);
20639 __ Crc32w(w15, w0, w1);
20640
20641 END();
20642 RUN();
20643
20644 ASSERT_EQUAL_64(0x0, x10);
20645 ASSERT_EQUAL_64(0x1d937b81, x11);
20646 ASSERT_EQUAL_64(0xed59b63b, x13);
20647 ASSERT_EQUAL_64(0x00be2612, x14);
20648 ASSERT_EQUAL_64(0xa036e530, x15);
20649
20650 TEARDOWN();
20651}
20652
20653
20654TEST(crc32x) {
20655 SETUP();
20656 START();
20657
20658 __ Mov(w0, 0);
20659 __ Mov(x1, 0);
20660 __ Crc32x(w10, w0, x1);
20661
20662 __ Mov(w0, 0x1);
20663 __ Mov(x1, UINT64_C(0x0000000800000031));
20664 __ Crc32x(w11, w0, x1);
20665
20666 __ Mov(w0, 0);
20667 __ Mov(x1, 128);
20668 __ Crc32x(w13, w0, x1);
20669
20670 __ Mov(w0, UINT32_MAX);
20671 __ Mov(x1, 255);
20672 __ Crc32x(w14, w0, x1);
20673
20674 __ Mov(w0, 0x00010001);
20675 __ Mov(x1, UINT64_C(0x1000100000000000));
20676 __ Crc32x(w15, w0, x1);
20677
20678 END();
20679 RUN();
20680
20681 ASSERT_EQUAL_64(0x0, x10);
20682 ASSERT_EQUAL_64(0x40797b92, x11);
20683 ASSERT_EQUAL_64(0x533b85da, x13);
20684 ASSERT_EQUAL_64(0xbc962670, x14);
20685 ASSERT_EQUAL_64(0x0667602f, x15);
20686
20687 TEARDOWN();
20688}
20689
20690
20691TEST(crc32cb) {
20692 SETUP();
20693 START();
20694
20695 __ Mov(w0, 0);
20696 __ Mov(w1, 0);
20697 __ Crc32cb(w10, w0, w1);
20698
20699 __ Mov(w0, 0x1);
20700 __ Mov(w1, 0x138);
20701 __ Crc32cb(w11, w0, w1);
20702
20703 __ Mov(w0, 0x1);
20704 __ Mov(w1, 0x38);
20705 __ Crc32cb(w12, w0, w1);
20706
20707 __ Mov(w0, 0);
20708 __ Mov(w1, 128);
20709 __ Crc32cb(w13, w0, w1);
20710
20711 __ Mov(w0, UINT32_MAX);
20712 __ Mov(w1, 255);
20713 __ Crc32cb(w14, w0, w1);
20714
20715 __ Mov(w0, 0x00010001);
20716 __ Mov(w1, 0x10001000);
20717 __ Crc32cb(w15, w0, w1);
20718
20719 END();
20720 RUN();
20721
20722 ASSERT_EQUAL_64(0x0, x10);
20723 ASSERT_EQUAL_64(0x4851927d, x11);
20724 ASSERT_EQUAL_64(0x4851927d, x12);
20725 ASSERT_EQUAL_64(0x82f63b78, x13);
20726 ASSERT_EQUAL_64(0x00ffffff, x14);
20727 ASSERT_EQUAL_64(0xf26b8203, x15);
20728
20729 TEARDOWN();
20730}
20731
20732
20733TEST(crc32ch) {
20734 SETUP();
20735 START();
20736
20737 __ Mov(w0, 0);
20738 __ Mov(w1, 0);
20739 __ Crc32ch(w10, w0, w1);
20740
20741 __ Mov(w0, 0x1);
20742 __ Mov(w1, 0x10038);
20743 __ Crc32ch(w11, w0, w1);
20744
20745 __ Mov(w0, 0x1);
20746 __ Mov(w1, 0x38);
20747 __ Crc32ch(w12, w0, w1);
20748
20749 __ Mov(w0, 0);
20750 __ Mov(w1, 128);
20751 __ Crc32ch(w13, w0, w1);
20752
20753 __ Mov(w0, UINT32_MAX);
20754 __ Mov(w1, 255);
20755 __ Crc32ch(w14, w0, w1);
20756
20757 __ Mov(w0, 0x00010001);
20758 __ Mov(w1, 0x10001000);
20759 __ Crc32ch(w15, w0, w1);
20760
20761 END();
20762 RUN();
20763
20764 ASSERT_EQUAL_64(0x0, x10);
20765 ASSERT_EQUAL_64(0xcef8494c, x11);
20766 ASSERT_EQUAL_64(0xcef8494c, x12);
20767 ASSERT_EQUAL_64(0xfbc3faf9, x13);
20768 ASSERT_EQUAL_64(0xad7dacae, x14);
20769 ASSERT_EQUAL_64(0x03fc5f19, x15);
20770
20771 TEARDOWN();
20772}
20773
20774
20775TEST(crc32cw) {
20776 SETUP();
20777 START();
20778
20779 __ Mov(w0, 0);
20780 __ Mov(w1, 0);
20781 __ Crc32cw(w10, w0, w1);
20782
20783 __ Mov(w0, 0x1);
20784 __ Mov(w1, 0x80000031);
20785 __ Crc32cw(w11, w0, w1);
20786
20787 __ Mov(w0, 0);
20788 __ Mov(w1, 128);
20789 __ Crc32cw(w13, w0, w1);
20790
20791 __ Mov(w0, UINT32_MAX);
20792 __ Mov(w1, 255);
20793 __ Crc32cw(w14, w0, w1);
20794
20795 __ Mov(w0, 0x00010001);
20796 __ Mov(w1, 0x10001000);
20797 __ Crc32cw(w15, w0, w1);
20798
20799 END();
20800 RUN();
20801
20802 ASSERT_EQUAL_64(0x0, x10);
20803 ASSERT_EQUAL_64(0xbcb79ece, x11);
20804 ASSERT_EQUAL_64(0x52a0c93f, x13);
20805 ASSERT_EQUAL_64(0x9f9b5c7a, x14);
20806 ASSERT_EQUAL_64(0xae1b882a, x15);
20807
20808 TEARDOWN();
20809}
20810
20811
20812TEST(crc32cx) {
20813 SETUP();
20814 START();
20815
20816 __ Mov(w0, 0);
20817 __ Mov(x1, 0);
20818 __ Crc32cx(w10, w0, x1);
20819
20820 __ Mov(w0, 0x1);
20821 __ Mov(x1, UINT64_C(0x0000000800000031));
20822 __ Crc32cx(w11, w0, x1);
20823
20824 __ Mov(w0, 0);
20825 __ Mov(x1, 128);
20826 __ Crc32cx(w13, w0, x1);
20827
20828 __ Mov(w0, UINT32_MAX);
20829 __ Mov(x1, 255);
20830 __ Crc32cx(w14, w0, x1);
20831
20832 __ Mov(w0, 0x00010001);
20833 __ Mov(x1, UINT64_C(0x1000100000000000));
20834 __ Crc32cx(w15, w0, x1);
20835
20836 END();
20837 RUN();
20838
20839 ASSERT_EQUAL_64(0x0, x10);
20840 ASSERT_EQUAL_64(0x7f320fcb, x11);
20841 ASSERT_EQUAL_64(0x34019664, x13);
20842 ASSERT_EQUAL_64(0x6cc27dd0, x14);
20843 ASSERT_EQUAL_64(0xc6f0acdb, x15);
20844
20845 TEARDOWN();
20846}
20847
20848
20849TEST(neon_fabd_scalar) {
20850 SETUP();
20851
20852 START();
20853 __ Fmov(s0, 2.0);
20854 __ Fmov(s1, 0.5);
20855 __ Fmov(s2, 0.0);
20856 __ Fmov(s3, -0.0);
20857 __ Fmov(s4, kFP32PositiveInfinity);
20858 __ Fmov(s5, kFP32NegativeInfinity);
20859 __ Fabd(s16, s1, s0);
20860 __ Fabd(s17, s2, s3);
20861 __ Fabd(s18, s2, s5);
20862 __ Fabd(s19, s3, s4);
20863 __ Fabd(s20, s3, s5);
20864
20865 __ Fmov(d21, 2.0);
20866 __ Fmov(d22, 0.5);
20867 __ Fmov(d23, 0.0);
20868 __ Fmov(d24, -0.0);
20869 __ Fmov(d25, kFP64PositiveInfinity);
20870 __ Fmov(d26, kFP64NegativeInfinity);
20871 __ Fabd(d27, d21, d22);
20872 __ Fabd(d28, d23, d24);
20873 __ Fabd(d29, d23, d26);
20874 __ Fabd(d30, d24, d25);
20875 __ Fabd(d31, d24, d26);
20876 END();
20877
20878 RUN();
20879
20880 ASSERT_EQUAL_FP32(1.5, s16);
20881 ASSERT_EQUAL_FP32(0.0, s17);
20882 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s18);
20883 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s19);
20884 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s20);
20885 ASSERT_EQUAL_FP64(1.5, d27);
20886 ASSERT_EQUAL_FP64(0.0, d28);
20887 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d29);
20888 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d30);
20889 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d31);
20890
20891 TEARDOWN();
20892}
20893
20894
20895TEST(neon_faddp_scalar) {
20896 SETUP();
20897
20898 START();
20899 __ Movi(d0, 0x3f80000040000000);
20900 __ Movi(d1, 0xff8000007f800000);
20901 __ Movi(d2, 0x0000000080000000);
20902 __ Faddp(s0, v0.V2S());
20903 __ Faddp(s1, v1.V2S());
20904 __ Faddp(s2, v2.V2S());
20905
20906 __ Movi(v3.V2D(), 0xc000000000000000, 0x4000000000000000);
20907 __ Movi(v4.V2D(), 0xfff8000000000000, 0x7ff8000000000000);
20908 __ Movi(v5.V2D(), 0x0000000000000000, 0x8000000000000000);
20909 __ Faddp(d3, v3.V2D());
20910 __ Faddp(d4, v4.V2D());
20911 __ Faddp(d5, v5.V2D());
20912 END();
20913
20914 RUN();
20915
20916 ASSERT_EQUAL_FP32(3.0, s0);
20917 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s1);
20918 ASSERT_EQUAL_FP32(0.0, s2);
20919 ASSERT_EQUAL_FP64(0.0, d3);
20920 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d4);
20921 ASSERT_EQUAL_FP64(0.0, d5);
20922
20923 TEARDOWN();
20924}
20925
20926
20927TEST(neon_fmaxp_scalar) {
20928 SETUP();
20929
20930 START();
20931 __ Movi(d0, 0x3f80000040000000);
20932 __ Movi(d1, 0xff8000007f800000);
20933 __ Movi(d2, 0x7fc00000ff800000);
20934 __ Fmaxp(s0, v0.V2S());
20935 __ Fmaxp(s1, v1.V2S());
20936 __ Fmaxp(s2, v2.V2S());
20937
20938 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
20939 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
20940 __ Movi(v5.V2D(), 0x7ff0000000000000, 0x7ff8000000000000);
20941 __ Fmaxp(d3, v3.V2D());
20942 __ Fmaxp(d4, v4.V2D());
20943 __ Fmaxp(d5, v5.V2D());
20944 END();
20945
20946 RUN();
20947
20948 ASSERT_EQUAL_FP32(2.0, s0);
20949 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s1);
20950 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s2);
20951 ASSERT_EQUAL_FP64(2.0, d3);
20952 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d4);
20953 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d5);
20954
20955 TEARDOWN();
20956}
20957
20958
20959TEST(neon_fmaxnmp_scalar) {
20960 SETUP();
20961
20962 START();
20963 __ Movi(d0, 0x3f80000040000000);
20964 __ Movi(d1, 0xff8000007f800000);
20965 __ Movi(d2, 0x7fc00000ff800000);
20966 __ Fmaxnmp(s0, v0.V2S());
20967 __ Fmaxnmp(s1, v1.V2S());
20968 __ Fmaxnmp(s2, v2.V2S());
20969
20970 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
20971 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
20972 __ Movi(v5.V2D(), 0x7ff8000000000000, 0xfff0000000000000);
20973 __ Fmaxnmp(d3, v3.V2D());
20974 __ Fmaxnmp(d4, v4.V2D());
20975 __ Fmaxnmp(d5, v5.V2D());
20976 END();
20977
20978 RUN();
20979
20980 ASSERT_EQUAL_FP32(2.0, s0);
20981 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s1);
20982 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s2);
20983 ASSERT_EQUAL_FP64(2.0, d3);
20984 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d4);
20985 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d5);
20986
20987 TEARDOWN();
20988}
20989
20990
20991TEST(neon_fminp_scalar) {
20992 SETUP();
20993
20994 START();
20995 __ Movi(d0, 0x3f80000040000000);
20996 __ Movi(d1, 0xff8000007f800000);
20997 __ Movi(d2, 0x7fc00000ff800000);
20998 __ Fminp(s0, v0.V2S());
20999 __ Fminp(s1, v1.V2S());
21000 __ Fminp(s2, v2.V2S());
21001
21002 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
21003 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
21004 __ Movi(v5.V2D(), 0x7ff0000000000000, 0x7ff8000000000000);
21005 __ Fminp(d3, v3.V2D());
21006 __ Fminp(d4, v4.V2D());
21007 __ Fminp(d5, v5.V2D());
21008 END();
21009
21010 RUN();
21011
21012 ASSERT_EQUAL_FP32(1.0, s0);
21013 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s1);
21014 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s2);
21015 ASSERT_EQUAL_FP64(1.0, d3);
21016 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d4);
21017 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d5);
21018
21019 TEARDOWN();
21020}
21021
21022
21023TEST(neon_fminnmp_scalar) {
21024 SETUP();
21025
21026 START();
21027 __ Movi(d0, 0x3f80000040000000);
21028 __ Movi(d1, 0xff8000007f800000);
21029 __ Movi(d2, 0x7fc00000ff800000);
21030 __ Fminnmp(s0, v0.V2S());
21031 __ Fminnmp(s1, v1.V2S());
21032 __ Fminnmp(s2, v2.V2S());
21033
21034 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
21035 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
21036 __ Movi(v5.V2D(), 0x7ff8000000000000, 0xfff0000000000000);
21037 __ Fminnmp(d3, v3.V2D());
21038 __ Fminnmp(d4, v4.V2D());
21039 __ Fminnmp(d5, v5.V2D());
21040 END();
21041
21042 RUN();
21043
21044 ASSERT_EQUAL_FP32(1.0, s0);
21045 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s1);
21046 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s2);
21047 ASSERT_EQUAL_FP64(1.0, d3);
21048 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d4);
21049 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d5);
21050
21051 TEARDOWN();
21052}
21053
21054
21055TEST(neon_tbl) {
21056 SETUP();
21057
21058 START();
21059 __ Movi(v30.V2D(), 0xbf561e188b1280e9, 0xbd542b8cbd24e8e8);
21060 __ Movi(v31.V2D(), 0xb5e9883d2c88a46d, 0x12276d5b614c915e);
21061 __ Movi(v0.V2D(), 0xc45b7782bc5ecd72, 0x5dd4fe5a4bc6bf5e);
21062 __ Movi(v1.V2D(), 0x1e3254094bd1746a, 0xf099ecf50e861c80);
21063
21064 __ Movi(v4.V2D(), 0xf80c030100031f16, 0x00070504031201ff);
21065 __ Movi(v5.V2D(), 0x1f01001afc14202a, 0x2a081e1b0c02020c);
21066 __ Movi(v6.V2D(), 0x353f1a13022a2360, 0x2c464a00203a0a33);
21067 __ Movi(v7.V2D(), 0x64801a1c054cf30d, 0x793a2c052e213739);
21068
21069 __ Movi(v8.V2D(), 0xb7f60ad7d7d88f13, 0x13eefc240496e842);
21070 __ Movi(v9.V2D(), 0x1be199c7c69b47ec, 0x8e4b9919f6eed443);
21071 __ Movi(v10.V2D(), 0x9bd2e1654c69e48f, 0x2143d089e426c6d2);
21072 __ Movi(v11.V2D(), 0xc31dbdc4a0393065, 0x1ecc2077caaf64d8);
21073 __ Movi(v12.V2D(), 0x29b24463967bc6eb, 0xdaf59970df01c93b);
21074 __ Movi(v13.V2D(), 0x3e20a4a4cb6813f4, 0x20a5832713dae669);
21075 __ Movi(v14.V2D(), 0xc5ff9a94041b1fdf, 0x2f46cde38cba2682);
21076 __ Movi(v15.V2D(), 0xd8cc5b0e61f387e6, 0xe69d6d314971e8fd);
21077
21078 __ Tbl(v8.V16B(), v1.V16B(), v4.V16B());
21079 __ Tbl(v9.V16B(), v0.V16B(), v1.V16B(), v5.V16B());
21080 __ Tbl(v10.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V16B());
21081 __ Tbl(v11.V16B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V16B());
21082 __ Tbl(v12.V8B(), v1.V16B(), v4.V8B());
21083 __ Tbl(v13.V8B(), v0.V16B(), v1.V16B(), v5.V8B());
21084 __ Tbl(v14.V8B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V8B());
21085 __ Tbl(v15.V8B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V8B());
21086
21087 __ Movi(v16.V2D(), 0xb7f60ad7d7d88f13, 0x13eefc240496e842);
21088 __ Movi(v17.V2D(), 0x1be199c7c69b47ec, 0x8e4b9919f6eed443);
21089 __ Movi(v18.V2D(), 0x9bd2e1654c69e48f, 0x2143d089e426c6d2);
21090 __ Movi(v19.V2D(), 0xc31dbdc4a0393065, 0x1ecc2077caaf64d8);
21091 __ Movi(v20.V2D(), 0x29b24463967bc6eb, 0xdaf59970df01c93b);
21092 __ Movi(v21.V2D(), 0x3e20a4a4cb6813f4, 0x20a5832713dae669);
21093 __ Movi(v22.V2D(), 0xc5ff9a94041b1fdf, 0x2f46cde38cba2682);
21094 __ Movi(v23.V2D(), 0xd8cc5b0e61f387e6, 0xe69d6d314971e8fd);
21095
21096 __ Tbx(v16.V16B(), v1.V16B(), v4.V16B());
21097 __ Tbx(v17.V16B(), v0.V16B(), v1.V16B(), v5.V16B());
21098 __ Tbx(v18.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V16B());
21099 __ Tbx(v19.V16B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V16B());
21100 __ Tbx(v20.V8B(), v1.V16B(), v4.V8B());
21101 __ Tbx(v21.V8B(), v0.V16B(), v1.V16B(), v5.V8B());
21102 __ Tbx(v22.V8B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V8B());
21103 __ Tbx(v23.V8B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V8B());
21104 END();
21105
21106 RUN();
21107
21108 ASSERT_EQUAL_128(0x00090e1c800e0000, 0x80f0ecf50e001c00, v8);
21109 ASSERT_EQUAL_128(0x1ebf5ed100f50000, 0x0072324b82c6c682, v9);
21110 ASSERT_EQUAL_128(0x00005e4b4cd10e00, 0x0900005e80008800, v10);
21111 ASSERT_EQUAL_128(0x0000883d2b00001e, 0x00d1822b5bbff074, v11);
21112 ASSERT_EQUAL_128(0x0000000000000000, 0x80f0ecf50e001c00, v12);
21113 ASSERT_EQUAL_128(0x0000000000000000, 0x0072324b82c6c682, v13);
21114 ASSERT_EQUAL_128(0x0000000000000000, 0x0900005e80008800, v14);
21115 ASSERT_EQUAL_128(0x0000000000000000, 0x00d1822b5bbff074, v15);
21116
21117 ASSERT_EQUAL_128(0xb7090e1c800e8f13, 0x80f0ecf50e961c42, v16);
21118 ASSERT_EQUAL_128(0x1ebf5ed1c6f547ec, 0x8e72324b82c6c682, v17);
21119 ASSERT_EQUAL_128(0x9bd25e4b4cd10e8f, 0x0943d05e802688d2, v18);
21120 ASSERT_EQUAL_128(0xc31d883d2b39301e, 0x1ed1822b5bbff074, v19);
21121 ASSERT_EQUAL_128(0x0000000000000000, 0x80f0ecf50e011c3b, v20);
21122 ASSERT_EQUAL_128(0x0000000000000000, 0x2072324b82c6c682, v21);
21123 ASSERT_EQUAL_128(0x0000000000000000, 0x0946cd5e80ba8882, v22);
21124 ASSERT_EQUAL_128(0x0000000000000000, 0xe6d1822b5bbff074, v23);
21125
21126 TEARDOWN();
21127}
21128
21129
21130TEST(regress_cmp_shift_imm) {
21131 SETUP();
21132
21133 START();
21134
21135 __ Mov(x0, 0x3d720c8d);
21136 __ Cmp(x0, Operand(0x3d720c8d));
21137
21138 END();
21139 RUN();
21140
21141 ASSERT_EQUAL_NZCV(ZCFlag);
21142
21143 TEARDOWN();
21144}
21145
21146
21147TEST(compute_address) {
21148 SETUP();
21149
21150 START();
21151 int64_t base_address = INT64_C(0x123000000abc);
21152 int64_t reg_offset = INT64_C(0x1087654321);
21153 Register base = x0;
21154 Register offset = x1;
21155
21156 __ Mov(base, base_address);
21157 __ Mov(offset, reg_offset);
21158
21159
21160 __ ComputeAddress(x2, MemOperand(base, 0));
21161 __ ComputeAddress(x3, MemOperand(base, 8));
21162 __ ComputeAddress(x4, MemOperand(base, -100));
21163
21164 __ ComputeAddress(x5, MemOperand(base, offset));
21165 __ ComputeAddress(x6, MemOperand(base, offset, LSL, 2));
21166 __ ComputeAddress(x7, MemOperand(base, offset, LSL, 4));
21167 __ ComputeAddress(x8, MemOperand(base, offset, LSL, 8));
21168
21169 __ ComputeAddress(x9, MemOperand(base, offset, SXTW));
21170 __ ComputeAddress(x10, MemOperand(base, offset, UXTW, 1));
21171 __ ComputeAddress(x11, MemOperand(base, offset, SXTW, 2));
21172 __ ComputeAddress(x12, MemOperand(base, offset, UXTW, 3));
21173
21174 END();
21175
21176 RUN();
21177
21178 ASSERT_EQUAL_64(base_address, base);
21179
21180 ASSERT_EQUAL_64(INT64_C(0x123000000abc), x2);
21181 ASSERT_EQUAL_64(INT64_C(0x123000000ac4), x3);
21182 ASSERT_EQUAL_64(INT64_C(0x123000000a58), x4);
21183
21184 ASSERT_EQUAL_64(INT64_C(0x124087654ddd), x5);
21185 ASSERT_EQUAL_64(INT64_C(0x12721d951740), x6);
21186 ASSERT_EQUAL_64(INT64_C(0x133876543ccc), x7);
21187 ASSERT_EQUAL_64(INT64_C(0x22b765432bbc), x8);
21188
21189 ASSERT_EQUAL_64(INT64_C(0x122f87654ddd), x9);
21190 ASSERT_EQUAL_64(INT64_C(0x12310eca90fe), x10);
21191 ASSERT_EQUAL_64(INT64_C(0x122e1d951740), x11);
21192 ASSERT_EQUAL_64(INT64_C(0x12343b2a23c4), x12);
21193
21194 TEARDOWN();
21195}
21196
21197
21198TEST(far_branch_backward) {
21199 // Test that the MacroAssembler correctly resolves backward branches to labels
21200 // that are outside the immediate range of branch instructions.
21201 // Take into account that backward branches can reach one instruction further
21202 // than forward branches.
21203 const int overflow_size = kInstructionSize +
21204 std::max(Instruction::ImmBranchForwardRange(TestBranchType),
21205 std::max(Instruction::ImmBranchForwardRange(CompareBranchType),
21206 Instruction::ImmBranchForwardRange(CondBranchType)));
21207
21208 SETUP();
21209 START();
21210
21211 Label done, fail;
21212 Label test_tbz, test_cbz, test_bcond;
21213 Label success_tbz, success_cbz, success_bcond;
21214
21215 __ Mov(x0, 0);
21216 __ Mov(x1, 1);
21217 __ Mov(x10, 0);
21218
21219 __ B(&test_tbz);
21220 __ Bind(&success_tbz);
21221 __ Orr(x0, x0, 1 << 0);
21222 __ B(&test_cbz);
21223 __ Bind(&success_cbz);
21224 __ Orr(x0, x0, 1 << 1);
21225 __ B(&test_bcond);
21226 __ Bind(&success_bcond);
21227 __ Orr(x0, x0, 1 << 2);
21228
21229 __ B(&done);
21230
21231 // Generate enough code to overflow the immediate range of the three types of
21232 // branches below.
21233 for (unsigned i = 0; i < overflow_size / kInstructionSize; ++i) {
21234 if (i % 100 == 0) {
21235 // If we do land in this code, we do not want to execute so many nops
21236 // before reaching the end of test (especially if tracing is activated).
21237 __ B(&fail);
21238 } else {
21239 __ Nop();
21240 }
21241 }
21242 __ B(&fail);
21243
21244 __ Bind(&test_tbz);
21245 __ Tbz(x10, 7, &success_tbz);
21246 __ Bind(&test_cbz);
21247 __ Cbz(x10, &success_cbz);
21248 __ Bind(&test_bcond);
21249 __ Cmp(x10, 0);
21250 __ B(eq, &success_bcond);
21251
21252 // For each out-of-range branch instructions, at least two instructions should
21253 // have been generated.
21254 VIXL_CHECK(masm.SizeOfCodeGeneratedSince(&test_tbz) >= 7 * kInstructionSize);
21255
21256 __ Bind(&fail);
21257 __ Mov(x1, 0);
21258 __ Bind(&done);
21259
21260 END();
21261 RUN();
21262
21263 ASSERT_EQUAL_64(0x7, x0);
21264 ASSERT_EQUAL_64(0x1, x1);
21265
21266 TEARDOWN();
21267}
21268
21269
21270TEST(single_veneer) {
21271 SETUP();
21272 START();
21273
21274 const int max_range = Instruction::ImmBranchForwardRange(TestBranchType);
21275
21276 Label success, fail, done;
21277
21278 __ Mov(x0, 0);
21279 __ Mov(x1, 1);
21280 __ Mov(x10, 0);
21281
21282 __ Tbz(x10, 7, &success);
21283
21284 // Generate enough code to overflow the immediate range of the `tbz`.
21285 for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
21286 if (i % 100 == 0) {
21287 // If we do land in this code, we do not want to execute so many nops
21288 // before reaching the end of test (especially if tracing is activated).
21289 __ B(&fail);
21290 } else {
21291 __ Nop();
21292 }
21293 }
21294 __ B(&fail);
21295
21296 __ Bind(&success);
21297 __ Mov(x0, 1);
21298
21299 __ B(&done);
21300 __ Bind(&fail);
21301 __ Mov(x1, 0);
21302 __ Bind(&done);
21303
21304 END();
21305 RUN();
21306
21307 ASSERT_EQUAL_64(1, x0);
21308 ASSERT_EQUAL_64(1, x1);
21309
21310 TEARDOWN();
21311}
21312
21313
21314TEST(simple_veneers) {
21315 // Test that the MacroAssembler correctly emits veneers for forward branches
21316 // to labels that are outside the immediate range of branch instructions.
21317 const int max_range =
21318 std::max(Instruction::ImmBranchForwardRange(TestBranchType),
21319 std::max(Instruction::ImmBranchForwardRange(CompareBranchType),
21320 Instruction::ImmBranchForwardRange(CondBranchType)));
21321
21322 SETUP();
21323 START();
21324
21325 Label done, fail;
21326 Label test_tbz, test_cbz, test_bcond;
21327 Label success_tbz, success_cbz, success_bcond;
21328
21329 __ Mov(x0, 0);
21330 __ Mov(x1, 1);
21331 __ Mov(x10, 0);
21332
21333 __ Bind(&test_tbz);
21334 __ Tbz(x10, 7, &success_tbz);
21335 __ Bind(&test_cbz);
21336 __ Cbz(x10, &success_cbz);
21337 __ Bind(&test_bcond);
21338 __ Cmp(x10, 0);
21339 __ B(eq, &success_bcond);
21340
21341 // Generate enough code to overflow the immediate range of the three types of
21342 // branches below.
21343 for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
21344 if (i % 100 == 0) {
21345 // If we do land in this code, we do not want to execute so many nops
21346 // before reaching the end of test (especially if tracing is activated).
21347 __ B(&fail);
21348 } else {
21349 __ Nop();
21350 }
21351 }
21352 __ B(&fail);
21353
21354 __ Bind(&success_tbz);
21355 __ Orr(x0, x0, 1 << 0);
21356 __ B(&test_cbz);
21357 __ Bind(&success_cbz);
21358 __ Orr(x0, x0, 1 << 1);
21359 __ B(&test_bcond);
21360 __ Bind(&success_bcond);
21361 __ Orr(x0, x0, 1 << 2);
21362
21363 __ B(&done);
21364 __ Bind(&fail);
21365 __ Mov(x1, 0);
21366 __ Bind(&done);
21367
21368 END();
21369 RUN();
21370
21371 ASSERT_EQUAL_64(0x7, x0);
21372 ASSERT_EQUAL_64(0x1, x1);
21373
21374 TEARDOWN();
21375}
21376
21377
21378TEST(veneers_stress) {
21379 SETUP();
21380 START();
21381
21382 // This is a code generation test stressing the emission of veneers. The code
21383 // generated is not executed.
21384
21385 Label target;
21386 const unsigned max_range = Instruction::ImmBranchForwardRange(CondBranchType);
21387 const unsigned iterations =
21388 (max_range + max_range / 4) / (4 * kInstructionSize);
21389 for (unsigned i = 0; i < iterations; i++) {
21390 __ B(&target);
21391 __ B(eq, &target);
21392 __ Cbz(x0, &target);
21393 __ Tbz(x0, 0, &target);
21394 }
21395 __ Bind(&target);
21396
21397 END();
21398 TEARDOWN();
21399}
21400
21401
21402TEST(veneers_two_out_of_range) {
21403 SETUP();
21404 START();
21405
21406 // This is a code generation test. The code generated is not executed.
21407 // Ensure that the MacroAssembler considers unresolved branches to chose when
21408 // a veneer pool should be emitted. We generate two branches that go out of
21409 // range at the same offset. When the MacroAssembler decides to emit the
21410 // veneer pool, the emission of a first veneer should not cause the other
21411 // branch to go out of range.
21412
21413 int range_cbz = Instruction::ImmBranchForwardRange(CompareBranchType);
21414 int range_tbz = Instruction::ImmBranchForwardRange(TestBranchType);
armvixldb644342015-07-21 11:37:10 +010021415 int max_target = static_cast<int>(masm.CursorOffset()) + range_cbz;
armvixl5289c592015-03-02 13:52:04 +000021416
21417 Label done;
21418
21419 // We use different labels to prevent the MacroAssembler from sharing veneers.
21420 Label target_cbz, target_tbz;
21421
21422 __ Cbz(x0, &target_cbz);
21423 while (masm.CursorOffset() < max_target - range_tbz) {
21424 __ Nop();
21425 }
21426 __ Tbz(x0, 0, &target_tbz);
21427 while (masm.CursorOffset() < max_target) {
21428 __ Nop();
21429 }
21430
21431 // This additional nop makes the branches go out of range.
21432 __ Nop();
21433
21434 __ Bind(&target_cbz);
21435 __ Bind(&target_tbz);
21436
21437 END();
21438 TEARDOWN();
21439}
21440
21441
21442TEST(veneers_hanging) {
21443 SETUP();
21444 START();
21445
21446 // This is a code generation test. The code generated is not executed.
21447 // Ensure that the MacroAssembler considers unresolved branches to chose when
21448 // a veneer pool should be emitted. This is similar to the
21449 // 'veneers_two_out_of_range' test. We try to trigger the following situation:
21450 // b.eq label
21451 // b.eq label
21452 // ...
21453 // nop
21454 // ...
21455 // cbz x0, label
21456 // cbz x0, label
21457 // ...
21458 // tbz x0, 0 label
21459 // nop
21460 // ...
21461 // nop <- From here the `b.eq` and `cbz` instructions run out of range,
21462 // so a literal pool is required.
21463 // veneer
21464 // veneer
21465 // veneer <- The `tbz` runs out of range somewhere in the middle of the
21466 // veneer veneer pool.
21467 // veneer
21468
21469 const int range_bcond = Instruction::ImmBranchForwardRange(CondBranchType);
21470 const int range_cbz = Instruction::ImmBranchForwardRange(CompareBranchType);
21471 const int range_tbz = Instruction::ImmBranchForwardRange(TestBranchType);
armvixldb644342015-07-21 11:37:10 +010021472 const int max_target = static_cast<int>(masm.CursorOffset()) + range_bcond;
armvixl5289c592015-03-02 13:52:04 +000021473
21474 Label done;
21475 const int n_bcond = 100;
21476 const int n_cbz = 100;
21477 const int n_tbz = 1;
21478 const int kNTotalBranches = n_bcond + n_cbz + n_tbz;
21479
21480 // We use different labels to prevent the MacroAssembler from sharing veneers.
21481 Label labels[kNTotalBranches];
21482 for (int i = 0; i < kNTotalBranches; i++) {
21483 new(&labels[i]) Label();
21484 }
21485
21486 for (int i = 0; i < n_bcond; i++) {
21487 __ B(eq, &labels[i]);
21488 }
21489
21490 while (masm.CursorOffset() < max_target - range_cbz) {
21491 __ Nop();
21492 }
21493
21494 for (int i = 0; i < n_cbz; i++) {
21495 __ Cbz(x0, &labels[n_bcond + i]);
21496 }
21497
21498 // Ensure the 'tbz' will go out of range after some of the previously
21499 // generated branches.
21500 int margin = (n_bcond / 2) * kInstructionSize;
21501 while (masm.CursorOffset() < max_target - range_tbz + margin) {
21502 __ Nop();
21503 }
21504
21505 __ Tbz(x0, 0, &labels[n_bcond + n_cbz]);
21506
21507 while (masm.CursorOffset() < max_target) {
21508 __ Nop();
21509 }
21510
21511 // This additional nop makes the 'b.eq' and 'cbz' instructions go out of range
21512 // and forces the emission of a veneer pool. The 'tbz' is not yet out of
21513 // range, but will go out of range while veneers are emitted for the other
21514 // branches.
21515 // The MacroAssembler should ensure that veneers are correctly emitted for all
21516 // the branches, including the 'tbz'. Checks will fail if the target of a
21517 // branch is out of range.
21518 __ Nop();
21519
21520 for (int i = 0; i < kNTotalBranches; i++) {
21521 __ Bind(&labels[i]);
21522 }
21523
21524 END();
21525 TEARDOWN();
21526}
21527
21528
21529TEST(collision_literal_veneer_pools) {
21530 SETUP();
21531 START();
21532
21533 // This is a code generation test. The code generated is not executed.
21534
21535 // Make sure the literal pool is empty;
21536 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21537 ASSERT_LITERAL_POOL_SIZE(0);
21538
21539 // We chose the offsets below to (try to) trigger the following situation:
21540 // buffer offset
21541 // 0: tbz x0, 0, target_tbz ----------------------------------.
21542 // 4: nop |
21543 // ... |
21544 // nop |
21545 // literal gen: ldr s0, [pc + ...] ; load from `pool start + 0` |
21546 // ldr s0, [pc + ...] ; load from `pool start + 4` |
21547 // ... |
21548 // ldr s0, [pc + ...] |
21549 // pool start: floating-point literal (0.1) |
21550 // floating-point literal (1.1) |
21551 // ... |
21552 // floating-point literal (<n>.1) <-----tbz-max-range--'
21553 // floating-point literal (<n+1>.1)
21554 // ...
21555
21556 const int range_tbz = Instruction::ImmBranchForwardRange(TestBranchType);
armvixldb644342015-07-21 11:37:10 +010021557 const int max_target = static_cast<int>(masm.CursorOffset()) + range_tbz;
armvixl5289c592015-03-02 13:52:04 +000021558
21559 const size_t target_literal_pool_size = 100 * kInstructionSize;
21560 const int offset_start_literal_gen =
21561 target_literal_pool_size + target_literal_pool_size / 2;
21562
21563
21564 Label target_tbz;
21565
21566 __ Tbz(x0, 0, &target_tbz);
21567 VIXL_CHECK(masm.NumberOfPotentialVeneers() == 1);
21568 while (masm.CursorOffset() < max_target - offset_start_literal_gen) {
21569 __ Nop();
21570 }
21571 VIXL_CHECK(masm.NumberOfPotentialVeneers() == 1);
21572
21573 for (int i = 0; i < 100; i++) {
21574 // Use a different value to force one literal pool entry per iteration.
21575 __ Ldr(s0, i + 0.1);
21576 }
21577 VIXL_CHECK(masm.LiteralPoolSize() >= target_literal_pool_size);
21578
21579 // Force emission of a literal pool.
21580 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21581 ASSERT_LITERAL_POOL_SIZE(0);
21582
21583 // The branch should not have gone out of range during the emission of the
21584 // literal pool.
21585 __ Bind(&target_tbz);
21586
21587 VIXL_CHECK(masm.NumberOfPotentialVeneers() == 0);
21588
21589 END();
21590 TEARDOWN();
21591}
armvixldb644342015-07-21 11:37:10 +010021592
21593
21594TEST(ldr_literal_explicit) {
21595 SETUP();
21596
21597 START();
21598 Literal<int64_t> automatically_placed_literal(1, masm.GetLiteralPool());
21599 Literal<int64_t> manually_placed_literal(2);
21600 {
21601 CodeBufferCheckScope scope(&masm,
21602 kInstructionSize + sizeof(int64_t),
21603 CodeBufferCheckScope::kCheck,
21604 CodeBufferCheckScope::kExactSize);
21605 Label over_literal;
21606 __ b(&over_literal);
21607 __ place(&manually_placed_literal);
21608 __ bind(&over_literal);
21609 }
21610 __ Ldr(x1, &manually_placed_literal);
21611 __ Ldr(x2, &automatically_placed_literal);
21612 __ Add(x0, x1, x2);
21613 END();
21614
21615 RUN();
21616
21617 ASSERT_EQUAL_64(3, x0);
21618
21619 TEARDOWN();
21620}
21621
21622
21623TEST(ldr_literal_automatically_placed) {
21624 SETUP();
21625
21626 START();
21627
21628 // We start with an empty literal pool.
21629 ASSERT_LITERAL_POOL_SIZE(0);
21630
21631 // Create a literal that should be placed by the literal pool.
21632 Literal<int64_t> explicit_literal(2, masm.GetLiteralPool());
21633 // It should not appear in the literal pool until its first use.
21634 ASSERT_LITERAL_POOL_SIZE(0);
21635
21636 // Check that using standard literals does not break the use of explicitly
21637 // created literals.
21638 __ Ldr(d1, 1.1);
21639 ASSERT_LITERAL_POOL_SIZE(8);
21640 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21641 ASSERT_LITERAL_POOL_SIZE(0);
21642
21643 __ Ldr(x2, &explicit_literal);
21644 ASSERT_LITERAL_POOL_SIZE(8);
21645 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21646 ASSERT_LITERAL_POOL_SIZE(0);
21647
21648 __ Ldr(d3, 3.3);
21649 ASSERT_LITERAL_POOL_SIZE(8);
21650 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21651 ASSERT_LITERAL_POOL_SIZE(0);
21652
21653 // Re-use our explicitly created literal. It has already been placed, so it
21654 // should not impact the literal pool.
21655 __ Ldr(x4, &explicit_literal);
21656 ASSERT_LITERAL_POOL_SIZE(0);
21657
21658 END();
21659
21660 RUN();
21661
21662 ASSERT_EQUAL_FP64(1.1, d1);
21663 ASSERT_EQUAL_64(2, x2);
21664 ASSERT_EQUAL_FP64(3.3, d3);
21665 ASSERT_EQUAL_64(2, x4);
21666
21667 TEARDOWN();
21668}
21669
21670
21671TEST(literal_update_overwrite) {
21672 SETUP();
21673
21674 START();
21675
21676 ASSERT_LITERAL_POOL_SIZE(0);
21677 LiteralPool* literal_pool = masm.GetLiteralPool();
21678
21679 Literal<int32_t> lit_32_update_before_pool(0xbad, literal_pool);
21680 Literal<int32_t> lit_32_update_after_pool(0xbad, literal_pool);
21681 Literal<int64_t> lit_64_update_before_pool(0xbad, literal_pool);
21682 Literal<int64_t> lit_64_update_after_pool(0xbad, literal_pool);
21683
21684 ASSERT_LITERAL_POOL_SIZE(0);
21685
21686 lit_32_update_before_pool.UpdateValue(32);
21687 lit_64_update_before_pool.UpdateValue(64);
21688
21689 __ Ldr(w1, &lit_32_update_before_pool);
21690 __ Ldr(x2, &lit_64_update_before_pool);
21691 __ Ldr(w3, &lit_32_update_after_pool);
21692 __ Ldr(x4, &lit_64_update_after_pool);
21693
21694 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21695
21696 VIXL_ASSERT(lit_32_update_after_pool.IsPlaced());
21697 VIXL_ASSERT(lit_64_update_after_pool.IsPlaced());
21698 lit_32_update_after_pool.UpdateValue(128, &masm);
21699 lit_64_update_after_pool.UpdateValue(256, &masm);
21700
21701 END();
21702
21703 RUN();
21704
21705 ASSERT_EQUAL_64(32, x1);
21706 ASSERT_EQUAL_64(64, x2);
21707 ASSERT_EQUAL_64(128, x3);
21708 ASSERT_EQUAL_64(256, x4);
21709
21710 TEARDOWN();
21711}
21712
21713
21714TEST(literal_deletion_policies) {
21715 SETUP();
21716
21717 START();
21718
21719 // We cannot check exactly when the deletion of the literals occur, but we
21720 // check that usage of the deletion policies is not broken.
21721
21722 ASSERT_LITERAL_POOL_SIZE(0);
21723 LiteralPool* literal_pool = masm.GetLiteralPool();
21724
21725 Literal<int32_t> lit_manual(0xbad, literal_pool);
21726 Literal<int32_t>* lit_deleted_on_placement =
21727 new Literal<int32_t>(0xbad,
21728 literal_pool,
21729 RawLiteral::kDeletedOnPlacementByPool);
21730 Literal<int32_t>* lit_deleted_on_pool_destruction =
21731 new Literal<int32_t>(0xbad,
21732 literal_pool,
21733 RawLiteral::kDeletedOnPoolDestruction);
21734
21735 ASSERT_LITERAL_POOL_SIZE(0);
21736
21737 lit_manual.UpdateValue(32);
21738 lit_deleted_on_placement->UpdateValue(64);
21739
21740 __ Ldr(w1, &lit_manual);
21741 __ Ldr(w2, lit_deleted_on_placement);
21742 __ Ldr(w3, lit_deleted_on_pool_destruction);
21743
21744 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21745
21746 VIXL_ASSERT(lit_manual.IsPlaced());
21747 VIXL_ASSERT(lit_deleted_on_placement->IsPlaced());
21748 VIXL_ASSERT(lit_deleted_on_pool_destruction->IsPlaced());
21749 lit_deleted_on_pool_destruction->UpdateValue(128, &masm);
21750
21751 END();
21752
21753 RUN();
21754
21755 ASSERT_EQUAL_64(32, x1);
21756 ASSERT_EQUAL_64(64, x2);
21757 ASSERT_EQUAL_64(128, x3);
21758
21759 TEARDOWN();
21760}
21761
21762
armvixlad96eda2013-06-14 11:42:37 +010021763} // namespace vixl