blob: 4603dcd51303795268f30d338c493c534c7d39f0 [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
Alexandre Ramesb68bacb2016-05-24 08:56:23 +010027#include <float.h>
armvixlad96eda2013-06-14 11:42:37 +010028#include <stdio.h>
armvixlf37fdc02014-02-05 13:22:16 +000029#include <stdlib.h>
armvixlad96eda2013-06-14 11:42:37 +010030#include <string.h>
Alexandre Ramesb68bacb2016-05-24 08:56:23 +010031
armvixl6e2c8272015-03-31 11:04:14 +010032#include <cmath>
armvixlad96eda2013-06-14 11:42:37 +010033
armvixl330dc712014-11-25 10:38:32 +000034#include "test-runner.h"
armvixlad96eda2013-06-14 11:42:37 +010035#include "test-utils-a64.h"
Alexandre Ramesb68bacb2016-05-24 08:56:23 +010036
37#include "a64/cpu-a64.h"
Alexandre Rames39c32a62016-05-23 15:47:22 +010038#include "a64/debugger-a64.h"
39#include "a64/disasm-a64.h"
Alexandre Ramesb68bacb2016-05-24 08:56:23 +010040#include "a64/macro-assembler-a64.h"
41#include "a64/simulator-a64.h"
armvixlad96eda2013-06-14 11:42:37 +010042
43namespace vixl {
44
45// Test infrastructure.
46//
47// Tests are functions which accept no parameters and have no return values.
48// The testing code should not perform an explicit return once completed. For
49// example to test the mov immediate instruction a very simple test would be:
50//
51// TEST(mov_x0_one) {
52// SETUP();
53//
54// START();
55// __ mov(x0, Operand(1));
56// END();
57//
58// RUN();
59//
60// ASSERT_EQUAL_64(1, x0);
61//
62// TEARDOWN();
63// }
64//
65// Within a START ... END block all registers but sp can be modified. sp has to
66// be explicitly saved/restored. The END() macro replaces the function return
67// so it may appear multiple times in a test if the test has multiple exit
68// points.
69//
70// Once the test has been run all integer and floating point registers as well
71// as flags are accessible through a RegisterDump instance, see
72// utils-a64.cc for more info on RegisterDump.
73//
74// We provide some helper assert to handle common cases:
75//
76// ASSERT_EQUAL_32(int32_t, int_32t)
77// ASSERT_EQUAL_FP32(float, float)
78// ASSERT_EQUAL_32(int32_t, W register)
79// ASSERT_EQUAL_FP32(float, S register)
80// ASSERT_EQUAL_64(int64_t, int_64t)
81// ASSERT_EQUAL_FP64(double, double)
82// ASSERT_EQUAL_64(int64_t, X register)
83// ASSERT_EQUAL_64(X register, X register)
84// ASSERT_EQUAL_FP64(double, D register)
85//
86// e.g. ASSERT_EQUAL_64(0.5, d30);
87//
armvixl578645f2013-08-15 17:21:42 +010088// If more advanced computation is required before the assert then access the
armvixlad96eda2013-06-14 11:42:37 +010089// RegisterDump named core directly:
90//
91// ASSERT_EQUAL_64(0x1234, core->reg_x0() & 0xffff);
92
93
94#define __ masm.
95#define TEST(name) TEST_(ASM_##name)
96
97#define BUF_SIZE (4096)
98
armvixl684cd2a2015-10-23 13:38:33 +010099#ifdef VIXL_INCLUDE_SIMULATOR
armvixlad96eda2013-06-14 11:42:37 +0100100// Run tests with the simulator.
armvixlc68cb642014-09-25 18:49:30 +0100101
102#define SETUP() \
103 MacroAssembler masm(BUF_SIZE); \
104 SETUP_COMMON()
105
106#define SETUP_CUSTOM(size, pic) \
107 byte* buf = new byte[size + BUF_SIZE]; \
108 MacroAssembler masm(buf, size + BUF_SIZE, pic); \
109 SETUP_COMMON()
110
111#define SETUP_COMMON() \
armvixl684cd2a2015-10-23 13:38:33 +0100112 masm.SetAllowSimulatorInstructions(true); \
armvixlad96eda2013-06-14 11:42:37 +0100113 Decoder decoder; \
armvixl330dc712014-11-25 10:38:32 +0000114 Simulator* simulator = Test::run_debugger() ? new Debugger(&decoder) \
115 : new Simulator(&decoder); \
116 simulator->set_coloured_trace(Test::coloured_trace()); \
117 simulator->set_instruction_stats(Test::instruction_stats()); \
armvixlad96eda2013-06-14 11:42:37 +0100118 RegisterDump core
119
armvixlc68cb642014-09-25 18:49:30 +0100120// This is a convenience macro to avoid creating a scope for every assembler
121// function called. It will still assert the buffer hasn't been exceeded.
122#define ALLOW_ASM() \
123 CodeBufferCheckScope guard(&masm, masm.BufferCapacity())
124
armvixlad96eda2013-06-14 11:42:37 +0100125#define START() \
126 masm.Reset(); \
127 simulator->ResetState(); \
128 __ PushCalleeSavedRegisters(); \
armvixl330dc712014-11-25 10:38:32 +0000129 if (Test::trace_reg()) { \
130 __ Trace(LOG_STATE, TRACE_ENABLE); \
armvixl578645f2013-08-15 17:21:42 +0100131 } \
armvixl330dc712014-11-25 10:38:32 +0000132 if (Test::trace_write()) { \
133 __ Trace(LOG_WRITE, TRACE_ENABLE); \
134 } \
135 if (Test::trace_sim()) { \
136 __ Trace(LOG_DISASM, TRACE_ENABLE); \
137 } \
138 if (Test::instruction_stats()) { \
armvixl578645f2013-08-15 17:21:42 +0100139 __ EnableInstrumentation(); \
armvixlad96eda2013-06-14 11:42:37 +0100140 }
141
142#define END() \
armvixl330dc712014-11-25 10:38:32 +0000143 if (Test::instruction_stats()) { \
armvixl578645f2013-08-15 17:21:42 +0100144 __ DisableInstrumentation(); \
145 } \
armvixl330dc712014-11-25 10:38:32 +0000146 __ Trace(LOG_ALL, TRACE_DISABLE); \
armvixlad96eda2013-06-14 11:42:37 +0100147 core.Dump(&masm); \
148 __ PopCalleeSavedRegisters(); \
149 __ Ret(); \
150 masm.FinalizeCode()
151
152#define RUN() \
armvixlc68cb642014-09-25 18:49:30 +0100153 simulator->RunFrom(masm.GetStartAddress<Instruction*>())
armvixlad96eda2013-06-14 11:42:37 +0100154
armvixlc68cb642014-09-25 18:49:30 +0100155#define TEARDOWN() TEARDOWN_COMMON()
156
157#define TEARDOWN_CUSTOM() \
158 delete[] buf; \
159 TEARDOWN_COMMON()
160
161#define TEARDOWN_COMMON() \
162 delete simulator;
armvixlad96eda2013-06-14 11:42:37 +0100163
armvixl684cd2a2015-10-23 13:38:33 +0100164#else // ifdef VIXL_INCLUDE_SIMULATOR.
armvixlad96eda2013-06-14 11:42:37 +0100165// Run the test on real hardware or models.
armvixlc68cb642014-09-25 18:49:30 +0100166#define SETUP() \
167 MacroAssembler masm(BUF_SIZE); \
168 SETUP_COMMON()
169
170#define SETUP_CUSTOM(size, pic) \
171 byte* buf = new byte[size + BUF_SIZE]; \
172 MacroAssembler masm(buf, size + BUF_SIZE, pic); \
173 SETUP_COMMON()
174
175#define SETUP_COMMON() \
armvixl684cd2a2015-10-23 13:38:33 +0100176 masm.SetAllowSimulatorInstructions(false); \
armvixlad96eda2013-06-14 11:42:37 +0100177 RegisterDump core; \
178 CPU::SetUp()
179
armvixlc68cb642014-09-25 18:49:30 +0100180// This is a convenience macro to avoid creating a scope for every assembler
181// function called. It will still assert the buffer hasn't been exceeded.
182#define ALLOW_ASM() \
183 CodeBufferCheckScope guard(&masm, masm.BufferCapacity())
184
armvixlad96eda2013-06-14 11:42:37 +0100185#define START() \
186 masm.Reset(); \
187 __ PushCalleeSavedRegisters()
188
189#define END() \
190 core.Dump(&masm); \
191 __ PopCalleeSavedRegisters(); \
192 __ Ret(); \
193 masm.FinalizeCode()
194
195#define RUN() \
armvixlad96eda2013-06-14 11:42:37 +0100196 { \
armvixlc68cb642014-09-25 18:49:30 +0100197 byte* buffer_start = masm.GetStartAddress<byte*>(); \
198 size_t buffer_length = masm.CursorOffset(); \
armvixlad96eda2013-06-14 11:42:37 +0100199 void (*test_function)(void); \
armvixlc68cb642014-09-25 18:49:30 +0100200 \
201 CPU::EnsureIAndDCacheCoherency(buffer_start, buffer_length); \
202 VIXL_STATIC_ASSERT(sizeof(buffer_start) == sizeof(test_function)); \
203 memcpy(&test_function, &buffer_start, sizeof(buffer_start)); \
armvixlad96eda2013-06-14 11:42:37 +0100204 test_function(); \
205 }
206
armvixlc68cb642014-09-25 18:49:30 +0100207#define TEARDOWN()
208
209#define TEARDOWN_CUSTOM() \
210 delete[] buf; \
armvixlad96eda2013-06-14 11:42:37 +0100211
armvixl684cd2a2015-10-23 13:38:33 +0100212#endif // ifdef VIXL_INCLUDE_SIMULATOR.
armvixlad96eda2013-06-14 11:42:37 +0100213
214#define ASSERT_EQUAL_NZCV(expected) \
215 assert(EqualNzcv(expected, core.flags_nzcv()))
216
217#define ASSERT_EQUAL_REGISTERS(expected) \
218 assert(EqualRegisters(&expected, &core))
219
220#define ASSERT_EQUAL_32(expected, result) \
221 assert(Equal32(static_cast<uint32_t>(expected), &core, result))
222
223#define ASSERT_EQUAL_FP32(expected, result) \
224 assert(EqualFP32(expected, &core, result))
225
226#define ASSERT_EQUAL_64(expected, result) \
227 assert(Equal64(expected, &core, result))
228
229#define ASSERT_EQUAL_FP64(expected, result) \
230 assert(EqualFP64(expected, &core, result))
231
armvixl5289c592015-03-02 13:52:04 +0000232#define ASSERT_EQUAL_128(expected_h, expected_l, result) \
233 assert(Equal128(expected_h, expected_l, &core, result))
234
armvixlad96eda2013-06-14 11:42:37 +0100235#define ASSERT_LITERAL_POOL_SIZE(expected) \
armvixl5289c592015-03-02 13:52:04 +0000236 assert((expected + kInstructionSize) == (masm.LiteralPoolSize()))
armvixlad96eda2013-06-14 11:42:37 +0100237
238
239TEST(stack_ops) {
240 SETUP();
241
242 START();
243 // save sp.
244 __ Mov(x29, sp);
245
246 // Set the sp to a known value.
247 __ Mov(sp, 0x1004);
248 __ Mov(x0, sp);
249
250 // Add immediate to the sp, and move the result to a normal register.
armvixlb0c8ae22014-03-21 14:03:59 +0000251 __ Add(sp, sp, 0x50);
armvixlad96eda2013-06-14 11:42:37 +0100252 __ Mov(x1, sp);
253
254 // Add extended to the sp, and move the result to a normal register.
255 __ Mov(x17, 0xfff);
256 __ Add(sp, sp, Operand(x17, SXTB));
257 __ Mov(x2, sp);
258
259 // Create an sp using a logical instruction, and move to normal register.
armvixlb0c8ae22014-03-21 14:03:59 +0000260 __ Orr(sp, xzr, 0x1fff);
armvixlad96eda2013-06-14 11:42:37 +0100261 __ Mov(x3, sp);
262
263 // Write wsp using a logical instruction.
armvixlb0c8ae22014-03-21 14:03:59 +0000264 __ Orr(wsp, wzr, 0xfffffff8);
armvixlad96eda2013-06-14 11:42:37 +0100265 __ Mov(x4, sp);
266
267 // Write sp, and read back wsp.
armvixlb0c8ae22014-03-21 14:03:59 +0000268 __ Orr(sp, xzr, 0xfffffff8);
armvixlad96eda2013-06-14 11:42:37 +0100269 __ Mov(w5, wsp);
270
271 // restore sp.
272 __ Mov(sp, x29);
273 END();
274
275 RUN();
276
277 ASSERT_EQUAL_64(0x1004, x0);
278 ASSERT_EQUAL_64(0x1054, x1);
279 ASSERT_EQUAL_64(0x1053, x2);
280 ASSERT_EQUAL_64(0x1fff, x3);
281 ASSERT_EQUAL_64(0xfffffff8, x4);
282 ASSERT_EQUAL_64(0xfffffff8, x5);
283
284 TEARDOWN();
285}
286
287
288TEST(mvn) {
289 SETUP();
290
291 START();
292 __ Mvn(w0, 0xfff);
293 __ Mvn(x1, 0xfff);
294 __ Mvn(w2, Operand(w0, LSL, 1));
295 __ Mvn(x3, Operand(x1, LSL, 2));
296 __ Mvn(w4, Operand(w0, LSR, 3));
297 __ Mvn(x5, Operand(x1, LSR, 4));
298 __ Mvn(w6, Operand(w0, ASR, 11));
299 __ Mvn(x7, Operand(x1, ASR, 12));
300 __ Mvn(w8, Operand(w0, ROR, 13));
301 __ Mvn(x9, Operand(x1, ROR, 14));
302 __ Mvn(w10, Operand(w2, UXTB));
303 __ Mvn(x11, Operand(x2, SXTB, 1));
304 __ Mvn(w12, Operand(w2, UXTH, 2));
305 __ Mvn(x13, Operand(x2, SXTH, 3));
306 __ Mvn(x14, Operand(w2, UXTW, 4));
307 __ Mvn(x15, Operand(w2, SXTW, 4));
308 END();
309
310 RUN();
311
312 ASSERT_EQUAL_64(0xfffff000, x0);
armvixlb0c8ae22014-03-21 14:03:59 +0000313 ASSERT_EQUAL_64(0xfffffffffffff000, x1);
armvixlad96eda2013-06-14 11:42:37 +0100314 ASSERT_EQUAL_64(0x00001fff, x2);
armvixlb0c8ae22014-03-21 14:03:59 +0000315 ASSERT_EQUAL_64(0x0000000000003fff, x3);
armvixlad96eda2013-06-14 11:42:37 +0100316 ASSERT_EQUAL_64(0xe00001ff, x4);
armvixlb0c8ae22014-03-21 14:03:59 +0000317 ASSERT_EQUAL_64(0xf0000000000000ff, x5);
armvixlad96eda2013-06-14 11:42:37 +0100318 ASSERT_EQUAL_64(0x00000001, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000319 ASSERT_EQUAL_64(0x0000000000000000, x7);
armvixlad96eda2013-06-14 11:42:37 +0100320 ASSERT_EQUAL_64(0x7ff80000, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000321 ASSERT_EQUAL_64(0x3ffc000000000000, x9);
armvixlad96eda2013-06-14 11:42:37 +0100322 ASSERT_EQUAL_64(0xffffff00, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000323 ASSERT_EQUAL_64(0x0000000000000001, x11);
armvixlad96eda2013-06-14 11:42:37 +0100324 ASSERT_EQUAL_64(0xffff8003, x12);
armvixlb0c8ae22014-03-21 14:03:59 +0000325 ASSERT_EQUAL_64(0xffffffffffff0007, x13);
326 ASSERT_EQUAL_64(0xfffffffffffe000f, x14);
327 ASSERT_EQUAL_64(0xfffffffffffe000f, x15);
armvixlad96eda2013-06-14 11:42:37 +0100328
329 TEARDOWN();
330}
331
332
armvixlf37fdc02014-02-05 13:22:16 +0000333TEST(mov_imm_w) {
334 SETUP();
335
336 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000337 __ Mov(w0, 0xffffffff);
338 __ Mov(w1, 0xffff1234);
339 __ Mov(w2, 0x1234ffff);
340 __ Mov(w3, 0x00000000);
341 __ Mov(w4, 0x00001234);
342 __ Mov(w5, 0x12340000);
343 __ Mov(w6, 0x12345678);
armvixl4a102ba2014-07-14 09:02:40 +0100344 __ Mov(w7, (int32_t)0x80000000);
345 __ Mov(w8, (int32_t)0xffff0000);
346 __ Mov(w9, kWMinInt);
armvixlf37fdc02014-02-05 13:22:16 +0000347 END();
348
349 RUN();
350
armvixlb0c8ae22014-03-21 14:03:59 +0000351 ASSERT_EQUAL_64(0xffffffff, x0);
352 ASSERT_EQUAL_64(0xffff1234, x1);
353 ASSERT_EQUAL_64(0x1234ffff, x2);
354 ASSERT_EQUAL_64(0x00000000, x3);
355 ASSERT_EQUAL_64(0x00001234, x4);
356 ASSERT_EQUAL_64(0x12340000, x5);
357 ASSERT_EQUAL_64(0x12345678, x6);
armvixl4a102ba2014-07-14 09:02:40 +0100358 ASSERT_EQUAL_64(0x80000000, x7);
359 ASSERT_EQUAL_64(0xffff0000, x8);
360 ASSERT_EQUAL_32(kWMinInt, w9);
armvixlf37fdc02014-02-05 13:22:16 +0000361
362 TEARDOWN();
363}
364
365
366TEST(mov_imm_x) {
367 SETUP();
368
369 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000370 __ Mov(x0, 0xffffffffffffffff);
371 __ Mov(x1, 0xffffffffffff1234);
372 __ Mov(x2, 0xffffffff12345678);
373 __ Mov(x3, 0xffff1234ffff5678);
374 __ Mov(x4, 0x1234ffffffff5678);
375 __ Mov(x5, 0x1234ffff5678ffff);
376 __ Mov(x6, 0x12345678ffffffff);
377 __ Mov(x7, 0x1234ffffffffffff);
378 __ Mov(x8, 0x123456789abcffff);
379 __ Mov(x9, 0x12345678ffff9abc);
380 __ Mov(x10, 0x1234ffff56789abc);
381 __ Mov(x11, 0xffff123456789abc);
382 __ Mov(x12, 0x0000000000000000);
383 __ Mov(x13, 0x0000000000001234);
384 __ Mov(x14, 0x0000000012345678);
385 __ Mov(x15, 0x0000123400005678);
386 __ Mov(x18, 0x1234000000005678);
387 __ Mov(x19, 0x1234000056780000);
388 __ Mov(x20, 0x1234567800000000);
389 __ Mov(x21, 0x1234000000000000);
390 __ Mov(x22, 0x123456789abc0000);
391 __ Mov(x23, 0x1234567800009abc);
392 __ Mov(x24, 0x1234000056789abc);
393 __ Mov(x25, 0x0000123456789abc);
394 __ Mov(x26, 0x123456789abcdef0);
395 __ Mov(x27, 0xffff000000000001);
396 __ Mov(x28, 0x8000ffff00000000);
armvixlf37fdc02014-02-05 13:22:16 +0000397 END();
398
399 RUN();
400
armvixlb0c8ae22014-03-21 14:03:59 +0000401 ASSERT_EQUAL_64(0xffffffffffff1234, x1);
402 ASSERT_EQUAL_64(0xffffffff12345678, x2);
403 ASSERT_EQUAL_64(0xffff1234ffff5678, x3);
404 ASSERT_EQUAL_64(0x1234ffffffff5678, x4);
405 ASSERT_EQUAL_64(0x1234ffff5678ffff, x5);
406 ASSERT_EQUAL_64(0x12345678ffffffff, x6);
407 ASSERT_EQUAL_64(0x1234ffffffffffff, x7);
408 ASSERT_EQUAL_64(0x123456789abcffff, x8);
409 ASSERT_EQUAL_64(0x12345678ffff9abc, x9);
410 ASSERT_EQUAL_64(0x1234ffff56789abc, x10);
411 ASSERT_EQUAL_64(0xffff123456789abc, x11);
412 ASSERT_EQUAL_64(0x0000000000000000, x12);
413 ASSERT_EQUAL_64(0x0000000000001234, x13);
414 ASSERT_EQUAL_64(0x0000000012345678, x14);
415 ASSERT_EQUAL_64(0x0000123400005678, x15);
416 ASSERT_EQUAL_64(0x1234000000005678, x18);
417 ASSERT_EQUAL_64(0x1234000056780000, x19);
418 ASSERT_EQUAL_64(0x1234567800000000, x20);
419 ASSERT_EQUAL_64(0x1234000000000000, x21);
420 ASSERT_EQUAL_64(0x123456789abc0000, x22);
421 ASSERT_EQUAL_64(0x1234567800009abc, x23);
422 ASSERT_EQUAL_64(0x1234000056789abc, x24);
423 ASSERT_EQUAL_64(0x0000123456789abc, x25);
424 ASSERT_EQUAL_64(0x123456789abcdef0, x26);
425 ASSERT_EQUAL_64(0xffff000000000001, x27);
426 ASSERT_EQUAL_64(0x8000ffff00000000, x28);
armvixlf37fdc02014-02-05 13:22:16 +0000427
428
429 TEARDOWN();
430}
431
432
armvixlad96eda2013-06-14 11:42:37 +0100433TEST(mov) {
434 SETUP();
armvixlc68cb642014-09-25 18:49:30 +0100435 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +0100436
437 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000438 __ Mov(x0, 0xffffffffffffffff);
439 __ Mov(x1, 0xffffffffffffffff);
440 __ Mov(x2, 0xffffffffffffffff);
441 __ Mov(x3, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +0100442
armvixlb0c8ae22014-03-21 14:03:59 +0000443 __ Mov(x0, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100444
armvixlb0c8ae22014-03-21 14:03:59 +0000445 __ movz(x1, UINT64_C(0xabcd) << 16);
446 __ movk(x2, UINT64_C(0xabcd) << 32);
447 __ movn(x3, UINT64_C(0xabcd) << 48);
armvixlad96eda2013-06-14 11:42:37 +0100448
armvixlb0c8ae22014-03-21 14:03:59 +0000449 __ Mov(x4, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100450 __ Mov(x5, x4);
451
452 __ Mov(w6, -1);
453
454 // Test that moves back to the same register have the desired effect. This
455 // is a no-op for X registers, and a truncation for W registers.
armvixlb0c8ae22014-03-21 14:03:59 +0000456 __ Mov(x7, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100457 __ Mov(x7, x7);
armvixlb0c8ae22014-03-21 14:03:59 +0000458 __ Mov(x8, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100459 __ Mov(w8, w8);
armvixlb0c8ae22014-03-21 14:03:59 +0000460 __ Mov(x9, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100461 __ Mov(x9, Operand(x9));
armvixlb0c8ae22014-03-21 14:03:59 +0000462 __ Mov(x10, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100463 __ Mov(w10, Operand(w10));
464
465 __ Mov(w11, 0xfff);
466 __ Mov(x12, 0xfff);
467 __ Mov(w13, Operand(w11, LSL, 1));
468 __ Mov(x14, Operand(x12, LSL, 2));
469 __ Mov(w15, Operand(w11, LSR, 3));
470 __ Mov(x18, Operand(x12, LSR, 4));
471 __ Mov(w19, Operand(w11, ASR, 11));
472 __ Mov(x20, Operand(x12, ASR, 12));
473 __ Mov(w21, Operand(w11, ROR, 13));
474 __ Mov(x22, Operand(x12, ROR, 14));
475 __ Mov(w23, Operand(w13, UXTB));
476 __ Mov(x24, Operand(x13, SXTB, 1));
477 __ Mov(w25, Operand(w13, UXTH, 2));
478 __ Mov(x26, Operand(x13, SXTH, 3));
479 __ Mov(x27, Operand(w13, UXTW, 4));
armvixlf37fdc02014-02-05 13:22:16 +0000480
armvixlb0c8ae22014-03-21 14:03:59 +0000481 __ Mov(x28, 0x0123456789abcdef);
armvixlf37fdc02014-02-05 13:22:16 +0000482 __ Mov(w28, w28, kDiscardForSameWReg);
armvixlad96eda2013-06-14 11:42:37 +0100483 END();
484
485 RUN();
486
armvixlb0c8ae22014-03-21 14:03:59 +0000487 ASSERT_EQUAL_64(0x0123456789abcdef, x0);
488 ASSERT_EQUAL_64(0x00000000abcd0000, x1);
489 ASSERT_EQUAL_64(0xffffabcdffffffff, x2);
490 ASSERT_EQUAL_64(0x5432ffffffffffff, x3);
armvixlad96eda2013-06-14 11:42:37 +0100491 ASSERT_EQUAL_64(x4, x5);
492 ASSERT_EQUAL_32(-1, w6);
armvixlb0c8ae22014-03-21 14:03:59 +0000493 ASSERT_EQUAL_64(0x0123456789abcdef, x7);
494 ASSERT_EQUAL_32(0x89abcdef, w8);
495 ASSERT_EQUAL_64(0x0123456789abcdef, x9);
496 ASSERT_EQUAL_32(0x89abcdef, w10);
armvixlad96eda2013-06-14 11:42:37 +0100497 ASSERT_EQUAL_64(0x00000fff, x11);
armvixlb0c8ae22014-03-21 14:03:59 +0000498 ASSERT_EQUAL_64(0x0000000000000fff, x12);
armvixlad96eda2013-06-14 11:42:37 +0100499 ASSERT_EQUAL_64(0x00001ffe, x13);
armvixlb0c8ae22014-03-21 14:03:59 +0000500 ASSERT_EQUAL_64(0x0000000000003ffc, x14);
armvixlad96eda2013-06-14 11:42:37 +0100501 ASSERT_EQUAL_64(0x000001ff, x15);
armvixlb0c8ae22014-03-21 14:03:59 +0000502 ASSERT_EQUAL_64(0x00000000000000ff, x18);
armvixlad96eda2013-06-14 11:42:37 +0100503 ASSERT_EQUAL_64(0x00000001, x19);
armvixlb0c8ae22014-03-21 14:03:59 +0000504 ASSERT_EQUAL_64(0x0000000000000000, x20);
armvixlad96eda2013-06-14 11:42:37 +0100505 ASSERT_EQUAL_64(0x7ff80000, x21);
armvixlb0c8ae22014-03-21 14:03:59 +0000506 ASSERT_EQUAL_64(0x3ffc000000000000, x22);
armvixlad96eda2013-06-14 11:42:37 +0100507 ASSERT_EQUAL_64(0x000000fe, x23);
armvixlb0c8ae22014-03-21 14:03:59 +0000508 ASSERT_EQUAL_64(0xfffffffffffffffc, x24);
armvixlad96eda2013-06-14 11:42:37 +0100509 ASSERT_EQUAL_64(0x00007ff8, x25);
armvixlb0c8ae22014-03-21 14:03:59 +0000510 ASSERT_EQUAL_64(0x000000000000fff0, x26);
511 ASSERT_EQUAL_64(0x000000000001ffe0, x27);
512 ASSERT_EQUAL_64(0x0123456789abcdef, x28);
armvixlad96eda2013-06-14 11:42:37 +0100513
514 TEARDOWN();
515}
516
517
518TEST(orr) {
519 SETUP();
520
521 START();
522 __ Mov(x0, 0xf0f0);
523 __ Mov(x1, 0xf00000ff);
524
525 __ Orr(x2, x0, Operand(x1));
526 __ Orr(w3, w0, Operand(w1, LSL, 28));
527 __ Orr(x4, x0, Operand(x1, LSL, 32));
528 __ Orr(x5, x0, Operand(x1, LSR, 4));
529 __ Orr(w6, w0, Operand(w1, ASR, 4));
530 __ Orr(x7, x0, Operand(x1, ASR, 4));
531 __ Orr(w8, w0, Operand(w1, ROR, 12));
532 __ Orr(x9, x0, Operand(x1, ROR, 12));
armvixlb0c8ae22014-03-21 14:03:59 +0000533 __ Orr(w10, w0, 0xf);
534 __ Orr(x11, x0, 0xf0000000f0000000);
armvixlad96eda2013-06-14 11:42:37 +0100535 END();
536
537 RUN();
538
armvixlb0c8ae22014-03-21 14:03:59 +0000539 ASSERT_EQUAL_64(0x00000000f000f0ff, x2);
armvixlad96eda2013-06-14 11:42:37 +0100540 ASSERT_EQUAL_64(0xf000f0f0, x3);
armvixlb0c8ae22014-03-21 14:03:59 +0000541 ASSERT_EQUAL_64(0xf00000ff0000f0f0, x4);
542 ASSERT_EQUAL_64(0x000000000f00f0ff, x5);
armvixlad96eda2013-06-14 11:42:37 +0100543 ASSERT_EQUAL_64(0xff00f0ff, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000544 ASSERT_EQUAL_64(0x000000000f00f0ff, x7);
armvixlad96eda2013-06-14 11:42:37 +0100545 ASSERT_EQUAL_64(0x0ffff0f0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000546 ASSERT_EQUAL_64(0x0ff00000000ff0f0, x9);
547 ASSERT_EQUAL_64(0x0000f0ff, x10);
548 ASSERT_EQUAL_64(0xf0000000f000f0f0, x11);
armvixlad96eda2013-06-14 11:42:37 +0100549
550 TEARDOWN();
551}
552
553
554TEST(orr_extend) {
555 SETUP();
556
557 START();
558 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +0000559 __ Mov(x1, 0x8000000080008080);
armvixlad96eda2013-06-14 11:42:37 +0100560 __ Orr(w6, w0, Operand(w1, UXTB));
561 __ Orr(x7, x0, Operand(x1, UXTH, 1));
562 __ Orr(w8, w0, Operand(w1, UXTW, 2));
563 __ Orr(x9, x0, Operand(x1, UXTX, 3));
564 __ Orr(w10, w0, Operand(w1, SXTB));
565 __ Orr(x11, x0, Operand(x1, SXTH, 1));
566 __ Orr(x12, x0, Operand(x1, SXTW, 2));
567 __ Orr(x13, x0, Operand(x1, SXTX, 3));
568 END();
569
570 RUN();
571
572 ASSERT_EQUAL_64(0x00000081, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000573 ASSERT_EQUAL_64(0x0000000000010101, x7);
armvixlad96eda2013-06-14 11:42:37 +0100574 ASSERT_EQUAL_64(0x00020201, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000575 ASSERT_EQUAL_64(0x0000000400040401, x9);
576 ASSERT_EQUAL_64(0xffffff81, x10);
577 ASSERT_EQUAL_64(0xffffffffffff0101, x11);
578 ASSERT_EQUAL_64(0xfffffffe00020201, x12);
579 ASSERT_EQUAL_64(0x0000000400040401, x13);
armvixlad96eda2013-06-14 11:42:37 +0100580
581 TEARDOWN();
582}
583
584
585TEST(bitwise_wide_imm) {
586 SETUP();
587
588 START();
589 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +0000590 __ Mov(x1, 0xf0f0f0f0f0f0f0f0);
armvixlad96eda2013-06-14 11:42:37 +0100591
armvixlb0c8ae22014-03-21 14:03:59 +0000592 __ Orr(x10, x0, 0x1234567890abcdef);
593 __ Orr(w11, w1, 0x90abcdef);
armvixl4a102ba2014-07-14 09:02:40 +0100594
595 __ Orr(w12, w0, kWMinInt);
596 __ Eor(w13, w0, kWMinInt);
armvixlad96eda2013-06-14 11:42:37 +0100597 END();
598
599 RUN();
600
601 ASSERT_EQUAL_64(0, x0);
armvixlb0c8ae22014-03-21 14:03:59 +0000602 ASSERT_EQUAL_64(0xf0f0f0f0f0f0f0f0, x1);
603 ASSERT_EQUAL_64(0x1234567890abcdef, x10);
604 ASSERT_EQUAL_64(0x00000000f0fbfdff, x11);
armvixl4a102ba2014-07-14 09:02:40 +0100605 ASSERT_EQUAL_32(kWMinInt, w12);
606 ASSERT_EQUAL_32(kWMinInt, w13);
armvixlad96eda2013-06-14 11:42:37 +0100607
608 TEARDOWN();
609}
610
611
612TEST(orn) {
613 SETUP();
614
615 START();
616 __ Mov(x0, 0xf0f0);
617 __ Mov(x1, 0xf00000ff);
618
619 __ Orn(x2, x0, Operand(x1));
620 __ Orn(w3, w0, Operand(w1, LSL, 4));
621 __ Orn(x4, x0, Operand(x1, LSL, 4));
622 __ Orn(x5, x0, Operand(x1, LSR, 1));
623 __ Orn(w6, w0, Operand(w1, ASR, 1));
624 __ Orn(x7, x0, Operand(x1, ASR, 1));
625 __ Orn(w8, w0, Operand(w1, ROR, 16));
626 __ Orn(x9, x0, Operand(x1, ROR, 16));
armvixlb0c8ae22014-03-21 14:03:59 +0000627 __ Orn(w10, w0, 0x0000ffff);
628 __ Orn(x11, x0, 0x0000ffff0000ffff);
armvixlad96eda2013-06-14 11:42:37 +0100629 END();
630
631 RUN();
632
armvixlb0c8ae22014-03-21 14:03:59 +0000633 ASSERT_EQUAL_64(0xffffffff0ffffff0, x2);
armvixlad96eda2013-06-14 11:42:37 +0100634 ASSERT_EQUAL_64(0xfffff0ff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +0000635 ASSERT_EQUAL_64(0xfffffff0fffff0ff, x4);
636 ASSERT_EQUAL_64(0xffffffff87fffff0, x5);
armvixlad96eda2013-06-14 11:42:37 +0100637 ASSERT_EQUAL_64(0x07fffff0, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000638 ASSERT_EQUAL_64(0xffffffff87fffff0, x7);
armvixlad96eda2013-06-14 11:42:37 +0100639 ASSERT_EQUAL_64(0xff00ffff, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000640 ASSERT_EQUAL_64(0xff00ffffffffffff, x9);
armvixlad96eda2013-06-14 11:42:37 +0100641 ASSERT_EQUAL_64(0xfffff0f0, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000642 ASSERT_EQUAL_64(0xffff0000fffff0f0, x11);
armvixlad96eda2013-06-14 11:42:37 +0100643
644 TEARDOWN();
645}
646
647
648TEST(orn_extend) {
649 SETUP();
650
651 START();
652 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +0000653 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100654 __ Orn(w6, w0, Operand(w1, UXTB));
655 __ Orn(x7, x0, Operand(x1, UXTH, 1));
656 __ Orn(w8, w0, Operand(w1, UXTW, 2));
657 __ Orn(x9, x0, Operand(x1, UXTX, 3));
658 __ Orn(w10, w0, Operand(w1, SXTB));
659 __ Orn(x11, x0, Operand(x1, SXTH, 1));
660 __ Orn(x12, x0, Operand(x1, SXTW, 2));
661 __ Orn(x13, x0, Operand(x1, SXTX, 3));
662 END();
663
664 RUN();
665
666 ASSERT_EQUAL_64(0xffffff7f, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000667 ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
armvixlad96eda2013-06-14 11:42:37 +0100668 ASSERT_EQUAL_64(0xfffdfdfb, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000669 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
armvixlad96eda2013-06-14 11:42:37 +0100670 ASSERT_EQUAL_64(0x0000007f, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000671 ASSERT_EQUAL_64(0x000000000000fefd, x11);
672 ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
673 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
armvixlad96eda2013-06-14 11:42:37 +0100674
675 TEARDOWN();
676}
677
678
679TEST(and_) {
680 SETUP();
681
682 START();
683 __ Mov(x0, 0xfff0);
684 __ Mov(x1, 0xf00000ff);
685
686 __ And(x2, x0, Operand(x1));
687 __ And(w3, w0, Operand(w1, LSL, 4));
688 __ And(x4, x0, Operand(x1, LSL, 4));
689 __ And(x5, x0, Operand(x1, LSR, 1));
690 __ And(w6, w0, Operand(w1, ASR, 20));
691 __ And(x7, x0, Operand(x1, ASR, 20));
692 __ And(w8, w0, Operand(w1, ROR, 28));
693 __ And(x9, x0, Operand(x1, ROR, 28));
694 __ And(w10, w0, Operand(0xff00));
695 __ And(x11, x0, Operand(0xff));
696 END();
697
698 RUN();
699
700 ASSERT_EQUAL_64(0x000000f0, x2);
701 ASSERT_EQUAL_64(0x00000ff0, x3);
702 ASSERT_EQUAL_64(0x00000ff0, x4);
703 ASSERT_EQUAL_64(0x00000070, x5);
704 ASSERT_EQUAL_64(0x0000ff00, x6);
705 ASSERT_EQUAL_64(0x00000f00, x7);
706 ASSERT_EQUAL_64(0x00000ff0, x8);
707 ASSERT_EQUAL_64(0x00000000, x9);
708 ASSERT_EQUAL_64(0x0000ff00, x10);
709 ASSERT_EQUAL_64(0x000000f0, x11);
710
711 TEARDOWN();
712}
713
714
715TEST(and_extend) {
716 SETUP();
717
718 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000719 __ Mov(x0, 0xffffffffffffffff);
720 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100721 __ And(w6, w0, Operand(w1, UXTB));
722 __ And(x7, x0, Operand(x1, UXTH, 1));
723 __ And(w8, w0, Operand(w1, UXTW, 2));
724 __ And(x9, x0, Operand(x1, UXTX, 3));
725 __ And(w10, w0, Operand(w1, SXTB));
726 __ And(x11, x0, Operand(x1, SXTH, 1));
727 __ And(x12, x0, Operand(x1, SXTW, 2));
728 __ And(x13, x0, Operand(x1, SXTX, 3));
729 END();
730
731 RUN();
732
733 ASSERT_EQUAL_64(0x00000081, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000734 ASSERT_EQUAL_64(0x0000000000010102, x7);
armvixlad96eda2013-06-14 11:42:37 +0100735 ASSERT_EQUAL_64(0x00020204, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000736 ASSERT_EQUAL_64(0x0000000400040408, x9);
armvixlad96eda2013-06-14 11:42:37 +0100737 ASSERT_EQUAL_64(0xffffff81, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000738 ASSERT_EQUAL_64(0xffffffffffff0102, x11);
739 ASSERT_EQUAL_64(0xfffffffe00020204, x12);
740 ASSERT_EQUAL_64(0x0000000400040408, x13);
armvixlad96eda2013-06-14 11:42:37 +0100741
742 TEARDOWN();
743}
744
745
746TEST(ands) {
747 SETUP();
748
749 START();
750 __ Mov(x1, 0xf00000ff);
armvixlf37fdc02014-02-05 13:22:16 +0000751 __ Ands(w0, w1, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +0100752 END();
753
754 RUN();
755
756 ASSERT_EQUAL_NZCV(NFlag);
757 ASSERT_EQUAL_64(0xf00000ff, x0);
758
759 START();
760 __ Mov(x0, 0xfff0);
761 __ Mov(x1, 0xf00000ff);
armvixlf37fdc02014-02-05 13:22:16 +0000762 __ Ands(w0, w0, Operand(w1, LSR, 4));
armvixlad96eda2013-06-14 11:42:37 +0100763 END();
764
765 RUN();
766
767 ASSERT_EQUAL_NZCV(ZFlag);
768 ASSERT_EQUAL_64(0x00000000, x0);
769
770 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000771 __ Mov(x0, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +0100772 __ Mov(x1, 0x00000001);
armvixlf37fdc02014-02-05 13:22:16 +0000773 __ Ands(x0, x0, Operand(x1, ROR, 1));
armvixlad96eda2013-06-14 11:42:37 +0100774 END();
775
776 RUN();
777
778 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +0000779 ASSERT_EQUAL_64(0x8000000000000000, x0);
armvixlad96eda2013-06-14 11:42:37 +0100780
781 START();
782 __ Mov(x0, 0xfff0);
armvixlf37fdc02014-02-05 13:22:16 +0000783 __ Ands(w0, w0, Operand(0xf));
armvixlad96eda2013-06-14 11:42:37 +0100784 END();
785
786 RUN();
787
788 ASSERT_EQUAL_NZCV(ZFlag);
789 ASSERT_EQUAL_64(0x00000000, x0);
790
791 START();
792 __ Mov(x0, 0xff000000);
armvixlf37fdc02014-02-05 13:22:16 +0000793 __ Ands(w0, w0, Operand(0x80000000));
armvixlad96eda2013-06-14 11:42:37 +0100794 END();
795
796 RUN();
797
798 ASSERT_EQUAL_NZCV(NFlag);
799 ASSERT_EQUAL_64(0x80000000, x0);
800
801 TEARDOWN();
802}
803
804
805TEST(bic) {
806 SETUP();
807
808 START();
809 __ Mov(x0, 0xfff0);
810 __ Mov(x1, 0xf00000ff);
811
812 __ Bic(x2, x0, Operand(x1));
813 __ Bic(w3, w0, Operand(w1, LSL, 4));
814 __ Bic(x4, x0, Operand(x1, LSL, 4));
815 __ Bic(x5, x0, Operand(x1, LSR, 1));
816 __ Bic(w6, w0, Operand(w1, ASR, 20));
817 __ Bic(x7, x0, Operand(x1, ASR, 20));
818 __ Bic(w8, w0, Operand(w1, ROR, 28));
819 __ Bic(x9, x0, Operand(x1, ROR, 24));
820 __ Bic(x10, x0, Operand(0x1f));
821 __ Bic(x11, x0, Operand(0x100));
822
823 // Test bic into sp when the constant cannot be encoded in the immediate
824 // field.
825 // Use x20 to preserve sp. We check for the result via x21 because the
826 // test infrastructure requires that sp be restored to its original value.
827 __ Mov(x20, sp);
828 __ Mov(x0, 0xffffff);
829 __ Bic(sp, x0, Operand(0xabcdef));
830 __ Mov(x21, sp);
831 __ Mov(sp, x20);
832 END();
833
834 RUN();
835
836 ASSERT_EQUAL_64(0x0000ff00, x2);
837 ASSERT_EQUAL_64(0x0000f000, x3);
838 ASSERT_EQUAL_64(0x0000f000, x4);
839 ASSERT_EQUAL_64(0x0000ff80, x5);
840 ASSERT_EQUAL_64(0x000000f0, x6);
841 ASSERT_EQUAL_64(0x0000f0f0, x7);
842 ASSERT_EQUAL_64(0x0000f000, x8);
843 ASSERT_EQUAL_64(0x0000ff00, x9);
844 ASSERT_EQUAL_64(0x0000ffe0, x10);
845 ASSERT_EQUAL_64(0x0000fef0, x11);
846
847 ASSERT_EQUAL_64(0x543210, x21);
848
849 TEARDOWN();
850}
851
852
853TEST(bic_extend) {
854 SETUP();
855
856 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000857 __ Mov(x0, 0xffffffffffffffff);
858 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100859 __ Bic(w6, w0, Operand(w1, UXTB));
860 __ Bic(x7, x0, Operand(x1, UXTH, 1));
861 __ Bic(w8, w0, Operand(w1, UXTW, 2));
862 __ Bic(x9, x0, Operand(x1, UXTX, 3));
863 __ Bic(w10, w0, Operand(w1, SXTB));
864 __ Bic(x11, x0, Operand(x1, SXTH, 1));
865 __ Bic(x12, x0, Operand(x1, SXTW, 2));
866 __ Bic(x13, x0, Operand(x1, SXTX, 3));
867 END();
868
869 RUN();
870
871 ASSERT_EQUAL_64(0xffffff7e, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000872 ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
armvixlad96eda2013-06-14 11:42:37 +0100873 ASSERT_EQUAL_64(0xfffdfdfb, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000874 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
armvixlad96eda2013-06-14 11:42:37 +0100875 ASSERT_EQUAL_64(0x0000007e, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000876 ASSERT_EQUAL_64(0x000000000000fefd, x11);
877 ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
878 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
armvixlad96eda2013-06-14 11:42:37 +0100879
880 TEARDOWN();
881}
882
883
884TEST(bics) {
885 SETUP();
886
887 START();
888 __ Mov(x1, 0xffff);
armvixlf37fdc02014-02-05 13:22:16 +0000889 __ Bics(w0, w1, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +0100890 END();
891
892 RUN();
893
894 ASSERT_EQUAL_NZCV(ZFlag);
895 ASSERT_EQUAL_64(0x00000000, x0);
896
897 START();
898 __ Mov(x0, 0xffffffff);
armvixlf37fdc02014-02-05 13:22:16 +0000899 __ Bics(w0, w0, Operand(w0, LSR, 1));
armvixlad96eda2013-06-14 11:42:37 +0100900 END();
901
902 RUN();
903
904 ASSERT_EQUAL_NZCV(NFlag);
905 ASSERT_EQUAL_64(0x80000000, x0);
906
907 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000908 __ Mov(x0, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +0100909 __ Mov(x1, 0x00000001);
armvixlf37fdc02014-02-05 13:22:16 +0000910 __ Bics(x0, x0, Operand(x1, ROR, 1));
armvixlad96eda2013-06-14 11:42:37 +0100911 END();
912
913 RUN();
914
915 ASSERT_EQUAL_NZCV(ZFlag);
916 ASSERT_EQUAL_64(0x00000000, x0);
917
918 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000919 __ Mov(x0, 0xffffffffffffffff);
920 __ Bics(x0, x0, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +0100921 END();
922
923 RUN();
924
925 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +0000926 ASSERT_EQUAL_64(0x8000000000000000, x0);
armvixlad96eda2013-06-14 11:42:37 +0100927
928 START();
929 __ Mov(w0, 0xffff0000);
armvixlb0c8ae22014-03-21 14:03:59 +0000930 __ Bics(w0, w0, 0xfffffff0);
armvixlad96eda2013-06-14 11:42:37 +0100931 END();
932
933 RUN();
934
935 ASSERT_EQUAL_NZCV(ZFlag);
936 ASSERT_EQUAL_64(0x00000000, x0);
937
938 TEARDOWN();
939}
940
941
942TEST(eor) {
943 SETUP();
944
945 START();
946 __ Mov(x0, 0xfff0);
947 __ Mov(x1, 0xf00000ff);
948
949 __ Eor(x2, x0, Operand(x1));
950 __ Eor(w3, w0, Operand(w1, LSL, 4));
951 __ Eor(x4, x0, Operand(x1, LSL, 4));
952 __ Eor(x5, x0, Operand(x1, LSR, 1));
953 __ Eor(w6, w0, Operand(w1, ASR, 20));
954 __ Eor(x7, x0, Operand(x1, ASR, 20));
955 __ Eor(w8, w0, Operand(w1, ROR, 28));
956 __ Eor(x9, x0, Operand(x1, ROR, 28));
armvixlb0c8ae22014-03-21 14:03:59 +0000957 __ Eor(w10, w0, 0xff00ff00);
958 __ Eor(x11, x0, 0xff00ff00ff00ff00);
armvixlad96eda2013-06-14 11:42:37 +0100959 END();
960
961 RUN();
962
armvixlb0c8ae22014-03-21 14:03:59 +0000963 ASSERT_EQUAL_64(0x00000000f000ff0f, x2);
armvixlad96eda2013-06-14 11:42:37 +0100964 ASSERT_EQUAL_64(0x0000f000, x3);
armvixlb0c8ae22014-03-21 14:03:59 +0000965 ASSERT_EQUAL_64(0x0000000f0000f000, x4);
966 ASSERT_EQUAL_64(0x000000007800ff8f, x5);
armvixlad96eda2013-06-14 11:42:37 +0100967 ASSERT_EQUAL_64(0xffff00f0, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000968 ASSERT_EQUAL_64(0x000000000000f0f0, x7);
armvixlad96eda2013-06-14 11:42:37 +0100969 ASSERT_EQUAL_64(0x0000f00f, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000970 ASSERT_EQUAL_64(0x00000ff00000ffff, x9);
armvixlad96eda2013-06-14 11:42:37 +0100971 ASSERT_EQUAL_64(0xff0000f0, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000972 ASSERT_EQUAL_64(0xff00ff00ff0000f0, x11);
armvixlad96eda2013-06-14 11:42:37 +0100973
974 TEARDOWN();
975}
976
977TEST(eor_extend) {
978 SETUP();
979
980 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000981 __ Mov(x0, 0x1111111111111111);
982 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100983 __ Eor(w6, w0, Operand(w1, UXTB));
984 __ Eor(x7, x0, Operand(x1, UXTH, 1));
985 __ Eor(w8, w0, Operand(w1, UXTW, 2));
986 __ Eor(x9, x0, Operand(x1, UXTX, 3));
987 __ Eor(w10, w0, Operand(w1, SXTB));
988 __ Eor(x11, x0, Operand(x1, SXTH, 1));
989 __ Eor(x12, x0, Operand(x1, SXTW, 2));
990 __ Eor(x13, x0, Operand(x1, SXTX, 3));
991 END();
992
993 RUN();
994
995 ASSERT_EQUAL_64(0x11111190, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000996 ASSERT_EQUAL_64(0x1111111111101013, x7);
armvixlad96eda2013-06-14 11:42:37 +0100997 ASSERT_EQUAL_64(0x11131315, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000998 ASSERT_EQUAL_64(0x1111111511151519, x9);
armvixlad96eda2013-06-14 11:42:37 +0100999 ASSERT_EQUAL_64(0xeeeeee90, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00001000 ASSERT_EQUAL_64(0xeeeeeeeeeeee1013, x11);
1001 ASSERT_EQUAL_64(0xeeeeeeef11131315, x12);
1002 ASSERT_EQUAL_64(0x1111111511151519, x13);
armvixlad96eda2013-06-14 11:42:37 +01001003
1004 TEARDOWN();
1005}
1006
1007
1008TEST(eon) {
1009 SETUP();
1010
1011 START();
1012 __ Mov(x0, 0xfff0);
1013 __ Mov(x1, 0xf00000ff);
1014
1015 __ Eon(x2, x0, Operand(x1));
1016 __ Eon(w3, w0, Operand(w1, LSL, 4));
1017 __ Eon(x4, x0, Operand(x1, LSL, 4));
1018 __ Eon(x5, x0, Operand(x1, LSR, 1));
1019 __ Eon(w6, w0, Operand(w1, ASR, 20));
1020 __ Eon(x7, x0, Operand(x1, ASR, 20));
1021 __ Eon(w8, w0, Operand(w1, ROR, 28));
1022 __ Eon(x9, x0, Operand(x1, ROR, 28));
armvixlb0c8ae22014-03-21 14:03:59 +00001023 __ Eon(w10, w0, 0x03c003c0);
1024 __ Eon(x11, x0, 0x0000100000001000);
armvixlad96eda2013-06-14 11:42:37 +01001025 END();
1026
1027 RUN();
1028
armvixlb0c8ae22014-03-21 14:03:59 +00001029 ASSERT_EQUAL_64(0xffffffff0fff00f0, x2);
armvixlad96eda2013-06-14 11:42:37 +01001030 ASSERT_EQUAL_64(0xffff0fff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00001031 ASSERT_EQUAL_64(0xfffffff0ffff0fff, x4);
1032 ASSERT_EQUAL_64(0xffffffff87ff0070, x5);
armvixlad96eda2013-06-14 11:42:37 +01001033 ASSERT_EQUAL_64(0x0000ff0f, x6);
armvixlb0c8ae22014-03-21 14:03:59 +00001034 ASSERT_EQUAL_64(0xffffffffffff0f0f, x7);
armvixlad96eda2013-06-14 11:42:37 +01001035 ASSERT_EQUAL_64(0xffff0ff0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001036 ASSERT_EQUAL_64(0xfffff00fffff0000, x9);
armvixlad96eda2013-06-14 11:42:37 +01001037 ASSERT_EQUAL_64(0xfc3f03cf, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00001038 ASSERT_EQUAL_64(0xffffefffffff100f, x11);
armvixlad96eda2013-06-14 11:42:37 +01001039
1040 TEARDOWN();
1041}
1042
1043
1044TEST(eon_extend) {
1045 SETUP();
1046
1047 START();
armvixlb0c8ae22014-03-21 14:03:59 +00001048 __ Mov(x0, 0x1111111111111111);
1049 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +01001050 __ Eon(w6, w0, Operand(w1, UXTB));
1051 __ Eon(x7, x0, Operand(x1, UXTH, 1));
1052 __ Eon(w8, w0, Operand(w1, UXTW, 2));
1053 __ Eon(x9, x0, Operand(x1, UXTX, 3));
1054 __ Eon(w10, w0, Operand(w1, SXTB));
1055 __ Eon(x11, x0, Operand(x1, SXTH, 1));
1056 __ Eon(x12, x0, Operand(x1, SXTW, 2));
1057 __ Eon(x13, x0, Operand(x1, SXTX, 3));
1058 END();
1059
1060 RUN();
1061
1062 ASSERT_EQUAL_64(0xeeeeee6f, x6);
armvixlb0c8ae22014-03-21 14:03:59 +00001063 ASSERT_EQUAL_64(0xeeeeeeeeeeefefec, x7);
armvixlad96eda2013-06-14 11:42:37 +01001064 ASSERT_EQUAL_64(0xeeececea, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001065 ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x9);
armvixlad96eda2013-06-14 11:42:37 +01001066 ASSERT_EQUAL_64(0x1111116f, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00001067 ASSERT_EQUAL_64(0x111111111111efec, x11);
1068 ASSERT_EQUAL_64(0x11111110eeececea, x12);
1069 ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x13);
armvixlad96eda2013-06-14 11:42:37 +01001070
1071 TEARDOWN();
1072}
1073
1074
1075TEST(mul) {
1076 SETUP();
1077
1078 START();
armvixl6e2c8272015-03-31 11:04:14 +01001079 __ Mov(x25, 0);
1080 __ Mov(x26, 1);
armvixlad96eda2013-06-14 11:42:37 +01001081 __ Mov(x18, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001082 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001083
armvixl6e2c8272015-03-31 11:04:14 +01001084 __ Mul(w0, w25, w25);
1085 __ Mul(w1, w25, w26);
1086 __ Mul(w2, w26, w18);
armvixlad96eda2013-06-14 11:42:37 +01001087 __ Mul(w3, w18, w19);
armvixl6e2c8272015-03-31 11:04:14 +01001088 __ Mul(x4, x25, x25);
1089 __ Mul(x5, x26, x18);
armvixlad96eda2013-06-14 11:42:37 +01001090 __ Mul(x6, x18, x19);
1091 __ Mul(x7, x19, x19);
armvixl6e2c8272015-03-31 11:04:14 +01001092 __ Smull(x8, w26, w18);
armvixlad96eda2013-06-14 11:42:37 +01001093 __ Smull(x9, w18, w18);
1094 __ Smull(x10, w19, w19);
armvixl6e2c8272015-03-31 11:04:14 +01001095 __ Mneg(w11, w25, w25);
1096 __ Mneg(w12, w25, w26);
1097 __ Mneg(w13, w26, w18);
armvixlad96eda2013-06-14 11:42:37 +01001098 __ Mneg(w14, w18, w19);
armvixl6e2c8272015-03-31 11:04:14 +01001099 __ Mneg(x20, x25, x25);
1100 __ Mneg(x21, x26, x18);
armvixlad96eda2013-06-14 11:42:37 +01001101 __ Mneg(x22, x18, x19);
1102 __ Mneg(x23, x19, x19);
1103 END();
1104
1105 RUN();
1106
1107 ASSERT_EQUAL_64(0, x0);
1108 ASSERT_EQUAL_64(0, x1);
1109 ASSERT_EQUAL_64(0xffffffff, x2);
1110 ASSERT_EQUAL_64(1, x3);
1111 ASSERT_EQUAL_64(0, x4);
1112 ASSERT_EQUAL_64(0xffffffff, x5);
armvixlb0c8ae22014-03-21 14:03:59 +00001113 ASSERT_EQUAL_64(0xffffffff00000001, x6);
armvixlad96eda2013-06-14 11:42:37 +01001114 ASSERT_EQUAL_64(1, x7);
armvixlb0c8ae22014-03-21 14:03:59 +00001115 ASSERT_EQUAL_64(0xffffffffffffffff, x8);
armvixlad96eda2013-06-14 11:42:37 +01001116 ASSERT_EQUAL_64(1, x9);
1117 ASSERT_EQUAL_64(1, x10);
1118 ASSERT_EQUAL_64(0, x11);
1119 ASSERT_EQUAL_64(0, x12);
1120 ASSERT_EQUAL_64(1, x13);
1121 ASSERT_EQUAL_64(0xffffffff, x14);
1122 ASSERT_EQUAL_64(0, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00001123 ASSERT_EQUAL_64(0xffffffff00000001, x21);
armvixlad96eda2013-06-14 11:42:37 +01001124 ASSERT_EQUAL_64(0xffffffff, x22);
armvixlb0c8ae22014-03-21 14:03:59 +00001125 ASSERT_EQUAL_64(0xffffffffffffffff, x23);
armvixlad96eda2013-06-14 11:42:37 +01001126
1127 TEARDOWN();
1128}
1129
1130
armvixlf37fdc02014-02-05 13:22:16 +00001131static void SmullHelper(int64_t expected, int64_t a, int64_t b) {
1132 SETUP();
1133 START();
1134 __ Mov(w0, a);
1135 __ Mov(w1, b);
1136 __ Smull(x2, w0, w1);
1137 END();
1138 RUN();
1139 ASSERT_EQUAL_64(expected, x2);
1140 TEARDOWN();
1141}
1142
1143
1144TEST(smull) {
1145 SmullHelper(0, 0, 0);
1146 SmullHelper(1, 1, 1);
1147 SmullHelper(-1, -1, 1);
1148 SmullHelper(1, -1, -1);
1149 SmullHelper(0xffffffff80000000, 0x80000000, 1);
1150 SmullHelper(0x0000000080000000, 0x00010000, 0x00008000);
1151}
1152
1153
armvixlad96eda2013-06-14 11:42:37 +01001154TEST(madd) {
1155 SETUP();
1156
1157 START();
1158 __ Mov(x16, 0);
1159 __ Mov(x17, 1);
1160 __ Mov(x18, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001161 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001162
1163 __ Madd(w0, w16, w16, w16);
1164 __ Madd(w1, w16, w16, w17);
1165 __ Madd(w2, w16, w16, w18);
1166 __ Madd(w3, w16, w16, w19);
1167 __ Madd(w4, w16, w17, w17);
1168 __ Madd(w5, w17, w17, w18);
1169 __ Madd(w6, w17, w17, w19);
1170 __ Madd(w7, w17, w18, w16);
1171 __ Madd(w8, w17, w18, w18);
1172 __ Madd(w9, w18, w18, w17);
1173 __ Madd(w10, w18, w19, w18);
1174 __ Madd(w11, w19, w19, w19);
1175
1176 __ Madd(x12, x16, x16, x16);
1177 __ Madd(x13, x16, x16, x17);
1178 __ Madd(x14, x16, x16, x18);
1179 __ Madd(x15, x16, x16, x19);
1180 __ Madd(x20, x16, x17, x17);
1181 __ Madd(x21, x17, x17, x18);
1182 __ Madd(x22, x17, x17, x19);
1183 __ Madd(x23, x17, x18, x16);
1184 __ Madd(x24, x17, x18, x18);
1185 __ Madd(x25, x18, x18, x17);
1186 __ Madd(x26, x18, x19, x18);
1187 __ Madd(x27, x19, x19, x19);
1188
1189 END();
1190
1191 RUN();
1192
1193 ASSERT_EQUAL_64(0, x0);
1194 ASSERT_EQUAL_64(1, x1);
1195 ASSERT_EQUAL_64(0xffffffff, x2);
1196 ASSERT_EQUAL_64(0xffffffff, x3);
1197 ASSERT_EQUAL_64(1, x4);
1198 ASSERT_EQUAL_64(0, x5);
1199 ASSERT_EQUAL_64(0, x6);
1200 ASSERT_EQUAL_64(0xffffffff, x7);
1201 ASSERT_EQUAL_64(0xfffffffe, x8);
1202 ASSERT_EQUAL_64(2, x9);
1203 ASSERT_EQUAL_64(0, x10);
1204 ASSERT_EQUAL_64(0, x11);
1205
1206 ASSERT_EQUAL_64(0, x12);
1207 ASSERT_EQUAL_64(1, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00001208 ASSERT_EQUAL_64(0x00000000ffffffff, x14);
armvixlad96eda2013-06-14 11:42:37 +01001209 ASSERT_EQUAL_64(0xffffffffffffffff, x15);
1210 ASSERT_EQUAL_64(1, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00001211 ASSERT_EQUAL_64(0x0000000100000000, x21);
armvixlad96eda2013-06-14 11:42:37 +01001212 ASSERT_EQUAL_64(0, x22);
armvixlb0c8ae22014-03-21 14:03:59 +00001213 ASSERT_EQUAL_64(0x00000000ffffffff, x23);
1214 ASSERT_EQUAL_64(0x00000001fffffffe, x24);
1215 ASSERT_EQUAL_64(0xfffffffe00000002, x25);
armvixlad96eda2013-06-14 11:42:37 +01001216 ASSERT_EQUAL_64(0, x26);
1217 ASSERT_EQUAL_64(0, x27);
1218
1219 TEARDOWN();
1220}
1221
1222
1223TEST(msub) {
1224 SETUP();
1225
1226 START();
1227 __ Mov(x16, 0);
1228 __ Mov(x17, 1);
1229 __ Mov(x18, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001230 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001231
1232 __ Msub(w0, w16, w16, w16);
1233 __ Msub(w1, w16, w16, w17);
1234 __ Msub(w2, w16, w16, w18);
1235 __ Msub(w3, w16, w16, w19);
1236 __ Msub(w4, w16, w17, w17);
1237 __ Msub(w5, w17, w17, w18);
1238 __ Msub(w6, w17, w17, w19);
1239 __ Msub(w7, w17, w18, w16);
1240 __ Msub(w8, w17, w18, w18);
1241 __ Msub(w9, w18, w18, w17);
1242 __ Msub(w10, w18, w19, w18);
1243 __ Msub(w11, w19, w19, w19);
1244
1245 __ Msub(x12, x16, x16, x16);
1246 __ Msub(x13, x16, x16, x17);
1247 __ Msub(x14, x16, x16, x18);
1248 __ Msub(x15, x16, x16, x19);
1249 __ Msub(x20, x16, x17, x17);
1250 __ Msub(x21, x17, x17, x18);
1251 __ Msub(x22, x17, x17, x19);
1252 __ Msub(x23, x17, x18, x16);
1253 __ Msub(x24, x17, x18, x18);
1254 __ Msub(x25, x18, x18, x17);
1255 __ Msub(x26, x18, x19, x18);
1256 __ Msub(x27, x19, x19, x19);
1257
1258 END();
1259
1260 RUN();
1261
1262 ASSERT_EQUAL_64(0, x0);
1263 ASSERT_EQUAL_64(1, x1);
1264 ASSERT_EQUAL_64(0xffffffff, x2);
1265 ASSERT_EQUAL_64(0xffffffff, x3);
1266 ASSERT_EQUAL_64(1, x4);
1267 ASSERT_EQUAL_64(0xfffffffe, x5);
1268 ASSERT_EQUAL_64(0xfffffffe, x6);
1269 ASSERT_EQUAL_64(1, x7);
1270 ASSERT_EQUAL_64(0, x8);
1271 ASSERT_EQUAL_64(0, x9);
1272 ASSERT_EQUAL_64(0xfffffffe, x10);
1273 ASSERT_EQUAL_64(0xfffffffe, x11);
1274
1275 ASSERT_EQUAL_64(0, x12);
1276 ASSERT_EQUAL_64(1, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00001277 ASSERT_EQUAL_64(0x00000000ffffffff, x14);
1278 ASSERT_EQUAL_64(0xffffffffffffffff, x15);
armvixlad96eda2013-06-14 11:42:37 +01001279 ASSERT_EQUAL_64(1, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00001280 ASSERT_EQUAL_64(0x00000000fffffffe, x21);
1281 ASSERT_EQUAL_64(0xfffffffffffffffe, x22);
1282 ASSERT_EQUAL_64(0xffffffff00000001, x23);
armvixlad96eda2013-06-14 11:42:37 +01001283 ASSERT_EQUAL_64(0, x24);
armvixlb0c8ae22014-03-21 14:03:59 +00001284 ASSERT_EQUAL_64(0x0000000200000000, x25);
1285 ASSERT_EQUAL_64(0x00000001fffffffe, x26);
1286 ASSERT_EQUAL_64(0xfffffffffffffffe, x27);
armvixlad96eda2013-06-14 11:42:37 +01001287
1288 TEARDOWN();
1289}
1290
1291
1292TEST(smulh) {
1293 SETUP();
1294
1295 START();
1296 __ Mov(x20, 0);
1297 __ Mov(x21, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00001298 __ Mov(x22, 0x0000000100000000);
1299 __ Mov(x23, 0x0000000012345678);
1300 __ Mov(x24, 0x0123456789abcdef);
1301 __ Mov(x25, 0x0000000200000000);
1302 __ Mov(x26, 0x8000000000000000);
1303 __ Mov(x27, 0xffffffffffffffff);
1304 __ Mov(x28, 0x5555555555555555);
1305 __ Mov(x29, 0xaaaaaaaaaaaaaaaa);
armvixlad96eda2013-06-14 11:42:37 +01001306
1307 __ Smulh(x0, x20, x24);
1308 __ Smulh(x1, x21, x24);
1309 __ Smulh(x2, x22, x23);
1310 __ Smulh(x3, x22, x24);
1311 __ Smulh(x4, x24, x25);
1312 __ Smulh(x5, x23, x27);
1313 __ Smulh(x6, x26, x26);
1314 __ Smulh(x7, x26, x27);
1315 __ Smulh(x8, x27, x27);
1316 __ Smulh(x9, x28, x28);
1317 __ Smulh(x10, x28, x29);
1318 __ Smulh(x11, x29, x29);
1319 END();
1320
1321 RUN();
1322
1323 ASSERT_EQUAL_64(0, x0);
1324 ASSERT_EQUAL_64(0, x1);
1325 ASSERT_EQUAL_64(0, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00001326 ASSERT_EQUAL_64(0x0000000001234567, x3);
1327 ASSERT_EQUAL_64(0x0000000002468acf, x4);
1328 ASSERT_EQUAL_64(0xffffffffffffffff, x5);
1329 ASSERT_EQUAL_64(0x4000000000000000, x6);
armvixlad96eda2013-06-14 11:42:37 +01001330 ASSERT_EQUAL_64(0, x7);
1331 ASSERT_EQUAL_64(0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001332 ASSERT_EQUAL_64(0x1c71c71c71c71c71, x9);
1333 ASSERT_EQUAL_64(0xe38e38e38e38e38e, x10);
1334 ASSERT_EQUAL_64(0x1c71c71c71c71c72, x11);
armvixlad96eda2013-06-14 11:42:37 +01001335
1336 TEARDOWN();
1337}
1338
1339
armvixl6e2c8272015-03-31 11:04:14 +01001340TEST(umulh) {
1341 SETUP();
1342
1343 START();
1344 __ Mov(x20, 0);
1345 __ Mov(x21, 1);
1346 __ Mov(x22, 0x0000000100000000);
1347 __ Mov(x23, 0x0000000012345678);
1348 __ Mov(x24, 0x0123456789abcdef);
1349 __ Mov(x25, 0x0000000200000000);
1350 __ Mov(x26, 0x8000000000000000);
1351 __ Mov(x27, 0xffffffffffffffff);
1352 __ Mov(x28, 0x5555555555555555);
1353 __ Mov(x29, 0xaaaaaaaaaaaaaaaa);
1354
1355 __ Umulh(x0, x20, x24);
1356 __ Umulh(x1, x21, x24);
1357 __ Umulh(x2, x22, x23);
1358 __ Umulh(x3, x22, x24);
1359 __ Umulh(x4, x24, x25);
1360 __ Umulh(x5, x23, x27);
1361 __ Umulh(x6, x26, x26);
1362 __ Umulh(x7, x26, x27);
1363 __ Umulh(x8, x27, x27);
1364 __ Umulh(x9, x28, x28);
1365 __ Umulh(x10, x28, x29);
1366 __ Umulh(x11, x29, x29);
1367 END();
1368
1369 RUN();
1370
1371 ASSERT_EQUAL_64(0, x0);
1372 ASSERT_EQUAL_64(0, x1);
1373 ASSERT_EQUAL_64(0, x2);
1374 ASSERT_EQUAL_64(0x0000000001234567, x3);
1375 ASSERT_EQUAL_64(0x0000000002468acf, x4);
1376 ASSERT_EQUAL_64(0x0000000012345677, x5);
1377 ASSERT_EQUAL_64(0x4000000000000000, x6);
1378 ASSERT_EQUAL_64(0x7fffffffffffffff, x7);
1379 ASSERT_EQUAL_64(0xfffffffffffffffe, x8);
1380 ASSERT_EQUAL_64(0x1c71c71c71c71c71, x9);
1381 ASSERT_EQUAL_64(0x38e38e38e38e38e3, x10);
1382 ASSERT_EQUAL_64(0x71c71c71c71c71c6, x11);
1383
1384 TEARDOWN();
1385}
1386
1387
armvixl5289c592015-03-02 13:52:04 +00001388TEST(smaddl_umaddl_umull) {
armvixlad96eda2013-06-14 11:42:37 +01001389 SETUP();
1390
1391 START();
1392 __ Mov(x17, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00001393 __ Mov(x18, 0x00000000ffffffff);
1394 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001395 __ Mov(x20, 4);
armvixlb0c8ae22014-03-21 14:03:59 +00001396 __ Mov(x21, 0x0000000200000000);
armvixlad96eda2013-06-14 11:42:37 +01001397
1398 __ Smaddl(x9, w17, w18, x20);
1399 __ Smaddl(x10, w18, w18, x20);
1400 __ Smaddl(x11, w19, w19, x20);
1401 __ Smaddl(x12, w19, w19, x21);
1402 __ Umaddl(x13, w17, w18, x20);
1403 __ Umaddl(x14, w18, w18, x20);
1404 __ Umaddl(x15, w19, w19, x20);
1405 __ Umaddl(x22, w19, w19, x21);
armvixl5289c592015-03-02 13:52:04 +00001406 __ Umull(x24, w19, w19);
1407 __ Umull(x25, w17, w18);
armvixlad96eda2013-06-14 11:42:37 +01001408 END();
1409
1410 RUN();
1411
1412 ASSERT_EQUAL_64(3, x9);
1413 ASSERT_EQUAL_64(5, x10);
1414 ASSERT_EQUAL_64(5, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00001415 ASSERT_EQUAL_64(0x0000000200000001, x12);
1416 ASSERT_EQUAL_64(0x0000000100000003, x13);
1417 ASSERT_EQUAL_64(0xfffffffe00000005, x14);
1418 ASSERT_EQUAL_64(0xfffffffe00000005, x15);
1419 ASSERT_EQUAL_64(1, x22);
armvixl5289c592015-03-02 13:52:04 +00001420 ASSERT_EQUAL_64(0xfffffffe00000001, x24);
1421 ASSERT_EQUAL_64(0x00000000ffffffff, x25);
armvixlad96eda2013-06-14 11:42:37 +01001422
1423 TEARDOWN();
1424}
1425
1426
1427TEST(smsubl_umsubl) {
1428 SETUP();
1429
1430 START();
1431 __ Mov(x17, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00001432 __ Mov(x18, 0x00000000ffffffff);
1433 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001434 __ Mov(x20, 4);
armvixlb0c8ae22014-03-21 14:03:59 +00001435 __ Mov(x21, 0x0000000200000000);
armvixlad96eda2013-06-14 11:42:37 +01001436
1437 __ Smsubl(x9, w17, w18, x20);
1438 __ Smsubl(x10, w18, w18, x20);
1439 __ Smsubl(x11, w19, w19, x20);
1440 __ Smsubl(x12, w19, w19, x21);
1441 __ Umsubl(x13, w17, w18, x20);
1442 __ Umsubl(x14, w18, w18, x20);
1443 __ Umsubl(x15, w19, w19, x20);
1444 __ Umsubl(x22, w19, w19, x21);
1445 END();
1446
1447 RUN();
1448
1449 ASSERT_EQUAL_64(5, x9);
1450 ASSERT_EQUAL_64(3, x10);
1451 ASSERT_EQUAL_64(3, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00001452 ASSERT_EQUAL_64(0x00000001ffffffff, x12);
1453 ASSERT_EQUAL_64(0xffffffff00000005, x13);
1454 ASSERT_EQUAL_64(0x0000000200000003, x14);
1455 ASSERT_EQUAL_64(0x0000000200000003, x15);
1456 ASSERT_EQUAL_64(0x00000003ffffffff, x22);
armvixlad96eda2013-06-14 11:42:37 +01001457
1458 TEARDOWN();
1459}
1460
1461
1462TEST(div) {
1463 SETUP();
1464
1465 START();
1466 __ Mov(x16, 1);
1467 __ Mov(x17, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001468 __ Mov(x18, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001469 __ Mov(x19, 0x80000000);
armvixlb0c8ae22014-03-21 14:03:59 +00001470 __ Mov(x20, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01001471 __ Mov(x21, 2);
1472
1473 __ Udiv(w0, w16, w16);
1474 __ Udiv(w1, w17, w16);
1475 __ Sdiv(w2, w16, w16);
1476 __ Sdiv(w3, w16, w17);
1477 __ Sdiv(w4, w17, w18);
1478
1479 __ Udiv(x5, x16, x16);
1480 __ Udiv(x6, x17, x18);
1481 __ Sdiv(x7, x16, x16);
1482 __ Sdiv(x8, x16, x17);
1483 __ Sdiv(x9, x17, x18);
1484
1485 __ Udiv(w10, w19, w21);
1486 __ Sdiv(w11, w19, w21);
1487 __ Udiv(x12, x19, x21);
1488 __ Sdiv(x13, x19, x21);
1489 __ Udiv(x14, x20, x21);
1490 __ Sdiv(x15, x20, x21);
armvixlf37fdc02014-02-05 13:22:16 +00001491
1492 __ Udiv(w22, w19, w17);
1493 __ Sdiv(w23, w19, w17);
1494 __ Udiv(x24, x20, x18);
1495 __ Sdiv(x25, x20, x18);
1496
1497 __ Udiv(x26, x16, x21);
1498 __ Sdiv(x27, x16, x21);
1499 __ Udiv(x28, x18, x21);
1500 __ Sdiv(x29, x18, x21);
1501
1502 __ Mov(x17, 0);
1503 __ Udiv(w18, w16, w17);
1504 __ Sdiv(w19, w16, w17);
1505 __ Udiv(x20, x16, x17);
1506 __ Sdiv(x21, x16, x17);
armvixlad96eda2013-06-14 11:42:37 +01001507 END();
1508
1509 RUN();
1510
1511 ASSERT_EQUAL_64(1, x0);
1512 ASSERT_EQUAL_64(0xffffffff, x1);
1513 ASSERT_EQUAL_64(1, x2);
1514 ASSERT_EQUAL_64(0xffffffff, x3);
1515 ASSERT_EQUAL_64(1, x4);
1516 ASSERT_EQUAL_64(1, x5);
1517 ASSERT_EQUAL_64(0, x6);
1518 ASSERT_EQUAL_64(1, x7);
1519 ASSERT_EQUAL_64(0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001520 ASSERT_EQUAL_64(0xffffffff00000001, x9);
armvixlad96eda2013-06-14 11:42:37 +01001521 ASSERT_EQUAL_64(0x40000000, x10);
armvixl5289c592015-03-02 13:52:04 +00001522 ASSERT_EQUAL_64(0xc0000000, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00001523 ASSERT_EQUAL_64(0x0000000040000000, x12);
1524 ASSERT_EQUAL_64(0x0000000040000000, x13);
1525 ASSERT_EQUAL_64(0x4000000000000000, x14);
armvixl5289c592015-03-02 13:52:04 +00001526 ASSERT_EQUAL_64(0xc000000000000000, x15);
armvixlf37fdc02014-02-05 13:22:16 +00001527 ASSERT_EQUAL_64(0, x22);
1528 ASSERT_EQUAL_64(0x80000000, x23);
1529 ASSERT_EQUAL_64(0, x24);
armvixlb0c8ae22014-03-21 14:03:59 +00001530 ASSERT_EQUAL_64(0x8000000000000000, x25);
armvixlf37fdc02014-02-05 13:22:16 +00001531 ASSERT_EQUAL_64(0, x26);
1532 ASSERT_EQUAL_64(0, x27);
armvixlb0c8ae22014-03-21 14:03:59 +00001533 ASSERT_EQUAL_64(0x7fffffffffffffff, x28);
armvixlf37fdc02014-02-05 13:22:16 +00001534 ASSERT_EQUAL_64(0, x29);
1535 ASSERT_EQUAL_64(0, x18);
1536 ASSERT_EQUAL_64(0, x19);
1537 ASSERT_EQUAL_64(0, x20);
1538 ASSERT_EQUAL_64(0, x21);
armvixlad96eda2013-06-14 11:42:37 +01001539
1540 TEARDOWN();
1541}
1542
1543
1544TEST(rbit_rev) {
1545 SETUP();
1546
1547 START();
armvixlb0c8ae22014-03-21 14:03:59 +00001548 __ Mov(x24, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01001549 __ Rbit(w0, w24);
1550 __ Rbit(x1, x24);
1551 __ Rev16(w2, w24);
1552 __ Rev16(x3, x24);
1553 __ Rev(w4, w24);
1554 __ Rev32(x5, x24);
1555 __ Rev(x6, x24);
1556 END();
1557
1558 RUN();
1559
1560 ASSERT_EQUAL_64(0x084c2a6e, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00001561 ASSERT_EQUAL_64(0x084c2a6e195d3b7f, x1);
armvixlad96eda2013-06-14 11:42:37 +01001562 ASSERT_EQUAL_64(0x54761032, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00001563 ASSERT_EQUAL_64(0xdcfe98ba54761032, x3);
armvixlad96eda2013-06-14 11:42:37 +01001564 ASSERT_EQUAL_64(0x10325476, x4);
armvixlb0c8ae22014-03-21 14:03:59 +00001565 ASSERT_EQUAL_64(0x98badcfe10325476, x5);
1566 ASSERT_EQUAL_64(0x1032547698badcfe, x6);
armvixlad96eda2013-06-14 11:42:37 +01001567
1568 TEARDOWN();
1569}
1570
1571
1572TEST(clz_cls) {
1573 SETUP();
1574
1575 START();
armvixlb0c8ae22014-03-21 14:03:59 +00001576 __ Mov(x24, 0x0008000000800000);
1577 __ Mov(x25, 0xff800000fff80000);
armvixlad96eda2013-06-14 11:42:37 +01001578 __ Mov(x26, 0);
1579 __ Clz(w0, w24);
1580 __ Clz(x1, x24);
1581 __ Clz(w2, w25);
1582 __ Clz(x3, x25);
1583 __ Clz(w4, w26);
1584 __ Clz(x5, x26);
1585 __ Cls(w6, w24);
1586 __ Cls(x7, x24);
1587 __ Cls(w8, w25);
1588 __ Cls(x9, x25);
1589 __ Cls(w10, w26);
1590 __ Cls(x11, x26);
1591 END();
1592
1593 RUN();
1594
1595 ASSERT_EQUAL_64(8, x0);
1596 ASSERT_EQUAL_64(12, x1);
1597 ASSERT_EQUAL_64(0, x2);
1598 ASSERT_EQUAL_64(0, x3);
1599 ASSERT_EQUAL_64(32, x4);
1600 ASSERT_EQUAL_64(64, x5);
1601 ASSERT_EQUAL_64(7, x6);
1602 ASSERT_EQUAL_64(11, x7);
1603 ASSERT_EQUAL_64(12, x8);
1604 ASSERT_EQUAL_64(8, x9);
1605 ASSERT_EQUAL_64(31, x10);
1606 ASSERT_EQUAL_64(63, x11);
1607
1608 TEARDOWN();
1609}
1610
1611
1612TEST(label) {
1613 SETUP();
1614
1615 Label label_1, label_2, label_3, label_4;
1616
1617 START();
1618 __ Mov(x0, 0x1);
1619 __ Mov(x1, 0x0);
1620 __ Mov(x22, lr); // Save lr.
1621
1622 __ B(&label_1);
1623 __ B(&label_1);
1624 __ B(&label_1); // Multiple branches to the same label.
1625 __ Mov(x0, 0x0);
1626 __ Bind(&label_2);
1627 __ B(&label_3); // Forward branch.
1628 __ Mov(x0, 0x0);
1629 __ Bind(&label_1);
1630 __ B(&label_2); // Backward branch.
1631 __ Mov(x0, 0x0);
1632 __ Bind(&label_3);
1633 __ Bl(&label_4);
1634 END();
1635
1636 __ Bind(&label_4);
1637 __ Mov(x1, 0x1);
1638 __ Mov(lr, x22);
1639 END();
1640
1641 RUN();
1642
1643 ASSERT_EQUAL_64(0x1, x0);
1644 ASSERT_EQUAL_64(0x1, x1);
1645
1646 TEARDOWN();
1647}
1648
1649
armvixlc68cb642014-09-25 18:49:30 +01001650TEST(label_2) {
1651 SETUP();
1652
1653 Label label_1, label_2, label_3;
1654 Label first_jump_to_3;
1655
1656 START();
1657 __ Mov(x0, 0x0);
1658
1659 __ B(&label_1);
1660 ptrdiff_t offset_2 = masm.CursorOffset();
1661 __ Orr(x0, x0, 1 << 1);
1662 __ B(&label_3);
1663 ptrdiff_t offset_1 = masm.CursorOffset();
1664 __ Orr(x0, x0, 1 << 0);
1665 __ B(&label_2);
1666 ptrdiff_t offset_3 = masm.CursorOffset();
1667 __ Tbz(x0, 2, &first_jump_to_3);
1668 __ Orr(x0, x0, 1 << 3);
1669 __ Bind(&first_jump_to_3);
1670 __ Orr(x0, x0, 1 << 2);
1671 __ Tbz(x0, 3, &label_3);
1672
1673 // Labels 1, 2, and 3 are bound before the current buffer offset. Branches to
1674 // label_1 and label_2 branch respectively forward and backward. Branches to
1675 // label 3 include both forward and backward branches.
1676 masm.BindToOffset(&label_1, offset_1);
1677 masm.BindToOffset(&label_2, offset_2);
1678 masm.BindToOffset(&label_3, offset_3);
1679
1680 END();
1681
1682 RUN();
1683
1684 ASSERT_EQUAL_64(0xf, x0);
1685
1686 TEARDOWN();
1687}
1688
1689
armvixlad96eda2013-06-14 11:42:37 +01001690TEST(adr) {
1691 SETUP();
1692
1693 Label label_1, label_2, label_3, label_4;
1694
1695 START();
1696 __ Mov(x0, 0x0); // Set to non-zero to indicate failure.
1697 __ Adr(x1, &label_3); // Set to zero to indicate success.
1698
1699 __ Adr(x2, &label_1); // Multiple forward references to the same label.
1700 __ Adr(x3, &label_1);
1701 __ Adr(x4, &label_1);
1702
1703 __ Bind(&label_2);
1704 __ Eor(x5, x2, Operand(x3)); // Ensure that x2,x3 and x4 are identical.
1705 __ Eor(x6, x2, Operand(x4));
1706 __ Orr(x0, x0, Operand(x5));
1707 __ Orr(x0, x0, Operand(x6));
1708 __ Br(x2); // label_1, label_3
1709
1710 __ Bind(&label_3);
1711 __ Adr(x2, &label_3); // Self-reference (offset 0).
1712 __ Eor(x1, x1, Operand(x2));
1713 __ Adr(x2, &label_4); // Simple forward reference.
1714 __ Br(x2); // label_4
1715
1716 __ Bind(&label_1);
1717 __ Adr(x2, &label_3); // Multiple reverse references to the same label.
1718 __ Adr(x3, &label_3);
1719 __ Adr(x4, &label_3);
1720 __ Adr(x5, &label_2); // Simple reverse reference.
1721 __ Br(x5); // label_2
1722
1723 __ Bind(&label_4);
1724 END();
1725
1726 RUN();
1727
1728 ASSERT_EQUAL_64(0x0, x0);
1729 ASSERT_EQUAL_64(0x0, x1);
1730
1731 TEARDOWN();
1732}
1733
1734
armvixl4a102ba2014-07-14 09:02:40 +01001735// Simple adrp tests: check that labels are linked and handled properly.
1736// This is similar to the adr test, but all the adrp instructions are put on the
1737// same page so that they return the same value.
1738TEST(adrp) {
1739 Label start;
1740 Label label_1, label_2, label_3;
1741
1742 SETUP_CUSTOM(2 * kPageSize, PageOffsetDependentCode);
1743 START();
1744
1745 // Waste space until the start of a page.
armvixlc68cb642014-09-25 18:49:30 +01001746 {
1747 InstructionAccurateScope scope(&masm,
1748 kPageSize / kInstructionSize,
1749 InstructionAccurateScope::kMaximumSize);
armvixl4a102ba2014-07-14 09:02:40 +01001750 const uintptr_t kPageOffsetMask = kPageSize - 1;
armvixlc68cb642014-09-25 18:49:30 +01001751 while ((masm.GetCursorAddress<uintptr_t>() & kPageOffsetMask) != 0) {
armvixl4a102ba2014-07-14 09:02:40 +01001752 __ b(&start);
1753 }
1754 __ bind(&start);
1755 }
1756
1757 // Simple forward reference.
1758 __ Adrp(x0, &label_2);
1759
1760 __ Bind(&label_1);
1761
1762 // Multiple forward references to the same label.
1763 __ Adrp(x1, &label_3);
1764 __ Adrp(x2, &label_3);
1765 __ Adrp(x3, &label_3);
1766
1767 __ Bind(&label_2);
1768
1769 // Self-reference (offset 0).
1770 __ Adrp(x4, &label_2);
1771
1772 __ Bind(&label_3);
1773
1774 // Simple reverse reference.
1775 __ Adrp(x5, &label_1);
1776
1777 // Multiple reverse references to the same label.
1778 __ Adrp(x6, &label_2);
1779 __ Adrp(x7, &label_2);
1780 __ Adrp(x8, &label_2);
1781
1782 VIXL_ASSERT(masm.SizeOfCodeGeneratedSince(&start) < kPageSize);
1783 END();
1784 RUN();
1785
1786 uint64_t expected = reinterpret_cast<uint64_t>(
1787 AlignDown(masm.GetLabelAddress<uint64_t*>(&start), kPageSize));
1788 ASSERT_EQUAL_64(expected, x0);
1789 ASSERT_EQUAL_64(expected, x1);
1790 ASSERT_EQUAL_64(expected, x2);
1791 ASSERT_EQUAL_64(expected, x3);
1792 ASSERT_EQUAL_64(expected, x4);
1793 ASSERT_EQUAL_64(expected, x5);
1794 ASSERT_EQUAL_64(expected, x6);
1795 ASSERT_EQUAL_64(expected, x7);
1796 ASSERT_EQUAL_64(expected, x8);
1797
armvixlc68cb642014-09-25 18:49:30 +01001798 TEARDOWN_CUSTOM();
armvixl4a102ba2014-07-14 09:02:40 +01001799}
1800
1801
1802static void AdrpPageBoundaryHelper(unsigned offset_into_page) {
1803 VIXL_ASSERT(offset_into_page < kPageSize);
1804 VIXL_ASSERT((offset_into_page % kInstructionSize) == 0);
1805
1806 const uintptr_t kPageOffsetMask = kPageSize - 1;
1807
1808 // The test label is always bound on page 0. Adrp instructions are generated
1809 // on pages from kStartPage to kEndPage (inclusive).
1810 const int kStartPage = -16;
1811 const int kEndPage = 16;
armvixlc68cb642014-09-25 18:49:30 +01001812 const int kMaxCodeSize = (kEndPage - kStartPage + 2) * kPageSize;
armvixl4a102ba2014-07-14 09:02:40 +01001813
armvixlc68cb642014-09-25 18:49:30 +01001814 SETUP_CUSTOM(kMaxCodeSize, PageOffsetDependentCode);
armvixl4a102ba2014-07-14 09:02:40 +01001815 START();
1816
armvixl4a102ba2014-07-14 09:02:40 +01001817 Label test;
armvixlc68cb642014-09-25 18:49:30 +01001818 Label start;
armvixl4a102ba2014-07-14 09:02:40 +01001819
armvixlc68cb642014-09-25 18:49:30 +01001820 {
1821 InstructionAccurateScope scope(&masm,
1822 kMaxCodeSize / kInstructionSize,
1823 InstructionAccurateScope::kMaximumSize);
1824 // Initialize NZCV with `eq` flags.
1825 __ cmp(wzr, wzr);
armvixl4a102ba2014-07-14 09:02:40 +01001826 // Waste space until the start of a page.
armvixlc68cb642014-09-25 18:49:30 +01001827 while ((masm.GetCursorAddress<uintptr_t>() & kPageOffsetMask) != 0) {
armvixl4a102ba2014-07-14 09:02:40 +01001828 __ b(&start);
1829 }
1830
1831 // The first page.
1832 VIXL_STATIC_ASSERT(kStartPage < 0);
armvixlc68cb642014-09-25 18:49:30 +01001833 {
1834 InstructionAccurateScope scope_page(&masm, kPageSize / kInstructionSize);
armvixl4a102ba2014-07-14 09:02:40 +01001835 __ bind(&start);
1836 __ adrp(x0, &test);
1837 __ adrp(x1, &test);
1838 for (size_t i = 2; i < (kPageSize / kInstructionSize); i += 2) {
1839 __ ccmp(x0, x1, NoFlag, eq);
1840 __ adrp(x1, &test);
1841 }
1842 }
1843
1844 // Subsequent pages.
1845 VIXL_STATIC_ASSERT(kEndPage >= 0);
1846 for (int page = (kStartPage + 1); page <= kEndPage; page++) {
1847 InstructionAccurateScope scope_page(&masm, kPageSize / kInstructionSize);
1848 if (page == 0) {
1849 for (size_t i = 0; i < (kPageSize / kInstructionSize);) {
1850 if (i++ == (offset_into_page / kInstructionSize)) __ bind(&test);
1851 __ ccmp(x0, x1, NoFlag, eq);
1852 if (i++ == (offset_into_page / kInstructionSize)) __ bind(&test);
1853 __ adrp(x1, &test);
1854 }
1855 } else {
1856 for (size_t i = 0; i < (kPageSize / kInstructionSize); i += 2) {
1857 __ ccmp(x0, x1, NoFlag, eq);
1858 __ adrp(x1, &test);
1859 }
1860 }
1861 }
armvixl4a102ba2014-07-14 09:02:40 +01001862 }
1863
armvixlc68cb642014-09-25 18:49:30 +01001864 // Every adrp instruction pointed to the same label (`test`), so they should
1865 // all have produced the same result.
1866
armvixl4a102ba2014-07-14 09:02:40 +01001867 END();
1868 RUN();
1869
1870 uintptr_t expected =
1871 AlignDown(masm.GetLabelAddress<uintptr_t>(&test), kPageSize);
1872 ASSERT_EQUAL_64(expected, x0);
1873 ASSERT_EQUAL_64(expected, x1);
1874 ASSERT_EQUAL_NZCV(ZCFlag);
1875
armvixlc68cb642014-09-25 18:49:30 +01001876 TEARDOWN_CUSTOM();
armvixl4a102ba2014-07-14 09:02:40 +01001877}
1878
1879
1880// Test that labels are correctly referenced by adrp across page boundaries.
1881TEST(adrp_page_boundaries) {
1882 VIXL_STATIC_ASSERT(kPageSize == 4096);
1883 AdrpPageBoundaryHelper(kInstructionSize * 0);
1884 AdrpPageBoundaryHelper(kInstructionSize * 1);
1885 AdrpPageBoundaryHelper(kInstructionSize * 512);
1886 AdrpPageBoundaryHelper(kInstructionSize * 1022);
1887 AdrpPageBoundaryHelper(kInstructionSize * 1023);
1888}
1889
1890
armvixldb644342015-07-21 11:37:10 +01001891static void AdrpOffsetHelper(int64_t offset) {
armvixl4a102ba2014-07-14 09:02:40 +01001892 const size_t kPageOffsetMask = kPageSize - 1;
armvixlc68cb642014-09-25 18:49:30 +01001893 const int kMaxCodeSize = 2 * kPageSize;
armvixl4a102ba2014-07-14 09:02:40 +01001894
armvixlc68cb642014-09-25 18:49:30 +01001895 SETUP_CUSTOM(kMaxCodeSize, PageOffsetDependentCode);
armvixl4a102ba2014-07-14 09:02:40 +01001896 START();
1897
armvixl4a102ba2014-07-14 09:02:40 +01001898 Label page;
armvixlc68cb642014-09-25 18:49:30 +01001899
1900 {
1901 InstructionAccurateScope scope(&masm,
1902 kMaxCodeSize / kInstructionSize,
1903 InstructionAccurateScope::kMaximumSize);
1904 // Initialize NZCV with `eq` flags.
1905 __ cmp(wzr, wzr);
armvixl4a102ba2014-07-14 09:02:40 +01001906 // Waste space until the start of a page.
armvixlc68cb642014-09-25 18:49:30 +01001907 while ((masm.GetCursorAddress<uintptr_t>() & kPageOffsetMask) != 0) {
armvixl4a102ba2014-07-14 09:02:40 +01001908 __ b(&page);
1909 }
1910 __ bind(&page);
1911
armvixlc68cb642014-09-25 18:49:30 +01001912 {
armvixldb644342015-07-21 11:37:10 +01001913 int imm21 = static_cast<int>(offset);
armvixlc68cb642014-09-25 18:49:30 +01001914 InstructionAccurateScope scope_page(&masm, kPageSize / kInstructionSize);
armvixl4a102ba2014-07-14 09:02:40 +01001915 // Every adrp instruction on this page should return the same value.
1916 __ adrp(x0, imm21);
1917 __ adrp(x1, imm21);
1918 for (size_t i = 2; i < kPageSize / kInstructionSize; i += 2) {
1919 __ ccmp(x0, x1, NoFlag, eq);
1920 __ adrp(x1, imm21);
1921 }
1922 }
1923 }
1924
1925 END();
1926 RUN();
1927
1928 uintptr_t expected =
armvixldb644342015-07-21 11:37:10 +01001929 masm.GetLabelAddress<uintptr_t>(&page) + (kPageSize * offset);
armvixl4a102ba2014-07-14 09:02:40 +01001930 ASSERT_EQUAL_64(expected, x0);
1931 ASSERT_EQUAL_64(expected, x1);
1932 ASSERT_EQUAL_NZCV(ZCFlag);
1933
armvixlc68cb642014-09-25 18:49:30 +01001934 TEARDOWN_CUSTOM();
armvixl4a102ba2014-07-14 09:02:40 +01001935}
1936
1937
1938// Check that adrp produces the correct result for a specific offset.
1939TEST(adrp_offset) {
1940 AdrpOffsetHelper(0);
1941 AdrpOffsetHelper(1);
1942 AdrpOffsetHelper(-1);
1943 AdrpOffsetHelper(4);
1944 AdrpOffsetHelper(-4);
1945 AdrpOffsetHelper(0x000fffff);
1946 AdrpOffsetHelper(-0x000fffff);
1947 AdrpOffsetHelper(-0x00100000);
1948}
1949
1950
armvixlad96eda2013-06-14 11:42:37 +01001951TEST(branch_cond) {
1952 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01001953 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01001954
armvixl5289c592015-03-02 13:52:04 +00001955 Label done, wrong;
armvixlad96eda2013-06-14 11:42:37 +01001956
1957 START();
1958 __ Mov(x0, 0x1);
1959 __ Mov(x1, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00001960 __ Mov(x2, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01001961
1962 // For each 'cmp' instruction below, condition codes other than the ones
1963 // following it would branch.
1964
armvixl578645f2013-08-15 17:21:42 +01001965 __ Cmp(x1, 0);
armvixlad96eda2013-06-14 11:42:37 +01001966 __ B(&wrong, eq);
1967 __ B(&wrong, lo);
1968 __ B(&wrong, mi);
1969 __ B(&wrong, vs);
1970 __ B(&wrong, ls);
1971 __ B(&wrong, lt);
1972 __ B(&wrong, le);
1973 Label ok_1;
1974 __ B(&ok_1, ne);
1975 __ Mov(x0, 0x0);
1976 __ Bind(&ok_1);
1977
armvixl578645f2013-08-15 17:21:42 +01001978 __ Cmp(x1, 1);
armvixlad96eda2013-06-14 11:42:37 +01001979 __ B(&wrong, ne);
1980 __ B(&wrong, lo);
1981 __ B(&wrong, mi);
1982 __ B(&wrong, vs);
1983 __ B(&wrong, hi);
1984 __ B(&wrong, lt);
1985 __ B(&wrong, gt);
1986 Label ok_2;
1987 __ B(&ok_2, pl);
1988 __ Mov(x0, 0x0);
1989 __ Bind(&ok_2);
1990
armvixl578645f2013-08-15 17:21:42 +01001991 __ Cmp(x1, 2);
armvixlad96eda2013-06-14 11:42:37 +01001992 __ B(&wrong, eq);
1993 __ B(&wrong, hs);
1994 __ B(&wrong, pl);
1995 __ B(&wrong, vs);
1996 __ B(&wrong, hi);
1997 __ B(&wrong, ge);
1998 __ B(&wrong, gt);
1999 Label ok_3;
2000 __ B(&ok_3, vc);
2001 __ Mov(x0, 0x0);
2002 __ Bind(&ok_3);
2003
armvixl578645f2013-08-15 17:21:42 +01002004 __ Cmp(x2, 1);
armvixlad96eda2013-06-14 11:42:37 +01002005 __ B(&wrong, eq);
2006 __ B(&wrong, lo);
2007 __ B(&wrong, mi);
2008 __ B(&wrong, vc);
2009 __ B(&wrong, ls);
2010 __ B(&wrong, ge);
2011 __ B(&wrong, gt);
2012 Label ok_4;
2013 __ B(&ok_4, le);
2014 __ Mov(x0, 0x0);
2015 __ Bind(&ok_4);
armvixl578645f2013-08-15 17:21:42 +01002016
armvixlc68cb642014-09-25 18:49:30 +01002017 // The MacroAssembler does not allow al as a branch condition.
armvixl578645f2013-08-15 17:21:42 +01002018 Label ok_5;
2019 __ b(&ok_5, al);
2020 __ Mov(x0, 0x0);
2021 __ Bind(&ok_5);
2022
armvixlc68cb642014-09-25 18:49:30 +01002023 // The MacroAssembler does not allow nv as a branch condition.
armvixl578645f2013-08-15 17:21:42 +01002024 Label ok_6;
2025 __ b(&ok_6, nv);
2026 __ Mov(x0, 0x0);
2027 __ Bind(&ok_6);
2028
armvixl5289c592015-03-02 13:52:04 +00002029 __ B(&done);
armvixlad96eda2013-06-14 11:42:37 +01002030
2031 __ Bind(&wrong);
2032 __ Mov(x0, 0x0);
armvixl5289c592015-03-02 13:52:04 +00002033
2034 __ Bind(&done);
armvixlad96eda2013-06-14 11:42:37 +01002035 END();
2036
2037 RUN();
2038
2039 ASSERT_EQUAL_64(0x1, x0);
2040
2041 TEARDOWN();
2042}
2043
2044
2045TEST(branch_to_reg) {
2046 SETUP();
2047
2048 // Test br.
2049 Label fn1, after_fn1;
2050
2051 START();
2052 __ Mov(x29, lr);
2053
2054 __ Mov(x1, 0);
2055 __ B(&after_fn1);
2056
2057 __ Bind(&fn1);
2058 __ Mov(x0, lr);
2059 __ Mov(x1, 42);
2060 __ Br(x0);
2061
2062 __ Bind(&after_fn1);
2063 __ Bl(&fn1);
2064
2065 // Test blr.
2066 Label fn2, after_fn2;
2067
2068 __ Mov(x2, 0);
2069 __ B(&after_fn2);
2070
2071 __ Bind(&fn2);
2072 __ Mov(x0, lr);
2073 __ Mov(x2, 84);
2074 __ Blr(x0);
2075
2076 __ Bind(&after_fn2);
2077 __ Bl(&fn2);
2078 __ Mov(x3, lr);
2079
2080 __ Mov(lr, x29);
2081 END();
2082
2083 RUN();
2084
2085 ASSERT_EQUAL_64(core.xreg(3) + kInstructionSize, x0);
2086 ASSERT_EQUAL_64(42, x1);
2087 ASSERT_EQUAL_64(84, x2);
2088
2089 TEARDOWN();
2090}
2091
2092
2093TEST(compare_branch) {
2094 SETUP();
2095
2096 START();
2097 __ Mov(x0, 0);
2098 __ Mov(x1, 0);
2099 __ Mov(x2, 0);
2100 __ Mov(x3, 0);
2101 __ Mov(x4, 0);
2102 __ Mov(x5, 0);
2103 __ Mov(x16, 0);
2104 __ Mov(x17, 42);
2105
2106 Label zt, zt_end;
2107 __ Cbz(w16, &zt);
2108 __ B(&zt_end);
2109 __ Bind(&zt);
2110 __ Mov(x0, 1);
2111 __ Bind(&zt_end);
2112
2113 Label zf, zf_end;
2114 __ Cbz(x17, &zf);
2115 __ B(&zf_end);
2116 __ Bind(&zf);
2117 __ Mov(x1, 1);
2118 __ Bind(&zf_end);
2119
2120 Label nzt, nzt_end;
2121 __ Cbnz(w17, &nzt);
2122 __ B(&nzt_end);
2123 __ Bind(&nzt);
2124 __ Mov(x2, 1);
2125 __ Bind(&nzt_end);
2126
2127 Label nzf, nzf_end;
2128 __ Cbnz(x16, &nzf);
2129 __ B(&nzf_end);
2130 __ Bind(&nzf);
2131 __ Mov(x3, 1);
2132 __ Bind(&nzf_end);
2133
armvixlb0c8ae22014-03-21 14:03:59 +00002134 __ Mov(x18, 0xffffffff00000000);
armvixlad96eda2013-06-14 11:42:37 +01002135
2136 Label a, a_end;
2137 __ Cbz(w18, &a);
2138 __ B(&a_end);
2139 __ Bind(&a);
2140 __ Mov(x4, 1);
2141 __ Bind(&a_end);
2142
2143 Label b, b_end;
2144 __ Cbnz(w18, &b);
2145 __ B(&b_end);
2146 __ Bind(&b);
2147 __ Mov(x5, 1);
2148 __ Bind(&b_end);
2149
2150 END();
2151
2152 RUN();
2153
2154 ASSERT_EQUAL_64(1, x0);
2155 ASSERT_EQUAL_64(0, x1);
2156 ASSERT_EQUAL_64(1, x2);
2157 ASSERT_EQUAL_64(0, x3);
2158 ASSERT_EQUAL_64(1, x4);
2159 ASSERT_EQUAL_64(0, x5);
2160
2161 TEARDOWN();
2162}
2163
2164
2165TEST(test_branch) {
2166 SETUP();
2167
2168 START();
2169 __ Mov(x0, 0);
2170 __ Mov(x1, 0);
2171 __ Mov(x2, 0);
2172 __ Mov(x3, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00002173 __ Mov(x16, 0xaaaaaaaaaaaaaaaa);
armvixlad96eda2013-06-14 11:42:37 +01002174
2175 Label bz, bz_end;
armvixlf37fdc02014-02-05 13:22:16 +00002176 __ Tbz(w16, 0, &bz);
armvixlad96eda2013-06-14 11:42:37 +01002177 __ B(&bz_end);
2178 __ Bind(&bz);
2179 __ Mov(x0, 1);
2180 __ Bind(&bz_end);
2181
2182 Label bo, bo_end;
2183 __ Tbz(x16, 63, &bo);
2184 __ B(&bo_end);
2185 __ Bind(&bo);
2186 __ Mov(x1, 1);
2187 __ Bind(&bo_end);
2188
2189 Label nbz, nbz_end;
2190 __ Tbnz(x16, 61, &nbz);
2191 __ B(&nbz_end);
2192 __ Bind(&nbz);
2193 __ Mov(x2, 1);
2194 __ Bind(&nbz_end);
2195
2196 Label nbo, nbo_end;
armvixlf37fdc02014-02-05 13:22:16 +00002197 __ Tbnz(w16, 2, &nbo);
armvixlad96eda2013-06-14 11:42:37 +01002198 __ B(&nbo_end);
2199 __ Bind(&nbo);
2200 __ Mov(x3, 1);
2201 __ Bind(&nbo_end);
2202 END();
2203
2204 RUN();
2205
2206 ASSERT_EQUAL_64(1, x0);
2207 ASSERT_EQUAL_64(0, x1);
2208 ASSERT_EQUAL_64(1, x2);
2209 ASSERT_EQUAL_64(0, x3);
2210
2211 TEARDOWN();
2212}
2213
2214
armvixlb0c8ae22014-03-21 14:03:59 +00002215TEST(branch_type) {
2216 SETUP();
2217
2218 Label fail, done;
2219
2220 START();
2221 __ Mov(x0, 0x0);
2222 __ Mov(x10, 0x7);
2223 __ Mov(x11, 0x0);
2224
2225 // Test non taken branches.
2226 __ Cmp(x10, 0x7);
2227 __ B(&fail, ne);
2228 __ B(&fail, never);
2229 __ B(&fail, reg_zero, x10);
2230 __ B(&fail, reg_not_zero, x11);
2231 __ B(&fail, reg_bit_clear, x10, 0);
2232 __ B(&fail, reg_bit_set, x10, 3);
2233
2234 // Test taken branches.
2235 Label l1, l2, l3, l4, l5;
2236 __ Cmp(x10, 0x7);
2237 __ B(&l1, eq);
2238 __ B(&fail);
2239 __ Bind(&l1);
2240 __ B(&l2, always);
2241 __ B(&fail);
2242 __ Bind(&l2);
2243 __ B(&l3, reg_not_zero, x10);
2244 __ B(&fail);
2245 __ Bind(&l3);
2246 __ B(&l4, reg_bit_clear, x10, 15);
2247 __ B(&fail);
2248 __ Bind(&l4);
2249 __ B(&l5, reg_bit_set, x10, 1);
2250 __ B(&fail);
2251 __ Bind(&l5);
2252
2253 __ B(&done);
2254
2255 __ Bind(&fail);
2256 __ Mov(x0, 0x1);
2257
2258 __ Bind(&done);
2259
2260 END();
2261
2262 RUN();
2263
2264 ASSERT_EQUAL_64(0x0, x0);
2265
2266 TEARDOWN();
2267}
2268
2269
armvixlad96eda2013-06-14 11:42:37 +01002270TEST(ldr_str_offset) {
2271 SETUP();
2272
armvixlb0c8ae22014-03-21 14:03:59 +00002273 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002274 uint64_t dst[5] = {0, 0, 0, 0, 0};
2275 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2276 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2277
2278 START();
2279 __ Mov(x17, src_base);
2280 __ Mov(x18, dst_base);
2281 __ Ldr(w0, MemOperand(x17));
2282 __ Str(w0, MemOperand(x18));
2283 __ Ldr(w1, MemOperand(x17, 4));
2284 __ Str(w1, MemOperand(x18, 12));
2285 __ Ldr(x2, MemOperand(x17, 8));
2286 __ Str(x2, MemOperand(x18, 16));
2287 __ Ldrb(w3, MemOperand(x17, 1));
2288 __ Strb(w3, MemOperand(x18, 25));
2289 __ Ldrh(w4, MemOperand(x17, 2));
2290 __ Strh(w4, MemOperand(x18, 33));
2291 END();
2292
2293 RUN();
2294
2295 ASSERT_EQUAL_64(0x76543210, x0);
2296 ASSERT_EQUAL_64(0x76543210, dst[0]);
2297 ASSERT_EQUAL_64(0xfedcba98, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00002298 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2299 ASSERT_EQUAL_64(0x0123456789abcdef, x2);
2300 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
armvixlad96eda2013-06-14 11:42:37 +01002301 ASSERT_EQUAL_64(0x32, x3);
2302 ASSERT_EQUAL_64(0x3200, dst[3]);
2303 ASSERT_EQUAL_64(0x7654, x4);
2304 ASSERT_EQUAL_64(0x765400, dst[4]);
2305 ASSERT_EQUAL_64(src_base, x17);
2306 ASSERT_EQUAL_64(dst_base, x18);
2307
2308 TEARDOWN();
2309}
2310
2311
2312TEST(ldr_str_wide) {
2313 SETUP();
2314
2315 uint32_t src[8192];
2316 uint32_t dst[8192];
2317 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2318 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2319 memset(src, 0xaa, 8192 * sizeof(src[0]));
2320 memset(dst, 0xaa, 8192 * sizeof(dst[0]));
2321 src[0] = 0;
2322 src[6144] = 6144;
2323 src[8191] = 8191;
2324
2325 START();
2326 __ Mov(x22, src_base);
2327 __ Mov(x23, dst_base);
2328 __ Mov(x24, src_base);
2329 __ Mov(x25, dst_base);
2330 __ Mov(x26, src_base);
2331 __ Mov(x27, dst_base);
2332
2333 __ Ldr(w0, MemOperand(x22, 8191 * sizeof(src[0])));
2334 __ Str(w0, MemOperand(x23, 8191 * sizeof(dst[0])));
2335 __ Ldr(w1, MemOperand(x24, 4096 * sizeof(src[0]), PostIndex));
2336 __ Str(w1, MemOperand(x25, 4096 * sizeof(dst[0]), PostIndex));
2337 __ Ldr(w2, MemOperand(x26, 6144 * sizeof(src[0]), PreIndex));
2338 __ Str(w2, MemOperand(x27, 6144 * sizeof(dst[0]), PreIndex));
2339 END();
2340
2341 RUN();
2342
2343 ASSERT_EQUAL_32(8191, w0);
2344 ASSERT_EQUAL_32(8191, dst[8191]);
2345 ASSERT_EQUAL_64(src_base, x22);
2346 ASSERT_EQUAL_64(dst_base, x23);
2347 ASSERT_EQUAL_32(0, w1);
2348 ASSERT_EQUAL_32(0, dst[0]);
2349 ASSERT_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24);
2350 ASSERT_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25);
2351 ASSERT_EQUAL_32(6144, w2);
2352 ASSERT_EQUAL_32(6144, dst[6144]);
2353 ASSERT_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26);
2354 ASSERT_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27);
2355
2356 TEARDOWN();
2357}
2358
2359
2360TEST(ldr_str_preindex) {
2361 SETUP();
2362
armvixlb0c8ae22014-03-21 14:03:59 +00002363 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002364 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2365 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2366 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2367
2368 START();
2369 __ Mov(x17, src_base);
2370 __ Mov(x18, dst_base);
2371 __ Mov(x19, src_base);
2372 __ Mov(x20, dst_base);
2373 __ Mov(x21, src_base + 16);
2374 __ Mov(x22, dst_base + 40);
2375 __ Mov(x23, src_base);
2376 __ Mov(x24, dst_base);
2377 __ Mov(x25, src_base);
2378 __ Mov(x26, dst_base);
2379 __ Ldr(w0, MemOperand(x17, 4, PreIndex));
2380 __ Str(w0, MemOperand(x18, 12, PreIndex));
2381 __ Ldr(x1, MemOperand(x19, 8, PreIndex));
2382 __ Str(x1, MemOperand(x20, 16, PreIndex));
2383 __ Ldr(w2, MemOperand(x21, -4, PreIndex));
2384 __ Str(w2, MemOperand(x22, -4, PreIndex));
2385 __ Ldrb(w3, MemOperand(x23, 1, PreIndex));
2386 __ Strb(w3, MemOperand(x24, 25, PreIndex));
2387 __ Ldrh(w4, MemOperand(x25, 3, PreIndex));
2388 __ Strh(w4, MemOperand(x26, 41, PreIndex));
2389 END();
2390
2391 RUN();
2392
2393 ASSERT_EQUAL_64(0xfedcba98, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002394 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2395 ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2396 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
armvixlad96eda2013-06-14 11:42:37 +01002397 ASSERT_EQUAL_64(0x01234567, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00002398 ASSERT_EQUAL_64(0x0123456700000000, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01002399 ASSERT_EQUAL_64(0x32, x3);
2400 ASSERT_EQUAL_64(0x3200, dst[3]);
2401 ASSERT_EQUAL_64(0x9876, x4);
2402 ASSERT_EQUAL_64(0x987600, dst[5]);
2403 ASSERT_EQUAL_64(src_base + 4, x17);
2404 ASSERT_EQUAL_64(dst_base + 12, x18);
2405 ASSERT_EQUAL_64(src_base + 8, x19);
2406 ASSERT_EQUAL_64(dst_base + 16, x20);
2407 ASSERT_EQUAL_64(src_base + 12, x21);
2408 ASSERT_EQUAL_64(dst_base + 36, x22);
2409 ASSERT_EQUAL_64(src_base + 1, x23);
2410 ASSERT_EQUAL_64(dst_base + 25, x24);
2411 ASSERT_EQUAL_64(src_base + 3, x25);
2412 ASSERT_EQUAL_64(dst_base + 41, x26);
2413
2414 TEARDOWN();
2415}
2416
2417
2418TEST(ldr_str_postindex) {
2419 SETUP();
2420
armvixlb0c8ae22014-03-21 14:03:59 +00002421 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002422 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2423 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2424 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2425
2426 START();
2427 __ Mov(x17, src_base + 4);
2428 __ Mov(x18, dst_base + 12);
2429 __ Mov(x19, src_base + 8);
2430 __ Mov(x20, dst_base + 16);
2431 __ Mov(x21, src_base + 8);
2432 __ Mov(x22, dst_base + 32);
2433 __ Mov(x23, src_base + 1);
2434 __ Mov(x24, dst_base + 25);
2435 __ Mov(x25, src_base + 3);
2436 __ Mov(x26, dst_base + 41);
2437 __ Ldr(w0, MemOperand(x17, 4, PostIndex));
2438 __ Str(w0, MemOperand(x18, 12, PostIndex));
2439 __ Ldr(x1, MemOperand(x19, 8, PostIndex));
2440 __ Str(x1, MemOperand(x20, 16, PostIndex));
2441 __ Ldr(x2, MemOperand(x21, -8, PostIndex));
2442 __ Str(x2, MemOperand(x22, -32, PostIndex));
2443 __ Ldrb(w3, MemOperand(x23, 1, PostIndex));
2444 __ Strb(w3, MemOperand(x24, 5, PostIndex));
2445 __ Ldrh(w4, MemOperand(x25, -3, PostIndex));
2446 __ Strh(w4, MemOperand(x26, -41, PostIndex));
2447 END();
2448
2449 RUN();
2450
2451 ASSERT_EQUAL_64(0xfedcba98, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002452 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2453 ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2454 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
2455 ASSERT_EQUAL_64(0x0123456789abcdef, x2);
2456 ASSERT_EQUAL_64(0x0123456789abcdef, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01002457 ASSERT_EQUAL_64(0x32, x3);
2458 ASSERT_EQUAL_64(0x3200, dst[3]);
2459 ASSERT_EQUAL_64(0x9876, x4);
2460 ASSERT_EQUAL_64(0x987600, dst[5]);
2461 ASSERT_EQUAL_64(src_base + 8, x17);
2462 ASSERT_EQUAL_64(dst_base + 24, x18);
2463 ASSERT_EQUAL_64(src_base + 16, x19);
2464 ASSERT_EQUAL_64(dst_base + 32, x20);
2465 ASSERT_EQUAL_64(src_base, x21);
2466 ASSERT_EQUAL_64(dst_base, x22);
2467 ASSERT_EQUAL_64(src_base + 2, x23);
2468 ASSERT_EQUAL_64(dst_base + 30, x24);
2469 ASSERT_EQUAL_64(src_base, x25);
2470 ASSERT_EQUAL_64(dst_base, x26);
2471
2472 TEARDOWN();
2473}
2474
2475
2476TEST(ldr_str_largeindex) {
2477 SETUP();
2478
2479 // This value won't fit in the immediate offset field of ldr/str instructions.
2480 int largeoffset = 0xabcdef;
2481
2482 int64_t data[3] = { 0x1122334455667788, 0, 0 };
armvixlb0c8ae22014-03-21 14:03:59 +00002483 uint64_t base_addr = reinterpret_cast<uintptr_t>(data);
2484 uint64_t drifted_addr = base_addr - largeoffset;
armvixlad96eda2013-06-14 11:42:37 +01002485
2486 // This test checks that we we can use large immediate offsets when
2487 // using PreIndex or PostIndex addressing mode of the MacroAssembler
2488 // Ldr/Str instructions.
2489
2490 START();
armvixlad96eda2013-06-14 11:42:37 +01002491 __ Mov(x19, drifted_addr);
armvixlb0c8ae22014-03-21 14:03:59 +00002492 __ Ldr(x0, MemOperand(x19, largeoffset, PreIndex));
armvixlad96eda2013-06-14 11:42:37 +01002493
armvixlb0c8ae22014-03-21 14:03:59 +00002494 __ Mov(x20, base_addr);
2495 __ Ldr(x1, MemOperand(x20, largeoffset, PostIndex));
2496
2497 __ Mov(x21, drifted_addr);
2498 __ Str(x0, MemOperand(x21, largeoffset + 8, PreIndex));
2499
2500 __ Mov(x22, base_addr + 16);
2501 __ Str(x0, MemOperand(x22, largeoffset, PostIndex));
armvixlad96eda2013-06-14 11:42:37 +01002502 END();
2503
2504 RUN();
2505
2506 ASSERT_EQUAL_64(0x1122334455667788, data[0]);
2507 ASSERT_EQUAL_64(0x1122334455667788, data[1]);
2508 ASSERT_EQUAL_64(0x1122334455667788, data[2]);
2509 ASSERT_EQUAL_64(0x1122334455667788, x0);
2510 ASSERT_EQUAL_64(0x1122334455667788, x1);
2511
armvixlb0c8ae22014-03-21 14:03:59 +00002512 ASSERT_EQUAL_64(base_addr, x19);
2513 ASSERT_EQUAL_64(base_addr + largeoffset, x20);
2514 ASSERT_EQUAL_64(base_addr + 8, x21);
2515 ASSERT_EQUAL_64(base_addr + 16 + largeoffset, x22);
armvixlad96eda2013-06-14 11:42:37 +01002516
2517 TEARDOWN();
2518}
2519
2520
2521TEST(load_signed) {
2522 SETUP();
2523
2524 uint32_t src[2] = {0x80008080, 0x7fff7f7f};
2525 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2526
2527 START();
2528 __ Mov(x24, src_base);
2529 __ Ldrsb(w0, MemOperand(x24));
2530 __ Ldrsb(w1, MemOperand(x24, 4));
2531 __ Ldrsh(w2, MemOperand(x24));
2532 __ Ldrsh(w3, MemOperand(x24, 4));
2533 __ Ldrsb(x4, MemOperand(x24));
2534 __ Ldrsb(x5, MemOperand(x24, 4));
2535 __ Ldrsh(x6, MemOperand(x24));
2536 __ Ldrsh(x7, MemOperand(x24, 4));
2537 __ Ldrsw(x8, MemOperand(x24));
2538 __ Ldrsw(x9, MemOperand(x24, 4));
2539 END();
2540
2541 RUN();
2542
2543 ASSERT_EQUAL_64(0xffffff80, x0);
2544 ASSERT_EQUAL_64(0x0000007f, x1);
2545 ASSERT_EQUAL_64(0xffff8080, x2);
2546 ASSERT_EQUAL_64(0x00007f7f, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00002547 ASSERT_EQUAL_64(0xffffffffffffff80, x4);
2548 ASSERT_EQUAL_64(0x000000000000007f, x5);
2549 ASSERT_EQUAL_64(0xffffffffffff8080, x6);
2550 ASSERT_EQUAL_64(0x0000000000007f7f, x7);
2551 ASSERT_EQUAL_64(0xffffffff80008080, x8);
2552 ASSERT_EQUAL_64(0x000000007fff7f7f, x9);
armvixlad96eda2013-06-14 11:42:37 +01002553
2554 TEARDOWN();
2555}
2556
2557
2558TEST(load_store_regoffset) {
2559 SETUP();
2560
2561 uint32_t src[3] = {1, 2, 3};
2562 uint32_t dst[4] = {0, 0, 0, 0};
2563 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2564 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2565
2566 START();
2567 __ Mov(x16, src_base);
2568 __ Mov(x17, dst_base);
2569 __ Mov(x18, src_base + 3 * sizeof(src[0]));
2570 __ Mov(x19, dst_base + 3 * sizeof(dst[0]));
2571 __ Mov(x20, dst_base + 4 * sizeof(dst[0]));
2572 __ Mov(x24, 0);
2573 __ Mov(x25, 4);
2574 __ Mov(x26, -4);
2575 __ Mov(x27, 0xfffffffc); // 32-bit -4.
2576 __ Mov(x28, 0xfffffffe); // 32-bit -2.
2577 __ Mov(x29, 0xffffffff); // 32-bit -1.
2578
2579 __ Ldr(w0, MemOperand(x16, x24));
2580 __ Ldr(x1, MemOperand(x16, x25));
2581 __ Ldr(w2, MemOperand(x18, x26));
2582 __ Ldr(w3, MemOperand(x18, x27, SXTW));
2583 __ Ldr(w4, MemOperand(x18, x28, SXTW, 2));
2584 __ Str(w0, MemOperand(x17, x24));
2585 __ Str(x1, MemOperand(x17, x25));
2586 __ Str(w2, MemOperand(x20, x29, SXTW, 2));
2587 END();
2588
2589 RUN();
2590
2591 ASSERT_EQUAL_64(1, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002592 ASSERT_EQUAL_64(0x0000000300000002, x1);
armvixlad96eda2013-06-14 11:42:37 +01002593 ASSERT_EQUAL_64(3, x2);
2594 ASSERT_EQUAL_64(3, x3);
2595 ASSERT_EQUAL_64(2, x4);
2596 ASSERT_EQUAL_32(1, dst[0]);
2597 ASSERT_EQUAL_32(2, dst[1]);
2598 ASSERT_EQUAL_32(3, dst[2]);
2599 ASSERT_EQUAL_32(3, dst[3]);
2600
2601 TEARDOWN();
2602}
2603
2604
2605TEST(load_store_float) {
2606 SETUP();
2607
2608 float src[3] = {1.0, 2.0, 3.0};
2609 float dst[3] = {0.0, 0.0, 0.0};
2610 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2611 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2612
2613 START();
2614 __ Mov(x17, src_base);
2615 __ Mov(x18, dst_base);
2616 __ Mov(x19, src_base);
2617 __ Mov(x20, dst_base);
2618 __ Mov(x21, src_base);
2619 __ Mov(x22, dst_base);
2620 __ Ldr(s0, MemOperand(x17, sizeof(src[0])));
2621 __ Str(s0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2622 __ Ldr(s1, MemOperand(x19, sizeof(src[0]), PostIndex));
2623 __ Str(s1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2624 __ Ldr(s2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2625 __ Str(s2, MemOperand(x22, sizeof(dst[0])));
2626 END();
2627
2628 RUN();
2629
2630 ASSERT_EQUAL_FP32(2.0, s0);
2631 ASSERT_EQUAL_FP32(2.0, dst[0]);
2632 ASSERT_EQUAL_FP32(1.0, s1);
2633 ASSERT_EQUAL_FP32(1.0, dst[2]);
2634 ASSERT_EQUAL_FP32(3.0, s2);
2635 ASSERT_EQUAL_FP32(3.0, dst[1]);
2636 ASSERT_EQUAL_64(src_base, x17);
2637 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2638 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2639 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2640 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2641 ASSERT_EQUAL_64(dst_base, x22);
2642
2643 TEARDOWN();
2644}
2645
2646
2647TEST(load_store_double) {
2648 SETUP();
2649
2650 double src[3] = {1.0, 2.0, 3.0};
2651 double dst[3] = {0.0, 0.0, 0.0};
2652 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2653 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2654
2655 START();
2656 __ Mov(x17, src_base);
2657 __ Mov(x18, dst_base);
2658 __ Mov(x19, src_base);
2659 __ Mov(x20, dst_base);
2660 __ Mov(x21, src_base);
2661 __ Mov(x22, dst_base);
2662 __ Ldr(d0, MemOperand(x17, sizeof(src[0])));
2663 __ Str(d0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2664 __ Ldr(d1, MemOperand(x19, sizeof(src[0]), PostIndex));
2665 __ Str(d1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2666 __ Ldr(d2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2667 __ Str(d2, MemOperand(x22, sizeof(dst[0])));
2668 END();
2669
2670 RUN();
2671
2672 ASSERT_EQUAL_FP64(2.0, d0);
2673 ASSERT_EQUAL_FP64(2.0, dst[0]);
2674 ASSERT_EQUAL_FP64(1.0, d1);
2675 ASSERT_EQUAL_FP64(1.0, dst[2]);
2676 ASSERT_EQUAL_FP64(3.0, d2);
2677 ASSERT_EQUAL_FP64(3.0, dst[1]);
2678 ASSERT_EQUAL_64(src_base, x17);
2679 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2680 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2681 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2682 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2683 ASSERT_EQUAL_64(dst_base, x22);
2684
2685 TEARDOWN();
2686}
2687
2688
armvixl5289c592015-03-02 13:52:04 +00002689TEST(load_store_b) {
2690 SETUP();
2691
2692 uint8_t src[3] = {0x12, 0x23, 0x34};
2693 uint8_t dst[3] = {0, 0, 0};
2694 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2695 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2696
2697 START();
2698 __ Mov(x17, src_base);
2699 __ Mov(x18, dst_base);
2700 __ Mov(x19, src_base);
2701 __ Mov(x20, dst_base);
2702 __ Mov(x21, src_base);
2703 __ Mov(x22, dst_base);
2704 __ Ldr(b0, MemOperand(x17, sizeof(src[0])));
2705 __ Str(b0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2706 __ Ldr(b1, MemOperand(x19, sizeof(src[0]), PostIndex));
2707 __ Str(b1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2708 __ Ldr(b2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2709 __ Str(b2, MemOperand(x22, sizeof(dst[0])));
2710 END();
2711
2712 RUN();
2713
2714 ASSERT_EQUAL_128(0, 0x23, q0);
2715 ASSERT_EQUAL_64(0x23, dst[0]);
2716 ASSERT_EQUAL_128(0, 0x12, q1);
2717 ASSERT_EQUAL_64(0x12, dst[2]);
2718 ASSERT_EQUAL_128(0, 0x34, q2);
2719 ASSERT_EQUAL_64(0x34, dst[1]);
2720 ASSERT_EQUAL_64(src_base, x17);
2721 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2722 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2723 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2724 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2725 ASSERT_EQUAL_64(dst_base, x22);
2726
2727 TEARDOWN();
2728}
2729
2730
2731TEST(load_store_h) {
2732 SETUP();
2733
2734 uint16_t src[3] = {0x1234, 0x2345, 0x3456};
2735 uint16_t dst[3] = {0, 0, 0};
2736 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2737 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2738
2739 START();
2740 __ Mov(x17, src_base);
2741 __ Mov(x18, dst_base);
2742 __ Mov(x19, src_base);
2743 __ Mov(x20, dst_base);
2744 __ Mov(x21, src_base);
2745 __ Mov(x22, dst_base);
2746 __ Ldr(h0, MemOperand(x17, sizeof(src[0])));
2747 __ Str(h0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2748 __ Ldr(h1, MemOperand(x19, sizeof(src[0]), PostIndex));
2749 __ Str(h1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2750 __ Ldr(h2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2751 __ Str(h2, MemOperand(x22, sizeof(dst[0])));
2752 END();
2753
2754 RUN();
2755
2756 ASSERT_EQUAL_128(0, 0x2345, q0);
2757 ASSERT_EQUAL_64(0x2345, dst[0]);
2758 ASSERT_EQUAL_128(0, 0x1234, q1);
2759 ASSERT_EQUAL_64(0x1234, dst[2]);
2760 ASSERT_EQUAL_128(0, 0x3456, q2);
2761 ASSERT_EQUAL_64(0x3456, dst[1]);
2762 ASSERT_EQUAL_64(src_base, x17);
2763 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2764 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2765 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2766 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2767 ASSERT_EQUAL_64(dst_base, x22);
2768
2769 TEARDOWN();
2770}
2771
2772
2773TEST(load_store_q) {
2774 SETUP();
2775
2776 uint8_t src[48] = {0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe,
2777 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
2778 0x21, 0x43, 0x65, 0x87, 0xa9, 0xcb, 0xed, 0x0f,
2779 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
2780 0x24, 0x46, 0x68, 0x8a, 0xac, 0xce, 0xe0, 0x02,
2781 0x42, 0x64, 0x86, 0xa8, 0xca, 0xec, 0x0e, 0x20};
2782
2783 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2784 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2785 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2786
2787 START();
2788 __ Mov(x17, src_base);
2789 __ Mov(x18, dst_base);
2790 __ Mov(x19, src_base);
2791 __ Mov(x20, dst_base);
2792 __ Mov(x21, src_base);
2793 __ Mov(x22, dst_base);
2794 __ Ldr(q0, MemOperand(x17, 16));
2795 __ Str(q0, MemOperand(x18, 16, PostIndex));
2796 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
2797 __ Str(q1, MemOperand(x20, 32, PreIndex));
2798 __ Ldr(q2, MemOperand(x21, 32, PreIndex));
2799 __ Str(q2, MemOperand(x22, 16));
2800 END();
2801
2802 RUN();
2803
2804 ASSERT_EQUAL_128(0xf0debc9a78563412, 0x0fedcba987654321, q0);
2805 ASSERT_EQUAL_64(0x0fedcba987654321, dst[0]);
2806 ASSERT_EQUAL_64(0xf0debc9a78563412, dst[1]);
2807 ASSERT_EQUAL_128(0xefcdab8967452301, 0xfedcba9876543210, q1);
2808 ASSERT_EQUAL_64(0xfedcba9876543210, dst[4]);
2809 ASSERT_EQUAL_64(0xefcdab8967452301, dst[5]);
2810 ASSERT_EQUAL_128(0x200eeccaa8866442, 0x02e0ceac8a684624, q2);
2811 ASSERT_EQUAL_64(0x02e0ceac8a684624, dst[2]);
2812 ASSERT_EQUAL_64(0x200eeccaa8866442, dst[3]);
2813 ASSERT_EQUAL_64(src_base, x17);
2814 ASSERT_EQUAL_64(dst_base + 16, x18);
2815 ASSERT_EQUAL_64(src_base + 16, x19);
2816 ASSERT_EQUAL_64(dst_base + 32, x20);
2817 ASSERT_EQUAL_64(src_base + 32, x21);
2818 ASSERT_EQUAL_64(dst_base, x22);
2819
2820 TEARDOWN();
2821}
2822
2823
2824TEST(load_store_v_regoffset) {
2825 SETUP();
2826
2827 uint8_t src[64];
2828 for (unsigned i = 0; i < sizeof(src); i++) {
2829 src[i] = i;
2830 }
2831 uint8_t dst[64];
2832 memset(dst, 0, sizeof(dst));
2833
2834 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2835 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2836
2837 START();
2838 __ Mov(x17, src_base + 16);
2839 __ Mov(x18, 1);
2840 __ Mov(w19, -1);
2841 __ Mov(x20, dst_base - 1);
2842
2843 __ Ldr(b0, MemOperand(x17, x18));
2844 __ Ldr(b1, MemOperand(x17, x19, SXTW));
2845
2846 __ Ldr(h2, MemOperand(x17, x18));
2847 __ Ldr(h3, MemOperand(x17, x18, UXTW, 1));
2848 __ Ldr(h4, MemOperand(x17, x19, SXTW, 1));
2849 __ Ldr(h5, MemOperand(x17, x18, LSL, 1));
2850
2851 __ Ldr(s16, MemOperand(x17, x18));
2852 __ Ldr(s17, MemOperand(x17, x18, UXTW, 2));
2853 __ Ldr(s18, MemOperand(x17, x19, SXTW, 2));
2854 __ Ldr(s19, MemOperand(x17, x18, LSL, 2));
2855
2856 __ Ldr(d20, MemOperand(x17, x18));
2857 __ Ldr(d21, MemOperand(x17, x18, UXTW, 3));
2858 __ Ldr(d22, MemOperand(x17, x19, SXTW, 3));
2859 __ Ldr(d23, MemOperand(x17, x18, LSL, 3));
2860
2861 __ Ldr(q24, MemOperand(x17, x18));
2862 __ Ldr(q25, MemOperand(x17, x18, UXTW, 4));
2863 __ Ldr(q26, MemOperand(x17, x19, SXTW, 4));
2864 __ Ldr(q27, MemOperand(x17, x18, LSL, 4));
2865
2866 // Store [bhsdq]27 to adjacent memory locations, then load again to check.
2867 __ Str(b27, MemOperand(x20, x18));
2868 __ Str(h27, MemOperand(x20, x18, UXTW, 1));
2869 __ Add(x20, x20, 8);
2870 __ Str(s27, MemOperand(x20, x19, SXTW, 2));
2871 __ Sub(x20, x20, 8);
2872 __ Str(d27, MemOperand(x20, x18, LSL, 3));
2873 __ Add(x20, x20, 32);
2874 __ Str(q27, MemOperand(x20, x19, SXTW, 4));
2875
2876 __ Sub(x20, x20, 32);
2877 __ Ldr(q6, MemOperand(x20, x18));
2878 __ Ldr(q7, MemOperand(x20, x18, LSL, 4));
2879
2880 END();
2881
2882 RUN();
2883
2884 ASSERT_EQUAL_128(0, 0x11, q0);
2885 ASSERT_EQUAL_128(0, 0x0f, q1);
2886 ASSERT_EQUAL_128(0, 0x1211, q2);
2887 ASSERT_EQUAL_128(0, 0x1312, q3);
2888 ASSERT_EQUAL_128(0, 0x0f0e, q4);
2889 ASSERT_EQUAL_128(0, 0x1312, q5);
2890 ASSERT_EQUAL_128(0, 0x14131211, q16);
2891 ASSERT_EQUAL_128(0, 0x17161514, q17);
2892 ASSERT_EQUAL_128(0, 0x0f0e0d0c, q18);
2893 ASSERT_EQUAL_128(0, 0x17161514, q19);
2894 ASSERT_EQUAL_128(0, 0x1817161514131211, q20);
2895 ASSERT_EQUAL_128(0, 0x1f1e1d1c1b1a1918, q21);
2896 ASSERT_EQUAL_128(0, 0x0f0e0d0c0b0a0908, q22);
2897 ASSERT_EQUAL_128(0, 0x1f1e1d1c1b1a1918, q23);
2898 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x1817161514131211, q24);
2899 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q25);
2900 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q26);
2901 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q27);
2902 ASSERT_EQUAL_128(0x2027262524232221, 0x2023222120212020, q6);
2903 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q7);
2904
2905 TEARDOWN();
2906}
2907
2908
2909TEST(neon_ld1_d) {
2910 SETUP();
2911
2912 uint8_t src[32 + 5];
2913 for (unsigned i = 0; i < sizeof(src); i++) {
2914 src[i] = i;
2915 }
2916 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2917
2918 START();
2919 __ Mov(x17, src_base);
2920 __ Ldr(q2, MemOperand(x17)); // Initialise top 64-bits of Q register.
2921 __ Ld1(v2.V8B(), MemOperand(x17));
2922 __ Add(x17, x17, 1);
2923 __ Ld1(v3.V8B(), v4.V8B(), MemOperand(x17));
2924 __ Add(x17, x17, 1);
2925 __ Ld1(v5.V4H(), v6.V4H(), v7.V4H(), MemOperand(x17));
2926 __ Add(x17, x17, 1);
2927 __ Ld1(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(), MemOperand(x17));
2928 __ Add(x17, x17, 1);
2929 __ Ld1(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x17));
2930 __ Add(x17, x17, 1);
2931 __ Ld1(v20.V1D(), v21.V1D(), v22.V1D(), v23.V1D(), MemOperand(x17));
2932 END();
2933
2934 RUN();
2935
2936 ASSERT_EQUAL_128(0, 0x0706050403020100, q2);
2937 ASSERT_EQUAL_128(0, 0x0807060504030201, q3);
2938 ASSERT_EQUAL_128(0, 0x100f0e0d0c0b0a09, q4);
2939 ASSERT_EQUAL_128(0, 0x0908070605040302, q5);
2940 ASSERT_EQUAL_128(0, 0x11100f0e0d0c0b0a, q6);
2941 ASSERT_EQUAL_128(0, 0x1918171615141312, q7);
2942 ASSERT_EQUAL_128(0, 0x0a09080706050403, q16);
2943 ASSERT_EQUAL_128(0, 0x1211100f0e0d0c0b, q17);
2944 ASSERT_EQUAL_128(0, 0x1a19181716151413, q18);
2945 ASSERT_EQUAL_128(0, 0x2221201f1e1d1c1b, q19);
2946 ASSERT_EQUAL_128(0, 0x0b0a090807060504, q30);
2947 ASSERT_EQUAL_128(0, 0x131211100f0e0d0c, q31);
2948 ASSERT_EQUAL_128(0, 0x1b1a191817161514, q0);
2949 ASSERT_EQUAL_128(0, 0x232221201f1e1d1c, q1);
2950 ASSERT_EQUAL_128(0, 0x0c0b0a0908070605, q20);
2951 ASSERT_EQUAL_128(0, 0x14131211100f0e0d, q21);
2952 ASSERT_EQUAL_128(0, 0x1c1b1a1918171615, q22);
2953 ASSERT_EQUAL_128(0, 0x24232221201f1e1d, q23);
2954
2955 TEARDOWN();
2956}
2957
2958
2959TEST(neon_ld1_d_postindex) {
2960 SETUP();
2961
2962 uint8_t src[32 + 5];
2963 for (unsigned i = 0; i < sizeof(src); i++) {
2964 src[i] = i;
2965 }
2966 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2967
2968 START();
2969 __ Mov(x17, src_base);
2970 __ Mov(x18, src_base + 1);
2971 __ Mov(x19, src_base + 2);
2972 __ Mov(x20, src_base + 3);
2973 __ Mov(x21, src_base + 4);
2974 __ Mov(x22, src_base + 5);
2975 __ Mov(x23, 1);
2976 __ Ldr(q2, MemOperand(x17)); // Initialise top 64-bits of Q register.
2977 __ Ld1(v2.V8B(), MemOperand(x17, x23, PostIndex));
2978 __ Ld1(v3.V8B(), v4.V8B(), MemOperand(x18, 16, PostIndex));
2979 __ Ld1(v5.V4H(), v6.V4H(), v7.V4H(), MemOperand(x19, 24, PostIndex));
2980 __ Ld1(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(),
2981 MemOperand(x20, 32, PostIndex));
2982 __ Ld1(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(),
2983 MemOperand(x21, 32, PostIndex));
2984 __ Ld1(v20.V1D(), v21.V1D(), v22.V1D(), v23.V1D(),
2985 MemOperand(x22, 32, PostIndex));
2986 END();
2987
2988 RUN();
2989
2990 ASSERT_EQUAL_128(0, 0x0706050403020100, q2);
2991 ASSERT_EQUAL_128(0, 0x0807060504030201, q3);
2992 ASSERT_EQUAL_128(0, 0x100f0e0d0c0b0a09, q4);
2993 ASSERT_EQUAL_128(0, 0x0908070605040302, q5);
2994 ASSERT_EQUAL_128(0, 0x11100f0e0d0c0b0a, q6);
2995 ASSERT_EQUAL_128(0, 0x1918171615141312, q7);
2996 ASSERT_EQUAL_128(0, 0x0a09080706050403, q16);
2997 ASSERT_EQUAL_128(0, 0x1211100f0e0d0c0b, q17);
2998 ASSERT_EQUAL_128(0, 0x1a19181716151413, q18);
2999 ASSERT_EQUAL_128(0, 0x2221201f1e1d1c1b, q19);
3000 ASSERT_EQUAL_128(0, 0x0b0a090807060504, q30);
3001 ASSERT_EQUAL_128(0, 0x131211100f0e0d0c, q31);
3002 ASSERT_EQUAL_128(0, 0x1b1a191817161514, q0);
3003 ASSERT_EQUAL_128(0, 0x232221201f1e1d1c, q1);
3004 ASSERT_EQUAL_128(0, 0x0c0b0a0908070605, q20);
3005 ASSERT_EQUAL_128(0, 0x14131211100f0e0d, q21);
3006 ASSERT_EQUAL_128(0, 0x1c1b1a1918171615, q22);
3007 ASSERT_EQUAL_128(0, 0x24232221201f1e1d, q23);
3008 ASSERT_EQUAL_64(src_base + 1, x17);
3009 ASSERT_EQUAL_64(src_base + 1 + 16, x18);
3010 ASSERT_EQUAL_64(src_base + 2 + 24, x19);
3011 ASSERT_EQUAL_64(src_base + 3 + 32, x20);
3012 ASSERT_EQUAL_64(src_base + 4 + 32, x21);
3013 ASSERT_EQUAL_64(src_base + 5 + 32, x22);
3014
3015 TEARDOWN();
3016}
3017
3018
3019TEST(neon_ld1_q) {
3020 SETUP();
3021
3022 uint8_t src[64 + 4];
3023 for (unsigned i = 0; i < sizeof(src); i++) {
3024 src[i] = i;
3025 }
3026 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3027
3028 START();
3029 __ Mov(x17, src_base);
3030 __ Ld1(v2.V16B(), MemOperand(x17));
3031 __ Add(x17, x17, 1);
3032 __ Ld1(v3.V16B(), v4.V16B(), MemOperand(x17));
3033 __ Add(x17, x17, 1);
3034 __ Ld1(v5.V8H(), v6.V8H(), v7.V8H(), MemOperand(x17));
3035 __ Add(x17, x17, 1);
3036 __ Ld1(v16.V4S(), v17.V4S(), v18.V4S(), v19.V4S(), MemOperand(x17));
3037 __ Add(x17, x17, 1);
3038 __ Ld1(v30.V2D(), v31.V2D(), v0.V2D(), v1.V2D(), MemOperand(x17));
3039 END();
3040
3041 RUN();
3042
3043 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q2);
3044 ASSERT_EQUAL_128(0x100f0e0d0c0b0a09, 0x0807060504030201, q3);
3045 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x1817161514131211, q4);
3046 ASSERT_EQUAL_128(0x11100f0e0d0c0b0a, 0x0908070605040302, q5);
3047 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x1918171615141312, q6);
3048 ASSERT_EQUAL_128(0x31302f2e2d2c2b2a, 0x2928272625242322, q7);
3049 ASSERT_EQUAL_128(0x1211100f0e0d0c0b, 0x0a09080706050403, q16);
3050 ASSERT_EQUAL_128(0x2221201f1e1d1c1b, 0x1a19181716151413, q17);
3051 ASSERT_EQUAL_128(0x3231302f2e2d2c2b, 0x2a29282726252423, q18);
3052 ASSERT_EQUAL_128(0x4241403f3e3d3c3b, 0x3a39383736353433, q19);
3053 ASSERT_EQUAL_128(0x131211100f0e0d0c, 0x0b0a090807060504, q30);
3054 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x1b1a191817161514, q31);
3055 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x2b2a292827262524, q0);
3056 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x3b3a393837363534, q1);
3057
3058 TEARDOWN();
3059}
3060
3061
3062TEST(neon_ld1_q_postindex) {
3063 SETUP();
3064
3065 uint8_t src[64 + 4];
3066 for (unsigned i = 0; i < sizeof(src); i++) {
3067 src[i] = i;
3068 }
3069 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3070
3071 START();
3072 __ Mov(x17, src_base);
3073 __ Mov(x18, src_base + 1);
3074 __ Mov(x19, src_base + 2);
3075 __ Mov(x20, src_base + 3);
3076 __ Mov(x21, src_base + 4);
3077 __ Mov(x22, 1);
3078 __ Ld1(v2.V16B(), MemOperand(x17, x22, PostIndex));
3079 __ Ld1(v3.V16B(), v4.V16B(), MemOperand(x18, 32, PostIndex));
3080 __ Ld1(v5.V8H(), v6.V8H(), v7.V8H(), MemOperand(x19, 48, PostIndex));
3081 __ Ld1(v16.V4S(), v17.V4S(), v18.V4S(), v19.V4S(),
3082 MemOperand(x20, 64, PostIndex));
3083 __ Ld1(v30.V2D(), v31.V2D(), v0.V2D(), v1.V2D(),
3084 MemOperand(x21, 64, PostIndex));
3085 END();
3086
3087 RUN();
3088
3089 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q2);
3090 ASSERT_EQUAL_128(0x100f0e0d0c0b0a09, 0x0807060504030201, q3);
3091 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x1817161514131211, q4);
3092 ASSERT_EQUAL_128(0x11100f0e0d0c0b0a, 0x0908070605040302, q5);
3093 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x1918171615141312, q6);
3094 ASSERT_EQUAL_128(0x31302f2e2d2c2b2a, 0x2928272625242322, q7);
3095 ASSERT_EQUAL_128(0x1211100f0e0d0c0b, 0x0a09080706050403, q16);
3096 ASSERT_EQUAL_128(0x2221201f1e1d1c1b, 0x1a19181716151413, q17);
3097 ASSERT_EQUAL_128(0x3231302f2e2d2c2b, 0x2a29282726252423, q18);
3098 ASSERT_EQUAL_128(0x4241403f3e3d3c3b, 0x3a39383736353433, q19);
3099 ASSERT_EQUAL_128(0x131211100f0e0d0c, 0x0b0a090807060504, q30);
3100 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x1b1a191817161514, q31);
3101 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x2b2a292827262524, q0);
3102 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x3b3a393837363534, q1);
3103 ASSERT_EQUAL_64(src_base + 1, x17);
3104 ASSERT_EQUAL_64(src_base + 1 + 32, x18);
3105 ASSERT_EQUAL_64(src_base + 2 + 48, x19);
3106 ASSERT_EQUAL_64(src_base + 3 + 64, x20);
3107 ASSERT_EQUAL_64(src_base + 4 + 64, x21);
3108
3109 TEARDOWN();
3110}
3111
3112
3113TEST(neon_ld1_lane) {
3114 SETUP();
3115
3116 uint8_t src[64];
3117 for (unsigned i = 0; i < sizeof(src); i++) {
3118 src[i] = i;
3119 }
3120 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3121
3122 START();
3123
3124 // Test loading whole register by element.
3125 __ Mov(x17, src_base);
3126 for (int i = 15; i >= 0; i--) {
3127 __ Ld1(v0.B(), i, MemOperand(x17));
3128 __ Add(x17, x17, 1);
3129 }
3130
3131 __ Mov(x17, src_base);
3132 for (int i = 7; i >= 0; i--) {
3133 __ Ld1(v1.H(), i, MemOperand(x17));
3134 __ Add(x17, x17, 1);
3135 }
3136
3137 __ Mov(x17, src_base);
3138 for (int i = 3; i >= 0; i--) {
3139 __ Ld1(v2.S(), i, MemOperand(x17));
3140 __ Add(x17, x17, 1);
3141 }
3142
3143 __ Mov(x17, src_base);
3144 for (int i = 1; i >= 0; i--) {
3145 __ Ld1(v3.D(), i, MemOperand(x17));
3146 __ Add(x17, x17, 1);
3147 }
3148
3149 // Test loading a single element into an initialised register.
3150 __ Mov(x17, src_base);
3151 __ Ldr(q4, MemOperand(x17));
3152 __ Ld1(v4.B(), 4, MemOperand(x17));
3153 __ Ldr(q5, MemOperand(x17));
3154 __ Ld1(v5.H(), 3, MemOperand(x17));
3155 __ Ldr(q6, MemOperand(x17));
3156 __ Ld1(v6.S(), 2, MemOperand(x17));
3157 __ Ldr(q7, MemOperand(x17));
3158 __ Ld1(v7.D(), 1, MemOperand(x17));
3159
3160 END();
3161
3162 RUN();
3163
3164 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
3165 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q1);
3166 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q2);
3167 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q3);
3168 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q4);
3169 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q5);
3170 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q6);
3171 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q7);
3172
3173 TEARDOWN();
3174}
3175
3176TEST(neon_ld2_d) {
3177 SETUP();
3178
3179 uint8_t src[64 + 4];
3180 for (unsigned i = 0; i < sizeof(src); i++) {
3181 src[i] = i;
3182 }
3183 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3184
3185 START();
3186 __ Mov(x17, src_base);
3187 __ Ld2(v2.V8B(), v3.V8B(), MemOperand(x17));
3188 __ Add(x17, x17, 1);
3189 __ Ld2(v4.V8B(), v5.V8B(), MemOperand(x17));
3190 __ Add(x17, x17, 1);
3191 __ Ld2(v6.V4H(), v7.V4H(), MemOperand(x17));
3192 __ Add(x17, x17, 1);
3193 __ Ld2(v31.V2S(), v0.V2S(), MemOperand(x17));
3194 END();
3195
3196 RUN();
3197
3198 ASSERT_EQUAL_128(0, 0x0e0c0a0806040200, q2);
3199 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q3);
3200 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q4);
3201 ASSERT_EQUAL_128(0, 0x100e0c0a08060402, q5);
3202 ASSERT_EQUAL_128(0, 0x0f0e0b0a07060302, q6);
3203 ASSERT_EQUAL_128(0, 0x11100d0c09080504, q7);
3204 ASSERT_EQUAL_128(0, 0x0e0d0c0b06050403, q31);
3205 ASSERT_EQUAL_128(0, 0x1211100f0a090807, q0);
3206
3207 TEARDOWN();
3208}
3209
3210TEST(neon_ld2_d_postindex) {
3211 SETUP();
3212
3213 uint8_t src[32 + 4];
3214 for (unsigned i = 0; i < sizeof(src); i++) {
3215 src[i] = i;
3216 }
3217 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3218
3219 START();
3220 __ Mov(x17, src_base);
3221 __ Mov(x18, src_base + 1);
3222 __ Mov(x19, src_base + 2);
3223 __ Mov(x20, src_base + 3);
3224 __ Mov(x21, src_base + 4);
3225 __ Mov(x22, 1);
3226 __ Ld2(v2.V8B(), v3.V8B(), MemOperand(x17, x22, PostIndex));
3227 __ Ld2(v4.V8B(), v5.V8B(), MemOperand(x18, 16, PostIndex));
3228 __ Ld2(v5.V4H(), v6.V4H(), MemOperand(x19, 16, PostIndex));
3229 __ Ld2(v16.V2S(), v17.V2S(), MemOperand(x20, 16, PostIndex));
3230 __ Ld2(v31.V2S(), v0.V2S(), MemOperand(x21, 16, PostIndex));
3231 END();
3232
3233 RUN();
3234
3235 ASSERT_EQUAL_128(0, 0x0e0c0a0806040200, q2);
3236 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q3);
3237 ASSERT_EQUAL_128(0, 0x0f0d0b0907050301, q4);
3238 ASSERT_EQUAL_128(0, 0x0f0e0b0a07060302, q5);
3239 ASSERT_EQUAL_128(0, 0x11100d0c09080504, q6);
3240 ASSERT_EQUAL_128(0, 0x0e0d0c0b06050403, q16);
3241 ASSERT_EQUAL_128(0, 0x1211100f0a090807, q17);
3242 ASSERT_EQUAL_128(0, 0x0f0e0d0c07060504, q31);
3243 ASSERT_EQUAL_128(0, 0x131211100b0a0908, q0);
3244
3245 ASSERT_EQUAL_64(src_base + 1, x17);
3246 ASSERT_EQUAL_64(src_base + 1 + 16, x18);
3247 ASSERT_EQUAL_64(src_base + 2 + 16, x19);
3248 ASSERT_EQUAL_64(src_base + 3 + 16, x20);
3249 ASSERT_EQUAL_64(src_base + 4 + 16, x21);
3250
3251 TEARDOWN();
3252}
3253
3254
3255TEST(neon_ld2_q) {
3256 SETUP();
3257
3258 uint8_t src[64 + 4];
3259 for (unsigned i = 0; i < sizeof(src); i++) {
3260 src[i] = i;
3261 }
3262 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3263
3264 START();
3265 __ Mov(x17, src_base);
3266 __ Ld2(v2.V16B(), v3.V16B(), MemOperand(x17));
3267 __ Add(x17, x17, 1);
3268 __ Ld2(v4.V16B(), v5.V16B(), MemOperand(x17));
3269 __ Add(x17, x17, 1);
3270 __ Ld2(v6.V8H(), v7.V8H(), MemOperand(x17));
3271 __ Add(x17, x17, 1);
3272 __ Ld2(v16.V4S(), v17.V4S(), MemOperand(x17));
3273 __ Add(x17, x17, 1);
3274 __ Ld2(v31.V2D(), v0.V2D(), MemOperand(x17));
3275 END();
3276
3277 RUN();
3278
3279 ASSERT_EQUAL_128(0x1e1c1a1816141210, 0x0e0c0a0806040200, q2);
3280 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q3);
3281 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q4);
3282 ASSERT_EQUAL_128(0x201e1c1a18161412, 0x100e0c0a08060402, q5);
3283 ASSERT_EQUAL_128(0x1f1e1b1a17161312, 0x0f0e0b0a07060302, q6);
3284 ASSERT_EQUAL_128(0x21201d1c19181514, 0x11100d0c09080504, q7);
3285 ASSERT_EQUAL_128(0x1e1d1c1b16151413, 0x0e0d0c0b06050403, q16);
3286 ASSERT_EQUAL_128(0x2221201f1a191817, 0x1211100f0a090807, q17);
3287 ASSERT_EQUAL_128(0x1b1a191817161514, 0x0b0a090807060504, q31);
3288 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x131211100f0e0d0c, q0);
3289
3290 TEARDOWN();
3291}
3292
3293
3294TEST(neon_ld2_q_postindex) {
3295 SETUP();
3296
3297 uint8_t src[64 + 4];
3298 for (unsigned i = 0; i < sizeof(src); i++) {
3299 src[i] = i;
3300 }
3301 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3302
3303 START();
3304 __ Mov(x17, src_base);
3305 __ Mov(x18, src_base + 1);
3306 __ Mov(x19, src_base + 2);
3307 __ Mov(x20, src_base + 3);
3308 __ Mov(x21, src_base + 4);
3309 __ Mov(x22, 1);
3310 __ Ld2(v2.V16B(), v3.V16B(), MemOperand(x17, x22, PostIndex));
3311 __ Ld2(v4.V16B(), v5.V16B(), MemOperand(x18, 32, PostIndex));
3312 __ Ld2(v6.V8H(), v7.V8H(), MemOperand(x19, 32, PostIndex));
3313 __ Ld2(v16.V4S(), v17.V4S(), MemOperand(x20, 32, PostIndex));
3314 __ Ld2(v31.V2D(), v0.V2D(), MemOperand(x21, 32, PostIndex));
3315 END();
3316
3317 RUN();
3318
3319 ASSERT_EQUAL_128(0x1e1c1a1816141210, 0x0e0c0a0806040200, q2);
3320 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q3);
3321 ASSERT_EQUAL_128(0x1f1d1b1917151311, 0x0f0d0b0907050301, q4);
3322 ASSERT_EQUAL_128(0x201e1c1a18161412, 0x100e0c0a08060402, q5);
3323 ASSERT_EQUAL_128(0x1f1e1b1a17161312, 0x0f0e0b0a07060302, q6);
3324 ASSERT_EQUAL_128(0x21201d1c19181514, 0x11100d0c09080504, q7);
3325 ASSERT_EQUAL_128(0x1e1d1c1b16151413, 0x0e0d0c0b06050403, q16);
3326 ASSERT_EQUAL_128(0x2221201f1a191817, 0x1211100f0a090807, q17);
3327 ASSERT_EQUAL_128(0x1b1a191817161514, 0x0b0a090807060504, q31);
3328 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x131211100f0e0d0c, q0);
3329
3330
3331
3332 ASSERT_EQUAL_64(src_base + 1, x17);
3333 ASSERT_EQUAL_64(src_base + 1 + 32, x18);
3334 ASSERT_EQUAL_64(src_base + 2 + 32, x19);
3335 ASSERT_EQUAL_64(src_base + 3 + 32, x20);
3336 ASSERT_EQUAL_64(src_base + 4 + 32, x21);
3337
3338 TEARDOWN();
3339}
3340
3341
3342TEST(neon_ld2_lane) {
3343 SETUP();
3344
3345 uint8_t src[64];
3346 for (unsigned i = 0; i < sizeof(src); i++) {
3347 src[i] = i;
3348 }
3349 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3350
3351 START();
3352
3353 // Test loading whole register by element.
3354 __ Mov(x17, src_base);
3355 for (int i = 15; i >= 0; i--) {
3356 __ Ld2(v0.B(), v1.B(), i, MemOperand(x17));
3357 __ Add(x17, x17, 1);
3358 }
3359
3360 __ Mov(x17, src_base);
3361 for (int i = 7; i >= 0; i--) {
3362 __ Ld2(v2.H(), v3.H(), i, MemOperand(x17));
3363 __ Add(x17, x17, 1);
3364 }
3365
3366 __ Mov(x17, src_base);
3367 for (int i = 3; i >= 0; i--) {
3368 __ Ld2(v4.S(), v5.S(), i, MemOperand(x17));
3369 __ Add(x17, x17, 1);
3370 }
3371
3372 __ Mov(x17, src_base);
3373 for (int i = 1; i >= 0; i--) {
3374 __ Ld2(v6.D(), v7.D(), i, MemOperand(x17));
3375 __ Add(x17, x17, 1);
3376 }
3377
3378 // Test loading a single element into an initialised register.
3379 __ Mov(x17, src_base);
3380 __ Mov(x4, x17);
3381 __ Ldr(q8, MemOperand(x4, 16, PostIndex));
3382 __ Ldr(q9, MemOperand(x4));
3383 __ Ld2(v8.B(), v9.B(), 4, MemOperand(x17));
3384 __ Mov(x5, x17);
3385 __ Ldr(q10, MemOperand(x5, 16, PostIndex));
3386 __ Ldr(q11, MemOperand(x5));
3387 __ Ld2(v10.H(), v11.H(), 3, MemOperand(x17));
3388 __ Mov(x6, x17);
3389 __ Ldr(q12, MemOperand(x6, 16, PostIndex));
3390 __ Ldr(q13, MemOperand(x6));
3391 __ Ld2(v12.S(), v13.S(), 2, MemOperand(x17));
3392 __ Mov(x7, x17);
3393 __ Ldr(q14, MemOperand(x7, 16, PostIndex));
3394 __ Ldr(q15, MemOperand(x7));
3395 __ Ld2(v14.D(), v15.D(), 1, MemOperand(x17));
3396
3397 END();
3398
3399 RUN();
3400
3401 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
3402 ASSERT_EQUAL_128(0x0102030405060708, 0x090a0b0c0d0e0f10, q1);
3403 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q2);
3404 ASSERT_EQUAL_128(0x0302040305040605, 0x0706080709080a09, q3);
3405 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q4);
3406 ASSERT_EQUAL_128(0x0706050408070605, 0x090807060a090807, q5);
3407 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q6);
3408 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x100f0e0d0c0b0a09, q7);
3409 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q8);
3410 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q9);
3411 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q10);
3412 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q11);
3413 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q12);
3414 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q13);
3415 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q14);
3416 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q15);
3417
3418 TEARDOWN();
3419}
3420
3421
3422TEST(neon_ld2_lane_postindex) {
3423 SETUP();
3424
3425 uint8_t src[64];
3426 for (unsigned i = 0; i < sizeof(src); i++) {
3427 src[i] = i;
3428 }
3429 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3430
3431 START();
3432 __ Mov(x17, src_base);
3433 __ Mov(x18, src_base);
3434 __ Mov(x19, src_base);
3435 __ Mov(x20, src_base);
3436 __ Mov(x21, src_base);
3437 __ Mov(x22, src_base);
3438 __ Mov(x23, src_base);
3439 __ Mov(x24, src_base);
3440
3441 // Test loading whole register by element.
3442 for (int i = 15; i >= 0; i--) {
3443 __ Ld2(v0.B(), v1.B(), i, MemOperand(x17, 2, PostIndex));
3444 }
3445
3446 for (int i = 7; i >= 0; i--) {
3447 __ Ld2(v2.H(), v3.H(), i, MemOperand(x18, 4, PostIndex));
3448 }
3449
3450 for (int i = 3; i >= 0; i--) {
3451 __ Ld2(v4.S(), v5.S(), i, MemOperand(x19, 8, PostIndex));
3452 }
3453
3454 for (int i = 1; i >= 0; i--) {
3455 __ Ld2(v6.D(), v7.D(), i, MemOperand(x20, 16, PostIndex));
3456 }
3457
3458 // Test loading a single element into an initialised register.
3459 __ Mov(x25, 1);
3460 __ Mov(x4, x21);
3461 __ Ldr(q8, MemOperand(x4, 16, PostIndex));
3462 __ Ldr(q9, MemOperand(x4));
3463 __ Ld2(v8.B(), v9.B(), 4, MemOperand(x21, x25, PostIndex));
3464 __ Add(x25, x25, 1);
3465
3466 __ Mov(x5, x22);
3467 __ Ldr(q10, MemOperand(x5, 16, PostIndex));
3468 __ Ldr(q11, MemOperand(x5));
3469 __ Ld2(v10.H(), v11.H(), 3, MemOperand(x22, x25, PostIndex));
3470 __ Add(x25, x25, 1);
3471
3472 __ Mov(x6, x23);
3473 __ Ldr(q12, MemOperand(x6, 16, PostIndex));
3474 __ Ldr(q13, MemOperand(x6));
3475 __ Ld2(v12.S(), v13.S(), 2, MemOperand(x23, x25, PostIndex));
3476 __ Add(x25, x25, 1);
3477
3478 __ Mov(x7, x24);
3479 __ Ldr(q14, MemOperand(x7, 16, PostIndex));
3480 __ Ldr(q15, MemOperand(x7));
3481 __ Ld2(v14.D(), v15.D(), 1, MemOperand(x24, x25, PostIndex));
3482
3483 END();
3484
3485 RUN();
3486
3487 ASSERT_EQUAL_128(0x00020406080a0c0e, 0x10121416181a1c1e, q0);
3488 ASSERT_EQUAL_128(0x01030507090b0d0f, 0x11131517191b1d1f, q1);
3489 ASSERT_EQUAL_128(0x0100050409080d0c, 0x1110151419181d1c, q2);
3490 ASSERT_EQUAL_128(0x030207060b0a0f0e, 0x131217161b1a1f1e, q3);
3491 ASSERT_EQUAL_128(0x030201000b0a0908, 0x131211101b1a1918, q4);
3492 ASSERT_EQUAL_128(0x070605040f0e0d0c, 0x171615141f1e1d1c, q5);
3493 ASSERT_EQUAL_128(0x0706050403020100, 0x1716151413121110, q6);
3494 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1f1e1d1c1b1a1918, q7);
3495 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q8);
3496 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q9);
3497 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q10);
3498 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q11);
3499 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q12);
3500 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q13);
3501 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q14);
3502 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q15);
3503
3504
3505
3506
3507 ASSERT_EQUAL_64(src_base + 32, x17);
3508 ASSERT_EQUAL_64(src_base + 32, x18);
3509 ASSERT_EQUAL_64(src_base + 32, x19);
3510 ASSERT_EQUAL_64(src_base + 32, x20);
3511 ASSERT_EQUAL_64(src_base + 1, x21);
3512 ASSERT_EQUAL_64(src_base + 2, x22);
3513 ASSERT_EQUAL_64(src_base + 3, x23);
3514 ASSERT_EQUAL_64(src_base + 4, x24);
3515
3516 TEARDOWN();
3517}
3518
3519
3520TEST(neon_ld2_alllanes) {
3521 SETUP();
3522
3523 uint8_t src[64];
3524 for (unsigned i = 0; i < sizeof(src); i++) {
3525 src[i] = i;
3526 }
3527 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3528
3529 START();
3530 __ Mov(x17, src_base + 1);
3531 __ Mov(x18, 1);
3532 __ Ld2r(v0.V8B(), v1.V8B(), MemOperand(x17));
3533 __ Add(x17, x17, 2);
3534 __ Ld2r(v2.V16B(), v3.V16B(), MemOperand(x17));
3535 __ Add(x17, x17, 1);
3536 __ Ld2r(v4.V4H(), v5.V4H(), MemOperand(x17));
3537 __ Add(x17, x17, 1);
3538 __ Ld2r(v6.V8H(), v7.V8H(), MemOperand(x17));
3539 __ Add(x17, x17, 4);
3540 __ Ld2r(v8.V2S(), v9.V2S(), MemOperand(x17));
3541 __ Add(x17, x17, 1);
3542 __ Ld2r(v10.V4S(), v11.V4S(), MemOperand(x17));
3543 __ Add(x17, x17, 8);
3544 __ Ld2r(v12.V2D(), v13.V2D(), MemOperand(x17));
3545 END();
3546
3547 RUN();
3548
3549 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
3550 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
3551 ASSERT_EQUAL_128(0x0303030303030303, 0x0303030303030303, q2);
3552 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
3553 ASSERT_EQUAL_128(0x0000000000000000, 0x0504050405040504, q4);
3554 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q5);
3555 ASSERT_EQUAL_128(0x0605060506050605, 0x0605060506050605, q6);
3556 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q7);
3557 ASSERT_EQUAL_128(0x0000000000000000, 0x0c0b0a090c0b0a09, q8);
3558 ASSERT_EQUAL_128(0x0000000000000000, 0x100f0e0d100f0e0d, q9);
3559 ASSERT_EQUAL_128(0x0d0c0b0a0d0c0b0a, 0x0d0c0b0a0d0c0b0a, q10);
3560 ASSERT_EQUAL_128(0x11100f0e11100f0e, 0x11100f0e11100f0e, q11);
3561 ASSERT_EQUAL_128(0x1918171615141312, 0x1918171615141312, q12);
3562 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x21201f1e1d1c1b1a, q13);
3563
3564 TEARDOWN();
3565}
3566
3567
3568TEST(neon_ld2_alllanes_postindex) {
3569 SETUP();
3570
3571 uint8_t src[64];
3572 for (unsigned i = 0; i < sizeof(src); i++) {
3573 src[i] = i;
3574 }
3575 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3576
3577 START();
3578 __ Mov(x17, src_base + 1);
3579 __ Mov(x18, 1);
3580 __ Ld2r(v0.V8B(), v1.V8B(), MemOperand(x17, 2, PostIndex));
3581 __ Ld2r(v2.V16B(), v3.V16B(), MemOperand(x17, x18, PostIndex));
3582 __ Ld2r(v4.V4H(), v5.V4H(), MemOperand(x17, x18, PostIndex));
3583 __ Ld2r(v6.V8H(), v7.V8H(), MemOperand(x17, 4, PostIndex));
3584 __ Ld2r(v8.V2S(), v9.V2S(), MemOperand(x17, x18, PostIndex));
3585 __ Ld2r(v10.V4S(), v11.V4S(), MemOperand(x17, 8, PostIndex));
3586 __ Ld2r(v12.V2D(), v13.V2D(), MemOperand(x17, 16, PostIndex));
3587 END();
3588
3589 RUN();
3590
3591 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
3592 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
3593 ASSERT_EQUAL_128(0x0303030303030303, 0x0303030303030303, q2);
3594 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
3595 ASSERT_EQUAL_128(0x0000000000000000, 0x0504050405040504, q4);
3596 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q5);
3597 ASSERT_EQUAL_128(0x0605060506050605, 0x0605060506050605, q6);
3598 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q7);
3599 ASSERT_EQUAL_128(0x0000000000000000, 0x0c0b0a090c0b0a09, q8);
3600 ASSERT_EQUAL_128(0x0000000000000000, 0x100f0e0d100f0e0d, q9);
3601 ASSERT_EQUAL_128(0x0d0c0b0a0d0c0b0a, 0x0d0c0b0a0d0c0b0a, q10);
3602 ASSERT_EQUAL_128(0x11100f0e11100f0e, 0x11100f0e11100f0e, q11);
3603 ASSERT_EQUAL_128(0x1918171615141312, 0x1918171615141312, q12);
3604 ASSERT_EQUAL_128(0x21201f1e1d1c1b1a, 0x21201f1e1d1c1b1a, q13);
3605 ASSERT_EQUAL_64(src_base + 34, x17);
3606
3607 TEARDOWN();
3608}
3609
3610
3611TEST(neon_ld3_d) {
3612 SETUP();
3613
3614 uint8_t src[64 + 4];
3615 for (unsigned i = 0; i < sizeof(src); i++) {
3616 src[i] = i;
3617 }
3618 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3619
3620 START();
3621 __ Mov(x17, src_base);
3622 __ Ld3(v2.V8B(), v3.V8B(), v4.V8B(), MemOperand(x17));
3623 __ Add(x17, x17, 1);
3624 __ Ld3(v5.V8B(), v6.V8B(), v7.V8B(), MemOperand(x17));
3625 __ Add(x17, x17, 1);
3626 __ Ld3(v8.V4H(), v9.V4H(), v10.V4H(), MemOperand(x17));
3627 __ Add(x17, x17, 1);
3628 __ Ld3(v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x17));
3629 END();
3630
3631 RUN();
3632
3633 ASSERT_EQUAL_128(0, 0x15120f0c09060300, q2);
3634 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q3);
3635 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q4);
3636 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q5);
3637 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q6);
3638 ASSERT_EQUAL_128(0, 0x1815120f0c090603, q7);
3639 ASSERT_EQUAL_128(0, 0x15140f0e09080302, q8);
3640 ASSERT_EQUAL_128(0, 0x171611100b0a0504, q9);
3641 ASSERT_EQUAL_128(0, 0x191813120d0c0706, q10);
3642 ASSERT_EQUAL_128(0, 0x1211100f06050403, q31);
3643 ASSERT_EQUAL_128(0, 0x161514130a090807, q0);
3644 ASSERT_EQUAL_128(0, 0x1a1918170e0d0c0b, q1);
3645
3646 TEARDOWN();
3647}
3648
3649
3650TEST(neon_ld3_d_postindex) {
3651 SETUP();
3652
3653 uint8_t src[32 + 4];
3654 for (unsigned i = 0; i < sizeof(src); i++) {
3655 src[i] = i;
3656 }
3657 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3658
3659 START();
3660 __ Mov(x17, src_base);
3661 __ Mov(x18, src_base + 1);
3662 __ Mov(x19, src_base + 2);
3663 __ Mov(x20, src_base + 3);
3664 __ Mov(x21, src_base + 4);
3665 __ Mov(x22, 1);
3666 __ Ld3(v2.V8B(), v3.V8B(), v4.V8B(), MemOperand(x17, x22, PostIndex));
3667 __ Ld3(v5.V8B(), v6.V8B(), v7.V8B(), MemOperand(x18, 24, PostIndex));
3668 __ Ld3(v8.V4H(), v9.V4H(), v10.V4H(), MemOperand(x19, 24, PostIndex));
3669 __ Ld3(v11.V2S(), v12.V2S(), v13.V2S(), MemOperand(x20, 24, PostIndex));
3670 __ Ld3(v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x21, 24, PostIndex));
3671 END();
3672
3673 RUN();
3674
3675 ASSERT_EQUAL_128(0, 0x15120f0c09060300, q2);
3676 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q3);
3677 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q4);
3678 ASSERT_EQUAL_128(0, 0x1613100d0a070401, q5);
3679 ASSERT_EQUAL_128(0, 0x1714110e0b080502, q6);
3680 ASSERT_EQUAL_128(0, 0x1815120f0c090603, q7);
3681 ASSERT_EQUAL_128(0, 0x15140f0e09080302, q8);
3682 ASSERT_EQUAL_128(0, 0x171611100b0a0504, q9);
3683 ASSERT_EQUAL_128(0, 0x191813120d0c0706, q10);
3684 ASSERT_EQUAL_128(0, 0x1211100f06050403, q11);
3685 ASSERT_EQUAL_128(0, 0x161514130a090807, q12);
3686 ASSERT_EQUAL_128(0, 0x1a1918170e0d0c0b, q13);
3687 ASSERT_EQUAL_128(0, 0x1312111007060504, q31);
3688 ASSERT_EQUAL_128(0, 0x171615140b0a0908, q0);
3689 ASSERT_EQUAL_128(0, 0x1b1a19180f0e0d0c, q1);
3690
3691 ASSERT_EQUAL_64(src_base + 1, x17);
3692 ASSERT_EQUAL_64(src_base + 1 + 24, x18);
3693 ASSERT_EQUAL_64(src_base + 2 + 24, x19);
3694 ASSERT_EQUAL_64(src_base + 3 + 24, x20);
3695 ASSERT_EQUAL_64(src_base + 4 + 24, x21);
3696
3697 TEARDOWN();
3698}
3699
3700
3701TEST(neon_ld3_q) {
3702 SETUP();
3703
3704 uint8_t src[64 + 4];
3705 for (unsigned i = 0; i < sizeof(src); i++) {
3706 src[i] = i;
3707 }
3708 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3709
3710 START();
3711 __ Mov(x17, src_base);
3712 __ Ld3(v2.V16B(), v3.V16B(), v4.V16B(), MemOperand(x17));
3713 __ Add(x17, x17, 1);
3714 __ Ld3(v5.V16B(), v6.V16B(), v7.V16B(), MemOperand(x17));
3715 __ Add(x17, x17, 1);
3716 __ Ld3(v8.V8H(), v9.V8H(), v10.V8H(), MemOperand(x17));
3717 __ Add(x17, x17, 1);
3718 __ Ld3(v11.V4S(), v12.V4S(), v13.V4S(), MemOperand(x17));
3719 __ Add(x17, x17, 1);
3720 __ Ld3(v31.V2D(), v0.V2D(), v1.V2D(), MemOperand(x17));
3721 END();
3722
3723 RUN();
3724
3725 ASSERT_EQUAL_128(0x2d2a2724211e1b18, 0x15120f0c09060300, q2);
3726 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q3);
3727 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q4);
3728 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q5);
3729 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q6);
3730 ASSERT_EQUAL_128(0x302d2a2724211e1b, 0x1815120f0c090603, q7);
3731 ASSERT_EQUAL_128(0x2d2c272621201b1a, 0x15140f0e09080302, q8);
3732 ASSERT_EQUAL_128(0x2f2e292823221d1c, 0x171611100b0a0504, q9);
3733 ASSERT_EQUAL_128(0x31302b2a25241f1e, 0x191813120d0c0706, q10);
3734 ASSERT_EQUAL_128(0x2a2928271e1d1c1b, 0x1211100f06050403, q11);
3735 ASSERT_EQUAL_128(0x2e2d2c2b2221201f, 0x161514130a090807, q12);
3736 ASSERT_EQUAL_128(0x3231302f26252423, 0x1a1918170e0d0c0b, q13);
3737 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x0b0a090807060504, q31);
3738 ASSERT_EQUAL_128(0x2b2a292827262524, 0x131211100f0e0d0c, q0);
3739 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x1b1a191817161514, q1);
3740
3741 TEARDOWN();
3742}
3743
3744
3745TEST(neon_ld3_q_postindex) {
3746 SETUP();
3747
3748 uint8_t src[64 + 4];
3749 for (unsigned i = 0; i < sizeof(src); i++) {
3750 src[i] = i;
3751 }
3752 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3753
3754 START();
3755 __ Mov(x17, src_base);
3756 __ Mov(x18, src_base + 1);
3757 __ Mov(x19, src_base + 2);
3758 __ Mov(x20, src_base + 3);
3759 __ Mov(x21, src_base + 4);
3760 __ Mov(x22, 1);
3761
3762 __ Ld3(v2.V16B(), v3.V16B(), v4.V16B(), MemOperand(x17, x22, PostIndex));
3763 __ Ld3(v5.V16B(), v6.V16B(), v7.V16B(), MemOperand(x18, 48, PostIndex));
3764 __ Ld3(v8.V8H(), v9.V8H(), v10.V8H(), MemOperand(x19, 48, PostIndex));
3765 __ Ld3(v11.V4S(), v12.V4S(), v13.V4S(), MemOperand(x20, 48, PostIndex));
3766 __ Ld3(v31.V2D(), v0.V2D(), v1.V2D(), MemOperand(x21, 48, PostIndex));
3767 END();
3768
3769 RUN();
3770
3771 ASSERT_EQUAL_128(0x2d2a2724211e1b18, 0x15120f0c09060300, q2);
3772 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q3);
3773 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q4);
3774 ASSERT_EQUAL_128(0x2e2b2825221f1c19, 0x1613100d0a070401, q5);
3775 ASSERT_EQUAL_128(0x2f2c292623201d1a, 0x1714110e0b080502, q6);
3776 ASSERT_EQUAL_128(0x302d2a2724211e1b, 0x1815120f0c090603, q7);
3777 ASSERT_EQUAL_128(0x2d2c272621201b1a, 0x15140f0e09080302, q8);
3778 ASSERT_EQUAL_128(0x2f2e292823221d1c, 0x171611100b0a0504, q9);
3779 ASSERT_EQUAL_128(0x31302b2a25241f1e, 0x191813120d0c0706, q10);
3780 ASSERT_EQUAL_128(0x2a2928271e1d1c1b, 0x1211100f06050403, q11);
3781 ASSERT_EQUAL_128(0x2e2d2c2b2221201f, 0x161514130a090807, q12);
3782 ASSERT_EQUAL_128(0x3231302f26252423, 0x1a1918170e0d0c0b, q13);
3783 ASSERT_EQUAL_128(0x232221201f1e1d1c, 0x0b0a090807060504, q31);
3784 ASSERT_EQUAL_128(0x2b2a292827262524, 0x131211100f0e0d0c, q0);
3785 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x1b1a191817161514, q1);
3786
3787 ASSERT_EQUAL_64(src_base + 1, x17);
3788 ASSERT_EQUAL_64(src_base + 1 + 48, x18);
3789 ASSERT_EQUAL_64(src_base + 2 + 48, x19);
3790 ASSERT_EQUAL_64(src_base + 3 + 48, x20);
3791 ASSERT_EQUAL_64(src_base + 4 + 48, x21);
3792
3793 TEARDOWN();
3794}
3795
3796
3797TEST(neon_ld3_lane) {
3798 SETUP();
3799
3800 uint8_t src[64];
3801 for (unsigned i = 0; i < sizeof(src); i++) {
3802 src[i] = i;
3803 }
3804 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3805
3806 START();
3807
3808 // Test loading whole register by element.
3809 __ Mov(x17, src_base);
3810 for (int i = 15; i >= 0; i--) {
3811 __ Ld3(v0.B(), v1.B(), v2.B(), i, MemOperand(x17));
3812 __ Add(x17, x17, 1);
3813 }
3814
3815 __ Mov(x17, src_base);
3816 for (int i = 7; i >= 0; i--) {
3817 __ Ld3(v3.H(), v4.H(), v5.H(), i, MemOperand(x17));
3818 __ Add(x17, x17, 1);
3819 }
3820
3821 __ Mov(x17, src_base);
3822 for (int i = 3; i >= 0; i--) {
3823 __ Ld3(v6.S(), v7.S(), v8.S(), i, MemOperand(x17));
3824 __ Add(x17, x17, 1);
3825 }
3826
3827 __ Mov(x17, src_base);
3828 for (int i = 1; i >= 0; i--) {
3829 __ Ld3(v9.D(), v10.D(), v11.D(), i, MemOperand(x17));
3830 __ Add(x17, x17, 1);
3831 }
3832
3833 // Test loading a single element into an initialised register.
3834 __ Mov(x17, src_base);
3835 __ Mov(x4, x17);
3836 __ Ldr(q12, MemOperand(x4, 16, PostIndex));
3837 __ Ldr(q13, MemOperand(x4, 16, PostIndex));
3838 __ Ldr(q14, MemOperand(x4));
3839 __ Ld3(v12.B(), v13.B(), v14.B(), 4, MemOperand(x17));
3840 __ Mov(x5, x17);
3841 __ Ldr(q15, MemOperand(x5, 16, PostIndex));
3842 __ Ldr(q16, MemOperand(x5, 16, PostIndex));
3843 __ Ldr(q17, MemOperand(x5));
3844 __ Ld3(v15.H(), v16.H(), v17.H(), 3, MemOperand(x17));
3845 __ Mov(x6, x17);
3846 __ Ldr(q18, MemOperand(x6, 16, PostIndex));
3847 __ Ldr(q19, MemOperand(x6, 16, PostIndex));
3848 __ Ldr(q20, MemOperand(x6));
3849 __ Ld3(v18.S(), v19.S(), v20.S(), 2, MemOperand(x17));
3850 __ Mov(x7, x17);
3851 __ Ldr(q21, MemOperand(x7, 16, PostIndex));
3852 __ Ldr(q22, MemOperand(x7, 16, PostIndex));
3853 __ Ldr(q23, MemOperand(x7));
3854 __ Ld3(v21.D(), v22.D(), v23.D(), 1, MemOperand(x17));
3855
3856 END();
3857
3858 RUN();
3859
3860 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
3861 ASSERT_EQUAL_128(0x0102030405060708, 0x090a0b0c0d0e0f10, q1);
3862 ASSERT_EQUAL_128(0x0203040506070809, 0x0a0b0c0d0e0f1011, q2);
3863 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q3);
3864 ASSERT_EQUAL_128(0x0302040305040605, 0x0706080709080a09, q4);
3865 ASSERT_EQUAL_128(0x0504060507060807, 0x09080a090b0a0c0b, q5);
3866 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q6);
3867 ASSERT_EQUAL_128(0x0706050408070605, 0x090807060a090807, q7);
3868 ASSERT_EQUAL_128(0x0b0a09080c0b0a09, 0x0d0c0b0a0e0d0c0b, q8);
3869 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q9);
3870 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x100f0e0d0c0b0a09, q10);
3871 ASSERT_EQUAL_128(0x1716151413121110, 0x1817161514131211, q11);
3872 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q12);
3873 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q13);
3874 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q14);
3875 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q15);
3876 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q16);
3877 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q17);
3878
3879 TEARDOWN();
3880}
3881
3882
3883TEST(neon_ld3_lane_postindex) {
3884 SETUP();
3885
3886 uint8_t src[64];
3887 for (unsigned i = 0; i < sizeof(src); i++) {
3888 src[i] = i;
3889 }
3890 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3891
3892 START();
3893
3894 // Test loading whole register by element.
3895 __ Mov(x17, src_base);
3896 __ Mov(x18, src_base);
3897 __ Mov(x19, src_base);
3898 __ Mov(x20, src_base);
3899 __ Mov(x21, src_base);
3900 __ Mov(x22, src_base);
3901 __ Mov(x23, src_base);
3902 __ Mov(x24, src_base);
3903 for (int i = 15; i >= 0; i--) {
3904 __ Ld3(v0.B(), v1.B(), v2.B(), i, MemOperand(x17, 3, PostIndex));
3905 }
3906
3907 for (int i = 7; i >= 0; i--) {
3908 __ Ld3(v3.H(), v4.H(), v5.H(), i, MemOperand(x18, 6, PostIndex));
3909 }
3910
3911 for (int i = 3; i >= 0; i--) {
3912 __ Ld3(v6.S(), v7.S(), v8.S(), i, MemOperand(x19, 12, PostIndex));
3913 }
3914
3915 for (int i = 1; i >= 0; i--) {
3916 __ Ld3(v9.D(), v10.D(), v11.D(), i, MemOperand(x20, 24, PostIndex));
3917 }
3918
3919
3920 // Test loading a single element into an initialised register.
3921 __ Mov(x25, 1);
3922 __ Mov(x4, x21);
3923 __ Ldr(q12, MemOperand(x4, 16, PostIndex));
3924 __ Ldr(q13, MemOperand(x4, 16, PostIndex));
3925 __ Ldr(q14, MemOperand(x4));
3926 __ Ld3(v12.B(), v13.B(), v14.B(), 4, MemOperand(x21, x25, PostIndex));
3927 __ Add(x25, x25, 1);
3928
3929 __ Mov(x5, x22);
3930 __ Ldr(q15, MemOperand(x5, 16, PostIndex));
3931 __ Ldr(q16, MemOperand(x5, 16, PostIndex));
3932 __ Ldr(q17, MemOperand(x5));
3933 __ Ld3(v15.H(), v16.H(), v17.H(), 3, MemOperand(x22, x25, PostIndex));
3934 __ Add(x25, x25, 1);
3935
3936 __ Mov(x6, x23);
3937 __ Ldr(q18, MemOperand(x6, 16, PostIndex));
3938 __ Ldr(q19, MemOperand(x6, 16, PostIndex));
3939 __ Ldr(q20, MemOperand(x6));
3940 __ Ld3(v18.S(), v19.S(), v20.S(), 2, MemOperand(x23, x25, PostIndex));
3941 __ Add(x25, x25, 1);
3942
3943 __ Mov(x7, x24);
3944 __ Ldr(q21, MemOperand(x7, 16, PostIndex));
3945 __ Ldr(q22, MemOperand(x7, 16, PostIndex));
3946 __ Ldr(q23, MemOperand(x7));
3947 __ Ld3(v21.D(), v22.D(), v23.D(), 1, MemOperand(x24, x25, PostIndex));
3948
3949 END();
3950
3951 RUN();
3952
3953 ASSERT_EQUAL_128(0x000306090c0f1215, 0x181b1e2124272a2d, q0);
3954 ASSERT_EQUAL_128(0x0104070a0d101316, 0x191c1f2225282b2e, q1);
3955 ASSERT_EQUAL_128(0x0205080b0e111417, 0x1a1d202326292c2f, q2);
3956 ASSERT_EQUAL_128(0x010007060d0c1312, 0x19181f1e25242b2a, q3);
3957 ASSERT_EQUAL_128(0x030209080f0e1514, 0x1b1a212027262d2c, q4);
3958 ASSERT_EQUAL_128(0x05040b0a11101716, 0x1d1c232229282f2e, q5);
3959 ASSERT_EQUAL_128(0x030201000f0e0d0c, 0x1b1a191827262524, q6);
3960 ASSERT_EQUAL_128(0x0706050413121110, 0x1f1e1d1c2b2a2928, q7);
3961 ASSERT_EQUAL_128(0x0b0a090817161514, 0x232221202f2e2d2c, q8);
3962 ASSERT_EQUAL_128(0x0706050403020100, 0x1f1e1d1c1b1a1918, q9);
3963 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x2726252423222120, q10);
3964 ASSERT_EQUAL_128(0x1716151413121110, 0x2f2e2d2c2b2a2928, q11);
3965 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q12);
3966 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q13);
3967 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q14);
3968 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q15);
3969 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q16);
3970 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q17);
3971 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q18);
3972 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q19);
3973 ASSERT_EQUAL_128(0x2f2e2d2c0b0a0908, 0x2726252423222120, q20);
3974 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q21);
3975 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q22);
3976 ASSERT_EQUAL_128(0x1716151413121110, 0x2726252423222120, q23);
3977
3978 ASSERT_EQUAL_64(src_base + 48, x17);
3979 ASSERT_EQUAL_64(src_base + 48, x18);
3980 ASSERT_EQUAL_64(src_base + 48, x19);
3981 ASSERT_EQUAL_64(src_base + 48, x20);
3982 ASSERT_EQUAL_64(src_base + 1, x21);
3983 ASSERT_EQUAL_64(src_base + 2, x22);
3984 ASSERT_EQUAL_64(src_base + 3, x23);
3985 ASSERT_EQUAL_64(src_base + 4, x24);
3986
3987 TEARDOWN();
3988}
3989
3990
3991TEST(neon_ld3_alllanes) {
3992 SETUP();
3993
3994 uint8_t src[64];
3995 for (unsigned i = 0; i < sizeof(src); i++) {
3996 src[i] = i;
3997 }
3998 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3999
4000 START();
4001 __ Mov(x17, src_base + 1);
4002 __ Mov(x18, 1);
4003 __ Ld3r(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x17));
4004 __ Add(x17, x17, 3);
4005 __ Ld3r(v3.V16B(), v4.V16B(), v5.V16B(), MemOperand(x17));
4006 __ Add(x17, x17, 1);
4007 __ Ld3r(v6.V4H(), v7.V4H(), v8.V4H(), MemOperand(x17));
4008 __ Add(x17, x17, 1);
4009 __ Ld3r(v9.V8H(), v10.V8H(), v11.V8H(), MemOperand(x17));
4010 __ Add(x17, x17, 6);
4011 __ Ld3r(v12.V2S(), v13.V2S(), v14.V2S(), MemOperand(x17));
4012 __ Add(x17, x17, 1);
4013 __ Ld3r(v15.V4S(), v16.V4S(), v17.V4S(), MemOperand(x17));
4014 __ Add(x17, x17, 12);
4015 __ Ld3r(v18.V2D(), v19.V2D(), v20.V2D(), MemOperand(x17));
4016 END();
4017
4018 RUN();
4019
4020 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4021 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4022 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4023 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
4024 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4025 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4026 ASSERT_EQUAL_128(0x0000000000000000, 0x0605060506050605, q6);
4027 ASSERT_EQUAL_128(0x0000000000000000, 0x0807080708070807, q7);
4028 ASSERT_EQUAL_128(0x0000000000000000, 0x0a090a090a090a09, q8);
4029 ASSERT_EQUAL_128(0x0706070607060706, 0x0706070607060706, q9);
4030 ASSERT_EQUAL_128(0x0908090809080908, 0x0908090809080908, q10);
4031 ASSERT_EQUAL_128(0x0b0a0b0a0b0a0b0a, 0x0b0a0b0a0b0a0b0a, q11);
4032 ASSERT_EQUAL_128(0x0000000000000000, 0x0f0e0d0c0f0e0d0c, q12);
4033 ASSERT_EQUAL_128(0x0000000000000000, 0x1312111013121110, q13);
4034 ASSERT_EQUAL_128(0x0000000000000000, 0x1716151417161514, q14);
4035 ASSERT_EQUAL_128(0x100f0e0d100f0e0d, 0x100f0e0d100f0e0d, q15);
4036 ASSERT_EQUAL_128(0x1413121114131211, 0x1413121114131211, q16);
4037 ASSERT_EQUAL_128(0x1817161518171615, 0x1817161518171615, q17);
4038 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x201f1e1d1c1b1a19, q18);
4039 ASSERT_EQUAL_128(0x2827262524232221, 0x2827262524232221, q19);
4040 ASSERT_EQUAL_128(0x302f2e2d2c2b2a29, 0x302f2e2d2c2b2a29, q20);
4041
4042 TEARDOWN();
4043}
4044
4045
4046TEST(neon_ld3_alllanes_postindex) {
4047 SETUP();
4048
4049 uint8_t src[64];
4050 for (unsigned i = 0; i < sizeof(src); i++) {
4051 src[i] = i;
4052 }
4053 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4054 __ Mov(x17, src_base + 1);
4055 __ Mov(x18, 1);
4056
4057 START();
4058 __ Mov(x17, src_base + 1);
4059 __ Mov(x18, 1);
4060 __ Ld3r(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x17, 3, PostIndex));
4061 __ Ld3r(v3.V16B(), v4.V16B(), v5.V16B(), MemOperand(x17, x18, PostIndex));
4062 __ Ld3r(v6.V4H(), v7.V4H(), v8.V4H(), MemOperand(x17, x18, PostIndex));
4063 __ Ld3r(v9.V8H(), v10.V8H(), v11.V8H(), MemOperand(x17, 6, PostIndex));
4064 __ Ld3r(v12.V2S(), v13.V2S(), v14.V2S(), MemOperand(x17, x18, PostIndex));
4065 __ Ld3r(v15.V4S(), v16.V4S(), v17.V4S(), MemOperand(x17, 12, PostIndex));
4066 __ Ld3r(v18.V2D(), v19.V2D(), v20.V2D(), MemOperand(x17, 24, PostIndex));
4067 END();
4068
4069 RUN();
4070
4071 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4072 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4073 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4074 ASSERT_EQUAL_128(0x0404040404040404, 0x0404040404040404, q3);
4075 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4076 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4077 ASSERT_EQUAL_128(0x0000000000000000, 0x0605060506050605, q6);
4078 ASSERT_EQUAL_128(0x0000000000000000, 0x0807080708070807, q7);
4079 ASSERT_EQUAL_128(0x0000000000000000, 0x0a090a090a090a09, q8);
4080 ASSERT_EQUAL_128(0x0706070607060706, 0x0706070607060706, q9);
4081 ASSERT_EQUAL_128(0x0908090809080908, 0x0908090809080908, q10);
4082 ASSERT_EQUAL_128(0x0b0a0b0a0b0a0b0a, 0x0b0a0b0a0b0a0b0a, q11);
4083 ASSERT_EQUAL_128(0x0000000000000000, 0x0f0e0d0c0f0e0d0c, q12);
4084 ASSERT_EQUAL_128(0x0000000000000000, 0x1312111013121110, q13);
4085 ASSERT_EQUAL_128(0x0000000000000000, 0x1716151417161514, q14);
4086 ASSERT_EQUAL_128(0x100f0e0d100f0e0d, 0x100f0e0d100f0e0d, q15);
4087 ASSERT_EQUAL_128(0x1413121114131211, 0x1413121114131211, q16);
4088 ASSERT_EQUAL_128(0x1817161518171615, 0x1817161518171615, q17);
4089 ASSERT_EQUAL_128(0x201f1e1d1c1b1a19, 0x201f1e1d1c1b1a19, q18);
4090 ASSERT_EQUAL_128(0x2827262524232221, 0x2827262524232221, q19);
4091 ASSERT_EQUAL_128(0x302f2e2d2c2b2a29, 0x302f2e2d2c2b2a29, q20);
4092
4093 TEARDOWN();
4094}
4095
4096
4097TEST(neon_ld4_d) {
4098 SETUP();
4099
4100 uint8_t src[64 + 4];
4101 for (unsigned i = 0; i < sizeof(src); i++) {
4102 src[i] = i;
4103 }
4104 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4105
4106 START();
4107 __ Mov(x17, src_base);
4108 __ Ld4(v2.V8B(), v3.V8B(), v4.V8B(), v5.V8B(), MemOperand(x17));
4109 __ Add(x17, x17, 1);
4110 __ Ld4(v6.V8B(), v7.V8B(), v8.V8B(), v9.V8B(), MemOperand(x17));
4111 __ Add(x17, x17, 1);
4112 __ Ld4(v10.V4H(), v11.V4H(), v12.V4H(), v13.V4H(), MemOperand(x17));
4113 __ Add(x17, x17, 1);
4114 __ Ld4(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(), MemOperand(x17));
4115 END();
4116
4117 RUN();
4118
4119 ASSERT_EQUAL_128(0, 0x1c1814100c080400, q2);
4120 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q3);
4121 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q4);
4122 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q5);
4123 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q6);
4124 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q7);
4125 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q8);
4126 ASSERT_EQUAL_128(0, 0x201c1814100c0804, q9);
4127 ASSERT_EQUAL_128(0, 0x1b1a13120b0a0302, q10);
4128 ASSERT_EQUAL_128(0, 0x1d1c15140d0c0504, q11);
4129 ASSERT_EQUAL_128(0, 0x1f1e17160f0e0706, q12);
4130 ASSERT_EQUAL_128(0, 0x2120191811100908, q13);
4131 ASSERT_EQUAL_128(0, 0x1615141306050403, q30);
4132 ASSERT_EQUAL_128(0, 0x1a1918170a090807, q31);
4133 ASSERT_EQUAL_128(0, 0x1e1d1c1b0e0d0c0b, q0);
4134 ASSERT_EQUAL_128(0, 0x2221201f1211100f, q1);
4135
4136 TEARDOWN();
4137}
4138
4139
4140TEST(neon_ld4_d_postindex) {
4141 SETUP();
4142
4143 uint8_t src[32 + 4];
4144 for (unsigned i = 0; i < sizeof(src); i++) {
4145 src[i] = i;
4146 }
4147 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4148
4149 START();
4150 __ Mov(x17, src_base);
4151 __ Mov(x18, src_base + 1);
4152 __ Mov(x19, src_base + 2);
4153 __ Mov(x20, src_base + 3);
4154 __ Mov(x21, src_base + 4);
4155 __ Mov(x22, 1);
4156 __ Ld4(v2.V8B(), v3.V8B(), v4.V8B(), v5.V8B(),
4157 MemOperand(x17, x22, PostIndex));
4158 __ Ld4(v6.V8B(), v7.V8B(), v8.V8B(), v9.V8B(),
4159 MemOperand(x18, 32, PostIndex));
4160 __ Ld4(v10.V4H(), v11.V4H(), v12.V4H(), v13.V4H(),
4161 MemOperand(x19, 32, PostIndex));
4162 __ Ld4(v14.V2S(), v15.V2S(), v16.V2S(), v17.V2S(),
4163 MemOperand(x20, 32, PostIndex));
4164 __ Ld4(v30.V2S(), v31.V2S(), v0.V2S(), v1.V2S(),
4165 MemOperand(x21, 32, PostIndex));
4166 END();
4167
4168 RUN();
4169
4170 ASSERT_EQUAL_128(0, 0x1c1814100c080400, q2);
4171 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q3);
4172 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q4);
4173 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q5);
4174 ASSERT_EQUAL_128(0, 0x1d1915110d090501, q6);
4175 ASSERT_EQUAL_128(0, 0x1e1a16120e0a0602, q7);
4176 ASSERT_EQUAL_128(0, 0x1f1b17130f0b0703, q8);
4177 ASSERT_EQUAL_128(0, 0x201c1814100c0804, q9);
4178 ASSERT_EQUAL_128(0, 0x1b1a13120b0a0302, q10);
4179 ASSERT_EQUAL_128(0, 0x1d1c15140d0c0504, q11);
4180 ASSERT_EQUAL_128(0, 0x1f1e17160f0e0706, q12);
4181 ASSERT_EQUAL_128(0, 0x2120191811100908, q13);
4182 ASSERT_EQUAL_128(0, 0x1615141306050403, q14);
4183 ASSERT_EQUAL_128(0, 0x1a1918170a090807, q15);
4184 ASSERT_EQUAL_128(0, 0x1e1d1c1b0e0d0c0b, q16);
4185 ASSERT_EQUAL_128(0, 0x2221201f1211100f, q17);
4186 ASSERT_EQUAL_128(0, 0x1716151407060504, q30);
4187 ASSERT_EQUAL_128(0, 0x1b1a19180b0a0908, q31);
4188 ASSERT_EQUAL_128(0, 0x1f1e1d1c0f0e0d0c, q0);
4189 ASSERT_EQUAL_128(0, 0x2322212013121110, q1);
4190
4191
4192 ASSERT_EQUAL_64(src_base + 1, x17);
4193 ASSERT_EQUAL_64(src_base + 1 + 32, x18);
4194 ASSERT_EQUAL_64(src_base + 2 + 32, x19);
4195 ASSERT_EQUAL_64(src_base + 3 + 32, x20);
4196 ASSERT_EQUAL_64(src_base + 4 + 32, x21);
4197 TEARDOWN();
4198}
4199
4200
4201TEST(neon_ld4_q) {
4202 SETUP();
4203
4204 uint8_t src[64 + 4];
4205 for (unsigned i = 0; i < sizeof(src); i++) {
4206 src[i] = i;
4207 }
4208 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4209
4210 START();
4211 __ Mov(x17, src_base);
4212 __ Ld4(v2.V16B(), v3.V16B(), v4.V16B(), v5.V16B(), MemOperand(x17));
4213 __ Add(x17, x17, 1);
4214 __ Ld4(v6.V16B(), v7.V16B(), v8.V16B(), v9.V16B(), MemOperand(x17));
4215 __ Add(x17, x17, 1);
4216 __ Ld4(v10.V8H(), v11.V8H(), v12.V8H(), v13.V8H(), MemOperand(x17));
4217 __ Add(x17, x17, 1);
4218 __ Ld4(v14.V4S(), v15.V4S(), v16.V4S(), v17.V4S(), MemOperand(x17));
4219 __ Add(x17, x17, 1);
4220 __ Ld4(v18.V2D(), v19.V2D(), v20.V2D(), v21.V2D(), MemOperand(x17));
4221 END();
4222
4223 RUN();
4224
4225 ASSERT_EQUAL_128(0x3c3834302c282420, 0x1c1814100c080400, q2);
4226 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q3);
4227 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q4);
4228 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q5);
4229 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q6);
4230 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q7);
4231 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q8);
4232 ASSERT_EQUAL_128(0x403c3834302c2824, 0x201c1814100c0804, q9);
4233 ASSERT_EQUAL_128(0x3b3a33322b2a2322, 0x1b1a13120b0a0302, q10);
4234 ASSERT_EQUAL_128(0x3d3c35342d2c2524, 0x1d1c15140d0c0504, q11);
4235 ASSERT_EQUAL_128(0x3f3e37362f2e2726, 0x1f1e17160f0e0706, q12);
4236 ASSERT_EQUAL_128(0x4140393831302928, 0x2120191811100908, q13);
4237 ASSERT_EQUAL_128(0x3635343326252423, 0x1615141306050403, q14);
4238 ASSERT_EQUAL_128(0x3a3938372a292827, 0x1a1918170a090807, q15);
4239 ASSERT_EQUAL_128(0x3e3d3c3b2e2d2c2b, 0x1e1d1c1b0e0d0c0b, q16);
4240 ASSERT_EQUAL_128(0x4241403f3231302f, 0x2221201f1211100f, q17);
4241 ASSERT_EQUAL_128(0x2b2a292827262524, 0x0b0a090807060504, q18);
4242 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x131211100f0e0d0c, q19);
4243 ASSERT_EQUAL_128(0x3b3a393837363534, 0x1b1a191817161514, q20);
4244 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x232221201f1e1d1c, q21);
4245 TEARDOWN();
4246}
4247
4248
4249TEST(neon_ld4_q_postindex) {
4250 SETUP();
4251
4252 uint8_t src[64 + 4];
4253 for (unsigned i = 0; i < sizeof(src); i++) {
4254 src[i] = i;
4255 }
4256 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4257
4258 START();
4259 __ Mov(x17, src_base);
4260 __ Mov(x18, src_base + 1);
4261 __ Mov(x19, src_base + 2);
4262 __ Mov(x20, src_base + 3);
4263 __ Mov(x21, src_base + 4);
4264 __ Mov(x22, 1);
4265
4266 __ Ld4(v2.V16B(), v3.V16B(), v4.V16B(), v5.V16B(),
4267 MemOperand(x17, x22, PostIndex));
4268 __ Ld4(v6.V16B(), v7.V16B(), v8.V16B(), v9.V16B(),
4269 MemOperand(x18, 64, PostIndex));
4270 __ Ld4(v10.V8H(), v11.V8H(), v12.V8H(), v13.V8H(),
4271 MemOperand(x19, 64, PostIndex));
4272 __ Ld4(v14.V4S(), v15.V4S(), v16.V4S(), v17.V4S(),
4273 MemOperand(x20, 64, PostIndex));
4274 __ Ld4(v30.V2D(), v31.V2D(), v0.V2D(), v1.V2D(),
4275 MemOperand(x21, 64, PostIndex));
4276 END();
4277
4278 RUN();
4279
4280 ASSERT_EQUAL_128(0x3c3834302c282420, 0x1c1814100c080400, q2);
4281 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q3);
4282 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q4);
4283 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q5);
4284 ASSERT_EQUAL_128(0x3d3935312d292521, 0x1d1915110d090501, q6);
4285 ASSERT_EQUAL_128(0x3e3a36322e2a2622, 0x1e1a16120e0a0602, q7);
4286 ASSERT_EQUAL_128(0x3f3b37332f2b2723, 0x1f1b17130f0b0703, q8);
4287 ASSERT_EQUAL_128(0x403c3834302c2824, 0x201c1814100c0804, q9);
4288 ASSERT_EQUAL_128(0x3b3a33322b2a2322, 0x1b1a13120b0a0302, q10);
4289 ASSERT_EQUAL_128(0x3d3c35342d2c2524, 0x1d1c15140d0c0504, q11);
4290 ASSERT_EQUAL_128(0x3f3e37362f2e2726, 0x1f1e17160f0e0706, q12);
4291 ASSERT_EQUAL_128(0x4140393831302928, 0x2120191811100908, q13);
4292 ASSERT_EQUAL_128(0x3635343326252423, 0x1615141306050403, q14);
4293 ASSERT_EQUAL_128(0x3a3938372a292827, 0x1a1918170a090807, q15);
4294 ASSERT_EQUAL_128(0x3e3d3c3b2e2d2c2b, 0x1e1d1c1b0e0d0c0b, q16);
4295 ASSERT_EQUAL_128(0x4241403f3231302f, 0x2221201f1211100f, q17);
4296 ASSERT_EQUAL_128(0x2b2a292827262524, 0x0b0a090807060504, q30);
4297 ASSERT_EQUAL_128(0x333231302f2e2d2c, 0x131211100f0e0d0c, q31);
4298 ASSERT_EQUAL_128(0x3b3a393837363534, 0x1b1a191817161514, q0);
4299 ASSERT_EQUAL_128(0x434241403f3e3d3c, 0x232221201f1e1d1c, q1);
4300
4301
4302
4303 ASSERT_EQUAL_64(src_base + 1, x17);
4304 ASSERT_EQUAL_64(src_base + 1 + 64, x18);
4305 ASSERT_EQUAL_64(src_base + 2 + 64, x19);
4306 ASSERT_EQUAL_64(src_base + 3 + 64, x20);
4307 ASSERT_EQUAL_64(src_base + 4 + 64, x21);
4308
4309 TEARDOWN();
4310}
4311
4312
4313TEST(neon_ld4_lane) {
4314 SETUP();
4315
4316 uint8_t src[64];
4317 for (unsigned i = 0; i < sizeof(src); i++) {
4318 src[i] = i;
4319 }
4320 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4321
4322 START();
4323
4324 // Test loading whole register by element.
4325 __ Mov(x17, src_base);
4326 for (int i = 15; i >= 0; i--) {
4327 __ Ld4(v0.B(), v1.B(), v2.B(), v3.B(), i, MemOperand(x17));
4328 __ Add(x17, x17, 1);
4329 }
4330
4331 __ Mov(x17, src_base);
4332 for (int i = 7; i >= 0; i--) {
4333 __ Ld4(v4.H(), v5.H(), v6.H(), v7.H(), i, MemOperand(x17));
4334 __ Add(x17, x17, 1);
4335 }
4336
4337 __ Mov(x17, src_base);
4338 for (int i = 3; i >= 0; i--) {
4339 __ Ld4(v8.S(), v9.S(), v10.S(), v11.S(), i, MemOperand(x17));
4340 __ Add(x17, x17, 1);
4341 }
4342
4343 __ Mov(x17, src_base);
4344 for (int i = 1; i >= 0; i--) {
4345 __ Ld4(v12.D(), v13.D(), v14.D(), v15.D(), i, MemOperand(x17));
4346 __ Add(x17, x17, 1);
4347 }
4348
4349 // Test loading a single element into an initialised register.
4350 __ Mov(x17, src_base);
4351 __ Mov(x4, x17);
4352 __ Ldr(q16, MemOperand(x4, 16, PostIndex));
4353 __ Ldr(q17, MemOperand(x4, 16, PostIndex));
4354 __ Ldr(q18, MemOperand(x4, 16, PostIndex));
4355 __ Ldr(q19, MemOperand(x4));
4356 __ Ld4(v16.B(), v17.B(), v18.B(), v19.B(), 4, MemOperand(x17));
4357
4358 __ Mov(x5, x17);
4359 __ Ldr(q20, MemOperand(x5, 16, PostIndex));
4360 __ Ldr(q21, MemOperand(x5, 16, PostIndex));
4361 __ Ldr(q22, MemOperand(x5, 16, PostIndex));
4362 __ Ldr(q23, MemOperand(x5));
4363 __ Ld4(v20.H(), v21.H(), v22.H(), v23.H(), 3, MemOperand(x17));
4364
4365 __ Mov(x6, x17);
4366 __ Ldr(q24, MemOperand(x6, 16, PostIndex));
4367 __ Ldr(q25, MemOperand(x6, 16, PostIndex));
4368 __ Ldr(q26, MemOperand(x6, 16, PostIndex));
4369 __ Ldr(q27, MemOperand(x6));
4370 __ Ld4(v24.S(), v25.S(), v26.S(), v27.S(), 2, MemOperand(x17));
4371
4372 __ Mov(x7, x17);
4373 __ Ldr(q28, MemOperand(x7, 16, PostIndex));
4374 __ Ldr(q29, MemOperand(x7, 16, PostIndex));
4375 __ Ldr(q30, MemOperand(x7, 16, PostIndex));
4376 __ Ldr(q31, MemOperand(x7));
4377 __ Ld4(v28.D(), v29.D(), v30.D(), v31.D(), 1, MemOperand(x17));
4378
4379 END();
4380
4381 RUN();
4382
4383 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
4384 ASSERT_EQUAL_128(0x0102030405060708, 0x090a0b0c0d0e0f10, q1);
4385 ASSERT_EQUAL_128(0x0203040506070809, 0x0a0b0c0d0e0f1011, q2);
4386 ASSERT_EQUAL_128(0x030405060708090a, 0x0b0c0d0e0f101112, q3);
4387 ASSERT_EQUAL_128(0x0100020103020403, 0x0504060507060807, q4);
4388 ASSERT_EQUAL_128(0x0302040305040605, 0x0706080709080a09, q5);
4389 ASSERT_EQUAL_128(0x0504060507060807, 0x09080a090b0a0c0b, q6);
4390 ASSERT_EQUAL_128(0x0706080709080a09, 0x0b0a0c0b0d0c0e0d, q7);
4391 ASSERT_EQUAL_128(0x0302010004030201, 0x0504030206050403, q8);
4392 ASSERT_EQUAL_128(0x0706050408070605, 0x090807060a090807, q9);
4393 ASSERT_EQUAL_128(0x0b0a09080c0b0a09, 0x0d0c0b0a0e0d0c0b, q10);
4394 ASSERT_EQUAL_128(0x0f0e0d0c100f0e0d, 0x11100f0e1211100f, q11);
4395 ASSERT_EQUAL_128(0x0706050403020100, 0x0807060504030201, q12);
4396 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x100f0e0d0c0b0a09, q13);
4397 ASSERT_EQUAL_128(0x1716151413121110, 0x1817161514131211, q14);
4398 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x201f1e1d1c1b1a19, q15);
4399 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q16);
4400 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q17);
4401 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q18);
4402 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736350333323130, q19);
4403 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q20);
4404 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q21);
4405 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q22);
4406 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x0706353433323130, q23);
4407 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q24);
4408 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q25);
4409 ASSERT_EQUAL_128(0x2f2e2d2c0b0a0908, 0x2726252423222120, q26);
4410 ASSERT_EQUAL_128(0x3f3e3d3c0f0e0d0c, 0x3736353433323130, q27);
4411 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q28);
4412 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q29);
4413 ASSERT_EQUAL_128(0x1716151413121110, 0x2726252423222120, q30);
4414 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x3736353433323130, q31);
4415
4416 TEARDOWN();
4417}
4418
4419
4420
4421TEST(neon_ld4_lane_postindex) {
4422 SETUP();
4423
4424 uint8_t src[64];
4425 for (unsigned i = 0; i < sizeof(src); i++) {
4426 src[i] = i;
4427 }
4428 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4429
4430 START();
4431
4432 // Test loading whole register by element.
4433 __ Mov(x17, src_base);
4434 for (int i = 15; i >= 0; i--) {
4435 __ Ld4(v0.B(), v1.B(), v2.B(), v3.B(), i,
4436 MemOperand(x17, 4, PostIndex));
4437 }
4438
4439 __ Mov(x18, src_base);
4440 for (int i = 7; i >= 0; i--) {
4441 __ Ld4(v4.H(), v5.H(), v6.H(), v7.H(), i,
4442 MemOperand(x18, 8, PostIndex));
4443 }
4444
4445 __ Mov(x19, src_base);
4446 for (int i = 3; i >= 0; i--) {
4447 __ Ld4(v8.S(), v9.S(), v10.S(), v11.S(), i,
4448 MemOperand(x19, 16, PostIndex));
4449 }
4450
4451 __ Mov(x20, src_base);
4452 for (int i = 1; i >= 0; i--) {
4453 __ Ld4(v12.D(), v13.D(), v14.D(), v15.D(), i,
4454 MemOperand(x20, 32, PostIndex));
4455 }
4456
4457 // Test loading a single element into an initialised register.
4458 __ Mov(x25, 1);
4459 __ Mov(x21, src_base);
4460 __ Mov(x22, src_base);
4461 __ Mov(x23, src_base);
4462 __ Mov(x24, src_base);
4463
4464 __ Mov(x4, x21);
4465 __ Ldr(q16, MemOperand(x4, 16, PostIndex));
4466 __ Ldr(q17, MemOperand(x4, 16, PostIndex));
4467 __ Ldr(q18, MemOperand(x4, 16, PostIndex));
4468 __ Ldr(q19, MemOperand(x4));
4469 __ Ld4(v16.B(), v17.B(), v18.B(), v19.B(), 4,
4470 MemOperand(x21, x25, PostIndex));
4471 __ Add(x25, x25, 1);
4472
4473 __ Mov(x5, x22);
4474 __ Ldr(q20, MemOperand(x5, 16, PostIndex));
4475 __ Ldr(q21, MemOperand(x5, 16, PostIndex));
4476 __ Ldr(q22, MemOperand(x5, 16, PostIndex));
4477 __ Ldr(q23, MemOperand(x5));
4478 __ Ld4(v20.H(), v21.H(), v22.H(), v23.H(), 3,
4479 MemOperand(x22, x25, PostIndex));
4480 __ Add(x25, x25, 1);
4481
4482 __ Mov(x6, x23);
4483 __ Ldr(q24, MemOperand(x6, 16, PostIndex));
4484 __ Ldr(q25, MemOperand(x6, 16, PostIndex));
4485 __ Ldr(q26, MemOperand(x6, 16, PostIndex));
4486 __ Ldr(q27, MemOperand(x6));
4487 __ Ld4(v24.S(), v25.S(), v26.S(), v27.S(), 2,
4488 MemOperand(x23, x25, PostIndex));
4489 __ Add(x25, x25, 1);
4490
4491 __ Mov(x7, x24);
4492 __ Ldr(q28, MemOperand(x7, 16, PostIndex));
4493 __ Ldr(q29, MemOperand(x7, 16, PostIndex));
4494 __ Ldr(q30, MemOperand(x7, 16, PostIndex));
4495 __ Ldr(q31, MemOperand(x7));
4496 __ Ld4(v28.D(), v29.D(), v30.D(), v31.D(), 1,
4497 MemOperand(x24, x25, PostIndex));
4498
4499 END();
4500
4501 RUN();
4502
4503 ASSERT_EQUAL_128(0x0004080c1014181c, 0x2024282c3034383c, q0);
4504 ASSERT_EQUAL_128(0x0105090d1115191d, 0x2125292d3135393d, q1);
4505 ASSERT_EQUAL_128(0x02060a0e12161a1e, 0x22262a2e32363a3e, q2);
4506 ASSERT_EQUAL_128(0x03070b0f13171b1f, 0x23272b2f33373b3f, q3);
4507 ASSERT_EQUAL_128(0x0100090811101918, 0x2120292831303938, q4);
4508 ASSERT_EQUAL_128(0x03020b0a13121b1a, 0x23222b2a33323b3a, q5);
4509 ASSERT_EQUAL_128(0x05040d0c15141d1c, 0x25242d2c35343d3c, q6);
4510 ASSERT_EQUAL_128(0x07060f0e17161f1e, 0x27262f2e37363f3e, q7);
4511 ASSERT_EQUAL_128(0x0302010013121110, 0x2322212033323130, q8);
4512 ASSERT_EQUAL_128(0x0706050417161514, 0x2726252437363534, q9);
4513 ASSERT_EQUAL_128(0x0b0a09081b1a1918, 0x2b2a29283b3a3938, q10);
4514 ASSERT_EQUAL_128(0x0f0e0d0c1f1e1d1c, 0x2f2e2d2c3f3e3d3c, q11);
4515 ASSERT_EQUAL_128(0x0706050403020100, 0x2726252423222120, q12);
4516 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x2f2e2d2c2b2a2928, q13);
4517 ASSERT_EQUAL_128(0x1716151413121110, 0x3736353433323130, q14);
4518 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x3f3e3d3c3b3a3938, q15);
4519 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q16);
4520 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716150113121110, q17);
4521 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726250223222120, q18);
4522 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736350333323130, q19);
4523 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q20);
4524 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0302151413121110, q21);
4525 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x0504252423222120, q22);
4526 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x0706353433323130, q23);
4527 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q24);
4528 ASSERT_EQUAL_128(0x1f1e1d1c07060504, 0x1716151413121110, q25);
4529 ASSERT_EQUAL_128(0x2f2e2d2c0b0a0908, 0x2726252423222120, q26);
4530 ASSERT_EQUAL_128(0x3f3e3d3c0f0e0d0c, 0x3736353433323130, q27);
4531 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q28);
4532 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x1716151413121110, q29);
4533 ASSERT_EQUAL_128(0x1716151413121110, 0x2726252423222120, q30);
4534 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x3736353433323130, q31);
4535
4536 ASSERT_EQUAL_64(src_base + 64, x17);
4537 ASSERT_EQUAL_64(src_base + 64, x18);
4538 ASSERT_EQUAL_64(src_base + 64, x19);
4539 ASSERT_EQUAL_64(src_base + 64, x20);
4540 ASSERT_EQUAL_64(src_base + 1, x21);
4541 ASSERT_EQUAL_64(src_base + 2, x22);
4542 ASSERT_EQUAL_64(src_base + 3, x23);
4543 ASSERT_EQUAL_64(src_base + 4, x24);
4544
4545 TEARDOWN();
4546}
4547
4548
4549TEST(neon_ld4_alllanes) {
4550 SETUP();
4551
4552 uint8_t src[64];
4553 for (unsigned i = 0; i < sizeof(src); i++) {
4554 src[i] = i;
4555 }
4556 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4557
4558 START();
4559 __ Mov(x17, src_base + 1);
4560 __ Mov(x18, 1);
4561 __ Ld4r(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(), MemOperand(x17));
4562 __ Add(x17, x17, 4);
4563 __ Ld4r(v4.V16B(), v5.V16B(), v6.V16B(), v7.V16B(), MemOperand(x17));
4564 __ Add(x17, x17, 1);
4565 __ Ld4r(v8.V4H(), v9.V4H(), v10.V4H(), v11.V4H(), MemOperand(x17));
4566 __ Add(x17, x17, 1);
4567 __ Ld4r(v12.V8H(), v13.V8H(), v14.V8H(), v15.V8H(), MemOperand(x17));
4568 __ Add(x17, x17, 8);
4569 __ Ld4r(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(), MemOperand(x17));
4570 __ Add(x17, x17, 1);
4571 __ Ld4r(v20.V4S(), v21.V4S(), v22.V4S(), v23.V4S(), MemOperand(x17));
4572 __ Add(x17, x17, 16);
4573 __ Ld4r(v24.V2D(), v25.V2D(), v26.V2D(), v27.V2D(), MemOperand(x17));
4574
4575
4576 END();
4577
4578 RUN();
4579
4580 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4581 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4582 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4583 ASSERT_EQUAL_128(0x0000000000000000, 0x0404040404040404, q3);
4584 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4585 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4586 ASSERT_EQUAL_128(0x0707070707070707, 0x0707070707070707, q6);
4587 ASSERT_EQUAL_128(0x0808080808080808, 0x0808080808080808, q7);
4588 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q8);
4589 ASSERT_EQUAL_128(0x0000000000000000, 0x0908090809080908, q9);
4590 ASSERT_EQUAL_128(0x0000000000000000, 0x0b0a0b0a0b0a0b0a, q10);
4591 ASSERT_EQUAL_128(0x0000000000000000, 0x0d0c0d0c0d0c0d0c, q11);
4592 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q12);
4593 ASSERT_EQUAL_128(0x0a090a090a090a09, 0x0a090a090a090a09, q13);
4594 ASSERT_EQUAL_128(0x0c0b0c0b0c0b0c0b, 0x0c0b0c0b0c0b0c0b, q14);
4595 ASSERT_EQUAL_128(0x0e0d0e0d0e0d0e0d, 0x0e0d0e0d0e0d0e0d, q15);
4596 ASSERT_EQUAL_128(0x0000000000000000, 0x1211100f1211100f, q16);
4597 ASSERT_EQUAL_128(0x0000000000000000, 0x1615141316151413, q17);
4598 ASSERT_EQUAL_128(0x0000000000000000, 0x1a1918171a191817, q18);
4599 ASSERT_EQUAL_128(0x0000000000000000, 0x1e1d1c1b1e1d1c1b, q19);
4600 ASSERT_EQUAL_128(0x1312111013121110, 0x1312111013121110, q20);
4601 ASSERT_EQUAL_128(0x1716151417161514, 0x1716151417161514, q21);
4602 ASSERT_EQUAL_128(0x1b1a19181b1a1918, 0x1b1a19181b1a1918, q22);
4603 ASSERT_EQUAL_128(0x1f1e1d1c1f1e1d1c, 0x1f1e1d1c1f1e1d1c, q23);
4604 ASSERT_EQUAL_128(0x2726252423222120, 0x2726252423222120, q24);
4605 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2f2e2d2c2b2a2928, q25);
4606 ASSERT_EQUAL_128(0x3736353433323130, 0x3736353433323130, q26);
4607 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3f3e3d3c3b3a3938, q27);
4608
4609 TEARDOWN();
4610}
4611
4612
4613TEST(neon_ld4_alllanes_postindex) {
4614 SETUP();
4615
4616 uint8_t src[64];
4617 for (unsigned i = 0; i < sizeof(src); i++) {
4618 src[i] = i;
4619 }
4620 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4621 __ Mov(x17, src_base + 1);
4622 __ Mov(x18, 1);
4623
4624 START();
4625 __ Mov(x17, src_base + 1);
4626 __ Mov(x18, 1);
4627 __ Ld4r(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(),
4628 MemOperand(x17, 4, PostIndex));
4629 __ Ld4r(v4.V16B(), v5.V16B(), v6.V16B(), v7.V16B(),
4630 MemOperand(x17, x18, PostIndex));
4631 __ Ld4r(v8.V4H(), v9.V4H(), v10.V4H(), v11.V4H(),
4632 MemOperand(x17, x18, PostIndex));
4633 __ Ld4r(v12.V8H(), v13.V8H(), v14.V8H(), v15.V8H(),
4634 MemOperand(x17, 8, PostIndex));
4635 __ Ld4r(v16.V2S(), v17.V2S(), v18.V2S(), v19.V2S(),
4636 MemOperand(x17, x18, PostIndex));
4637 __ Ld4r(v20.V4S(), v21.V4S(), v22.V4S(), v23.V4S(),
4638 MemOperand(x17, 16, PostIndex));
4639 __ Ld4r(v24.V2D(), v25.V2D(), v26.V2D(), v27.V2D(),
4640 MemOperand(x17, 32, PostIndex));
4641 END();
4642
4643 RUN();
4644
4645 ASSERT_EQUAL_128(0x0000000000000000, 0x0101010101010101, q0);
4646 ASSERT_EQUAL_128(0x0000000000000000, 0x0202020202020202, q1);
4647 ASSERT_EQUAL_128(0x0000000000000000, 0x0303030303030303, q2);
4648 ASSERT_EQUAL_128(0x0000000000000000, 0x0404040404040404, q3);
4649 ASSERT_EQUAL_128(0x0505050505050505, 0x0505050505050505, q4);
4650 ASSERT_EQUAL_128(0x0606060606060606, 0x0606060606060606, q5);
4651 ASSERT_EQUAL_128(0x0707070707070707, 0x0707070707070707, q6);
4652 ASSERT_EQUAL_128(0x0808080808080808, 0x0808080808080808, q7);
4653 ASSERT_EQUAL_128(0x0000000000000000, 0x0706070607060706, q8);
4654 ASSERT_EQUAL_128(0x0000000000000000, 0x0908090809080908, q9);
4655 ASSERT_EQUAL_128(0x0000000000000000, 0x0b0a0b0a0b0a0b0a, q10);
4656 ASSERT_EQUAL_128(0x0000000000000000, 0x0d0c0d0c0d0c0d0c, q11);
4657 ASSERT_EQUAL_128(0x0807080708070807, 0x0807080708070807, q12);
4658 ASSERT_EQUAL_128(0x0a090a090a090a09, 0x0a090a090a090a09, q13);
4659 ASSERT_EQUAL_128(0x0c0b0c0b0c0b0c0b, 0x0c0b0c0b0c0b0c0b, q14);
4660 ASSERT_EQUAL_128(0x0e0d0e0d0e0d0e0d, 0x0e0d0e0d0e0d0e0d, q15);
4661 ASSERT_EQUAL_128(0x0000000000000000, 0x1211100f1211100f, q16);
4662 ASSERT_EQUAL_128(0x0000000000000000, 0x1615141316151413, q17);
4663 ASSERT_EQUAL_128(0x0000000000000000, 0x1a1918171a191817, q18);
4664 ASSERT_EQUAL_128(0x0000000000000000, 0x1e1d1c1b1e1d1c1b, q19);
4665 ASSERT_EQUAL_128(0x1312111013121110, 0x1312111013121110, q20);
4666 ASSERT_EQUAL_128(0x1716151417161514, 0x1716151417161514, q21);
4667 ASSERT_EQUAL_128(0x1b1a19181b1a1918, 0x1b1a19181b1a1918, q22);
4668 ASSERT_EQUAL_128(0x1f1e1d1c1f1e1d1c, 0x1f1e1d1c1f1e1d1c, q23);
4669 ASSERT_EQUAL_128(0x2726252423222120, 0x2726252423222120, q24);
4670 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2f2e2d2c2b2a2928, q25);
4671 ASSERT_EQUAL_128(0x3736353433323130, 0x3736353433323130, q26);
4672 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3f3e3d3c3b3a3938, q27);
4673 ASSERT_EQUAL_64(src_base + 64, x17);
4674
4675 TEARDOWN();
4676}
4677
4678
4679TEST(neon_st1_lane) {
4680 SETUP();
4681
4682 uint8_t src[64];
4683 for (unsigned i = 0; i < sizeof(src); i++) {
4684 src[i] = i;
4685 }
4686 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4687
4688 START();
4689 __ Mov(x17, src_base);
4690 __ Mov(x18, -16);
4691 __ Ldr(q0, MemOperand(x17));
4692
4693 for (int i = 15; i >= 0; i--) {
4694 __ St1(v0.B(), i, MemOperand(x17));
4695 __ Add(x17, x17, 1);
4696 }
4697 __ Ldr(q1, MemOperand(x17, x18));
4698
4699 for (int i = 7; i >= 0; i--) {
4700 __ St1(v0.H(), i, MemOperand(x17));
4701 __ Add(x17, x17, 2);
4702 }
4703 __ Ldr(q2, MemOperand(x17, x18));
4704
4705 for (int i = 3; i >= 0; i--) {
4706 __ St1(v0.S(), i, MemOperand(x17));
4707 __ Add(x17, x17, 4);
4708 }
4709 __ Ldr(q3, MemOperand(x17, x18));
4710
4711 for (int i = 1; i >= 0; i--) {
4712 __ St1(v0.D(), i, MemOperand(x17));
4713 __ Add(x17, x17, 8);
4714 }
4715 __ Ldr(q4, MemOperand(x17, x18));
4716
4717 END();
4718
4719 RUN();
4720
4721 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q1);
4722 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q2);
4723 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q3);
4724 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q4);
4725
4726 TEARDOWN();
4727}
4728
4729
4730TEST(neon_st2_lane) {
4731 SETUP();
4732
4733 // Struct size * addressing modes * element sizes * vector size.
4734 uint8_t dst[2 * 2 * 4 * 16];
4735 memset(dst, 0, sizeof(dst));
4736 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4737
4738 START();
4739 __ Mov(x17, dst_base);
4740 __ Mov(x18, dst_base);
4741 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
4742 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
4743
4744 // Test B stores with and without post index.
4745 for (int i = 15; i >= 0; i--) {
4746 __ St2(v0.B(), v1.B(), i, MemOperand(x18));
4747 __ Add(x18, x18, 2);
4748 }
4749 for (int i = 15; i >= 0; i--) {
4750 __ St2(v0.B(), v1.B(), i, MemOperand(x18, 2, PostIndex));
4751 }
4752 __ Ldr(q2, MemOperand(x17, 0 * 16));
4753 __ Ldr(q3, MemOperand(x17, 1 * 16));
4754 __ Ldr(q4, MemOperand(x17, 2 * 16));
4755 __ Ldr(q5, MemOperand(x17, 3 * 16));
4756
4757 // Test H stores with and without post index.
4758 __ Mov(x0, 4);
4759 for (int i = 7; i >= 0; i--) {
4760 __ St2(v0.H(), v1.H(), i, MemOperand(x18));
4761 __ Add(x18, x18, 4);
4762 }
4763 for (int i = 7; i >= 0; i--) {
4764 __ St2(v0.H(), v1.H(), i, MemOperand(x18, x0, PostIndex));
4765 }
4766 __ Ldr(q6, MemOperand(x17, 4 * 16));
4767 __ Ldr(q7, MemOperand(x17, 5 * 16));
4768 __ Ldr(q16, MemOperand(x17, 6 * 16));
4769 __ Ldr(q17, MemOperand(x17, 7 * 16));
4770
4771 // Test S stores with and without post index.
4772 for (int i = 3; i >= 0; i--) {
4773 __ St2(v0.S(), v1.S(), i, MemOperand(x18));
4774 __ Add(x18, x18, 8);
4775 }
4776 for (int i = 3; i >= 0; i--) {
4777 __ St2(v0.S(), v1.S(), i, MemOperand(x18, 8, PostIndex));
4778 }
4779 __ Ldr(q18, MemOperand(x17, 8 * 16));
4780 __ Ldr(q19, MemOperand(x17, 9 * 16));
4781 __ Ldr(q20, MemOperand(x17, 10 * 16));
4782 __ Ldr(q21, MemOperand(x17, 11 * 16));
4783
4784 // Test D stores with and without post index.
4785 __ Mov(x0, 16);
4786 __ St2(v0.D(), v1.D(), 1, MemOperand(x18));
4787 __ Add(x18, x18, 16);
4788 __ St2(v0.D(), v1.D(), 0, MemOperand(x18, 16, PostIndex));
4789 __ St2(v0.D(), v1.D(), 1, MemOperand(x18, x0, PostIndex));
4790 __ St2(v0.D(), v1.D(), 0, MemOperand(x18, x0, PostIndex));
4791 __ Ldr(q22, MemOperand(x17, 12 * 16));
4792 __ Ldr(q23, MemOperand(x17, 13 * 16));
4793 __ Ldr(q24, MemOperand(x17, 14 * 16));
4794 __ Ldr(q25, MemOperand(x17, 15 * 16));
4795 END();
4796
4797 RUN();
4798
4799 ASSERT_EQUAL_128(0x1707160615051404, 0x1303120211011000, q2);
4800 ASSERT_EQUAL_128(0x1f0f1e0e1d0d1c0c, 0x1b0b1a0a19091808, q3);
4801 ASSERT_EQUAL_128(0x1707160615051404, 0x1303120211011000, q4);
4802 ASSERT_EQUAL_128(0x1f0f1e0e1d0d1c0c, 0x1b0b1a0a19091808, q5);
4803
4804 ASSERT_EQUAL_128(0x1617060714150405, 0x1213020310110001, q6);
4805 ASSERT_EQUAL_128(0x1e1f0e0f1c1d0c0d, 0x1a1b0a0b18190809, q7);
4806 ASSERT_EQUAL_128(0x1617060714150405, 0x1213020310110001, q16);
4807 ASSERT_EQUAL_128(0x1e1f0e0f1c1d0c0d, 0x1a1b0a0b18190809, q17);
4808
4809 ASSERT_EQUAL_128(0x1415161704050607, 0x1011121300010203, q18);
4810 ASSERT_EQUAL_128(0x1c1d1e1f0c0d0e0f, 0x18191a1b08090a0b, q19);
4811 ASSERT_EQUAL_128(0x1415161704050607, 0x1011121300010203, q20);
4812 ASSERT_EQUAL_128(0x1c1d1e1f0c0d0e0f, 0x18191a1b08090a0b, q21);
4813
4814 ASSERT_EQUAL_128(0x1011121314151617, 0x0001020304050607, q22);
4815 ASSERT_EQUAL_128(0x18191a1b1c1d1e1f, 0x08090a0b0c0d0e0f, q23);
4816 ASSERT_EQUAL_128(0x1011121314151617, 0x0001020304050607, q22);
4817 ASSERT_EQUAL_128(0x18191a1b1c1d1e1f, 0x08090a0b0c0d0e0f, q23);
4818
4819 TEARDOWN();
4820}
4821
4822
4823TEST(neon_st3_lane) {
4824 SETUP();
4825
4826 // Struct size * addressing modes * element sizes * vector size.
4827 uint8_t dst[3 * 2 * 4 * 16];
4828 memset(dst, 0, sizeof(dst));
4829 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4830
4831 START();
4832 __ Mov(x17, dst_base);
4833 __ Mov(x18, dst_base);
4834 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
4835 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
4836 __ Movi(v2.V2D(), 0x2021222324252627, 0x28292a2b2c2d2e2f);
4837
4838 // Test B stores with and without post index.
4839 for (int i = 15; i >= 0; i--) {
4840 __ St3(v0.B(), v1.B(), v2.B(), i, MemOperand(x18));
4841 __ Add(x18, x18, 3);
4842 }
4843 for (int i = 15; i >= 0; i--) {
4844 __ St3(v0.B(), v1.B(), v2.B(), i, MemOperand(x18, 3, PostIndex));
4845 }
4846 __ Ldr(q3, MemOperand(x17, 0 * 16));
4847 __ Ldr(q4, MemOperand(x17, 1 * 16));
4848 __ Ldr(q5, MemOperand(x17, 2 * 16));
4849 __ Ldr(q6, MemOperand(x17, 3 * 16));
4850 __ Ldr(q7, MemOperand(x17, 4 * 16));
4851 __ Ldr(q16, MemOperand(x17, 5 * 16));
4852
4853 // Test H stores with and without post index.
4854 __ Mov(x0, 6);
4855 for (int i = 7; i >= 0; i--) {
4856 __ St3(v0.H(), v1.H(), v2.H(), i, MemOperand(x18));
4857 __ Add(x18, x18, 6);
4858 }
4859 for (int i = 7; i >= 0; i--) {
4860 __ St3(v0.H(), v1.H(), v2.H(), i, MemOperand(x18, x0, PostIndex));
4861 }
4862 __ Ldr(q17, MemOperand(x17, 6 * 16));
4863 __ Ldr(q18, MemOperand(x17, 7 * 16));
4864 __ Ldr(q19, MemOperand(x17, 8 * 16));
4865 __ Ldr(q20, MemOperand(x17, 9 * 16));
4866 __ Ldr(q21, MemOperand(x17, 10 * 16));
4867 __ Ldr(q22, MemOperand(x17, 11 * 16));
4868
4869 // Test S stores with and without post index.
4870 for (int i = 3; i >= 0; i--) {
4871 __ St3(v0.S(), v1.S(), v2.S(), i, MemOperand(x18));
4872 __ Add(x18, x18, 12);
4873 }
4874 for (int i = 3; i >= 0; i--) {
4875 __ St3(v0.S(), v1.S(), v2.S(), i, MemOperand(x18, 12, PostIndex));
4876 }
4877 __ Ldr(q23, MemOperand(x17, 12 * 16));
4878 __ Ldr(q24, MemOperand(x17, 13 * 16));
4879 __ Ldr(q25, MemOperand(x17, 14 * 16));
4880 __ Ldr(q26, MemOperand(x17, 15 * 16));
4881 __ Ldr(q27, MemOperand(x17, 16 * 16));
4882 __ Ldr(q28, MemOperand(x17, 17 * 16));
4883
4884 // Test D stores with and without post index.
4885 __ Mov(x0, 24);
4886 __ St3(v0.D(), v1.D(), v2.D(), 1, MemOperand(x18));
4887 __ Add(x18, x18, 24);
4888 __ St3(v0.D(), v1.D(), v2.D(), 0, MemOperand(x18, 24, PostIndex));
4889 __ St3(v0.D(), v1.D(), v2.D(), 1, MemOperand(x18, x0, PostIndex));
4890 __ Ldr(q29, MemOperand(x17, 18 * 16));
4891 __ Ldr(q30, MemOperand(x17, 19 * 16));
4892 __ Ldr(q31, MemOperand(x17, 20 * 16));
4893 END();
4894
4895 RUN();
4896
4897 ASSERT_EQUAL_128(0x0524140423130322, 0x1202211101201000, q3);
4898 ASSERT_EQUAL_128(0x1a0a291909281808, 0x2717072616062515, q4);
4899 ASSERT_EQUAL_128(0x2f1f0f2e1e0e2d1d, 0x0d2c1c0c2b1b0b2a, q5);
4900 ASSERT_EQUAL_128(0x0524140423130322, 0x1202211101201000, q6);
4901 ASSERT_EQUAL_128(0x1a0a291909281808, 0x2717072616062515, q7);
4902 ASSERT_EQUAL_128(0x2f1f0f2e1e0e2d1d, 0x0d2c1c0c2b1b0b2a, q16);
4903
4904 ASSERT_EQUAL_128(0x1415040522231213, 0x0203202110110001, q17);
4905 ASSERT_EQUAL_128(0x0a0b282918190809, 0x2627161706072425, q18);
4906 ASSERT_EQUAL_128(0x2e2f1e1f0e0f2c2d, 0x1c1d0c0d2a2b1a1b, q19);
4907 ASSERT_EQUAL_128(0x1415040522231213, 0x0203202110110001, q20);
4908 ASSERT_EQUAL_128(0x0a0b282918190809, 0x2627161706072425, q21);
4909 ASSERT_EQUAL_128(0x2e2f1e1f0e0f2c2d, 0x1c1d0c0d2a2b1a1b, q22);
4910
4911 ASSERT_EQUAL_128(0x0405060720212223, 0x1011121300010203, q23);
4912 ASSERT_EQUAL_128(0x18191a1b08090a0b, 0x2425262714151617, q24);
4913 ASSERT_EQUAL_128(0x2c2d2e2f1c1d1e1f, 0x0c0d0e0f28292a2b, q25);
4914 ASSERT_EQUAL_128(0x0405060720212223, 0x1011121300010203, q26);
4915 ASSERT_EQUAL_128(0x18191a1b08090a0b, 0x2425262714151617, q27);
4916 ASSERT_EQUAL_128(0x2c2d2e2f1c1d1e1f, 0x0c0d0e0f28292a2b, q28);
4917
4918 TEARDOWN();
4919}
4920
4921
4922TEST(neon_st4_lane) {
4923 SETUP();
4924
4925 // Struct size * element sizes * vector size.
4926 uint8_t dst[4 * 4 * 16];
4927 memset(dst, 0, sizeof(dst));
4928 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4929
4930 START();
4931 __ Mov(x17, dst_base);
4932 __ Mov(x18, dst_base);
4933 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
4934 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
4935 __ Movi(v2.V2D(), 0x2021222324252627, 0x28292a2b2c2d2e2f);
4936 __ Movi(v3.V2D(), 0x2021222324252627, 0x28292a2b2c2d2e2f);
4937
4938 // Test B stores without post index.
4939 for (int i = 15; i >= 0; i--) {
4940 __ St4(v0.B(), v1.B(), v2.B(), v3.B(), i, MemOperand(x18));
4941 __ Add(x18, x18, 4);
4942 }
4943 __ Ldr(q4, MemOperand(x17, 0 * 16));
4944 __ Ldr(q5, MemOperand(x17, 1 * 16));
4945 __ Ldr(q6, MemOperand(x17, 2 * 16));
4946 __ Ldr(q7, MemOperand(x17, 3 * 16));
4947
4948 // Test H stores with post index.
4949 __ Mov(x0, 8);
4950 for (int i = 7; i >= 0; i--) {
4951 __ St4(v0.H(), v1.H(), v2.H(), v3.H(), i, MemOperand(x18, x0, PostIndex));
4952 }
4953 __ Ldr(q16, MemOperand(x17, 4 * 16));
4954 __ Ldr(q17, MemOperand(x17, 5 * 16));
4955 __ Ldr(q18, MemOperand(x17, 6 * 16));
4956 __ Ldr(q19, MemOperand(x17, 7 * 16));
4957
4958 // Test S stores without post index.
4959 for (int i = 3; i >= 0; i--) {
4960 __ St4(v0.S(), v1.S(), v2.S(), v3.S(), i, MemOperand(x18));
4961 __ Add(x18, x18, 16);
4962 }
4963 __ Ldr(q20, MemOperand(x17, 8 * 16));
4964 __ Ldr(q21, MemOperand(x17, 9 * 16));
4965 __ Ldr(q22, MemOperand(x17, 10 * 16));
4966 __ Ldr(q23, MemOperand(x17, 11 * 16));
4967
4968 // Test D stores with post index.
4969 __ Mov(x0, 32);
4970 __ St4(v0.D(), v1.D(), v2.D(), v3.D(), 0, MemOperand(x18, 32, PostIndex));
4971 __ St4(v0.D(), v1.D(), v2.D(), v3.D(), 1, MemOperand(x18, x0, PostIndex));
4972
4973 __ Ldr(q24, MemOperand(x17, 12 * 16));
4974 __ Ldr(q25, MemOperand(x17, 13 * 16));
4975 __ Ldr(q26, MemOperand(x17, 14 * 16));
4976 __ Ldr(q27, MemOperand(x17, 15 * 16));
4977 END();
4978
4979 RUN();
4980
4981 ASSERT_EQUAL_128(0x2323130322221202, 0x2121110120201000, q4);
4982 ASSERT_EQUAL_128(0x2727170726261606, 0x2525150524241404, q5);
4983 ASSERT_EQUAL_128(0x2b2b1b0b2a2a1a0a, 0x2929190928281808, q6);
4984 ASSERT_EQUAL_128(0x2f2f1f0f2e2e1e0e, 0x2d2d1d0d2c2c1c0c, q7);
4985
4986 ASSERT_EQUAL_128(0x2223222312130203, 0x2021202110110001, q16);
4987 ASSERT_EQUAL_128(0x2627262716170607, 0x2425242514150405, q17);
4988 ASSERT_EQUAL_128(0x2a2b2a2b1a1b0a0b, 0x2829282918190809, q18);
4989 ASSERT_EQUAL_128(0x2e2f2e2f1e1f0e0f, 0x2c2d2c2d1c1d0c0d, q19);
4990
4991 ASSERT_EQUAL_128(0x2021222320212223, 0x1011121300010203, q20);
4992 ASSERT_EQUAL_128(0x2425262724252627, 0x1415161704050607, q21);
4993 ASSERT_EQUAL_128(0x28292a2b28292a2b, 0x18191a1b08090a0b, q22);
4994 ASSERT_EQUAL_128(0x2c2d2e2f2c2d2e2f, 0x1c1d1e1f0c0d0e0f, q23);
4995
4996 ASSERT_EQUAL_128(0x18191a1b1c1d1e1f, 0x08090a0b0c0d0e0f, q24);
4997 ASSERT_EQUAL_128(0x28292a2b2c2d2e2f, 0x28292a2b2c2d2e2f, q25);
4998 ASSERT_EQUAL_128(0x1011121314151617, 0x0001020304050607, q26);
4999 ASSERT_EQUAL_128(0x2021222324252627, 0x2021222324252627, q27);
5000
5001 TEARDOWN();
5002}
5003
5004
5005TEST(neon_ld1_lane_postindex) {
5006 SETUP();
5007
5008 uint8_t src[64];
5009 for (unsigned i = 0; i < sizeof(src); i++) {
5010 src[i] = i;
5011 }
5012 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5013
5014 START();
5015 __ Mov(x17, src_base);
5016 __ Mov(x18, src_base);
5017 __ Mov(x19, src_base);
5018 __ Mov(x20, src_base);
5019 __ Mov(x21, src_base);
5020 __ Mov(x22, src_base);
5021 __ Mov(x23, src_base);
5022 __ Mov(x24, src_base);
5023
5024 // Test loading whole register by element.
5025 for (int i = 15; i >= 0; i--) {
5026 __ Ld1(v0.B(), i, MemOperand(x17, 1, PostIndex));
5027 }
5028
5029 for (int i = 7; i >= 0; i--) {
5030 __ Ld1(v1.H(), i, MemOperand(x18, 2, PostIndex));
5031 }
5032
5033 for (int i = 3; i >= 0; i--) {
5034 __ Ld1(v2.S(), i, MemOperand(x19, 4, PostIndex));
5035 }
5036
5037 for (int i = 1; i >= 0; i--) {
5038 __ Ld1(v3.D(), i, MemOperand(x20, 8, PostIndex));
5039 }
5040
5041 // Test loading a single element into an initialised register.
5042 __ Mov(x25, 1);
5043 __ Ldr(q4, MemOperand(x21));
5044 __ Ld1(v4.B(), 4, MemOperand(x21, x25, PostIndex));
5045 __ Add(x25, x25, 1);
5046
5047 __ Ldr(q5, MemOperand(x22));
5048 __ Ld1(v5.H(), 3, MemOperand(x22, x25, PostIndex));
5049 __ Add(x25, x25, 1);
5050
5051 __ Ldr(q6, MemOperand(x23));
5052 __ Ld1(v6.S(), 2, MemOperand(x23, x25, PostIndex));
5053 __ Add(x25, x25, 1);
5054
5055 __ Ldr(q7, MemOperand(x24));
5056 __ Ld1(v7.D(), 1, MemOperand(x24, x25, PostIndex));
5057
5058 END();
5059
5060 RUN();
5061
5062 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q0);
5063 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q1);
5064 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q2);
5065 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q3);
5066 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050003020100, q4);
5067 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0100050403020100, q5);
5068 ASSERT_EQUAL_128(0x0f0e0d0c03020100, 0x0706050403020100, q6);
5069 ASSERT_EQUAL_128(0x0706050403020100, 0x0706050403020100, q7);
5070 ASSERT_EQUAL_64(src_base + 16, x17);
5071 ASSERT_EQUAL_64(src_base + 16, x18);
5072 ASSERT_EQUAL_64(src_base + 16, x19);
5073 ASSERT_EQUAL_64(src_base + 16, x20);
5074 ASSERT_EQUAL_64(src_base + 1, x21);
5075 ASSERT_EQUAL_64(src_base + 2, x22);
5076 ASSERT_EQUAL_64(src_base + 3, x23);
5077 ASSERT_EQUAL_64(src_base + 4, x24);
5078
5079 TEARDOWN();
5080}
5081
5082
5083TEST(neon_st1_lane_postindex) {
5084 SETUP();
5085
5086 uint8_t src[64];
5087 for (unsigned i = 0; i < sizeof(src); i++) {
5088 src[i] = i;
5089 }
5090 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5091
5092 START();
5093 __ Mov(x17, src_base);
5094 __ Mov(x18, -16);
5095 __ Ldr(q0, MemOperand(x17));
5096
5097 for (int i = 15; i >= 0; i--) {
5098 __ St1(v0.B(), i, MemOperand(x17, 1, PostIndex));
5099 }
5100 __ Ldr(q1, MemOperand(x17, x18));
5101
5102 for (int i = 7; i >= 0; i--) {
5103 __ St1(v0.H(), i, MemOperand(x17, 2, PostIndex));
5104 }
5105 __ Ldr(q2, MemOperand(x17, x18));
5106
5107 for (int i = 3; i >= 0; i--) {
5108 __ St1(v0.S(), i, MemOperand(x17, 4, PostIndex));
5109 }
5110 __ Ldr(q3, MemOperand(x17, x18));
5111
5112 for (int i = 1; i >= 0; i--) {
5113 __ St1(v0.D(), i, MemOperand(x17, 8, PostIndex));
5114 }
5115 __ Ldr(q4, MemOperand(x17, x18));
5116
5117 END();
5118
5119 RUN();
5120
5121 ASSERT_EQUAL_128(0x0001020304050607, 0x08090a0b0c0d0e0f, q1);
5122 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q2);
5123 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q3);
5124 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q4);
5125
5126 TEARDOWN();
5127}
5128
5129
5130TEST(neon_ld1_alllanes) {
5131 SETUP();
5132
5133 uint8_t src[64];
5134 for (unsigned i = 0; i < sizeof(src); i++) {
5135 src[i] = i;
5136 }
5137 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5138
5139 START();
5140 __ Mov(x17, src_base + 1);
5141 __ Ld1r(v0.V8B(), MemOperand(x17));
5142 __ Add(x17, x17, 1);
5143 __ Ld1r(v1.V16B(), MemOperand(x17));
5144 __ Add(x17, x17, 1);
5145 __ Ld1r(v2.V4H(), MemOperand(x17));
5146 __ Add(x17, x17, 1);
5147 __ Ld1r(v3.V8H(), MemOperand(x17));
5148 __ Add(x17, x17, 1);
5149 __ Ld1r(v4.V2S(), MemOperand(x17));
5150 __ Add(x17, x17, 1);
5151 __ Ld1r(v5.V4S(), MemOperand(x17));
5152 __ Add(x17, x17, 1);
5153 __ Ld1r(v6.V1D(), MemOperand(x17));
5154 __ Add(x17, x17, 1);
5155 __ Ld1r(v7.V2D(), MemOperand(x17));
5156 END();
5157
5158 RUN();
5159
5160 ASSERT_EQUAL_128(0, 0x0101010101010101, q0);
5161 ASSERT_EQUAL_128(0x0202020202020202, 0x0202020202020202, q1);
5162 ASSERT_EQUAL_128(0, 0x0403040304030403, q2);
5163 ASSERT_EQUAL_128(0x0504050405040504, 0x0504050405040504, q3);
5164 ASSERT_EQUAL_128(0, 0x0807060508070605, q4);
5165 ASSERT_EQUAL_128(0x0908070609080706, 0x0908070609080706, q5);
5166 ASSERT_EQUAL_128(0, 0x0e0d0c0b0a090807, q6);
5167 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0f0e0d0c0b0a0908, q7);
5168
5169 TEARDOWN();
5170}
5171
5172
5173TEST(neon_ld1_alllanes_postindex) {
5174 SETUP();
5175
5176 uint8_t src[64];
5177 for (unsigned i = 0; i < sizeof(src); i++) {
5178 src[i] = i;
5179 }
5180 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5181
5182 START();
5183 __ Mov(x17, src_base + 1);
5184 __ Mov(x18, 1);
5185 __ Ld1r(v0.V8B(), MemOperand(x17, 1, PostIndex));
5186 __ Ld1r(v1.V16B(), MemOperand(x17, x18, PostIndex));
5187 __ Ld1r(v2.V4H(), MemOperand(x17, x18, PostIndex));
5188 __ Ld1r(v3.V8H(), MemOperand(x17, 2, PostIndex));
5189 __ Ld1r(v4.V2S(), MemOperand(x17, x18, PostIndex));
5190 __ Ld1r(v5.V4S(), MemOperand(x17, 4, PostIndex));
5191 __ Ld1r(v6.V2D(), MemOperand(x17, 8, PostIndex));
5192 END();
5193
5194 RUN();
5195
5196 ASSERT_EQUAL_128(0, 0x0101010101010101, q0);
5197 ASSERT_EQUAL_128(0x0202020202020202, 0x0202020202020202, q1);
5198 ASSERT_EQUAL_128(0, 0x0403040304030403, q2);
5199 ASSERT_EQUAL_128(0x0504050405040504, 0x0504050405040504, q3);
5200 ASSERT_EQUAL_128(0, 0x0908070609080706, q4);
5201 ASSERT_EQUAL_128(0x0a0908070a090807, 0x0a0908070a090807, q5);
5202 ASSERT_EQUAL_128(0x1211100f0e0d0c0b, 0x1211100f0e0d0c0b, q6);
5203 ASSERT_EQUAL_64(src_base + 19, x17);
5204
5205 TEARDOWN();
5206}
5207
5208
5209TEST(neon_st1_d) {
5210 SETUP();
5211
5212 uint8_t src[14 * kDRegSizeInBytes];
5213 for (unsigned i = 0; i < sizeof(src); i++) {
5214 src[i] = i;
5215 }
5216 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5217
5218 START();
5219 __ Mov(x17, src_base);
5220 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5221 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5222 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5223 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5224 __ Mov(x17, src_base);
5225
5226 __ St1(v0.V8B(), MemOperand(x17));
5227 __ Ldr(d16, MemOperand(x17, 8, PostIndex));
5228
5229 __ St1(v0.V8B(), v1.V8B(), MemOperand(x17));
5230 __ Ldr(q17, MemOperand(x17, 16, PostIndex));
5231
5232 __ St1(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x17));
5233 __ Ldr(d18, MemOperand(x17, 8, PostIndex));
5234 __ Ldr(d19, MemOperand(x17, 8, PostIndex));
5235 __ Ldr(d20, MemOperand(x17, 8, PostIndex));
5236
5237 __ St1(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(), MemOperand(x17));
5238 __ Ldr(q21, MemOperand(x17, 16, PostIndex));
5239 __ Ldr(q22, MemOperand(x17, 16, PostIndex));
5240
5241 __ St1(v0.V1D(), v1.V1D(), v2.V1D(), v3.V1D(), MemOperand(x17));
5242 __ Ldr(q23, MemOperand(x17, 16, PostIndex));
5243 __ Ldr(q24, MemOperand(x17));
5244 END();
5245
5246 RUN();
5247
5248 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q0);
5249 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q1);
5250 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q2);
5251 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323130, q3);
5252 ASSERT_EQUAL_128(0, 0x0706050403020100, q16);
5253 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q17);
5254 ASSERT_EQUAL_128(0, 0x0706050403020100, q18);
5255 ASSERT_EQUAL_128(0, 0x1716151413121110, q19);
5256 ASSERT_EQUAL_128(0, 0x2726252423222120, q20);
5257 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q21);
5258 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q22);
5259 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q23);
5260 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q24);
5261
5262 TEARDOWN();
5263}
5264
5265
5266TEST(neon_st1_d_postindex) {
5267 SETUP();
5268
5269 uint8_t src[64 + 14 * kDRegSizeInBytes];
5270 for (unsigned i = 0; i < sizeof(src); i++) {
5271 src[i] = i;
5272 }
5273 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5274
5275 START();
5276 __ Mov(x17, src_base);
5277 __ Mov(x18, -8);
5278 __ Mov(x19, -16);
5279 __ Mov(x20, -24);
5280 __ Mov(x21, -32);
5281 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5282 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5283 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5284 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5285 __ Mov(x17, src_base);
5286
5287 __ St1(v0.V8B(), MemOperand(x17, 8, PostIndex));
5288 __ Ldr(d16, MemOperand(x17, x18));
5289
5290 __ St1(v0.V8B(), v1.V8B(), MemOperand(x17, 16, PostIndex));
5291 __ Ldr(q17, MemOperand(x17, x19));
5292
5293 __ St1(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x17, 24, PostIndex));
5294 __ Ldr(d18, MemOperand(x17, x20));
5295 __ Ldr(d19, MemOperand(x17, x19));
5296 __ Ldr(d20, MemOperand(x17, x18));
5297
5298 __ St1(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(),
5299 MemOperand(x17, 32, PostIndex));
5300 __ Ldr(q21, MemOperand(x17, x21));
5301 __ Ldr(q22, MemOperand(x17, x19));
5302
5303 __ St1(v0.V1D(), v1.V1D(), v2.V1D(), v3.V1D(),
5304 MemOperand(x17, 32, PostIndex));
5305 __ Ldr(q23, MemOperand(x17, x21));
5306 __ Ldr(q24, MemOperand(x17, x19));
5307 END();
5308
5309 RUN();
5310
5311 ASSERT_EQUAL_128(0, 0x0706050403020100, q16);
5312 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q17);
5313 ASSERT_EQUAL_128(0, 0x0706050403020100, q18);
5314 ASSERT_EQUAL_128(0, 0x1716151413121110, q19);
5315 ASSERT_EQUAL_128(0, 0x2726252423222120, q20);
5316 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q21);
5317 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q22);
5318 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q23);
5319 ASSERT_EQUAL_128(0x3736353433323130, 0x2726252423222120, q24);
5320
5321 TEARDOWN();
5322}
5323
5324
5325TEST(neon_st1_q) {
5326 SETUP();
5327
5328 uint8_t src[64 + 160];
5329 for (unsigned i = 0; i < sizeof(src); i++) {
5330 src[i] = i;
5331 }
5332 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5333
5334 START();
5335 __ Mov(x17, src_base);
5336 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5337 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5338 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5339 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5340
5341 __ St1(v0.V16B(), MemOperand(x17));
5342 __ Ldr(q16, MemOperand(x17, 16, PostIndex));
5343
5344 __ St1(v0.V8H(), v1.V8H(), MemOperand(x17));
5345 __ Ldr(q17, MemOperand(x17, 16, PostIndex));
5346 __ Ldr(q18, MemOperand(x17, 16, PostIndex));
5347
5348 __ St1(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x17));
5349 __ Ldr(q19, MemOperand(x17, 16, PostIndex));
5350 __ Ldr(q20, MemOperand(x17, 16, PostIndex));
5351 __ Ldr(q21, MemOperand(x17, 16, PostIndex));
5352
5353 __ St1(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(), MemOperand(x17));
5354 __ Ldr(q22, MemOperand(x17, 16, PostIndex));
5355 __ Ldr(q23, MemOperand(x17, 16, PostIndex));
5356 __ Ldr(q24, MemOperand(x17, 16, PostIndex));
5357 __ Ldr(q25, MemOperand(x17));
5358 END();
5359
5360 RUN();
5361
5362 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q16);
5363 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q17);
5364 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q18);
5365 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q19);
5366 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q20);
5367 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q21);
5368 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q22);
5369 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q23);
5370 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q24);
5371 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323130, q25);
5372
5373 TEARDOWN();
5374}
5375
5376
5377TEST(neon_st1_q_postindex) {
5378 SETUP();
5379
5380 uint8_t src[64 + 160];
5381 for (unsigned i = 0; i < sizeof(src); i++) {
5382 src[i] = i;
5383 }
5384 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5385
5386 START();
5387 __ Mov(x17, src_base);
5388 __ Mov(x18, -16);
5389 __ Mov(x19, -32);
5390 __ Mov(x20, -48);
5391 __ Mov(x21, -64);
5392 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5393 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5394 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5395 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5396
5397 __ St1(v0.V16B(), MemOperand(x17, 16, PostIndex));
5398 __ Ldr(q16, MemOperand(x17, x18));
5399
5400 __ St1(v0.V8H(), v1.V8H(), MemOperand(x17, 32, PostIndex));
5401 __ Ldr(q17, MemOperand(x17, x19));
5402 __ Ldr(q18, MemOperand(x17, x18));
5403
5404 __ St1(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x17, 48, PostIndex));
5405 __ Ldr(q19, MemOperand(x17, x20));
5406 __ Ldr(q20, MemOperand(x17, x19));
5407 __ Ldr(q21, MemOperand(x17, x18));
5408
5409 __ St1(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(),
5410 MemOperand(x17, 64, PostIndex));
5411 __ Ldr(q22, MemOperand(x17, x21));
5412 __ Ldr(q23, MemOperand(x17, x20));
5413 __ Ldr(q24, MemOperand(x17, x19));
5414 __ Ldr(q25, MemOperand(x17, x18));
5415
5416 END();
5417
5418 RUN();
5419
5420 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q16);
5421 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q17);
5422 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q18);
5423 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q19);
5424 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q20);
5425 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q21);
5426 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q22);
5427 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x1716151413121110, q23);
5428 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726252423222120, q24);
5429 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323130, q25);
5430
5431 TEARDOWN();
5432}
5433
5434
5435TEST(neon_st2_d) {
5436 SETUP();
5437
5438 uint8_t src[4*16];
5439 for (unsigned i = 0; i < sizeof(src); i++) {
5440 src[i] = i;
5441 }
5442 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5443
5444 START();
5445 __ Mov(x17, src_base);
5446 __ Mov(x18, src_base);
5447 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5448 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5449
5450 __ St2(v0.V8B(), v1.V8B(), MemOperand(x18));
5451 __ Add(x18, x18, 22);
5452 __ St2(v0.V4H(), v1.V4H(), MemOperand(x18));
5453 __ Add(x18, x18, 11);
5454 __ St2(v0.V2S(), v1.V2S(), MemOperand(x18));
5455
5456 __ Mov(x19, src_base);
5457 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5458 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5459 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5460 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5461
5462 END();
5463
5464 RUN();
5465
5466 ASSERT_EQUAL_128(0x1707160615051404, 0x1303120211011000, q0);
5467 ASSERT_EQUAL_128(0x0504131203021110, 0x0100151413121110, q1);
5468 ASSERT_EQUAL_128(0x1615140706050413, 0x1211100302010014, q2);
5469 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736353433323117, q3);
5470
5471 TEARDOWN();
5472}
5473
5474
5475TEST(neon_st2_d_postindex) {
5476 SETUP();
5477
5478 uint8_t src[4*16];
5479 for (unsigned i = 0; i < sizeof(src); i++) {
5480 src[i] = i;
5481 }
5482 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5483
5484 START();
5485 __ Mov(x22, 5);
5486 __ Mov(x17, src_base);
5487 __ Mov(x18, src_base);
5488 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5489 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5490
5491 __ St2(v0.V8B(), v1.V8B(), MemOperand(x18, x22, PostIndex));
5492 __ St2(v0.V4H(), v1.V4H(), MemOperand(x18, 16, PostIndex));
5493 __ St2(v0.V2S(), v1.V2S(), MemOperand(x18));
5494
5495
5496 __ Mov(x19, src_base);
5497 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5498 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5499 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5500
5501 END();
5502
5503 RUN();
5504
5505 ASSERT_EQUAL_128(0x1405041312030211, 0x1001000211011000, q0);
5506 ASSERT_EQUAL_128(0x0605041312111003, 0x0201001716070615, q1);
5507 ASSERT_EQUAL_128(0x2f2e2d2c2b2a2928, 0x2726251716151407, q2);
5508
5509 TEARDOWN();
5510}
5511
5512
5513TEST(neon_st2_q) {
5514 SETUP();
5515
5516 uint8_t src[5*16];
5517 for (unsigned i = 0; i < sizeof(src); i++) {
5518 src[i] = i;
5519 }
5520 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5521
5522 START();
5523 __ Mov(x17, src_base);
5524 __ Mov(x18, src_base);
5525 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5526 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5527
5528 __ St2(v0.V16B(), v1.V16B(), MemOperand(x18));
5529 __ Add(x18, x18, 8);
5530 __ St2(v0.V8H(), v1.V8H(), MemOperand(x18));
5531 __ Add(x18, x18, 22);
5532 __ St2(v0.V4S(), v1.V4S(), MemOperand(x18));
5533 __ Add(x18, x18, 2);
5534 __ St2(v0.V2D(), v1.V2D(), MemOperand(x18));
5535
5536 __ Mov(x19, src_base);
5537 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5538 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5539 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5540 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5541
5542 END();
5543
5544 RUN();
5545
5546 ASSERT_EQUAL_128(0x1312030211100100, 0x1303120211011000, q0);
5547 ASSERT_EQUAL_128(0x01000b0a19180908, 0x1716070615140504, q1);
5548 ASSERT_EQUAL_128(0x1716151413121110, 0x0706050403020100, q2);
5549 ASSERT_EQUAL_128(0x1f1e1d1c1b1a1918, 0x0f0e0d0c0b0a0908, q3);
5550 TEARDOWN();
5551}
5552
5553
5554TEST(neon_st2_q_postindex) {
5555 SETUP();
5556
5557 uint8_t src[5*16];
5558 for (unsigned i = 0; i < sizeof(src); i++) {
5559 src[i] = i;
5560 }
5561 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5562
5563 START();
5564 __ Mov(x22, 5);
5565 __ Mov(x17, src_base);
5566 __ Mov(x18, src_base);
5567 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5568 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5569
5570 __ St2(v0.V16B(), v1.V16B(), MemOperand(x18, x22, PostIndex));
5571 __ St2(v0.V8H(), v1.V8H(), MemOperand(x18, 32, PostIndex));
5572 __ St2(v0.V4S(), v1.V4S(), MemOperand(x18, x22, PostIndex));
5573 __ St2(v0.V2D(), v1.V2D(), MemOperand(x18));
5574
5575 __ Mov(x19, src_base);
5576 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5577 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5578 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5579 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5580 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5581
5582 END();
5583
5584 RUN();
5585
5586 ASSERT_EQUAL_128(0x1405041312030211, 0x1001000211011000, q0);
5587 ASSERT_EQUAL_128(0x1c0d0c1b1a0b0a19, 0x1809081716070615, q1);
5588 ASSERT_EQUAL_128(0x0504030201001003, 0x0201001f1e0f0e1d, q2);
5589 ASSERT_EQUAL_128(0x0d0c0b0a09081716, 0x1514131211100706, q3);
5590 ASSERT_EQUAL_128(0x4f4e4d4c4b4a1f1e, 0x1d1c1b1a19180f0e, q4);
5591
5592 TEARDOWN();
5593}
5594
5595
5596TEST(neon_st3_d) {
5597 SETUP();
5598
5599 uint8_t src[3*16];
5600 for (unsigned i = 0; i < sizeof(src); i++) {
5601 src[i] = i;
5602 }
5603 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5604
5605 START();
5606 __ Mov(x17, src_base);
5607 __ Mov(x18, src_base);
5608 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5609 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5610 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5611
5612 __ St3(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x18));
5613 __ Add(x18, x18, 3);
5614 __ St3(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x18));
5615 __ Add(x18, x18, 2);
5616 __ St3(v0.V2S(), v1.V2S(), v2.V2S(), MemOperand(x18));
5617
5618
5619 __ Mov(x19, src_base);
5620 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5621 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5622
5623 END();
5624
5625 RUN();
5626
5627 ASSERT_EQUAL_128(0x2221201312111003, 0x0201000100201000, q0);
5628 ASSERT_EQUAL_128(0x1f1e1d2726252417, 0x1615140706050423, q1);
5629
5630 TEARDOWN();
5631}
5632
5633
5634TEST(neon_st3_d_postindex) {
5635 SETUP();
5636
5637 uint8_t src[4*16];
5638 for (unsigned i = 0; i < sizeof(src); i++) {
5639 src[i] = i;
5640 }
5641 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5642
5643 START();
5644 __ Mov(x22, 5);
5645 __ Mov(x17, src_base);
5646 __ Mov(x18, src_base);
5647 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5648 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5649 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5650
5651 __ St3(v0.V8B(), v1.V8B(), v2.V8B(), MemOperand(x18, x22, PostIndex));
5652 __ St3(v0.V4H(), v1.V4H(), v2.V4H(), MemOperand(x18, 24, PostIndex));
5653 __ St3(v0.V2S(), v1.V2S(), v2.V2S(), MemOperand(x18));
5654
5655
5656 __ Mov(x19, src_base);
5657 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5658 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5659 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5660 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5661
5662 END();
5663
5664 RUN();
5665
5666 ASSERT_EQUAL_128(0x2213120302212011, 0x1001001101201000, q0);
5667 ASSERT_EQUAL_128(0x0201002726171607, 0x0625241514050423, q1);
5668 ASSERT_EQUAL_128(0x1615140706050423, 0x2221201312111003, q2);
5669 ASSERT_EQUAL_128(0x3f3e3d3c3b3a3938, 0x3736352726252417, q3);
5670
5671 TEARDOWN();
5672}
5673
5674
5675TEST(neon_st3_q) {
5676 SETUP();
5677
5678 uint8_t src[6*16];
5679 for (unsigned i = 0; i < sizeof(src); i++) {
5680 src[i] = i;
5681 }
5682 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5683
5684 START();
5685 __ Mov(x17, src_base);
5686 __ Mov(x18, src_base);
5687 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5688 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5689 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5690
5691 __ St3(v0.V16B(), v1.V16B(), v2.V16B(), MemOperand(x18));
5692 __ Add(x18, x18, 5);
5693 __ St3(v0.V8H(), v1.V8H(), v2.V8H(), MemOperand(x18));
5694 __ Add(x18, x18, 12);
5695 __ St3(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x18));
5696 __ Add(x18, x18, 22);
5697 __ St3(v0.V2D(), v1.V2D(), v2.V2D(), MemOperand(x18));
5698
5699 __ Mov(x19, src_base);
5700 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5701 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5702 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5703 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5704 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5705 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5706
5707 END();
5708
5709 RUN();
5710
5711 ASSERT_EQUAL_128(0x2213120302212011, 0x1001001101201000, q0);
5712 ASSERT_EQUAL_128(0x0605042322212013, 0x1211100302010023, q1);
5713 ASSERT_EQUAL_128(0x1007060504030201, 0x0025241716151407, q2);
5714 ASSERT_EQUAL_128(0x0827262524232221, 0x2017161514131211, q3);
5715 ASSERT_EQUAL_128(0x281f1e1d1c1b1a19, 0x180f0e0d0c0b0a09, q4);
5716 ASSERT_EQUAL_128(0x5f5e5d5c5b5a5958, 0x572f2e2d2c2b2a29, q5);
5717
5718 TEARDOWN();
5719}
5720
5721
5722TEST(neon_st3_q_postindex) {
5723 SETUP();
5724
5725 uint8_t src[7*16];
5726 for (unsigned i = 0; i < sizeof(src); i++) {
5727 src[i] = i;
5728 }
5729 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5730
5731 START();
5732 __ Mov(x22, 5);
5733 __ Mov(x17, src_base);
5734 __ Mov(x18, src_base);
5735 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5736 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5737 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5738
5739 __ St3(v0.V16B(), v1.V16B(), v2.V16B(), MemOperand(x18, x22, PostIndex));
5740 __ St3(v0.V8H(), v1.V8H(), v2.V8H(), MemOperand(x18, 48, PostIndex));
5741 __ St3(v0.V4S(), v1.V4S(), v2.V4S(), MemOperand(x18, x22, PostIndex));
5742 __ St3(v0.V2D(), v1.V2D(), v2.V2D(), MemOperand(x18));
5743
5744 __ Mov(x19, src_base);
5745 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5746 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5747 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5748 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5749 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5750 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5751 __ Ldr(q6, MemOperand(x19, 16, PostIndex));
5752
5753 END();
5754
5755 RUN();
5756
5757 ASSERT_EQUAL_128(0x2213120302212011, 0x1001001101201000, q0);
5758 ASSERT_EQUAL_128(0x1809082726171607, 0x0625241514050423, q1);
5759 ASSERT_EQUAL_128(0x0e2d2c1d1c0d0c2b, 0x2a1b1a0b0a292819, q2);
5760 ASSERT_EQUAL_128(0x0504030201001003, 0x0201002f2e1f1e0f, q3);
5761 ASSERT_EQUAL_128(0x2524232221201716, 0x1514131211100706, q4);
5762 ASSERT_EQUAL_128(0x1d1c1b1a19180f0e, 0x0d0c0b0a09082726, q5);
5763 ASSERT_EQUAL_128(0x6f6e6d6c6b6a2f2e, 0x2d2c2b2a29281f1e, q6);
5764
5765 TEARDOWN();
5766}
5767
5768
5769TEST(neon_st4_d) {
5770 SETUP();
5771
5772 uint8_t src[4*16];
5773 for (unsigned i = 0; i < sizeof(src); i++) {
5774 src[i] = i;
5775 }
5776 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5777
5778 START();
5779 __ Mov(x17, src_base);
5780 __ Mov(x18, src_base);
5781 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5782 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5783 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5784 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5785
5786 __ St4(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(), MemOperand(x18));
5787 __ Add(x18, x18, 12);
5788 __ St4(v0.V4H(), v1.V4H(), v2.V4H(), v3.V4H(), MemOperand(x18));
5789 __ Add(x18, x18, 15);
5790 __ St4(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(), MemOperand(x18));
5791
5792
5793 __ Mov(x19, src_base);
5794 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5795 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5796 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5797 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5798
5799 END();
5800
5801 RUN();
5802
5803 ASSERT_EQUAL_128(0x1110010032221202, 0X3121110130201000, q0);
5804 ASSERT_EQUAL_128(0x1003020100322322, 0X1312030231302120, q1);
5805 ASSERT_EQUAL_128(0x1407060504333231, 0X3023222120131211, q2);
5806 ASSERT_EQUAL_128(0x3f3e3d3c3b373635, 0x3427262524171615, q3);
5807
5808 TEARDOWN();
5809}
5810
5811
5812TEST(neon_st4_d_postindex) {
5813 SETUP();
5814
5815 uint8_t src[5*16];
5816 for (unsigned i = 0; i < sizeof(src); i++) {
5817 src[i] = i;
5818 }
5819 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5820
5821 START();
5822 __ Mov(x22, 5);
5823 __ Mov(x17, src_base);
5824 __ Mov(x18, src_base);
5825 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5826 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5827 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5828 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5829
5830 __ St4(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(),
5831 MemOperand(x18, x22, PostIndex));
5832 __ St4(v0.V4H(), v1.V4H(), v2.V4H(), v3.V4H(),
5833 MemOperand(x18, 32, PostIndex));
5834 __ St4(v0.V2S(), v1.V2S(), v2.V2S(), v3.V2S(),
5835 MemOperand(x18));
5836
5837
5838 __ Mov(x19, src_base);
5839 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5840 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5841 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5842 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5843 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5844
5845 END();
5846
5847 RUN();
5848
5849 ASSERT_EQUAL_128(0x1203023130212011, 0x1001000130201000, q0);
5850 ASSERT_EQUAL_128(0x1607063534252415, 0x1405043332232213, q1);
5851 ASSERT_EQUAL_128(0x2221201312111003, 0x0201003736272617, q2);
5852 ASSERT_EQUAL_128(0x2625241716151407, 0x0605043332313023, q3);
5853 ASSERT_EQUAL_128(0x4f4e4d4c4b4a4948, 0x4746453736353427, q4);
5854
5855 TEARDOWN();
5856}
5857
5858
5859TEST(neon_st4_q) {
5860 SETUP();
5861
5862 uint8_t src[7*16];
5863 for (unsigned i = 0; i < sizeof(src); i++) {
5864 src[i] = i;
5865 }
5866 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5867
5868 START();
5869 __ Mov(x17, src_base);
5870 __ Mov(x18, src_base);
5871 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5872 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5873 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5874 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5875
5876 __ St4(v0.V16B(), v1.V16B(), v2.V16B(), v3.V16B(), MemOperand(x18));
5877 __ Add(x18, x18, 5);
5878 __ St4(v0.V8H(), v1.V8H(), v2.V8H(), v3.V8H(), MemOperand(x18));
5879 __ Add(x18, x18, 12);
5880 __ St4(v0.V4S(), v1.V4S(), v2.V4S(), v3.V4S(), MemOperand(x18));
5881 __ Add(x18, x18, 22);
5882 __ St4(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(), MemOperand(x18));
5883 __ Add(x18, x18, 10);
5884
5885 __ Mov(x19, src_base);
5886 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5887 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5888 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5889 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5890 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5891 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5892 __ Ldr(q6, MemOperand(x19, 16, PostIndex));
5893
5894 END();
5895
5896 RUN();
5897
5898 ASSERT_EQUAL_128(0x1203023130212011, 0x1001000130201000, q0);
5899 ASSERT_EQUAL_128(0x3231302322212013, 0x1211100302010013, q1);
5900 ASSERT_EQUAL_128(0x1007060504030201, 0x0015140706050433, q2);
5901 ASSERT_EQUAL_128(0x3027262524232221, 0x2017161514131211, q3);
5902 ASSERT_EQUAL_128(0x180f0e0d0c0b0a09, 0x0837363534333231, q4);
5903 ASSERT_EQUAL_128(0x382f2e2d2c2b2a29, 0x281f1e1d1c1b1a19, q5);
5904 ASSERT_EQUAL_128(0x6f6e6d6c6b6a6968, 0x673f3e3d3c3b3a39, q6);
5905
5906 TEARDOWN();
5907}
5908
5909
5910TEST(neon_st4_q_postindex) {
5911 SETUP();
5912
5913 uint8_t src[9*16];
5914 for (unsigned i = 0; i < sizeof(src); i++) {
5915 src[i] = i;
5916 }
5917 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5918
5919 START();
5920 __ Mov(x22, 5);
5921 __ Mov(x17, src_base);
5922 __ Mov(x18, src_base);
5923 __ Ldr(q0, MemOperand(x17, 16, PostIndex));
5924 __ Ldr(q1, MemOperand(x17, 16, PostIndex));
5925 __ Ldr(q2, MemOperand(x17, 16, PostIndex));
5926 __ Ldr(q3, MemOperand(x17, 16, PostIndex));
5927
5928 __ St4(v0.V16B(), v1.V16B(), v2.V16B(), v3.V16B(),
5929 MemOperand(x18, x22, PostIndex));
5930 __ St4(v0.V8H(), v1.V8H(), v2.V8H(), v3.V8H(),
5931 MemOperand(x18, 64, PostIndex));
5932 __ St4(v0.V4S(), v1.V4S(), v2.V4S(), v3.V4S(),
5933 MemOperand(x18, x22, PostIndex));
5934 __ St4(v0.V2D(), v1.V2D(), v2.V2D(), v3.V2D(),
5935 MemOperand(x18));
5936
5937 __ Mov(x19, src_base);
5938 __ Ldr(q0, MemOperand(x19, 16, PostIndex));
5939 __ Ldr(q1, MemOperand(x19, 16, PostIndex));
5940 __ Ldr(q2, MemOperand(x19, 16, PostIndex));
5941 __ Ldr(q3, MemOperand(x19, 16, PostIndex));
5942 __ Ldr(q4, MemOperand(x19, 16, PostIndex));
5943 __ Ldr(q5, MemOperand(x19, 16, PostIndex));
5944 __ Ldr(q6, MemOperand(x19, 16, PostIndex));
5945 __ Ldr(q7, MemOperand(x19, 16, PostIndex));
5946 __ Ldr(q8, MemOperand(x19, 16, PostIndex));
5947
5948 END();
5949
5950 RUN();
5951
5952 ASSERT_EQUAL_128(0x1203023130212011, 0x1001000130201000, q0);
5953 ASSERT_EQUAL_128(0x1607063534252415, 0x1405043332232213, q1);
5954 ASSERT_EQUAL_128(0x1a0b0a3938292819, 0x1809083736272617, q2);
5955 ASSERT_EQUAL_128(0x1e0f0e3d3c2d2c1d, 0x1c0d0c3b3a2b2a1b, q3);
5956 ASSERT_EQUAL_128(0x0504030201001003, 0x0201003f3e2f2e1f, q4);
5957 ASSERT_EQUAL_128(0x2524232221201716, 0x1514131211100706, q5);
5958 ASSERT_EQUAL_128(0x0d0c0b0a09083736, 0x3534333231302726, q6);
5959 ASSERT_EQUAL_128(0x2d2c2b2a29281f1e, 0x1d1c1b1a19180f0e, q7);
5960 ASSERT_EQUAL_128(0x8f8e8d8c8b8a3f3e, 0x3d3c3b3a39382f2e, q8);
5961
5962 TEARDOWN();
5963}
5964
5965
armvixlad96eda2013-06-14 11:42:37 +01005966TEST(ldp_stp_float) {
5967 SETUP();
5968
5969 float src[2] = {1.0, 2.0};
5970 float dst[3] = {0.0, 0.0, 0.0};
5971 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
5972 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
5973
5974 START();
5975 __ Mov(x16, src_base);
5976 __ Mov(x17, dst_base);
5977 __ Ldp(s31, s0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
5978 __ Stp(s0, s31, MemOperand(x17, sizeof(dst[1]), PreIndex));
5979 END();
5980
5981 RUN();
5982
5983 ASSERT_EQUAL_FP32(1.0, s31);
5984 ASSERT_EQUAL_FP32(2.0, s0);
5985 ASSERT_EQUAL_FP32(0.0, dst[0]);
5986 ASSERT_EQUAL_FP32(2.0, dst[1]);
5987 ASSERT_EQUAL_FP32(1.0, dst[2]);
5988 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
5989 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
5990
5991 TEARDOWN();
5992}
5993
5994
5995TEST(ldp_stp_double) {
5996 SETUP();
5997
5998 double src[2] = {1.0, 2.0};
5999 double dst[3] = {0.0, 0.0, 0.0};
6000 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6001 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6002
6003 START();
6004 __ Mov(x16, src_base);
6005 __ Mov(x17, dst_base);
6006 __ Ldp(d31, d0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
6007 __ Stp(d0, d31, MemOperand(x17, sizeof(dst[1]), PreIndex));
6008 END();
6009
6010 RUN();
6011
6012 ASSERT_EQUAL_FP64(1.0, d31);
6013 ASSERT_EQUAL_FP64(2.0, d0);
6014 ASSERT_EQUAL_FP64(0.0, dst[0]);
6015 ASSERT_EQUAL_FP64(2.0, dst[1]);
6016 ASSERT_EQUAL_FP64(1.0, dst[2]);
6017 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
6018 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
6019
6020 TEARDOWN();
6021}
6022
6023
armvixl5289c592015-03-02 13:52:04 +00006024TEST(ldp_stp_quad) {
6025 SETUP();
6026
6027 uint64_t src[4] = {0x0123456789abcdef, 0xaaaaaaaa55555555,
6028 0xfedcba9876543210, 0x55555555aaaaaaaa};
6029 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
6030 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6031 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6032
6033 START();
6034 __ Mov(x16, src_base);
6035 __ Mov(x17, dst_base);
6036 __ Ldp(q31, q0, MemOperand(x16, 4 * sizeof(src[0]), PostIndex));
6037 __ Stp(q0, q31, MemOperand(x17, 2 * sizeof(dst[1]), PreIndex));
6038 END();
6039
6040 RUN();
6041
6042 ASSERT_EQUAL_128(0xaaaaaaaa55555555, 0x0123456789abcdef, q31);
6043 ASSERT_EQUAL_128(0x55555555aaaaaaaa, 0xfedcba9876543210, q0);
6044 ASSERT_EQUAL_64(0, dst[0]);
6045 ASSERT_EQUAL_64(0, dst[1]);
6046 ASSERT_EQUAL_64(0xfedcba9876543210, dst[2]);
6047 ASSERT_EQUAL_64(0x55555555aaaaaaaa, dst[3]);
6048 ASSERT_EQUAL_64(0x0123456789abcdef, dst[4]);
6049 ASSERT_EQUAL_64(0xaaaaaaaa55555555, dst[5]);
6050 ASSERT_EQUAL_64(src_base + 4 * sizeof(src[0]), x16);
6051 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[1]), x17);
6052
6053 TEARDOWN();
6054}
6055
6056
armvixlad96eda2013-06-14 11:42:37 +01006057TEST(ldp_stp_offset) {
6058 SETUP();
6059
armvixlb0c8ae22014-03-21 14:03:59 +00006060 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6061 0xffeeddccbbaa9988};
armvixlad96eda2013-06-14 11:42:37 +01006062 uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
6063 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6064 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6065
6066 START();
6067 __ Mov(x16, src_base);
6068 __ Mov(x17, dst_base);
6069 __ Mov(x18, src_base + 24);
6070 __ Mov(x19, dst_base + 56);
6071 __ Ldp(w0, w1, MemOperand(x16));
6072 __ Ldp(w2, w3, MemOperand(x16, 4));
6073 __ Ldp(x4, x5, MemOperand(x16, 8));
6074 __ Ldp(w6, w7, MemOperand(x18, -12));
6075 __ Ldp(x8, x9, MemOperand(x18, -16));
6076 __ Stp(w0, w1, MemOperand(x17));
6077 __ Stp(w2, w3, MemOperand(x17, 8));
6078 __ Stp(x4, x5, MemOperand(x17, 16));
6079 __ Stp(w6, w7, MemOperand(x19, -24));
6080 __ Stp(x8, x9, MemOperand(x19, -16));
6081 END();
6082
6083 RUN();
6084
6085 ASSERT_EQUAL_64(0x44556677, x0);
6086 ASSERT_EQUAL_64(0x00112233, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00006087 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
armvixlad96eda2013-06-14 11:42:37 +01006088 ASSERT_EQUAL_64(0x00112233, x2);
6089 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006090 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
6091 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6092 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
6093 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6094 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01006095 ASSERT_EQUAL_64(0x8899aabb, x6);
6096 ASSERT_EQUAL_64(0xbbaa9988, x7);
armvixlb0c8ae22014-03-21 14:03:59 +00006097 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
6098 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
6099 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
6100 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
6101 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
armvixlad96eda2013-06-14 11:42:37 +01006102 ASSERT_EQUAL_64(src_base, x16);
6103 ASSERT_EQUAL_64(dst_base, x17);
6104 ASSERT_EQUAL_64(src_base + 24, x18);
6105 ASSERT_EQUAL_64(dst_base + 56, x19);
6106
6107 TEARDOWN();
6108}
6109
6110
armvixlc68cb642014-09-25 18:49:30 +01006111TEST(ldp_stp_offset_wide) {
6112 SETUP();
6113
6114 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6115 0xffeeddccbbaa9988};
6116 uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
6117 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6118 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6119 // Move base too far from the array to force multiple instructions
6120 // to be emitted.
6121 const int64_t base_offset = 1024;
6122
6123 START();
6124 __ Mov(x20, src_base - base_offset);
6125 __ Mov(x21, dst_base - base_offset);
6126 __ Mov(x18, src_base + base_offset + 24);
6127 __ Mov(x19, dst_base + base_offset + 56);
6128 __ Ldp(w0, w1, MemOperand(x20, base_offset));
6129 __ Ldp(w2, w3, MemOperand(x20, base_offset + 4));
6130 __ Ldp(x4, x5, MemOperand(x20, base_offset + 8));
6131 __ Ldp(w6, w7, MemOperand(x18, -12 - base_offset));
6132 __ Ldp(x8, x9, MemOperand(x18, -16 - base_offset));
6133 __ Stp(w0, w1, MemOperand(x21, base_offset));
6134 __ Stp(w2, w3, MemOperand(x21, base_offset + 8));
6135 __ Stp(x4, x5, MemOperand(x21, base_offset + 16));
6136 __ Stp(w6, w7, MemOperand(x19, -24 - base_offset));
6137 __ Stp(x8, x9, MemOperand(x19, -16 - base_offset));
6138 END();
6139
6140 RUN();
6141
6142 ASSERT_EQUAL_64(0x44556677, x0);
6143 ASSERT_EQUAL_64(0x00112233, x1);
6144 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
6145 ASSERT_EQUAL_64(0x00112233, x2);
6146 ASSERT_EQUAL_64(0xccddeeff, x3);
6147 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
6148 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6149 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
6150 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6151 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
6152 ASSERT_EQUAL_64(0x8899aabb, x6);
6153 ASSERT_EQUAL_64(0xbbaa9988, x7);
6154 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
6155 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
6156 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
6157 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
6158 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
6159 ASSERT_EQUAL_64(src_base - base_offset, x20);
6160 ASSERT_EQUAL_64(dst_base - base_offset, x21);
6161 ASSERT_EQUAL_64(src_base + base_offset + 24, x18);
6162 ASSERT_EQUAL_64(dst_base + base_offset + 56, x19);
6163
6164 TEARDOWN();
6165}
6166
6167
armvixlad96eda2013-06-14 11:42:37 +01006168TEST(ldnp_stnp_offset) {
6169 SETUP();
6170
armvixl5289c592015-03-02 13:52:04 +00006171 uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
6172 0xffeeddccbbaa9988, 0x7766554433221100};
6173 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 +01006174 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6175 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6176
6177 START();
6178 __ Mov(x16, src_base);
6179 __ Mov(x17, dst_base);
6180 __ Mov(x18, src_base + 24);
armvixl5289c592015-03-02 13:52:04 +00006181 __ Mov(x19, dst_base + 64);
6182 __ Mov(x20, src_base + 32);
6183
6184 // Ensure address set up has happened before executing non-temporal ops.
6185 __ Dmb(InnerShareable, BarrierAll);
6186
armvixlad96eda2013-06-14 11:42:37 +01006187 __ Ldnp(w0, w1, MemOperand(x16));
6188 __ Ldnp(w2, w3, MemOperand(x16, 4));
6189 __ Ldnp(x4, x5, MemOperand(x16, 8));
6190 __ Ldnp(w6, w7, MemOperand(x18, -12));
6191 __ Ldnp(x8, x9, MemOperand(x18, -16));
armvixl5289c592015-03-02 13:52:04 +00006192 __ Ldnp(q16, q17, MemOperand(x16));
6193 __ Ldnp(q19, q18, MemOperand(x20, -32));
armvixlad96eda2013-06-14 11:42:37 +01006194 __ Stnp(w0, w1, MemOperand(x17));
6195 __ Stnp(w2, w3, MemOperand(x17, 8));
6196 __ Stnp(x4, x5, MemOperand(x17, 16));
armvixl5289c592015-03-02 13:52:04 +00006197 __ Stnp(w6, w7, MemOperand(x19, -32));
6198 __ Stnp(x8, x9, MemOperand(x19, -24));
6199 __ Stnp(q17, q16, MemOperand(x19));
6200 __ Stnp(q18, q19, MemOperand(x19, 32));
armvixlad96eda2013-06-14 11:42:37 +01006201 END();
6202
6203 RUN();
6204
6205 ASSERT_EQUAL_64(0x44556677, x0);
6206 ASSERT_EQUAL_64(0x00112233, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00006207 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
armvixlad96eda2013-06-14 11:42:37 +01006208 ASSERT_EQUAL_64(0x00112233, x2);
6209 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006210 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
6211 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6212 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
6213 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6214 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01006215 ASSERT_EQUAL_64(0x8899aabb, x6);
6216 ASSERT_EQUAL_64(0xbbaa9988, x7);
armvixlb0c8ae22014-03-21 14:03:59 +00006217 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
6218 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
6219 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
6220 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
6221 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
armvixl5289c592015-03-02 13:52:04 +00006222 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x0011223344556677, q16);
6223 ASSERT_EQUAL_128(0x7766554433221100, 0xffeeddccbbaa9988, q17);
6224 ASSERT_EQUAL_128(0x7766554433221100, 0xffeeddccbbaa9988, q18);
6225 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x0011223344556677, q19);
6226 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[8]);
6227 ASSERT_EQUAL_64(0x7766554433221100, dst[9]);
6228 ASSERT_EQUAL_64(0x0011223344556677, dst[10]);
6229 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[11]);
6230 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[12]);
6231 ASSERT_EQUAL_64(0x7766554433221100, dst[13]);
6232 ASSERT_EQUAL_64(0x0011223344556677, dst[14]);
6233 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[15]);
armvixlad96eda2013-06-14 11:42:37 +01006234 ASSERT_EQUAL_64(src_base, x16);
6235 ASSERT_EQUAL_64(dst_base, x17);
6236 ASSERT_EQUAL_64(src_base + 24, x18);
armvixl5289c592015-03-02 13:52:04 +00006237 ASSERT_EQUAL_64(dst_base + 64, x19);
6238 ASSERT_EQUAL_64(src_base + 32, x20);
6239
6240 TEARDOWN();
6241}
6242
6243
6244TEST(ldnp_stnp_offset_float) {
6245 SETUP();
6246
6247 float src[3] = {1.2, 2.3, 3.4};
6248 float dst[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6249 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6250 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6251
6252 START();
6253 __ Mov(x16, src_base);
6254 __ Mov(x17, dst_base);
6255 __ Mov(x18, src_base + 12);
6256 __ Mov(x19, dst_base + 24);
6257
6258 // Ensure address set up has happened before executing non-temporal ops.
6259 __ Dmb(InnerShareable, BarrierAll);
6260
6261 __ Ldnp(s0, s1, MemOperand(x16));
6262 __ Ldnp(s2, s3, MemOperand(x16, 4));
6263 __ Ldnp(s5, s4, MemOperand(x18, -8));
6264 __ Stnp(s1, s0, MemOperand(x17));
6265 __ Stnp(s3, s2, MemOperand(x17, 8));
6266 __ Stnp(s4, s5, MemOperand(x19, -8));
6267 END();
6268
6269 RUN();
6270
6271 ASSERT_EQUAL_FP32(1.2, s0);
6272 ASSERT_EQUAL_FP32(2.3, s1);
6273 ASSERT_EQUAL_FP32(2.3, dst[0]);
6274 ASSERT_EQUAL_FP32(1.2, dst[1]);
6275 ASSERT_EQUAL_FP32(2.3, s2);
6276 ASSERT_EQUAL_FP32(3.4, s3);
6277 ASSERT_EQUAL_FP32(3.4, dst[2]);
6278 ASSERT_EQUAL_FP32(2.3, dst[3]);
6279 ASSERT_EQUAL_FP32(3.4, s4);
6280 ASSERT_EQUAL_FP32(2.3, s5);
6281 ASSERT_EQUAL_FP32(3.4, dst[4]);
6282 ASSERT_EQUAL_FP32(2.3, dst[5]);
6283 ASSERT_EQUAL_64(src_base, x16);
6284 ASSERT_EQUAL_64(dst_base, x17);
6285 ASSERT_EQUAL_64(src_base + 12, x18);
6286 ASSERT_EQUAL_64(dst_base + 24, x19);
6287
6288 TEARDOWN();
6289}
6290
6291
6292TEST(ldnp_stnp_offset_double) {
6293 SETUP();
6294
6295 double src[3] = {1.2, 2.3, 3.4};
6296 double dst[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6297 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6298 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6299
6300 START();
6301 __ Mov(x16, src_base);
6302 __ Mov(x17, dst_base);
6303 __ Mov(x18, src_base + 24);
6304 __ Mov(x19, dst_base + 48);
6305
6306 // Ensure address set up has happened before executing non-temporal ops.
6307 __ Dmb(InnerShareable, BarrierAll);
6308
6309 __ Ldnp(d0, d1, MemOperand(x16));
6310 __ Ldnp(d2, d3, MemOperand(x16, 8));
6311 __ Ldnp(d5, d4, MemOperand(x18, -16));
6312 __ Stnp(d1, d0, MemOperand(x17));
6313 __ Stnp(d3, d2, MemOperand(x17, 16));
6314 __ Stnp(d4, d5, MemOperand(x19, -16));
6315 END();
6316
6317 RUN();
6318
6319 ASSERT_EQUAL_FP64(1.2, d0);
6320 ASSERT_EQUAL_FP64(2.3, d1);
6321 ASSERT_EQUAL_FP64(2.3, dst[0]);
6322 ASSERT_EQUAL_FP64(1.2, dst[1]);
6323 ASSERT_EQUAL_FP64(2.3, d2);
6324 ASSERT_EQUAL_FP64(3.4, d3);
6325 ASSERT_EQUAL_FP64(3.4, dst[2]);
6326 ASSERT_EQUAL_FP64(2.3, dst[3]);
6327 ASSERT_EQUAL_FP64(3.4, d4);
6328 ASSERT_EQUAL_FP64(2.3, d5);
6329 ASSERT_EQUAL_FP64(3.4, dst[4]);
6330 ASSERT_EQUAL_FP64(2.3, dst[5]);
6331 ASSERT_EQUAL_64(src_base, x16);
6332 ASSERT_EQUAL_64(dst_base, x17);
6333 ASSERT_EQUAL_64(src_base + 24, x18);
6334 ASSERT_EQUAL_64(dst_base + 48, x19);
armvixlad96eda2013-06-14 11:42:37 +01006335
6336 TEARDOWN();
6337}
6338
6339
6340TEST(ldp_stp_preindex) {
6341 SETUP();
6342
armvixlb0c8ae22014-03-21 14:03:59 +00006343 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6344 0xffeeddccbbaa9988};
armvixlad96eda2013-06-14 11:42:37 +01006345 uint64_t dst[5] = {0, 0, 0, 0, 0};
6346 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6347 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6348
6349 START();
6350 __ Mov(x16, src_base);
6351 __ Mov(x17, dst_base);
6352 __ Mov(x18, dst_base + 16);
6353 __ Ldp(w0, w1, MemOperand(x16, 4, PreIndex));
6354 __ Mov(x19, x16);
6355 __ Ldp(w2, w3, MemOperand(x16, -4, PreIndex));
6356 __ Stp(w2, w3, MemOperand(x17, 4, PreIndex));
6357 __ Mov(x20, x17);
6358 __ Stp(w0, w1, MemOperand(x17, -4, PreIndex));
6359 __ Ldp(x4, x5, MemOperand(x16, 8, PreIndex));
6360 __ Mov(x21, x16);
6361 __ Ldp(x6, x7, MemOperand(x16, -8, PreIndex));
6362 __ Stp(x7, x6, MemOperand(x18, 8, PreIndex));
6363 __ Mov(x22, x18);
6364 __ Stp(x5, x4, MemOperand(x18, -8, PreIndex));
6365 END();
6366
6367 RUN();
6368
6369 ASSERT_EQUAL_64(0x00112233, x0);
6370 ASSERT_EQUAL_64(0xccddeeff, x1);
6371 ASSERT_EQUAL_64(0x44556677, x2);
6372 ASSERT_EQUAL_64(0x00112233, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006373 ASSERT_EQUAL_64(0xccddeeff00112233, dst[0]);
6374 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6375 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6376 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6377 ASSERT_EQUAL_64(0x0011223344556677, x6);
6378 ASSERT_EQUAL_64(0x8899aabbccddeeff, x7);
6379 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6380 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6381 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01006382 ASSERT_EQUAL_64(src_base, x16);
6383 ASSERT_EQUAL_64(dst_base, x17);
6384 ASSERT_EQUAL_64(dst_base + 16, x18);
6385 ASSERT_EQUAL_64(src_base + 4, x19);
6386 ASSERT_EQUAL_64(dst_base + 4, x20);
6387 ASSERT_EQUAL_64(src_base + 8, x21);
6388 ASSERT_EQUAL_64(dst_base + 24, x22);
6389
6390 TEARDOWN();
6391}
6392
6393
armvixlc68cb642014-09-25 18:49:30 +01006394TEST(ldp_stp_preindex_wide) {
6395 SETUP();
6396
6397 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
6398 0xffeeddccbbaa9988};
6399 uint64_t dst[5] = {0, 0, 0, 0, 0};
6400 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6401 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6402 // Move base too far from the array to force multiple instructions
6403 // to be emitted.
6404 const int64_t base_offset = 1024;
6405
6406 START();
6407 __ Mov(x24, src_base - base_offset);
6408 __ Mov(x25, dst_base + base_offset);
6409 __ Mov(x18, dst_base + base_offset + 16);
6410 __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PreIndex));
6411 __ Mov(x19, x24);
6412 __ Mov(x24, src_base - base_offset + 4);
6413 __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PreIndex));
6414 __ Stp(w2, w3, MemOperand(x25, 4 - base_offset , PreIndex));
6415 __ Mov(x20, x25);
6416 __ Mov(x25, dst_base + base_offset + 4);
6417 __ Mov(x24, src_base - base_offset);
6418 __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PreIndex));
6419 __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PreIndex));
6420 __ Mov(x21, x24);
6421 __ Mov(x24, src_base - base_offset + 8);
6422 __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PreIndex));
6423 __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PreIndex));
6424 __ Mov(x22, x18);
6425 __ Mov(x18, dst_base + base_offset + 16 + 8);
6426 __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PreIndex));
6427 END();
6428
6429 RUN();
6430
6431 ASSERT_EQUAL_64(0x00112233, x0);
6432 ASSERT_EQUAL_64(0xccddeeff, x1);
6433 ASSERT_EQUAL_64(0x44556677, x2);
6434 ASSERT_EQUAL_64(0x00112233, x3);
6435 ASSERT_EQUAL_64(0xccddeeff00112233, dst[0]);
6436 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6437 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
6438 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
6439 ASSERT_EQUAL_64(0x0011223344556677, x6);
6440 ASSERT_EQUAL_64(0x8899aabbccddeeff, x7);
6441 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6442 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6443 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
6444 ASSERT_EQUAL_64(src_base, x24);
6445 ASSERT_EQUAL_64(dst_base, x25);
6446 ASSERT_EQUAL_64(dst_base + 16, x18);
6447 ASSERT_EQUAL_64(src_base + 4, x19);
6448 ASSERT_EQUAL_64(dst_base + 4, x20);
6449 ASSERT_EQUAL_64(src_base + 8, x21);
6450 ASSERT_EQUAL_64(dst_base + 24, x22);
6451
6452 TEARDOWN();
6453}
6454
6455
armvixlad96eda2013-06-14 11:42:37 +01006456TEST(ldp_stp_postindex) {
6457 SETUP();
6458
armvixlb0c8ae22014-03-21 14:03:59 +00006459 uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
6460 0xffeeddccbbaa9988, 0x7766554433221100};
armvixlad96eda2013-06-14 11:42:37 +01006461 uint64_t dst[5] = {0, 0, 0, 0, 0};
6462 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6463 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6464
6465 START();
6466 __ Mov(x16, src_base);
6467 __ Mov(x17, dst_base);
6468 __ Mov(x18, dst_base + 16);
6469 __ Ldp(w0, w1, MemOperand(x16, 4, PostIndex));
6470 __ Mov(x19, x16);
6471 __ Ldp(w2, w3, MemOperand(x16, -4, PostIndex));
6472 __ Stp(w2, w3, MemOperand(x17, 4, PostIndex));
6473 __ Mov(x20, x17);
6474 __ Stp(w0, w1, MemOperand(x17, -4, PostIndex));
6475 __ Ldp(x4, x5, MemOperand(x16, 8, PostIndex));
6476 __ Mov(x21, x16);
6477 __ Ldp(x6, x7, MemOperand(x16, -8, PostIndex));
6478 __ Stp(x7, x6, MemOperand(x18, 8, PostIndex));
6479 __ Mov(x22, x18);
6480 __ Stp(x5, x4, MemOperand(x18, -8, PostIndex));
6481 END();
6482
6483 RUN();
6484
6485 ASSERT_EQUAL_64(0x44556677, x0);
6486 ASSERT_EQUAL_64(0x00112233, x1);
6487 ASSERT_EQUAL_64(0x00112233, x2);
6488 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006489 ASSERT_EQUAL_64(0x4455667700112233, dst[0]);
6490 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6491 ASSERT_EQUAL_64(0x0011223344556677, x4);
6492 ASSERT_EQUAL_64(0x8899aabbccddeeff, x5);
6493 ASSERT_EQUAL_64(0x8899aabbccddeeff, x6);
6494 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x7);
6495 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6496 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6497 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01006498 ASSERT_EQUAL_64(src_base, x16);
6499 ASSERT_EQUAL_64(dst_base, x17);
6500 ASSERT_EQUAL_64(dst_base + 16, x18);
6501 ASSERT_EQUAL_64(src_base + 4, x19);
6502 ASSERT_EQUAL_64(dst_base + 4, x20);
6503 ASSERT_EQUAL_64(src_base + 8, x21);
6504 ASSERT_EQUAL_64(dst_base + 24, x22);
6505
6506 TEARDOWN();
6507}
6508
6509
armvixlc68cb642014-09-25 18:49:30 +01006510TEST(ldp_stp_postindex_wide) {
6511 SETUP();
6512
6513 uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
6514 0xffeeddccbbaa9988, 0x7766554433221100};
6515 uint64_t dst[5] = {0, 0, 0, 0, 0};
6516 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6517 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6518 // Move base too far from the array to force multiple instructions
6519 // to be emitted.
6520 const int64_t base_offset = 1024;
6521
6522 START();
6523 __ Mov(x24, src_base);
6524 __ Mov(x25, dst_base);
6525 __ Mov(x18, dst_base + 16);
6526 __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PostIndex));
6527 __ Mov(x19, x24);
6528 __ Sub(x24, x24, base_offset);
6529 __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PostIndex));
6530 __ Stp(w2, w3, MemOperand(x25, 4 - base_offset, PostIndex));
6531 __ Mov(x20, x25);
6532 __ Sub(x24, x24, base_offset);
6533 __ Add(x25, x25, base_offset);
6534 __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PostIndex));
6535 __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PostIndex));
6536 __ Mov(x21, x24);
6537 __ Sub(x24, x24, base_offset);
6538 __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PostIndex));
6539 __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PostIndex));
6540 __ Mov(x22, x18);
6541 __ Add(x18, x18, base_offset);
6542 __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PostIndex));
6543 END();
6544
6545 RUN();
6546
6547 ASSERT_EQUAL_64(0x44556677, x0);
6548 ASSERT_EQUAL_64(0x00112233, x1);
6549 ASSERT_EQUAL_64(0x00112233, x2);
6550 ASSERT_EQUAL_64(0xccddeeff, x3);
6551 ASSERT_EQUAL_64(0x4455667700112233, dst[0]);
6552 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
6553 ASSERT_EQUAL_64(0x0011223344556677, x4);
6554 ASSERT_EQUAL_64(0x8899aabbccddeeff, x5);
6555 ASSERT_EQUAL_64(0x8899aabbccddeeff, x6);
6556 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x7);
6557 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
6558 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
6559 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
6560 ASSERT_EQUAL_64(src_base + base_offset, x24);
6561 ASSERT_EQUAL_64(dst_base - base_offset, x25);
6562 ASSERT_EQUAL_64(dst_base - base_offset + 16, x18);
6563 ASSERT_EQUAL_64(src_base + base_offset + 4, x19);
6564 ASSERT_EQUAL_64(dst_base - base_offset + 4, x20);
6565 ASSERT_EQUAL_64(src_base + base_offset + 8, x21);
6566 ASSERT_EQUAL_64(dst_base - base_offset + 24, x22);
6567
6568 TEARDOWN();
6569}
6570
6571
armvixlad96eda2013-06-14 11:42:37 +01006572TEST(ldp_sign_extend) {
6573 SETUP();
6574
6575 uint32_t src[2] = {0x80000000, 0x7fffffff};
6576 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6577
6578 START();
6579 __ Mov(x24, src_base);
6580 __ Ldpsw(x0, x1, MemOperand(x24));
6581 END();
6582
6583 RUN();
6584
armvixlb0c8ae22014-03-21 14:03:59 +00006585 ASSERT_EQUAL_64(0xffffffff80000000, x0);
6586 ASSERT_EQUAL_64(0x000000007fffffff, x1);
armvixlad96eda2013-06-14 11:42:37 +01006587
6588 TEARDOWN();
6589}
6590
6591
6592TEST(ldur_stur) {
6593 SETUP();
6594
armvixlb0c8ae22014-03-21 14:03:59 +00006595 int64_t src[2] = {0x0123456789abcdef, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01006596 int64_t dst[5] = {0, 0, 0, 0, 0};
6597 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6598 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6599
6600 START();
6601 __ Mov(x17, src_base);
6602 __ Mov(x18, dst_base);
6603 __ Mov(x19, src_base + 16);
6604 __ Mov(x20, dst_base + 32);
6605 __ Mov(x21, dst_base + 40);
6606 __ Ldr(w0, MemOperand(x17, 1));
6607 __ Str(w0, MemOperand(x18, 2));
6608 __ Ldr(x1, MemOperand(x17, 3));
6609 __ Str(x1, MemOperand(x18, 9));
6610 __ Ldr(w2, MemOperand(x19, -9));
6611 __ Str(w2, MemOperand(x20, -5));
6612 __ Ldrb(w3, MemOperand(x19, -1));
6613 __ Strb(w3, MemOperand(x21, -1));
6614 END();
6615
6616 RUN();
6617
6618 ASSERT_EQUAL_64(0x6789abcd, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00006619 ASSERT_EQUAL_64(0x00006789abcd0000, dst[0]);
6620 ASSERT_EQUAL_64(0xabcdef0123456789, x1);
6621 ASSERT_EQUAL_64(0xcdef012345678900, dst[1]);
armvixlad96eda2013-06-14 11:42:37 +01006622 ASSERT_EQUAL_64(0x000000ab, dst[2]);
6623 ASSERT_EQUAL_64(0xabcdef01, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00006624 ASSERT_EQUAL_64(0x00abcdef01000000, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01006625 ASSERT_EQUAL_64(0x00000001, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00006626 ASSERT_EQUAL_64(0x0100000000000000, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01006627 ASSERT_EQUAL_64(src_base, x17);
6628 ASSERT_EQUAL_64(dst_base, x18);
6629 ASSERT_EQUAL_64(src_base + 16, x19);
6630 ASSERT_EQUAL_64(dst_base + 32, x20);
6631
6632 TEARDOWN();
6633}
6634
6635
armvixl5289c592015-03-02 13:52:04 +00006636TEST(ldur_stur_fp) {
6637 SETUP();
6638
6639 int64_t src[3] = {0x0123456789abcdef, 0x0123456789abcdef,
6640 0x0123456789abcdef};
6641 int64_t dst[5] = {0, 0, 0, 0, 0};
6642 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
6643 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
6644
6645 START();
6646 __ Mov(x17, src_base);
6647 __ Mov(x18, dst_base);
6648 __ Ldr(b0, MemOperand(x17));
6649 __ Str(b0, MemOperand(x18));
6650 __ Ldr(h1, MemOperand(x17, 1));
6651 __ Str(h1, MemOperand(x18, 1));
6652 __ Ldr(s2, MemOperand(x17, 2));
6653 __ Str(s2, MemOperand(x18, 3));
6654 __ Ldr(d3, MemOperand(x17, 3));
6655 __ Str(d3, MemOperand(x18, 7));
6656 __ Ldr(q4, MemOperand(x17, 4));
6657 __ Str(q4, MemOperand(x18, 15));
6658 END();
6659
6660 RUN();
6661
6662 ASSERT_EQUAL_128(0, 0xef, q0);
6663 ASSERT_EQUAL_128(0, 0xabcd, q1);
6664 ASSERT_EQUAL_128(0, 0x456789ab, q2);
6665 ASSERT_EQUAL_128(0, 0xabcdef0123456789, q3);
6666 ASSERT_EQUAL_128(0x89abcdef01234567, 0x89abcdef01234567, q4);
6667 ASSERT_EQUAL_64(0x89456789ababcdef, dst[0]);
6668 ASSERT_EQUAL_64(0x67abcdef01234567, dst[1]);
6669 ASSERT_EQUAL_64(0x6789abcdef012345, dst[2]);
6670 ASSERT_EQUAL_64(0x0089abcdef012345, dst[3]);
6671
6672 TEARDOWN();
6673}
6674
6675
armvixlad96eda2013-06-14 11:42:37 +01006676TEST(ldr_literal) {
6677 SETUP();
6678
6679 START();
armvixlb0c8ae22014-03-21 14:03:59 +00006680 __ Ldr(x2, 0x1234567890abcdef);
armvixlad96eda2013-06-14 11:42:37 +01006681 __ Ldr(w3, 0xfedcba09);
armvixlc68cb642014-09-25 18:49:30 +01006682 __ Ldrsw(x4, 0x7fffffff);
6683 __ Ldrsw(x5, 0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006684 __ Ldr(q11, 0x1234000056780000, 0xabcd0000ef000000);
armvixlad96eda2013-06-14 11:42:37 +01006685 __ Ldr(d13, 1.234);
6686 __ Ldr(s25, 2.5);
6687 END();
6688
6689 RUN();
6690
armvixlb0c8ae22014-03-21 14:03:59 +00006691 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
armvixlad96eda2013-06-14 11:42:37 +01006692 ASSERT_EQUAL_64(0xfedcba09, x3);
armvixlc68cb642014-09-25 18:49:30 +01006693 ASSERT_EQUAL_64(0x7fffffff, x4);
6694 ASSERT_EQUAL_64(0xffffffff80000000, x5);
armvixl5289c592015-03-02 13:52:04 +00006695 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
armvixlad96eda2013-06-14 11:42:37 +01006696 ASSERT_EQUAL_FP64(1.234, d13);
6697 ASSERT_EQUAL_FP32(2.5, s25);
6698
6699 TEARDOWN();
6700}
6701
6702
armvixlc68cb642014-09-25 18:49:30 +01006703TEST(ldr_literal_range) {
6704 SETUP();
armvixlad96eda2013-06-14 11:42:37 +01006705
6706 START();
armvixlc68cb642014-09-25 18:49:30 +01006707 // Make sure the pool is empty;
6708 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
armvixlad96eda2013-06-14 11:42:37 +01006709 ASSERT_LITERAL_POOL_SIZE(0);
6710
armvixlc68cb642014-09-25 18:49:30 +01006711 // Create some literal pool entries.
armvixlb0c8ae22014-03-21 14:03:59 +00006712 __ Ldr(x0, 0x1234567890abcdef);
armvixlad96eda2013-06-14 11:42:37 +01006713 __ Ldr(w1, 0xfedcba09);
armvixlc68cb642014-09-25 18:49:30 +01006714 __ Ldrsw(x2, 0x7fffffff);
6715 __ Ldrsw(x3, 0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006716 __ Ldr(q2, 0x1234000056780000, 0xabcd0000ef000000);
armvixlad96eda2013-06-14 11:42:37 +01006717 __ Ldr(d0, 1.234);
6718 __ Ldr(s1, 2.5);
armvixl5289c592015-03-02 13:52:04 +00006719 ASSERT_LITERAL_POOL_SIZE(48);
armvixlad96eda2013-06-14 11:42:37 +01006720
armvixlc68cb642014-09-25 18:49:30 +01006721 // Emit more code than the maximum literal load range to ensure the pool
6722 // should be emitted.
armvixl330dc712014-11-25 10:38:32 +00006723 const ptrdiff_t end = masm.CursorOffset() + 2 * kMaxLoadLiteralRange;
6724 while (masm.CursorOffset() < end) {
armvixlad96eda2013-06-14 11:42:37 +01006725 __ Nop();
armvixlad96eda2013-06-14 11:42:37 +01006726 }
6727
armvixlc68cb642014-09-25 18:49:30 +01006728 // The pool should have been emitted.
armvixlad96eda2013-06-14 11:42:37 +01006729 ASSERT_LITERAL_POOL_SIZE(0);
6730
6731 // These loads should be after the pool (and will require a new one).
armvixlb0c8ae22014-03-21 14:03:59 +00006732 __ Ldr(x4, 0x34567890abcdef12);
armvixlad96eda2013-06-14 11:42:37 +01006733 __ Ldr(w5, 0xdcba09fe);
armvixlc68cb642014-09-25 18:49:30 +01006734 __ Ldrsw(x6, 0x7fffffff);
6735 __ Ldrsw(x7, 0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006736 __ Ldr(q6, 0x1234000056780000, 0xabcd0000ef000000);
armvixlad96eda2013-06-14 11:42:37 +01006737 __ Ldr(d4, 123.4);
6738 __ Ldr(s5, 250.0);
armvixl5289c592015-03-02 13:52:04 +00006739 ASSERT_LITERAL_POOL_SIZE(48);
armvixlad96eda2013-06-14 11:42:37 +01006740 END();
6741
6742 RUN();
6743
6744 // Check that the literals loaded correctly.
armvixlb0c8ae22014-03-21 14:03:59 +00006745 ASSERT_EQUAL_64(0x1234567890abcdef, x0);
armvixlad96eda2013-06-14 11:42:37 +01006746 ASSERT_EQUAL_64(0xfedcba09, x1);
armvixlc68cb642014-09-25 18:49:30 +01006747 ASSERT_EQUAL_64(0x7fffffff, x2);
6748 ASSERT_EQUAL_64(0xffffffff80000000, x3);
armvixl5289c592015-03-02 13:52:04 +00006749 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q2);
armvixlad96eda2013-06-14 11:42:37 +01006750 ASSERT_EQUAL_FP64(1.234, d0);
6751 ASSERT_EQUAL_FP32(2.5, s1);
armvixlb0c8ae22014-03-21 14:03:59 +00006752 ASSERT_EQUAL_64(0x34567890abcdef12, x4);
armvixlad96eda2013-06-14 11:42:37 +01006753 ASSERT_EQUAL_64(0xdcba09fe, x5);
armvixlc68cb642014-09-25 18:49:30 +01006754 ASSERT_EQUAL_64(0x7fffffff, x6);
6755 ASSERT_EQUAL_64(0xffffffff80000000, x7);
armvixl5289c592015-03-02 13:52:04 +00006756 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q6);
armvixlad96eda2013-06-14 11:42:37 +01006757 ASSERT_EQUAL_FP64(123.4, d4);
6758 ASSERT_EQUAL_FP32(250.0, s5);
6759
6760 TEARDOWN();
6761}
6762
6763
armvixl5289c592015-03-02 13:52:04 +00006764TEST(ldr_literal_values_q) {
6765 SETUP();
6766
6767 static const uint64_t kHalfValues[] = {
6768 0x8000000000000000, 0x7fffffffffffffff, 0x0000000000000000,
6769 0xffffffffffffffff, 0x00ff00ff00ff00ff, 0x1234567890abcdef
6770 };
6771 const int card = sizeof(kHalfValues) / sizeof(kHalfValues[0]);
6772 const Register& ref_low64 = x1;
6773 const Register& ref_high64 = x2;
6774 const Register& loaded_low64 = x3;
6775 const Register& loaded_high64 = x4;
6776 const VRegister& tgt = q0;
6777
6778 START();
6779 __ Mov(x0, 0);
6780
6781 for (int i = 0; i < card; i++) {
6782 __ Mov(ref_low64, kHalfValues[i]);
6783 for (int j = 0; j < card; j++) {
6784 __ Mov(ref_high64, kHalfValues[j]);
6785 __ Ldr(tgt, kHalfValues[j], kHalfValues[i]);
6786 __ Mov(loaded_low64, tgt.V2D(), 0);
6787 __ Mov(loaded_high64, tgt.V2D(), 1);
6788 __ Cmp(loaded_low64, ref_low64);
6789 __ Ccmp(loaded_high64, ref_high64, NoFlag, eq);
6790 __ Cset(x0, ne);
6791 }
6792 }
6793 END();
6794
6795 RUN();
6796
6797 // If one of the values differs, the trace can be used to identify which one.
6798 ASSERT_EQUAL_64(0, x0);
6799
6800 TEARDOWN();
6801}
6802
6803
armvixlc68cb642014-09-25 18:49:30 +01006804template <typename T>
6805void LoadIntValueHelper(T values[], int card) {
6806 SETUP();
6807
6808 const bool is_32bits = (sizeof(T) == 4);
6809 const Register& tgt1 = is_32bits ? w1 : x1;
6810 const Register& tgt2 = is_32bits ? w2 : x2;
6811
6812 START();
6813 __ Mov(x0, 0);
6814
6815 // If one of the values differ then x0 will be one.
6816 for (int i = 0; i < card; ++i) {
6817 __ Mov(tgt1, values[i]);
6818 __ Ldr(tgt2, values[i]);
6819 __ Cmp(tgt1, tgt2);
6820 __ Cset(x0, ne);
6821 }
6822 END();
6823
6824 RUN();
6825
6826 // If one of the values differs, the trace can be used to identify which one.
6827 ASSERT_EQUAL_64(0, x0);
6828
6829 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +01006830}
6831
6832
armvixlc68cb642014-09-25 18:49:30 +01006833TEST(ldr_literal_values_x) {
6834 static const uint64_t kValues[] = {
6835 0x8000000000000000, 0x7fffffffffffffff, 0x0000000000000000,
6836 0xffffffffffffffff, 0x00ff00ff00ff00ff, 0x1234567890abcdef
6837 };
6838
6839 LoadIntValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006840}
6841
6842
armvixlc68cb642014-09-25 18:49:30 +01006843TEST(ldr_literal_values_w) {
6844 static const uint32_t kValues[] = {
6845 0x80000000, 0x7fffffff, 0x00000000, 0xffffffff, 0x00ff00ff, 0x12345678,
6846 0x90abcdef
6847 };
6848
6849 LoadIntValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006850}
6851
6852
armvixlc68cb642014-09-25 18:49:30 +01006853template <typename T>
6854void LoadFPValueHelper(T values[], int card) {
6855 SETUP();
6856
6857 const bool is_32bits = (sizeof(T) == 4);
6858 const FPRegister& fp_tgt = is_32bits ? s2 : d2;
6859 const Register& tgt1 = is_32bits ? w1 : x1;
6860 const Register& tgt2 = is_32bits ? w2 : x2;
6861
6862 START();
6863 __ Mov(x0, 0);
6864
6865 // If one of the values differ then x0 will be one.
6866 for (int i = 0; i < card; ++i) {
6867 __ Mov(tgt1, is_32bits ? float_to_rawbits(values[i])
6868 : double_to_rawbits(values[i]));
6869 __ Ldr(fp_tgt, values[i]);
6870 __ Fmov(tgt2, fp_tgt);
6871 __ Cmp(tgt1, tgt2);
6872 __ Cset(x0, ne);
6873 }
6874 END();
6875
6876 RUN();
6877
6878 // If one of the values differs, the trace can be used to identify which one.
6879 ASSERT_EQUAL_64(0, x0);
6880
6881 TEARDOWN();
6882}
6883
6884TEST(ldr_literal_values_d) {
6885 static const double kValues[] = {
6886 -0.0, 0.0, -1.0, 1.0, -1e10, 1e10
6887 };
6888
6889 LoadFPValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006890}
6891
6892
armvixlc68cb642014-09-25 18:49:30 +01006893TEST(ldr_literal_values_s) {
6894 static const float kValues[] = {
6895 -0.0, 0.0, -1.0, 1.0, -1e10, 1e10
6896 };
6897
6898 LoadFPValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
armvixlad96eda2013-06-14 11:42:37 +01006899}
6900
6901
armvixlc68cb642014-09-25 18:49:30 +01006902TEST(ldr_literal_custom) {
armvixlc68cb642014-09-25 18:49:30 +01006903 SETUP();
6904 ALLOW_ASM();
6905
armvixl330dc712014-11-25 10:38:32 +00006906 Label end_of_pool_before;
6907 Label end_of_pool_after;
6908 Literal<uint64_t> before_x(0x1234567890abcdef);
6909 Literal<uint32_t> before_w(0xfedcba09);
6910 Literal<uint32_t> before_sx(0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006911 Literal<uint64_t> before_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006912 Literal<double> before_d(1.234);
6913 Literal<float> before_s(2.5);
6914 Literal<uint64_t> after_x(0x1234567890abcdef);
6915 Literal<uint32_t> after_w(0xfedcba09);
6916 Literal<uint32_t> after_sx(0x80000000);
armvixl5289c592015-03-02 13:52:04 +00006917 Literal<uint64_t> after_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006918 Literal<double> after_d(1.234);
6919 Literal<float> after_s(2.5);
armvixlc68cb642014-09-25 18:49:30 +01006920
6921 START();
armvixlc68cb642014-09-25 18:49:30 +01006922
armvixl330dc712014-11-25 10:38:32 +00006923 // Manually generate a pool.
6924 __ B(&end_of_pool_before);
6925 __ place(&before_x);
6926 __ place(&before_w);
6927 __ place(&before_sx);
armvixl5289c592015-03-02 13:52:04 +00006928 __ place(&before_q);
armvixl330dc712014-11-25 10:38:32 +00006929 __ place(&before_d);
6930 __ place(&before_s);
6931 __ Bind(&end_of_pool_before);
6932
6933 __ ldr(x2, &before_x);
6934 __ ldr(w3, &before_w);
6935 __ ldrsw(x5, &before_sx);
armvixl5289c592015-03-02 13:52:04 +00006936 __ ldr(q11, &before_q);
armvixl330dc712014-11-25 10:38:32 +00006937 __ ldr(d13, &before_d);
6938 __ ldr(s25, &before_s);
6939
6940 __ ldr(x6, &after_x);
6941 __ ldr(w7, &after_w);
6942 __ ldrsw(x8, &after_sx);
armvixl5289c592015-03-02 13:52:04 +00006943 __ ldr(q18, &after_q);
armvixl330dc712014-11-25 10:38:32 +00006944 __ ldr(d14, &after_d);
6945 __ ldr(s26, &after_s);
6946
6947 // Manually generate a pool.
6948 __ B(&end_of_pool_after);
6949 __ place(&after_x);
6950 __ place(&after_w);
6951 __ place(&after_sx);
armvixl5289c592015-03-02 13:52:04 +00006952 __ place(&after_q);
armvixl330dc712014-11-25 10:38:32 +00006953 __ place(&after_d);
6954 __ place(&after_s);
6955 __ Bind(&end_of_pool_after);
6956
armvixlc68cb642014-09-25 18:49:30 +01006957 END();
6958
6959 RUN();
6960
6961 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
6962 ASSERT_EQUAL_64(0xfedcba09, x3);
6963 ASSERT_EQUAL_64(0xffffffff80000000, x5);
armvixl5289c592015-03-02 13:52:04 +00006964 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
armvixlc68cb642014-09-25 18:49:30 +01006965 ASSERT_EQUAL_FP64(1.234, d13);
6966 ASSERT_EQUAL_FP32(2.5, s25);
6967
armvixl330dc712014-11-25 10:38:32 +00006968 ASSERT_EQUAL_64(0x1234567890abcdef, x6);
6969 ASSERT_EQUAL_64(0xfedcba09, x7);
6970 ASSERT_EQUAL_64(0xffffffff80000000, x8);
armvixl5289c592015-03-02 13:52:04 +00006971 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q18);
armvixl330dc712014-11-25 10:38:32 +00006972 ASSERT_EQUAL_FP64(1.234, d14);
6973 ASSERT_EQUAL_FP32(2.5, s26);
6974
6975 TEARDOWN();
6976}
6977
6978
6979TEST(ldr_literal_custom_shared) {
6980 SETUP();
6981 ALLOW_ASM();
6982
6983 Label end_of_pool_before;
6984 Label end_of_pool_after;
6985 Literal<uint64_t> before_x(0x1234567890abcdef);
6986 Literal<uint32_t> before_w(0xfedcba09);
armvixl5289c592015-03-02 13:52:04 +00006987 Literal<uint64_t> before_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006988 Literal<double> before_d(1.234);
6989 Literal<float> before_s(2.5);
6990 Literal<uint64_t> after_x(0x1234567890abcdef);
6991 Literal<uint32_t> after_w(0xfedcba09);
armvixl5289c592015-03-02 13:52:04 +00006992 Literal<uint64_t> after_q(0x1234000056780000, 0xabcd0000ef000000);
armvixl330dc712014-11-25 10:38:32 +00006993 Literal<double> after_d(1.234);
6994 Literal<float> after_s(2.5);
6995
6996 START();
6997
6998 // Manually generate a pool.
6999 __ B(&end_of_pool_before);
7000 __ place(&before_x);
7001 __ place(&before_w);
armvixl5289c592015-03-02 13:52:04 +00007002 __ place(&before_q);
armvixl330dc712014-11-25 10:38:32 +00007003 __ place(&before_d);
7004 __ place(&before_s);
7005 __ Bind(&end_of_pool_before);
7006
7007 // Load the entries several times to test that literals can be shared.
7008 for (int i = 0; i < 50; i++) {
7009 __ ldr(x2, &before_x);
7010 __ ldr(w3, &before_w);
7011 __ ldrsw(x5, &before_w); // Re-use before_w.
armvixl5289c592015-03-02 13:52:04 +00007012 __ ldr(q11, &before_q);
armvixl330dc712014-11-25 10:38:32 +00007013 __ ldr(d13, &before_d);
7014 __ ldr(s25, &before_s);
7015
7016 __ ldr(x6, &after_x);
7017 __ ldr(w7, &after_w);
7018 __ ldrsw(x8, &after_w); // Re-use after_w.
armvixl5289c592015-03-02 13:52:04 +00007019 __ ldr(q18, &after_q);
armvixl330dc712014-11-25 10:38:32 +00007020 __ ldr(d14, &after_d);
7021 __ ldr(s26, &after_s);
7022 }
7023
7024 // Manually generate a pool.
7025 __ B(&end_of_pool_after);
7026 __ place(&after_x);
7027 __ place(&after_w);
armvixl5289c592015-03-02 13:52:04 +00007028 __ place(&after_q);
armvixl330dc712014-11-25 10:38:32 +00007029 __ place(&after_d);
7030 __ place(&after_s);
7031 __ Bind(&end_of_pool_after);
7032
7033 END();
7034
7035 RUN();
7036
7037 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
7038 ASSERT_EQUAL_64(0xfedcba09, x3);
7039 ASSERT_EQUAL_64(0xfffffffffedcba09, x5);
armvixl5289c592015-03-02 13:52:04 +00007040 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
armvixl330dc712014-11-25 10:38:32 +00007041 ASSERT_EQUAL_FP64(1.234, d13);
7042 ASSERT_EQUAL_FP32(2.5, s25);
7043
7044 ASSERT_EQUAL_64(0x1234567890abcdef, x6);
7045 ASSERT_EQUAL_64(0xfedcba09, x7);
7046 ASSERT_EQUAL_64(0xfffffffffedcba09, x8);
armvixl5289c592015-03-02 13:52:04 +00007047 ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q18);
armvixl330dc712014-11-25 10:38:32 +00007048 ASSERT_EQUAL_FP64(1.234, d14);
7049 ASSERT_EQUAL_FP32(2.5, s26);
7050
7051 TEARDOWN();
7052}
7053
7054
7055TEST(prfm_offset) {
7056 SETUP();
7057
7058 START();
7059 // The address used in prfm doesn't have to be valid.
7060 __ Mov(x0, 0x0123456789abcdef);
7061
7062 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7063 // Unallocated prefetch operations are ignored, so test all of them.
7064 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7065
7066 __ Prfm(op, MemOperand(x0));
7067 __ Prfm(op, MemOperand(x0, 8));
7068 __ Prfm(op, MemOperand(x0, 32760));
7069 __ Prfm(op, MemOperand(x0, 32768));
7070
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 __ Prfm(op, MemOperand(x0, -1));
7076 __ Prfm(op, MemOperand(x0, -9));
7077 __ Prfm(op, MemOperand(x0, -255));
7078 __ Prfm(op, MemOperand(x0, -257));
7079
7080 __ Prfm(op, MemOperand(x0, 0xfedcba9876543210));
7081 }
7082
7083 END();
7084 RUN();
7085 TEARDOWN();
7086}
7087
7088
7089TEST(prfm_regoffset) {
7090 SETUP();
7091
7092 START();
7093 // The address used in prfm doesn't have to be valid.
7094 __ Mov(x0, 0x0123456789abcdef);
7095
7096 CPURegList inputs(CPURegister::kRegister, kXRegSize, 10, 18);
7097 __ Mov(x10, 0);
7098 __ Mov(x11, 1);
7099 __ Mov(x12, 8);
7100 __ Mov(x13, 255);
7101 __ Mov(x14, -0);
7102 __ Mov(x15, -1);
7103 __ Mov(x16, -8);
7104 __ Mov(x17, -255);
7105 __ Mov(x18, 0xfedcba9876543210);
7106
7107 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7108 // Unallocated prefetch operations are ignored, so test all of them.
7109 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7110
7111 CPURegList loop = inputs;
7112 while (!loop.IsEmpty()) {
7113 Register input(loop.PopLowestIndex());
7114 __ Prfm(op, MemOperand(x0, input));
7115 __ Prfm(op, MemOperand(x0, input, UXTW));
7116 __ Prfm(op, MemOperand(x0, input, UXTW, 3));
7117 __ Prfm(op, MemOperand(x0, input, LSL));
7118 __ Prfm(op, MemOperand(x0, input, LSL, 3));
7119 __ Prfm(op, MemOperand(x0, input, SXTW));
7120 __ Prfm(op, MemOperand(x0, input, SXTW, 3));
7121 __ Prfm(op, MemOperand(x0, input, SXTX));
7122 __ Prfm(op, MemOperand(x0, input, SXTX, 3));
7123 }
7124 }
7125
7126 END();
7127 RUN();
7128 TEARDOWN();
7129}
7130
7131
7132TEST(prfm_literal_imm19) {
7133 SETUP();
7134 ALLOW_ASM();
7135 START();
7136
7137 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7138 // Unallocated prefetch operations are ignored, so test all of them.
7139 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7140
7141 // The address used in prfm doesn't have to be valid.
7142 __ prfm(op, 0);
7143 __ prfm(op, 1);
7144 __ prfm(op, -1);
7145 __ prfm(op, 1000);
7146 __ prfm(op, -1000);
7147 __ prfm(op, 0x3ffff);
7148 __ prfm(op, -0x40000);
7149 }
7150
7151 END();
7152 RUN();
7153 TEARDOWN();
7154}
7155
7156
7157TEST(prfm_literal) {
7158 SETUP();
7159 ALLOW_ASM();
7160
7161 Label end_of_pool_before;
7162 Label end_of_pool_after;
7163 Literal<uint64_t> before(0);
7164 Literal<uint64_t> after(0);
7165
7166 START();
7167
7168 // Manually generate a pool.
7169 __ B(&end_of_pool_before);
7170 __ place(&before);
7171 __ Bind(&end_of_pool_before);
7172
7173 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7174 // Unallocated prefetch operations are ignored, so test all of them.
7175 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7176
7177 CodeBufferCheckScope guard(&masm, 2 * kInstructionSize);
7178 __ prfm(op, &before);
7179 __ prfm(op, &after);
7180 }
7181
7182 // Manually generate a pool.
7183 __ B(&end_of_pool_after);
7184 __ place(&after);
7185 __ Bind(&end_of_pool_after);
7186
7187 END();
7188 RUN();
7189 TEARDOWN();
7190}
7191
7192
7193TEST(prfm_wide) {
7194 SETUP();
7195
7196 START();
7197 // The address used in prfm doesn't have to be valid.
7198 __ Mov(x0, 0x0123456789abcdef);
7199
7200 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7201 // Unallocated prefetch operations are ignored, so test all of them.
7202 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7203
7204 __ Prfm(op, MemOperand(x0, 0x40000));
7205 __ Prfm(op, MemOperand(x0, -0x40001));
7206 __ Prfm(op, MemOperand(x0, UINT64_C(0x5555555555555555)));
7207 __ Prfm(op, MemOperand(x0, UINT64_C(0xfedcba9876543210)));
7208 }
7209
7210 END();
7211 RUN();
7212 TEARDOWN();
7213}
7214
7215
7216TEST(load_prfm_literal) {
7217 // Test literals shared between both prfm and ldr.
7218 SETUP();
7219 ALLOW_ASM();
7220
7221 Label end_of_pool_before;
7222 Label end_of_pool_after;
7223 Literal<uint64_t> before_x(0x1234567890abcdef);
7224 Literal<uint32_t> before_w(0xfedcba09);
7225 Literal<uint32_t> before_sx(0x80000000);
7226 Literal<double> before_d(1.234);
7227 Literal<float> before_s(2.5);
7228 Literal<uint64_t> after_x(0x1234567890abcdef);
7229 Literal<uint32_t> after_w(0xfedcba09);
7230 Literal<uint32_t> after_sx(0x80000000);
7231 Literal<double> after_d(1.234);
7232 Literal<float> after_s(2.5);
7233
7234 START();
7235
7236 // Manually generate a pool.
7237 __ B(&end_of_pool_before);
7238 __ place(&before_x);
7239 __ place(&before_w);
7240 __ place(&before_sx);
7241 __ place(&before_d);
7242 __ place(&before_s);
7243 __ Bind(&end_of_pool_before);
7244
7245 for (int i = 0; i < (1 << ImmPrefetchOperation_width); i++) {
7246 // Unallocated prefetch operations are ignored, so test all of them.
7247 PrefetchOperation op = static_cast<PrefetchOperation>(i);
7248
7249 __ prfm(op, &before_x);
7250 __ prfm(op, &before_w);
7251 __ prfm(op, &before_sx);
7252 __ prfm(op, &before_d);
7253 __ prfm(op, &before_s);
7254
7255 __ prfm(op, &after_x);
7256 __ prfm(op, &after_w);
7257 __ prfm(op, &after_sx);
7258 __ prfm(op, &after_d);
7259 __ prfm(op, &after_s);
7260 }
7261
7262 __ ldr(x2, &before_x);
7263 __ ldr(w3, &before_w);
7264 __ ldrsw(x5, &before_sx);
7265 __ ldr(d13, &before_d);
7266 __ ldr(s25, &before_s);
7267
7268 __ ldr(x6, &after_x);
7269 __ ldr(w7, &after_w);
7270 __ ldrsw(x8, &after_sx);
7271 __ ldr(d14, &after_d);
7272 __ ldr(s26, &after_s);
7273
7274 // Manually generate a pool.
7275 __ B(&end_of_pool_after);
7276 __ place(&after_x);
7277 __ place(&after_w);
7278 __ place(&after_sx);
7279 __ place(&after_d);
7280 __ place(&after_s);
7281 __ Bind(&end_of_pool_after);
7282
7283 END();
7284
7285 RUN();
7286
7287 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
7288 ASSERT_EQUAL_64(0xfedcba09, x3);
7289 ASSERT_EQUAL_64(0xffffffff80000000, x5);
7290 ASSERT_EQUAL_FP64(1.234, d13);
7291 ASSERT_EQUAL_FP32(2.5, s25);
7292
7293 ASSERT_EQUAL_64(0x1234567890abcdef, x6);
7294 ASSERT_EQUAL_64(0xfedcba09, x7);
7295 ASSERT_EQUAL_64(0xffffffff80000000, x8);
7296 ASSERT_EQUAL_FP64(1.234, d14);
7297 ASSERT_EQUAL_FP32(2.5, s26);
7298
armvixlc68cb642014-09-25 18:49:30 +01007299 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +01007300}
7301
7302
7303TEST(add_sub_imm) {
7304 SETUP();
7305
7306 START();
7307 __ Mov(x0, 0x0);
7308 __ Mov(x1, 0x1111);
armvixlb0c8ae22014-03-21 14:03:59 +00007309 __ Mov(x2, 0xffffffffffffffff);
7310 __ Mov(x3, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01007311
7312 __ Add(x10, x0, Operand(0x123));
7313 __ Add(x11, x1, Operand(0x122000));
7314 __ Add(x12, x0, Operand(0xabc << 12));
7315 __ Add(x13, x2, Operand(1));
7316
7317 __ Add(w14, w0, Operand(0x123));
7318 __ Add(w15, w1, Operand(0x122000));
7319 __ Add(w16, w0, Operand(0xabc << 12));
7320 __ Add(w17, w2, Operand(1));
7321
7322 __ Sub(x20, x0, Operand(0x1));
7323 __ Sub(x21, x1, Operand(0x111));
7324 __ Sub(x22, x1, Operand(0x1 << 12));
7325 __ Sub(x23, x3, Operand(1));
7326
7327 __ Sub(w24, w0, Operand(0x1));
7328 __ Sub(w25, w1, Operand(0x111));
7329 __ Sub(w26, w1, Operand(0x1 << 12));
7330 __ Sub(w27, w3, Operand(1));
7331 END();
7332
7333 RUN();
7334
7335 ASSERT_EQUAL_64(0x123, x10);
7336 ASSERT_EQUAL_64(0x123111, x11);
7337 ASSERT_EQUAL_64(0xabc000, x12);
7338 ASSERT_EQUAL_64(0x0, x13);
7339
7340 ASSERT_EQUAL_32(0x123, w14);
7341 ASSERT_EQUAL_32(0x123111, w15);
7342 ASSERT_EQUAL_32(0xabc000, w16);
7343 ASSERT_EQUAL_32(0x0, w17);
7344
armvixlb0c8ae22014-03-21 14:03:59 +00007345 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlad96eda2013-06-14 11:42:37 +01007346 ASSERT_EQUAL_64(0x1000, x21);
7347 ASSERT_EQUAL_64(0x111, x22);
armvixlb0c8ae22014-03-21 14:03:59 +00007348 ASSERT_EQUAL_64(0x7fffffffffffffff, x23);
armvixlad96eda2013-06-14 11:42:37 +01007349
7350 ASSERT_EQUAL_32(0xffffffff, w24);
7351 ASSERT_EQUAL_32(0x1000, w25);
7352 ASSERT_EQUAL_32(0x111, w26);
7353 ASSERT_EQUAL_32(0xffffffff, w27);
7354
7355 TEARDOWN();
7356}
7357
7358
7359TEST(add_sub_wide_imm) {
7360 SETUP();
7361
7362 START();
7363 __ Mov(x0, 0x0);
7364 __ Mov(x1, 0x1);
7365
armvixlb0c8ae22014-03-21 14:03:59 +00007366 __ Add(x10, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01007367 __ Add(x11, x1, Operand(0xffffffff));
7368
7369 __ Add(w12, w0, Operand(0x12345678));
7370 __ Add(w13, w1, Operand(0xffffffff));
7371
armvixl4a102ba2014-07-14 09:02:40 +01007372 __ Add(w18, w0, Operand(kWMinInt));
7373 __ Sub(w19, w0, Operand(kWMinInt));
armvixlad96eda2013-06-14 11:42:37 +01007374
armvixl4a102ba2014-07-14 09:02:40 +01007375 __ Sub(x20, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01007376 __ Sub(w21, w0, Operand(0x12345678));
armvixl4a102ba2014-07-14 09:02:40 +01007377
armvixlad96eda2013-06-14 11:42:37 +01007378 END();
7379
7380 RUN();
7381
armvixlb0c8ae22014-03-21 14:03:59 +00007382 ASSERT_EQUAL_64(0x1234567890abcdef, x10);
7383 ASSERT_EQUAL_64(0x100000000, x11);
armvixlad96eda2013-06-14 11:42:37 +01007384
7385 ASSERT_EQUAL_32(0x12345678, w12);
7386 ASSERT_EQUAL_64(0x0, x13);
7387
armvixl4a102ba2014-07-14 09:02:40 +01007388 ASSERT_EQUAL_32(kWMinInt, w18);
7389 ASSERT_EQUAL_32(kWMinInt, w19);
armvixlad96eda2013-06-14 11:42:37 +01007390
armvixl4a102ba2014-07-14 09:02:40 +01007391 ASSERT_EQUAL_64(-0x1234567890abcdef, x20);
armvixlad96eda2013-06-14 11:42:37 +01007392 ASSERT_EQUAL_32(-0x12345678, w21);
7393
7394 TEARDOWN();
7395}
7396
7397
7398TEST(add_sub_shifted) {
7399 SETUP();
7400
7401 START();
7402 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00007403 __ Mov(x1, 0x0123456789abcdef);
7404 __ Mov(x2, 0xfedcba9876543210);
7405 __ Mov(x3, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01007406
7407 __ Add(x10, x1, Operand(x2));
7408 __ Add(x11, x0, Operand(x1, LSL, 8));
7409 __ Add(x12, x0, Operand(x1, LSR, 8));
7410 __ Add(x13, x0, Operand(x1, ASR, 8));
7411 __ Add(x14, x0, Operand(x2, ASR, 8));
7412 __ Add(w15, w0, Operand(w1, ASR, 8));
7413 __ Add(w18, w3, Operand(w1, ROR, 8));
7414 __ Add(x19, x3, Operand(x1, ROR, 8));
7415
7416 __ Sub(x20, x3, Operand(x2));
7417 __ Sub(x21, x3, Operand(x1, LSL, 8));
7418 __ Sub(x22, x3, Operand(x1, LSR, 8));
7419 __ Sub(x23, x3, Operand(x1, ASR, 8));
7420 __ Sub(x24, x3, Operand(x2, ASR, 8));
7421 __ Sub(w25, w3, Operand(w1, ASR, 8));
7422 __ Sub(w26, w3, Operand(w1, ROR, 8));
7423 __ Sub(x27, x3, Operand(x1, ROR, 8));
7424 END();
7425
7426 RUN();
7427
armvixlb0c8ae22014-03-21 14:03:59 +00007428 ASSERT_EQUAL_64(0xffffffffffffffff, x10);
7429 ASSERT_EQUAL_64(0x23456789abcdef00, x11);
7430 ASSERT_EQUAL_64(0x000123456789abcd, x12);
7431 ASSERT_EQUAL_64(0x000123456789abcd, x13);
7432 ASSERT_EQUAL_64(0xfffedcba98765432, x14);
armvixlad96eda2013-06-14 11:42:37 +01007433 ASSERT_EQUAL_64(0xff89abcd, x15);
7434 ASSERT_EQUAL_64(0xef89abcc, x18);
armvixlb0c8ae22014-03-21 14:03:59 +00007435 ASSERT_EQUAL_64(0xef0123456789abcc, x19);
armvixlad96eda2013-06-14 11:42:37 +01007436
armvixlb0c8ae22014-03-21 14:03:59 +00007437 ASSERT_EQUAL_64(0x0123456789abcdef, x20);
7438 ASSERT_EQUAL_64(0xdcba9876543210ff, x21);
7439 ASSERT_EQUAL_64(0xfffedcba98765432, x22);
7440 ASSERT_EQUAL_64(0xfffedcba98765432, x23);
7441 ASSERT_EQUAL_64(0x000123456789abcd, x24);
armvixlad96eda2013-06-14 11:42:37 +01007442 ASSERT_EQUAL_64(0x00765432, x25);
7443 ASSERT_EQUAL_64(0x10765432, x26);
armvixlb0c8ae22014-03-21 14:03:59 +00007444 ASSERT_EQUAL_64(0x10fedcba98765432, x27);
armvixlad96eda2013-06-14 11:42:37 +01007445
7446 TEARDOWN();
7447}
7448
7449
7450TEST(add_sub_extended) {
7451 SETUP();
7452
7453 START();
7454 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00007455 __ Mov(x1, 0x0123456789abcdef);
7456 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01007457 __ Mov(w3, 0x80);
7458
7459 __ Add(x10, x0, Operand(x1, UXTB, 0));
7460 __ Add(x11, x0, Operand(x1, UXTB, 1));
7461 __ Add(x12, x0, Operand(x1, UXTH, 2));
7462 __ Add(x13, x0, Operand(x1, UXTW, 4));
7463
7464 __ Add(x14, x0, Operand(x1, SXTB, 0));
7465 __ Add(x15, x0, Operand(x1, SXTB, 1));
7466 __ Add(x16, x0, Operand(x1, SXTH, 2));
7467 __ Add(x17, x0, Operand(x1, SXTW, 3));
7468 __ Add(x18, x0, Operand(x2, SXTB, 0));
7469 __ Add(x19, x0, Operand(x2, SXTB, 1));
7470 __ Add(x20, x0, Operand(x2, SXTH, 2));
7471 __ Add(x21, x0, Operand(x2, SXTW, 3));
7472
7473 __ Add(x22, x1, Operand(x2, SXTB, 1));
7474 __ Sub(x23, x1, Operand(x2, SXTB, 1));
7475
7476 __ Add(w24, w1, Operand(w2, UXTB, 2));
7477 __ Add(w25, w0, Operand(w1, SXTB, 0));
7478 __ Add(w26, w0, Operand(w1, SXTB, 1));
7479 __ Add(w27, w2, Operand(w1, SXTW, 3));
7480
7481 __ Add(w28, w0, Operand(w1, SXTW, 3));
7482 __ Add(x29, x0, Operand(w1, SXTW, 3));
7483
7484 __ Sub(x30, x0, Operand(w3, SXTB, 1));
7485 END();
7486
7487 RUN();
7488
armvixlb0c8ae22014-03-21 14:03:59 +00007489 ASSERT_EQUAL_64(0xef, x10);
7490 ASSERT_EQUAL_64(0x1de, x11);
7491 ASSERT_EQUAL_64(0x337bc, x12);
7492 ASSERT_EQUAL_64(0x89abcdef0, x13);
armvixlad96eda2013-06-14 11:42:37 +01007493
armvixlb0c8ae22014-03-21 14:03:59 +00007494 ASSERT_EQUAL_64(0xffffffffffffffef, x14);
7495 ASSERT_EQUAL_64(0xffffffffffffffde, x15);
7496 ASSERT_EQUAL_64(0xffffffffffff37bc, x16);
7497 ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x17);
7498 ASSERT_EQUAL_64(0x10, x18);
7499 ASSERT_EQUAL_64(0x20, x19);
7500 ASSERT_EQUAL_64(0xc840, x20);
7501 ASSERT_EQUAL_64(0x3b2a19080, x21);
armvixlad96eda2013-06-14 11:42:37 +01007502
armvixlb0c8ae22014-03-21 14:03:59 +00007503 ASSERT_EQUAL_64(0x0123456789abce0f, x22);
7504 ASSERT_EQUAL_64(0x0123456789abcdcf, x23);
armvixlad96eda2013-06-14 11:42:37 +01007505
7506 ASSERT_EQUAL_32(0x89abce2f, w24);
7507 ASSERT_EQUAL_32(0xffffffef, w25);
7508 ASSERT_EQUAL_32(0xffffffde, w26);
7509 ASSERT_EQUAL_32(0xc3b2a188, w27);
7510
7511 ASSERT_EQUAL_32(0x4d5e6f78, w28);
armvixlb0c8ae22014-03-21 14:03:59 +00007512 ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x29);
armvixlad96eda2013-06-14 11:42:37 +01007513
7514 ASSERT_EQUAL_64(256, x30);
7515
7516 TEARDOWN();
7517}
7518
7519
7520TEST(add_sub_negative) {
7521 SETUP();
7522
7523 START();
7524 __ Mov(x0, 0);
7525 __ Mov(x1, 4687);
7526 __ Mov(x2, 0x1122334455667788);
7527 __ Mov(w3, 0x11223344);
7528 __ Mov(w4, 400000);
7529
7530 __ Add(x10, x0, -42);
7531 __ Add(x11, x1, -687);
7532 __ Add(x12, x2, -0x88);
7533
7534 __ Sub(x13, x0, -600);
7535 __ Sub(x14, x1, -313);
7536 __ Sub(x15, x2, -0x555);
7537
7538 __ Add(w19, w3, -0x344);
7539 __ Add(w20, w4, -2000);
7540
7541 __ Sub(w21, w3, -0xbc);
7542 __ Sub(w22, w4, -2000);
7543 END();
7544
7545 RUN();
7546
7547 ASSERT_EQUAL_64(-42, x10);
7548 ASSERT_EQUAL_64(4000, x11);
7549 ASSERT_EQUAL_64(0x1122334455667700, x12);
7550
7551 ASSERT_EQUAL_64(600, x13);
7552 ASSERT_EQUAL_64(5000, x14);
7553 ASSERT_EQUAL_64(0x1122334455667cdd, x15);
7554
7555 ASSERT_EQUAL_32(0x11223000, w19);
7556 ASSERT_EQUAL_32(398000, w20);
7557
7558 ASSERT_EQUAL_32(0x11223400, w21);
7559 ASSERT_EQUAL_32(402000, w22);
7560
7561 TEARDOWN();
7562}
7563
7564
armvixlf37fdc02014-02-05 13:22:16 +00007565TEST(add_sub_zero) {
7566 SETUP();
7567
7568 START();
7569 __ Mov(x0, 0);
7570 __ Mov(x1, 0);
7571 __ Mov(x2, 0);
7572
7573 Label blob1;
7574 __ Bind(&blob1);
7575 __ Add(x0, x0, 0);
7576 __ Sub(x1, x1, 0);
7577 __ Sub(x2, x2, xzr);
armvixlb0c8ae22014-03-21 14:03:59 +00007578 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob1) == 0);
armvixlf37fdc02014-02-05 13:22:16 +00007579
7580 Label blob2;
7581 __ Bind(&blob2);
7582 __ Add(w3, w3, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00007583 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob2) != 0);
armvixlf37fdc02014-02-05 13:22:16 +00007584
7585 Label blob3;
7586 __ Bind(&blob3);
7587 __ Sub(w3, w3, wzr);
armvixlb0c8ae22014-03-21 14:03:59 +00007588 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob3) != 0);
armvixlf37fdc02014-02-05 13:22:16 +00007589
7590 END();
7591
7592 RUN();
7593
7594 ASSERT_EQUAL_64(0, x0);
7595 ASSERT_EQUAL_64(0, x1);
7596 ASSERT_EQUAL_64(0, x2);
7597
7598 TEARDOWN();
7599}
7600
7601
7602TEST(claim_drop_zero) {
7603 SETUP();
7604
7605 START();
7606
7607 Label start;
7608 __ Bind(&start);
7609 __ Claim(Operand(0));
7610 __ Drop(Operand(0));
7611 __ Claim(Operand(xzr));
7612 __ Drop(Operand(xzr));
armvixlb0c8ae22014-03-21 14:03:59 +00007613 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlf37fdc02014-02-05 13:22:16 +00007614
7615 END();
7616
7617 RUN();
7618
7619 TEARDOWN();
7620}
7621
7622
armvixlad96eda2013-06-14 11:42:37 +01007623TEST(neg) {
7624 SETUP();
7625
7626 START();
armvixlb0c8ae22014-03-21 14:03:59 +00007627 __ Mov(x0, 0xf123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01007628
7629 // Immediate.
7630 __ Neg(x1, 0x123);
7631 __ Neg(w2, 0x123);
7632
7633 // Shifted.
7634 __ Neg(x3, Operand(x0, LSL, 1));
7635 __ Neg(w4, Operand(w0, LSL, 2));
7636 __ Neg(x5, Operand(x0, LSR, 3));
7637 __ Neg(w6, Operand(w0, LSR, 4));
7638 __ Neg(x7, Operand(x0, ASR, 5));
7639 __ Neg(w8, Operand(w0, ASR, 6));
7640
7641 // Extended.
7642 __ Neg(w9, Operand(w0, UXTB));
7643 __ Neg(x10, Operand(x0, SXTB, 1));
7644 __ Neg(w11, Operand(w0, UXTH, 2));
7645 __ Neg(x12, Operand(x0, SXTH, 3));
7646 __ Neg(w13, Operand(w0, UXTW, 4));
7647 __ Neg(x14, Operand(x0, SXTW, 4));
7648 END();
7649
7650 RUN();
7651
armvixlb0c8ae22014-03-21 14:03:59 +00007652 ASSERT_EQUAL_64(0xfffffffffffffedd, x1);
armvixlad96eda2013-06-14 11:42:37 +01007653 ASSERT_EQUAL_64(0xfffffedd, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00007654 ASSERT_EQUAL_64(0x1db97530eca86422, x3);
armvixlad96eda2013-06-14 11:42:37 +01007655 ASSERT_EQUAL_64(0xd950c844, x4);
armvixlb0c8ae22014-03-21 14:03:59 +00007656 ASSERT_EQUAL_64(0xe1db97530eca8643, x5);
armvixlad96eda2013-06-14 11:42:37 +01007657 ASSERT_EQUAL_64(0xf7654322, x6);
armvixlb0c8ae22014-03-21 14:03:59 +00007658 ASSERT_EQUAL_64(0x0076e5d4c3b2a191, x7);
armvixlad96eda2013-06-14 11:42:37 +01007659 ASSERT_EQUAL_64(0x01d950c9, x8);
7660 ASSERT_EQUAL_64(0xffffff11, x9);
armvixlb0c8ae22014-03-21 14:03:59 +00007661 ASSERT_EQUAL_64(0x0000000000000022, x10);
armvixlad96eda2013-06-14 11:42:37 +01007662 ASSERT_EQUAL_64(0xfffcc844, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00007663 ASSERT_EQUAL_64(0x0000000000019088, x12);
armvixlad96eda2013-06-14 11:42:37 +01007664 ASSERT_EQUAL_64(0x65432110, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00007665 ASSERT_EQUAL_64(0x0000000765432110, x14);
armvixlad96eda2013-06-14 11:42:37 +01007666
7667 TEARDOWN();
7668}
7669
7670
armvixl684cd2a2015-10-23 13:38:33 +01007671template<typename T, typename Op>
7672static void AdcsSbcsHelper(Op op, T left, T right, int carry,
7673 T expected, StatusFlags expected_flags) {
7674 int reg_size = sizeof(T) * 8;
7675 Register left_reg(0, reg_size);
7676 Register right_reg(1, reg_size);
7677 Register result_reg(2, reg_size);
7678
7679 SETUP();
7680 START();
7681
7682 __ Mov(left_reg, left);
7683 __ Mov(right_reg, right);
7684 __ Mov(x10, (carry ? CFlag : NoFlag));
7685
7686 __ Msr(NZCV, x10);
7687 (masm.*op)(result_reg, left_reg, right_reg);
7688
7689 END();
7690 RUN();
7691
7692 ASSERT_EQUAL_64(left, left_reg.X());
7693 ASSERT_EQUAL_64(right, right_reg.X());
7694 ASSERT_EQUAL_64(expected, result_reg.X());
7695 ASSERT_EQUAL_NZCV(expected_flags);
7696
7697 TEARDOWN();
7698}
7699
7700
7701TEST(adcs_sbcs_x) {
7702 uint64_t inputs[] = {
7703 0x0000000000000000, 0x0000000000000001,
7704 0x7ffffffffffffffe, 0x7fffffffffffffff,
7705 0x8000000000000000, 0x8000000000000001,
7706 0xfffffffffffffffe, 0xffffffffffffffff,
7707 };
7708 static const size_t input_count = sizeof(inputs) / sizeof(inputs[0]);
7709
7710 struct Expected {
7711 uint64_t carry0_result;
7712 StatusFlags carry0_flags;
7713 uint64_t carry1_result;
7714 StatusFlags carry1_flags;
7715 };
7716
7717 static const Expected expected_adcs_x[input_count][input_count] = {
7718 {{0x0000000000000000, ZFlag, 0x0000000000000001, NoFlag},
7719 {0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag},
7720 {0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag},
7721 {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
7722 {0x8000000000000000, NFlag, 0x8000000000000001, NFlag},
7723 {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
7724 {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
7725 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag}},
7726 {{0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag},
7727 {0x0000000000000002, NoFlag, 0x0000000000000003, NoFlag},
7728 {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
7729 {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
7730 {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
7731 {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
7732 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7733 {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag}},
7734 {{0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag},
7735 {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
7736 {0xfffffffffffffffc, NVFlag, 0xfffffffffffffffd, NVFlag},
7737 {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
7738 {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
7739 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7740 {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
7741 {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag}},
7742 {{0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
7743 {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
7744 {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
7745 {0xfffffffffffffffe, NVFlag, 0xffffffffffffffff, NVFlag},
7746 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7747 {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
7748 {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
7749 {0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag}},
7750 {{0x8000000000000000, NFlag, 0x8000000000000001, NFlag},
7751 {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
7752 {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
7753 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7754 {0x0000000000000000, ZCVFlag, 0x0000000000000001, CVFlag},
7755 {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
7756 {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
7757 {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag}},
7758 {{0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
7759 {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
7760 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7761 {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
7762 {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
7763 {0x0000000000000002, CVFlag, 0x0000000000000003, CVFlag},
7764 {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
7765 {0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag}},
7766 {{0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
7767 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7768 {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
7769 {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
7770 {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
7771 {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
7772 {0xfffffffffffffffc, NCFlag, 0xfffffffffffffffd, NCFlag},
7773 {0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag}},
7774 {{0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7775 {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
7776 {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
7777 {0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag},
7778 {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
7779 {0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag},
7780 {0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag},
7781 {0xfffffffffffffffe, NCFlag, 0xffffffffffffffff, NCFlag}}
7782 };
7783
7784 static const Expected expected_sbcs_x[input_count][input_count] = {
7785 {{0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7786 {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
7787 {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
7788 {0x8000000000000000, NFlag, 0x8000000000000001, NFlag},
7789 {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
7790 {0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag},
7791 {0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag},
7792 {0x0000000000000000, ZFlag, 0x0000000000000001, NoFlag}},
7793 {{0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
7794 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7795 {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
7796 {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
7797 {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
7798 {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
7799 {0x0000000000000002, NoFlag, 0x0000000000000003, NoFlag},
7800 {0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag}},
7801 {{0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
7802 {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
7803 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7804 {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
7805 {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
7806 {0xfffffffffffffffc, NVFlag, 0xfffffffffffffffd, NVFlag},
7807 {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
7808 {0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag}},
7809 {{0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag},
7810 {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
7811 {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
7812 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7813 {0xfffffffffffffffe, NVFlag, 0xffffffffffffffff, NVFlag},
7814 {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
7815 {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
7816 {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag}},
7817 {{0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
7818 {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
7819 {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
7820 {0x0000000000000000, ZCVFlag, 0x0000000000000001, CVFlag},
7821 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7822 {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
7823 {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
7824 {0x8000000000000000, NFlag, 0x8000000000000001, NFlag}},
7825 {{0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag},
7826 {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
7827 {0x0000000000000002, CVFlag, 0x0000000000000003, CVFlag},
7828 {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
7829 {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
7830 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7831 {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
7832 {0x8000000000000001, NFlag, 0x8000000000000002, NFlag}},
7833 {{0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag},
7834 {0xfffffffffffffffc, NCFlag, 0xfffffffffffffffd, NCFlag},
7835 {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
7836 {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
7837 {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
7838 {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
7839 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
7840 {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag}},
7841 {{0xfffffffffffffffe, NCFlag, 0xffffffffffffffff, NCFlag},
7842 {0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag},
7843 {0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag},
7844 {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
7845 {0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag},
7846 {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
7847 {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
7848 {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag}}
7849 };
7850
7851 for (size_t left = 0; left < input_count; left++) {
7852 for (size_t right = 0; right < input_count; right++) {
7853 const Expected & expected = expected_adcs_x[left][right];
7854 AdcsSbcsHelper(&MacroAssembler::Adcs, inputs[left], inputs[right], 0,
7855 expected.carry0_result, expected.carry0_flags);
7856 AdcsSbcsHelper(&MacroAssembler::Adcs, inputs[left], inputs[right], 1,
7857 expected.carry1_result, expected.carry1_flags);
7858 }
7859 }
7860
7861 for (size_t left = 0; left < input_count; left++) {
7862 for (size_t right = 0; right < input_count; right++) {
7863 const Expected & expected = expected_sbcs_x[left][right];
7864 AdcsSbcsHelper(&MacroAssembler::Sbcs, inputs[left], inputs[right], 0,
7865 expected.carry0_result, expected.carry0_flags);
7866 AdcsSbcsHelper(&MacroAssembler::Sbcs, inputs[left], inputs[right], 1,
7867 expected.carry1_result, expected.carry1_flags);
7868 }
7869 }
7870}
7871
7872
7873TEST(adcs_sbcs_w) {
7874 uint32_t inputs[] = {
7875 0x00000000, 0x00000001, 0x7ffffffe, 0x7fffffff,
7876 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff,
7877 };
7878 static const size_t input_count = sizeof(inputs) / sizeof(inputs[0]);
7879
7880 struct Expected {
7881 uint32_t carry0_result;
7882 StatusFlags carry0_flags;
7883 uint32_t carry1_result;
7884 StatusFlags carry1_flags;
7885 };
7886
7887 static const Expected expected_adcs_w[input_count][input_count] = {
7888 {{0x00000000, ZFlag, 0x00000001, NoFlag},
7889 {0x00000001, NoFlag, 0x00000002, NoFlag},
7890 {0x7ffffffe, NoFlag, 0x7fffffff, NoFlag},
7891 {0x7fffffff, NoFlag, 0x80000000, NVFlag},
7892 {0x80000000, NFlag, 0x80000001, NFlag},
7893 {0x80000001, NFlag, 0x80000002, NFlag},
7894 {0xfffffffe, NFlag, 0xffffffff, NFlag},
7895 {0xffffffff, NFlag, 0x00000000, ZCFlag}},
7896 {{0x00000001, NoFlag, 0x00000002, NoFlag},
7897 {0x00000002, NoFlag, 0x00000003, NoFlag},
7898 {0x7fffffff, NoFlag, 0x80000000, NVFlag},
7899 {0x80000000, NVFlag, 0x80000001, NVFlag},
7900 {0x80000001, NFlag, 0x80000002, NFlag},
7901 {0x80000002, NFlag, 0x80000003, NFlag},
7902 {0xffffffff, NFlag, 0x00000000, ZCFlag},
7903 {0x00000000, ZCFlag, 0x00000001, CFlag}},
7904 {{0x7ffffffe, NoFlag, 0x7fffffff, NoFlag},
7905 {0x7fffffff, NoFlag, 0x80000000, NVFlag},
7906 {0xfffffffc, NVFlag, 0xfffffffd, NVFlag},
7907 {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
7908 {0xfffffffe, NFlag, 0xffffffff, NFlag},
7909 {0xffffffff, NFlag, 0x00000000, ZCFlag},
7910 {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
7911 {0x7ffffffd, CFlag, 0x7ffffffe, CFlag}},
7912 {{0x7fffffff, NoFlag, 0x80000000, NVFlag},
7913 {0x80000000, NVFlag, 0x80000001, NVFlag},
7914 {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
7915 {0xfffffffe, NVFlag, 0xffffffff, NVFlag},
7916 {0xffffffff, NFlag, 0x00000000, ZCFlag},
7917 {0x00000000, ZCFlag, 0x00000001, CFlag},
7918 {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
7919 {0x7ffffffe, CFlag, 0x7fffffff, CFlag}},
7920 {{0x80000000, NFlag, 0x80000001, NFlag},
7921 {0x80000001, NFlag, 0x80000002, NFlag},
7922 {0xfffffffe, NFlag, 0xffffffff, NFlag},
7923 {0xffffffff, NFlag, 0x00000000, ZCFlag},
7924 {0x00000000, ZCVFlag, 0x00000001, CVFlag},
7925 {0x00000001, CVFlag, 0x00000002, CVFlag},
7926 {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
7927 {0x7fffffff, CVFlag, 0x80000000, NCFlag}},
7928 {{0x80000001, NFlag, 0x80000002, NFlag},
7929 {0x80000002, NFlag, 0x80000003, NFlag},
7930 {0xffffffff, NFlag, 0x00000000, ZCFlag},
7931 {0x00000000, ZCFlag, 0x00000001, CFlag},
7932 {0x00000001, CVFlag, 0x00000002, CVFlag},
7933 {0x00000002, CVFlag, 0x00000003, CVFlag},
7934 {0x7fffffff, CVFlag, 0x80000000, NCFlag},
7935 {0x80000000, NCFlag, 0x80000001, NCFlag}},
7936 {{0xfffffffe, NFlag, 0xffffffff, NFlag},
7937 {0xffffffff, NFlag, 0x00000000, ZCFlag},
7938 {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
7939 {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
7940 {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
7941 {0x7fffffff, CVFlag, 0x80000000, NCFlag},
7942 {0xfffffffc, NCFlag, 0xfffffffd, NCFlag},
7943 {0xfffffffd, NCFlag, 0xfffffffe, NCFlag}},
7944 {{0xffffffff, NFlag, 0x00000000, ZCFlag},
7945 {0x00000000, ZCFlag, 0x00000001, CFlag},
7946 {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
7947 {0x7ffffffe, CFlag, 0x7fffffff, CFlag},
7948 {0x7fffffff, CVFlag, 0x80000000, NCFlag},
7949 {0x80000000, NCFlag, 0x80000001, NCFlag},
7950 {0xfffffffd, NCFlag, 0xfffffffe, NCFlag},
7951 {0xfffffffe, NCFlag, 0xffffffff, NCFlag}}
7952 };
7953
7954 static const Expected expected_sbcs_w[input_count][input_count] = {
7955 {{0xffffffff, NFlag, 0x00000000, ZCFlag},
7956 {0xfffffffe, NFlag, 0xffffffff, NFlag},
7957 {0x80000001, NFlag, 0x80000002, NFlag},
7958 {0x80000000, NFlag, 0x80000001, NFlag},
7959 {0x7fffffff, NoFlag, 0x80000000, NVFlag},
7960 {0x7ffffffe, NoFlag, 0x7fffffff, NoFlag},
7961 {0x00000001, NoFlag, 0x00000002, NoFlag},
7962 {0x00000000, ZFlag, 0x00000001, NoFlag}},
7963 {{0x00000000, ZCFlag, 0x00000001, CFlag},
7964 {0xffffffff, NFlag, 0x00000000, ZCFlag},
7965 {0x80000002, NFlag, 0x80000003, NFlag},
7966 {0x80000001, NFlag, 0x80000002, NFlag},
7967 {0x80000000, NVFlag, 0x80000001, NVFlag},
7968 {0x7fffffff, NoFlag, 0x80000000, NVFlag},
7969 {0x00000002, NoFlag, 0x00000003, NoFlag},
7970 {0x00000001, NoFlag, 0x00000002, NoFlag}},
7971 {{0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
7972 {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
7973 {0xffffffff, NFlag, 0x00000000, ZCFlag},
7974 {0xfffffffe, NFlag, 0xffffffff, NFlag},
7975 {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
7976 {0xfffffffc, NVFlag, 0xfffffffd, NVFlag},
7977 {0x7fffffff, NoFlag, 0x80000000, NVFlag},
7978 {0x7ffffffe, NoFlag, 0x7fffffff, NoFlag}},
7979 {{0x7ffffffe, CFlag, 0x7fffffff, CFlag},
7980 {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
7981 {0x00000000, ZCFlag, 0x00000001, CFlag},
7982 {0xffffffff, NFlag, 0x00000000, ZCFlag},
7983 {0xfffffffe, NVFlag, 0xffffffff, NVFlag},
7984 {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
7985 {0x80000000, NVFlag, 0x80000001, NVFlag},
7986 {0x7fffffff, NoFlag, 0x80000000, NVFlag}},
7987 {{0x7fffffff, CVFlag, 0x80000000, NCFlag},
7988 {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
7989 {0x00000001, CVFlag, 0x00000002, CVFlag},
7990 {0x00000000, ZCVFlag, 0x00000001, CVFlag},
7991 {0xffffffff, NFlag, 0x00000000, ZCFlag},
7992 {0xfffffffe, NFlag, 0xffffffff, NFlag},
7993 {0x80000001, NFlag, 0x80000002, NFlag},
7994 {0x80000000, NFlag, 0x80000001, NFlag}},
7995 {{0x80000000, NCFlag, 0x80000001, NCFlag},
7996 {0x7fffffff, CVFlag, 0x80000000, NCFlag},
7997 {0x00000002, CVFlag, 0x00000003, CVFlag},
7998 {0x00000001, CVFlag, 0x00000002, CVFlag},
7999 {0x00000000, ZCFlag, 0x00000001, CFlag},
8000 {0xffffffff, NFlag, 0x00000000, ZCFlag},
8001 {0x80000002, NFlag, 0x80000003, NFlag},
8002 {0x80000001, NFlag, 0x80000002, NFlag}},
8003 {{0xfffffffd, NCFlag, 0xfffffffe, NCFlag},
8004 {0xfffffffc, NCFlag, 0xfffffffd, NCFlag},
8005 {0x7fffffff, CVFlag, 0x80000000, NCFlag},
8006 {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
8007 {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
8008 {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
8009 {0xffffffff, NFlag, 0x00000000, ZCFlag},
8010 {0xfffffffe, NFlag, 0xffffffff, NFlag}},
8011 {{0xfffffffe, NCFlag, 0xffffffff, NCFlag},
8012 {0xfffffffd, NCFlag, 0xfffffffe, NCFlag},
8013 {0x80000000, NCFlag, 0x80000001, NCFlag},
8014 {0x7fffffff, CVFlag, 0x80000000, NCFlag},
8015 {0x7ffffffe, CFlag, 0x7fffffff, CFlag},
8016 {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
8017 {0x00000000, ZCFlag, 0x00000001, CFlag},
8018 {0xffffffff, NFlag, 0x00000000, ZCFlag}}
8019 };
8020
8021 for (size_t left = 0; left < input_count; left++) {
8022 for (size_t right = 0; right < input_count; right++) {
8023 const Expected & expected = expected_adcs_w[left][right];
8024 AdcsSbcsHelper(&MacroAssembler::Adcs, inputs[left], inputs[right], 0,
8025 expected.carry0_result, expected.carry0_flags);
8026 AdcsSbcsHelper(&MacroAssembler::Adcs, inputs[left], inputs[right], 1,
8027 expected.carry1_result, expected.carry1_flags);
8028 }
8029 }
8030
8031 for (size_t left = 0; left < input_count; left++) {
8032 for (size_t right = 0; right < input_count; right++) {
8033 const Expected & expected = expected_sbcs_w[left][right];
8034 AdcsSbcsHelper(&MacroAssembler::Sbcs, inputs[left], inputs[right], 0,
8035 expected.carry0_result, expected.carry0_flags);
8036 AdcsSbcsHelper(&MacroAssembler::Sbcs, inputs[left], inputs[right], 1,
8037 expected.carry1_result, expected.carry1_flags);
8038 }
8039 }
8040}
8041
8042
armvixlad96eda2013-06-14 11:42:37 +01008043TEST(adc_sbc_shift) {
8044 SETUP();
8045
8046 START();
8047 __ Mov(x0, 0);
8048 __ Mov(x1, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00008049 __ Mov(x2, 0x0123456789abcdef);
8050 __ Mov(x3, 0xfedcba9876543210);
8051 __ Mov(x4, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008052
8053 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008054 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01008055
8056 __ Adc(x5, x2, Operand(x3));
8057 __ Adc(x6, x0, Operand(x1, LSL, 60));
8058 __ Sbc(x7, x4, Operand(x3, LSR, 4));
8059 __ Adc(x8, x2, Operand(x3, ASR, 4));
8060 __ Adc(x9, x2, Operand(x3, ROR, 8));
8061
8062 __ Adc(w10, w2, Operand(w3));
8063 __ Adc(w11, w0, Operand(w1, LSL, 30));
8064 __ Sbc(w12, w4, Operand(w3, LSR, 4));
8065 __ Adc(w13, w2, Operand(w3, ASR, 4));
8066 __ Adc(w14, w2, Operand(w3, ROR, 8));
8067
8068 // Set the C flag.
8069 __ Cmp(w0, Operand(w0));
8070
8071 __ Adc(x18, x2, Operand(x3));
8072 __ Adc(x19, x0, Operand(x1, LSL, 60));
8073 __ Sbc(x20, x4, Operand(x3, LSR, 4));
8074 __ Adc(x21, x2, Operand(x3, ASR, 4));
8075 __ Adc(x22, x2, Operand(x3, ROR, 8));
8076
8077 __ Adc(w23, w2, Operand(w3));
8078 __ Adc(w24, w0, Operand(w1, LSL, 30));
8079 __ Sbc(w25, w4, Operand(w3, LSR, 4));
8080 __ Adc(w26, w2, Operand(w3, ASR, 4));
8081 __ Adc(w27, w2, Operand(w3, ROR, 8));
8082 END();
8083
8084 RUN();
8085
armvixlb0c8ae22014-03-21 14:03:59 +00008086 ASSERT_EQUAL_64(0xffffffffffffffff, x5);
8087 ASSERT_EQUAL_64(INT64_C(1) << 60, x6);
8088 ASSERT_EQUAL_64(0xf0123456789abcdd, x7);
8089 ASSERT_EQUAL_64(0x0111111111111110, x8);
8090 ASSERT_EQUAL_64(0x1222222222222221, x9);
armvixlad96eda2013-06-14 11:42:37 +01008091
8092 ASSERT_EQUAL_32(0xffffffff, w10);
armvixlb0c8ae22014-03-21 14:03:59 +00008093 ASSERT_EQUAL_32(INT32_C(1) << 30, w11);
armvixlad96eda2013-06-14 11:42:37 +01008094 ASSERT_EQUAL_32(0xf89abcdd, w12);
8095 ASSERT_EQUAL_32(0x91111110, w13);
8096 ASSERT_EQUAL_32(0x9a222221, w14);
8097
armvixlb0c8ae22014-03-21 14:03:59 +00008098 ASSERT_EQUAL_64(0xffffffffffffffff + 1, x18);
8099 ASSERT_EQUAL_64((INT64_C(1) << 60) + 1, x19);
8100 ASSERT_EQUAL_64(0xf0123456789abcdd + 1, x20);
8101 ASSERT_EQUAL_64(0x0111111111111110 + 1, x21);
8102 ASSERT_EQUAL_64(0x1222222222222221 + 1, x22);
armvixlad96eda2013-06-14 11:42:37 +01008103
8104 ASSERT_EQUAL_32(0xffffffff + 1, w23);
armvixlb0c8ae22014-03-21 14:03:59 +00008105 ASSERT_EQUAL_32((INT32_C(1) << 30) + 1, w24);
armvixlad96eda2013-06-14 11:42:37 +01008106 ASSERT_EQUAL_32(0xf89abcdd + 1, w25);
8107 ASSERT_EQUAL_32(0x91111110 + 1, w26);
8108 ASSERT_EQUAL_32(0x9a222221 + 1, w27);
8109
armvixlad96eda2013-06-14 11:42:37 +01008110 TEARDOWN();
8111}
8112
8113
8114TEST(adc_sbc_extend) {
8115 SETUP();
8116
8117 START();
8118 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008119 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01008120
8121 __ Mov(x0, 0);
8122 __ Mov(x1, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00008123 __ Mov(x2, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01008124
8125 __ Adc(x10, x1, Operand(w2, UXTB, 1));
8126 __ Adc(x11, x1, Operand(x2, SXTH, 2));
8127 __ Sbc(x12, x1, Operand(w2, UXTW, 4));
8128 __ Adc(x13, x1, Operand(x2, UXTX, 4));
8129
8130 __ Adc(w14, w1, Operand(w2, UXTB, 1));
8131 __ Adc(w15, w1, Operand(w2, SXTH, 2));
8132 __ Adc(w9, w1, Operand(w2, UXTW, 4));
8133
8134 // Set the C flag.
8135 __ Cmp(w0, Operand(w0));
8136
8137 __ Adc(x20, x1, Operand(w2, UXTB, 1));
8138 __ Adc(x21, x1, Operand(x2, SXTH, 2));
8139 __ Sbc(x22, x1, Operand(w2, UXTW, 4));
8140 __ Adc(x23, x1, Operand(x2, UXTX, 4));
8141
8142 __ Adc(w24, w1, Operand(w2, UXTB, 1));
8143 __ Adc(w25, w1, Operand(w2, SXTH, 2));
8144 __ Adc(w26, w1, Operand(w2, UXTW, 4));
8145 END();
8146
8147 RUN();
8148
8149 ASSERT_EQUAL_64(0x1df, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00008150 ASSERT_EQUAL_64(0xffffffffffff37bd, x11);
8151 ASSERT_EQUAL_64(0xfffffff765432110, x12);
8152 ASSERT_EQUAL_64(0x123456789abcdef1, x13);
armvixlad96eda2013-06-14 11:42:37 +01008153
8154 ASSERT_EQUAL_32(0x1df, w14);
8155 ASSERT_EQUAL_32(0xffff37bd, w15);
8156 ASSERT_EQUAL_32(0x9abcdef1, w9);
8157
8158 ASSERT_EQUAL_64(0x1df + 1, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00008159 ASSERT_EQUAL_64(0xffffffffffff37bd + 1, x21);
8160 ASSERT_EQUAL_64(0xfffffff765432110 + 1, x22);
8161 ASSERT_EQUAL_64(0x123456789abcdef1 + 1, x23);
armvixlad96eda2013-06-14 11:42:37 +01008162
8163 ASSERT_EQUAL_32(0x1df + 1, w24);
8164 ASSERT_EQUAL_32(0xffff37bd + 1, w25);
8165 ASSERT_EQUAL_32(0x9abcdef1 + 1, w26);
8166
8167 // Check that adc correctly sets the condition flags.
8168 START();
8169 __ Mov(x0, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00008170 __ Mov(x1, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008171 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008172 __ Adds(x0, x0, Operand(0));
8173 __ Adcs(x10, x0, Operand(x1, SXTX, 1));
armvixlad96eda2013-06-14 11:42:37 +01008174 END();
8175
8176 RUN();
8177
8178 ASSERT_EQUAL_NZCV(CFlag);
8179
8180 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008181 __ Mov(x0, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008182 __ Mov(x1, 1);
8183 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008184 __ Adds(x0, x0, Operand(0));
8185 __ Adcs(x10, x0, Operand(x1, UXTB, 2));
armvixlad96eda2013-06-14 11:42:37 +01008186 END();
8187
8188 RUN();
8189
8190 ASSERT_EQUAL_NZCV(NVFlag);
8191
8192 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008193 __ Mov(x0, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008194 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008195 __ Adds(x0, x0, Operand(0));
8196 __ Adcs(x10, x0, Operand(1));
armvixlad96eda2013-06-14 11:42:37 +01008197 END();
8198
8199 RUN();
8200
8201 ASSERT_EQUAL_NZCV(NVFlag);
8202
8203 TEARDOWN();
8204}
8205
8206
8207TEST(adc_sbc_wide_imm) {
8208 SETUP();
8209
8210 START();
8211 __ Mov(x0, 0);
8212
8213 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008214 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01008215
armvixlb0c8ae22014-03-21 14:03:59 +00008216 __ Adc(x7, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01008217 __ Adc(w8, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00008218 __ Sbc(x9, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00008219 __ Sbc(w10, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00008220 __ Ngc(x11, Operand(0xffffffff00000000));
armvixlf37fdc02014-02-05 13:22:16 +00008221 __ Ngc(w12, Operand(0xffff0000));
armvixlad96eda2013-06-14 11:42:37 +01008222
8223 // Set the C flag.
8224 __ Cmp(w0, Operand(w0));
8225
armvixlb0c8ae22014-03-21 14:03:59 +00008226 __ Adc(x18, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00008227 __ Adc(w19, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00008228 __ Sbc(x20, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00008229 __ Sbc(w21, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00008230 __ Ngc(x22, Operand(0xffffffff00000000));
armvixlf37fdc02014-02-05 13:22:16 +00008231 __ Ngc(w23, Operand(0xffff0000));
armvixlad96eda2013-06-14 11:42:37 +01008232 END();
8233
8234 RUN();
8235
armvixlb0c8ae22014-03-21 14:03:59 +00008236 ASSERT_EQUAL_64(0x1234567890abcdef, x7);
armvixlad96eda2013-06-14 11:42:37 +01008237 ASSERT_EQUAL_64(0xffffffff, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00008238 ASSERT_EQUAL_64(0xedcba9876f543210, x9);
armvixlf37fdc02014-02-05 13:22:16 +00008239 ASSERT_EQUAL_64(0, x10);
8240 ASSERT_EQUAL_64(0xffffffff, x11);
8241 ASSERT_EQUAL_64(0xffff, x12);
8242
armvixlb0c8ae22014-03-21 14:03:59 +00008243 ASSERT_EQUAL_64(0x1234567890abcdef + 1, x18);
armvixlf37fdc02014-02-05 13:22:16 +00008244 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +00008245 ASSERT_EQUAL_64(0xedcba9876f543211, x20);
armvixlf37fdc02014-02-05 13:22:16 +00008246 ASSERT_EQUAL_64(1, x21);
armvixlb0c8ae22014-03-21 14:03:59 +00008247 ASSERT_EQUAL_64(0x0000000100000000, x22);
8248 ASSERT_EQUAL_64(0x0000000000010000, x23);
armvixlad96eda2013-06-14 11:42:37 +01008249
8250 TEARDOWN();
8251}
8252
8253TEST(flags) {
8254 SETUP();
8255
8256 START();
8257 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00008258 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01008259 __ Neg(x10, Operand(x0));
8260 __ Neg(x11, Operand(x1));
8261 __ Neg(w12, Operand(w1));
8262 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008263 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01008264 __ Ngc(x13, Operand(x0));
8265 // Set the C flag.
8266 __ Cmp(x0, Operand(x0));
8267 __ Ngc(w14, Operand(w0));
8268 END();
8269
8270 RUN();
8271
8272 ASSERT_EQUAL_64(0, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00008273 ASSERT_EQUAL_64(-0x1111111111111111, x11);
armvixlad96eda2013-06-14 11:42:37 +01008274 ASSERT_EQUAL_32(-0x11111111, w12);
armvixlb0c8ae22014-03-21 14:03:59 +00008275 ASSERT_EQUAL_64(-1, x13);
armvixlad96eda2013-06-14 11:42:37 +01008276 ASSERT_EQUAL_32(0, w14);
8277
8278 START();
8279 __ Mov(x0, 0);
8280 __ Cmp(x0, Operand(x0));
8281 END();
8282
8283 RUN();
8284
8285 ASSERT_EQUAL_NZCV(ZCFlag);
8286
8287 START();
8288 __ Mov(w0, 0);
8289 __ Cmp(w0, Operand(w0));
8290 END();
8291
8292 RUN();
8293
8294 ASSERT_EQUAL_NZCV(ZCFlag);
8295
8296 START();
8297 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00008298 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01008299 __ Cmp(x0, Operand(x1));
8300 END();
8301
8302 RUN();
8303
8304 ASSERT_EQUAL_NZCV(NFlag);
8305
8306 START();
8307 __ Mov(w0, 0);
8308 __ Mov(w1, 0x11111111);
8309 __ Cmp(w0, Operand(w1));
8310 END();
8311
8312 RUN();
8313
8314 ASSERT_EQUAL_NZCV(NFlag);
8315
8316 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008317 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01008318 __ Cmp(x1, Operand(0));
8319 END();
8320
8321 RUN();
8322
8323 ASSERT_EQUAL_NZCV(CFlag);
8324
8325 START();
8326 __ Mov(w1, 0x11111111);
8327 __ Cmp(w1, Operand(0));
8328 END();
8329
8330 RUN();
8331
8332 ASSERT_EQUAL_NZCV(CFlag);
8333
8334 START();
8335 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00008336 __ Mov(x1, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008337 __ Cmn(x1, Operand(x0));
8338 END();
8339
8340 RUN();
8341
8342 ASSERT_EQUAL_NZCV(NVFlag);
8343
8344 START();
8345 __ Mov(w0, 1);
8346 __ Mov(w1, 0x7fffffff);
8347 __ Cmn(w1, Operand(w0));
8348 END();
8349
8350 RUN();
8351
8352 ASSERT_EQUAL_NZCV(NVFlag);
8353
8354 START();
8355 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00008356 __ Mov(x1, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008357 __ Cmn(x1, Operand(x0));
8358 END();
8359
8360 RUN();
8361
8362 ASSERT_EQUAL_NZCV(ZCFlag);
8363
8364 START();
8365 __ Mov(w0, 1);
8366 __ Mov(w1, 0xffffffff);
8367 __ Cmn(w1, Operand(w0));
8368 END();
8369
8370 RUN();
8371
8372 ASSERT_EQUAL_NZCV(ZCFlag);
8373
8374 START();
8375 __ Mov(w0, 0);
8376 __ Mov(w1, 1);
8377 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00008378 __ Adds(w0, w0, Operand(0));
8379 __ Ngcs(w0, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +01008380 END();
8381
8382 RUN();
8383
8384 ASSERT_EQUAL_NZCV(NFlag);
8385
8386 START();
8387 __ Mov(w0, 0);
8388 __ Mov(w1, 0);
8389 // Set the C flag.
8390 __ Cmp(w0, Operand(w0));
armvixlf37fdc02014-02-05 13:22:16 +00008391 __ Ngcs(w0, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +01008392 END();
8393
8394 RUN();
8395
8396 ASSERT_EQUAL_NZCV(ZCFlag);
8397
8398 TEARDOWN();
8399}
8400
8401
8402TEST(cmp_shift) {
8403 SETUP();
8404
8405 START();
8406 __ Mov(x18, 0xf0000000);
armvixlb0c8ae22014-03-21 14:03:59 +00008407 __ Mov(x19, 0xf000000010000000);
8408 __ Mov(x20, 0xf0000000f0000000);
8409 __ Mov(x21, 0x7800000078000000);
8410 __ Mov(x22, 0x3c0000003c000000);
8411 __ Mov(x23, 0x8000000780000000);
8412 __ Mov(x24, 0x0000000f00000000);
8413 __ Mov(x25, 0x00000003c0000000);
8414 __ Mov(x26, 0x8000000780000000);
armvixlad96eda2013-06-14 11:42:37 +01008415 __ Mov(x27, 0xc0000003);
8416
8417 __ Cmp(w20, Operand(w21, LSL, 1));
8418 __ Mrs(x0, NZCV);
8419
8420 __ Cmp(x20, Operand(x22, LSL, 2));
8421 __ Mrs(x1, NZCV);
8422
8423 __ Cmp(w19, Operand(w23, LSR, 3));
8424 __ Mrs(x2, NZCV);
8425
8426 __ Cmp(x18, Operand(x24, LSR, 4));
8427 __ Mrs(x3, NZCV);
8428
8429 __ Cmp(w20, Operand(w25, ASR, 2));
8430 __ Mrs(x4, NZCV);
8431
8432 __ Cmp(x20, Operand(x26, ASR, 3));
8433 __ Mrs(x5, NZCV);
8434
8435 __ Cmp(w27, Operand(w22, ROR, 28));
8436 __ Mrs(x6, NZCV);
8437
8438 __ Cmp(x20, Operand(x21, ROR, 31));
8439 __ Mrs(x7, NZCV);
8440 END();
8441
8442 RUN();
8443
8444 ASSERT_EQUAL_32(ZCFlag, w0);
8445 ASSERT_EQUAL_32(ZCFlag, w1);
8446 ASSERT_EQUAL_32(ZCFlag, w2);
8447 ASSERT_EQUAL_32(ZCFlag, w3);
8448 ASSERT_EQUAL_32(ZCFlag, w4);
8449 ASSERT_EQUAL_32(ZCFlag, w5);
8450 ASSERT_EQUAL_32(ZCFlag, w6);
8451 ASSERT_EQUAL_32(ZCFlag, w7);
8452
8453 TEARDOWN();
8454}
8455
8456
8457TEST(cmp_extend) {
8458 SETUP();
8459
8460 START();
8461 __ Mov(w20, 0x2);
8462 __ Mov(w21, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00008463 __ Mov(x22, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008464 __ Mov(x23, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00008465 __ Mov(x24, 0xfffffffffffffffe);
armvixlad96eda2013-06-14 11:42:37 +01008466 __ Mov(x25, 0xffff);
8467 __ Mov(x26, 0xffffffff);
8468
8469 __ Cmp(w20, Operand(w21, LSL, 1));
8470 __ Mrs(x0, NZCV);
8471
8472 __ Cmp(x22, Operand(x23, SXTB, 0));
8473 __ Mrs(x1, NZCV);
8474
8475 __ Cmp(x24, Operand(x23, SXTB, 1));
8476 __ Mrs(x2, NZCV);
8477
8478 __ Cmp(x24, Operand(x23, UXTB, 1));
8479 __ Mrs(x3, NZCV);
8480
8481 __ Cmp(w22, Operand(w25, UXTH));
8482 __ Mrs(x4, NZCV);
8483
8484 __ Cmp(x22, Operand(x25, SXTH));
8485 __ Mrs(x5, NZCV);
8486
8487 __ Cmp(x22, Operand(x26, UXTW));
8488 __ Mrs(x6, NZCV);
8489
8490 __ Cmp(x24, Operand(x26, SXTW, 1));
8491 __ Mrs(x7, NZCV);
8492 END();
8493
8494 RUN();
8495
8496 ASSERT_EQUAL_32(ZCFlag, w0);
8497 ASSERT_EQUAL_32(ZCFlag, w1);
8498 ASSERT_EQUAL_32(ZCFlag, w2);
8499 ASSERT_EQUAL_32(NCFlag, w3);
8500 ASSERT_EQUAL_32(NCFlag, w4);
8501 ASSERT_EQUAL_32(ZCFlag, w5);
8502 ASSERT_EQUAL_32(NCFlag, w6);
8503 ASSERT_EQUAL_32(ZCFlag, w7);
8504
8505 TEARDOWN();
8506}
8507
8508
8509TEST(ccmp) {
8510 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008511 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008512
8513 START();
8514 __ Mov(w16, 0);
8515 __ Mov(w17, 1);
armvixl578645f2013-08-15 17:21:42 +01008516 __ Cmp(w16, w16);
8517 __ Ccmp(w16, w17, NCFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01008518 __ Mrs(x0, NZCV);
8519
armvixl578645f2013-08-15 17:21:42 +01008520 __ Cmp(w16, w16);
8521 __ Ccmp(w16, w17, NCFlag, ne);
armvixlad96eda2013-06-14 11:42:37 +01008522 __ Mrs(x1, NZCV);
8523
armvixl578645f2013-08-15 17:21:42 +01008524 __ Cmp(x16, x16);
8525 __ Ccmn(x16, 2, NZCVFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01008526 __ Mrs(x2, NZCV);
8527
armvixl578645f2013-08-15 17:21:42 +01008528 __ Cmp(x16, x16);
8529 __ Ccmn(x16, 2, NZCVFlag, ne);
armvixlad96eda2013-06-14 11:42:37 +01008530 __ Mrs(x3, NZCV);
armvixl578645f2013-08-15 17:21:42 +01008531
armvixlc68cb642014-09-25 18:49:30 +01008532 // The MacroAssembler does not allow al as a condition.
armvixl578645f2013-08-15 17:21:42 +01008533 __ ccmp(x16, x16, NZCVFlag, al);
8534 __ Mrs(x4, NZCV);
8535
armvixlc68cb642014-09-25 18:49:30 +01008536 // The MacroAssembler does not allow nv as a condition.
armvixl578645f2013-08-15 17:21:42 +01008537 __ ccmp(x16, x16, NZCVFlag, nv);
8538 __ Mrs(x5, NZCV);
8539
armvixlad96eda2013-06-14 11:42:37 +01008540 END();
8541
8542 RUN();
8543
8544 ASSERT_EQUAL_32(NFlag, w0);
8545 ASSERT_EQUAL_32(NCFlag, w1);
8546 ASSERT_EQUAL_32(NoFlag, w2);
8547 ASSERT_EQUAL_32(NZCVFlag, w3);
armvixl578645f2013-08-15 17:21:42 +01008548 ASSERT_EQUAL_32(ZCFlag, w4);
8549 ASSERT_EQUAL_32(ZCFlag, w5);
armvixlad96eda2013-06-14 11:42:37 +01008550
8551 TEARDOWN();
8552}
8553
8554
8555TEST(ccmp_wide_imm) {
8556 SETUP();
8557
8558 START();
8559 __ Mov(w20, 0);
8560
8561 __ Cmp(w20, Operand(w20));
8562 __ Ccmp(w20, Operand(0x12345678), NZCVFlag, eq);
8563 __ Mrs(x0, NZCV);
8564
8565 __ Cmp(w20, Operand(w20));
armvixlb0c8ae22014-03-21 14:03:59 +00008566 __ Ccmp(x20, Operand(0xffffffffffffffff), NZCVFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01008567 __ Mrs(x1, NZCV);
8568 END();
8569
8570 RUN();
8571
8572 ASSERT_EQUAL_32(NFlag, w0);
8573 ASSERT_EQUAL_32(NoFlag, w1);
8574
8575 TEARDOWN();
8576}
8577
8578
8579TEST(ccmp_shift_extend) {
8580 SETUP();
8581
8582 START();
8583 __ Mov(w20, 0x2);
8584 __ Mov(w21, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00008585 __ Mov(x22, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008586 __ Mov(x23, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00008587 __ Mov(x24, 0xfffffffffffffffe);
armvixlad96eda2013-06-14 11:42:37 +01008588
8589 __ Cmp(w20, Operand(w20));
8590 __ Ccmp(w20, Operand(w21, LSL, 1), NZCVFlag, eq);
8591 __ Mrs(x0, NZCV);
8592
8593 __ Cmp(w20, Operand(w20));
8594 __ Ccmp(x22, Operand(x23, SXTB, 0), NZCVFlag, eq);
8595 __ Mrs(x1, NZCV);
8596
8597 __ Cmp(w20, Operand(w20));
8598 __ Ccmp(x24, Operand(x23, SXTB, 1), NZCVFlag, eq);
8599 __ Mrs(x2, NZCV);
8600
8601 __ Cmp(w20, Operand(w20));
8602 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, eq);
8603 __ Mrs(x3, NZCV);
8604
8605 __ Cmp(w20, Operand(w20));
8606 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, ne);
8607 __ Mrs(x4, NZCV);
8608 END();
8609
8610 RUN();
8611
8612 ASSERT_EQUAL_32(ZCFlag, w0);
8613 ASSERT_EQUAL_32(ZCFlag, w1);
8614 ASSERT_EQUAL_32(ZCFlag, w2);
8615 ASSERT_EQUAL_32(NCFlag, w3);
8616 ASSERT_EQUAL_32(NZCVFlag, w4);
8617
8618 TEARDOWN();
8619}
8620
8621
Alexandre Rames2fbea6c2016-06-07 09:21:11 +01008622TEST(csel_reg) {
armvixlad96eda2013-06-14 11:42:37 +01008623 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008624 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008625
8626 START();
8627 __ Mov(x16, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00008628 __ Mov(x24, 0x0000000f0000000f);
8629 __ Mov(x25, 0x0000001f0000001f);
armvixlad96eda2013-06-14 11:42:37 +01008630
8631 __ Cmp(w16, Operand(0));
8632 __ Csel(w0, w24, w25, eq);
8633 __ Csel(w1, w24, w25, ne);
8634 __ Csinc(w2, w24, w25, mi);
8635 __ Csinc(w3, w24, w25, pl);
8636
armvixlc68cb642014-09-25 18:49:30 +01008637 // The MacroAssembler does not allow al or nv as a condition.
armvixl578645f2013-08-15 17:21:42 +01008638 __ csel(w13, w24, w25, al);
8639 __ csel(x14, x24, x25, nv);
8640
armvixlad96eda2013-06-14 11:42:37 +01008641 __ Cmp(x16, Operand(1));
8642 __ Csinv(x4, x24, x25, gt);
8643 __ Csinv(x5, x24, x25, le);
8644 __ Csneg(x6, x24, x25, hs);
8645 __ Csneg(x7, x24, x25, lo);
8646
8647 __ Cset(w8, ne);
8648 __ Csetm(w9, ne);
8649 __ Cinc(x10, x25, ne);
8650 __ Cinv(x11, x24, ne);
8651 __ Cneg(x12, x24, ne);
armvixl578645f2013-08-15 17:21:42 +01008652
armvixlc68cb642014-09-25 18:49:30 +01008653 // The MacroAssembler does not allow al or nv as a condition.
armvixl578645f2013-08-15 17:21:42 +01008654 __ csel(w15, w24, w25, al);
8655 __ csel(x17, x24, x25, nv);
8656
armvixlad96eda2013-06-14 11:42:37 +01008657 END();
8658
8659 RUN();
8660
8661 ASSERT_EQUAL_64(0x0000000f, x0);
8662 ASSERT_EQUAL_64(0x0000001f, x1);
8663 ASSERT_EQUAL_64(0x00000020, x2);
8664 ASSERT_EQUAL_64(0x0000000f, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00008665 ASSERT_EQUAL_64(0xffffffe0ffffffe0, x4);
8666 ASSERT_EQUAL_64(0x0000000f0000000f, x5);
8667 ASSERT_EQUAL_64(0xffffffe0ffffffe1, x6);
8668 ASSERT_EQUAL_64(0x0000000f0000000f, x7);
armvixlad96eda2013-06-14 11:42:37 +01008669 ASSERT_EQUAL_64(0x00000001, x8);
8670 ASSERT_EQUAL_64(0xffffffff, x9);
armvixlb0c8ae22014-03-21 14:03:59 +00008671 ASSERT_EQUAL_64(0x0000001f00000020, x10);
8672 ASSERT_EQUAL_64(0xfffffff0fffffff0, x11);
8673 ASSERT_EQUAL_64(0xfffffff0fffffff1, x12);
armvixl578645f2013-08-15 17:21:42 +01008674 ASSERT_EQUAL_64(0x0000000f, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00008675 ASSERT_EQUAL_64(0x0000000f0000000f, x14);
armvixl578645f2013-08-15 17:21:42 +01008676 ASSERT_EQUAL_64(0x0000000f, x15);
armvixlb0c8ae22014-03-21 14:03:59 +00008677 ASSERT_EQUAL_64(0x0000000f0000000f, x17);
armvixlad96eda2013-06-14 11:42:37 +01008678
8679 TEARDOWN();
8680}
8681
8682
armvixlf37fdc02014-02-05 13:22:16 +00008683TEST(csel_imm) {
8684 SETUP();
8685
Alexandre Rames2fbea6c2016-06-07 09:21:11 +01008686 int values[] = {-123, -2, -1, 0, 1, 2, 123};
8687 int n_values = sizeof(values) / sizeof(values[0]);
8688
8689 for (int i = 0; i < n_values; i++) {
8690 for (int j = 0; j < n_values; j++) {
8691 int left = values[i];
8692 int right = values[j];
8693
8694 START();
8695 __ Mov(x10, 0);
8696 __ Cmp(x10, 0);
8697 __ Csel(w0, left, right, eq);
8698 __ Csel(w1, left, right, ne);
8699 __ Csel(x2, left, right, eq);
8700 __ Csel(x3, left, right, ne);
8701
8702 END();
8703
8704 RUN();
8705
8706 ASSERT_EQUAL_32(left, w0);
8707 ASSERT_EQUAL_32(right, w1);
8708 ASSERT_EQUAL_64(left, x2);
8709 ASSERT_EQUAL_64(right, x3);
8710 }
8711 }
8712
8713 TEARDOWN();
8714}
8715
8716
8717TEST(csel_mixed) {
8718 SETUP();
8719
armvixlf37fdc02014-02-05 13:22:16 +00008720 START();
8721 __ Mov(x18, 0);
8722 __ Mov(x19, 0x80000000);
armvixlb0c8ae22014-03-21 14:03:59 +00008723 __ Mov(x20, 0x8000000000000000);
armvixlf37fdc02014-02-05 13:22:16 +00008724
8725 __ Cmp(x18, Operand(0));
8726 __ Csel(w0, w19, -2, ne);
8727 __ Csel(w1, w19, -1, ne);
8728 __ Csel(w2, w19, 0, ne);
8729 __ Csel(w3, w19, 1, ne);
8730 __ Csel(w4, w19, 2, ne);
8731 __ Csel(w5, w19, Operand(w19, ASR, 31), ne);
8732 __ Csel(w6, w19, Operand(w19, ROR, 1), ne);
8733 __ Csel(w7, w19, 3, eq);
8734
8735 __ Csel(x8, x20, -2, ne);
8736 __ Csel(x9, x20, -1, ne);
8737 __ Csel(x10, x20, 0, ne);
8738 __ Csel(x11, x20, 1, ne);
8739 __ Csel(x12, x20, 2, ne);
8740 __ Csel(x13, x20, Operand(x20, ASR, 63), ne);
8741 __ Csel(x14, x20, Operand(x20, ROR, 1), ne);
8742 __ Csel(x15, x20, 3, eq);
8743
8744 END();
8745
8746 RUN();
8747
8748 ASSERT_EQUAL_32(-2, w0);
8749 ASSERT_EQUAL_32(-1, w1);
8750 ASSERT_EQUAL_32(0, w2);
8751 ASSERT_EQUAL_32(1, w3);
8752 ASSERT_EQUAL_32(2, w4);
8753 ASSERT_EQUAL_32(-1, w5);
8754 ASSERT_EQUAL_32(0x40000000, w6);
8755 ASSERT_EQUAL_32(0x80000000, w7);
8756
8757 ASSERT_EQUAL_64(-2, x8);
8758 ASSERT_EQUAL_64(-1, x9);
8759 ASSERT_EQUAL_64(0, x10);
8760 ASSERT_EQUAL_64(1, x11);
8761 ASSERT_EQUAL_64(2, x12);
8762 ASSERT_EQUAL_64(-1, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00008763 ASSERT_EQUAL_64(0x4000000000000000, x14);
8764 ASSERT_EQUAL_64(0x8000000000000000, x15);
armvixlf37fdc02014-02-05 13:22:16 +00008765
8766 TEARDOWN();
8767}
8768
8769
armvixlad96eda2013-06-14 11:42:37 +01008770TEST(lslv) {
8771 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008772 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008773
armvixlb0c8ae22014-03-21 14:03:59 +00008774 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01008775 int shift[] = {1, 3, 5, 9, 17, 33};
8776
8777 START();
8778 __ Mov(x0, value);
8779 __ Mov(w1, shift[0]);
8780 __ Mov(w2, shift[1]);
8781 __ Mov(w3, shift[2]);
8782 __ Mov(w4, shift[3]);
8783 __ Mov(w5, shift[4]);
8784 __ Mov(w6, shift[5]);
8785
armvixlc68cb642014-09-25 18:49:30 +01008786 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008787 __ lslv(x0, x0, xzr);
8788
8789 __ Lsl(x16, x0, x1);
8790 __ Lsl(x17, x0, x2);
8791 __ Lsl(x18, x0, x3);
8792 __ Lsl(x19, x0, x4);
8793 __ Lsl(x20, x0, x5);
8794 __ Lsl(x21, x0, x6);
8795
8796 __ Lsl(w22, w0, w1);
8797 __ Lsl(w23, w0, w2);
8798 __ Lsl(w24, w0, w3);
8799 __ Lsl(w25, w0, w4);
8800 __ Lsl(w26, w0, w5);
8801 __ Lsl(w27, w0, w6);
8802 END();
8803
8804 RUN();
8805
8806 ASSERT_EQUAL_64(value, x0);
8807 ASSERT_EQUAL_64(value << (shift[0] & 63), x16);
8808 ASSERT_EQUAL_64(value << (shift[1] & 63), x17);
8809 ASSERT_EQUAL_64(value << (shift[2] & 63), x18);
8810 ASSERT_EQUAL_64(value << (shift[3] & 63), x19);
8811 ASSERT_EQUAL_64(value << (shift[4] & 63), x20);
8812 ASSERT_EQUAL_64(value << (shift[5] & 63), x21);
8813 ASSERT_EQUAL_32(value << (shift[0] & 31), w22);
8814 ASSERT_EQUAL_32(value << (shift[1] & 31), w23);
8815 ASSERT_EQUAL_32(value << (shift[2] & 31), w24);
8816 ASSERT_EQUAL_32(value << (shift[3] & 31), w25);
8817 ASSERT_EQUAL_32(value << (shift[4] & 31), w26);
8818 ASSERT_EQUAL_32(value << (shift[5] & 31), w27);
8819
8820 TEARDOWN();
8821}
8822
8823
8824TEST(lsrv) {
8825 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008826 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008827
armvixlb0c8ae22014-03-21 14:03:59 +00008828 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01008829 int shift[] = {1, 3, 5, 9, 17, 33};
8830
8831 START();
8832 __ Mov(x0, value);
8833 __ Mov(w1, shift[0]);
8834 __ Mov(w2, shift[1]);
8835 __ Mov(w3, shift[2]);
8836 __ Mov(w4, shift[3]);
8837 __ Mov(w5, shift[4]);
8838 __ Mov(w6, shift[5]);
8839
armvixlc68cb642014-09-25 18:49:30 +01008840 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008841 __ lsrv(x0, x0, xzr);
8842
8843 __ Lsr(x16, x0, x1);
8844 __ Lsr(x17, x0, x2);
8845 __ Lsr(x18, x0, x3);
8846 __ Lsr(x19, x0, x4);
8847 __ Lsr(x20, x0, x5);
8848 __ Lsr(x21, x0, x6);
8849
8850 __ Lsr(w22, w0, w1);
8851 __ Lsr(w23, w0, w2);
8852 __ Lsr(w24, w0, w3);
8853 __ Lsr(w25, w0, w4);
8854 __ Lsr(w26, w0, w5);
8855 __ Lsr(w27, w0, w6);
8856 END();
8857
8858 RUN();
8859
8860 ASSERT_EQUAL_64(value, x0);
8861 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
8862 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
8863 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
8864 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
8865 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
8866 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
8867
armvixlb0c8ae22014-03-21 14:03:59 +00008868 value &= 0xffffffff;
armvixlad96eda2013-06-14 11:42:37 +01008869 ASSERT_EQUAL_32(value >> (shift[0] & 31), w22);
8870 ASSERT_EQUAL_32(value >> (shift[1] & 31), w23);
8871 ASSERT_EQUAL_32(value >> (shift[2] & 31), w24);
8872 ASSERT_EQUAL_32(value >> (shift[3] & 31), w25);
8873 ASSERT_EQUAL_32(value >> (shift[4] & 31), w26);
8874 ASSERT_EQUAL_32(value >> (shift[5] & 31), w27);
8875
8876 TEARDOWN();
8877}
8878
8879
8880TEST(asrv) {
8881 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008882 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008883
armvixlb0c8ae22014-03-21 14:03:59 +00008884 int64_t value = 0xfedcba98fedcba98;
armvixlad96eda2013-06-14 11:42:37 +01008885 int shift[] = {1, 3, 5, 9, 17, 33};
8886
8887 START();
8888 __ Mov(x0, value);
8889 __ Mov(w1, shift[0]);
8890 __ Mov(w2, shift[1]);
8891 __ Mov(w3, shift[2]);
8892 __ Mov(w4, shift[3]);
8893 __ Mov(w5, shift[4]);
8894 __ Mov(w6, shift[5]);
8895
armvixlc68cb642014-09-25 18:49:30 +01008896 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008897 __ asrv(x0, x0, xzr);
8898
8899 __ Asr(x16, x0, x1);
8900 __ Asr(x17, x0, x2);
8901 __ Asr(x18, x0, x3);
8902 __ Asr(x19, x0, x4);
8903 __ Asr(x20, x0, x5);
8904 __ Asr(x21, x0, x6);
8905
8906 __ Asr(w22, w0, w1);
8907 __ Asr(w23, w0, w2);
8908 __ Asr(w24, w0, w3);
8909 __ Asr(w25, w0, w4);
8910 __ Asr(w26, w0, w5);
8911 __ Asr(w27, w0, w6);
8912 END();
8913
8914 RUN();
8915
8916 ASSERT_EQUAL_64(value, x0);
8917 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
8918 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
8919 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
8920 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
8921 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
8922 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
8923
armvixlb0c8ae22014-03-21 14:03:59 +00008924 int32_t value32 = static_cast<int32_t>(value & 0xffffffff);
armvixlad96eda2013-06-14 11:42:37 +01008925 ASSERT_EQUAL_32(value32 >> (shift[0] & 31), w22);
8926 ASSERT_EQUAL_32(value32 >> (shift[1] & 31), w23);
8927 ASSERT_EQUAL_32(value32 >> (shift[2] & 31), w24);
8928 ASSERT_EQUAL_32(value32 >> (shift[3] & 31), w25);
8929 ASSERT_EQUAL_32(value32 >> (shift[4] & 31), w26);
8930 ASSERT_EQUAL_32(value32 >> (shift[5] & 31), w27);
8931
8932 TEARDOWN();
8933}
8934
8935
8936TEST(rorv) {
8937 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008938 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008939
armvixlb0c8ae22014-03-21 14:03:59 +00008940 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01008941 int shift[] = {4, 8, 12, 16, 24, 36};
8942
8943 START();
8944 __ Mov(x0, value);
8945 __ Mov(w1, shift[0]);
8946 __ Mov(w2, shift[1]);
8947 __ Mov(w3, shift[2]);
8948 __ Mov(w4, shift[3]);
8949 __ Mov(w5, shift[4]);
8950 __ Mov(w6, shift[5]);
8951
armvixlc68cb642014-09-25 18:49:30 +01008952 // The MacroAssembler does not allow zr as an argument.
armvixlad96eda2013-06-14 11:42:37 +01008953 __ rorv(x0, x0, xzr);
8954
8955 __ Ror(x16, x0, x1);
8956 __ Ror(x17, x0, x2);
8957 __ Ror(x18, x0, x3);
8958 __ Ror(x19, x0, x4);
8959 __ Ror(x20, x0, x5);
8960 __ Ror(x21, x0, x6);
8961
8962 __ Ror(w22, w0, w1);
8963 __ Ror(w23, w0, w2);
8964 __ Ror(w24, w0, w3);
8965 __ Ror(w25, w0, w4);
8966 __ Ror(w26, w0, w5);
8967 __ Ror(w27, w0, w6);
8968 END();
8969
8970 RUN();
8971
8972 ASSERT_EQUAL_64(value, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00008973 ASSERT_EQUAL_64(0xf0123456789abcde, x16);
8974 ASSERT_EQUAL_64(0xef0123456789abcd, x17);
8975 ASSERT_EQUAL_64(0xdef0123456789abc, x18);
8976 ASSERT_EQUAL_64(0xcdef0123456789ab, x19);
8977 ASSERT_EQUAL_64(0xabcdef0123456789, x20);
8978 ASSERT_EQUAL_64(0x789abcdef0123456, x21);
armvixlad96eda2013-06-14 11:42:37 +01008979 ASSERT_EQUAL_32(0xf89abcde, w22);
8980 ASSERT_EQUAL_32(0xef89abcd, w23);
8981 ASSERT_EQUAL_32(0xdef89abc, w24);
8982 ASSERT_EQUAL_32(0xcdef89ab, w25);
8983 ASSERT_EQUAL_32(0xabcdef89, w26);
8984 ASSERT_EQUAL_32(0xf89abcde, w27);
8985
8986 TEARDOWN();
8987}
8988
8989
8990TEST(bfm) {
8991 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01008992 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01008993
8994 START();
armvixlb0c8ae22014-03-21 14:03:59 +00008995 __ Mov(x1, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01008996
armvixlb0c8ae22014-03-21 14:03:59 +00008997 __ Mov(x10, 0x8888888888888888);
8998 __ Mov(x11, 0x8888888888888888);
8999 __ Mov(x12, 0x8888888888888888);
9000 __ Mov(x13, 0x8888888888888888);
armvixlad96eda2013-06-14 11:42:37 +01009001 __ Mov(w20, 0x88888888);
9002 __ Mov(w21, 0x88888888);
9003
armvixlc68cb642014-09-25 18:49:30 +01009004 // There are no macro instruction for bfm.
armvixl5289c592015-03-02 13:52:04 +00009005 __ Bfm(x10, x1, 16, 31);
9006 __ Bfm(x11, x1, 32, 15);
armvixlad96eda2013-06-14 11:42:37 +01009007
armvixl5289c592015-03-02 13:52:04 +00009008 __ Bfm(w20, w1, 16, 23);
9009 __ Bfm(w21, w1, 24, 15);
armvixlad96eda2013-06-14 11:42:37 +01009010
9011 // Aliases.
9012 __ Bfi(x12, x1, 16, 8);
9013 __ Bfxil(x13, x1, 16, 8);
9014 END();
9015
9016 RUN();
9017
9018
armvixlb0c8ae22014-03-21 14:03:59 +00009019 ASSERT_EQUAL_64(0x88888888888889ab, x10);
9020 ASSERT_EQUAL_64(0x8888cdef88888888, x11);
armvixlad96eda2013-06-14 11:42:37 +01009021
9022 ASSERT_EQUAL_32(0x888888ab, w20);
9023 ASSERT_EQUAL_32(0x88cdef88, w21);
9024
armvixlb0c8ae22014-03-21 14:03:59 +00009025 ASSERT_EQUAL_64(0x8888888888ef8888, x12);
9026 ASSERT_EQUAL_64(0x88888888888888ab, x13);
armvixlad96eda2013-06-14 11:42:37 +01009027
9028 TEARDOWN();
9029}
9030
9031
9032TEST(sbfm) {
9033 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01009034 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01009035
9036 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009037 __ Mov(x1, 0x0123456789abcdef);
9038 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01009039
armvixlc68cb642014-09-25 18:49:30 +01009040 // There are no macro instruction for sbfm.
armvixl5289c592015-03-02 13:52:04 +00009041 __ Sbfm(x10, x1, 16, 31);
9042 __ Sbfm(x11, x1, 32, 15);
9043 __ Sbfm(x12, x1, 32, 47);
9044 __ Sbfm(x13, x1, 48, 35);
armvixlad96eda2013-06-14 11:42:37 +01009045
armvixl5289c592015-03-02 13:52:04 +00009046 __ Sbfm(w14, w1, 16, 23);
9047 __ Sbfm(w15, w1, 24, 15);
9048 __ Sbfm(w16, w2, 16, 23);
9049 __ Sbfm(w17, w2, 24, 15);
armvixlad96eda2013-06-14 11:42:37 +01009050
9051 // Aliases.
9052 __ Asr(x18, x1, 32);
9053 __ Asr(x19, x2, 32);
9054 __ Sbfiz(x20, x1, 8, 16);
9055 __ Sbfiz(x21, x2, 8, 16);
9056 __ Sbfx(x22, x1, 8, 16);
9057 __ Sbfx(x23, x2, 8, 16);
armvixlf37fdc02014-02-05 13:22:16 +00009058 __ Sxtb(x24, w1);
armvixlad96eda2013-06-14 11:42:37 +01009059 __ Sxtb(x25, x2);
armvixlf37fdc02014-02-05 13:22:16 +00009060 __ Sxth(x26, w1);
armvixlad96eda2013-06-14 11:42:37 +01009061 __ Sxth(x27, x2);
armvixlf37fdc02014-02-05 13:22:16 +00009062 __ Sxtw(x28, w1);
armvixlad96eda2013-06-14 11:42:37 +01009063 __ Sxtw(x29, x2);
9064 END();
9065
9066 RUN();
9067
9068
armvixlb0c8ae22014-03-21 14:03:59 +00009069 ASSERT_EQUAL_64(0xffffffffffff89ab, x10);
9070 ASSERT_EQUAL_64(0xffffcdef00000000, x11);
9071 ASSERT_EQUAL_64(0x0000000000004567, x12);
9072 ASSERT_EQUAL_64(0x000789abcdef0000, x13);
armvixlad96eda2013-06-14 11:42:37 +01009073
9074 ASSERT_EQUAL_32(0xffffffab, w14);
9075 ASSERT_EQUAL_32(0xffcdef00, w15);
armvixlb0c8ae22014-03-21 14:03:59 +00009076 ASSERT_EQUAL_32(0x00000054, w16);
armvixlad96eda2013-06-14 11:42:37 +01009077 ASSERT_EQUAL_32(0x00321000, w17);
9078
armvixlb0c8ae22014-03-21 14:03:59 +00009079 ASSERT_EQUAL_64(0x0000000001234567, x18);
9080 ASSERT_EQUAL_64(0xfffffffffedcba98, x19);
9081 ASSERT_EQUAL_64(0xffffffffffcdef00, x20);
9082 ASSERT_EQUAL_64(0x0000000000321000, x21);
9083 ASSERT_EQUAL_64(0xffffffffffffabcd, x22);
9084 ASSERT_EQUAL_64(0x0000000000005432, x23);
9085 ASSERT_EQUAL_64(0xffffffffffffffef, x24);
9086 ASSERT_EQUAL_64(0x0000000000000010, x25);
9087 ASSERT_EQUAL_64(0xffffffffffffcdef, x26);
9088 ASSERT_EQUAL_64(0x0000000000003210, x27);
9089 ASSERT_EQUAL_64(0xffffffff89abcdef, x28);
9090 ASSERT_EQUAL_64(0x0000000076543210, x29);
armvixlad96eda2013-06-14 11:42:37 +01009091
9092 TEARDOWN();
9093}
9094
9095
9096TEST(ubfm) {
9097 SETUP();
armvixlc68cb642014-09-25 18:49:30 +01009098 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +01009099
9100 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009101 __ Mov(x1, 0x0123456789abcdef);
9102 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01009103
armvixlb0c8ae22014-03-21 14:03:59 +00009104 __ Mov(x10, 0x8888888888888888);
9105 __ Mov(x11, 0x8888888888888888);
armvixlad96eda2013-06-14 11:42:37 +01009106
armvixlc68cb642014-09-25 18:49:30 +01009107 // There are no macro instruction for ubfm.
armvixl5289c592015-03-02 13:52:04 +00009108 __ Ubfm(x10, x1, 16, 31);
9109 __ Ubfm(x11, x1, 32, 15);
9110 __ Ubfm(x12, x1, 32, 47);
9111 __ Ubfm(x13, x1, 48, 35);
armvixlad96eda2013-06-14 11:42:37 +01009112
armvixl5289c592015-03-02 13:52:04 +00009113 __ Ubfm(w25, w1, 16, 23);
9114 __ Ubfm(w26, w1, 24, 15);
9115 __ Ubfm(w27, w2, 16, 23);
9116 __ Ubfm(w28, w2, 24, 15);
armvixlad96eda2013-06-14 11:42:37 +01009117
9118 // Aliases
9119 __ Lsl(x15, x1, 63);
9120 __ Lsl(x16, x1, 0);
9121 __ Lsr(x17, x1, 32);
9122 __ Ubfiz(x18, x1, 8, 16);
9123 __ Ubfx(x19, x1, 8, 16);
9124 __ Uxtb(x20, x1);
9125 __ Uxth(x21, x1);
9126 __ Uxtw(x22, x1);
9127 END();
9128
9129 RUN();
9130
armvixlb0c8ae22014-03-21 14:03:59 +00009131 ASSERT_EQUAL_64(0x00000000000089ab, x10);
9132 ASSERT_EQUAL_64(0x0000cdef00000000, x11);
9133 ASSERT_EQUAL_64(0x0000000000004567, x12);
9134 ASSERT_EQUAL_64(0x000789abcdef0000, x13);
armvixlad96eda2013-06-14 11:42:37 +01009135
9136 ASSERT_EQUAL_32(0x000000ab, w25);
9137 ASSERT_EQUAL_32(0x00cdef00, w26);
armvixlb0c8ae22014-03-21 14:03:59 +00009138 ASSERT_EQUAL_32(0x00000054, w27);
armvixlad96eda2013-06-14 11:42:37 +01009139 ASSERT_EQUAL_32(0x00321000, w28);
9140
armvixlb0c8ae22014-03-21 14:03:59 +00009141 ASSERT_EQUAL_64(0x8000000000000000, x15);
9142 ASSERT_EQUAL_64(0x0123456789abcdef, x16);
9143 ASSERT_EQUAL_64(0x0000000001234567, x17);
9144 ASSERT_EQUAL_64(0x0000000000cdef00, x18);
9145 ASSERT_EQUAL_64(0x000000000000abcd, x19);
9146 ASSERT_EQUAL_64(0x00000000000000ef, x20);
9147 ASSERT_EQUAL_64(0x000000000000cdef, x21);
9148 ASSERT_EQUAL_64(0x0000000089abcdef, x22);
armvixlad96eda2013-06-14 11:42:37 +01009149
9150 TEARDOWN();
9151}
9152
9153
9154TEST(extr) {
9155 SETUP();
9156
9157 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009158 __ Mov(x1, 0x0123456789abcdef);
9159 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01009160
9161 __ Extr(w10, w1, w2, 0);
9162 __ Extr(w11, w1, w2, 1);
9163 __ Extr(x12, x2, x1, 2);
9164
9165 __ Ror(w13, w1, 0);
9166 __ Ror(w14, w2, 17);
9167 __ Ror(w15, w1, 31);
armvixl4a102ba2014-07-14 09:02:40 +01009168 __ Ror(x18, x2, 0);
9169 __ Ror(x19, x2, 1);
9170 __ Ror(x20, x1, 63);
armvixlad96eda2013-06-14 11:42:37 +01009171 END();
9172
9173 RUN();
9174
9175 ASSERT_EQUAL_64(0x76543210, x10);
9176 ASSERT_EQUAL_64(0xbb2a1908, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00009177 ASSERT_EQUAL_64(0x0048d159e26af37b, x12);
armvixlad96eda2013-06-14 11:42:37 +01009178 ASSERT_EQUAL_64(0x89abcdef, x13);
9179 ASSERT_EQUAL_64(0x19083b2a, x14);
9180 ASSERT_EQUAL_64(0x13579bdf, x15);
armvixl4a102ba2014-07-14 09:02:40 +01009181 ASSERT_EQUAL_64(0xfedcba9876543210, x18);
9182 ASSERT_EQUAL_64(0x7f6e5d4c3b2a1908, x19);
9183 ASSERT_EQUAL_64(0x02468acf13579bde, x20);
armvixlad96eda2013-06-14 11:42:37 +01009184
9185 TEARDOWN();
9186}
9187
9188
9189TEST(fmov_imm) {
9190 SETUP();
9191
9192 START();
9193 __ Fmov(s11, 1.0);
9194 __ Fmov(d22, -13.0);
9195 __ Fmov(s1, 255.0);
9196 __ Fmov(d2, 12.34567);
9197 __ Fmov(s3, 0.0);
9198 __ Fmov(d4, 0.0);
9199 __ Fmov(s5, kFP32PositiveInfinity);
9200 __ Fmov(d6, kFP64NegativeInfinity);
9201 END();
9202
9203 RUN();
9204
9205 ASSERT_EQUAL_FP32(1.0, s11);
9206 ASSERT_EQUAL_FP64(-13.0, d22);
9207 ASSERT_EQUAL_FP32(255.0, s1);
9208 ASSERT_EQUAL_FP64(12.34567, d2);
9209 ASSERT_EQUAL_FP32(0.0, s3);
9210 ASSERT_EQUAL_FP64(0.0, d4);
9211 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
9212 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d6);
9213
9214 TEARDOWN();
9215}
9216
9217
9218TEST(fmov_reg) {
9219 SETUP();
9220
9221 START();
9222 __ Fmov(s20, 1.0);
9223 __ Fmov(w10, s20);
9224 __ Fmov(s30, w10);
9225 __ Fmov(s5, s20);
9226 __ Fmov(d1, -13.0);
9227 __ Fmov(x1, d1);
9228 __ Fmov(d2, x1);
9229 __ Fmov(d4, d1);
armvixlb0c8ae22014-03-21 14:03:59 +00009230 __ Fmov(d6, rawbits_to_double(0x0123456789abcdef));
armvixlad96eda2013-06-14 11:42:37 +01009231 __ Fmov(s6, s6);
armvixl5289c592015-03-02 13:52:04 +00009232
9233 __ Fmov(d0, 0.0);
9234 __ Fmov(v0.D(), 1, x1);
9235 __ Fmov(x2, v0.D(), 1);
9236
armvixlad96eda2013-06-14 11:42:37 +01009237 END();
9238
9239 RUN();
9240
9241 ASSERT_EQUAL_32(float_to_rawbits(1.0), w10);
9242 ASSERT_EQUAL_FP32(1.0, s30);
9243 ASSERT_EQUAL_FP32(1.0, s5);
9244 ASSERT_EQUAL_64(double_to_rawbits(-13.0), x1);
9245 ASSERT_EQUAL_FP64(-13.0, d2);
9246 ASSERT_EQUAL_FP64(-13.0, d4);
9247 ASSERT_EQUAL_FP32(rawbits_to_float(0x89abcdef), s6);
armvixl5289c592015-03-02 13:52:04 +00009248 ASSERT_EQUAL_128(double_to_rawbits(-13.0), 0x0000000000000000, q0);
9249 ASSERT_EQUAL_64(double_to_rawbits(-13.0), x2);
armvixlad96eda2013-06-14 11:42:37 +01009250 TEARDOWN();
9251}
9252
9253
9254TEST(fadd) {
9255 SETUP();
9256
9257 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009258 __ Fmov(s14, -0.0f);
9259 __ Fmov(s15, kFP32PositiveInfinity);
9260 __ Fmov(s16, kFP32NegativeInfinity);
9261 __ Fmov(s17, 3.25f);
9262 __ Fmov(s18, 1.0f);
9263 __ Fmov(s19, 0.0f);
armvixlad96eda2013-06-14 11:42:37 +01009264
9265 __ Fmov(d26, -0.0);
9266 __ Fmov(d27, kFP64PositiveInfinity);
9267 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009268 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01009269 __ Fmov(d30, -2.0);
9270 __ Fmov(d31, 2.25);
9271
armvixlb0c8ae22014-03-21 14:03:59 +00009272 __ Fadd(s0, s17, s18);
9273 __ Fadd(s1, s18, s19);
9274 __ Fadd(s2, s14, s18);
9275 __ Fadd(s3, s15, s18);
9276 __ Fadd(s4, s16, s18);
9277 __ Fadd(s5, s15, s16);
9278 __ Fadd(s6, s16, s15);
armvixlad96eda2013-06-14 11:42:37 +01009279
armvixlb0c8ae22014-03-21 14:03:59 +00009280 __ Fadd(d7, d30, d31);
9281 __ Fadd(d8, d29, d31);
9282 __ Fadd(d9, d26, d31);
9283 __ Fadd(d10, d27, d31);
9284 __ Fadd(d11, d28, d31);
9285 __ Fadd(d12, d27, d28);
9286 __ Fadd(d13, d28, d27);
armvixlad96eda2013-06-14 11:42:37 +01009287 END();
9288
9289 RUN();
9290
9291 ASSERT_EQUAL_FP32(4.25, s0);
9292 ASSERT_EQUAL_FP32(1.0, s1);
9293 ASSERT_EQUAL_FP32(1.0, s2);
9294 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
9295 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00009296 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9297 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9298 ASSERT_EQUAL_FP64(0.25, d7);
9299 ASSERT_EQUAL_FP64(2.25, d8);
9300 ASSERT_EQUAL_FP64(2.25, d9);
9301 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d10);
9302 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d11);
9303 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9304 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009305
9306 TEARDOWN();
9307}
9308
9309
9310TEST(fsub) {
9311 SETUP();
9312
9313 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009314 __ Fmov(s14, -0.0f);
9315 __ Fmov(s15, kFP32PositiveInfinity);
9316 __ Fmov(s16, kFP32NegativeInfinity);
9317 __ Fmov(s17, 3.25f);
9318 __ Fmov(s18, 1.0f);
9319 __ Fmov(s19, 0.0f);
armvixlad96eda2013-06-14 11:42:37 +01009320
9321 __ Fmov(d26, -0.0);
9322 __ Fmov(d27, kFP64PositiveInfinity);
9323 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009324 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01009325 __ Fmov(d30, -2.0);
9326 __ Fmov(d31, 2.25);
9327
armvixlb0c8ae22014-03-21 14:03:59 +00009328 __ Fsub(s0, s17, s18);
9329 __ Fsub(s1, s18, s19);
9330 __ Fsub(s2, s14, s18);
9331 __ Fsub(s3, s18, s15);
9332 __ Fsub(s4, s18, s16);
9333 __ Fsub(s5, s15, s15);
9334 __ Fsub(s6, s16, s16);
armvixlad96eda2013-06-14 11:42:37 +01009335
armvixlb0c8ae22014-03-21 14:03:59 +00009336 __ Fsub(d7, d30, d31);
9337 __ Fsub(d8, d29, d31);
9338 __ Fsub(d9, d26, d31);
9339 __ Fsub(d10, d31, d27);
9340 __ Fsub(d11, d31, d28);
9341 __ Fsub(d12, d27, d27);
9342 __ Fsub(d13, d28, d28);
armvixlad96eda2013-06-14 11:42:37 +01009343 END();
9344
9345 RUN();
9346
9347 ASSERT_EQUAL_FP32(2.25, s0);
9348 ASSERT_EQUAL_FP32(1.0, s1);
9349 ASSERT_EQUAL_FP32(-1.0, s2);
9350 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
9351 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00009352 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9353 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9354 ASSERT_EQUAL_FP64(-4.25, d7);
9355 ASSERT_EQUAL_FP64(-2.25, d8);
9356 ASSERT_EQUAL_FP64(-2.25, d9);
9357 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
9358 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
9359 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9360 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009361
9362 TEARDOWN();
9363}
9364
9365
9366TEST(fmul) {
9367 SETUP();
9368
9369 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009370 __ Fmov(s14, -0.0f);
9371 __ Fmov(s15, kFP32PositiveInfinity);
9372 __ Fmov(s16, kFP32NegativeInfinity);
9373 __ Fmov(s17, 3.25f);
9374 __ Fmov(s18, 2.0f);
9375 __ Fmov(s19, 0.0f);
9376 __ Fmov(s20, -2.0f);
armvixlad96eda2013-06-14 11:42:37 +01009377
9378 __ Fmov(d26, -0.0);
9379 __ Fmov(d27, kFP64PositiveInfinity);
9380 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009381 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01009382 __ Fmov(d30, -2.0);
9383 __ Fmov(d31, 2.25);
9384
armvixlb0c8ae22014-03-21 14:03:59 +00009385 __ Fmul(s0, s17, s18);
9386 __ Fmul(s1, s18, s19);
9387 __ Fmul(s2, s14, s14);
9388 __ Fmul(s3, s15, s20);
9389 __ Fmul(s4, s16, s20);
9390 __ Fmul(s5, s15, s19);
9391 __ Fmul(s6, s19, s16);
armvixlad96eda2013-06-14 11:42:37 +01009392
armvixlb0c8ae22014-03-21 14:03:59 +00009393 __ Fmul(d7, d30, d31);
9394 __ Fmul(d8, d29, d31);
9395 __ Fmul(d9, d26, d26);
9396 __ Fmul(d10, d27, d30);
9397 __ Fmul(d11, d28, d30);
9398 __ Fmul(d12, d27, d29);
9399 __ Fmul(d13, d29, d28);
armvixlad96eda2013-06-14 11:42:37 +01009400 END();
9401
9402 RUN();
9403
9404 ASSERT_EQUAL_FP32(6.5, s0);
9405 ASSERT_EQUAL_FP32(0.0, s1);
9406 ASSERT_EQUAL_FP32(0.0, s2);
9407 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
9408 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00009409 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9410 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9411 ASSERT_EQUAL_FP64(-4.5, d7);
9412 ASSERT_EQUAL_FP64(0.0, d8);
9413 ASSERT_EQUAL_FP64(0.0, d9);
9414 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
9415 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
9416 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9417 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009418
9419 TEARDOWN();
9420}
9421
9422
armvixlb0c8ae22014-03-21 14:03:59 +00009423static void FmaddFmsubHelper(double n, double m, double a,
9424 double fmadd, double fmsub,
9425 double fnmadd, double fnmsub) {
armvixlad96eda2013-06-14 11:42:37 +01009426 SETUP();
armvixlad96eda2013-06-14 11:42:37 +01009427 START();
armvixlad96eda2013-06-14 11:42:37 +01009428
armvixlf37fdc02014-02-05 13:22:16 +00009429 __ Fmov(d0, n);
9430 __ Fmov(d1, m);
9431 __ Fmov(d2, a);
9432 __ Fmadd(d28, d0, d1, d2);
9433 __ Fmsub(d29, d0, d1, d2);
9434 __ Fnmadd(d30, d0, d1, d2);
9435 __ Fnmsub(d31, d0, d1, d2);
armvixlad96eda2013-06-14 11:42:37 +01009436
armvixlad96eda2013-06-14 11:42:37 +01009437 END();
armvixlad96eda2013-06-14 11:42:37 +01009438 RUN();
9439
armvixlf37fdc02014-02-05 13:22:16 +00009440 ASSERT_EQUAL_FP64(fmadd, d28);
9441 ASSERT_EQUAL_FP64(fmsub, d29);
armvixlb0c8ae22014-03-21 14:03:59 +00009442 ASSERT_EQUAL_FP64(fnmadd, d30);
9443 ASSERT_EQUAL_FP64(fnmsub, d31);
armvixlad96eda2013-06-14 11:42:37 +01009444
9445 TEARDOWN();
9446}
9447
9448
armvixlf37fdc02014-02-05 13:22:16 +00009449TEST(fmadd_fmsub_double) {
armvixlb0c8ae22014-03-21 14:03:59 +00009450 // It's hard to check the result of fused operations because the only way to
9451 // calculate the result is using fma, which is what the simulator uses anyway.
armvixlf37fdc02014-02-05 13:22:16 +00009452
armvixlb0c8ae22014-03-21 14:03:59 +00009453 // Basic operation.
9454 FmaddFmsubHelper(1.0, 2.0, 3.0, 5.0, 1.0, -5.0, -1.0);
9455 FmaddFmsubHelper(-1.0, 2.0, 3.0, 1.0, 5.0, -1.0, -5.0);
armvixlf37fdc02014-02-05 13:22:16 +00009456
armvixlb0c8ae22014-03-21 14:03:59 +00009457 // Check the sign of exact zeroes.
9458 // n m a fmadd fmsub fnmadd fnmsub
9459 FmaddFmsubHelper(-0.0, +0.0, -0.0, -0.0, +0.0, +0.0, +0.0);
9460 FmaddFmsubHelper(+0.0, +0.0, -0.0, +0.0, -0.0, +0.0, +0.0);
9461 FmaddFmsubHelper(+0.0, +0.0, +0.0, +0.0, +0.0, -0.0, +0.0);
9462 FmaddFmsubHelper(-0.0, +0.0, +0.0, +0.0, +0.0, +0.0, -0.0);
9463 FmaddFmsubHelper(+0.0, -0.0, -0.0, -0.0, +0.0, +0.0, +0.0);
9464 FmaddFmsubHelper(-0.0, -0.0, -0.0, +0.0, -0.0, +0.0, +0.0);
9465 FmaddFmsubHelper(-0.0, -0.0, +0.0, +0.0, +0.0, -0.0, +0.0);
9466 FmaddFmsubHelper(+0.0, -0.0, +0.0, +0.0, +0.0, +0.0, -0.0);
9467
9468 // Check NaN generation.
9469 FmaddFmsubHelper(kFP64PositiveInfinity, 0.0, 42.0,
9470 kFP64DefaultNaN, kFP64DefaultNaN,
9471 kFP64DefaultNaN, kFP64DefaultNaN);
9472 FmaddFmsubHelper(0.0, kFP64PositiveInfinity, 42.0,
9473 kFP64DefaultNaN, kFP64DefaultNaN,
9474 kFP64DefaultNaN, kFP64DefaultNaN);
9475 FmaddFmsubHelper(kFP64PositiveInfinity, 1.0, kFP64PositiveInfinity,
9476 kFP64PositiveInfinity, // inf + ( inf * 1) = inf
9477 kFP64DefaultNaN, // inf + (-inf * 1) = NaN
9478 kFP64NegativeInfinity, // -inf + (-inf * 1) = -inf
9479 kFP64DefaultNaN); // -inf + ( inf * 1) = NaN
9480 FmaddFmsubHelper(kFP64NegativeInfinity, 1.0, kFP64PositiveInfinity,
9481 kFP64DefaultNaN, // inf + (-inf * 1) = NaN
9482 kFP64PositiveInfinity, // inf + ( inf * 1) = inf
9483 kFP64DefaultNaN, // -inf + ( inf * 1) = NaN
9484 kFP64NegativeInfinity); // -inf + (-inf * 1) = -inf
armvixlf37fdc02014-02-05 13:22:16 +00009485}
9486
9487
armvixlb0c8ae22014-03-21 14:03:59 +00009488static void FmaddFmsubHelper(float n, float m, float a,
9489 float fmadd, float fmsub,
9490 float fnmadd, float fnmsub) {
armvixlf37fdc02014-02-05 13:22:16 +00009491 SETUP();
9492 START();
9493
9494 __ Fmov(s0, n);
9495 __ Fmov(s1, m);
9496 __ Fmov(s2, a);
armvixlb0c8ae22014-03-21 14:03:59 +00009497 __ Fmadd(s28, s0, s1, s2);
9498 __ Fmsub(s29, s0, s1, s2);
9499 __ Fnmadd(s30, s0, s1, s2);
9500 __ Fnmsub(s31, s0, s1, s2);
armvixlf37fdc02014-02-05 13:22:16 +00009501
9502 END();
9503 RUN();
9504
armvixlb0c8ae22014-03-21 14:03:59 +00009505 ASSERT_EQUAL_FP32(fmadd, s28);
9506 ASSERT_EQUAL_FP32(fmsub, s29);
9507 ASSERT_EQUAL_FP32(fnmadd, s30);
9508 ASSERT_EQUAL_FP32(fnmsub, s31);
armvixlf37fdc02014-02-05 13:22:16 +00009509
9510 TEARDOWN();
9511}
9512
9513
9514TEST(fmadd_fmsub_float) {
armvixlb0c8ae22014-03-21 14:03:59 +00009515 // It's hard to check the result of fused operations because the only way to
9516 // calculate the result is using fma, which is what the simulator uses anyway.
armvixlf37fdc02014-02-05 13:22:16 +00009517
armvixlb0c8ae22014-03-21 14:03:59 +00009518 // Basic operation.
9519 FmaddFmsubHelper(1.0f, 2.0f, 3.0f, 5.0f, 1.0f, -5.0f, -1.0f);
9520 FmaddFmsubHelper(-1.0f, 2.0f, 3.0f, 1.0f, 5.0f, -1.0f, -5.0f);
armvixlf37fdc02014-02-05 13:22:16 +00009521
armvixlb0c8ae22014-03-21 14:03:59 +00009522 // Check the sign of exact zeroes.
9523 // n m a fmadd fmsub fnmadd fnmsub
9524 FmaddFmsubHelper(-0.0f, +0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
9525 FmaddFmsubHelper(+0.0f, +0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
9526 FmaddFmsubHelper(+0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
9527 FmaddFmsubHelper(-0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
9528 FmaddFmsubHelper(+0.0f, -0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
9529 FmaddFmsubHelper(-0.0f, -0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
9530 FmaddFmsubHelper(-0.0f, -0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
9531 FmaddFmsubHelper(+0.0f, -0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
9532
9533 // Check NaN generation.
9534 FmaddFmsubHelper(kFP32PositiveInfinity, 0.0f, 42.0f,
9535 kFP32DefaultNaN, kFP32DefaultNaN,
9536 kFP32DefaultNaN, kFP32DefaultNaN);
9537 FmaddFmsubHelper(0.0f, kFP32PositiveInfinity, 42.0f,
9538 kFP32DefaultNaN, kFP32DefaultNaN,
9539 kFP32DefaultNaN, kFP32DefaultNaN);
9540 FmaddFmsubHelper(kFP32PositiveInfinity, 1.0f, kFP32PositiveInfinity,
9541 kFP32PositiveInfinity, // inf + ( inf * 1) = inf
9542 kFP32DefaultNaN, // inf + (-inf * 1) = NaN
9543 kFP32NegativeInfinity, // -inf + (-inf * 1) = -inf
9544 kFP32DefaultNaN); // -inf + ( inf * 1) = NaN
9545 FmaddFmsubHelper(kFP32NegativeInfinity, 1.0f, kFP32PositiveInfinity,
9546 kFP32DefaultNaN, // inf + (-inf * 1) = NaN
9547 kFP32PositiveInfinity, // inf + ( inf * 1) = inf
9548 kFP32DefaultNaN, // -inf + ( inf * 1) = NaN
9549 kFP32NegativeInfinity); // -inf + (-inf * 1) = -inf
armvixlf37fdc02014-02-05 13:22:16 +00009550}
9551
9552
armvixlb0c8ae22014-03-21 14:03:59 +00009553TEST(fmadd_fmsub_double_nans) {
9554 // Make sure that NaN propagation works correctly.
9555 double s1 = rawbits_to_double(0x7ff5555511111111);
9556 double s2 = rawbits_to_double(0x7ff5555522222222);
9557 double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
9558 double q1 = rawbits_to_double(0x7ffaaaaa11111111);
9559 double q2 = rawbits_to_double(0x7ffaaaaa22222222);
9560 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
9561 VIXL_ASSERT(IsSignallingNaN(s1));
9562 VIXL_ASSERT(IsSignallingNaN(s2));
9563 VIXL_ASSERT(IsSignallingNaN(sa));
9564 VIXL_ASSERT(IsQuietNaN(q1));
9565 VIXL_ASSERT(IsQuietNaN(q2));
9566 VIXL_ASSERT(IsQuietNaN(qa));
armvixlf37fdc02014-02-05 13:22:16 +00009567
armvixlb0c8ae22014-03-21 14:03:59 +00009568 // The input NaNs after passing through ProcessNaN.
9569 double s1_proc = rawbits_to_double(0x7ffd555511111111);
9570 double s2_proc = rawbits_to_double(0x7ffd555522222222);
9571 double sa_proc = rawbits_to_double(0x7ffd5555aaaaaaaa);
9572 double q1_proc = q1;
9573 double q2_proc = q2;
9574 double qa_proc = qa;
9575 VIXL_ASSERT(IsQuietNaN(s1_proc));
9576 VIXL_ASSERT(IsQuietNaN(s2_proc));
9577 VIXL_ASSERT(IsQuietNaN(sa_proc));
9578 VIXL_ASSERT(IsQuietNaN(q1_proc));
9579 VIXL_ASSERT(IsQuietNaN(q2_proc));
9580 VIXL_ASSERT(IsQuietNaN(qa_proc));
armvixlf37fdc02014-02-05 13:22:16 +00009581
armvixl5799d6c2014-05-01 11:05:00 +01009582 // Negated NaNs as it would be done on ARMv8 hardware.
9583 double s1_proc_neg = rawbits_to_double(0xfffd555511111111);
9584 double sa_proc_neg = rawbits_to_double(0xfffd5555aaaaaaaa);
9585 double q1_proc_neg = rawbits_to_double(0xfffaaaaa11111111);
9586 double qa_proc_neg = rawbits_to_double(0xfffaaaaaaaaaaaaa);
9587 VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
9588 VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
9589 VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
9590 VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
9591
armvixlb0c8ae22014-03-21 14:03:59 +00009592 // Quiet NaNs are propagated.
armvixl5799d6c2014-05-01 11:05:00 +01009593 FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009594 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009595 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9596 FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
9597 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9598 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9599 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00009600
armvixlb0c8ae22014-03-21 14:03:59 +00009601 // Signalling NaNs are propagated, and made quiet.
armvixl5799d6c2014-05-01 11:05:00 +01009602 FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009603 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009604 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9605 FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9606 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9607 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9608 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00009609
armvixlb0c8ae22014-03-21 14:03:59 +00009610 // Signalling NaNs take precedence over quiet NaNs.
armvixl5799d6c2014-05-01 11:05:00 +01009611 FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009612 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009613 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9614 FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9615 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9616 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9617 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00009618
armvixlb0c8ae22014-03-21 14:03:59 +00009619 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
9620 FmaddFmsubHelper(0, kFP64PositiveInfinity, qa,
9621 kFP64DefaultNaN, kFP64DefaultNaN,
9622 kFP64DefaultNaN, kFP64DefaultNaN);
9623 FmaddFmsubHelper(kFP64PositiveInfinity, 0, qa,
9624 kFP64DefaultNaN, kFP64DefaultNaN,
9625 kFP64DefaultNaN, kFP64DefaultNaN);
9626 FmaddFmsubHelper(0, kFP64NegativeInfinity, qa,
9627 kFP64DefaultNaN, kFP64DefaultNaN,
9628 kFP64DefaultNaN, kFP64DefaultNaN);
9629 FmaddFmsubHelper(kFP64NegativeInfinity, 0, qa,
9630 kFP64DefaultNaN, kFP64DefaultNaN,
9631 kFP64DefaultNaN, kFP64DefaultNaN);
9632}
armvixlf37fdc02014-02-05 13:22:16 +00009633
armvixlf37fdc02014-02-05 13:22:16 +00009634
armvixlb0c8ae22014-03-21 14:03:59 +00009635TEST(fmadd_fmsub_float_nans) {
9636 // Make sure that NaN propagation works correctly.
9637 float s1 = rawbits_to_float(0x7f951111);
9638 float s2 = rawbits_to_float(0x7f952222);
9639 float sa = rawbits_to_float(0x7f95aaaa);
9640 float q1 = rawbits_to_float(0x7fea1111);
9641 float q2 = rawbits_to_float(0x7fea2222);
9642 float qa = rawbits_to_float(0x7feaaaaa);
9643 VIXL_ASSERT(IsSignallingNaN(s1));
9644 VIXL_ASSERT(IsSignallingNaN(s2));
9645 VIXL_ASSERT(IsSignallingNaN(sa));
9646 VIXL_ASSERT(IsQuietNaN(q1));
9647 VIXL_ASSERT(IsQuietNaN(q2));
9648 VIXL_ASSERT(IsQuietNaN(qa));
armvixlf37fdc02014-02-05 13:22:16 +00009649
armvixlb0c8ae22014-03-21 14:03:59 +00009650 // The input NaNs after passing through ProcessNaN.
9651 float s1_proc = rawbits_to_float(0x7fd51111);
9652 float s2_proc = rawbits_to_float(0x7fd52222);
9653 float sa_proc = rawbits_to_float(0x7fd5aaaa);
9654 float q1_proc = q1;
9655 float q2_proc = q2;
9656 float qa_proc = qa;
9657 VIXL_ASSERT(IsQuietNaN(s1_proc));
9658 VIXL_ASSERT(IsQuietNaN(s2_proc));
9659 VIXL_ASSERT(IsQuietNaN(sa_proc));
9660 VIXL_ASSERT(IsQuietNaN(q1_proc));
9661 VIXL_ASSERT(IsQuietNaN(q2_proc));
9662 VIXL_ASSERT(IsQuietNaN(qa_proc));
9663
armvixl5799d6c2014-05-01 11:05:00 +01009664 // Negated NaNs as it would be done on ARMv8 hardware.
9665 float s1_proc_neg = rawbits_to_float(0xffd51111);
9666 float sa_proc_neg = rawbits_to_float(0xffd5aaaa);
9667 float q1_proc_neg = rawbits_to_float(0xffea1111);
9668 float qa_proc_neg = rawbits_to_float(0xffeaaaaa);
9669 VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
9670 VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
9671 VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
9672 VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
9673
armvixlb0c8ae22014-03-21 14:03:59 +00009674 // Quiet NaNs are propagated.
armvixl5799d6c2014-05-01 11:05:00 +01009675 FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009676 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009677 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9678 FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
9679 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9680 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
9681 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00009682
9683 // Signalling NaNs are propagated, and made quiet.
armvixl5799d6c2014-05-01 11:05:00 +01009684 FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009685 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009686 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9687 FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9688 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9689 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9690 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00009691
9692 // Signalling NaNs take precedence over quiet NaNs.
armvixl5799d6c2014-05-01 11:05:00 +01009693 FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00009694 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01009695 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9696 FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
9697 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9698 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
9699 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00009700
9701 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
9702 FmaddFmsubHelper(0, kFP32PositiveInfinity, qa,
9703 kFP32DefaultNaN, kFP32DefaultNaN,
9704 kFP32DefaultNaN, kFP32DefaultNaN);
9705 FmaddFmsubHelper(kFP32PositiveInfinity, 0, qa,
9706 kFP32DefaultNaN, kFP32DefaultNaN,
9707 kFP32DefaultNaN, kFP32DefaultNaN);
9708 FmaddFmsubHelper(0, kFP32NegativeInfinity, qa,
9709 kFP32DefaultNaN, kFP32DefaultNaN,
9710 kFP32DefaultNaN, kFP32DefaultNaN);
9711 FmaddFmsubHelper(kFP32NegativeInfinity, 0, qa,
9712 kFP32DefaultNaN, kFP32DefaultNaN,
9713 kFP32DefaultNaN, kFP32DefaultNaN);
armvixlf37fdc02014-02-05 13:22:16 +00009714}
9715
9716
armvixlad96eda2013-06-14 11:42:37 +01009717TEST(fdiv) {
9718 SETUP();
9719
9720 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009721 __ Fmov(s14, -0.0f);
9722 __ Fmov(s15, kFP32PositiveInfinity);
9723 __ Fmov(s16, kFP32NegativeInfinity);
9724 __ Fmov(s17, 3.25f);
9725 __ Fmov(s18, 2.0f);
9726 __ Fmov(s19, 2.0f);
9727 __ Fmov(s20, -2.0f);
armvixlad96eda2013-06-14 11:42:37 +01009728
9729 __ Fmov(d26, -0.0);
9730 __ Fmov(d27, kFP64PositiveInfinity);
9731 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009732 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01009733 __ Fmov(d30, -2.0);
9734 __ Fmov(d31, 2.25);
9735
armvixlb0c8ae22014-03-21 14:03:59 +00009736 __ Fdiv(s0, s17, s18);
9737 __ Fdiv(s1, s18, s19);
9738 __ Fdiv(s2, s14, s18);
9739 __ Fdiv(s3, s18, s15);
9740 __ Fdiv(s4, s18, s16);
9741 __ Fdiv(s5, s15, s16);
9742 __ Fdiv(s6, s14, s14);
9743
9744 __ Fdiv(d7, d31, d30);
9745 __ Fdiv(d8, d29, d31);
9746 __ Fdiv(d9, d26, d31);
9747 __ Fdiv(d10, d31, d27);
9748 __ Fdiv(d11, d31, d28);
9749 __ Fdiv(d12, d28, d27);
9750 __ Fdiv(d13, d29, d29);
armvixlad96eda2013-06-14 11:42:37 +01009751 END();
9752
9753 RUN();
9754
armvixlb0c8ae22014-03-21 14:03:59 +00009755 ASSERT_EQUAL_FP32(1.625f, s0);
9756 ASSERT_EQUAL_FP32(1.0f, s1);
9757 ASSERT_EQUAL_FP32(-0.0f, s2);
9758 ASSERT_EQUAL_FP32(0.0f, s3);
9759 ASSERT_EQUAL_FP32(-0.0f, s4);
9760 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
9761 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
9762 ASSERT_EQUAL_FP64(-1.125, d7);
armvixlad96eda2013-06-14 11:42:37 +01009763 ASSERT_EQUAL_FP64(0.0, d8);
9764 ASSERT_EQUAL_FP64(-0.0, d9);
armvixlb0c8ae22014-03-21 14:03:59 +00009765 ASSERT_EQUAL_FP64(0.0, d10);
9766 ASSERT_EQUAL_FP64(-0.0, d11);
9767 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
9768 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01009769
9770 TEARDOWN();
9771}
9772
9773
armvixlf37fdc02014-02-05 13:22:16 +00009774static float MinMaxHelper(float n,
9775 float m,
9776 bool min,
9777 float quiet_nan_substitute = 0.0) {
armvixlb0c8ae22014-03-21 14:03:59 +00009778 const uint64_t kFP32QuietNaNMask = 0x00400000;
armvixlf37fdc02014-02-05 13:22:16 +00009779 uint32_t raw_n = float_to_rawbits(n);
9780 uint32_t raw_m = float_to_rawbits(m);
armvixlad96eda2013-06-14 11:42:37 +01009781
armvixl6e2c8272015-03-31 11:04:14 +01009782 if (std::isnan(n) && ((raw_n & kFP32QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009783 // n is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009784 return rawbits_to_float(raw_n | kFP32QuietNaNMask);
armvixl6e2c8272015-03-31 11:04:14 +01009785 } else if (std::isnan(m) && ((raw_m & kFP32QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009786 // m is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009787 return rawbits_to_float(raw_m | kFP32QuietNaNMask);
armvixlf37fdc02014-02-05 13:22:16 +00009788 } else if (quiet_nan_substitute == 0.0) {
armvixl6e2c8272015-03-31 11:04:14 +01009789 if (std::isnan(n)) {
armvixlf37fdc02014-02-05 13:22:16 +00009790 // n is quiet NaN.
9791 return n;
armvixl6e2c8272015-03-31 11:04:14 +01009792 } else if (std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009793 // m is quiet NaN.
9794 return m;
9795 }
9796 } else {
9797 // Substitute n or m if one is quiet, but not both.
armvixl6e2c8272015-03-31 11:04:14 +01009798 if (std::isnan(n) && !std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009799 // n is quiet NaN: replace with substitute.
9800 n = quiet_nan_substitute;
armvixl6e2c8272015-03-31 11:04:14 +01009801 } else if (!std::isnan(n) && std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009802 // m is quiet NaN: replace with substitute.
9803 m = quiet_nan_substitute;
armvixlad96eda2013-06-14 11:42:37 +01009804 }
9805 }
armvixlad96eda2013-06-14 11:42:37 +01009806
armvixlf37fdc02014-02-05 13:22:16 +00009807 if ((n == 0.0) && (m == 0.0) &&
9808 (copysign(1.0, n) != copysign(1.0, m))) {
9809 return min ? -0.0 : 0.0;
9810 }
armvixlad96eda2013-06-14 11:42:37 +01009811
armvixlf37fdc02014-02-05 13:22:16 +00009812 return min ? fminf(n, m) : fmaxf(n, m);
armvixlad96eda2013-06-14 11:42:37 +01009813}
9814
9815
armvixlf37fdc02014-02-05 13:22:16 +00009816static double MinMaxHelper(double n,
9817 double m,
9818 bool min,
9819 double quiet_nan_substitute = 0.0) {
armvixlb0c8ae22014-03-21 14:03:59 +00009820 const uint64_t kFP64QuietNaNMask = 0x0008000000000000;
armvixlf37fdc02014-02-05 13:22:16 +00009821 uint64_t raw_n = double_to_rawbits(n);
9822 uint64_t raw_m = double_to_rawbits(m);
armvixlad96eda2013-06-14 11:42:37 +01009823
armvixl6e2c8272015-03-31 11:04:14 +01009824 if (std::isnan(n) && ((raw_n & kFP64QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009825 // n is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009826 return rawbits_to_double(raw_n | kFP64QuietNaNMask);
armvixl6e2c8272015-03-31 11:04:14 +01009827 } else if (std::isnan(m) && ((raw_m & kFP64QuietNaNMask) == 0)) {
armvixlf37fdc02014-02-05 13:22:16 +00009828 // m is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00009829 return rawbits_to_double(raw_m | kFP64QuietNaNMask);
armvixlf37fdc02014-02-05 13:22:16 +00009830 } else if (quiet_nan_substitute == 0.0) {
armvixl6e2c8272015-03-31 11:04:14 +01009831 if (std::isnan(n)) {
armvixlf37fdc02014-02-05 13:22:16 +00009832 // n is quiet NaN.
9833 return n;
armvixl6e2c8272015-03-31 11:04:14 +01009834 } else if (std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009835 // m is quiet NaN.
9836 return m;
9837 }
9838 } else {
9839 // Substitute n or m if one is quiet, but not both.
armvixl6e2c8272015-03-31 11:04:14 +01009840 if (std::isnan(n) && !std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009841 // n is quiet NaN: replace with substitute.
9842 n = quiet_nan_substitute;
armvixl6e2c8272015-03-31 11:04:14 +01009843 } else if (!std::isnan(n) && std::isnan(m)) {
armvixlf37fdc02014-02-05 13:22:16 +00009844 // m is quiet NaN: replace with substitute.
9845 m = quiet_nan_substitute;
armvixlad96eda2013-06-14 11:42:37 +01009846 }
9847 }
armvixlf37fdc02014-02-05 13:22:16 +00009848
9849 if ((n == 0.0) && (m == 0.0) &&
9850 (copysign(1.0, n) != copysign(1.0, m))) {
9851 return min ? -0.0 : 0.0;
9852 }
9853
9854 return min ? fmin(n, m) : fmax(n, m);
9855}
9856
9857
9858static void FminFmaxDoubleHelper(double n, double m, double min, double max,
9859 double minnm, double maxnm) {
9860 SETUP();
9861
9862 START();
9863 __ Fmov(d0, n);
9864 __ Fmov(d1, m);
9865 __ Fmin(d28, d0, d1);
9866 __ Fmax(d29, d0, d1);
9867 __ Fminnm(d30, d0, d1);
9868 __ Fmaxnm(d31, d0, d1);
armvixlad96eda2013-06-14 11:42:37 +01009869 END();
9870
9871 RUN();
9872
armvixlf37fdc02014-02-05 13:22:16 +00009873 ASSERT_EQUAL_FP64(min, d28);
9874 ASSERT_EQUAL_FP64(max, d29);
9875 ASSERT_EQUAL_FP64(minnm, d30);
9876 ASSERT_EQUAL_FP64(maxnm, d31);
armvixlad96eda2013-06-14 11:42:37 +01009877
9878 TEARDOWN();
9879}
9880
9881
armvixlf37fdc02014-02-05 13:22:16 +00009882TEST(fmax_fmin_d) {
armvixlb0c8ae22014-03-21 14:03:59 +00009883 // Use non-standard NaNs to check that the payload bits are preserved.
9884 double snan = rawbits_to_double(0x7ff5555512345678);
9885 double qnan = rawbits_to_double(0x7ffaaaaa87654321);
9886
9887 double snan_processed = rawbits_to_double(0x7ffd555512345678);
9888 double qnan_processed = qnan;
9889
9890 VIXL_ASSERT(IsSignallingNaN(snan));
9891 VIXL_ASSERT(IsQuietNaN(qnan));
9892 VIXL_ASSERT(IsQuietNaN(snan_processed));
9893 VIXL_ASSERT(IsQuietNaN(qnan_processed));
9894
armvixlf37fdc02014-02-05 13:22:16 +00009895 // Bootstrap tests.
9896 FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0);
9897 FminFmaxDoubleHelper(0, 1, 0, 1, 0, 1);
9898 FminFmaxDoubleHelper(kFP64PositiveInfinity, kFP64NegativeInfinity,
9899 kFP64NegativeInfinity, kFP64PositiveInfinity,
9900 kFP64NegativeInfinity, kFP64PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009901 FminFmaxDoubleHelper(snan, 0,
9902 snan_processed, snan_processed,
9903 snan_processed, snan_processed);
9904 FminFmaxDoubleHelper(0, snan,
9905 snan_processed, snan_processed,
9906 snan_processed, snan_processed);
9907 FminFmaxDoubleHelper(qnan, 0,
9908 qnan_processed, qnan_processed,
armvixlf37fdc02014-02-05 13:22:16 +00009909 0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00009910 FminFmaxDoubleHelper(0, qnan,
9911 qnan_processed, qnan_processed,
9912 0, 0);
9913 FminFmaxDoubleHelper(qnan, snan,
9914 snan_processed, snan_processed,
9915 snan_processed, snan_processed);
9916 FminFmaxDoubleHelper(snan, qnan,
9917 snan_processed, snan_processed,
9918 snan_processed, snan_processed);
armvixlf37fdc02014-02-05 13:22:16 +00009919
9920 // Iterate over all combinations of inputs.
9921 double inputs[] = { DBL_MAX, DBL_MIN, 1.0, 0.0,
9922 -DBL_MAX, -DBL_MIN, -1.0, -0.0,
9923 kFP64PositiveInfinity, kFP64NegativeInfinity,
9924 kFP64QuietNaN, kFP64SignallingNaN };
9925
9926 const int count = sizeof(inputs) / sizeof(inputs[0]);
9927
9928 for (int in = 0; in < count; in++) {
9929 double n = inputs[in];
9930 for (int im = 0; im < count; im++) {
9931 double m = inputs[im];
9932 FminFmaxDoubleHelper(n, m,
9933 MinMaxHelper(n, m, true),
9934 MinMaxHelper(n, m, false),
9935 MinMaxHelper(n, m, true, kFP64PositiveInfinity),
9936 MinMaxHelper(n, m, false, kFP64NegativeInfinity));
9937 }
9938 }
9939}
9940
9941
9942static void FminFmaxFloatHelper(float n, float m, float min, float max,
9943 float minnm, float maxnm) {
9944 SETUP();
9945
9946 START();
armvixlb0c8ae22014-03-21 14:03:59 +00009947 __ Fmov(s0, n);
9948 __ Fmov(s1, m);
armvixlf37fdc02014-02-05 13:22:16 +00009949 __ Fmin(s28, s0, s1);
9950 __ Fmax(s29, s0, s1);
9951 __ Fminnm(s30, s0, s1);
9952 __ Fmaxnm(s31, s0, s1);
9953 END();
9954
9955 RUN();
9956
9957 ASSERT_EQUAL_FP32(min, s28);
9958 ASSERT_EQUAL_FP32(max, s29);
9959 ASSERT_EQUAL_FP32(minnm, s30);
9960 ASSERT_EQUAL_FP32(maxnm, s31);
9961
9962 TEARDOWN();
9963}
9964
9965
9966TEST(fmax_fmin_s) {
armvixlb0c8ae22014-03-21 14:03:59 +00009967 // Use non-standard NaNs to check that the payload bits are preserved.
9968 float snan = rawbits_to_float(0x7f951234);
9969 float qnan = rawbits_to_float(0x7fea8765);
9970
9971 float snan_processed = rawbits_to_float(0x7fd51234);
9972 float qnan_processed = qnan;
9973
9974 VIXL_ASSERT(IsSignallingNaN(snan));
9975 VIXL_ASSERT(IsQuietNaN(qnan));
9976 VIXL_ASSERT(IsQuietNaN(snan_processed));
9977 VIXL_ASSERT(IsQuietNaN(qnan_processed));
9978
armvixlf37fdc02014-02-05 13:22:16 +00009979 // Bootstrap tests.
9980 FminFmaxFloatHelper(0, 0, 0, 0, 0, 0);
9981 FminFmaxFloatHelper(0, 1, 0, 1, 0, 1);
9982 FminFmaxFloatHelper(kFP32PositiveInfinity, kFP32NegativeInfinity,
9983 kFP32NegativeInfinity, kFP32PositiveInfinity,
9984 kFP32NegativeInfinity, kFP32PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00009985 FminFmaxFloatHelper(snan, 0,
9986 snan_processed, snan_processed,
9987 snan_processed, snan_processed);
9988 FminFmaxFloatHelper(0, snan,
9989 snan_processed, snan_processed,
9990 snan_processed, snan_processed);
9991 FminFmaxFloatHelper(qnan, 0,
9992 qnan_processed, qnan_processed,
armvixlf37fdc02014-02-05 13:22:16 +00009993 0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00009994 FminFmaxFloatHelper(0, qnan,
9995 qnan_processed, qnan_processed,
9996 0, 0);
9997 FminFmaxFloatHelper(qnan, snan,
9998 snan_processed, snan_processed,
9999 snan_processed, snan_processed);
10000 FminFmaxFloatHelper(snan, qnan,
10001 snan_processed, snan_processed,
10002 snan_processed, snan_processed);
armvixlf37fdc02014-02-05 13:22:16 +000010003
10004 // Iterate over all combinations of inputs.
10005 float inputs[] = { FLT_MAX, FLT_MIN, 1.0, 0.0,
10006 -FLT_MAX, -FLT_MIN, -1.0, -0.0,
10007 kFP32PositiveInfinity, kFP32NegativeInfinity,
10008 kFP32QuietNaN, kFP32SignallingNaN };
10009
10010 const int count = sizeof(inputs) / sizeof(inputs[0]);
10011
10012 for (int in = 0; in < count; in++) {
10013 float n = inputs[in];
10014 for (int im = 0; im < count; im++) {
10015 float m = inputs[im];
10016 FminFmaxFloatHelper(n, m,
10017 MinMaxHelper(n, m, true),
10018 MinMaxHelper(n, m, false),
10019 MinMaxHelper(n, m, true, kFP32PositiveInfinity),
10020 MinMaxHelper(n, m, false, kFP32NegativeInfinity));
10021 }
10022 }
10023}
10024
10025
armvixlad96eda2013-06-14 11:42:37 +010010026TEST(fccmp) {
10027 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010010028 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +010010029
10030 START();
10031 __ Fmov(s16, 0.0);
10032 __ Fmov(s17, 0.5);
10033 __ Fmov(d18, -0.5);
10034 __ Fmov(d19, -1.0);
10035 __ Mov(x20, 0);
armvixl6e2c8272015-03-31 11:04:14 +010010036 __ Mov(x21, 0x7ff0000000000001); // Double precision NaN.
10037 __ Fmov(d21, x21);
10038 __ Mov(w22, 0x7f800001); // Single precision NaN.
10039 __ Fmov(s22, w22);
armvixlad96eda2013-06-14 11:42:37 +010010040
armvixl578645f2013-08-15 17:21:42 +010010041 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +010010042 __ Fccmp(s16, s16, NoFlag, eq);
10043 __ Mrs(x0, NZCV);
10044
armvixl578645f2013-08-15 17:21:42 +010010045 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +010010046 __ Fccmp(s16, s16, VFlag, ne);
10047 __ Mrs(x1, NZCV);
10048
armvixl578645f2013-08-15 17:21:42 +010010049 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +010010050 __ Fccmp(s16, s17, CFlag, ge);
10051 __ Mrs(x2, NZCV);
10052
armvixl578645f2013-08-15 17:21:42 +010010053 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +010010054 __ Fccmp(s16, s17, CVFlag, lt);
10055 __ Mrs(x3, NZCV);
10056
armvixl578645f2013-08-15 17:21:42 +010010057 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +010010058 __ Fccmp(d18, d18, ZFlag, le);
10059 __ Mrs(x4, NZCV);
10060
armvixl578645f2013-08-15 17:21:42 +010010061 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +010010062 __ Fccmp(d18, d18, ZVFlag, gt);
10063 __ Mrs(x5, NZCV);
10064
armvixl578645f2013-08-15 17:21:42 +010010065 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +010010066 __ Fccmp(d18, d19, ZCVFlag, ls);
10067 __ Mrs(x6, NZCV);
10068
armvixl578645f2013-08-15 17:21:42 +010010069 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +010010070 __ Fccmp(d18, d19, NFlag, hi);
10071 __ Mrs(x7, NZCV);
armvixl578645f2013-08-15 17:21:42 +010010072
armvixlc68cb642014-09-25 18:49:30 +010010073 // The Macro Assembler does not allow al or nv as condition.
armvixl578645f2013-08-15 17:21:42 +010010074 __ fccmp(s16, s16, NFlag, al);
10075 __ Mrs(x8, NZCV);
10076
10077 __ fccmp(d18, d18, NFlag, nv);
10078 __ Mrs(x9, NZCV);
armvixl6e2c8272015-03-31 11:04:14 +010010079
10080 __ Cmp(x20, 0);
10081 __ Fccmpe(s16, s16, NoFlag, eq);
10082 __ Mrs(x10, NZCV);
10083
10084 __ Cmp(x20, 0);
10085 __ Fccmpe(d18, d19, ZCVFlag, ls);
10086 __ Mrs(x11, NZCV);
10087
10088 __ Cmp(x20, 0);
10089 __ Fccmpe(d21, d21, NoFlag, eq);
10090 __ Mrs(x12, NZCV);
10091
10092 __ Cmp(x20, 0);
10093 __ Fccmpe(s22, s22, NoFlag, eq);
10094 __ Mrs(x13, NZCV);
armvixlad96eda2013-06-14 11:42:37 +010010095 END();
10096
10097 RUN();
10098
10099 ASSERT_EQUAL_32(ZCFlag, w0);
10100 ASSERT_EQUAL_32(VFlag, w1);
10101 ASSERT_EQUAL_32(NFlag, w2);
10102 ASSERT_EQUAL_32(CVFlag, w3);
10103 ASSERT_EQUAL_32(ZCFlag, w4);
10104 ASSERT_EQUAL_32(ZVFlag, w5);
10105 ASSERT_EQUAL_32(CFlag, w6);
10106 ASSERT_EQUAL_32(NFlag, w7);
armvixl578645f2013-08-15 17:21:42 +010010107 ASSERT_EQUAL_32(ZCFlag, w8);
10108 ASSERT_EQUAL_32(ZCFlag, w9);
armvixl6e2c8272015-03-31 11:04:14 +010010109 ASSERT_EQUAL_32(ZCFlag, w10);
10110 ASSERT_EQUAL_32(CFlag, w11);
10111 ASSERT_EQUAL_32(CVFlag, w12);
10112 ASSERT_EQUAL_32(CVFlag, w13);
armvixlad96eda2013-06-14 11:42:37 +010010113
10114 TEARDOWN();
10115}
10116
10117
10118TEST(fcmp) {
10119 SETUP();
10120
10121 START();
armvixlf37fdc02014-02-05 13:22:16 +000010122
10123 // Some of these tests require a floating-point scratch register assigned to
10124 // the macro assembler, but most do not.
armvixlb0c8ae22014-03-21 14:03:59 +000010125 {
10126 UseScratchRegisterScope temps(&masm);
10127 temps.ExcludeAll();
10128 temps.Include(ip0, ip1);
armvixlf37fdc02014-02-05 13:22:16 +000010129
armvixlb0c8ae22014-03-21 14:03:59 +000010130 __ Fmov(s8, 0.0);
10131 __ Fmov(s9, 0.5);
10132 __ Mov(w18, 0x7f800001); // Single precision NaN.
10133 __ Fmov(s18, w18);
armvixlad96eda2013-06-14 11:42:37 +010010134
armvixlb0c8ae22014-03-21 14:03:59 +000010135 __ Fcmp(s8, s8);
10136 __ Mrs(x0, NZCV);
10137 __ Fcmp(s8, s9);
10138 __ Mrs(x1, NZCV);
10139 __ Fcmp(s9, s8);
10140 __ Mrs(x2, NZCV);
10141 __ Fcmp(s8, s18);
10142 __ Mrs(x3, NZCV);
10143 __ Fcmp(s18, s18);
10144 __ Mrs(x4, NZCV);
10145 __ Fcmp(s8, 0.0);
10146 __ Mrs(x5, NZCV);
10147 temps.Include(d0);
10148 __ Fcmp(s8, 255.0);
10149 temps.Exclude(d0);
10150 __ Mrs(x6, NZCV);
armvixlad96eda2013-06-14 11:42:37 +010010151
armvixlb0c8ae22014-03-21 14:03:59 +000010152 __ Fmov(d19, 0.0);
10153 __ Fmov(d20, 0.5);
10154 __ Mov(x21, 0x7ff0000000000001); // Double precision NaN.
10155 __ Fmov(d21, x21);
armvixlad96eda2013-06-14 11:42:37 +010010156
armvixlb0c8ae22014-03-21 14:03:59 +000010157 __ Fcmp(d19, d19);
10158 __ Mrs(x10, NZCV);
10159 __ Fcmp(d19, d20);
10160 __ Mrs(x11, NZCV);
10161 __ Fcmp(d20, d19);
10162 __ Mrs(x12, NZCV);
10163 __ Fcmp(d19, d21);
10164 __ Mrs(x13, NZCV);
10165 __ Fcmp(d21, d21);
10166 __ Mrs(x14, NZCV);
10167 __ Fcmp(d19, 0.0);
10168 __ Mrs(x15, NZCV);
10169 temps.Include(d0);
10170 __ Fcmp(d19, 12.3456);
10171 temps.Exclude(d0);
10172 __ Mrs(x16, NZCV);
armvixl6e2c8272015-03-31 11:04:14 +010010173
10174 __ Fcmpe(s8, s8);
10175 __ Mrs(x22, NZCV);
10176 __ Fcmpe(s8, 0.0);
10177 __ Mrs(x23, NZCV);
10178 __ Fcmpe(d19, d19);
10179 __ Mrs(x24, NZCV);
10180 __ Fcmpe(d19, 0.0);
10181 __ Mrs(x25, NZCV);
10182 __ Fcmpe(s18, s18);
10183 __ Mrs(x26, NZCV);
10184 __ Fcmpe(d21, d21);
10185 __ Mrs(x27, NZCV);
armvixlb0c8ae22014-03-21 14:03:59 +000010186 }
10187
armvixlad96eda2013-06-14 11:42:37 +010010188 END();
10189
10190 RUN();
10191
10192 ASSERT_EQUAL_32(ZCFlag, w0);
10193 ASSERT_EQUAL_32(NFlag, w1);
10194 ASSERT_EQUAL_32(CFlag, w2);
10195 ASSERT_EQUAL_32(CVFlag, w3);
10196 ASSERT_EQUAL_32(CVFlag, w4);
10197 ASSERT_EQUAL_32(ZCFlag, w5);
10198 ASSERT_EQUAL_32(NFlag, w6);
10199 ASSERT_EQUAL_32(ZCFlag, w10);
10200 ASSERT_EQUAL_32(NFlag, w11);
10201 ASSERT_EQUAL_32(CFlag, w12);
10202 ASSERT_EQUAL_32(CVFlag, w13);
10203 ASSERT_EQUAL_32(CVFlag, w14);
10204 ASSERT_EQUAL_32(ZCFlag, w15);
10205 ASSERT_EQUAL_32(NFlag, w16);
armvixl6e2c8272015-03-31 11:04:14 +010010206 ASSERT_EQUAL_32(ZCFlag, w22);
10207 ASSERT_EQUAL_32(ZCFlag, w23);
10208 ASSERT_EQUAL_32(ZCFlag, w24);
10209 ASSERT_EQUAL_32(ZCFlag, w25);
10210 ASSERT_EQUAL_32(CVFlag, w26);
10211 ASSERT_EQUAL_32(CVFlag, w27);
armvixlad96eda2013-06-14 11:42:37 +010010212
10213 TEARDOWN();
10214}
10215
10216
10217TEST(fcsel) {
10218 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010010219 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +010010220
10221 START();
10222 __ Mov(x16, 0);
10223 __ Fmov(s16, 1.0);
10224 __ Fmov(s17, 2.0);
10225 __ Fmov(d18, 3.0);
10226 __ Fmov(d19, 4.0);
10227
armvixl578645f2013-08-15 17:21:42 +010010228 __ Cmp(x16, 0);
armvixlad96eda2013-06-14 11:42:37 +010010229 __ Fcsel(s0, s16, s17, eq);
10230 __ Fcsel(s1, s16, s17, ne);
10231 __ Fcsel(d2, d18, d19, eq);
10232 __ Fcsel(d3, d18, d19, ne);
armvixlc68cb642014-09-25 18:49:30 +010010233 // The Macro Assembler does not allow al or nv as condition.
armvixl578645f2013-08-15 17:21:42 +010010234 __ fcsel(s4, s16, s17, al);
10235 __ fcsel(d5, d18, d19, nv);
armvixlad96eda2013-06-14 11:42:37 +010010236 END();
10237
10238 RUN();
10239
10240 ASSERT_EQUAL_FP32(1.0, s0);
10241 ASSERT_EQUAL_FP32(2.0, s1);
10242 ASSERT_EQUAL_FP64(3.0, d2);
10243 ASSERT_EQUAL_FP64(4.0, d3);
armvixl578645f2013-08-15 17:21:42 +010010244 ASSERT_EQUAL_FP32(1.0, s4);
10245 ASSERT_EQUAL_FP64(3.0, d5);
armvixlad96eda2013-06-14 11:42:37 +010010246
10247 TEARDOWN();
10248}
10249
10250
10251TEST(fneg) {
10252 SETUP();
10253
10254 START();
10255 __ Fmov(s16, 1.0);
10256 __ Fmov(s17, 0.0);
10257 __ Fmov(s18, kFP32PositiveInfinity);
10258 __ Fmov(d19, 1.0);
10259 __ Fmov(d20, 0.0);
10260 __ Fmov(d21, kFP64PositiveInfinity);
10261
10262 __ Fneg(s0, s16);
10263 __ Fneg(s1, s0);
10264 __ Fneg(s2, s17);
10265 __ Fneg(s3, s2);
10266 __ Fneg(s4, s18);
10267 __ Fneg(s5, s4);
10268 __ Fneg(d6, d19);
10269 __ Fneg(d7, d6);
10270 __ Fneg(d8, d20);
10271 __ Fneg(d9, d8);
10272 __ Fneg(d10, d21);
10273 __ Fneg(d11, d10);
10274 END();
10275
10276 RUN();
10277
10278 ASSERT_EQUAL_FP32(-1.0, s0);
10279 ASSERT_EQUAL_FP32(1.0, s1);
10280 ASSERT_EQUAL_FP32(-0.0, s2);
10281 ASSERT_EQUAL_FP32(0.0, s3);
10282 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
10283 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
10284 ASSERT_EQUAL_FP64(-1.0, d6);
10285 ASSERT_EQUAL_FP64(1.0, d7);
10286 ASSERT_EQUAL_FP64(-0.0, d8);
10287 ASSERT_EQUAL_FP64(0.0, d9);
10288 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
10289 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
10290
10291 TEARDOWN();
10292}
10293
10294
10295TEST(fabs) {
10296 SETUP();
10297
10298 START();
10299 __ Fmov(s16, -1.0);
10300 __ Fmov(s17, -0.0);
10301 __ Fmov(s18, kFP32NegativeInfinity);
10302 __ Fmov(d19, -1.0);
10303 __ Fmov(d20, -0.0);
10304 __ Fmov(d21, kFP64NegativeInfinity);
10305
10306 __ Fabs(s0, s16);
10307 __ Fabs(s1, s0);
10308 __ Fabs(s2, s17);
10309 __ Fabs(s3, s18);
10310 __ Fabs(d4, d19);
10311 __ Fabs(d5, d4);
10312 __ Fabs(d6, d20);
10313 __ Fabs(d7, d21);
10314 END();
10315
10316 RUN();
10317
10318 ASSERT_EQUAL_FP32(1.0, s0);
10319 ASSERT_EQUAL_FP32(1.0, s1);
10320 ASSERT_EQUAL_FP32(0.0, s2);
10321 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
10322 ASSERT_EQUAL_FP64(1.0, d4);
10323 ASSERT_EQUAL_FP64(1.0, d5);
10324 ASSERT_EQUAL_FP64(0.0, d6);
10325 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
10326
10327 TEARDOWN();
10328}
10329
10330
10331TEST(fsqrt) {
10332 SETUP();
10333
10334 START();
10335 __ Fmov(s16, 0.0);
10336 __ Fmov(s17, 1.0);
10337 __ Fmov(s18, 0.25);
10338 __ Fmov(s19, 65536.0);
10339 __ Fmov(s20, -0.0);
10340 __ Fmov(s21, kFP32PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000010341 __ Fmov(s22, -1.0);
10342 __ Fmov(d23, 0.0);
10343 __ Fmov(d24, 1.0);
10344 __ Fmov(d25, 0.25);
10345 __ Fmov(d26, 4294967296.0);
10346 __ Fmov(d27, -0.0);
10347 __ Fmov(d28, kFP64PositiveInfinity);
10348 __ Fmov(d29, -1.0);
armvixlad96eda2013-06-14 11:42:37 +010010349
10350 __ Fsqrt(s0, s16);
10351 __ Fsqrt(s1, s17);
10352 __ Fsqrt(s2, s18);
10353 __ Fsqrt(s3, s19);
10354 __ Fsqrt(s4, s20);
10355 __ Fsqrt(s5, s21);
armvixlb0c8ae22014-03-21 14:03:59 +000010356 __ Fsqrt(s6, s22);
armvixlad96eda2013-06-14 11:42:37 +010010357 __ Fsqrt(d7, d23);
10358 __ Fsqrt(d8, d24);
10359 __ Fsqrt(d9, d25);
10360 __ Fsqrt(d10, d26);
10361 __ Fsqrt(d11, d27);
armvixlb0c8ae22014-03-21 14:03:59 +000010362 __ Fsqrt(d12, d28);
10363 __ Fsqrt(d13, d29);
armvixlad96eda2013-06-14 11:42:37 +010010364 END();
10365
10366 RUN();
10367
10368 ASSERT_EQUAL_FP32(0.0, s0);
10369 ASSERT_EQUAL_FP32(1.0, s1);
10370 ASSERT_EQUAL_FP32(0.5, s2);
10371 ASSERT_EQUAL_FP32(256.0, s3);
10372 ASSERT_EQUAL_FP32(-0.0, s4);
10373 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
armvixlb0c8ae22014-03-21 14:03:59 +000010374 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
10375 ASSERT_EQUAL_FP64(0.0, d7);
10376 ASSERT_EQUAL_FP64(1.0, d8);
10377 ASSERT_EQUAL_FP64(0.5, d9);
10378 ASSERT_EQUAL_FP64(65536.0, d10);
10379 ASSERT_EQUAL_FP64(-0.0, d11);
10380 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d12);
10381 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +010010382
10383 TEARDOWN();
10384}
10385
10386
armvixlf37fdc02014-02-05 13:22:16 +000010387TEST(frinta) {
10388 SETUP();
10389
10390 START();
10391 __ Fmov(s16, 1.0);
10392 __ Fmov(s17, 1.1);
10393 __ Fmov(s18, 1.5);
10394 __ Fmov(s19, 1.9);
10395 __ Fmov(s20, 2.5);
10396 __ Fmov(s21, -1.5);
10397 __ Fmov(s22, -2.5);
10398 __ Fmov(s23, kFP32PositiveInfinity);
10399 __ Fmov(s24, kFP32NegativeInfinity);
10400 __ Fmov(s25, 0.0);
10401 __ Fmov(s26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010402 __ Fmov(s27, -0.2);
armvixlf37fdc02014-02-05 13:22:16 +000010403
10404 __ Frinta(s0, s16);
10405 __ Frinta(s1, s17);
10406 __ Frinta(s2, s18);
10407 __ Frinta(s3, s19);
10408 __ Frinta(s4, s20);
10409 __ Frinta(s5, s21);
10410 __ Frinta(s6, s22);
10411 __ Frinta(s7, s23);
10412 __ Frinta(s8, s24);
10413 __ Frinta(s9, s25);
10414 __ Frinta(s10, s26);
armvixl5799d6c2014-05-01 11:05:00 +010010415 __ Frinta(s11, s27);
armvixlf37fdc02014-02-05 13:22:16 +000010416
10417 __ Fmov(d16, 1.0);
10418 __ Fmov(d17, 1.1);
10419 __ Fmov(d18, 1.5);
10420 __ Fmov(d19, 1.9);
10421 __ Fmov(d20, 2.5);
10422 __ Fmov(d21, -1.5);
10423 __ Fmov(d22, -2.5);
10424 __ Fmov(d23, kFP32PositiveInfinity);
10425 __ Fmov(d24, kFP32NegativeInfinity);
10426 __ Fmov(d25, 0.0);
10427 __ Fmov(d26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010428 __ Fmov(d27, -0.2);
armvixlf37fdc02014-02-05 13:22:16 +000010429
armvixl5799d6c2014-05-01 11:05:00 +010010430 __ Frinta(d12, d16);
10431 __ Frinta(d13, d17);
10432 __ Frinta(d14, d18);
10433 __ Frinta(d15, d19);
10434 __ Frinta(d16, d20);
10435 __ Frinta(d17, d21);
10436 __ Frinta(d18, d22);
10437 __ Frinta(d19, d23);
10438 __ Frinta(d20, d24);
10439 __ Frinta(d21, d25);
10440 __ Frinta(d22, d26);
10441 __ Frinta(d23, d27);
armvixlf37fdc02014-02-05 13:22:16 +000010442 END();
10443
10444 RUN();
10445
10446 ASSERT_EQUAL_FP32(1.0, s0);
10447 ASSERT_EQUAL_FP32(1.0, s1);
10448 ASSERT_EQUAL_FP32(2.0, s2);
10449 ASSERT_EQUAL_FP32(2.0, s3);
10450 ASSERT_EQUAL_FP32(3.0, s4);
10451 ASSERT_EQUAL_FP32(-2.0, s5);
10452 ASSERT_EQUAL_FP32(-3.0, s6);
10453 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10454 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10455 ASSERT_EQUAL_FP32(0.0, s9);
10456 ASSERT_EQUAL_FP32(-0.0, s10);
armvixl5799d6c2014-05-01 11:05:00 +010010457 ASSERT_EQUAL_FP32(-0.0, s11);
armvixlf37fdc02014-02-05 13:22:16 +000010458 ASSERT_EQUAL_FP64(1.0, d12);
armvixl5799d6c2014-05-01 11:05:00 +010010459 ASSERT_EQUAL_FP64(1.0, d13);
armvixlf37fdc02014-02-05 13:22:16 +000010460 ASSERT_EQUAL_FP64(2.0, d14);
armvixl5799d6c2014-05-01 11:05:00 +010010461 ASSERT_EQUAL_FP64(2.0, d15);
10462 ASSERT_EQUAL_FP64(3.0, d16);
10463 ASSERT_EQUAL_FP64(-2.0, d17);
10464 ASSERT_EQUAL_FP64(-3.0, d18);
10465 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10466 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10467 ASSERT_EQUAL_FP64(0.0, d21);
10468 ASSERT_EQUAL_FP64(-0.0, d22);
10469 ASSERT_EQUAL_FP64(-0.0, d23);
10470
10471 TEARDOWN();
10472}
10473
10474
armvixl330dc712014-11-25 10:38:32 +000010475TEST(frinti) {
10476 // VIXL only supports the round-to-nearest FPCR mode, so this test has the
10477 // same results as frintn.
10478 SETUP();
10479
10480 START();
10481 __ Fmov(s16, 1.0);
10482 __ Fmov(s17, 1.1);
10483 __ Fmov(s18, 1.5);
10484 __ Fmov(s19, 1.9);
10485 __ Fmov(s20, 2.5);
10486 __ Fmov(s21, -1.5);
10487 __ Fmov(s22, -2.5);
10488 __ Fmov(s23, kFP32PositiveInfinity);
10489 __ Fmov(s24, kFP32NegativeInfinity);
10490 __ Fmov(s25, 0.0);
10491 __ Fmov(s26, -0.0);
10492 __ Fmov(s27, -0.2);
10493
10494 __ Frinti(s0, s16);
10495 __ Frinti(s1, s17);
10496 __ Frinti(s2, s18);
10497 __ Frinti(s3, s19);
10498 __ Frinti(s4, s20);
10499 __ Frinti(s5, s21);
10500 __ Frinti(s6, s22);
10501 __ Frinti(s7, s23);
10502 __ Frinti(s8, s24);
10503 __ Frinti(s9, s25);
10504 __ Frinti(s10, s26);
10505 __ Frinti(s11, s27);
10506
10507 __ Fmov(d16, 1.0);
10508 __ Fmov(d17, 1.1);
10509 __ Fmov(d18, 1.5);
10510 __ Fmov(d19, 1.9);
10511 __ Fmov(d20, 2.5);
10512 __ Fmov(d21, -1.5);
10513 __ Fmov(d22, -2.5);
10514 __ Fmov(d23, kFP32PositiveInfinity);
10515 __ Fmov(d24, kFP32NegativeInfinity);
10516 __ Fmov(d25, 0.0);
10517 __ Fmov(d26, -0.0);
10518 __ Fmov(d27, -0.2);
10519
10520 __ Frinti(d12, d16);
10521 __ Frinti(d13, d17);
10522 __ Frinti(d14, d18);
10523 __ Frinti(d15, d19);
10524 __ Frinti(d16, d20);
10525 __ Frinti(d17, d21);
10526 __ Frinti(d18, d22);
10527 __ Frinti(d19, d23);
10528 __ Frinti(d20, d24);
10529 __ Frinti(d21, d25);
10530 __ Frinti(d22, d26);
10531 __ Frinti(d23, d27);
10532 END();
10533
10534 RUN();
10535
10536 ASSERT_EQUAL_FP32(1.0, s0);
10537 ASSERT_EQUAL_FP32(1.0, s1);
10538 ASSERT_EQUAL_FP32(2.0, s2);
10539 ASSERT_EQUAL_FP32(2.0, s3);
10540 ASSERT_EQUAL_FP32(2.0, s4);
10541 ASSERT_EQUAL_FP32(-2.0, s5);
10542 ASSERT_EQUAL_FP32(-2.0, s6);
10543 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10544 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10545 ASSERT_EQUAL_FP32(0.0, s9);
10546 ASSERT_EQUAL_FP32(-0.0, s10);
10547 ASSERT_EQUAL_FP32(-0.0, s11);
10548 ASSERT_EQUAL_FP64(1.0, d12);
10549 ASSERT_EQUAL_FP64(1.0, d13);
10550 ASSERT_EQUAL_FP64(2.0, d14);
10551 ASSERT_EQUAL_FP64(2.0, d15);
10552 ASSERT_EQUAL_FP64(2.0, d16);
10553 ASSERT_EQUAL_FP64(-2.0, d17);
10554 ASSERT_EQUAL_FP64(-2.0, d18);
10555 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10556 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10557 ASSERT_EQUAL_FP64(0.0, d21);
10558 ASSERT_EQUAL_FP64(-0.0, d22);
10559 ASSERT_EQUAL_FP64(-0.0, d23);
10560
10561 TEARDOWN();
10562}
10563
10564
armvixl5799d6c2014-05-01 11:05:00 +010010565TEST(frintm) {
10566 SETUP();
10567
10568 START();
10569 __ Fmov(s16, 1.0);
10570 __ Fmov(s17, 1.1);
10571 __ Fmov(s18, 1.5);
10572 __ Fmov(s19, 1.9);
10573 __ Fmov(s20, 2.5);
10574 __ Fmov(s21, -1.5);
10575 __ Fmov(s22, -2.5);
10576 __ Fmov(s23, kFP32PositiveInfinity);
10577 __ Fmov(s24, kFP32NegativeInfinity);
10578 __ Fmov(s25, 0.0);
10579 __ Fmov(s26, -0.0);
10580 __ Fmov(s27, -0.2);
10581
10582 __ Frintm(s0, s16);
10583 __ Frintm(s1, s17);
10584 __ Frintm(s2, s18);
10585 __ Frintm(s3, s19);
10586 __ Frintm(s4, s20);
10587 __ Frintm(s5, s21);
10588 __ Frintm(s6, s22);
10589 __ Frintm(s7, s23);
10590 __ Frintm(s8, s24);
10591 __ Frintm(s9, s25);
10592 __ Frintm(s10, s26);
10593 __ Frintm(s11, s27);
10594
10595 __ Fmov(d16, 1.0);
10596 __ Fmov(d17, 1.1);
10597 __ Fmov(d18, 1.5);
10598 __ Fmov(d19, 1.9);
10599 __ Fmov(d20, 2.5);
10600 __ Fmov(d21, -1.5);
10601 __ Fmov(d22, -2.5);
10602 __ Fmov(d23, kFP32PositiveInfinity);
10603 __ Fmov(d24, kFP32NegativeInfinity);
10604 __ Fmov(d25, 0.0);
10605 __ Fmov(d26, -0.0);
10606 __ Fmov(d27, -0.2);
10607
10608 __ Frintm(d12, d16);
10609 __ Frintm(d13, d17);
10610 __ Frintm(d14, d18);
10611 __ Frintm(d15, d19);
10612 __ Frintm(d16, d20);
10613 __ Frintm(d17, d21);
10614 __ Frintm(d18, d22);
10615 __ Frintm(d19, d23);
10616 __ Frintm(d20, d24);
10617 __ Frintm(d21, d25);
10618 __ Frintm(d22, d26);
10619 __ Frintm(d23, d27);
10620 END();
10621
10622 RUN();
10623
10624 ASSERT_EQUAL_FP32(1.0, s0);
10625 ASSERT_EQUAL_FP32(1.0, s1);
10626 ASSERT_EQUAL_FP32(1.0, s2);
10627 ASSERT_EQUAL_FP32(1.0, s3);
10628 ASSERT_EQUAL_FP32(2.0, s4);
10629 ASSERT_EQUAL_FP32(-2.0, s5);
10630 ASSERT_EQUAL_FP32(-3.0, s6);
10631 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10632 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10633 ASSERT_EQUAL_FP32(0.0, s9);
10634 ASSERT_EQUAL_FP32(-0.0, s10);
10635 ASSERT_EQUAL_FP32(-1.0, s11);
10636 ASSERT_EQUAL_FP64(1.0, d12);
10637 ASSERT_EQUAL_FP64(1.0, d13);
10638 ASSERT_EQUAL_FP64(1.0, d14);
10639 ASSERT_EQUAL_FP64(1.0, d15);
10640 ASSERT_EQUAL_FP64(2.0, d16);
10641 ASSERT_EQUAL_FP64(-2.0, d17);
10642 ASSERT_EQUAL_FP64(-3.0, d18);
10643 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10644 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10645 ASSERT_EQUAL_FP64(0.0, d21);
10646 ASSERT_EQUAL_FP64(-0.0, d22);
10647 ASSERT_EQUAL_FP64(-1.0, d23);
armvixlf37fdc02014-02-05 13:22:16 +000010648
10649 TEARDOWN();
10650}
10651
10652
armvixlad96eda2013-06-14 11:42:37 +010010653TEST(frintn) {
10654 SETUP();
10655
10656 START();
10657 __ Fmov(s16, 1.0);
10658 __ Fmov(s17, 1.1);
10659 __ Fmov(s18, 1.5);
10660 __ Fmov(s19, 1.9);
10661 __ Fmov(s20, 2.5);
10662 __ Fmov(s21, -1.5);
10663 __ Fmov(s22, -2.5);
10664 __ Fmov(s23, kFP32PositiveInfinity);
10665 __ Fmov(s24, kFP32NegativeInfinity);
10666 __ Fmov(s25, 0.0);
10667 __ Fmov(s26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010668 __ Fmov(s27, -0.2);
armvixlad96eda2013-06-14 11:42:37 +010010669
10670 __ Frintn(s0, s16);
10671 __ Frintn(s1, s17);
10672 __ Frintn(s2, s18);
10673 __ Frintn(s3, s19);
10674 __ Frintn(s4, s20);
10675 __ Frintn(s5, s21);
10676 __ Frintn(s6, s22);
10677 __ Frintn(s7, s23);
10678 __ Frintn(s8, s24);
10679 __ Frintn(s9, s25);
10680 __ Frintn(s10, s26);
armvixl5799d6c2014-05-01 11:05:00 +010010681 __ Frintn(s11, s27);
armvixlad96eda2013-06-14 11:42:37 +010010682
10683 __ Fmov(d16, 1.0);
10684 __ Fmov(d17, 1.1);
10685 __ Fmov(d18, 1.5);
10686 __ Fmov(d19, 1.9);
10687 __ Fmov(d20, 2.5);
10688 __ Fmov(d21, -1.5);
10689 __ Fmov(d22, -2.5);
10690 __ Fmov(d23, kFP32PositiveInfinity);
10691 __ Fmov(d24, kFP32NegativeInfinity);
10692 __ Fmov(d25, 0.0);
10693 __ Fmov(d26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +010010694 __ Fmov(d27, -0.2);
armvixlad96eda2013-06-14 11:42:37 +010010695
armvixl5799d6c2014-05-01 11:05:00 +010010696 __ Frintn(d12, d16);
10697 __ Frintn(d13, d17);
10698 __ Frintn(d14, d18);
10699 __ Frintn(d15, d19);
10700 __ Frintn(d16, d20);
10701 __ Frintn(d17, d21);
10702 __ Frintn(d18, d22);
10703 __ Frintn(d19, d23);
10704 __ Frintn(d20, d24);
10705 __ Frintn(d21, d25);
10706 __ Frintn(d22, d26);
10707 __ Frintn(d23, d27);
armvixlad96eda2013-06-14 11:42:37 +010010708 END();
10709
10710 RUN();
10711
10712 ASSERT_EQUAL_FP32(1.0, s0);
10713 ASSERT_EQUAL_FP32(1.0, s1);
10714 ASSERT_EQUAL_FP32(2.0, s2);
10715 ASSERT_EQUAL_FP32(2.0, s3);
10716 ASSERT_EQUAL_FP32(2.0, s4);
10717 ASSERT_EQUAL_FP32(-2.0, s5);
10718 ASSERT_EQUAL_FP32(-2.0, s6);
10719 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10720 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10721 ASSERT_EQUAL_FP32(0.0, s9);
10722 ASSERT_EQUAL_FP32(-0.0, s10);
armvixl5799d6c2014-05-01 11:05:00 +010010723 ASSERT_EQUAL_FP32(-0.0, s11);
armvixlad96eda2013-06-14 11:42:37 +010010724 ASSERT_EQUAL_FP64(1.0, d12);
armvixl5799d6c2014-05-01 11:05:00 +010010725 ASSERT_EQUAL_FP64(1.0, d13);
armvixlad96eda2013-06-14 11:42:37 +010010726 ASSERT_EQUAL_FP64(2.0, d14);
10727 ASSERT_EQUAL_FP64(2.0, d15);
armvixl5799d6c2014-05-01 11:05:00 +010010728 ASSERT_EQUAL_FP64(2.0, d16);
armvixlad96eda2013-06-14 11:42:37 +010010729 ASSERT_EQUAL_FP64(-2.0, d17);
armvixl5799d6c2014-05-01 11:05:00 +010010730 ASSERT_EQUAL_FP64(-2.0, d18);
10731 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10732 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10733 ASSERT_EQUAL_FP64(0.0, d21);
10734 ASSERT_EQUAL_FP64(-0.0, d22);
10735 ASSERT_EQUAL_FP64(-0.0, d23);
armvixlad96eda2013-06-14 11:42:37 +010010736
10737 TEARDOWN();
10738}
10739
10740
armvixl330dc712014-11-25 10:38:32 +000010741TEST(frintp) {
10742 SETUP();
10743
10744 START();
10745 __ Fmov(s16, 1.0);
10746 __ Fmov(s17, 1.1);
10747 __ Fmov(s18, 1.5);
10748 __ Fmov(s19, 1.9);
10749 __ Fmov(s20, 2.5);
10750 __ Fmov(s21, -1.5);
10751 __ Fmov(s22, -2.5);
10752 __ Fmov(s23, kFP32PositiveInfinity);
10753 __ Fmov(s24, kFP32NegativeInfinity);
10754 __ Fmov(s25, 0.0);
10755 __ Fmov(s26, -0.0);
10756 __ Fmov(s27, -0.2);
10757
10758 __ Frintp(s0, s16);
10759 __ Frintp(s1, s17);
10760 __ Frintp(s2, s18);
10761 __ Frintp(s3, s19);
10762 __ Frintp(s4, s20);
10763 __ Frintp(s5, s21);
10764 __ Frintp(s6, s22);
10765 __ Frintp(s7, s23);
10766 __ Frintp(s8, s24);
10767 __ Frintp(s9, s25);
10768 __ Frintp(s10, s26);
10769 __ Frintp(s11, s27);
10770
10771 __ Fmov(d16, 1.0);
10772 __ Fmov(d17, 1.1);
10773 __ Fmov(d18, 1.5);
10774 __ Fmov(d19, 1.9);
10775 __ Fmov(d20, 2.5);
10776 __ Fmov(d21, -1.5);
10777 __ Fmov(d22, -2.5);
10778 __ Fmov(d23, kFP32PositiveInfinity);
10779 __ Fmov(d24, kFP32NegativeInfinity);
10780 __ Fmov(d25, 0.0);
10781 __ Fmov(d26, -0.0);
10782 __ Fmov(d27, -0.2);
10783
10784 __ Frintp(d12, d16);
10785 __ Frintp(d13, d17);
10786 __ Frintp(d14, d18);
10787 __ Frintp(d15, d19);
10788 __ Frintp(d16, d20);
10789 __ Frintp(d17, d21);
10790 __ Frintp(d18, d22);
10791 __ Frintp(d19, d23);
10792 __ Frintp(d20, d24);
10793 __ Frintp(d21, d25);
10794 __ Frintp(d22, d26);
10795 __ Frintp(d23, d27);
10796 END();
10797
10798 RUN();
10799
10800 ASSERT_EQUAL_FP32(1.0, s0);
10801 ASSERT_EQUAL_FP32(2.0, s1);
10802 ASSERT_EQUAL_FP32(2.0, s2);
10803 ASSERT_EQUAL_FP32(2.0, s3);
10804 ASSERT_EQUAL_FP32(3.0, s4);
10805 ASSERT_EQUAL_FP32(-1.0, s5);
10806 ASSERT_EQUAL_FP32(-2.0, s6);
10807 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10808 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10809 ASSERT_EQUAL_FP32(0.0, s9);
10810 ASSERT_EQUAL_FP32(-0.0, s10);
10811 ASSERT_EQUAL_FP32(-0.0, s11);
10812 ASSERT_EQUAL_FP64(1.0, d12);
10813 ASSERT_EQUAL_FP64(2.0, d13);
10814 ASSERT_EQUAL_FP64(2.0, d14);
10815 ASSERT_EQUAL_FP64(2.0, d15);
10816 ASSERT_EQUAL_FP64(3.0, d16);
10817 ASSERT_EQUAL_FP64(-1.0, d17);
10818 ASSERT_EQUAL_FP64(-2.0, d18);
10819 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10820 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10821 ASSERT_EQUAL_FP64(0.0, d21);
10822 ASSERT_EQUAL_FP64(-0.0, d22);
10823 ASSERT_EQUAL_FP64(-0.0, d23);
10824
10825 TEARDOWN();
10826}
10827
10828
10829TEST(frintx) {
10830 // VIXL only supports the round-to-nearest FPCR mode, and it doesn't support
10831 // FP exceptions, so this test has the same results as frintn (and frinti).
10832 SETUP();
10833
10834 START();
10835 __ Fmov(s16, 1.0);
10836 __ Fmov(s17, 1.1);
10837 __ Fmov(s18, 1.5);
10838 __ Fmov(s19, 1.9);
10839 __ Fmov(s20, 2.5);
10840 __ Fmov(s21, -1.5);
10841 __ Fmov(s22, -2.5);
10842 __ Fmov(s23, kFP32PositiveInfinity);
10843 __ Fmov(s24, kFP32NegativeInfinity);
10844 __ Fmov(s25, 0.0);
10845 __ Fmov(s26, -0.0);
10846 __ Fmov(s27, -0.2);
10847
10848 __ Frintx(s0, s16);
10849 __ Frintx(s1, s17);
10850 __ Frintx(s2, s18);
10851 __ Frintx(s3, s19);
10852 __ Frintx(s4, s20);
10853 __ Frintx(s5, s21);
10854 __ Frintx(s6, s22);
10855 __ Frintx(s7, s23);
10856 __ Frintx(s8, s24);
10857 __ Frintx(s9, s25);
10858 __ Frintx(s10, s26);
10859 __ Frintx(s11, s27);
10860
10861 __ Fmov(d16, 1.0);
10862 __ Fmov(d17, 1.1);
10863 __ Fmov(d18, 1.5);
10864 __ Fmov(d19, 1.9);
10865 __ Fmov(d20, 2.5);
10866 __ Fmov(d21, -1.5);
10867 __ Fmov(d22, -2.5);
10868 __ Fmov(d23, kFP32PositiveInfinity);
10869 __ Fmov(d24, kFP32NegativeInfinity);
10870 __ Fmov(d25, 0.0);
10871 __ Fmov(d26, -0.0);
10872 __ Fmov(d27, -0.2);
10873
10874 __ Frintx(d12, d16);
10875 __ Frintx(d13, d17);
10876 __ Frintx(d14, d18);
10877 __ Frintx(d15, d19);
10878 __ Frintx(d16, d20);
10879 __ Frintx(d17, d21);
10880 __ Frintx(d18, d22);
10881 __ Frintx(d19, d23);
10882 __ Frintx(d20, d24);
10883 __ Frintx(d21, d25);
10884 __ Frintx(d22, d26);
10885 __ Frintx(d23, d27);
10886 END();
10887
10888 RUN();
10889
10890 ASSERT_EQUAL_FP32(1.0, s0);
10891 ASSERT_EQUAL_FP32(1.0, s1);
10892 ASSERT_EQUAL_FP32(2.0, s2);
10893 ASSERT_EQUAL_FP32(2.0, s3);
10894 ASSERT_EQUAL_FP32(2.0, s4);
10895 ASSERT_EQUAL_FP32(-2.0, s5);
10896 ASSERT_EQUAL_FP32(-2.0, s6);
10897 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10898 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10899 ASSERT_EQUAL_FP32(0.0, s9);
10900 ASSERT_EQUAL_FP32(-0.0, s10);
10901 ASSERT_EQUAL_FP32(-0.0, s11);
10902 ASSERT_EQUAL_FP64(1.0, d12);
10903 ASSERT_EQUAL_FP64(1.0, d13);
10904 ASSERT_EQUAL_FP64(2.0, d14);
10905 ASSERT_EQUAL_FP64(2.0, d15);
10906 ASSERT_EQUAL_FP64(2.0, d16);
10907 ASSERT_EQUAL_FP64(-2.0, d17);
10908 ASSERT_EQUAL_FP64(-2.0, d18);
10909 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
10910 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
10911 ASSERT_EQUAL_FP64(0.0, d21);
10912 ASSERT_EQUAL_FP64(-0.0, d22);
10913 ASSERT_EQUAL_FP64(-0.0, d23);
10914
10915 TEARDOWN();
10916}
10917
10918
armvixlad96eda2013-06-14 11:42:37 +010010919TEST(frintz) {
10920 SETUP();
10921
10922 START();
10923 __ Fmov(s16, 1.0);
10924 __ Fmov(s17, 1.1);
10925 __ Fmov(s18, 1.5);
10926 __ Fmov(s19, 1.9);
10927 __ Fmov(s20, 2.5);
10928 __ Fmov(s21, -1.5);
10929 __ Fmov(s22, -2.5);
10930 __ Fmov(s23, kFP32PositiveInfinity);
10931 __ Fmov(s24, kFP32NegativeInfinity);
10932 __ Fmov(s25, 0.0);
10933 __ Fmov(s26, -0.0);
10934
10935 __ Frintz(s0, s16);
10936 __ Frintz(s1, s17);
10937 __ Frintz(s2, s18);
10938 __ Frintz(s3, s19);
10939 __ Frintz(s4, s20);
10940 __ Frintz(s5, s21);
10941 __ Frintz(s6, s22);
10942 __ Frintz(s7, s23);
10943 __ Frintz(s8, s24);
10944 __ Frintz(s9, s25);
10945 __ Frintz(s10, s26);
10946
10947 __ Fmov(d16, 1.0);
10948 __ Fmov(d17, 1.1);
10949 __ Fmov(d18, 1.5);
10950 __ Fmov(d19, 1.9);
10951 __ Fmov(d20, 2.5);
10952 __ Fmov(d21, -1.5);
10953 __ Fmov(d22, -2.5);
10954 __ Fmov(d23, kFP32PositiveInfinity);
10955 __ Fmov(d24, kFP32NegativeInfinity);
10956 __ Fmov(d25, 0.0);
10957 __ Fmov(d26, -0.0);
10958
10959 __ Frintz(d11, d16);
10960 __ Frintz(d12, d17);
10961 __ Frintz(d13, d18);
10962 __ Frintz(d14, d19);
10963 __ Frintz(d15, d20);
10964 __ Frintz(d16, d21);
10965 __ Frintz(d17, d22);
10966 __ Frintz(d18, d23);
10967 __ Frintz(d19, d24);
10968 __ Frintz(d20, d25);
10969 __ Frintz(d21, d26);
10970 END();
10971
10972 RUN();
10973
10974 ASSERT_EQUAL_FP32(1.0, s0);
10975 ASSERT_EQUAL_FP32(1.0, s1);
10976 ASSERT_EQUAL_FP32(1.0, s2);
10977 ASSERT_EQUAL_FP32(1.0, s3);
10978 ASSERT_EQUAL_FP32(2.0, s4);
10979 ASSERT_EQUAL_FP32(-1.0, s5);
10980 ASSERT_EQUAL_FP32(-2.0, s6);
10981 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
10982 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
10983 ASSERT_EQUAL_FP32(0.0, s9);
10984 ASSERT_EQUAL_FP32(-0.0, s10);
10985 ASSERT_EQUAL_FP64(1.0, d11);
10986 ASSERT_EQUAL_FP64(1.0, d12);
10987 ASSERT_EQUAL_FP64(1.0, d13);
10988 ASSERT_EQUAL_FP64(1.0, d14);
10989 ASSERT_EQUAL_FP64(2.0, d15);
10990 ASSERT_EQUAL_FP64(-1.0, d16);
10991 ASSERT_EQUAL_FP64(-2.0, d17);
10992 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
10993 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
10994 ASSERT_EQUAL_FP64(0.0, d20);
10995 ASSERT_EQUAL_FP64(-0.0, d21);
10996
10997 TEARDOWN();
10998}
10999
11000
armvixl578645f2013-08-15 17:21:42 +010011001TEST(fcvt_ds) {
armvixlad96eda2013-06-14 11:42:37 +010011002 SETUP();
11003
11004 START();
11005 __ Fmov(s16, 1.0);
11006 __ Fmov(s17, 1.1);
11007 __ Fmov(s18, 1.5);
11008 __ Fmov(s19, 1.9);
11009 __ Fmov(s20, 2.5);
11010 __ Fmov(s21, -1.5);
11011 __ Fmov(s22, -2.5);
11012 __ Fmov(s23, kFP32PositiveInfinity);
11013 __ Fmov(s24, kFP32NegativeInfinity);
11014 __ Fmov(s25, 0.0);
11015 __ Fmov(s26, -0.0);
armvixl578645f2013-08-15 17:21:42 +010011016 __ Fmov(s27, FLT_MAX);
11017 __ Fmov(s28, FLT_MIN);
11018 __ Fmov(s29, rawbits_to_float(0x7fc12345)); // Quiet NaN.
11019 __ Fmov(s30, rawbits_to_float(0x7f812345)); // Signalling NaN.
armvixlad96eda2013-06-14 11:42:37 +010011020
11021 __ Fcvt(d0, s16);
11022 __ Fcvt(d1, s17);
11023 __ Fcvt(d2, s18);
11024 __ Fcvt(d3, s19);
11025 __ Fcvt(d4, s20);
11026 __ Fcvt(d5, s21);
11027 __ Fcvt(d6, s22);
11028 __ Fcvt(d7, s23);
11029 __ Fcvt(d8, s24);
11030 __ Fcvt(d9, s25);
11031 __ Fcvt(d10, s26);
armvixl578645f2013-08-15 17:21:42 +010011032 __ Fcvt(d11, s27);
11033 __ Fcvt(d12, s28);
11034 __ Fcvt(d13, s29);
11035 __ Fcvt(d14, s30);
armvixlad96eda2013-06-14 11:42:37 +010011036 END();
11037
11038 RUN();
11039
11040 ASSERT_EQUAL_FP64(1.0f, d0);
11041 ASSERT_EQUAL_FP64(1.1f, d1);
11042 ASSERT_EQUAL_FP64(1.5f, d2);
11043 ASSERT_EQUAL_FP64(1.9f, d3);
11044 ASSERT_EQUAL_FP64(2.5f, d4);
11045 ASSERT_EQUAL_FP64(-1.5f, d5);
11046 ASSERT_EQUAL_FP64(-2.5f, d6);
11047 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
11048 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8);
11049 ASSERT_EQUAL_FP64(0.0f, d9);
11050 ASSERT_EQUAL_FP64(-0.0f, d10);
armvixl578645f2013-08-15 17:21:42 +010011051 ASSERT_EQUAL_FP64(FLT_MAX, d11);
11052 ASSERT_EQUAL_FP64(FLT_MIN, d12);
11053
11054 // Check that the NaN payload is preserved according to A64 conversion rules:
11055 // - The sign bit is preserved.
11056 // - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
11057 // - The remaining mantissa bits are copied until they run out.
11058 // - The low-order bits that haven't already been assigned are set to 0.
11059 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d13);
11060 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d14);
armvixlad96eda2013-06-14 11:42:37 +010011061
11062 TEARDOWN();
11063}
11064
11065
armvixl578645f2013-08-15 17:21:42 +010011066TEST(fcvt_sd) {
armvixl5799d6c2014-05-01 11:05:00 +010011067 // Test simple conversions here. Complex behaviour (such as rounding
11068 // specifics) are tested in the simulator tests.
armvixl578645f2013-08-15 17:21:42 +010011069
armvixl5799d6c2014-05-01 11:05:00 +010011070 SETUP();
armvixl578645f2013-08-15 17:21:42 +010011071
armvixl5799d6c2014-05-01 11:05:00 +010011072 START();
11073 __ Fmov(d16, 1.0);
11074 __ Fmov(d17, 1.1);
11075 __ Fmov(d18, 1.5);
11076 __ Fmov(d19, 1.9);
11077 __ Fmov(d20, 2.5);
11078 __ Fmov(d21, -1.5);
11079 __ Fmov(d22, -2.5);
11080 __ Fmov(d23, kFP32PositiveInfinity);
11081 __ Fmov(d24, kFP32NegativeInfinity);
11082 __ Fmov(d25, 0.0);
11083 __ Fmov(d26, -0.0);
11084 __ Fmov(d27, FLT_MAX);
11085 __ Fmov(d28, FLT_MIN);
11086 __ Fmov(d29, rawbits_to_double(0x7ff82468a0000000)); // Quiet NaN.
11087 __ Fmov(d30, rawbits_to_double(0x7ff02468a0000000)); // Signalling NaN.
armvixl578645f2013-08-15 17:21:42 +010011088
armvixl5799d6c2014-05-01 11:05:00 +010011089 __ Fcvt(s0, d16);
11090 __ Fcvt(s1, d17);
11091 __ Fcvt(s2, d18);
11092 __ Fcvt(s3, d19);
11093 __ Fcvt(s4, d20);
11094 __ Fcvt(s5, d21);
11095 __ Fcvt(s6, d22);
11096 __ Fcvt(s7, d23);
11097 __ Fcvt(s8, d24);
11098 __ Fcvt(s9, d25);
11099 __ Fcvt(s10, d26);
11100 __ Fcvt(s11, d27);
11101 __ Fcvt(s12, d28);
11102 __ Fcvt(s13, d29);
11103 __ Fcvt(s14, d30);
11104 END();
armvixl578645f2013-08-15 17:21:42 +010011105
armvixl5799d6c2014-05-01 11:05:00 +010011106 RUN();
armvixl578645f2013-08-15 17:21:42 +010011107
armvixl5799d6c2014-05-01 11:05:00 +010011108 ASSERT_EQUAL_FP32(1.0f, s0);
11109 ASSERT_EQUAL_FP32(1.1f, s1);
11110 ASSERT_EQUAL_FP32(1.5f, s2);
11111 ASSERT_EQUAL_FP32(1.9f, s3);
11112 ASSERT_EQUAL_FP32(2.5f, s4);
11113 ASSERT_EQUAL_FP32(-1.5f, s5);
11114 ASSERT_EQUAL_FP32(-2.5f, s6);
11115 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
11116 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
11117 ASSERT_EQUAL_FP32(0.0f, s9);
11118 ASSERT_EQUAL_FP32(-0.0f, s10);
11119 ASSERT_EQUAL_FP32(FLT_MAX, s11);
11120 ASSERT_EQUAL_FP32(FLT_MIN, s12);
armvixl578645f2013-08-15 17:21:42 +010011121
armvixl5799d6c2014-05-01 11:05:00 +010011122 // Check that the NaN payload is preserved according to A64 conversion rules:
11123 // - The sign bit is preserved.
11124 // - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
11125 // - The remaining mantissa bits are copied until they run out.
11126 // - The low-order bits that haven't already been assigned are set to 0.
11127 ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s13);
11128 ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s14);
armvixl578645f2013-08-15 17:21:42 +010011129
armvixl5799d6c2014-05-01 11:05:00 +010011130 TEARDOWN();
armvixl578645f2013-08-15 17:21:42 +010011131}
11132
11133
armvixl5289c592015-03-02 13:52:04 +000011134TEST(fcvt_half) {
11135 SETUP();
11136
11137 START();
11138 Label done;
11139 {
11140 // Check all exact conversions from half to float and back.
11141 Label ok, fail;
11142 __ Mov(w0, 0);
11143 for (int i = 0; i < 0xffff; i += 3) {
11144 if ((i & 0x7c00) == 0x7c00) continue;
11145 __ Mov(w1, i);
11146 __ Fmov(s1, w1);
11147 __ Fcvt(s2, h1);
11148 __ Fcvt(h2, s2);
11149 __ Fmov(w2, s2);
11150 __ Cmp(w1, w2);
11151 __ B(&fail, ne);
11152 }
11153 __ B(&ok);
11154 __ Bind(&fail);
11155 __ Mov(w0, 1);
11156 __ B(&done);
11157 __ Bind(&ok);
11158 }
11159 {
11160 // Check all exact conversions from half to double and back.
11161 Label ok, fail;
11162 for (int i = 0; i < 0xffff; i += 3) {
11163 if ((i & 0x7c00) == 0x7c00) continue;
11164 __ Mov(w1, i);
11165 __ Fmov(s1, w1);
11166 __ Fcvt(d2, h1);
11167 __ Fcvt(h2, d2);
11168 __ Mov(w2, v2.S(), 0);
11169 __ Cmp(w1, w2);
11170 __ B(&fail, ne);
11171 }
11172 __ B(&ok);
11173 __ Bind(&fail);
11174 __ Mov(w0, 2);
11175 __ Bind(&ok);
11176 }
11177 __ Bind(&done);
11178
11179 // Check some other interesting values.
11180 __ Fmov(s0, kFP32PositiveInfinity);
11181 __ Fmov(s1, kFP32NegativeInfinity);
11182 __ Fmov(s2, 65504); // Max half precision.
11183 __ Fmov(s3, 6.10352e-5); // Min positive normal.
11184 __ Fmov(s4, 6.09756e-5); // Max subnormal.
11185 __ Fmov(s5, 5.96046e-8); // Min positive subnormal.
11186 __ Fmov(s6, 5e-9); // Not representable -> zero.
11187 __ Fmov(s7, -0.0);
11188 __ Fcvt(h0, s0);
11189 __ Fcvt(h1, s1);
11190 __ Fcvt(h2, s2);
11191 __ Fcvt(h3, s3);
11192 __ Fcvt(h4, s4);
11193 __ Fcvt(h5, s5);
11194 __ Fcvt(h6, s6);
11195 __ Fcvt(h7, s7);
11196
11197 __ Fmov(d20, kFP64PositiveInfinity);
11198 __ Fmov(d21, kFP64NegativeInfinity);
11199 __ Fmov(d22, 65504); // Max half precision.
11200 __ Fmov(d23, 6.10352e-5); // Min positive normal.
11201 __ Fmov(d24, 6.09756e-5); // Max subnormal.
11202 __ Fmov(d25, 5.96046e-8); // Min positive subnormal.
11203 __ Fmov(d26, 5e-9); // Not representable -> zero.
11204 __ Fmov(d27, -0.0);
11205 __ Fcvt(h20, d20);
11206 __ Fcvt(h21, d21);
11207 __ Fcvt(h22, d22);
11208 __ Fcvt(h23, d23);
11209 __ Fcvt(h24, d24);
11210 __ Fcvt(h25, d25);
11211 __ Fcvt(h26, d26);
11212 __ Fcvt(h27, d27);
11213 END();
11214
11215 RUN();
11216
11217 ASSERT_EQUAL_32(0, w0); // 1 => float failed, 2 => double failed.
11218 ASSERT_EQUAL_128(0, kFP16PositiveInfinity, q0);
11219 ASSERT_EQUAL_128(0, kFP16NegativeInfinity, q1);
11220 ASSERT_EQUAL_128(0, 0x7bff, q2);
11221 ASSERT_EQUAL_128(0, 0x0400, q3);
11222 ASSERT_EQUAL_128(0, 0x03ff, q4);
11223 ASSERT_EQUAL_128(0, 0x0001, q5);
11224 ASSERT_EQUAL_128(0, 0, q6);
11225 ASSERT_EQUAL_128(0, 0x8000, q7);
11226 ASSERT_EQUAL_128(0, kFP16PositiveInfinity, q20);
11227 ASSERT_EQUAL_128(0, kFP16NegativeInfinity, q21);
11228 ASSERT_EQUAL_128(0, 0x7bff, q22);
11229 ASSERT_EQUAL_128(0, 0x0400, q23);
11230 ASSERT_EQUAL_128(0, 0x03ff, q24);
11231 ASSERT_EQUAL_128(0, 0x0001, q25);
11232 ASSERT_EQUAL_128(0, 0, q26);
11233 ASSERT_EQUAL_128(0, 0x8000, q27);
11234 TEARDOWN();
11235}
11236
11237
armvixlf37fdc02014-02-05 13:22:16 +000011238TEST(fcvtas) {
11239 SETUP();
11240
11241 START();
11242 __ Fmov(s0, 1.0);
11243 __ Fmov(s1, 1.1);
11244 __ Fmov(s2, 2.5);
11245 __ Fmov(s3, -2.5);
11246 __ Fmov(s4, kFP32PositiveInfinity);
11247 __ Fmov(s5, kFP32NegativeInfinity);
11248 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11249 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
11250 __ Fmov(d8, 1.0);
11251 __ Fmov(d9, 1.1);
11252 __ Fmov(d10, 2.5);
11253 __ Fmov(d11, -2.5);
11254 __ Fmov(d12, kFP64PositiveInfinity);
11255 __ Fmov(d13, kFP64NegativeInfinity);
11256 __ Fmov(d14, kWMaxInt - 1);
11257 __ Fmov(d15, kWMinInt + 1);
11258 __ Fmov(s17, 1.1);
11259 __ Fmov(s18, 2.5);
11260 __ Fmov(s19, -2.5);
11261 __ Fmov(s20, kFP32PositiveInfinity);
11262 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011263 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +000011264 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
11265 __ Fmov(d24, 1.1);
11266 __ Fmov(d25, 2.5);
11267 __ Fmov(d26, -2.5);
11268 __ Fmov(d27, kFP64PositiveInfinity);
11269 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011270 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +000011271 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
11272
11273 __ Fcvtas(w0, s0);
11274 __ Fcvtas(w1, s1);
11275 __ Fcvtas(w2, s2);
11276 __ Fcvtas(w3, s3);
11277 __ Fcvtas(w4, s4);
11278 __ Fcvtas(w5, s5);
11279 __ Fcvtas(w6, s6);
11280 __ Fcvtas(w7, s7);
11281 __ Fcvtas(w8, d8);
11282 __ Fcvtas(w9, d9);
11283 __ Fcvtas(w10, d10);
11284 __ Fcvtas(w11, d11);
11285 __ Fcvtas(w12, d12);
11286 __ Fcvtas(w13, d13);
11287 __ Fcvtas(w14, d14);
11288 __ Fcvtas(w15, d15);
11289 __ Fcvtas(x17, s17);
11290 __ Fcvtas(x18, s18);
11291 __ Fcvtas(x19, s19);
11292 __ Fcvtas(x20, s20);
11293 __ Fcvtas(x21, s21);
11294 __ Fcvtas(x22, s22);
11295 __ Fcvtas(x23, s23);
11296 __ Fcvtas(x24, d24);
11297 __ Fcvtas(x25, d25);
11298 __ Fcvtas(x26, d26);
11299 __ Fcvtas(x27, d27);
11300 __ Fcvtas(x28, d28);
11301 __ Fcvtas(x29, d29);
11302 __ Fcvtas(x30, d30);
11303 END();
11304
11305 RUN();
11306
11307 ASSERT_EQUAL_64(1, x0);
11308 ASSERT_EQUAL_64(1, x1);
11309 ASSERT_EQUAL_64(3, x2);
11310 ASSERT_EQUAL_64(0xfffffffd, x3);
11311 ASSERT_EQUAL_64(0x7fffffff, x4);
11312 ASSERT_EQUAL_64(0x80000000, x5);
11313 ASSERT_EQUAL_64(0x7fffff80, x6);
11314 ASSERT_EQUAL_64(0x80000080, x7);
11315 ASSERT_EQUAL_64(1, x8);
11316 ASSERT_EQUAL_64(1, x9);
11317 ASSERT_EQUAL_64(3, x10);
11318 ASSERT_EQUAL_64(0xfffffffd, x11);
11319 ASSERT_EQUAL_64(0x7fffffff, x12);
11320 ASSERT_EQUAL_64(0x80000000, x13);
11321 ASSERT_EQUAL_64(0x7ffffffe, x14);
11322 ASSERT_EQUAL_64(0x80000001, x15);
11323 ASSERT_EQUAL_64(1, x17);
11324 ASSERT_EQUAL_64(3, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011325 ASSERT_EQUAL_64(0xfffffffffffffffd, x19);
11326 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11327 ASSERT_EQUAL_64(0x8000000000000000, x21);
11328 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11329 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlf37fdc02014-02-05 13:22:16 +000011330 ASSERT_EQUAL_64(1, x24);
11331 ASSERT_EQUAL_64(3, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011332 ASSERT_EQUAL_64(0xfffffffffffffffd, x26);
11333 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11334 ASSERT_EQUAL_64(0x8000000000000000, x28);
11335 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11336 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlf37fdc02014-02-05 13:22:16 +000011337
11338 TEARDOWN();
11339}
11340
11341
11342TEST(fcvtau) {
11343 SETUP();
11344
11345 START();
11346 __ Fmov(s0, 1.0);
11347 __ Fmov(s1, 1.1);
11348 __ Fmov(s2, 2.5);
11349 __ Fmov(s3, -2.5);
11350 __ Fmov(s4, kFP32PositiveInfinity);
11351 __ Fmov(s5, kFP32NegativeInfinity);
11352 __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX.
11353 __ Fmov(d8, 1.0);
11354 __ Fmov(d9, 1.1);
11355 __ Fmov(d10, 2.5);
11356 __ Fmov(d11, -2.5);
11357 __ Fmov(d12, kFP64PositiveInfinity);
11358 __ Fmov(d13, kFP64NegativeInfinity);
11359 __ Fmov(d14, 0xfffffffe);
11360 __ Fmov(s16, 1.0);
11361 __ Fmov(s17, 1.1);
11362 __ Fmov(s18, 2.5);
11363 __ Fmov(s19, -2.5);
11364 __ Fmov(s20, kFP32PositiveInfinity);
11365 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011366 __ Fmov(s22, 0xffffff0000000000); // Largest float < UINT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +000011367 __ Fmov(d24, 1.1);
11368 __ Fmov(d25, 2.5);
11369 __ Fmov(d26, -2.5);
11370 __ Fmov(d27, kFP64PositiveInfinity);
11371 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011372 __ Fmov(d29, 0xfffffffffffff800); // Largest double < UINT64_MAX.
11373 __ Fmov(s30, 0x100000000);
armvixlf37fdc02014-02-05 13:22:16 +000011374
11375 __ Fcvtau(w0, s0);
11376 __ Fcvtau(w1, s1);
11377 __ Fcvtau(w2, s2);
11378 __ Fcvtau(w3, s3);
11379 __ Fcvtau(w4, s4);
11380 __ Fcvtau(w5, s5);
11381 __ Fcvtau(w6, s6);
11382 __ Fcvtau(w8, d8);
11383 __ Fcvtau(w9, d9);
11384 __ Fcvtau(w10, d10);
11385 __ Fcvtau(w11, d11);
11386 __ Fcvtau(w12, d12);
11387 __ Fcvtau(w13, d13);
11388 __ Fcvtau(w14, d14);
11389 __ Fcvtau(w15, d15);
11390 __ Fcvtau(x16, s16);
11391 __ Fcvtau(x17, s17);
11392 __ Fcvtau(x18, s18);
11393 __ Fcvtau(x19, s19);
11394 __ Fcvtau(x20, s20);
11395 __ Fcvtau(x21, s21);
11396 __ Fcvtau(x22, s22);
11397 __ Fcvtau(x24, d24);
11398 __ Fcvtau(x25, d25);
11399 __ Fcvtau(x26, d26);
11400 __ Fcvtau(x27, d27);
11401 __ Fcvtau(x28, d28);
11402 __ Fcvtau(x29, d29);
11403 __ Fcvtau(w30, s30);
11404 END();
11405
11406 RUN();
11407
11408 ASSERT_EQUAL_64(1, x0);
11409 ASSERT_EQUAL_64(1, x1);
11410 ASSERT_EQUAL_64(3, x2);
11411 ASSERT_EQUAL_64(0, x3);
11412 ASSERT_EQUAL_64(0xffffffff, x4);
11413 ASSERT_EQUAL_64(0, x5);
11414 ASSERT_EQUAL_64(0xffffff00, x6);
11415 ASSERT_EQUAL_64(1, x8);
11416 ASSERT_EQUAL_64(1, x9);
11417 ASSERT_EQUAL_64(3, x10);
11418 ASSERT_EQUAL_64(0, x11);
11419 ASSERT_EQUAL_64(0xffffffff, x12);
11420 ASSERT_EQUAL_64(0, x13);
11421 ASSERT_EQUAL_64(0xfffffffe, x14);
11422 ASSERT_EQUAL_64(1, x16);
11423 ASSERT_EQUAL_64(1, x17);
11424 ASSERT_EQUAL_64(3, x18);
11425 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +000011426 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlf37fdc02014-02-05 13:22:16 +000011427 ASSERT_EQUAL_64(0, x21);
armvixlb0c8ae22014-03-21 14:03:59 +000011428 ASSERT_EQUAL_64(0xffffff0000000000, x22);
armvixlf37fdc02014-02-05 13:22:16 +000011429 ASSERT_EQUAL_64(1, x24);
11430 ASSERT_EQUAL_64(3, x25);
11431 ASSERT_EQUAL_64(0, x26);
armvixlb0c8ae22014-03-21 14:03:59 +000011432 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
armvixlf37fdc02014-02-05 13:22:16 +000011433 ASSERT_EQUAL_64(0, x28);
armvixlb0c8ae22014-03-21 14:03:59 +000011434 ASSERT_EQUAL_64(0xfffffffffffff800, x29);
armvixlf37fdc02014-02-05 13:22:16 +000011435 ASSERT_EQUAL_64(0xffffffff, x30);
11436
11437 TEARDOWN();
11438}
11439
11440
armvixlad96eda2013-06-14 11:42:37 +010011441TEST(fcvtms) {
11442 SETUP();
11443
11444 START();
11445 __ Fmov(s0, 1.0);
11446 __ Fmov(s1, 1.1);
11447 __ Fmov(s2, 1.5);
11448 __ Fmov(s3, -1.5);
11449 __ Fmov(s4, kFP32PositiveInfinity);
11450 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011451 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11452 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011453 __ Fmov(d8, 1.0);
11454 __ Fmov(d9, 1.1);
11455 __ Fmov(d10, 1.5);
11456 __ Fmov(d11, -1.5);
11457 __ Fmov(d12, kFP64PositiveInfinity);
11458 __ Fmov(d13, kFP64NegativeInfinity);
11459 __ Fmov(d14, kWMaxInt - 1);
11460 __ Fmov(d15, kWMinInt + 1);
11461 __ Fmov(s17, 1.1);
11462 __ Fmov(s18, 1.5);
11463 __ Fmov(s19, -1.5);
11464 __ Fmov(s20, kFP32PositiveInfinity);
11465 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011466 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11467 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011468 __ Fmov(d24, 1.1);
11469 __ Fmov(d25, 1.5);
11470 __ Fmov(d26, -1.5);
11471 __ Fmov(d27, kFP64PositiveInfinity);
11472 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011473 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11474 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011475
11476 __ Fcvtms(w0, s0);
11477 __ Fcvtms(w1, s1);
11478 __ Fcvtms(w2, s2);
11479 __ Fcvtms(w3, s3);
11480 __ Fcvtms(w4, s4);
11481 __ Fcvtms(w5, s5);
11482 __ Fcvtms(w6, s6);
11483 __ Fcvtms(w7, s7);
11484 __ Fcvtms(w8, d8);
11485 __ Fcvtms(w9, d9);
11486 __ Fcvtms(w10, d10);
11487 __ Fcvtms(w11, d11);
11488 __ Fcvtms(w12, d12);
11489 __ Fcvtms(w13, d13);
11490 __ Fcvtms(w14, d14);
11491 __ Fcvtms(w15, d15);
11492 __ Fcvtms(x17, s17);
11493 __ Fcvtms(x18, s18);
11494 __ Fcvtms(x19, s19);
11495 __ Fcvtms(x20, s20);
11496 __ Fcvtms(x21, s21);
11497 __ Fcvtms(x22, s22);
11498 __ Fcvtms(x23, s23);
11499 __ Fcvtms(x24, d24);
11500 __ Fcvtms(x25, d25);
11501 __ Fcvtms(x26, d26);
11502 __ Fcvtms(x27, d27);
11503 __ Fcvtms(x28, d28);
11504 __ Fcvtms(x29, d29);
11505 __ Fcvtms(x30, d30);
11506 END();
11507
11508 RUN();
11509
11510 ASSERT_EQUAL_64(1, x0);
11511 ASSERT_EQUAL_64(1, x1);
11512 ASSERT_EQUAL_64(1, x2);
11513 ASSERT_EQUAL_64(0xfffffffe, x3);
11514 ASSERT_EQUAL_64(0x7fffffff, x4);
11515 ASSERT_EQUAL_64(0x80000000, x5);
11516 ASSERT_EQUAL_64(0x7fffff80, x6);
11517 ASSERT_EQUAL_64(0x80000080, x7);
11518 ASSERT_EQUAL_64(1, x8);
11519 ASSERT_EQUAL_64(1, x9);
11520 ASSERT_EQUAL_64(1, x10);
11521 ASSERT_EQUAL_64(0xfffffffe, x11);
11522 ASSERT_EQUAL_64(0x7fffffff, x12);
11523 ASSERT_EQUAL_64(0x80000000, x13);
11524 ASSERT_EQUAL_64(0x7ffffffe, x14);
11525 ASSERT_EQUAL_64(0x80000001, x15);
11526 ASSERT_EQUAL_64(1, x17);
11527 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011528 ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
11529 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11530 ASSERT_EQUAL_64(0x8000000000000000, x21);
11531 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11532 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010011533 ASSERT_EQUAL_64(1, x24);
11534 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011535 ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
11536 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11537 ASSERT_EQUAL_64(0x8000000000000000, x28);
11538 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11539 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +010011540
11541 TEARDOWN();
11542}
11543
11544
11545TEST(fcvtmu) {
11546 SETUP();
11547
11548 START();
11549 __ Fmov(s0, 1.0);
11550 __ Fmov(s1, 1.1);
11551 __ Fmov(s2, 1.5);
11552 __ Fmov(s3, -1.5);
11553 __ Fmov(s4, kFP32PositiveInfinity);
11554 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011555 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11556 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011557 __ Fmov(d8, 1.0);
11558 __ Fmov(d9, 1.1);
11559 __ Fmov(d10, 1.5);
11560 __ Fmov(d11, -1.5);
11561 __ Fmov(d12, kFP64PositiveInfinity);
11562 __ Fmov(d13, kFP64NegativeInfinity);
11563 __ Fmov(d14, kWMaxInt - 1);
11564 __ Fmov(d15, kWMinInt + 1);
11565 __ Fmov(s17, 1.1);
11566 __ Fmov(s18, 1.5);
11567 __ Fmov(s19, -1.5);
11568 __ Fmov(s20, kFP32PositiveInfinity);
11569 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011570 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11571 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011572 __ Fmov(d24, 1.1);
11573 __ Fmov(d25, 1.5);
11574 __ Fmov(d26, -1.5);
11575 __ Fmov(d27, kFP64PositiveInfinity);
11576 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011577 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11578 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011579
11580 __ Fcvtmu(w0, s0);
11581 __ Fcvtmu(w1, s1);
11582 __ Fcvtmu(w2, s2);
11583 __ Fcvtmu(w3, s3);
11584 __ Fcvtmu(w4, s4);
11585 __ Fcvtmu(w5, s5);
11586 __ Fcvtmu(w6, s6);
11587 __ Fcvtmu(w7, s7);
11588 __ Fcvtmu(w8, d8);
11589 __ Fcvtmu(w9, d9);
11590 __ Fcvtmu(w10, d10);
11591 __ Fcvtmu(w11, d11);
11592 __ Fcvtmu(w12, d12);
11593 __ Fcvtmu(w13, d13);
11594 __ Fcvtmu(w14, d14);
11595 __ Fcvtmu(x17, s17);
11596 __ Fcvtmu(x18, s18);
11597 __ Fcvtmu(x19, s19);
11598 __ Fcvtmu(x20, s20);
11599 __ Fcvtmu(x21, s21);
11600 __ Fcvtmu(x22, s22);
11601 __ Fcvtmu(x23, s23);
11602 __ Fcvtmu(x24, d24);
11603 __ Fcvtmu(x25, d25);
11604 __ Fcvtmu(x26, d26);
11605 __ Fcvtmu(x27, d27);
11606 __ Fcvtmu(x28, d28);
11607 __ Fcvtmu(x29, d29);
11608 __ Fcvtmu(x30, d30);
11609 END();
11610
11611 RUN();
11612
11613 ASSERT_EQUAL_64(1, x0);
11614 ASSERT_EQUAL_64(1, x1);
11615 ASSERT_EQUAL_64(1, x2);
11616 ASSERT_EQUAL_64(0, x3);
11617 ASSERT_EQUAL_64(0xffffffff, x4);
11618 ASSERT_EQUAL_64(0, x5);
11619 ASSERT_EQUAL_64(0x7fffff80, x6);
11620 ASSERT_EQUAL_64(0, x7);
11621 ASSERT_EQUAL_64(1, x8);
11622 ASSERT_EQUAL_64(1, x9);
11623 ASSERT_EQUAL_64(1, x10);
11624 ASSERT_EQUAL_64(0, x11);
11625 ASSERT_EQUAL_64(0xffffffff, x12);
11626 ASSERT_EQUAL_64(0, x13);
11627 ASSERT_EQUAL_64(0x7ffffffe, x14);
11628 ASSERT_EQUAL_64(1, x17);
11629 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011630 ASSERT_EQUAL_64(0, x19);
11631 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
11632 ASSERT_EQUAL_64(0, x21);
11633 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11634 ASSERT_EQUAL_64(0, x23);
armvixlad96eda2013-06-14 11:42:37 +010011635 ASSERT_EQUAL_64(1, x24);
11636 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011637 ASSERT_EQUAL_64(0, x26);
11638 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
11639 ASSERT_EQUAL_64(0, x28);
11640 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11641 ASSERT_EQUAL_64(0, x30);
armvixlad96eda2013-06-14 11:42:37 +010011642
11643 TEARDOWN();
11644}
11645
11646
11647TEST(fcvtns) {
11648 SETUP();
11649
11650 START();
11651 __ Fmov(s0, 1.0);
11652 __ Fmov(s1, 1.1);
11653 __ Fmov(s2, 1.5);
11654 __ Fmov(s3, -1.5);
11655 __ Fmov(s4, kFP32PositiveInfinity);
11656 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011657 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11658 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011659 __ Fmov(d8, 1.0);
11660 __ Fmov(d9, 1.1);
11661 __ Fmov(d10, 1.5);
11662 __ Fmov(d11, -1.5);
11663 __ Fmov(d12, kFP64PositiveInfinity);
11664 __ Fmov(d13, kFP64NegativeInfinity);
11665 __ Fmov(d14, kWMaxInt - 1);
11666 __ Fmov(d15, kWMinInt + 1);
11667 __ Fmov(s17, 1.1);
11668 __ Fmov(s18, 1.5);
11669 __ Fmov(s19, -1.5);
11670 __ Fmov(s20, kFP32PositiveInfinity);
11671 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011672 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11673 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011674 __ Fmov(d24, 1.1);
11675 __ Fmov(d25, 1.5);
11676 __ Fmov(d26, -1.5);
11677 __ Fmov(d27, kFP64PositiveInfinity);
11678 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011679 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11680 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011681
11682 __ Fcvtns(w0, s0);
11683 __ Fcvtns(w1, s1);
11684 __ Fcvtns(w2, s2);
11685 __ Fcvtns(w3, s3);
11686 __ Fcvtns(w4, s4);
11687 __ Fcvtns(w5, s5);
11688 __ Fcvtns(w6, s6);
11689 __ Fcvtns(w7, s7);
11690 __ Fcvtns(w8, d8);
11691 __ Fcvtns(w9, d9);
11692 __ Fcvtns(w10, d10);
11693 __ Fcvtns(w11, d11);
11694 __ Fcvtns(w12, d12);
11695 __ Fcvtns(w13, d13);
11696 __ Fcvtns(w14, d14);
11697 __ Fcvtns(w15, d15);
11698 __ Fcvtns(x17, s17);
11699 __ Fcvtns(x18, s18);
11700 __ Fcvtns(x19, s19);
11701 __ Fcvtns(x20, s20);
11702 __ Fcvtns(x21, s21);
11703 __ Fcvtns(x22, s22);
11704 __ Fcvtns(x23, s23);
11705 __ Fcvtns(x24, d24);
11706 __ Fcvtns(x25, d25);
11707 __ Fcvtns(x26, d26);
11708 __ Fcvtns(x27, d27);
11709 __ Fcvtns(x28, d28);
11710 __ Fcvtns(x29, d29);
11711 __ Fcvtns(x30, d30);
11712 END();
11713
11714 RUN();
11715
11716 ASSERT_EQUAL_64(1, x0);
11717 ASSERT_EQUAL_64(1, x1);
11718 ASSERT_EQUAL_64(2, x2);
11719 ASSERT_EQUAL_64(0xfffffffe, x3);
11720 ASSERT_EQUAL_64(0x7fffffff, x4);
11721 ASSERT_EQUAL_64(0x80000000, x5);
11722 ASSERT_EQUAL_64(0x7fffff80, x6);
11723 ASSERT_EQUAL_64(0x80000080, x7);
11724 ASSERT_EQUAL_64(1, x8);
11725 ASSERT_EQUAL_64(1, x9);
11726 ASSERT_EQUAL_64(2, x10);
11727 ASSERT_EQUAL_64(0xfffffffe, x11);
11728 ASSERT_EQUAL_64(0x7fffffff, x12);
11729 ASSERT_EQUAL_64(0x80000000, x13);
11730 ASSERT_EQUAL_64(0x7ffffffe, x14);
11731 ASSERT_EQUAL_64(0x80000001, x15);
11732 ASSERT_EQUAL_64(1, x17);
11733 ASSERT_EQUAL_64(2, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011734 ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
11735 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11736 ASSERT_EQUAL_64(0x8000000000000000, x21);
11737 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11738 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010011739 ASSERT_EQUAL_64(1, x24);
11740 ASSERT_EQUAL_64(2, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011741 ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
11742 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11743 ASSERT_EQUAL_64(0x8000000000000000, x28);
11744 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11745 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +010011746
11747 TEARDOWN();
11748}
11749
11750
11751TEST(fcvtnu) {
11752 SETUP();
11753
11754 START();
11755 __ Fmov(s0, 1.0);
11756 __ Fmov(s1, 1.1);
11757 __ Fmov(s2, 1.5);
11758 __ Fmov(s3, -1.5);
11759 __ Fmov(s4, kFP32PositiveInfinity);
11760 __ Fmov(s5, kFP32NegativeInfinity);
11761 __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX.
11762 __ Fmov(d8, 1.0);
11763 __ Fmov(d9, 1.1);
11764 __ Fmov(d10, 1.5);
11765 __ Fmov(d11, -1.5);
11766 __ Fmov(d12, kFP64PositiveInfinity);
11767 __ Fmov(d13, kFP64NegativeInfinity);
11768 __ Fmov(d14, 0xfffffffe);
11769 __ Fmov(s16, 1.0);
11770 __ Fmov(s17, 1.1);
11771 __ Fmov(s18, 1.5);
11772 __ Fmov(s19, -1.5);
11773 __ Fmov(s20, kFP32PositiveInfinity);
11774 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011775 __ Fmov(s22, 0xffffff0000000000); // Largest float < UINT64_MAX.
armvixlad96eda2013-06-14 11:42:37 +010011776 __ Fmov(d24, 1.1);
11777 __ Fmov(d25, 1.5);
11778 __ Fmov(d26, -1.5);
11779 __ Fmov(d27, kFP64PositiveInfinity);
11780 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011781 __ Fmov(d29, 0xfffffffffffff800); // Largest double < UINT64_MAX.
11782 __ Fmov(s30, 0x100000000);
armvixlad96eda2013-06-14 11:42:37 +010011783
11784 __ Fcvtnu(w0, s0);
11785 __ Fcvtnu(w1, s1);
11786 __ Fcvtnu(w2, s2);
11787 __ Fcvtnu(w3, s3);
11788 __ Fcvtnu(w4, s4);
11789 __ Fcvtnu(w5, s5);
11790 __ Fcvtnu(w6, s6);
11791 __ Fcvtnu(w8, d8);
11792 __ Fcvtnu(w9, d9);
11793 __ Fcvtnu(w10, d10);
11794 __ Fcvtnu(w11, d11);
11795 __ Fcvtnu(w12, d12);
11796 __ Fcvtnu(w13, d13);
11797 __ Fcvtnu(w14, d14);
11798 __ Fcvtnu(w15, d15);
11799 __ Fcvtnu(x16, s16);
11800 __ Fcvtnu(x17, s17);
11801 __ Fcvtnu(x18, s18);
11802 __ Fcvtnu(x19, s19);
11803 __ Fcvtnu(x20, s20);
11804 __ Fcvtnu(x21, s21);
11805 __ Fcvtnu(x22, s22);
11806 __ Fcvtnu(x24, d24);
11807 __ Fcvtnu(x25, d25);
11808 __ Fcvtnu(x26, d26);
11809 __ Fcvtnu(x27, d27);
11810 __ Fcvtnu(x28, d28);
11811 __ Fcvtnu(x29, d29);
11812 __ Fcvtnu(w30, s30);
11813 END();
11814
11815 RUN();
11816
11817 ASSERT_EQUAL_64(1, x0);
11818 ASSERT_EQUAL_64(1, x1);
11819 ASSERT_EQUAL_64(2, x2);
11820 ASSERT_EQUAL_64(0, x3);
11821 ASSERT_EQUAL_64(0xffffffff, x4);
11822 ASSERT_EQUAL_64(0, x5);
11823 ASSERT_EQUAL_64(0xffffff00, x6);
11824 ASSERT_EQUAL_64(1, x8);
11825 ASSERT_EQUAL_64(1, x9);
11826 ASSERT_EQUAL_64(2, x10);
11827 ASSERT_EQUAL_64(0, x11);
11828 ASSERT_EQUAL_64(0xffffffff, x12);
11829 ASSERT_EQUAL_64(0, x13);
11830 ASSERT_EQUAL_64(0xfffffffe, x14);
11831 ASSERT_EQUAL_64(1, x16);
11832 ASSERT_EQUAL_64(1, x17);
11833 ASSERT_EQUAL_64(2, x18);
11834 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +000011835 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlad96eda2013-06-14 11:42:37 +010011836 ASSERT_EQUAL_64(0, x21);
armvixlb0c8ae22014-03-21 14:03:59 +000011837 ASSERT_EQUAL_64(0xffffff0000000000, x22);
armvixlad96eda2013-06-14 11:42:37 +010011838 ASSERT_EQUAL_64(1, x24);
11839 ASSERT_EQUAL_64(2, x25);
11840 ASSERT_EQUAL_64(0, x26);
armvixlb0c8ae22014-03-21 14:03:59 +000011841 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
armvixlad96eda2013-06-14 11:42:37 +010011842 ASSERT_EQUAL_64(0, x28);
armvixlb0c8ae22014-03-21 14:03:59 +000011843 ASSERT_EQUAL_64(0xfffffffffffff800, x29);
armvixlad96eda2013-06-14 11:42:37 +010011844 ASSERT_EQUAL_64(0xffffffff, x30);
11845
11846 TEARDOWN();
11847}
11848
11849
11850TEST(fcvtzs) {
11851 SETUP();
11852
11853 START();
11854 __ Fmov(s0, 1.0);
11855 __ Fmov(s1, 1.1);
11856 __ Fmov(s2, 1.5);
11857 __ Fmov(s3, -1.5);
11858 __ Fmov(s4, kFP32PositiveInfinity);
11859 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011860 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11861 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011862 __ Fmov(d8, 1.0);
11863 __ Fmov(d9, 1.1);
11864 __ Fmov(d10, 1.5);
11865 __ Fmov(d11, -1.5);
11866 __ Fmov(d12, kFP64PositiveInfinity);
11867 __ Fmov(d13, kFP64NegativeInfinity);
11868 __ Fmov(d14, kWMaxInt - 1);
11869 __ Fmov(d15, kWMinInt + 1);
11870 __ Fmov(s17, 1.1);
11871 __ Fmov(s18, 1.5);
11872 __ Fmov(s19, -1.5);
11873 __ Fmov(s20, kFP32PositiveInfinity);
11874 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011875 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11876 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011877 __ Fmov(d24, 1.1);
11878 __ Fmov(d25, 1.5);
11879 __ Fmov(d26, -1.5);
11880 __ Fmov(d27, kFP64PositiveInfinity);
11881 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011882 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11883 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011884
11885 __ Fcvtzs(w0, s0);
11886 __ Fcvtzs(w1, s1);
11887 __ Fcvtzs(w2, s2);
11888 __ Fcvtzs(w3, s3);
11889 __ Fcvtzs(w4, s4);
11890 __ Fcvtzs(w5, s5);
11891 __ Fcvtzs(w6, s6);
11892 __ Fcvtzs(w7, s7);
11893 __ Fcvtzs(w8, d8);
11894 __ Fcvtzs(w9, d9);
11895 __ Fcvtzs(w10, d10);
11896 __ Fcvtzs(w11, d11);
11897 __ Fcvtzs(w12, d12);
11898 __ Fcvtzs(w13, d13);
11899 __ Fcvtzs(w14, d14);
11900 __ Fcvtzs(w15, d15);
11901 __ Fcvtzs(x17, s17);
11902 __ Fcvtzs(x18, s18);
11903 __ Fcvtzs(x19, s19);
11904 __ Fcvtzs(x20, s20);
11905 __ Fcvtzs(x21, s21);
11906 __ Fcvtzs(x22, s22);
11907 __ Fcvtzs(x23, s23);
11908 __ Fcvtzs(x24, d24);
11909 __ Fcvtzs(x25, d25);
11910 __ Fcvtzs(x26, d26);
11911 __ Fcvtzs(x27, d27);
11912 __ Fcvtzs(x28, d28);
11913 __ Fcvtzs(x29, d29);
11914 __ Fcvtzs(x30, d30);
11915 END();
11916
11917 RUN();
11918
11919 ASSERT_EQUAL_64(1, x0);
11920 ASSERT_EQUAL_64(1, x1);
11921 ASSERT_EQUAL_64(1, x2);
11922 ASSERT_EQUAL_64(0xffffffff, x3);
11923 ASSERT_EQUAL_64(0x7fffffff, x4);
11924 ASSERT_EQUAL_64(0x80000000, x5);
11925 ASSERT_EQUAL_64(0x7fffff80, x6);
11926 ASSERT_EQUAL_64(0x80000080, x7);
11927 ASSERT_EQUAL_64(1, x8);
11928 ASSERT_EQUAL_64(1, x9);
11929 ASSERT_EQUAL_64(1, x10);
11930 ASSERT_EQUAL_64(0xffffffff, x11);
11931 ASSERT_EQUAL_64(0x7fffffff, x12);
11932 ASSERT_EQUAL_64(0x80000000, x13);
11933 ASSERT_EQUAL_64(0x7ffffffe, x14);
11934 ASSERT_EQUAL_64(0x80000001, x15);
11935 ASSERT_EQUAL_64(1, x17);
11936 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000011937 ASSERT_EQUAL_64(0xffffffffffffffff, x19);
11938 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
11939 ASSERT_EQUAL_64(0x8000000000000000, x21);
11940 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
11941 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010011942 ASSERT_EQUAL_64(1, x24);
11943 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000011944 ASSERT_EQUAL_64(0xffffffffffffffff, x26);
11945 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
11946 ASSERT_EQUAL_64(0x8000000000000000, x28);
11947 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
11948 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +010011949
11950 TEARDOWN();
11951}
11952
11953TEST(fcvtzu) {
11954 SETUP();
11955
11956 START();
11957 __ Fmov(s0, 1.0);
11958 __ Fmov(s1, 1.1);
11959 __ Fmov(s2, 1.5);
11960 __ Fmov(s3, -1.5);
11961 __ Fmov(s4, kFP32PositiveInfinity);
11962 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011963 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
11964 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011965 __ Fmov(d8, 1.0);
11966 __ Fmov(d9, 1.1);
11967 __ Fmov(d10, 1.5);
11968 __ Fmov(d11, -1.5);
11969 __ Fmov(d12, kFP64PositiveInfinity);
11970 __ Fmov(d13, kFP64NegativeInfinity);
11971 __ Fmov(d14, kWMaxInt - 1);
11972 __ Fmov(d15, kWMinInt + 1);
11973 __ Fmov(s17, 1.1);
11974 __ Fmov(s18, 1.5);
11975 __ Fmov(s19, -1.5);
11976 __ Fmov(s20, kFP32PositiveInfinity);
11977 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011978 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
11979 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011980 __ Fmov(d24, 1.1);
11981 __ Fmov(d25, 1.5);
11982 __ Fmov(d26, -1.5);
11983 __ Fmov(d27, kFP64PositiveInfinity);
11984 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +000011985 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
11986 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +010011987
11988 __ Fcvtzu(w0, s0);
11989 __ Fcvtzu(w1, s1);
11990 __ Fcvtzu(w2, s2);
11991 __ Fcvtzu(w3, s3);
11992 __ Fcvtzu(w4, s4);
11993 __ Fcvtzu(w5, s5);
11994 __ Fcvtzu(w6, s6);
11995 __ Fcvtzu(w7, s7);
11996 __ Fcvtzu(w8, d8);
11997 __ Fcvtzu(w9, d9);
11998 __ Fcvtzu(w10, d10);
11999 __ Fcvtzu(w11, d11);
12000 __ Fcvtzu(w12, d12);
12001 __ Fcvtzu(w13, d13);
12002 __ Fcvtzu(w14, d14);
12003 __ Fcvtzu(x17, s17);
12004 __ Fcvtzu(x18, s18);
12005 __ Fcvtzu(x19, s19);
12006 __ Fcvtzu(x20, s20);
12007 __ Fcvtzu(x21, s21);
12008 __ Fcvtzu(x22, s22);
12009 __ Fcvtzu(x23, s23);
12010 __ Fcvtzu(x24, d24);
12011 __ Fcvtzu(x25, d25);
12012 __ Fcvtzu(x26, d26);
12013 __ Fcvtzu(x27, d27);
12014 __ Fcvtzu(x28, d28);
12015 __ Fcvtzu(x29, d29);
12016 __ Fcvtzu(x30, d30);
12017 END();
12018
12019 RUN();
12020
12021 ASSERT_EQUAL_64(1, x0);
12022 ASSERT_EQUAL_64(1, x1);
12023 ASSERT_EQUAL_64(1, x2);
12024 ASSERT_EQUAL_64(0, x3);
12025 ASSERT_EQUAL_64(0xffffffff, x4);
12026 ASSERT_EQUAL_64(0, x5);
12027 ASSERT_EQUAL_64(0x7fffff80, x6);
12028 ASSERT_EQUAL_64(0, x7);
12029 ASSERT_EQUAL_64(1, x8);
12030 ASSERT_EQUAL_64(1, x9);
12031 ASSERT_EQUAL_64(1, x10);
12032 ASSERT_EQUAL_64(0, x11);
12033 ASSERT_EQUAL_64(0xffffffff, x12);
12034 ASSERT_EQUAL_64(0, x13);
12035 ASSERT_EQUAL_64(0x7ffffffe, x14);
12036 ASSERT_EQUAL_64(1, x17);
12037 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +000012038 ASSERT_EQUAL_64(0, x19);
12039 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
12040 ASSERT_EQUAL_64(0, x21);
12041 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
12042 ASSERT_EQUAL_64(0, x23);
armvixlad96eda2013-06-14 11:42:37 +010012043 ASSERT_EQUAL_64(1, x24);
12044 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +000012045 ASSERT_EQUAL_64(0, x26);
12046 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
12047 ASSERT_EQUAL_64(0, x28);
12048 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
12049 ASSERT_EQUAL_64(0, x30);
armvixlad96eda2013-06-14 11:42:37 +010012050
12051 TEARDOWN();
12052}
12053
12054
armvixl5289c592015-03-02 13:52:04 +000012055TEST(neon_fcvtl) {
12056 SETUP();
12057
12058 START();
12059
12060 __ Movi(v0.V2D(), 0x000080007efffeff, 0x3100b1007c00fc00);
12061 __ Movi(v1.V2D(), 0x03ff83ff00038003, 0x000180017c01fc01);
12062 __ Movi(v2.V2D(), 0x3e200000be200000, 0x7f800000ff800000);
12063 __ Movi(v3.V2D(), 0x0000000080000000, 0x7f8fffffff8fffff);
12064 __ Movi(v4.V2D(), 0x7fcfffffffcfffff, 0x0000000180000001);
12065 __ Fcvtl(v16.V4S(), v0.V4H());
12066 __ Fcvtl2(v17.V4S(), v0.V8H());
12067 __ Fcvtl(v18.V4S(), v1.V4H());
12068 __ Fcvtl2(v19.V4S(), v1.V8H());
12069
12070 __ Fcvtl(v20.V2D(), v2.V2S());
12071 __ Fcvtl2(v21.V2D(), v2.V4S());
12072 __ Fcvtl(v22.V2D(), v3.V2S());
12073 __ Fcvtl2(v23.V2D(), v3.V4S());
12074 __ Fcvtl(v24.V2D(), v4.V2S());
12075 __ Fcvtl2(v25.V2D(), v4.V4S());
12076
12077 END();
12078
12079 RUN();
12080 ASSERT_EQUAL_128(0x3e200000be200000, 0x7f800000ff800000, q16);
12081 ASSERT_EQUAL_128(0x0000000080000000, 0x7fdfe000ffdfe000, q17);
12082 ASSERT_EQUAL_128(0x33800000b3800000, 0x7fc02000ffc02000, q18);
12083 ASSERT_EQUAL_128(0x387fc000b87fc000, 0x34400000b4400000, q19);
12084 ASSERT_EQUAL_128(0x7ff0000000000000, 0xfff0000000000000, q20);
12085 ASSERT_EQUAL_128(0x3fc4000000000000, 0xbfc4000000000000, q21);
12086 ASSERT_EQUAL_128(0x7ff9ffffe0000000, 0xfff9ffffe0000000, q22);
12087 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000000000, q23);
12088 ASSERT_EQUAL_128(0x36a0000000000000, 0xb6a0000000000000, q24);
12089 ASSERT_EQUAL_128(0x7ff9ffffe0000000, 0xfff9ffffe0000000, q25);
12090 TEARDOWN();
12091}
12092
12093
12094TEST(neon_fcvtn) {
12095 SETUP();
12096
12097 START();
12098
12099 __ Movi(v0.V2D(), 0x3e200000be200000, 0x7f800000ff800000);
12100 __ Movi(v1.V2D(), 0x0000000080000000, 0x7f8fffffff8fffff);
12101 __ Movi(v2.V2D(), 0x7fcfffffffcfffff, 0x0000000180000001);
12102 __ Movi(v3.V2D(), 0x3fc4000000000000, 0xbfc4000000000000);
12103 __ Movi(v4.V2D(), 0x7ff0000000000000, 0xfff0000000000000);
12104 __ Movi(v5.V2D(), 0x0000000000000000, 0x8000000000000000);
12105 __ Movi(v6.V2D(), 0x7ff0ffffffffffff, 0xfff0ffffffffffff);
12106 __ Movi(v7.V2D(), 0x7ff8ffffffffffff, 0xfff8ffffffffffff);
12107 __ Movi(v8.V2D(), 0x0000000000000001, 0x8000000000000001);
12108
12109 __ Fcvtn(v16.V4H(), v0.V4S());
12110 __ Fcvtn2(v16.V8H(), v1.V4S());
12111 __ Fcvtn(v17.V4H(), v2.V4S());
12112 __ Fcvtn(v18.V2S(), v3.V2D());
12113 __ Fcvtn2(v18.V4S(), v4.V2D());
12114 __ Fcvtn(v19.V2S(), v5.V2D());
12115 __ Fcvtn2(v19.V4S(), v6.V2D());
12116 __ Fcvtn(v20.V2S(), v7.V2D());
12117 __ Fcvtn2(v20.V4S(), v8.V2D());
12118 END();
12119
12120 RUN();
12121 ASSERT_EQUAL_128(0x000080007e7ffe7f, 0x3100b1007c00fc00, q16);
12122 ASSERT_EQUAL_128(0, 0x7e7ffe7f00008000, q17);
12123 ASSERT_EQUAL_128(0x7f800000ff800000, 0x3e200000be200000, q18);
12124 ASSERT_EQUAL_128(0x7fc7ffffffc7ffff, 0x0000000080000000, q19);
12125 ASSERT_EQUAL_128(0x0000000080000000, 0x7fc7ffffffc7ffff, q20);
12126 TEARDOWN();
12127}
12128
12129
12130TEST(neon_fcvtxn) {
12131 SETUP();
12132
12133 START();
12134 __ Movi(v0.V2D(), 0x3e200000be200000, 0x7f800000ff800000);
12135 __ Movi(v1.V2D(), 0x0000000080000000, 0x7f8fffffff8fffff);
12136 __ Movi(v2.V2D(), 0x7fcfffffffcfffff, 0x0000000180000001);
12137 __ Movi(v3.V2D(), 0x3fc4000000000000, 0xbfc4000000000000);
12138 __ Movi(v4.V2D(), 0x7ff0000000000000, 0xfff0000000000000);
12139 __ Movi(v5.V2D(), 0x0000000000000000, 0x8000000000000000);
12140 __ Movi(v6.V2D(), 0x7ff0ffffffffffff, 0xfff0ffffffffffff);
12141 __ Movi(v7.V2D(), 0x7ff8ffffffffffff, 0xfff8ffffffffffff);
12142 __ Movi(v8.V2D(), 0x0000000000000001, 0x8000000000000001);
12143 __ Movi(v9.V2D(), 0x41ed000000000000, 0x41efffffffefffff);
12144 __ Fcvtxn(v16.V2S(), v0.V2D());
12145 __ Fcvtxn2(v16.V4S(), v1.V2D());
12146 __ Fcvtxn(v17.V2S(), v2.V2D());
12147 __ Fcvtxn2(v17.V4S(), v3.V2D());
12148 __ Fcvtxn(v18.V2S(), v4.V2D());
12149 __ Fcvtxn2(v18.V4S(), v5.V2D());
12150 __ Fcvtxn(v19.V2S(), v6.V2D());
12151 __ Fcvtxn2(v19.V4S(), v7.V2D());
12152 __ Fcvtxn(v20.V2S(), v8.V2D());
12153 __ Fcvtxn2(v20.V4S(), v9.V2D());
12154 __ Fcvtxn(s21, d0);
12155 END();
12156
12157 RUN();
12158 ASSERT_EQUAL_128(0x000000017f7fffff, 0x310000057f7fffff, q16);
12159 ASSERT_EQUAL_128(0x3e200000be200000, 0x7f7fffff00000001, q17);
12160 ASSERT_EQUAL_128(0x0000000080000000, 0x7f800000ff800000, q18);
12161 ASSERT_EQUAL_128(0x7fc7ffffffc7ffff, 0x7fc7ffffffc7ffff, q19);
12162 ASSERT_EQUAL_128(0x4f6800004f7fffff, 0x0000000180000001, q20);
12163 ASSERT_EQUAL_128(0, 0x7f7fffff, q21);
12164 TEARDOWN();
12165}
12166
12167
armvixl578645f2013-08-15 17:21:42 +010012168// Test that scvtf and ucvtf can convert the 64-bit input into the expected
12169// value. All possible values of 'fbits' are tested. The expected value is
12170// modified accordingly in each case.
12171//
12172// The expected value is specified as the bit encoding of the expected double
12173// produced by scvtf (expected_scvtf_bits) as well as ucvtf
12174// (expected_ucvtf_bits).
12175//
12176// Where the input value is representable by int32_t or uint32_t, conversions
12177// from W registers will also be tested.
12178static void TestUScvtfHelper(uint64_t in,
12179 uint64_t expected_scvtf_bits,
12180 uint64_t expected_ucvtf_bits) {
12181 uint64_t u64 = in;
12182 uint32_t u32 = u64 & 0xffffffff;
12183 int64_t s64 = static_cast<int64_t>(in);
12184 int32_t s32 = s64 & 0x7fffffff;
12185
12186 bool cvtf_s32 = (s64 == s32);
12187 bool cvtf_u32 = (u64 == u32);
12188
12189 double results_scvtf_x[65];
12190 double results_ucvtf_x[65];
12191 double results_scvtf_w[33];
12192 double results_ucvtf_w[33];
12193
armvixlad96eda2013-06-14 11:42:37 +010012194 SETUP();
armvixlad96eda2013-06-14 11:42:37 +010012195 START();
armvixlad96eda2013-06-14 11:42:37 +010012196
armvixlb0c8ae22014-03-21 14:03:59 +000012197 __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
12198 __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
12199 __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
12200 __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
armvixl578645f2013-08-15 17:21:42 +010012201
12202 __ Mov(x10, s64);
12203
12204 // Corrupt the top word, in case it is accidentally used during W-register
12205 // conversions.
12206 __ Mov(x11, 0x5555555555555555);
12207 __ Bfi(x11, x10, 0, kWRegSize);
12208
12209 // Test integer conversions.
12210 __ Scvtf(d0, x10);
12211 __ Ucvtf(d1, x10);
12212 __ Scvtf(d2, w11);
12213 __ Ucvtf(d3, w11);
12214 __ Str(d0, MemOperand(x0));
12215 __ Str(d1, MemOperand(x1));
12216 __ Str(d2, MemOperand(x2));
12217 __ Str(d3, MemOperand(x3));
12218
12219 // Test all possible values of fbits.
12220 for (int fbits = 1; fbits <= 32; fbits++) {
12221 __ Scvtf(d0, x10, fbits);
12222 __ Ucvtf(d1, x10, fbits);
12223 __ Scvtf(d2, w11, fbits);
12224 __ Ucvtf(d3, w11, fbits);
12225 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
12226 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
12227 __ Str(d2, MemOperand(x2, fbits * kDRegSizeInBytes));
12228 __ Str(d3, MemOperand(x3, fbits * kDRegSizeInBytes));
12229 }
12230
12231 // Conversions from W registers can only handle fbits values <= 32, so just
12232 // test conversions from X registers for 32 < fbits <= 64.
12233 for (int fbits = 33; fbits <= 64; fbits++) {
12234 __ Scvtf(d0, x10, fbits);
12235 __ Ucvtf(d1, x10, fbits);
12236 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
12237 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
12238 }
12239
12240 END();
armvixlad96eda2013-06-14 11:42:37 +010012241 RUN();
12242
armvixl578645f2013-08-15 17:21:42 +010012243 // Check the results.
12244 double expected_scvtf_base = rawbits_to_double(expected_scvtf_bits);
12245 double expected_ucvtf_base = rawbits_to_double(expected_ucvtf_bits);
12246
12247 for (int fbits = 0; fbits <= 32; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010012248 double expected_scvtf = expected_scvtf_base / std::pow(2, fbits);
12249 double expected_ucvtf = expected_ucvtf_base / std::pow(2, fbits);
armvixl578645f2013-08-15 17:21:42 +010012250 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
12251 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
12252 if (cvtf_s32) ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_w[fbits]);
12253 if (cvtf_u32) ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_w[fbits]);
12254 }
12255 for (int fbits = 33; fbits <= 64; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010012256 double expected_scvtf = expected_scvtf_base / std::pow(2, fbits);
12257 double expected_ucvtf = expected_ucvtf_base / std::pow(2, fbits);
armvixl578645f2013-08-15 17:21:42 +010012258 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
12259 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
12260 }
armvixlad96eda2013-06-14 11:42:37 +010012261
12262 TEARDOWN();
12263}
12264
12265
armvixl578645f2013-08-15 17:21:42 +010012266TEST(scvtf_ucvtf_double) {
12267 // Simple conversions of positive numbers which require no rounding; the
12268 // results should not depened on the rounding mode, and ucvtf and scvtf should
12269 // produce the same result.
12270 TestUScvtfHelper(0x0000000000000000, 0x0000000000000000, 0x0000000000000000);
12271 TestUScvtfHelper(0x0000000000000001, 0x3ff0000000000000, 0x3ff0000000000000);
12272 TestUScvtfHelper(0x0000000040000000, 0x41d0000000000000, 0x41d0000000000000);
12273 TestUScvtfHelper(0x0000000100000000, 0x41f0000000000000, 0x41f0000000000000);
12274 TestUScvtfHelper(0x4000000000000000, 0x43d0000000000000, 0x43d0000000000000);
12275 // Test mantissa extremities.
12276 TestUScvtfHelper(0x4000000000000400, 0x43d0000000000001, 0x43d0000000000001);
12277 // The largest int32_t that fits in a double.
12278 TestUScvtfHelper(0x000000007fffffff, 0x41dfffffffc00000, 0x41dfffffffc00000);
12279 // Values that would be negative if treated as an int32_t.
12280 TestUScvtfHelper(0x00000000ffffffff, 0x41efffffffe00000, 0x41efffffffe00000);
12281 TestUScvtfHelper(0x0000000080000000, 0x41e0000000000000, 0x41e0000000000000);
12282 TestUScvtfHelper(0x0000000080000001, 0x41e0000000200000, 0x41e0000000200000);
12283 // The largest int64_t that fits in a double.
12284 TestUScvtfHelper(0x7ffffffffffffc00, 0x43dfffffffffffff, 0x43dfffffffffffff);
12285 // Check for bit pattern reproduction.
12286 TestUScvtfHelper(0x0123456789abcde0, 0x43723456789abcde, 0x43723456789abcde);
12287 TestUScvtfHelper(0x0000000012345678, 0x41b2345678000000, 0x41b2345678000000);
12288
12289 // Simple conversions of negative int64_t values. These require no rounding,
12290 // and the results should not depend on the rounding mode.
12291 TestUScvtfHelper(0xffffffffc0000000, 0xc1d0000000000000, 0x43effffffff80000);
12292 TestUScvtfHelper(0xffffffff00000000, 0xc1f0000000000000, 0x43efffffffe00000);
12293 TestUScvtfHelper(0xc000000000000000, 0xc3d0000000000000, 0x43e8000000000000);
12294
12295 // Conversions which require rounding.
12296 TestUScvtfHelper(0x1000000000000000, 0x43b0000000000000, 0x43b0000000000000);
12297 TestUScvtfHelper(0x1000000000000001, 0x43b0000000000000, 0x43b0000000000000);
12298 TestUScvtfHelper(0x1000000000000080, 0x43b0000000000000, 0x43b0000000000000);
12299 TestUScvtfHelper(0x1000000000000081, 0x43b0000000000001, 0x43b0000000000001);
12300 TestUScvtfHelper(0x1000000000000100, 0x43b0000000000001, 0x43b0000000000001);
12301 TestUScvtfHelper(0x1000000000000101, 0x43b0000000000001, 0x43b0000000000001);
12302 TestUScvtfHelper(0x1000000000000180, 0x43b0000000000002, 0x43b0000000000002);
12303 TestUScvtfHelper(0x1000000000000181, 0x43b0000000000002, 0x43b0000000000002);
12304 TestUScvtfHelper(0x1000000000000200, 0x43b0000000000002, 0x43b0000000000002);
12305 TestUScvtfHelper(0x1000000000000201, 0x43b0000000000002, 0x43b0000000000002);
12306 TestUScvtfHelper(0x1000000000000280, 0x43b0000000000002, 0x43b0000000000002);
12307 TestUScvtfHelper(0x1000000000000281, 0x43b0000000000003, 0x43b0000000000003);
12308 TestUScvtfHelper(0x1000000000000300, 0x43b0000000000003, 0x43b0000000000003);
12309 // Check rounding of negative int64_t values (and large uint64_t values).
12310 TestUScvtfHelper(0x8000000000000000, 0xc3e0000000000000, 0x43e0000000000000);
12311 TestUScvtfHelper(0x8000000000000001, 0xc3e0000000000000, 0x43e0000000000000);
12312 TestUScvtfHelper(0x8000000000000200, 0xc3e0000000000000, 0x43e0000000000000);
12313 TestUScvtfHelper(0x8000000000000201, 0xc3dfffffffffffff, 0x43e0000000000000);
12314 TestUScvtfHelper(0x8000000000000400, 0xc3dfffffffffffff, 0x43e0000000000000);
12315 TestUScvtfHelper(0x8000000000000401, 0xc3dfffffffffffff, 0x43e0000000000001);
12316 TestUScvtfHelper(0x8000000000000600, 0xc3dffffffffffffe, 0x43e0000000000001);
12317 TestUScvtfHelper(0x8000000000000601, 0xc3dffffffffffffe, 0x43e0000000000001);
12318 TestUScvtfHelper(0x8000000000000800, 0xc3dffffffffffffe, 0x43e0000000000001);
12319 TestUScvtfHelper(0x8000000000000801, 0xc3dffffffffffffe, 0x43e0000000000001);
12320 TestUScvtfHelper(0x8000000000000a00, 0xc3dffffffffffffe, 0x43e0000000000001);
12321 TestUScvtfHelper(0x8000000000000a01, 0xc3dffffffffffffd, 0x43e0000000000001);
12322 TestUScvtfHelper(0x8000000000000c00, 0xc3dffffffffffffd, 0x43e0000000000002);
12323 // Round up to produce a result that's too big for the input to represent.
12324 TestUScvtfHelper(0x7ffffffffffffe00, 0x43e0000000000000, 0x43e0000000000000);
12325 TestUScvtfHelper(0x7fffffffffffffff, 0x43e0000000000000, 0x43e0000000000000);
12326 TestUScvtfHelper(0xfffffffffffffc00, 0xc090000000000000, 0x43f0000000000000);
12327 TestUScvtfHelper(0xffffffffffffffff, 0xbff0000000000000, 0x43f0000000000000);
12328}
12329
12330
12331// The same as TestUScvtfHelper, but convert to floats.
12332static void TestUScvtf32Helper(uint64_t in,
12333 uint32_t expected_scvtf_bits,
12334 uint32_t expected_ucvtf_bits) {
12335 uint64_t u64 = in;
12336 uint32_t u32 = u64 & 0xffffffff;
12337 int64_t s64 = static_cast<int64_t>(in);
12338 int32_t s32 = s64 & 0x7fffffff;
12339
12340 bool cvtf_s32 = (s64 == s32);
12341 bool cvtf_u32 = (u64 == u32);
12342
12343 float results_scvtf_x[65];
12344 float results_ucvtf_x[65];
12345 float results_scvtf_w[33];
12346 float results_ucvtf_w[33];
12347
armvixlad96eda2013-06-14 11:42:37 +010012348 SETUP();
armvixlad96eda2013-06-14 11:42:37 +010012349 START();
armvixlad96eda2013-06-14 11:42:37 +010012350
armvixlb0c8ae22014-03-21 14:03:59 +000012351 __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
12352 __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
12353 __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
12354 __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
armvixl578645f2013-08-15 17:21:42 +010012355
12356 __ Mov(x10, s64);
12357
12358 // Corrupt the top word, in case it is accidentally used during W-register
12359 // conversions.
12360 __ Mov(x11, 0x5555555555555555);
12361 __ Bfi(x11, x10, 0, kWRegSize);
12362
12363 // Test integer conversions.
12364 __ Scvtf(s0, x10);
12365 __ Ucvtf(s1, x10);
12366 __ Scvtf(s2, w11);
12367 __ Ucvtf(s3, w11);
12368 __ Str(s0, MemOperand(x0));
12369 __ Str(s1, MemOperand(x1));
12370 __ Str(s2, MemOperand(x2));
12371 __ Str(s3, MemOperand(x3));
12372
12373 // Test all possible values of fbits.
12374 for (int fbits = 1; fbits <= 32; fbits++) {
12375 __ Scvtf(s0, x10, fbits);
12376 __ Ucvtf(s1, x10, fbits);
12377 __ Scvtf(s2, w11, fbits);
12378 __ Ucvtf(s3, w11, fbits);
12379 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
12380 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
12381 __ Str(s2, MemOperand(x2, fbits * kSRegSizeInBytes));
12382 __ Str(s3, MemOperand(x3, fbits * kSRegSizeInBytes));
12383 }
12384
12385 // Conversions from W registers can only handle fbits values <= 32, so just
12386 // test conversions from X registers for 32 < fbits <= 64.
12387 for (int fbits = 33; fbits <= 64; fbits++) {
12388 __ Scvtf(s0, x10, fbits);
12389 __ Ucvtf(s1, x10, fbits);
12390 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
12391 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
12392 }
armvixlad96eda2013-06-14 11:42:37 +010012393
12394 END();
armvixlad96eda2013-06-14 11:42:37 +010012395 RUN();
12396
armvixl578645f2013-08-15 17:21:42 +010012397 // Check the results.
12398 float expected_scvtf_base = rawbits_to_float(expected_scvtf_bits);
12399 float expected_ucvtf_base = rawbits_to_float(expected_ucvtf_bits);
armvixlad96eda2013-06-14 11:42:37 +010012400
armvixl578645f2013-08-15 17:21:42 +010012401 for (int fbits = 0; fbits <= 32; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010012402 float expected_scvtf = expected_scvtf_base / std::pow(2.0f, fbits);
12403 float expected_ucvtf = expected_ucvtf_base / std::pow(2.0f, fbits);
armvixl578645f2013-08-15 17:21:42 +010012404 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
12405 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
12406 if (cvtf_s32) ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_w[fbits]);
12407 if (cvtf_u32) ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_w[fbits]);
armvixl578645f2013-08-15 17:21:42 +010012408 }
12409 for (int fbits = 33; fbits <= 64; fbits++) {
armvixl6e2c8272015-03-31 11:04:14 +010012410 float expected_scvtf = expected_scvtf_base / std::pow(2.0f, fbits);
12411 float expected_ucvtf = expected_ucvtf_base / std::pow(2.0f, fbits);
armvixl578645f2013-08-15 17:21:42 +010012412 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
12413 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
12414 }
armvixlad96eda2013-06-14 11:42:37 +010012415
12416 TEARDOWN();
12417}
12418
12419
armvixl578645f2013-08-15 17:21:42 +010012420TEST(scvtf_ucvtf_float) {
12421 // Simple conversions of positive numbers which require no rounding; the
12422 // results should not depened on the rounding mode, and ucvtf and scvtf should
12423 // produce the same result.
12424 TestUScvtf32Helper(0x0000000000000000, 0x00000000, 0x00000000);
12425 TestUScvtf32Helper(0x0000000000000001, 0x3f800000, 0x3f800000);
12426 TestUScvtf32Helper(0x0000000040000000, 0x4e800000, 0x4e800000);
12427 TestUScvtf32Helper(0x0000000100000000, 0x4f800000, 0x4f800000);
12428 TestUScvtf32Helper(0x4000000000000000, 0x5e800000, 0x5e800000);
12429 // Test mantissa extremities.
12430 TestUScvtf32Helper(0x0000000000800001, 0x4b000001, 0x4b000001);
12431 TestUScvtf32Helper(0x4000008000000000, 0x5e800001, 0x5e800001);
12432 // The largest int32_t that fits in a float.
12433 TestUScvtf32Helper(0x000000007fffff80, 0x4effffff, 0x4effffff);
12434 // Values that would be negative if treated as an int32_t.
12435 TestUScvtf32Helper(0x00000000ffffff00, 0x4f7fffff, 0x4f7fffff);
12436 TestUScvtf32Helper(0x0000000080000000, 0x4f000000, 0x4f000000);
12437 TestUScvtf32Helper(0x0000000080000100, 0x4f000001, 0x4f000001);
12438 // The largest int64_t that fits in a float.
12439 TestUScvtf32Helper(0x7fffff8000000000, 0x5effffff, 0x5effffff);
12440 // Check for bit pattern reproduction.
12441 TestUScvtf32Helper(0x0000000000876543, 0x4b076543, 0x4b076543);
12442
12443 // Simple conversions of negative int64_t values. These require no rounding,
12444 // and the results should not depend on the rounding mode.
12445 TestUScvtf32Helper(0xfffffc0000000000, 0xd4800000, 0x5f7ffffc);
12446 TestUScvtf32Helper(0xc000000000000000, 0xde800000, 0x5f400000);
12447
12448 // Conversions which require rounding.
12449 TestUScvtf32Helper(0x0000800000000000, 0x57000000, 0x57000000);
12450 TestUScvtf32Helper(0x0000800000000001, 0x57000000, 0x57000000);
12451 TestUScvtf32Helper(0x0000800000800000, 0x57000000, 0x57000000);
12452 TestUScvtf32Helper(0x0000800000800001, 0x57000001, 0x57000001);
12453 TestUScvtf32Helper(0x0000800001000000, 0x57000001, 0x57000001);
12454 TestUScvtf32Helper(0x0000800001000001, 0x57000001, 0x57000001);
12455 TestUScvtf32Helper(0x0000800001800000, 0x57000002, 0x57000002);
12456 TestUScvtf32Helper(0x0000800001800001, 0x57000002, 0x57000002);
12457 TestUScvtf32Helper(0x0000800002000000, 0x57000002, 0x57000002);
12458 TestUScvtf32Helper(0x0000800002000001, 0x57000002, 0x57000002);
12459 TestUScvtf32Helper(0x0000800002800000, 0x57000002, 0x57000002);
12460 TestUScvtf32Helper(0x0000800002800001, 0x57000003, 0x57000003);
12461 TestUScvtf32Helper(0x0000800003000000, 0x57000003, 0x57000003);
12462 // Check rounding of negative int64_t values (and large uint64_t values).
12463 TestUScvtf32Helper(0x8000000000000000, 0xdf000000, 0x5f000000);
12464 TestUScvtf32Helper(0x8000000000000001, 0xdf000000, 0x5f000000);
12465 TestUScvtf32Helper(0x8000004000000000, 0xdf000000, 0x5f000000);
12466 TestUScvtf32Helper(0x8000004000000001, 0xdeffffff, 0x5f000000);
12467 TestUScvtf32Helper(0x8000008000000000, 0xdeffffff, 0x5f000000);
12468 TestUScvtf32Helper(0x8000008000000001, 0xdeffffff, 0x5f000001);
12469 TestUScvtf32Helper(0x800000c000000000, 0xdefffffe, 0x5f000001);
12470 TestUScvtf32Helper(0x800000c000000001, 0xdefffffe, 0x5f000001);
12471 TestUScvtf32Helper(0x8000010000000000, 0xdefffffe, 0x5f000001);
12472 TestUScvtf32Helper(0x8000010000000001, 0xdefffffe, 0x5f000001);
12473 TestUScvtf32Helper(0x8000014000000000, 0xdefffffe, 0x5f000001);
12474 TestUScvtf32Helper(0x8000014000000001, 0xdefffffd, 0x5f000001);
12475 TestUScvtf32Helper(0x8000018000000000, 0xdefffffd, 0x5f000002);
12476 // Round up to produce a result that's too big for the input to represent.
12477 TestUScvtf32Helper(0x000000007fffffc0, 0x4f000000, 0x4f000000);
12478 TestUScvtf32Helper(0x000000007fffffff, 0x4f000000, 0x4f000000);
12479 TestUScvtf32Helper(0x00000000ffffff80, 0x4f800000, 0x4f800000);
12480 TestUScvtf32Helper(0x00000000ffffffff, 0x4f800000, 0x4f800000);
12481 TestUScvtf32Helper(0x7fffffc000000000, 0x5f000000, 0x5f000000);
12482 TestUScvtf32Helper(0x7fffffffffffffff, 0x5f000000, 0x5f000000);
12483 TestUScvtf32Helper(0xffffff8000000000, 0xd3000000, 0x5f800000);
12484 TestUScvtf32Helper(0xffffffffffffffff, 0xbf800000, 0x5f800000);
12485}
12486
12487
armvixlad96eda2013-06-14 11:42:37 +010012488TEST(system_mrs) {
12489 SETUP();
12490
12491 START();
12492 __ Mov(w0, 0);
12493 __ Mov(w1, 1);
12494 __ Mov(w2, 0x80000000);
12495
12496 // Set the Z and C flags.
12497 __ Cmp(w0, w0);
12498 __ Mrs(x3, NZCV);
12499
12500 // Set the N flag.
12501 __ Cmp(w0, w1);
12502 __ Mrs(x4, NZCV);
12503
12504 // Set the Z, C and V flags.
armvixlf37fdc02014-02-05 13:22:16 +000012505 __ Adds(w0, w2, w2);
armvixlad96eda2013-06-14 11:42:37 +010012506 __ Mrs(x5, NZCV);
armvixl578645f2013-08-15 17:21:42 +010012507
12508 // Read the default FPCR.
12509 __ Mrs(x6, FPCR);
armvixlad96eda2013-06-14 11:42:37 +010012510 END();
12511
12512 RUN();
12513
armvixl578645f2013-08-15 17:21:42 +010012514 // NZCV
armvixlad96eda2013-06-14 11:42:37 +010012515 ASSERT_EQUAL_32(ZCFlag, w3);
12516 ASSERT_EQUAL_32(NFlag, w4);
12517 ASSERT_EQUAL_32(ZCVFlag, w5);
12518
armvixl578645f2013-08-15 17:21:42 +010012519 // FPCR
12520 // The default FPCR on Linux-based platforms is 0.
12521 ASSERT_EQUAL_32(0, w6);
12522
armvixlad96eda2013-06-14 11:42:37 +010012523 TEARDOWN();
12524}
12525
12526
12527TEST(system_msr) {
armvixl578645f2013-08-15 17:21:42 +010012528 // All FPCR fields that must be implemented: AHP, DN, FZ, RMode
12529 const uint64_t fpcr_core = 0x07c00000;
12530
12531 // All FPCR fields (including fields which may be read-as-zero):
12532 // Stride, Len
12533 // IDE, IXE, UFE, OFE, DZE, IOE
12534 const uint64_t fpcr_all = fpcr_core | 0x00379f00;
12535
armvixlad96eda2013-06-14 11:42:37 +010012536 SETUP();
12537
12538 START();
12539 __ Mov(w0, 0);
12540 __ Mov(w1, 0x7fffffff);
12541
12542 __ Mov(x7, 0);
12543
12544 __ Mov(x10, NVFlag);
12545 __ Cmp(w0, w0); // Set Z and C.
12546 __ Msr(NZCV, x10); // Set N and V.
12547 // The Msr should have overwritten every flag set by the Cmp.
12548 __ Cinc(x7, x7, mi); // N
12549 __ Cinc(x7, x7, ne); // !Z
12550 __ Cinc(x7, x7, lo); // !C
12551 __ Cinc(x7, x7, vs); // V
12552
12553 __ Mov(x10, ZCFlag);
12554 __ Cmn(w1, w1); // Set N and V.
12555 __ Msr(NZCV, x10); // Set Z and C.
12556 // The Msr should have overwritten every flag set by the Cmn.
12557 __ Cinc(x7, x7, pl); // !N
12558 __ Cinc(x7, x7, eq); // Z
12559 __ Cinc(x7, x7, hs); // C
12560 __ Cinc(x7, x7, vc); // !V
12561
armvixl578645f2013-08-15 17:21:42 +010012562 // All core FPCR fields must be writable.
12563 __ Mov(x8, fpcr_core);
12564 __ Msr(FPCR, x8);
12565 __ Mrs(x8, FPCR);
12566
12567 // All FPCR fields, including optional ones. This part of the test doesn't
12568 // achieve much other than ensuring that supported fields can be cleared by
12569 // the next test.
12570 __ Mov(x9, fpcr_all);
12571 __ Msr(FPCR, x9);
12572 __ Mrs(x9, FPCR);
12573 __ And(x9, x9, fpcr_core);
12574
12575 // The undefined bits must ignore writes.
12576 // It's conceivable that a future version of the architecture could use these
12577 // fields (making this test fail), but in the meantime this is a useful test
12578 // for the simulator.
12579 __ Mov(x10, ~fpcr_all);
12580 __ Msr(FPCR, x10);
12581 __ Mrs(x10, FPCR);
12582
armvixlad96eda2013-06-14 11:42:37 +010012583 END();
12584
12585 RUN();
12586
12587 // We should have incremented x7 (from 0) exactly 8 times.
12588 ASSERT_EQUAL_64(8, x7);
12589
armvixl578645f2013-08-15 17:21:42 +010012590 ASSERT_EQUAL_64(fpcr_core, x8);
12591 ASSERT_EQUAL_64(fpcr_core, x9);
12592 ASSERT_EQUAL_64(0, x10);
12593
armvixlad96eda2013-06-14 11:42:37 +010012594 TEARDOWN();
12595}
12596
12597
12598TEST(system_nop) {
12599 SETUP();
12600 RegisterDump before;
12601
12602 START();
12603 before.Dump(&masm);
12604 __ Nop();
12605 END();
12606
12607 RUN();
12608
12609 ASSERT_EQUAL_REGISTERS(before);
12610 ASSERT_EQUAL_NZCV(before.flags_nzcv());
12611
12612 TEARDOWN();
12613}
12614
12615
12616TEST(zero_dest) {
12617 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010012618 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +010012619 RegisterDump before;
12620
12621 START();
12622 // Preserve the stack pointer, in case we clobber it.
12623 __ Mov(x30, sp);
12624 // Initialize the other registers used in this test.
armvixlb0c8ae22014-03-21 14:03:59 +000012625 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012626 __ Mov(x0, 0);
12627 __ Mov(x1, literal_base);
12628 for (unsigned i = 2; i < x30.code(); i++) {
12629 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
12630 }
12631 before.Dump(&masm);
12632
12633 // All of these instructions should be NOPs in these forms, but have
12634 // alternate forms which can write into the stack pointer.
12635 __ add(xzr, x0, x1);
12636 __ add(xzr, x1, xzr);
12637 __ add(xzr, xzr, x1);
12638
12639 __ and_(xzr, x0, x2);
12640 __ and_(xzr, x2, xzr);
12641 __ and_(xzr, xzr, x2);
12642
12643 __ bic(xzr, x0, x3);
12644 __ bic(xzr, x3, xzr);
12645 __ bic(xzr, xzr, x3);
12646
12647 __ eon(xzr, x0, x4);
12648 __ eon(xzr, x4, xzr);
12649 __ eon(xzr, xzr, x4);
12650
12651 __ eor(xzr, x0, x5);
12652 __ eor(xzr, x5, xzr);
12653 __ eor(xzr, xzr, x5);
12654
12655 __ orr(xzr, x0, x6);
12656 __ orr(xzr, x6, xzr);
12657 __ orr(xzr, xzr, x6);
12658
12659 __ sub(xzr, x0, x7);
12660 __ sub(xzr, x7, xzr);
12661 __ sub(xzr, xzr, x7);
12662
12663 // Swap the saved stack pointer with the real one. If sp was written
12664 // during the test, it will show up in x30. This is done because the test
12665 // framework assumes that sp will be valid at the end of the test.
12666 __ Mov(x29, x30);
12667 __ Mov(x30, sp);
12668 __ Mov(sp, x29);
12669 // We used x29 as a scratch register, so reset it to make sure it doesn't
12670 // trigger a test failure.
12671 __ Add(x29, x28, x1);
12672 END();
12673
12674 RUN();
12675
12676 ASSERT_EQUAL_REGISTERS(before);
12677 ASSERT_EQUAL_NZCV(before.flags_nzcv());
12678
12679 TEARDOWN();
12680}
12681
12682
12683TEST(zero_dest_setflags) {
12684 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010012685 ALLOW_ASM();
armvixlad96eda2013-06-14 11:42:37 +010012686 RegisterDump before;
12687
12688 START();
12689 // Preserve the stack pointer, in case we clobber it.
12690 __ Mov(x30, sp);
12691 // Initialize the other registers used in this test.
armvixlb0c8ae22014-03-21 14:03:59 +000012692 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012693 __ Mov(x0, 0);
12694 __ Mov(x1, literal_base);
12695 for (int i = 2; i < 30; i++) {
12696 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
12697 }
12698 before.Dump(&masm);
12699
12700 // All of these instructions should only write to the flags in these forms,
12701 // but have alternate forms which can write into the stack pointer.
armvixlf37fdc02014-02-05 13:22:16 +000012702 __ adds(xzr, x0, Operand(x1, UXTX));
12703 __ adds(xzr, x1, Operand(xzr, UXTX));
12704 __ adds(xzr, x1, 1234);
12705 __ adds(xzr, x0, x1);
12706 __ adds(xzr, x1, xzr);
12707 __ adds(xzr, xzr, x1);
armvixlad96eda2013-06-14 11:42:37 +010012708
armvixlf37fdc02014-02-05 13:22:16 +000012709 __ ands(xzr, x2, ~0xf);
12710 __ ands(xzr, xzr, ~0xf);
12711 __ ands(xzr, x0, x2);
12712 __ ands(xzr, x2, xzr);
12713 __ ands(xzr, xzr, x2);
armvixlad96eda2013-06-14 11:42:37 +010012714
armvixlf37fdc02014-02-05 13:22:16 +000012715 __ bics(xzr, x3, ~0xf);
12716 __ bics(xzr, xzr, ~0xf);
12717 __ bics(xzr, x0, x3);
12718 __ bics(xzr, x3, xzr);
12719 __ bics(xzr, xzr, x3);
armvixlad96eda2013-06-14 11:42:37 +010012720
armvixlf37fdc02014-02-05 13:22:16 +000012721 __ subs(xzr, x0, Operand(x3, UXTX));
12722 __ subs(xzr, x3, Operand(xzr, UXTX));
12723 __ subs(xzr, x3, 1234);
12724 __ subs(xzr, x0, x3);
12725 __ subs(xzr, x3, xzr);
12726 __ subs(xzr, xzr, x3);
armvixlad96eda2013-06-14 11:42:37 +010012727
12728 // Swap the saved stack pointer with the real one. If sp was written
12729 // during the test, it will show up in x30. This is done because the test
12730 // framework assumes that sp will be valid at the end of the test.
12731 __ Mov(x29, x30);
12732 __ Mov(x30, sp);
12733 __ Mov(sp, x29);
12734 // We used x29 as a scratch register, so reset it to make sure it doesn't
12735 // trigger a test failure.
12736 __ Add(x29, x28, x1);
12737 END();
12738
12739 RUN();
12740
12741 ASSERT_EQUAL_REGISTERS(before);
12742
12743 TEARDOWN();
12744}
12745
12746
12747TEST(register_bit) {
12748 // No code generation takes place in this test, so no need to setup and
12749 // teardown.
12750
12751 // Simple tests.
armvixlb0c8ae22014-03-21 14:03:59 +000012752 assert(x0.Bit() == (UINT64_C(1) << 0));
12753 assert(x1.Bit() == (UINT64_C(1) << 1));
12754 assert(x10.Bit() == (UINT64_C(1) << 10));
armvixlad96eda2013-06-14 11:42:37 +010012755
12756 // AAPCS64 definitions.
armvixlb0c8ae22014-03-21 14:03:59 +000012757 assert(lr.Bit() == (UINT64_C(1) << kLinkRegCode));
armvixlad96eda2013-06-14 11:42:37 +010012758
12759 // Fixed (hardware) definitions.
armvixlb0c8ae22014-03-21 14:03:59 +000012760 assert(xzr.Bit() == (UINT64_C(1) << kZeroRegCode));
armvixlad96eda2013-06-14 11:42:37 +010012761
12762 // Internal ABI definitions.
armvixlb0c8ae22014-03-21 14:03:59 +000012763 assert(sp.Bit() == (UINT64_C(1) << kSPRegInternalCode));
armvixlad96eda2013-06-14 11:42:37 +010012764 assert(sp.Bit() != xzr.Bit());
12765
12766 // xn.Bit() == wn.Bit() at all times, for the same n.
12767 assert(x0.Bit() == w0.Bit());
12768 assert(x1.Bit() == w1.Bit());
12769 assert(x10.Bit() == w10.Bit());
12770 assert(xzr.Bit() == wzr.Bit());
12771 assert(sp.Bit() == wsp.Bit());
12772}
12773
12774
12775TEST(stack_pointer_override) {
12776 // This test generates some stack maintenance code, but the test only checks
12777 // the reported state.
12778 SETUP();
12779 START();
12780
12781 // The default stack pointer in VIXL is sp.
12782 assert(sp.Is(__ StackPointer()));
12783 __ SetStackPointer(x0);
12784 assert(x0.Is(__ StackPointer()));
12785 __ SetStackPointer(x28);
12786 assert(x28.Is(__ StackPointer()));
12787 __ SetStackPointer(sp);
12788 assert(sp.Is(__ StackPointer()));
12789
12790 END();
12791 RUN();
12792 TEARDOWN();
12793}
12794
12795
12796TEST(peek_poke_simple) {
12797 SETUP();
12798 START();
12799
12800 static const RegList x0_to_x3 = x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit();
12801 static const RegList x10_to_x13 = x10.Bit() | x11.Bit() |
12802 x12.Bit() | x13.Bit();
12803
12804 // The literal base is chosen to have two useful properties:
12805 // * When multiplied by small values (such as a register index), this value
12806 // is clearly readable in the result.
12807 // * The value is not formed from repeating fixed-size smaller values, so it
12808 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000012809 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012810
12811 // Initialize the registers.
12812 __ Mov(x0, literal_base);
12813 __ Add(x1, x0, x0);
12814 __ Add(x2, x1, x0);
12815 __ Add(x3, x2, x0);
12816
12817 __ Claim(32);
12818
12819 // Simple exchange.
12820 // After this test:
12821 // x0-x3 should be unchanged.
12822 // w10-w13 should contain the lower words of x0-x3.
12823 __ Poke(x0, 0);
12824 __ Poke(x1, 8);
12825 __ Poke(x2, 16);
12826 __ Poke(x3, 24);
12827 Clobber(&masm, x0_to_x3);
12828 __ Peek(x0, 0);
12829 __ Peek(x1, 8);
12830 __ Peek(x2, 16);
12831 __ Peek(x3, 24);
12832
12833 __ Poke(w0, 0);
12834 __ Poke(w1, 4);
12835 __ Poke(w2, 8);
12836 __ Poke(w3, 12);
12837 Clobber(&masm, x10_to_x13);
12838 __ Peek(w10, 0);
12839 __ Peek(w11, 4);
12840 __ Peek(w12, 8);
12841 __ Peek(w13, 12);
12842
12843 __ Drop(32);
12844
12845 END();
12846 RUN();
12847
12848 ASSERT_EQUAL_64(literal_base * 1, x0);
12849 ASSERT_EQUAL_64(literal_base * 2, x1);
12850 ASSERT_EQUAL_64(literal_base * 3, x2);
12851 ASSERT_EQUAL_64(literal_base * 4, x3);
12852
12853 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
12854 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
12855 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
12856 ASSERT_EQUAL_64((literal_base * 4) & 0xffffffff, x13);
12857
12858 TEARDOWN();
12859}
12860
12861
12862TEST(peek_poke_unaligned) {
12863 SETUP();
12864 START();
12865
12866 // The literal base is chosen to have two useful properties:
12867 // * When multiplied by small values (such as a register index), this value
12868 // is clearly readable in the result.
12869 // * The value is not formed from repeating fixed-size smaller values, so it
12870 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000012871 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012872
12873 // Initialize the registers.
12874 __ Mov(x0, literal_base);
12875 __ Add(x1, x0, x0);
12876 __ Add(x2, x1, x0);
12877 __ Add(x3, x2, x0);
12878 __ Add(x4, x3, x0);
12879 __ Add(x5, x4, x0);
12880 __ Add(x6, x5, x0);
12881
12882 __ Claim(32);
12883
12884 // Unaligned exchanges.
12885 // After this test:
12886 // x0-x6 should be unchanged.
12887 // w10-w12 should contain the lower words of x0-x2.
12888 __ Poke(x0, 1);
12889 Clobber(&masm, x0.Bit());
12890 __ Peek(x0, 1);
12891 __ Poke(x1, 2);
12892 Clobber(&masm, x1.Bit());
12893 __ Peek(x1, 2);
12894 __ Poke(x2, 3);
12895 Clobber(&masm, x2.Bit());
12896 __ Peek(x2, 3);
12897 __ Poke(x3, 4);
12898 Clobber(&masm, x3.Bit());
12899 __ Peek(x3, 4);
12900 __ Poke(x4, 5);
12901 Clobber(&masm, x4.Bit());
12902 __ Peek(x4, 5);
12903 __ Poke(x5, 6);
12904 Clobber(&masm, x5.Bit());
12905 __ Peek(x5, 6);
12906 __ Poke(x6, 7);
12907 Clobber(&masm, x6.Bit());
12908 __ Peek(x6, 7);
12909
12910 __ Poke(w0, 1);
12911 Clobber(&masm, w10.Bit());
12912 __ Peek(w10, 1);
12913 __ Poke(w1, 2);
12914 Clobber(&masm, w11.Bit());
12915 __ Peek(w11, 2);
12916 __ Poke(w2, 3);
12917 Clobber(&masm, w12.Bit());
12918 __ Peek(w12, 3);
12919
12920 __ Drop(32);
12921
12922 END();
12923 RUN();
12924
12925 ASSERT_EQUAL_64(literal_base * 1, x0);
12926 ASSERT_EQUAL_64(literal_base * 2, x1);
12927 ASSERT_EQUAL_64(literal_base * 3, x2);
12928 ASSERT_EQUAL_64(literal_base * 4, x3);
12929 ASSERT_EQUAL_64(literal_base * 5, x4);
12930 ASSERT_EQUAL_64(literal_base * 6, x5);
12931 ASSERT_EQUAL_64(literal_base * 7, x6);
12932
12933 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
12934 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
12935 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
12936
12937 TEARDOWN();
12938}
12939
12940
12941TEST(peek_poke_endianness) {
12942 SETUP();
12943 START();
12944
12945 // The literal base is chosen to have two useful properties:
12946 // * When multiplied by small values (such as a register index), this value
12947 // is clearly readable in the result.
12948 // * The value is not formed from repeating fixed-size smaller values, so it
12949 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000012950 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010012951
12952 // Initialize the registers.
12953 __ Mov(x0, literal_base);
12954 __ Add(x1, x0, x0);
12955
12956 __ Claim(32);
12957
12958 // Endianness tests.
12959 // After this section:
12960 // x4 should match x0[31:0]:x0[63:32]
12961 // w5 should match w1[15:0]:w1[31:16]
12962 __ Poke(x0, 0);
12963 __ Poke(x0, 8);
12964 __ Peek(x4, 4);
12965
12966 __ Poke(w1, 0);
12967 __ Poke(w1, 4);
12968 __ Peek(w5, 2);
12969
12970 __ Drop(32);
12971
12972 END();
12973 RUN();
12974
12975 uint64_t x0_expected = literal_base * 1;
12976 uint64_t x1_expected = literal_base * 2;
12977 uint64_t x4_expected = (x0_expected << 32) | (x0_expected >> 32);
12978 uint64_t x5_expected = ((x1_expected << 16) & 0xffff0000) |
12979 ((x1_expected >> 16) & 0x0000ffff);
12980
12981 ASSERT_EQUAL_64(x0_expected, x0);
12982 ASSERT_EQUAL_64(x1_expected, x1);
12983 ASSERT_EQUAL_64(x4_expected, x4);
12984 ASSERT_EQUAL_64(x5_expected, x5);
12985
12986 TEARDOWN();
12987}
12988
12989
12990TEST(peek_poke_mixed) {
12991 SETUP();
12992 START();
12993
armvixl6e2c8272015-03-31 11:04:14 +010012994 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
12995 UseScratchRegisterScope temps(&masm);
12996 temps.ExcludeAll();
12997
armvixlad96eda2013-06-14 11:42:37 +010012998 // The literal base is chosen to have two useful properties:
12999 // * When multiplied by small values (such as a register index), this value
13000 // is clearly readable in the result.
13001 // * The value is not formed from repeating fixed-size smaller values, so it
13002 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000013003 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013004
13005 // Initialize the registers.
13006 __ Mov(x0, literal_base);
13007 __ Add(x1, x0, x0);
13008 __ Add(x2, x1, x0);
13009 __ Add(x3, x2, x0);
13010
13011 __ Claim(32);
13012
13013 // Mix with other stack operations.
13014 // After this section:
13015 // x0-x3 should be unchanged.
13016 // x6 should match x1[31:0]:x0[63:32]
13017 // w7 should match x1[15:0]:x0[63:48]
13018 __ Poke(x1, 8);
13019 __ Poke(x0, 0);
13020 {
armvixlb0c8ae22014-03-21 14:03:59 +000013021 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013022 __ Mov(x4, __ StackPointer());
13023 __ SetStackPointer(x4);
13024
13025 __ Poke(wzr, 0); // Clobber the space we're about to drop.
13026 __ Drop(4);
13027 __ Peek(x6, 0);
13028 __ Claim(8);
13029 __ Peek(w7, 10);
13030 __ Poke(x3, 28);
13031 __ Poke(xzr, 0); // Clobber the space we're about to drop.
13032 __ Drop(8);
13033 __ Poke(x2, 12);
13034 __ Push(w0);
13035
13036 __ Mov(sp, __ StackPointer());
13037 __ SetStackPointer(sp);
13038 }
13039
13040 __ Pop(x0, x1, x2, x3);
13041
13042 END();
13043 RUN();
13044
13045 uint64_t x0_expected = literal_base * 1;
13046 uint64_t x1_expected = literal_base * 2;
13047 uint64_t x2_expected = literal_base * 3;
13048 uint64_t x3_expected = literal_base * 4;
13049 uint64_t x6_expected = (x1_expected << 32) | (x0_expected >> 32);
13050 uint64_t x7_expected = ((x1_expected << 16) & 0xffff0000) |
13051 ((x0_expected >> 48) & 0x0000ffff);
13052
13053 ASSERT_EQUAL_64(x0_expected, x0);
13054 ASSERT_EQUAL_64(x1_expected, x1);
13055 ASSERT_EQUAL_64(x2_expected, x2);
13056 ASSERT_EQUAL_64(x3_expected, x3);
13057 ASSERT_EQUAL_64(x6_expected, x6);
13058 ASSERT_EQUAL_64(x7_expected, x7);
13059
13060 TEARDOWN();
13061}
13062
13063
armvixlc68cb642014-09-25 18:49:30 +010013064TEST(peek_poke_reglist) {
13065 SETUP();
13066 START();
13067
armvixl6e2c8272015-03-31 11:04:14 +010013068 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13069 UseScratchRegisterScope temps(&masm);
13070 temps.ExcludeAll();
13071
armvixlc68cb642014-09-25 18:49:30 +010013072 // The literal base is chosen to have two useful properties:
13073 // * When multiplied by small values (such as a register index), this value
13074 // is clearly readable in the result.
13075 // * The value is not formed from repeating fixed-size smaller values, so it
13076 // can be used to detect endianness-related errors.
13077 uint64_t base = 0x0100001000100101;
13078
13079 // Initialize the registers.
13080 __ Mov(x1, base);
13081 __ Add(x2, x1, x1);
13082 __ Add(x3, x2, x1);
13083 __ Add(x4, x3, x1);
13084
13085 CPURegList list_1(x1, x2, x3, x4);
13086 CPURegList list_2(x11, x12, x13, x14);
13087 int list_1_size = list_1.TotalSizeInBytes();
13088
13089 __ Claim(2 * list_1_size);
13090
13091 __ PokeCPURegList(list_1, 0);
13092 __ PokeXRegList(list_1.list(), list_1_size);
13093 __ PeekCPURegList(list_2, 2 * kXRegSizeInBytes);
13094 __ PeekXRegList(x15.Bit(), kWRegSizeInBytes);
13095 __ PeekWRegList(w16.Bit() | w17.Bit(), 3 * kXRegSizeInBytes);
13096
13097 __ Drop(2 * list_1_size);
13098
13099
13100 uint64_t base_d = 0x1010010001000010;
13101
13102 // Initialize the registers.
13103 __ Mov(x1, base_d);
13104 __ Add(x2, x1, x1);
13105 __ Add(x3, x2, x1);
13106 __ Add(x4, x3, x1);
13107 __ Fmov(d1, x1);
13108 __ Fmov(d2, x2);
13109 __ Fmov(d3, x3);
13110 __ Fmov(d4, x4);
13111
13112 CPURegList list_d_1(d1, d2, d3, d4);
13113 CPURegList list_d_2(d11, d12, d13, d14);
13114 int list_d_1_size = list_d_1.TotalSizeInBytes();
13115
13116 __ Claim(2 * list_d_1_size);
13117
13118 __ PokeCPURegList(list_d_1, 0);
13119 __ PokeDRegList(list_d_1.list(), list_d_1_size);
13120 __ PeekCPURegList(list_d_2, 2 * kDRegSizeInBytes);
13121 __ PeekDRegList(d15.Bit(), kSRegSizeInBytes);
13122 __ PeekSRegList(s16.Bit() | s17.Bit(), 3 * kDRegSizeInBytes);
13123
13124 __ Drop(2 * list_d_1_size);
13125
13126
13127 END();
13128 RUN();
13129
13130 ASSERT_EQUAL_64(3 * base, x11);
13131 ASSERT_EQUAL_64(4 * base, x12);
13132 ASSERT_EQUAL_64(1 * base, x13);
13133 ASSERT_EQUAL_64(2 * base, x14);
13134 ASSERT_EQUAL_64(((1 * base) >> kWRegSize) | ((2 * base) << kWRegSize), x15);
13135 ASSERT_EQUAL_64(2 * base, x14);
13136 ASSERT_EQUAL_32((4 * base) & kWRegMask, w16);
13137 ASSERT_EQUAL_32((4 * base) >> kWRegSize, w17);
13138
13139 ASSERT_EQUAL_FP64(rawbits_to_double(3 * base_d), d11);
13140 ASSERT_EQUAL_FP64(rawbits_to_double(4 * base_d), d12);
13141 ASSERT_EQUAL_FP64(rawbits_to_double(1 * base_d), d13);
13142 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base_d), d14);
13143 ASSERT_EQUAL_FP64(
13144 rawbits_to_double((base_d >> kSRegSize) | ((2 * base_d) << kSRegSize)),
13145 d15);
13146 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base_d), d14);
13147 ASSERT_EQUAL_FP32(rawbits_to_float((4 * base_d) & kSRegMask), s16);
13148 ASSERT_EQUAL_FP32(rawbits_to_float((4 * base_d) >> kSRegSize), s17);
13149
13150 TEARDOWN();
13151}
13152
13153
armvixl6e2c8272015-03-31 11:04:14 +010013154TEST(load_store_reglist) {
13155 SETUP();
13156 START();
13157
13158 // The literal base is chosen to have two useful properties:
13159 // * When multiplied by small values (such as a register index), this value
13160 // is clearly readable in the result.
13161 // * The value is not formed from repeating fixed-size smaller values, so it
13162 // can be used to detect endianness-related errors.
13163 uint64_t high_base = UINT32_C(0x01000010);
13164 uint64_t low_base = UINT32_C(0x00100101);
13165 uint64_t base = (high_base << 32) | low_base;
13166 uint64_t array[21];
13167 memset(array, 0, sizeof(array));
13168
13169 // Initialize the registers.
13170 __ Mov(x1, base);
13171 __ Add(x2, x1, x1);
13172 __ Add(x3, x2, x1);
13173 __ Add(x4, x3, x1);
13174 __ Fmov(d1, x1);
13175 __ Fmov(d2, x2);
13176 __ Fmov(d3, x3);
13177 __ Fmov(d4, x4);
13178 __ Fmov(d5, x1);
13179 __ Fmov(d6, x2);
13180 __ Fmov(d7, x3);
13181 __ Fmov(d8, x4);
13182
13183 Register reg_base = x20;
13184 Register reg_index = x21;
13185 int size_stored = 0;
13186
13187 __ Mov(reg_base, reinterpret_cast<uintptr_t>(&array));
13188
13189 // Test aligned accesses.
13190 CPURegList list_src(w1, w2, w3, w4);
13191 CPURegList list_dst(w11, w12, w13, w14);
13192 CPURegList list_fp_src_1(d1, d2, d3, d4);
13193 CPURegList list_fp_dst_1(d11, d12, d13, d14);
13194
13195 __ StoreCPURegList(list_src, MemOperand(reg_base, 0 * sizeof(uint64_t)));
13196 __ LoadCPURegList(list_dst, MemOperand(reg_base, 0 * sizeof(uint64_t)));
13197 size_stored += 4 * kWRegSizeInBytes;
13198
13199 __ Mov(reg_index, size_stored);
13200 __ StoreCPURegList(list_src, MemOperand(reg_base, reg_index));
13201 __ LoadCPURegList(list_dst, MemOperand(reg_base, reg_index));
13202 size_stored += 4 * kWRegSizeInBytes;
13203
13204 __ StoreCPURegList(list_fp_src_1, MemOperand(reg_base, size_stored));
13205 __ LoadCPURegList(list_fp_dst_1, MemOperand(reg_base, size_stored));
13206 size_stored += 4 * kDRegSizeInBytes;
13207
13208 __ Mov(reg_index, size_stored);
13209 __ StoreCPURegList(list_fp_src_1, MemOperand(reg_base, reg_index));
13210 __ LoadCPURegList(list_fp_dst_1, MemOperand(reg_base, reg_index));
13211 size_stored += 4 * kDRegSizeInBytes;
13212
13213 // Test unaligned accesses.
13214 CPURegList list_fp_src_2(d5, d6, d7, d8);
13215 CPURegList list_fp_dst_2(d15, d16, d17, d18);
13216
13217 __ Str(wzr, MemOperand(reg_base, size_stored));
13218 size_stored += 1 * kWRegSizeInBytes;
13219 __ StoreCPURegList(list_fp_src_2, MemOperand(reg_base, size_stored));
13220 __ LoadCPURegList(list_fp_dst_2, MemOperand(reg_base, size_stored));
13221 size_stored += 4 * kDRegSizeInBytes;
13222
13223 __ Mov(reg_index, size_stored);
13224 __ StoreCPURegList(list_fp_src_2, MemOperand(reg_base, reg_index));
13225 __ LoadCPURegList(list_fp_dst_2, MemOperand(reg_base, reg_index));
13226
13227 END();
13228 RUN();
13229
13230 VIXL_CHECK(array[0] == (1 * low_base) + (2 * low_base << kWRegSize));
13231 VIXL_CHECK(array[1] == (3 * low_base) + (4 * low_base << kWRegSize));
13232 VIXL_CHECK(array[2] == (1 * low_base) + (2 * low_base << kWRegSize));
13233 VIXL_CHECK(array[3] == (3 * low_base) + (4 * low_base << kWRegSize));
13234 VIXL_CHECK(array[4] == 1 * base);
13235 VIXL_CHECK(array[5] == 2 * base);
13236 VIXL_CHECK(array[6] == 3 * base);
13237 VIXL_CHECK(array[7] == 4 * base);
13238 VIXL_CHECK(array[8] == 1 * base);
13239 VIXL_CHECK(array[9] == 2 * base);
13240 VIXL_CHECK(array[10] == 3 * base);
13241 VIXL_CHECK(array[11] == 4 * base);
13242 VIXL_CHECK(array[12] == ((1 * low_base) << kSRegSize));
13243 VIXL_CHECK(array[13] == (((2 * low_base) << kSRegSize) | (1 * high_base)));
13244 VIXL_CHECK(array[14] == (((3 * low_base) << kSRegSize) | (2 * high_base)));
13245 VIXL_CHECK(array[15] == (((4 * low_base) << kSRegSize) | (3 * high_base)));
13246 VIXL_CHECK(array[16] == (((1 * low_base) << kSRegSize) | (4 * high_base)));
13247 VIXL_CHECK(array[17] == (((2 * low_base) << kSRegSize) | (1 * high_base)));
13248 VIXL_CHECK(array[18] == (((3 * low_base) << kSRegSize) | (2 * high_base)));
13249 VIXL_CHECK(array[19] == (((4 * low_base) << kSRegSize) | (3 * high_base)));
13250 VIXL_CHECK(array[20] == (4 * high_base));
13251
13252 ASSERT_EQUAL_64(1 * low_base, x11);
13253 ASSERT_EQUAL_64(2 * low_base, x12);
13254 ASSERT_EQUAL_64(3 * low_base, x13);
13255 ASSERT_EQUAL_64(4 * low_base, x14);
13256 ASSERT_EQUAL_FP64(rawbits_to_double(1 * base), d11);
13257 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base), d12);
13258 ASSERT_EQUAL_FP64(rawbits_to_double(3 * base), d13);
13259 ASSERT_EQUAL_FP64(rawbits_to_double(4 * base), d14);
13260 ASSERT_EQUAL_FP64(rawbits_to_double(1 * base), d15);
13261 ASSERT_EQUAL_FP64(rawbits_to_double(2 * base), d16);
13262 ASSERT_EQUAL_FP64(rawbits_to_double(3 * base), d17);
13263 ASSERT_EQUAL_FP64(rawbits_to_double(4 * base), d18);
13264
13265 TEARDOWN();
13266}
13267
13268
armvixlad96eda2013-06-14 11:42:37 +010013269// This enum is used only as an argument to the push-pop test helpers.
13270enum PushPopMethod {
13271 // Push or Pop using the Push and Pop methods, with blocks of up to four
13272 // registers. (Smaller blocks will be used if necessary.)
13273 PushPopByFour,
13274
13275 // Use Push<Size>RegList and Pop<Size>RegList to transfer the registers.
13276 PushPopRegList
13277};
13278
13279
13280// The maximum number of registers that can be used by the PushPopXReg* tests,
13281// where a reg_count field is provided.
13282static int const kPushPopXRegMaxRegCount = -1;
13283
13284// Test a simple push-pop pattern:
13285// * Claim <claim> bytes to set the stack alignment.
13286// * Push <reg_count> registers with size <reg_size>.
13287// * Clobber the register contents.
13288// * Pop <reg_count> registers to restore the original contents.
13289// * Drop <claim> bytes to restore the original stack pointer.
13290//
13291// Different push and pop methods can be specified independently to test for
13292// proper word-endian behaviour.
13293static void PushPopXRegSimpleHelper(int reg_count,
13294 int claim,
13295 int reg_size,
13296 PushPopMethod push_method,
13297 PushPopMethod pop_method) {
13298 SETUP();
13299
13300 START();
13301
13302 // Arbitrarily pick a register to use as a stack pointer.
13303 const Register& stack_pointer = x20;
13304 const RegList allowed = ~stack_pointer.Bit();
13305 if (reg_count == kPushPopXRegMaxRegCount) {
13306 reg_count = CountSetBits(allowed, kNumberOfRegisters);
13307 }
13308 // Work out which registers to use, based on reg_size.
13309 Register r[kNumberOfRegisters];
13310 Register x[kNumberOfRegisters];
13311 RegList list = PopulateRegisterArray(NULL, x, r, reg_size, reg_count,
13312 allowed);
13313
armvixl6e2c8272015-03-31 11:04:14 +010013314 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13315 UseScratchRegisterScope temps(&masm);
13316 temps.ExcludeAll();
13317
armvixlad96eda2013-06-14 11:42:37 +010013318 // The literal base is chosen to have two useful properties:
13319 // * When multiplied by small values (such as a register index), this value
13320 // is clearly readable in the result.
13321 // * The value is not formed from repeating fixed-size smaller values, so it
13322 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000013323 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013324
13325 {
armvixlb0c8ae22014-03-21 14:03:59 +000013326 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013327 __ Mov(stack_pointer, __ StackPointer());
13328 __ SetStackPointer(stack_pointer);
13329
13330 int i;
13331
13332 // Initialize the registers.
13333 for (i = 0; i < reg_count; i++) {
13334 // Always write into the X register, to ensure that the upper word is
13335 // properly ignored by Push when testing W registers.
13336 __ Mov(x[i], literal_base * i);
13337 }
13338
13339 // Claim memory first, as requested.
13340 __ Claim(claim);
13341
13342 switch (push_method) {
13343 case PushPopByFour:
13344 // Push high-numbered registers first (to the highest addresses).
13345 for (i = reg_count; i >= 4; i -= 4) {
13346 __ Push(r[i-1], r[i-2], r[i-3], r[i-4]);
13347 }
13348 // Finish off the leftovers.
13349 switch (i) {
13350 case 3: __ Push(r[2], r[1], r[0]); break;
13351 case 2: __ Push(r[1], r[0]); break;
13352 case 1: __ Push(r[0]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013353 default: VIXL_ASSERT(i == 0); break;
armvixlad96eda2013-06-14 11:42:37 +010013354 }
13355 break;
13356 case PushPopRegList:
13357 __ PushSizeRegList(list, reg_size);
13358 break;
13359 }
13360
13361 // Clobber all the registers, to ensure that they get repopulated by Pop.
13362 Clobber(&masm, list);
13363
13364 switch (pop_method) {
13365 case PushPopByFour:
13366 // Pop low-numbered registers first (from the lowest addresses).
13367 for (i = 0; i <= (reg_count-4); i += 4) {
13368 __ Pop(r[i], r[i+1], r[i+2], r[i+3]);
13369 }
13370 // Finish off the leftovers.
13371 switch (reg_count - i) {
13372 case 3: __ Pop(r[i], r[i+1], r[i+2]); break;
13373 case 2: __ Pop(r[i], r[i+1]); break;
13374 case 1: __ Pop(r[i]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013375 default: VIXL_ASSERT(i == reg_count); break;
armvixlad96eda2013-06-14 11:42:37 +010013376 }
13377 break;
13378 case PushPopRegList:
13379 __ PopSizeRegList(list, reg_size);
13380 break;
13381 }
13382
13383 // Drop memory to restore stack_pointer.
13384 __ Drop(claim);
13385
13386 __ Mov(sp, __ StackPointer());
13387 __ SetStackPointer(sp);
13388 }
13389
13390 END();
13391
13392 RUN();
13393
13394 // Check that the register contents were preserved.
13395 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
13396 // that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +000013397 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +010013398 for (int i = 0; i < reg_count; i++) {
13399 if (x[i].Is(xzr)) {
13400 ASSERT_EQUAL_64(0, x[i]);
13401 } else {
13402 ASSERT_EQUAL_64(literal_base * i, x[i]);
13403 }
13404 }
13405
13406 TEARDOWN();
13407}
13408
13409
13410TEST(push_pop_xreg_simple_32) {
13411 for (int claim = 0; claim <= 8; claim++) {
13412 for (int count = 0; count <= 8; count++) {
13413 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13414 PushPopByFour, PushPopByFour);
13415 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13416 PushPopByFour, PushPopRegList);
13417 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13418 PushPopRegList, PushPopByFour);
13419 PushPopXRegSimpleHelper(count, claim, kWRegSize,
13420 PushPopRegList, PushPopRegList);
13421 }
13422 // Test with the maximum number of registers.
13423 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13424 claim, kWRegSize, PushPopByFour, PushPopByFour);
13425 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13426 claim, kWRegSize, PushPopByFour, PushPopRegList);
13427 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13428 claim, kWRegSize, PushPopRegList, PushPopByFour);
13429 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13430 claim, kWRegSize, PushPopRegList, PushPopRegList);
13431 }
13432}
13433
13434
13435TEST(push_pop_xreg_simple_64) {
13436 for (int claim = 0; claim <= 8; claim++) {
13437 for (int count = 0; count <= 8; count++) {
13438 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13439 PushPopByFour, PushPopByFour);
13440 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13441 PushPopByFour, PushPopRegList);
13442 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13443 PushPopRegList, PushPopByFour);
13444 PushPopXRegSimpleHelper(count, claim, kXRegSize,
13445 PushPopRegList, PushPopRegList);
13446 }
13447 // Test with the maximum number of registers.
13448 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13449 claim, kXRegSize, PushPopByFour, PushPopByFour);
13450 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13451 claim, kXRegSize, PushPopByFour, PushPopRegList);
13452 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13453 claim, kXRegSize, PushPopRegList, PushPopByFour);
13454 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
13455 claim, kXRegSize, PushPopRegList, PushPopRegList);
13456 }
13457}
13458
13459
13460// The maximum number of registers that can be used by the PushPopFPXReg* tests,
13461// where a reg_count field is provided.
13462static int const kPushPopFPXRegMaxRegCount = -1;
13463
13464// Test a simple push-pop pattern:
13465// * Claim <claim> bytes to set the stack alignment.
13466// * Push <reg_count> FP registers with size <reg_size>.
13467// * Clobber the register contents.
13468// * Pop <reg_count> FP registers to restore the original contents.
13469// * Drop <claim> bytes to restore the original stack pointer.
13470//
13471// Different push and pop methods can be specified independently to test for
13472// proper word-endian behaviour.
13473static void PushPopFPXRegSimpleHelper(int reg_count,
13474 int claim,
13475 int reg_size,
13476 PushPopMethod push_method,
13477 PushPopMethod pop_method) {
13478 SETUP();
13479
13480 START();
13481
13482 // We can use any floating-point register. None of them are reserved for
13483 // debug code, for example.
13484 static RegList const allowed = ~0;
13485 if (reg_count == kPushPopFPXRegMaxRegCount) {
13486 reg_count = CountSetBits(allowed, kNumberOfFPRegisters);
13487 }
13488 // Work out which registers to use, based on reg_size.
13489 FPRegister v[kNumberOfRegisters];
13490 FPRegister d[kNumberOfRegisters];
13491 RegList list = PopulateFPRegisterArray(NULL, d, v, reg_size, reg_count,
13492 allowed);
13493
13494 // Arbitrarily pick a register to use as a stack pointer.
13495 const Register& stack_pointer = x10;
13496
armvixl6e2c8272015-03-31 11:04:14 +010013497 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13498 UseScratchRegisterScope temps(&masm);
13499 temps.ExcludeAll();
13500
armvixlad96eda2013-06-14 11:42:37 +010013501 // The literal base is chosen to have two useful properties:
13502 // * When multiplied (using an integer) by small values (such as a register
13503 // index), this value is clearly readable in the result.
13504 // * The value is not formed from repeating fixed-size smaller values, so it
13505 // can be used to detect endianness-related errors.
13506 // * It is never a floating-point NaN, and will therefore always compare
13507 // equal to itself.
armvixlb0c8ae22014-03-21 14:03:59 +000013508 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013509
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 int i;
13516
13517 // Initialize the registers, using X registers to load the literal.
13518 __ Mov(x0, 0);
13519 __ Mov(x1, literal_base);
13520 for (i = 0; i < reg_count; i++) {
13521 // Always write into the D register, to ensure that the upper word is
13522 // properly ignored by Push when testing S registers.
13523 __ Fmov(d[i], x0);
13524 // Calculate the next literal.
13525 __ Add(x0, x0, x1);
13526 }
13527
13528 // Claim memory first, as requested.
13529 __ Claim(claim);
13530
13531 switch (push_method) {
13532 case PushPopByFour:
13533 // Push high-numbered registers first (to the highest addresses).
13534 for (i = reg_count; i >= 4; i -= 4) {
13535 __ Push(v[i-1], v[i-2], v[i-3], v[i-4]);
13536 }
13537 // Finish off the leftovers.
13538 switch (i) {
13539 case 3: __ Push(v[2], v[1], v[0]); break;
13540 case 2: __ Push(v[1], v[0]); break;
13541 case 1: __ Push(v[0]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013542 default: VIXL_ASSERT(i == 0); break;
armvixlad96eda2013-06-14 11:42:37 +010013543 }
13544 break;
13545 case PushPopRegList:
armvixl5289c592015-03-02 13:52:04 +000013546 __ PushSizeRegList(list, reg_size, CPURegister::kVRegister);
armvixlad96eda2013-06-14 11:42:37 +010013547 break;
13548 }
13549
13550 // Clobber all the registers, to ensure that they get repopulated by Pop.
13551 ClobberFP(&masm, list);
13552
13553 switch (pop_method) {
13554 case PushPopByFour:
13555 // Pop low-numbered registers first (from the lowest addresses).
13556 for (i = 0; i <= (reg_count-4); i += 4) {
13557 __ Pop(v[i], v[i+1], v[i+2], v[i+3]);
13558 }
13559 // Finish off the leftovers.
13560 switch (reg_count - i) {
13561 case 3: __ Pop(v[i], v[i+1], v[i+2]); break;
13562 case 2: __ Pop(v[i], v[i+1]); break;
13563 case 1: __ Pop(v[i]); break;
armvixlb0c8ae22014-03-21 14:03:59 +000013564 default: VIXL_ASSERT(i == reg_count); break;
armvixlad96eda2013-06-14 11:42:37 +010013565 }
13566 break;
13567 case PushPopRegList:
armvixl5289c592015-03-02 13:52:04 +000013568 __ PopSizeRegList(list, reg_size, CPURegister::kVRegister);
armvixlad96eda2013-06-14 11:42:37 +010013569 break;
13570 }
13571
13572 // Drop memory to restore the stack pointer.
13573 __ Drop(claim);
13574
13575 __ Mov(sp, __ StackPointer());
13576 __ SetStackPointer(sp);
13577 }
13578
13579 END();
13580
13581 RUN();
13582
13583 // Check that the register contents were preserved.
13584 // Always use ASSERT_EQUAL_FP64, even when testing S registers, so we can
13585 // test that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +000013586 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +010013587 for (int i = 0; i < reg_count; i++) {
13588 uint64_t literal = literal_base * i;
13589 double expected;
13590 memcpy(&expected, &literal, sizeof(expected));
13591 ASSERT_EQUAL_FP64(expected, d[i]);
13592 }
13593
13594 TEARDOWN();
13595}
13596
13597
13598TEST(push_pop_fp_xreg_simple_32) {
13599 for (int claim = 0; claim <= 8; claim++) {
13600 for (int count = 0; count <= 8; count++) {
13601 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13602 PushPopByFour, PushPopByFour);
13603 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13604 PushPopByFour, PushPopRegList);
13605 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13606 PushPopRegList, PushPopByFour);
13607 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
13608 PushPopRegList, PushPopRegList);
13609 }
13610 // Test with the maximum number of registers.
13611 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13612 PushPopByFour, PushPopByFour);
13613 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13614 PushPopByFour, PushPopRegList);
13615 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13616 PushPopRegList, PushPopByFour);
13617 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
13618 PushPopRegList, PushPopRegList);
13619 }
13620}
13621
13622
13623TEST(push_pop_fp_xreg_simple_64) {
13624 for (int claim = 0; claim <= 8; claim++) {
13625 for (int count = 0; count <= 8; count++) {
13626 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13627 PushPopByFour, PushPopByFour);
13628 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13629 PushPopByFour, PushPopRegList);
13630 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13631 PushPopRegList, PushPopByFour);
13632 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
13633 PushPopRegList, PushPopRegList);
13634 }
13635 // Test with the maximum number of registers.
13636 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13637 PushPopByFour, PushPopByFour);
13638 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13639 PushPopByFour, PushPopRegList);
13640 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13641 PushPopRegList, PushPopByFour);
13642 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
13643 PushPopRegList, PushPopRegList);
13644 }
13645}
13646
13647
13648// Push and pop data using an overlapping combination of Push/Pop and
13649// RegList-based methods.
13650static void PushPopXRegMixedMethodsHelper(int claim, int reg_size) {
13651 SETUP();
13652
13653 // Arbitrarily pick a register to use as a stack pointer.
13654 const Register& stack_pointer = x5;
13655 const RegList allowed = ~stack_pointer.Bit();
13656 // Work out which registers to use, based on reg_size.
13657 Register r[10];
13658 Register x[10];
13659 PopulateRegisterArray(NULL, x, r, reg_size, 10, allowed);
13660
13661 // Calculate some handy register lists.
13662 RegList r0_to_r3 = 0;
13663 for (int i = 0; i <= 3; i++) {
13664 r0_to_r3 |= x[i].Bit();
13665 }
13666 RegList r4_to_r5 = 0;
13667 for (int i = 4; i <= 5; i++) {
13668 r4_to_r5 |= x[i].Bit();
13669 }
13670 RegList r6_to_r9 = 0;
13671 for (int i = 6; i <= 9; i++) {
13672 r6_to_r9 |= x[i].Bit();
13673 }
13674
armvixl6e2c8272015-03-31 11:04:14 +010013675 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13676 UseScratchRegisterScope temps(&masm);
13677 temps.ExcludeAll();
13678
armvixlad96eda2013-06-14 11:42:37 +010013679 // The literal base is chosen to have two useful properties:
13680 // * When multiplied by small values (such as a register index), this value
13681 // is clearly readable in the result.
13682 // * The value is not formed from repeating fixed-size smaller values, so it
13683 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000013684 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013685
13686 START();
13687 {
armvixlb0c8ae22014-03-21 14:03:59 +000013688 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013689 __ Mov(stack_pointer, __ StackPointer());
13690 __ SetStackPointer(stack_pointer);
13691
13692 // Claim memory first, as requested.
13693 __ Claim(claim);
13694
13695 __ Mov(x[3], literal_base * 3);
13696 __ Mov(x[2], literal_base * 2);
13697 __ Mov(x[1], literal_base * 1);
13698 __ Mov(x[0], literal_base * 0);
13699
13700 __ PushSizeRegList(r0_to_r3, reg_size);
13701 __ Push(r[3], r[2]);
13702
13703 Clobber(&masm, r0_to_r3);
13704 __ PopSizeRegList(r0_to_r3, reg_size);
13705
13706 __ Push(r[2], r[1], r[3], r[0]);
13707
13708 Clobber(&masm, r4_to_r5);
13709 __ Pop(r[4], r[5]);
13710 Clobber(&masm, r6_to_r9);
13711 __ Pop(r[6], r[7], r[8], r[9]);
13712
13713 // Drop memory to restore stack_pointer.
13714 __ Drop(claim);
13715
13716 __ Mov(sp, __ StackPointer());
13717 __ SetStackPointer(sp);
13718 }
13719
13720 END();
13721
13722 RUN();
13723
13724 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
13725 // that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +000013726 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +010013727
13728 ASSERT_EQUAL_64(literal_base * 3, x[9]);
13729 ASSERT_EQUAL_64(literal_base * 2, x[8]);
13730 ASSERT_EQUAL_64(literal_base * 0, x[7]);
13731 ASSERT_EQUAL_64(literal_base * 3, x[6]);
13732 ASSERT_EQUAL_64(literal_base * 1, x[5]);
13733 ASSERT_EQUAL_64(literal_base * 2, x[4]);
13734
13735 TEARDOWN();
13736}
13737
13738
13739TEST(push_pop_xreg_mixed_methods_64) {
13740 for (int claim = 0; claim <= 8; claim++) {
13741 PushPopXRegMixedMethodsHelper(claim, kXRegSize);
13742 }
13743}
13744
13745
13746TEST(push_pop_xreg_mixed_methods_32) {
13747 for (int claim = 0; claim <= 8; claim++) {
13748 PushPopXRegMixedMethodsHelper(claim, kWRegSize);
13749 }
13750}
13751
13752
13753// Push and pop data using overlapping X- and W-sized quantities.
13754static void PushPopXRegWXOverlapHelper(int reg_count, int claim) {
13755 SETUP();
13756
13757 // Arbitrarily pick a register to use as a stack pointer.
13758 const Register& stack_pointer = x10;
13759 const RegList allowed = ~stack_pointer.Bit();
13760 if (reg_count == kPushPopXRegMaxRegCount) {
13761 reg_count = CountSetBits(allowed, kNumberOfRegisters);
13762 }
13763 // Work out which registers to use, based on reg_size.
13764 Register w[kNumberOfRegisters];
13765 Register x[kNumberOfRegisters];
13766 RegList list = PopulateRegisterArray(w, x, NULL, 0, reg_count, allowed);
13767
13768 // The number of W-sized slots we expect to pop. When we pop, we alternate
13769 // between W and X registers, so we need reg_count*1.5 W-sized slots.
13770 int const requested_w_slots = reg_count + reg_count / 2;
13771
13772 // Track what _should_ be on the stack, using W-sized slots.
13773 static int const kMaxWSlots = kNumberOfRegisters + kNumberOfRegisters / 2;
13774 uint32_t stack[kMaxWSlots];
13775 for (int i = 0; i < kMaxWSlots; i++) {
13776 stack[i] = 0xdeadbeef;
13777 }
13778
armvixl6e2c8272015-03-31 11:04:14 +010013779 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13780 UseScratchRegisterScope temps(&masm);
13781 temps.ExcludeAll();
13782
armvixlad96eda2013-06-14 11:42:37 +010013783 // The literal base is chosen to have two useful properties:
13784 // * When multiplied by small values (such as a register index), this value
13785 // is clearly readable in the result.
13786 // * The value is not formed from repeating fixed-size smaller values, so it
13787 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +000013788 static uint64_t const literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +010013789 static uint64_t const literal_base_hi = literal_base >> 32;
13790 static uint64_t const literal_base_lo = literal_base & 0xffffffff;
13791 static uint64_t const literal_base_w = literal_base & 0xffffffff;
13792
13793 START();
13794 {
armvixlb0c8ae22014-03-21 14:03:59 +000013795 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +010013796 __ Mov(stack_pointer, __ StackPointer());
13797 __ SetStackPointer(stack_pointer);
13798
13799 // Initialize the registers.
13800 for (int i = 0; i < reg_count; i++) {
13801 // Always write into the X register, to ensure that the upper word is
13802 // properly ignored by Push when testing W registers.
13803 __ Mov(x[i], literal_base * i);
13804 }
13805
13806 // Claim memory first, as requested.
13807 __ Claim(claim);
13808
13809 // The push-pop pattern is as follows:
13810 // Push: Pop:
13811 // x[0](hi) -> w[0]
13812 // x[0](lo) -> x[1](hi)
13813 // w[1] -> x[1](lo)
13814 // w[1] -> w[2]
13815 // x[2](hi) -> x[2](hi)
13816 // x[2](lo) -> x[2](lo)
13817 // x[2](hi) -> w[3]
13818 // x[2](lo) -> x[4](hi)
13819 // x[2](hi) -> x[4](lo)
13820 // x[2](lo) -> w[5]
13821 // w[3] -> x[5](hi)
13822 // w[3] -> x[6](lo)
13823 // w[3] -> w[7]
13824 // w[3] -> x[8](hi)
13825 // x[4](hi) -> x[8](lo)
13826 // x[4](lo) -> w[9]
13827 // ... pattern continues ...
13828 //
13829 // That is, registers are pushed starting with the lower numbers,
13830 // alternating between x and w registers, and pushing i%4+1 copies of each,
13831 // where i is the register number.
13832 // Registers are popped starting with the higher numbers one-by-one,
13833 // alternating between x and w registers, but only popping one at a time.
13834 //
13835 // This pattern provides a wide variety of alignment effects and overlaps.
13836
13837 // ---- Push ----
13838
13839 int active_w_slots = 0;
13840 for (int i = 0; active_w_slots < requested_w_slots; i++) {
armvixlb0c8ae22014-03-21 14:03:59 +000013841 VIXL_ASSERT(i < reg_count);
armvixlad96eda2013-06-14 11:42:37 +010013842 // In order to test various arguments to PushMultipleTimes, and to try to
13843 // exercise different alignment and overlap effects, we push each
13844 // register a different number of times.
13845 int times = i % 4 + 1;
13846 if (i & 1) {
13847 // Push odd-numbered registers as W registers.
13848 __ PushMultipleTimes(times, w[i]);
13849 // Fill in the expected stack slots.
13850 for (int j = 0; j < times; j++) {
13851 if (w[i].Is(wzr)) {
13852 // The zero register always writes zeroes.
13853 stack[active_w_slots++] = 0;
13854 } else {
13855 stack[active_w_slots++] = literal_base_w * i;
13856 }
13857 }
13858 } else {
13859 // Push even-numbered registers as X registers.
13860 __ PushMultipleTimes(times, x[i]);
13861 // Fill in the expected stack slots.
13862 for (int j = 0; j < times; j++) {
13863 if (x[i].Is(xzr)) {
13864 // The zero register always writes zeroes.
13865 stack[active_w_slots++] = 0;
13866 stack[active_w_slots++] = 0;
13867 } else {
13868 stack[active_w_slots++] = literal_base_hi * i;
13869 stack[active_w_slots++] = literal_base_lo * i;
13870 }
13871 }
13872 }
13873 }
13874 // Because we were pushing several registers at a time, we probably pushed
13875 // more than we needed to.
13876 if (active_w_slots > requested_w_slots) {
13877 __ Drop((active_w_slots - requested_w_slots) * kWRegSizeInBytes);
13878 // Bump the number of active W-sized slots back to where it should be,
13879 // and fill the empty space with a dummy value.
13880 do {
13881 stack[active_w_slots--] = 0xdeadbeef;
13882 } while (active_w_slots > requested_w_slots);
13883 }
13884
13885 // ---- Pop ----
13886
13887 Clobber(&masm, list);
13888
13889 // If popping an even number of registers, the first one will be X-sized.
13890 // Otherwise, the first one will be W-sized.
13891 bool next_is_64 = !(reg_count & 1);
13892 for (int i = reg_count-1; i >= 0; i--) {
13893 if (next_is_64) {
13894 __ Pop(x[i]);
13895 active_w_slots -= 2;
13896 } else {
13897 __ Pop(w[i]);
13898 active_w_slots -= 1;
13899 }
13900 next_is_64 = !next_is_64;
13901 }
armvixlb0c8ae22014-03-21 14:03:59 +000013902 VIXL_ASSERT(active_w_slots == 0);
armvixlad96eda2013-06-14 11:42:37 +010013903
13904 // Drop memory to restore stack_pointer.
13905 __ Drop(claim);
13906
13907 __ Mov(sp, __ StackPointer());
13908 __ SetStackPointer(sp);
13909 }
13910
13911 END();
13912
13913 RUN();
13914
13915 int slot = 0;
13916 for (int i = 0; i < reg_count; i++) {
13917 // Even-numbered registers were written as W registers.
13918 // Odd-numbered registers were written as X registers.
13919 bool expect_64 = (i & 1);
13920 uint64_t expected;
13921
13922 if (expect_64) {
13923 uint64_t hi = stack[slot++];
13924 uint64_t lo = stack[slot++];
13925 expected = (hi << 32) | lo;
13926 } else {
13927 expected = stack[slot++];
13928 }
13929
13930 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can
13931 // test that the upper word was properly cleared by Pop.
13932 if (x[i].Is(xzr)) {
13933 ASSERT_EQUAL_64(0, x[i]);
13934 } else {
13935 ASSERT_EQUAL_64(expected, x[i]);
13936 }
13937 }
armvixlb0c8ae22014-03-21 14:03:59 +000013938 VIXL_ASSERT(slot == requested_w_slots);
armvixlad96eda2013-06-14 11:42:37 +010013939
13940 TEARDOWN();
13941}
13942
13943
13944TEST(push_pop_xreg_wx_overlap) {
13945 for (int claim = 0; claim <= 8; claim++) {
13946 for (int count = 1; count <= 8; count++) {
13947 PushPopXRegWXOverlapHelper(count, claim);
13948 }
13949 // Test with the maximum number of registers.
13950 PushPopXRegWXOverlapHelper(kPushPopXRegMaxRegCount, claim);
13951 }
13952}
13953
13954
13955TEST(push_pop_sp) {
13956 SETUP();
13957
13958 START();
13959
armvixlb0c8ae22014-03-21 14:03:59 +000013960 VIXL_ASSERT(sp.Is(__ StackPointer()));
armvixlad96eda2013-06-14 11:42:37 +010013961
armvixl6e2c8272015-03-31 11:04:14 +010013962 // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
13963 UseScratchRegisterScope temps(&masm);
13964 temps.ExcludeAll();
13965
armvixlb0c8ae22014-03-21 14:03:59 +000013966 __ Mov(x3, 0x3333333333333333);
13967 __ Mov(x2, 0x2222222222222222);
13968 __ Mov(x1, 0x1111111111111111);
13969 __ Mov(x0, 0x0000000000000000);
armvixlad96eda2013-06-14 11:42:37 +010013970 __ Claim(2 * kXRegSizeInBytes);
13971 __ PushXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
13972 __ Push(x3, x2);
13973 __ PopXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
13974 __ Push(x2, x1, x3, x0);
13975 __ Pop(x4, x5);
13976 __ Pop(x6, x7, x8, x9);
13977
13978 __ Claim(2 * kXRegSizeInBytes);
13979 __ PushWRegList(w0.Bit() | w1.Bit() | w2.Bit() | w3.Bit());
13980 __ Push(w3, w1, w2, w0);
13981 __ PopWRegList(w10.Bit() | w11.Bit() | w12.Bit() | w13.Bit());
13982 __ Pop(w14, w15, w16, w17);
13983
13984 __ Claim(2 * kXRegSizeInBytes);
13985 __ Push(w2, w2, w1, w1);
13986 __ Push(x3, x3);
13987 __ Pop(w18, w19, w20, w21);
13988 __ Pop(x22, x23);
13989
13990 __ Claim(2 * kXRegSizeInBytes);
13991 __ PushXRegList(x1.Bit() | x22.Bit());
13992 __ PopXRegList(x24.Bit() | x26.Bit());
13993
13994 __ Claim(2 * kXRegSizeInBytes);
13995 __ PushWRegList(w1.Bit() | w2.Bit() | w4.Bit() | w22.Bit());
13996 __ PopWRegList(w25.Bit() | w27.Bit() | w28.Bit() | w29.Bit());
13997
13998 __ Claim(2 * kXRegSizeInBytes);
13999 __ PushXRegList(0);
14000 __ PopXRegList(0);
14001 __ PushXRegList(0xffffffff);
14002 __ PopXRegList(0xffffffff);
14003 __ Drop(12 * kXRegSizeInBytes);
14004 END();
14005
14006 RUN();
14007
armvixlb0c8ae22014-03-21 14:03:59 +000014008 ASSERT_EQUAL_64(0x1111111111111111, x3);
14009 ASSERT_EQUAL_64(0x0000000000000000, x2);
14010 ASSERT_EQUAL_64(0x3333333333333333, x1);
14011 ASSERT_EQUAL_64(0x2222222222222222, x0);
14012 ASSERT_EQUAL_64(0x3333333333333333, x9);
14013 ASSERT_EQUAL_64(0x2222222222222222, x8);
14014 ASSERT_EQUAL_64(0x0000000000000000, x7);
14015 ASSERT_EQUAL_64(0x3333333333333333, x6);
14016 ASSERT_EQUAL_64(0x1111111111111111, x5);
14017 ASSERT_EQUAL_64(0x2222222222222222, x4);
armvixlad96eda2013-06-14 11:42:37 +010014018
14019 ASSERT_EQUAL_32(0x11111111U, w13);
14020 ASSERT_EQUAL_32(0x33333333U, w12);
14021 ASSERT_EQUAL_32(0x00000000U, w11);
14022 ASSERT_EQUAL_32(0x22222222U, w10);
14023 ASSERT_EQUAL_32(0x11111111U, w17);
14024 ASSERT_EQUAL_32(0x00000000U, w16);
14025 ASSERT_EQUAL_32(0x33333333U, w15);
14026 ASSERT_EQUAL_32(0x22222222U, w14);
14027
14028 ASSERT_EQUAL_32(0x11111111U, w18);
14029 ASSERT_EQUAL_32(0x11111111U, w19);
14030 ASSERT_EQUAL_32(0x11111111U, w20);
14031 ASSERT_EQUAL_32(0x11111111U, w21);
armvixlb0c8ae22014-03-21 14:03:59 +000014032 ASSERT_EQUAL_64(0x3333333333333333, x22);
14033 ASSERT_EQUAL_64(0x0000000000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +010014034
armvixlb0c8ae22014-03-21 14:03:59 +000014035 ASSERT_EQUAL_64(0x3333333333333333, x24);
14036 ASSERT_EQUAL_64(0x3333333333333333, x26);
armvixlad96eda2013-06-14 11:42:37 +010014037
14038 ASSERT_EQUAL_32(0x33333333U, w25);
14039 ASSERT_EQUAL_32(0x00000000U, w27);
14040 ASSERT_EQUAL_32(0x22222222U, w28);
14041 ASSERT_EQUAL_32(0x33333333U, w29);
14042 TEARDOWN();
14043}
14044
14045
14046TEST(noreg) {
14047 // This test doesn't generate any code, but it verifies some invariants
14048 // related to NoReg.
armvixlb0c8ae22014-03-21 14:03:59 +000014049 VIXL_CHECK(NoReg.Is(NoFPReg));
14050 VIXL_CHECK(NoFPReg.Is(NoReg));
armvixl5289c592015-03-02 13:52:04 +000014051
14052 VIXL_CHECK(NoVReg.Is(NoReg));
14053 VIXL_CHECK(NoReg.Is(NoVReg));
14054
armvixlb0c8ae22014-03-21 14:03:59 +000014055 VIXL_CHECK(NoReg.Is(NoCPUReg));
14056 VIXL_CHECK(NoCPUReg.Is(NoReg));
armvixl5289c592015-03-02 13:52:04 +000014057
armvixlb0c8ae22014-03-21 14:03:59 +000014058 VIXL_CHECK(NoFPReg.Is(NoCPUReg));
14059 VIXL_CHECK(NoCPUReg.Is(NoFPReg));
armvixlad96eda2013-06-14 11:42:37 +010014060
armvixl5289c592015-03-02 13:52:04 +000014061 VIXL_CHECK(NoVReg.Is(NoCPUReg));
14062 VIXL_CHECK(NoCPUReg.Is(NoVReg));
14063
armvixlb0c8ae22014-03-21 14:03:59 +000014064 VIXL_CHECK(NoReg.IsNone());
14065 VIXL_CHECK(NoFPReg.IsNone());
armvixl5289c592015-03-02 13:52:04 +000014066 VIXL_CHECK(NoVReg.IsNone());
armvixlb0c8ae22014-03-21 14:03:59 +000014067 VIXL_CHECK(NoCPUReg.IsNone());
armvixlad96eda2013-06-14 11:42:37 +010014068}
14069
14070
14071TEST(isvalid) {
14072 // This test doesn't generate any code, but it verifies some invariants
14073 // related to IsValid().
armvixlb0c8ae22014-03-21 14:03:59 +000014074 VIXL_CHECK(!NoReg.IsValid());
14075 VIXL_CHECK(!NoFPReg.IsValid());
armvixl5289c592015-03-02 13:52:04 +000014076 VIXL_CHECK(!NoVReg.IsValid());
armvixlb0c8ae22014-03-21 14:03:59 +000014077 VIXL_CHECK(!NoCPUReg.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010014078
armvixlb0c8ae22014-03-21 14:03:59 +000014079 VIXL_CHECK(x0.IsValid());
14080 VIXL_CHECK(w0.IsValid());
14081 VIXL_CHECK(x30.IsValid());
14082 VIXL_CHECK(w30.IsValid());
14083 VIXL_CHECK(xzr.IsValid());
14084 VIXL_CHECK(wzr.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010014085
armvixlb0c8ae22014-03-21 14:03:59 +000014086 VIXL_CHECK(sp.IsValid());
14087 VIXL_CHECK(wsp.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010014088
armvixlb0c8ae22014-03-21 14:03:59 +000014089 VIXL_CHECK(d0.IsValid());
14090 VIXL_CHECK(s0.IsValid());
14091 VIXL_CHECK(d31.IsValid());
14092 VIXL_CHECK(s31.IsValid());
armvixlad96eda2013-06-14 11:42:37 +010014093
armvixlb0c8ae22014-03-21 14:03:59 +000014094 VIXL_CHECK(x0.IsValidRegister());
14095 VIXL_CHECK(w0.IsValidRegister());
14096 VIXL_CHECK(xzr.IsValidRegister());
14097 VIXL_CHECK(wzr.IsValidRegister());
14098 VIXL_CHECK(sp.IsValidRegister());
14099 VIXL_CHECK(wsp.IsValidRegister());
14100 VIXL_CHECK(!x0.IsValidFPRegister());
14101 VIXL_CHECK(!w0.IsValidFPRegister());
14102 VIXL_CHECK(!xzr.IsValidFPRegister());
14103 VIXL_CHECK(!wzr.IsValidFPRegister());
14104 VIXL_CHECK(!sp.IsValidFPRegister());
14105 VIXL_CHECK(!wsp.IsValidFPRegister());
armvixlad96eda2013-06-14 11:42:37 +010014106
armvixlb0c8ae22014-03-21 14:03:59 +000014107 VIXL_CHECK(d0.IsValidFPRegister());
14108 VIXL_CHECK(s0.IsValidFPRegister());
14109 VIXL_CHECK(!d0.IsValidRegister());
14110 VIXL_CHECK(!s0.IsValidRegister());
armvixlad96eda2013-06-14 11:42:37 +010014111
14112 // Test the same as before, but using CPURegister types. This shouldn't make
14113 // any difference.
armvixlb0c8ae22014-03-21 14:03:59 +000014114 VIXL_CHECK(static_cast<CPURegister>(x0).IsValid());
14115 VIXL_CHECK(static_cast<CPURegister>(w0).IsValid());
14116 VIXL_CHECK(static_cast<CPURegister>(x30).IsValid());
14117 VIXL_CHECK(static_cast<CPURegister>(w30).IsValid());
14118 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValid());
14119 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValid());
armvixlad96eda2013-06-14 11:42:37 +010014120
armvixlb0c8ae22014-03-21 14:03:59 +000014121 VIXL_CHECK(static_cast<CPURegister>(sp).IsValid());
14122 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValid());
armvixlad96eda2013-06-14 11:42:37 +010014123
armvixlb0c8ae22014-03-21 14:03:59 +000014124 VIXL_CHECK(static_cast<CPURegister>(d0).IsValid());
14125 VIXL_CHECK(static_cast<CPURegister>(s0).IsValid());
14126 VIXL_CHECK(static_cast<CPURegister>(d31).IsValid());
14127 VIXL_CHECK(static_cast<CPURegister>(s31).IsValid());
armvixlad96eda2013-06-14 11:42:37 +010014128
armvixlb0c8ae22014-03-21 14:03:59 +000014129 VIXL_CHECK(static_cast<CPURegister>(x0).IsValidRegister());
14130 VIXL_CHECK(static_cast<CPURegister>(w0).IsValidRegister());
14131 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValidRegister());
14132 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValidRegister());
14133 VIXL_CHECK(static_cast<CPURegister>(sp).IsValidRegister());
14134 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValidRegister());
14135 VIXL_CHECK(!static_cast<CPURegister>(x0).IsValidFPRegister());
14136 VIXL_CHECK(!static_cast<CPURegister>(w0).IsValidFPRegister());
14137 VIXL_CHECK(!static_cast<CPURegister>(xzr).IsValidFPRegister());
14138 VIXL_CHECK(!static_cast<CPURegister>(wzr).IsValidFPRegister());
14139 VIXL_CHECK(!static_cast<CPURegister>(sp).IsValidFPRegister());
14140 VIXL_CHECK(!static_cast<CPURegister>(wsp).IsValidFPRegister());
armvixlad96eda2013-06-14 11:42:37 +010014141
armvixlb0c8ae22014-03-21 14:03:59 +000014142 VIXL_CHECK(static_cast<CPURegister>(d0).IsValidFPRegister());
14143 VIXL_CHECK(static_cast<CPURegister>(s0).IsValidFPRegister());
14144 VIXL_CHECK(!static_cast<CPURegister>(d0).IsValidRegister());
14145 VIXL_CHECK(!static_cast<CPURegister>(s0).IsValidRegister());
armvixlad96eda2013-06-14 11:42:37 +010014146}
14147
14148
14149TEST(printf) {
armvixlc68cb642014-09-25 18:49:30 +010014150 SETUP();
armvixlad96eda2013-06-14 11:42:37 +010014151 START();
14152
14153 char const * test_plain_string = "Printf with no arguments.\n";
14154 char const * test_substring = "'This is a substring.'";
14155 RegisterDump before;
14156
14157 // Initialize x29 to the value of the stack pointer. We will use x29 as a
14158 // temporary stack pointer later, and initializing it in this way allows the
14159 // RegisterDump check to pass.
14160 __ Mov(x29, __ StackPointer());
14161
14162 // Test simple integer arguments.
14163 __ Mov(x0, 1234);
14164 __ Mov(x1, 0x1234);
14165
14166 // Test simple floating-point arguments.
14167 __ Fmov(d0, 1.234);
14168
14169 // Test pointer (string) arguments.
14170 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
14171
14172 // Test the maximum number of arguments, and sign extension.
14173 __ Mov(w3, 0xffffffff);
14174 __ Mov(w4, 0xffffffff);
14175 __ Mov(x5, 0xffffffffffffffff);
14176 __ Mov(x6, 0xffffffffffffffff);
14177 __ Fmov(s1, 1.234);
14178 __ Fmov(s2, 2.345);
14179 __ Fmov(d3, 3.456);
14180 __ Fmov(d4, 4.567);
14181
14182 // Test printing callee-saved registers.
14183 __ Mov(x28, 0x123456789abcdef);
14184 __ Fmov(d10, 42.0);
14185
14186 // Test with three arguments.
14187 __ Mov(x10, 3);
14188 __ Mov(x11, 40);
14189 __ Mov(x12, 500);
14190
armvixl5799d6c2014-05-01 11:05:00 +010014191 // A single character.
14192 __ Mov(w13, 'x');
14193
14194 // Check that we don't clobber any registers.
armvixlad96eda2013-06-14 11:42:37 +010014195 before.Dump(&masm);
14196
14197 __ Printf(test_plain_string); // NOLINT(runtime/printf)
armvixl5799d6c2014-05-01 11:05:00 +010014198 __ Printf("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1);
14199 __ Printf("w5: %" PRId32 ", x5: %" PRId64"\n", w5, x5);
armvixlad96eda2013-06-14 11:42:37 +010014200 __ Printf("d0: %f\n", d0);
14201 __ Printf("Test %%s: %s\n", x2);
14202 __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
14203 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
14204 w3, w4, x5, x6);
14205 __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
armvixl5799d6c2014-05-01 11:05:00 +010014206 __ Printf("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
armvixlad96eda2013-06-14 11:42:37 +010014207 __ Printf("%g\n", d10);
armvixl5799d6c2014-05-01 11:05:00 +010014208 __ Printf("%%%%%s%%%c%%\n", x2, w13);
14209
14210 // Print the stack pointer (sp).
14211 __ Printf("StackPointer(sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
14212 __ StackPointer(), __ StackPointer().W());
armvixlad96eda2013-06-14 11:42:37 +010014213
14214 // Test with a different stack pointer.
14215 const Register old_stack_pointer = __ StackPointer();
armvixl5799d6c2014-05-01 11:05:00 +010014216 __ Mov(x29, old_stack_pointer);
armvixlad96eda2013-06-14 11:42:37 +010014217 __ SetStackPointer(x29);
armvixl5799d6c2014-05-01 11:05:00 +010014218 // Print the stack pointer (not sp).
14219 __ Printf("StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
14220 __ StackPointer(), __ StackPointer().W());
14221 __ Mov(old_stack_pointer, __ StackPointer());
armvixlad96eda2013-06-14 11:42:37 +010014222 __ SetStackPointer(old_stack_pointer);
14223
armvixl5799d6c2014-05-01 11:05:00 +010014224 // Test with three arguments.
armvixlad96eda2013-06-14 11:42:37 +010014225 __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12);
14226
armvixl5799d6c2014-05-01 11:05:00 +010014227 // Mixed argument types.
14228 __ Printf("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
14229 w3, s1, x5, d3);
14230 __ Printf("s1: %f, d3: %f, w3: %" PRId32 ", x5: %" PRId64 "\n",
14231 s1, d3, w3, x5);
14232
armvixlad96eda2013-06-14 11:42:37 +010014233 END();
14234 RUN();
14235
14236 // We cannot easily test the output of the Printf sequences, and because
14237 // Printf preserves all registers by default, we can't look at the number of
14238 // bytes that were printed. However, the printf_no_preserve test should check
14239 // that, and here we just test that we didn't clobber any registers.
14240 ASSERT_EQUAL_REGISTERS(before);
14241
14242 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +010014243}
14244
14245
14246TEST(printf_no_preserve) {
armvixlad96eda2013-06-14 11:42:37 +010014247 SETUP();
14248 START();
14249
14250 char const * test_plain_string = "Printf with no arguments.\n";
14251 char const * test_substring = "'This is a substring.'";
14252
14253 __ PrintfNoPreserve(test_plain_string);
14254 __ Mov(x19, x0);
14255
14256 // Test simple integer arguments.
14257 __ Mov(x0, 1234);
14258 __ Mov(x1, 0x1234);
14259 __ PrintfNoPreserve("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1);
14260 __ Mov(x20, x0);
14261
14262 // Test simple floating-point arguments.
14263 __ Fmov(d0, 1.234);
14264 __ PrintfNoPreserve("d0: %f\n", d0);
14265 __ Mov(x21, x0);
14266
14267 // Test pointer (string) arguments.
14268 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
14269 __ PrintfNoPreserve("Test %%s: %s\n", x2);
14270 __ Mov(x22, x0);
14271
14272 // Test the maximum number of arguments, and sign extension.
14273 __ Mov(w3, 0xffffffff);
14274 __ Mov(w4, 0xffffffff);
14275 __ Mov(x5, 0xffffffffffffffff);
14276 __ Mov(x6, 0xffffffffffffffff);
14277 __ PrintfNoPreserve("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
14278 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
14279 w3, w4, x5, x6);
14280 __ Mov(x23, x0);
14281
14282 __ Fmov(s1, 1.234);
14283 __ Fmov(s2, 2.345);
14284 __ Fmov(d3, 3.456);
14285 __ Fmov(d4, 4.567);
14286 __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
14287 __ Mov(x24, x0);
14288
14289 // Test printing callee-saved registers.
14290 __ Mov(x28, 0x123456789abcdef);
armvixl5799d6c2014-05-01 11:05:00 +010014291 __ PrintfNoPreserve("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
armvixlad96eda2013-06-14 11:42:37 +010014292 __ Mov(x25, x0);
14293
14294 __ Fmov(d10, 42.0);
14295 __ PrintfNoPreserve("%g\n", d10);
14296 __ Mov(x26, x0);
14297
14298 // Test with a different stack pointer.
14299 const Register old_stack_pointer = __ StackPointer();
14300 __ Mov(x29, old_stack_pointer);
14301 __ SetStackPointer(x29);
armvixl5799d6c2014-05-01 11:05:00 +010014302 // Print the stack pointer (not sp).
14303 __ PrintfNoPreserve(
14304 "StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
14305 __ StackPointer(), __ StackPointer().W());
armvixlad96eda2013-06-14 11:42:37 +010014306 __ Mov(x27, x0);
armvixlad96eda2013-06-14 11:42:37 +010014307 __ Mov(old_stack_pointer, __ StackPointer());
14308 __ SetStackPointer(old_stack_pointer);
14309
14310 // Test with three arguments.
14311 __ Mov(x3, 3);
14312 __ Mov(x4, 40);
14313 __ Mov(x5, 500);
14314 __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5);
14315 __ Mov(x28, x0);
14316
armvixl5799d6c2014-05-01 11:05:00 +010014317 // Mixed argument types.
14318 __ Mov(w3, 0xffffffff);
14319 __ Fmov(s1, 1.234);
14320 __ Mov(x5, 0xffffffffffffffff);
14321 __ Fmov(d3, 3.456);
14322 __ PrintfNoPreserve("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
14323 w3, s1, x5, d3);
14324 __ Mov(x29, x0);
14325
armvixlad96eda2013-06-14 11:42:37 +010014326 END();
14327 RUN();
14328
14329 // We cannot easily test the exact output of the Printf sequences, but we can
14330 // use the return code to check that the string length was correct.
14331
14332 // Printf with no arguments.
14333 ASSERT_EQUAL_64(strlen(test_plain_string), x19);
14334 // x0: 1234, x1: 0x00001234
14335 ASSERT_EQUAL_64(25, x20);
14336 // d0: 1.234000
14337 ASSERT_EQUAL_64(13, x21);
14338 // Test %s: 'This is a substring.'
14339 ASSERT_EQUAL_64(32, x22);
14340 // w3(uint32): 4294967295
14341 // w4(int32): -1
14342 // x5(uint64): 18446744073709551615
14343 // x6(int64): -1
14344 ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23);
14345 // %f: 1.234000
14346 // %g: 2.345
14347 // %e: 3.456000e+00
14348 // %E: 4.567000E+00
14349 ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24);
armvixl5799d6c2014-05-01 11:05:00 +010014350 // 0x89abcdef, 0x123456789abcdef
14351 ASSERT_EQUAL_64(30, x25);
armvixlad96eda2013-06-14 11:42:37 +010014352 // 42
14353 ASSERT_EQUAL_64(3, x26);
armvixl5799d6c2014-05-01 11:05:00 +010014354 // StackPointer(not sp): 0x00007fb037ae2370, 0x37ae2370
armvixlad96eda2013-06-14 11:42:37 +010014355 // Note: This is an example value, but the field width is fixed here so the
14356 // string length is still predictable.
armvixl5799d6c2014-05-01 11:05:00 +010014357 ASSERT_EQUAL_64(53, x27);
armvixlad96eda2013-06-14 11:42:37 +010014358 // 3=3, 4=40, 5=500
14359 ASSERT_EQUAL_64(17, x28);
armvixl5799d6c2014-05-01 11:05:00 +010014360 // w3: 4294967295, s1: 1.234000, x5: 18446744073709551615, d3: 3.456000
14361 ASSERT_EQUAL_64(69, x29);
armvixlad96eda2013-06-14 11:42:37 +010014362
14363 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +010014364}
14365
14366
armvixl684cd2a2015-10-23 13:38:33 +010014367#ifndef VIXL_INCLUDE_SIMULATOR
armvixlad96eda2013-06-14 11:42:37 +010014368TEST(trace) {
14369 // The Trace helper should not generate any code unless the simulator (or
14370 // debugger) is being used.
14371 SETUP();
14372 START();
14373
14374 Label start;
14375 __ Bind(&start);
14376 __ Trace(LOG_ALL, TRACE_ENABLE);
14377 __ Trace(LOG_ALL, TRACE_DISABLE);
armvixlb0c8ae22014-03-21 14:03:59 +000014378 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlad96eda2013-06-14 11:42:37 +010014379
14380 END();
14381 TEARDOWN();
14382}
14383#endif
14384
14385
armvixl684cd2a2015-10-23 13:38:33 +010014386#ifndef VIXL_INCLUDE_SIMULATOR
armvixlad96eda2013-06-14 11:42:37 +010014387TEST(log) {
14388 // The Log helper should not generate any code unless the simulator (or
14389 // debugger) is being used.
14390 SETUP();
14391 START();
14392
14393 Label start;
14394 __ Bind(&start);
14395 __ Log(LOG_ALL);
armvixlb0c8ae22014-03-21 14:03:59 +000014396 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlad96eda2013-06-14 11:42:37 +010014397
14398 END();
14399 TEARDOWN();
14400}
14401#endif
14402
14403
14404TEST(instruction_accurate_scope) {
14405 SETUP();
14406 START();
14407
14408 // By default macro instructions are allowed.
armvixlb0c8ae22014-03-21 14:03:59 +000014409 VIXL_ASSERT(masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +010014410 {
armvixlc68cb642014-09-25 18:49:30 +010014411 InstructionAccurateScope scope1(&masm, 2);
armvixlb0c8ae22014-03-21 14:03:59 +000014412 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlc68cb642014-09-25 18:49:30 +010014413 __ nop();
armvixlad96eda2013-06-14 11:42:37 +010014414 {
armvixlc68cb642014-09-25 18:49:30 +010014415 InstructionAccurateScope scope2(&masm, 1);
armvixlb0c8ae22014-03-21 14:03:59 +000014416 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlc68cb642014-09-25 18:49:30 +010014417 __ nop();
armvixlad96eda2013-06-14 11:42:37 +010014418 }
armvixlb0c8ae22014-03-21 14:03:59 +000014419 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +010014420 }
armvixlb0c8ae22014-03-21 14:03:59 +000014421 VIXL_ASSERT(masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +010014422
14423 {
14424 InstructionAccurateScope scope(&masm, 2);
14425 __ add(x0, x0, x0);
14426 __ sub(x0, x0, x0);
14427 }
14428
14429 END();
14430 RUN();
14431 TEARDOWN();
14432}
14433
14434
14435TEST(blr_lr) {
14436 // A simple test to check that the simulator correcty handle "blr lr".
14437 SETUP();
14438
14439 START();
14440 Label target;
14441 Label end;
14442
14443 __ Mov(x0, 0x0);
14444 __ Adr(lr, &target);
14445
14446 __ Blr(lr);
14447 __ Mov(x0, 0xdeadbeef);
14448 __ B(&end);
14449
14450 __ Bind(&target);
14451 __ Mov(x0, 0xc001c0de);
14452
14453 __ Bind(&end);
14454 END();
14455
14456 RUN();
14457
14458 ASSERT_EQUAL_64(0xc001c0de, x0);
14459
14460 TEARDOWN();
14461}
14462
armvixlf37fdc02014-02-05 13:22:16 +000014463
14464TEST(barriers) {
14465 // Generate all supported barriers, this is just a smoke test
14466 SETUP();
14467
14468 START();
14469
14470 // DMB
14471 __ Dmb(FullSystem, BarrierAll);
14472 __ Dmb(FullSystem, BarrierReads);
14473 __ Dmb(FullSystem, BarrierWrites);
14474 __ Dmb(FullSystem, BarrierOther);
14475
14476 __ Dmb(InnerShareable, BarrierAll);
14477 __ Dmb(InnerShareable, BarrierReads);
14478 __ Dmb(InnerShareable, BarrierWrites);
14479 __ Dmb(InnerShareable, BarrierOther);
14480
14481 __ Dmb(NonShareable, BarrierAll);
14482 __ Dmb(NonShareable, BarrierReads);
14483 __ Dmb(NonShareable, BarrierWrites);
14484 __ Dmb(NonShareable, BarrierOther);
14485
14486 __ Dmb(OuterShareable, BarrierAll);
14487 __ Dmb(OuterShareable, BarrierReads);
14488 __ Dmb(OuterShareable, BarrierWrites);
14489 __ Dmb(OuterShareable, BarrierOther);
14490
14491 // DSB
14492 __ Dsb(FullSystem, BarrierAll);
14493 __ Dsb(FullSystem, BarrierReads);
14494 __ Dsb(FullSystem, BarrierWrites);
14495 __ Dsb(FullSystem, BarrierOther);
14496
14497 __ Dsb(InnerShareable, BarrierAll);
14498 __ Dsb(InnerShareable, BarrierReads);
14499 __ Dsb(InnerShareable, BarrierWrites);
14500 __ Dsb(InnerShareable, BarrierOther);
14501
14502 __ Dsb(NonShareable, BarrierAll);
14503 __ Dsb(NonShareable, BarrierReads);
14504 __ Dsb(NonShareable, BarrierWrites);
14505 __ Dsb(NonShareable, BarrierOther);
14506
14507 __ Dsb(OuterShareable, BarrierAll);
14508 __ Dsb(OuterShareable, BarrierReads);
14509 __ Dsb(OuterShareable, BarrierWrites);
14510 __ Dsb(OuterShareable, BarrierOther);
14511
14512 // ISB
14513 __ Isb();
14514
14515 END();
14516
14517 RUN();
14518
14519 TEARDOWN();
14520}
14521
armvixlb0c8ae22014-03-21 14:03:59 +000014522
14523TEST(process_nan_double) {
14524 // Make sure that NaN propagation works correctly.
14525 double sn = rawbits_to_double(0x7ff5555511111111);
14526 double qn = rawbits_to_double(0x7ffaaaaa11111111);
14527 VIXL_ASSERT(IsSignallingNaN(sn));
14528 VIXL_ASSERT(IsQuietNaN(qn));
14529
14530 // The input NaNs after passing through ProcessNaN.
14531 double sn_proc = rawbits_to_double(0x7ffd555511111111);
14532 double qn_proc = qn;
14533 VIXL_ASSERT(IsQuietNaN(sn_proc));
14534 VIXL_ASSERT(IsQuietNaN(qn_proc));
14535
14536 SETUP();
14537 START();
14538
14539 // Execute a number of instructions which all use ProcessNaN, and check that
14540 // they all handle the NaN correctly.
14541 __ Fmov(d0, sn);
14542 __ Fmov(d10, qn);
14543
14544 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14545 // - Signalling NaN
14546 __ Fmov(d1, d0);
14547 __ Fabs(d2, d0);
14548 __ Fneg(d3, d0);
14549 // - Quiet NaN
14550 __ Fmov(d11, d10);
14551 __ Fabs(d12, d10);
14552 __ Fneg(d13, d10);
14553
14554 // Operations that use ProcessNaN.
14555 // - Signalling NaN
14556 __ Fsqrt(d4, d0);
14557 __ Frinta(d5, d0);
14558 __ Frintn(d6, d0);
14559 __ Frintz(d7, d0);
14560 // - Quiet NaN
14561 __ Fsqrt(d14, d10);
14562 __ Frinta(d15, d10);
14563 __ Frintn(d16, d10);
14564 __ Frintz(d17, d10);
14565
14566 // The behaviour of fcvt is checked in TEST(fcvt_sd).
14567
14568 END();
14569 RUN();
14570
14571 uint64_t qn_raw = double_to_rawbits(qn);
14572 uint64_t sn_raw = double_to_rawbits(sn);
14573
14574 // - Signalling NaN
14575 ASSERT_EQUAL_FP64(sn, d1);
14576 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw & ~kDSignMask), d2);
14577 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw ^ kDSignMask), d3);
14578 // - Quiet NaN
14579 ASSERT_EQUAL_FP64(qn, d11);
14580 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw & ~kDSignMask), d12);
14581 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw ^ kDSignMask), d13);
14582
14583 // - Signalling NaN
14584 ASSERT_EQUAL_FP64(sn_proc, d4);
14585 ASSERT_EQUAL_FP64(sn_proc, d5);
14586 ASSERT_EQUAL_FP64(sn_proc, d6);
14587 ASSERT_EQUAL_FP64(sn_proc, d7);
14588 // - Quiet NaN
14589 ASSERT_EQUAL_FP64(qn_proc, d14);
14590 ASSERT_EQUAL_FP64(qn_proc, d15);
14591 ASSERT_EQUAL_FP64(qn_proc, d16);
14592 ASSERT_EQUAL_FP64(qn_proc, d17);
14593
14594 TEARDOWN();
14595}
14596
14597
14598TEST(process_nan_float) {
14599 // Make sure that NaN propagation works correctly.
14600 float sn = rawbits_to_float(0x7f951111);
14601 float qn = rawbits_to_float(0x7fea1111);
14602 VIXL_ASSERT(IsSignallingNaN(sn));
14603 VIXL_ASSERT(IsQuietNaN(qn));
14604
14605 // The input NaNs after passing through ProcessNaN.
14606 float sn_proc = rawbits_to_float(0x7fd51111);
14607 float qn_proc = qn;
14608 VIXL_ASSERT(IsQuietNaN(sn_proc));
14609 VIXL_ASSERT(IsQuietNaN(qn_proc));
14610
14611 SETUP();
14612 START();
14613
14614 // Execute a number of instructions which all use ProcessNaN, and check that
14615 // they all handle the NaN correctly.
14616 __ Fmov(s0, sn);
14617 __ Fmov(s10, qn);
14618
14619 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14620 // - Signalling NaN
14621 __ Fmov(s1, s0);
14622 __ Fabs(s2, s0);
14623 __ Fneg(s3, s0);
14624 // - Quiet NaN
14625 __ Fmov(s11, s10);
14626 __ Fabs(s12, s10);
14627 __ Fneg(s13, s10);
14628
14629 // Operations that use ProcessNaN.
14630 // - Signalling NaN
14631 __ Fsqrt(s4, s0);
14632 __ Frinta(s5, s0);
14633 __ Frintn(s6, s0);
14634 __ Frintz(s7, s0);
14635 // - Quiet NaN
14636 __ Fsqrt(s14, s10);
14637 __ Frinta(s15, s10);
14638 __ Frintn(s16, s10);
14639 __ Frintz(s17, s10);
14640
14641 // The behaviour of fcvt is checked in TEST(fcvt_sd).
14642
14643 END();
14644 RUN();
14645
14646 uint32_t qn_raw = float_to_rawbits(qn);
14647 uint32_t sn_raw = float_to_rawbits(sn);
14648
14649 // - Signalling NaN
14650 ASSERT_EQUAL_FP32(sn, s1);
14651 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw & ~kSSignMask), s2);
14652 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw ^ kSSignMask), s3);
14653 // - Quiet NaN
14654 ASSERT_EQUAL_FP32(qn, s11);
14655 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw & ~kSSignMask), s12);
14656 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw ^ kSSignMask), s13);
14657
14658 // - Signalling NaN
14659 ASSERT_EQUAL_FP32(sn_proc, s4);
14660 ASSERT_EQUAL_FP32(sn_proc, s5);
14661 ASSERT_EQUAL_FP32(sn_proc, s6);
14662 ASSERT_EQUAL_FP32(sn_proc, s7);
14663 // - Quiet NaN
14664 ASSERT_EQUAL_FP32(qn_proc, s14);
14665 ASSERT_EQUAL_FP32(qn_proc, s15);
14666 ASSERT_EQUAL_FP32(qn_proc, s16);
14667 ASSERT_EQUAL_FP32(qn_proc, s17);
14668
14669 TEARDOWN();
14670}
14671
14672
14673static void ProcessNaNsHelper(double n, double m, double expected) {
armvixl6e2c8272015-03-31 11:04:14 +010014674 VIXL_ASSERT(std::isnan(n) || std::isnan(m));
14675 VIXL_ASSERT(std::isnan(expected));
armvixlb0c8ae22014-03-21 14:03:59 +000014676
14677 SETUP();
14678 START();
14679
14680 // Execute a number of instructions which all use ProcessNaNs, and check that
14681 // they all propagate NaNs correctly.
14682 __ Fmov(d0, n);
14683 __ Fmov(d1, m);
14684
14685 __ Fadd(d2, d0, d1);
14686 __ Fsub(d3, d0, d1);
14687 __ Fmul(d4, d0, d1);
14688 __ Fdiv(d5, d0, d1);
14689 __ Fmax(d6, d0, d1);
14690 __ Fmin(d7, d0, d1);
14691
14692 END();
14693 RUN();
14694
14695 ASSERT_EQUAL_FP64(expected, d2);
14696 ASSERT_EQUAL_FP64(expected, d3);
14697 ASSERT_EQUAL_FP64(expected, d4);
14698 ASSERT_EQUAL_FP64(expected, d5);
14699 ASSERT_EQUAL_FP64(expected, d6);
14700 ASSERT_EQUAL_FP64(expected, d7);
14701
14702 TEARDOWN();
14703}
14704
14705
14706TEST(process_nans_double) {
14707 // Make sure that NaN propagation works correctly.
14708 double sn = rawbits_to_double(0x7ff5555511111111);
14709 double sm = rawbits_to_double(0x7ff5555522222222);
14710 double qn = rawbits_to_double(0x7ffaaaaa11111111);
14711 double qm = rawbits_to_double(0x7ffaaaaa22222222);
14712 VIXL_ASSERT(IsSignallingNaN(sn));
14713 VIXL_ASSERT(IsSignallingNaN(sm));
14714 VIXL_ASSERT(IsQuietNaN(qn));
14715 VIXL_ASSERT(IsQuietNaN(qm));
14716
14717 // The input NaNs after passing through ProcessNaN.
14718 double sn_proc = rawbits_to_double(0x7ffd555511111111);
14719 double sm_proc = rawbits_to_double(0x7ffd555522222222);
14720 double qn_proc = qn;
14721 double qm_proc = qm;
14722 VIXL_ASSERT(IsQuietNaN(sn_proc));
14723 VIXL_ASSERT(IsQuietNaN(sm_proc));
14724 VIXL_ASSERT(IsQuietNaN(qn_proc));
14725 VIXL_ASSERT(IsQuietNaN(qm_proc));
14726
14727 // Quiet NaNs are propagated.
14728 ProcessNaNsHelper(qn, 0, qn_proc);
14729 ProcessNaNsHelper(0, qm, qm_proc);
14730 ProcessNaNsHelper(qn, qm, qn_proc);
14731
14732 // Signalling NaNs are propagated, and made quiet.
14733 ProcessNaNsHelper(sn, 0, sn_proc);
14734 ProcessNaNsHelper(0, sm, sm_proc);
14735 ProcessNaNsHelper(sn, sm, sn_proc);
14736
14737 // Signalling NaNs take precedence over quiet NaNs.
14738 ProcessNaNsHelper(sn, qm, sn_proc);
14739 ProcessNaNsHelper(qn, sm, sm_proc);
14740 ProcessNaNsHelper(sn, sm, sn_proc);
14741}
14742
14743
14744static void ProcessNaNsHelper(float n, float m, float expected) {
armvixl6e2c8272015-03-31 11:04:14 +010014745 VIXL_ASSERT(std::isnan(n) || std::isnan(m));
14746 VIXL_ASSERT(std::isnan(expected));
armvixlb0c8ae22014-03-21 14:03:59 +000014747
14748 SETUP();
14749 START();
14750
14751 // Execute a number of instructions which all use ProcessNaNs, and check that
14752 // they all propagate NaNs correctly.
14753 __ Fmov(s0, n);
14754 __ Fmov(s1, m);
14755
14756 __ Fadd(s2, s0, s1);
14757 __ Fsub(s3, s0, s1);
14758 __ Fmul(s4, s0, s1);
14759 __ Fdiv(s5, s0, s1);
14760 __ Fmax(s6, s0, s1);
14761 __ Fmin(s7, s0, s1);
14762
14763 END();
14764 RUN();
14765
14766 ASSERT_EQUAL_FP32(expected, s2);
14767 ASSERT_EQUAL_FP32(expected, s3);
14768 ASSERT_EQUAL_FP32(expected, s4);
14769 ASSERT_EQUAL_FP32(expected, s5);
14770 ASSERT_EQUAL_FP32(expected, s6);
14771 ASSERT_EQUAL_FP32(expected, s7);
14772
14773 TEARDOWN();
14774}
14775
14776
14777TEST(process_nans_float) {
14778 // Make sure that NaN propagation works correctly.
14779 float sn = rawbits_to_float(0x7f951111);
14780 float sm = rawbits_to_float(0x7f952222);
14781 float qn = rawbits_to_float(0x7fea1111);
14782 float qm = rawbits_to_float(0x7fea2222);
14783 VIXL_ASSERT(IsSignallingNaN(sn));
14784 VIXL_ASSERT(IsSignallingNaN(sm));
14785 VIXL_ASSERT(IsQuietNaN(qn));
14786 VIXL_ASSERT(IsQuietNaN(qm));
14787
14788 // The input NaNs after passing through ProcessNaN.
14789 float sn_proc = rawbits_to_float(0x7fd51111);
14790 float sm_proc = rawbits_to_float(0x7fd52222);
14791 float qn_proc = qn;
14792 float qm_proc = qm;
14793 VIXL_ASSERT(IsQuietNaN(sn_proc));
14794 VIXL_ASSERT(IsQuietNaN(sm_proc));
14795 VIXL_ASSERT(IsQuietNaN(qn_proc));
14796 VIXL_ASSERT(IsQuietNaN(qm_proc));
14797
14798 // Quiet NaNs are propagated.
14799 ProcessNaNsHelper(qn, 0, qn_proc);
14800 ProcessNaNsHelper(0, qm, qm_proc);
14801 ProcessNaNsHelper(qn, qm, qn_proc);
14802
14803 // Signalling NaNs are propagated, and made quiet.
14804 ProcessNaNsHelper(sn, 0, sn_proc);
14805 ProcessNaNsHelper(0, sm, sm_proc);
14806 ProcessNaNsHelper(sn, sm, sn_proc);
14807
14808 // Signalling NaNs take precedence over quiet NaNs.
14809 ProcessNaNsHelper(sn, qm, sn_proc);
14810 ProcessNaNsHelper(qn, sm, sm_proc);
14811 ProcessNaNsHelper(sn, sm, sn_proc);
14812}
14813
14814
14815static void DefaultNaNHelper(float n, float m, float a) {
armvixl6e2c8272015-03-31 11:04:14 +010014816 VIXL_ASSERT(std::isnan(n) || std::isnan(m) || std::isnan(a));
armvixlb0c8ae22014-03-21 14:03:59 +000014817
armvixl6e2c8272015-03-31 11:04:14 +010014818 bool test_1op = std::isnan(n);
14819 bool test_2op = std::isnan(n) || std::isnan(m);
armvixlb0c8ae22014-03-21 14:03:59 +000014820
14821 SETUP();
14822 START();
14823
14824 // Enable Default-NaN mode in the FPCR.
14825 __ Mrs(x0, FPCR);
14826 __ Orr(x1, x0, DN_mask);
14827 __ Msr(FPCR, x1);
14828
14829 // Execute a number of instructions which all use ProcessNaNs, and check that
14830 // they all produce the default NaN.
14831 __ Fmov(s0, n);
14832 __ Fmov(s1, m);
14833 __ Fmov(s2, a);
14834
14835 if (test_1op) {
14836 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14837 __ Fmov(s10, s0);
14838 __ Fabs(s11, s0);
14839 __ Fneg(s12, s0);
14840
14841 // Operations that use ProcessNaN.
14842 __ Fsqrt(s13, s0);
14843 __ Frinta(s14, s0);
14844 __ Frintn(s15, s0);
14845 __ Frintz(s16, s0);
14846
14847 // Fcvt usually has special NaN handling, but it respects default-NaN mode.
14848 __ Fcvt(d17, s0);
14849 }
14850
14851 if (test_2op) {
14852 __ Fadd(s18, s0, s1);
14853 __ Fsub(s19, s0, s1);
14854 __ Fmul(s20, s0, s1);
14855 __ Fdiv(s21, s0, s1);
14856 __ Fmax(s22, s0, s1);
14857 __ Fmin(s23, s0, s1);
14858 }
14859
14860 __ Fmadd(s24, s0, s1, s2);
14861 __ Fmsub(s25, s0, s1, s2);
14862 __ Fnmadd(s26, s0, s1, s2);
14863 __ Fnmsub(s27, s0, s1, s2);
14864
14865 // Restore FPCR.
14866 __ Msr(FPCR, x0);
14867
14868 END();
14869 RUN();
14870
14871 if (test_1op) {
14872 uint32_t n_raw = float_to_rawbits(n);
14873 ASSERT_EQUAL_FP32(n, s10);
14874 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw & ~kSSignMask), s11);
14875 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw ^ kSSignMask), s12);
14876 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s13);
14877 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s14);
14878 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s15);
14879 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s16);
14880 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d17);
14881 }
14882
14883 if (test_2op) {
14884 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s18);
14885 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s19);
14886 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s20);
14887 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s21);
14888 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s22);
14889 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s23);
14890 }
14891
14892 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s24);
14893 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s25);
14894 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s26);
14895 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s27);
14896
14897 TEARDOWN();
14898}
14899
14900
14901TEST(default_nan_float) {
14902 float sn = rawbits_to_float(0x7f951111);
14903 float sm = rawbits_to_float(0x7f952222);
14904 float sa = rawbits_to_float(0x7f95aaaa);
14905 float qn = rawbits_to_float(0x7fea1111);
14906 float qm = rawbits_to_float(0x7fea2222);
14907 float qa = rawbits_to_float(0x7feaaaaa);
14908 VIXL_ASSERT(IsSignallingNaN(sn));
14909 VIXL_ASSERT(IsSignallingNaN(sm));
14910 VIXL_ASSERT(IsSignallingNaN(sa));
14911 VIXL_ASSERT(IsQuietNaN(qn));
14912 VIXL_ASSERT(IsQuietNaN(qm));
14913 VIXL_ASSERT(IsQuietNaN(qa));
14914
14915 // - Signalling NaNs
14916 DefaultNaNHelper(sn, 0.0f, 0.0f);
14917 DefaultNaNHelper(0.0f, sm, 0.0f);
14918 DefaultNaNHelper(0.0f, 0.0f, sa);
14919 DefaultNaNHelper(sn, sm, 0.0f);
14920 DefaultNaNHelper(0.0f, sm, sa);
14921 DefaultNaNHelper(sn, 0.0f, sa);
14922 DefaultNaNHelper(sn, sm, sa);
14923 // - Quiet NaNs
14924 DefaultNaNHelper(qn, 0.0f, 0.0f);
14925 DefaultNaNHelper(0.0f, qm, 0.0f);
14926 DefaultNaNHelper(0.0f, 0.0f, qa);
14927 DefaultNaNHelper(qn, qm, 0.0f);
14928 DefaultNaNHelper(0.0f, qm, qa);
14929 DefaultNaNHelper(qn, 0.0f, qa);
14930 DefaultNaNHelper(qn, qm, qa);
14931 // - Mixed NaNs
14932 DefaultNaNHelper(qn, sm, sa);
14933 DefaultNaNHelper(sn, qm, sa);
14934 DefaultNaNHelper(sn, sm, qa);
14935 DefaultNaNHelper(qn, qm, sa);
14936 DefaultNaNHelper(sn, qm, qa);
14937 DefaultNaNHelper(qn, sm, qa);
14938 DefaultNaNHelper(qn, qm, qa);
14939}
14940
14941
14942static void DefaultNaNHelper(double n, double m, double a) {
armvixl6e2c8272015-03-31 11:04:14 +010014943 VIXL_ASSERT(std::isnan(n) || std::isnan(m) || std::isnan(a));
armvixlb0c8ae22014-03-21 14:03:59 +000014944
armvixl6e2c8272015-03-31 11:04:14 +010014945 bool test_1op = std::isnan(n);
14946 bool test_2op = std::isnan(n) || std::isnan(m);
armvixlb0c8ae22014-03-21 14:03:59 +000014947
14948 SETUP();
14949 START();
14950
14951 // Enable Default-NaN mode in the FPCR.
14952 __ Mrs(x0, FPCR);
14953 __ Orr(x1, x0, DN_mask);
14954 __ Msr(FPCR, x1);
14955
14956 // Execute a number of instructions which all use ProcessNaNs, and check that
14957 // they all produce the default NaN.
14958 __ Fmov(d0, n);
14959 __ Fmov(d1, m);
14960 __ Fmov(d2, a);
14961
14962 if (test_1op) {
14963 // Operations that always propagate NaNs unchanged, even signalling NaNs.
14964 __ Fmov(d10, d0);
14965 __ Fabs(d11, d0);
14966 __ Fneg(d12, d0);
14967
14968 // Operations that use ProcessNaN.
14969 __ Fsqrt(d13, d0);
14970 __ Frinta(d14, d0);
14971 __ Frintn(d15, d0);
14972 __ Frintz(d16, d0);
14973
14974 // Fcvt usually has special NaN handling, but it respects default-NaN mode.
14975 __ Fcvt(s17, d0);
14976 }
14977
14978 if (test_2op) {
14979 __ Fadd(d18, d0, d1);
14980 __ Fsub(d19, d0, d1);
14981 __ Fmul(d20, d0, d1);
14982 __ Fdiv(d21, d0, d1);
14983 __ Fmax(d22, d0, d1);
14984 __ Fmin(d23, d0, d1);
14985 }
14986
14987 __ Fmadd(d24, d0, d1, d2);
14988 __ Fmsub(d25, d0, d1, d2);
14989 __ Fnmadd(d26, d0, d1, d2);
14990 __ Fnmsub(d27, d0, d1, d2);
14991
14992 // Restore FPCR.
14993 __ Msr(FPCR, x0);
14994
14995 END();
14996 RUN();
14997
14998 if (test_1op) {
14999 uint64_t n_raw = double_to_rawbits(n);
15000 ASSERT_EQUAL_FP64(n, d10);
15001 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw & ~kDSignMask), d11);
15002 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw ^ kDSignMask), d12);
15003 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
15004 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d14);
15005 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d15);
15006 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d16);
15007 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s17);
15008 }
15009
15010 if (test_2op) {
15011 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d18);
15012 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d19);
15013 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d20);
15014 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d21);
15015 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d22);
15016 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d23);
15017 }
15018
15019 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d24);
15020 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d25);
15021 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d26);
15022 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d27);
15023
15024 TEARDOWN();
15025}
15026
15027
15028TEST(default_nan_double) {
15029 double sn = rawbits_to_double(0x7ff5555511111111);
15030 double sm = rawbits_to_double(0x7ff5555522222222);
15031 double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
15032 double qn = rawbits_to_double(0x7ffaaaaa11111111);
15033 double qm = rawbits_to_double(0x7ffaaaaa22222222);
15034 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
15035 VIXL_ASSERT(IsSignallingNaN(sn));
15036 VIXL_ASSERT(IsSignallingNaN(sm));
15037 VIXL_ASSERT(IsSignallingNaN(sa));
15038 VIXL_ASSERT(IsQuietNaN(qn));
15039 VIXL_ASSERT(IsQuietNaN(qm));
15040 VIXL_ASSERT(IsQuietNaN(qa));
15041
15042 // - Signalling NaNs
15043 DefaultNaNHelper(sn, 0.0, 0.0);
15044 DefaultNaNHelper(0.0, sm, 0.0);
15045 DefaultNaNHelper(0.0, 0.0, sa);
15046 DefaultNaNHelper(sn, sm, 0.0);
15047 DefaultNaNHelper(0.0, sm, sa);
15048 DefaultNaNHelper(sn, 0.0, sa);
15049 DefaultNaNHelper(sn, sm, sa);
15050 // - Quiet NaNs
15051 DefaultNaNHelper(qn, 0.0, 0.0);
15052 DefaultNaNHelper(0.0, qm, 0.0);
15053 DefaultNaNHelper(0.0, 0.0, qa);
15054 DefaultNaNHelper(qn, qm, 0.0);
15055 DefaultNaNHelper(0.0, qm, qa);
15056 DefaultNaNHelper(qn, 0.0, qa);
15057 DefaultNaNHelper(qn, qm, qa);
15058 // - Mixed NaNs
15059 DefaultNaNHelper(qn, sm, sa);
15060 DefaultNaNHelper(sn, qm, sa);
15061 DefaultNaNHelper(sn, sm, qa);
15062 DefaultNaNHelper(qn, qm, sa);
15063 DefaultNaNHelper(sn, qm, qa);
15064 DefaultNaNHelper(qn, sm, qa);
15065 DefaultNaNHelper(qn, qm, qa);
15066}
15067
15068
armvixl4a102ba2014-07-14 09:02:40 +010015069TEST(ldar_stlr) {
15070 // The middle value is read, modified, and written. The padding exists only to
15071 // check for over-write.
15072 uint8_t b[] = {0, 0x12, 0};
15073 uint16_t h[] = {0, 0x1234, 0};
15074 uint32_t w[] = {0, 0x12345678, 0};
15075 uint64_t x[] = {0, 0x123456789abcdef0, 0};
15076
15077 SETUP();
15078 START();
15079
15080 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
15081 __ Ldarb(w0, MemOperand(x10));
15082 __ Add(w0, w0, 1);
15083 __ Stlrb(w0, MemOperand(x10));
15084
15085 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
15086 __ Ldarh(w0, MemOperand(x10));
15087 __ Add(w0, w0, 1);
15088 __ Stlrh(w0, MemOperand(x10));
15089
15090 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
15091 __ Ldar(w0, MemOperand(x10));
15092 __ Add(w0, w0, 1);
15093 __ Stlr(w0, MemOperand(x10));
15094
15095 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
15096 __ Ldar(x0, MemOperand(x10));
15097 __ Add(x0, x0, 1);
15098 __ Stlr(x0, MemOperand(x10));
15099
15100 END();
15101 RUN();
15102
15103 ASSERT_EQUAL_32(0x13, b[1]);
15104 ASSERT_EQUAL_32(0x1235, h[1]);
15105 ASSERT_EQUAL_32(0x12345679, w[1]);
15106 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
15107
15108 // Check for over-write.
15109 ASSERT_EQUAL_32(0, b[0]);
15110 ASSERT_EQUAL_32(0, b[2]);
15111 ASSERT_EQUAL_32(0, h[0]);
15112 ASSERT_EQUAL_32(0, h[2]);
15113 ASSERT_EQUAL_32(0, w[0]);
15114 ASSERT_EQUAL_32(0, w[2]);
armvixldb644342015-07-21 11:37:10 +010015115 ASSERT_EQUAL_64(0, x[0]);
15116 ASSERT_EQUAL_64(0, x[2]);
armvixl4a102ba2014-07-14 09:02:40 +010015117
15118 TEARDOWN();
15119}
15120
15121
15122TEST(ldxr_stxr) {
15123 // The middle value is read, modified, and written. The padding exists only to
15124 // check for over-write.
15125 uint8_t b[] = {0, 0x12, 0};
15126 uint16_t h[] = {0, 0x1234, 0};
15127 uint32_t w[] = {0, 0x12345678, 0};
15128 uint64_t x[] = {0, 0x123456789abcdef0, 0};
15129
15130 // As above, but get suitably-aligned values for ldxp and stxp.
15131 uint32_t wp_data[] = {0, 0, 0, 0, 0};
15132 uint32_t * wp = AlignUp(wp_data + 1, kWRegSizeInBytes * 2) - 1;
15133 wp[1] = 0x12345678; // wp[1] is 64-bit-aligned.
15134 wp[2] = 0x87654321;
15135 uint64_t xp_data[] = {0, 0, 0, 0, 0};
15136 uint64_t * xp = AlignUp(xp_data + 1, kXRegSizeInBytes * 2) - 1;
15137 xp[1] = 0x123456789abcdef0; // xp[1] is 128-bit-aligned.
15138 xp[2] = 0x0fedcba987654321;
15139
15140 SETUP();
15141 START();
15142
15143 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
15144 Label try_b;
15145 __ Bind(&try_b);
15146 __ Ldxrb(w0, MemOperand(x10));
15147 __ Add(w0, w0, 1);
15148 __ Stxrb(w5, w0, MemOperand(x10));
15149 __ Cbnz(w5, &try_b);
15150
15151 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
15152 Label try_h;
15153 __ Bind(&try_h);
15154 __ Ldxrh(w0, MemOperand(x10));
15155 __ Add(w0, w0, 1);
15156 __ Stxrh(w5, w0, MemOperand(x10));
15157 __ Cbnz(w5, &try_h);
15158
15159 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
15160 Label try_w;
15161 __ Bind(&try_w);
15162 __ Ldxr(w0, MemOperand(x10));
15163 __ Add(w0, w0, 1);
15164 __ Stxr(w5, w0, MemOperand(x10));
15165 __ Cbnz(w5, &try_w);
15166
15167 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
15168 Label try_x;
15169 __ Bind(&try_x);
15170 __ Ldxr(x0, MemOperand(x10));
15171 __ Add(x0, x0, 1);
15172 __ Stxr(w5, x0, MemOperand(x10));
15173 __ Cbnz(w5, &try_x);
15174
15175 __ Mov(x10, reinterpret_cast<uintptr_t>(&wp[1]));
15176 Label try_wp;
15177 __ Bind(&try_wp);
15178 __ Ldxp(w0, w1, MemOperand(x10));
15179 __ Add(w0, w0, 1);
15180 __ Add(w1, w1, 1);
15181 __ Stxp(w5, w0, w1, MemOperand(x10));
15182 __ Cbnz(w5, &try_wp);
15183
15184 __ Mov(x10, reinterpret_cast<uintptr_t>(&xp[1]));
15185 Label try_xp;
15186 __ Bind(&try_xp);
15187 __ Ldxp(x0, x1, MemOperand(x10));
15188 __ Add(x0, x0, 1);
15189 __ Add(x1, x1, 1);
15190 __ Stxp(w5, x0, x1, MemOperand(x10));
15191 __ Cbnz(w5, &try_xp);
15192
15193 END();
15194 RUN();
15195
15196 ASSERT_EQUAL_32(0x13, b[1]);
15197 ASSERT_EQUAL_32(0x1235, h[1]);
15198 ASSERT_EQUAL_32(0x12345679, w[1]);
15199 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
15200 ASSERT_EQUAL_32(0x12345679, wp[1]);
15201 ASSERT_EQUAL_32(0x87654322, wp[2]);
15202 ASSERT_EQUAL_64(0x123456789abcdef1, xp[1]);
15203 ASSERT_EQUAL_64(0x0fedcba987654322, xp[2]);
15204
15205 // Check for over-write.
15206 ASSERT_EQUAL_32(0, b[0]);
15207 ASSERT_EQUAL_32(0, b[2]);
15208 ASSERT_EQUAL_32(0, h[0]);
15209 ASSERT_EQUAL_32(0, h[2]);
15210 ASSERT_EQUAL_32(0, w[0]);
15211 ASSERT_EQUAL_32(0, w[2]);
15212 ASSERT_EQUAL_64(0, x[0]);
15213 ASSERT_EQUAL_64(0, x[2]);
15214 ASSERT_EQUAL_32(0, wp[0]);
15215 ASSERT_EQUAL_32(0, wp[3]);
15216 ASSERT_EQUAL_64(0, xp[0]);
15217 ASSERT_EQUAL_64(0, xp[3]);
15218
15219 TEARDOWN();
15220}
15221
15222
15223TEST(ldaxr_stlxr) {
15224 // The middle value is read, modified, and written. The padding exists only to
15225 // check for over-write.
15226 uint8_t b[] = {0, 0x12, 0};
15227 uint16_t h[] = {0, 0x1234, 0};
15228 uint32_t w[] = {0, 0x12345678, 0};
15229 uint64_t x[] = {0, 0x123456789abcdef0, 0};
15230
15231 // As above, but get suitably-aligned values for ldxp and stxp.
15232 uint32_t wp_data[] = {0, 0, 0, 0, 0};
15233 uint32_t * wp = AlignUp(wp_data + 1, kWRegSizeInBytes * 2) - 1;
15234 wp[1] = 0x12345678; // wp[1] is 64-bit-aligned.
15235 wp[2] = 0x87654321;
15236 uint64_t xp_data[] = {0, 0, 0, 0, 0};
15237 uint64_t * xp = AlignUp(xp_data + 1, kXRegSizeInBytes * 2) - 1;
15238 xp[1] = 0x123456789abcdef0; // xp[1] is 128-bit-aligned.
15239 xp[2] = 0x0fedcba987654321;
15240
15241 SETUP();
15242 START();
15243
15244 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
15245 Label try_b;
15246 __ Bind(&try_b);
15247 __ Ldaxrb(w0, MemOperand(x10));
15248 __ Add(w0, w0, 1);
15249 __ Stlxrb(w5, w0, MemOperand(x10));
15250 __ Cbnz(w5, &try_b);
15251
15252 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
15253 Label try_h;
15254 __ Bind(&try_h);
15255 __ Ldaxrh(w0, MemOperand(x10));
15256 __ Add(w0, w0, 1);
15257 __ Stlxrh(w5, w0, MemOperand(x10));
15258 __ Cbnz(w5, &try_h);
15259
15260 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
15261 Label try_w;
15262 __ Bind(&try_w);
15263 __ Ldaxr(w0, MemOperand(x10));
15264 __ Add(w0, w0, 1);
15265 __ Stlxr(w5, w0, MemOperand(x10));
15266 __ Cbnz(w5, &try_w);
15267
15268 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
15269 Label try_x;
15270 __ Bind(&try_x);
15271 __ Ldaxr(x0, MemOperand(x10));
15272 __ Add(x0, x0, 1);
15273 __ Stlxr(w5, x0, MemOperand(x10));
15274 __ Cbnz(w5, &try_x);
15275
15276 __ Mov(x10, reinterpret_cast<uintptr_t>(&wp[1]));
15277 Label try_wp;
15278 __ Bind(&try_wp);
15279 __ Ldaxp(w0, w1, MemOperand(x10));
15280 __ Add(w0, w0, 1);
15281 __ Add(w1, w1, 1);
15282 __ Stlxp(w5, w0, w1, MemOperand(x10));
15283 __ Cbnz(w5, &try_wp);
15284
15285 __ Mov(x10, reinterpret_cast<uintptr_t>(&xp[1]));
15286 Label try_xp;
15287 __ Bind(&try_xp);
15288 __ Ldaxp(x0, x1, MemOperand(x10));
15289 __ Add(x0, x0, 1);
15290 __ Add(x1, x1, 1);
15291 __ Stlxp(w5, x0, x1, MemOperand(x10));
15292 __ Cbnz(w5, &try_xp);
15293
15294 END();
15295 RUN();
15296
15297 ASSERT_EQUAL_32(0x13, b[1]);
15298 ASSERT_EQUAL_32(0x1235, h[1]);
15299 ASSERT_EQUAL_32(0x12345679, w[1]);
15300 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
15301 ASSERT_EQUAL_32(0x12345679, wp[1]);
15302 ASSERT_EQUAL_32(0x87654322, wp[2]);
15303 ASSERT_EQUAL_64(0x123456789abcdef1, xp[1]);
15304 ASSERT_EQUAL_64(0x0fedcba987654322, xp[2]);
15305
15306 // Check for over-write.
15307 ASSERT_EQUAL_32(0, b[0]);
15308 ASSERT_EQUAL_32(0, b[2]);
15309 ASSERT_EQUAL_32(0, h[0]);
15310 ASSERT_EQUAL_32(0, h[2]);
15311 ASSERT_EQUAL_32(0, w[0]);
15312 ASSERT_EQUAL_32(0, w[2]);
15313 ASSERT_EQUAL_64(0, x[0]);
15314 ASSERT_EQUAL_64(0, x[2]);
15315 ASSERT_EQUAL_32(0, wp[0]);
15316 ASSERT_EQUAL_32(0, wp[3]);
15317 ASSERT_EQUAL_64(0, xp[0]);
15318 ASSERT_EQUAL_64(0, xp[3]);
15319
15320 TEARDOWN();
15321}
15322
15323
15324TEST(clrex) {
15325 // This data should never be written.
15326 uint64_t data[] = {0, 0, 0};
15327 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
15328
15329 SETUP();
15330 START();
15331
15332 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
15333 __ Mov(w6, 0);
15334
15335 __ Ldxrb(w0, MemOperand(x10));
15336 __ Clrex();
15337 __ Add(w0, w0, 1);
15338 __ Stxrb(w5, w0, MemOperand(x10));
15339 __ Add(w6, w6, w5);
15340
15341 __ Ldxrh(w0, MemOperand(x10));
15342 __ Clrex();
15343 __ Add(w0, w0, 1);
15344 __ Stxrh(w5, w0, MemOperand(x10));
15345 __ Add(w6, w6, w5);
15346
15347 __ Ldxr(w0, MemOperand(x10));
15348 __ Clrex();
15349 __ Add(w0, w0, 1);
15350 __ Stxr(w5, w0, MemOperand(x10));
15351 __ Add(w6, w6, w5);
15352
15353 __ Ldxr(x0, MemOperand(x10));
15354 __ Clrex();
15355 __ Add(x0, x0, 1);
15356 __ Stxr(w5, x0, MemOperand(x10));
15357 __ Add(w6, w6, w5);
15358
15359 __ Ldxp(w0, w1, MemOperand(x10));
15360 __ Clrex();
15361 __ Add(w0, w0, 1);
15362 __ Add(w1, w1, 1);
15363 __ Stxp(w5, w0, w1, MemOperand(x10));
15364 __ Add(w6, w6, w5);
15365
15366 __ Ldxp(x0, x1, MemOperand(x10));
15367 __ Clrex();
15368 __ Add(x0, x0, 1);
15369 __ Add(x1, x1, 1);
15370 __ Stxp(w5, x0, x1, MemOperand(x10));
15371 __ Add(w6, w6, w5);
15372
15373 // Acquire-release variants.
15374
15375 __ Ldaxrb(w0, MemOperand(x10));
15376 __ Clrex();
15377 __ Add(w0, w0, 1);
15378 __ Stlxrb(w5, w0, MemOperand(x10));
15379 __ Add(w6, w6, w5);
15380
15381 __ Ldaxrh(w0, MemOperand(x10));
15382 __ Clrex();
15383 __ Add(w0, w0, 1);
15384 __ Stlxrh(w5, w0, MemOperand(x10));
15385 __ Add(w6, w6, w5);
15386
15387 __ Ldaxr(w0, MemOperand(x10));
15388 __ Clrex();
15389 __ Add(w0, w0, 1);
15390 __ Stlxr(w5, w0, MemOperand(x10));
15391 __ Add(w6, w6, w5);
15392
15393 __ Ldaxr(x0, MemOperand(x10));
15394 __ Clrex();
15395 __ Add(x0, x0, 1);
15396 __ Stlxr(w5, x0, MemOperand(x10));
15397 __ Add(w6, w6, w5);
15398
15399 __ Ldaxp(w0, w1, MemOperand(x10));
15400 __ Clrex();
15401 __ Add(w0, w0, 1);
15402 __ Add(w1, w1, 1);
15403 __ Stlxp(w5, w0, w1, MemOperand(x10));
15404 __ Add(w6, w6, w5);
15405
15406 __ Ldaxp(x0, x1, MemOperand(x10));
15407 __ Clrex();
15408 __ Add(x0, x0, 1);
15409 __ Add(x1, x1, 1);
15410 __ Stlxp(w5, x0, x1, MemOperand(x10));
15411 __ Add(w6, w6, w5);
15412
15413 END();
15414 RUN();
15415
15416 // None of the 12 store-exclusives should have succeeded.
15417 ASSERT_EQUAL_32(12, w6);
15418
15419 ASSERT_EQUAL_64(0, data[0]);
15420 ASSERT_EQUAL_64(0, data[1]);
15421 ASSERT_EQUAL_64(0, data[2]);
armvixldb644342015-07-21 11:37:10 +010015422
15423 TEARDOWN();
armvixl4a102ba2014-07-14 09:02:40 +010015424}
15425
15426
armvixl684cd2a2015-10-23 13:38:33 +010015427#ifdef VIXL_INCLUDE_SIMULATOR
armvixl4a102ba2014-07-14 09:02:40 +010015428// Check that the simulator occasionally makes store-exclusive fail.
15429TEST(ldxr_stxr_fail) {
15430 uint64_t data[] = {0, 0, 0};
15431 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
15432
15433 // Impose a hard limit on the number of attempts, so the test cannot hang.
15434 static const uint64_t kWatchdog = 10000;
15435 Label done;
15436
15437 SETUP();
15438 START();
15439
15440 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
15441 __ Mov(x11, kWatchdog);
15442
15443 // This loop is the opposite of what we normally do with ldxr and stxr; we
15444 // keep trying until we fail (or the watchdog counter runs out).
15445 Label try_b;
15446 __ Bind(&try_b);
15447 __ Ldxrb(w0, MemOperand(x10));
15448 __ Stxrb(w5, w0, MemOperand(x10));
15449 // Check the watchdog counter.
15450 __ Sub(x11, x11, 1);
15451 __ Cbz(x11, &done);
15452 // Check the exclusive-store result.
15453 __ Cbz(w5, &try_b);
15454
15455 Label try_h;
15456 __ Bind(&try_h);
15457 __ Ldxrh(w0, MemOperand(x10));
15458 __ Stxrh(w5, w0, MemOperand(x10));
15459 __ Sub(x11, x11, 1);
15460 __ Cbz(x11, &done);
15461 __ Cbz(w5, &try_h);
15462
15463 Label try_w;
15464 __ Bind(&try_w);
15465 __ Ldxr(w0, MemOperand(x10));
15466 __ Stxr(w5, w0, MemOperand(x10));
15467 __ Sub(x11, x11, 1);
15468 __ Cbz(x11, &done);
15469 __ Cbz(w5, &try_w);
15470
15471 Label try_x;
15472 __ Bind(&try_x);
15473 __ Ldxr(x0, MemOperand(x10));
15474 __ Stxr(w5, x0, MemOperand(x10));
15475 __ Sub(x11, x11, 1);
15476 __ Cbz(x11, &done);
15477 __ Cbz(w5, &try_x);
15478
15479 Label try_wp;
15480 __ Bind(&try_wp);
15481 __ Ldxp(w0, w1, MemOperand(x10));
15482 __ Stxp(w5, w0, w1, MemOperand(x10));
15483 __ Sub(x11, x11, 1);
15484 __ Cbz(x11, &done);
15485 __ Cbz(w5, &try_wp);
15486
15487 Label try_xp;
15488 __ Bind(&try_xp);
15489 __ Ldxp(x0, x1, MemOperand(x10));
15490 __ Stxp(w5, x0, x1, MemOperand(x10));
15491 __ Sub(x11, x11, 1);
15492 __ Cbz(x11, &done);
15493 __ Cbz(w5, &try_xp);
15494
15495 __ Bind(&done);
15496 // Trigger an error if x11 (watchdog) is zero.
15497 __ Cmp(x11, 0);
15498 __ Cset(x12, eq);
15499
15500 END();
15501 RUN();
15502
15503 // Check that the watchdog counter didn't run out.
15504 ASSERT_EQUAL_64(0, x12);
armvixldb644342015-07-21 11:37:10 +010015505
15506 TEARDOWN();
armvixl4a102ba2014-07-14 09:02:40 +010015507}
15508#endif
15509
15510
armvixl684cd2a2015-10-23 13:38:33 +010015511#ifdef VIXL_INCLUDE_SIMULATOR
armvixl4a102ba2014-07-14 09:02:40 +010015512// Check that the simulator occasionally makes store-exclusive fail.
15513TEST(ldaxr_stlxr_fail) {
15514 uint64_t data[] = {0, 0, 0};
15515 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
15516
15517 // Impose a hard limit on the number of attempts, so the test cannot hang.
15518 static const uint64_t kWatchdog = 10000;
15519 Label done;
15520
15521 SETUP();
15522 START();
15523
15524 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
15525 __ Mov(x11, kWatchdog);
15526
15527 // This loop is the opposite of what we normally do with ldxr and stxr; we
15528 // keep trying until we fail (or the watchdog counter runs out).
15529 Label try_b;
15530 __ Bind(&try_b);
15531 __ Ldxrb(w0, MemOperand(x10));
15532 __ Stxrb(w5, w0, MemOperand(x10));
15533 // Check the watchdog counter.
15534 __ Sub(x11, x11, 1);
15535 __ Cbz(x11, &done);
15536 // Check the exclusive-store result.
15537 __ Cbz(w5, &try_b);
15538
15539 Label try_h;
15540 __ Bind(&try_h);
15541 __ Ldaxrh(w0, MemOperand(x10));
15542 __ Stlxrh(w5, w0, MemOperand(x10));
15543 __ Sub(x11, x11, 1);
15544 __ Cbz(x11, &done);
15545 __ Cbz(w5, &try_h);
15546
15547 Label try_w;
15548 __ Bind(&try_w);
15549 __ Ldaxr(w0, MemOperand(x10));
15550 __ Stlxr(w5, w0, MemOperand(x10));
15551 __ Sub(x11, x11, 1);
15552 __ Cbz(x11, &done);
15553 __ Cbz(w5, &try_w);
15554
15555 Label try_x;
15556 __ Bind(&try_x);
15557 __ Ldaxr(x0, MemOperand(x10));
15558 __ Stlxr(w5, x0, MemOperand(x10));
15559 __ Sub(x11, x11, 1);
15560 __ Cbz(x11, &done);
15561 __ Cbz(w5, &try_x);
15562
15563 Label try_wp;
15564 __ Bind(&try_wp);
15565 __ Ldaxp(w0, w1, MemOperand(x10));
15566 __ Stlxp(w5, w0, w1, MemOperand(x10));
15567 __ Sub(x11, x11, 1);
15568 __ Cbz(x11, &done);
15569 __ Cbz(w5, &try_wp);
15570
15571 Label try_xp;
15572 __ Bind(&try_xp);
15573 __ Ldaxp(x0, x1, MemOperand(x10));
15574 __ Stlxp(w5, x0, x1, MemOperand(x10));
15575 __ Sub(x11, x11, 1);
15576 __ Cbz(x11, &done);
15577 __ Cbz(w5, &try_xp);
15578
15579 __ Bind(&done);
15580 // Trigger an error if x11 (watchdog) is zero.
15581 __ Cmp(x11, 0);
15582 __ Cset(x12, eq);
15583
15584 END();
15585 RUN();
15586
15587 // Check that the watchdog counter didn't run out.
15588 ASSERT_EQUAL_64(0, x12);
armvixldb644342015-07-21 11:37:10 +010015589
15590 TEARDOWN();
armvixl4a102ba2014-07-14 09:02:40 +010015591}
15592#endif
15593
15594
15595TEST(load_store_tagged_immediate_offset) {
15596 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15597 int tag_count = sizeof(tags) / sizeof(tags[0]);
15598
armvixl5289c592015-03-02 13:52:04 +000015599 const int kMaxDataLength = 160;
armvixl4a102ba2014-07-14 09:02:40 +010015600
15601 for (int i = 0; i < tag_count; i++) {
15602 unsigned char src[kMaxDataLength];
15603 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
15604 uint64_t src_tag = tags[i];
15605 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
15606
15607 for (int k = 0; k < kMaxDataLength; k++) {
15608 src[k] = k + 1;
15609 }
15610
15611 for (int j = 0; j < tag_count; j++) {
15612 unsigned char dst[kMaxDataLength];
15613 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
15614 uint64_t dst_tag = tags[j];
15615 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
15616
15617 memset(dst, 0, kMaxDataLength);
15618
15619 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015620 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010015621 START();
15622
15623 __ Mov(x0, src_tagged);
15624 __ Mov(x1, dst_tagged);
15625
15626 int offset = 0;
15627
15628 // Scaled-immediate offsets.
armvixl5289c592015-03-02 13:52:04 +000015629 __ ldp(q0, q1, MemOperand(x0, offset));
15630 __ stp(q0, q1, MemOperand(x1, offset));
15631 offset += 2 * kQRegSizeInBytes;
armvixl4a102ba2014-07-14 09:02:40 +010015632
15633 __ ldp(x2, x3, MemOperand(x0, offset));
15634 __ stp(x2, x3, MemOperand(x1, offset));
15635 offset += 2 * kXRegSizeInBytes;
15636
15637 __ ldpsw(x2, x3, MemOperand(x0, offset));
15638 __ stp(w2, w3, MemOperand(x1, offset));
15639 offset += 2 * kWRegSizeInBytes;
15640
15641 __ ldp(d0, d1, MemOperand(x0, offset));
15642 __ stp(d0, d1, MemOperand(x1, offset));
15643 offset += 2 * kDRegSizeInBytes;
15644
15645 __ ldp(w2, w3, MemOperand(x0, offset));
15646 __ stp(w2, w3, MemOperand(x1, offset));
15647 offset += 2 * kWRegSizeInBytes;
15648
15649 __ ldp(s0, s1, MemOperand(x0, offset));
15650 __ stp(s0, s1, MemOperand(x1, offset));
15651 offset += 2 * kSRegSizeInBytes;
15652
15653 __ ldr(x2, MemOperand(x0, offset), RequireScaledOffset);
15654 __ str(x2, MemOperand(x1, offset), RequireScaledOffset);
15655 offset += kXRegSizeInBytes;
15656
15657 __ ldr(d0, MemOperand(x0, offset), RequireScaledOffset);
15658 __ str(d0, MemOperand(x1, offset), RequireScaledOffset);
15659 offset += kDRegSizeInBytes;
15660
15661 __ ldr(w2, MemOperand(x0, offset), RequireScaledOffset);
15662 __ str(w2, MemOperand(x1, offset), RequireScaledOffset);
15663 offset += kWRegSizeInBytes;
15664
15665 __ ldr(s0, MemOperand(x0, offset), RequireScaledOffset);
15666 __ str(s0, MemOperand(x1, offset), RequireScaledOffset);
15667 offset += kSRegSizeInBytes;
15668
15669 __ ldrh(w2, MemOperand(x0, offset), RequireScaledOffset);
15670 __ strh(w2, MemOperand(x1, offset), RequireScaledOffset);
15671 offset += 2;
15672
15673 __ ldrsh(w2, MemOperand(x0, offset), RequireScaledOffset);
15674 __ strh(w2, MemOperand(x1, offset), RequireScaledOffset);
15675 offset += 2;
15676
15677 __ ldrb(w2, MemOperand(x0, offset), RequireScaledOffset);
15678 __ strb(w2, MemOperand(x1, offset), RequireScaledOffset);
15679 offset += 1;
15680
15681 __ ldrsb(w2, MemOperand(x0, offset), RequireScaledOffset);
15682 __ strb(w2, MemOperand(x1, offset), RequireScaledOffset);
15683 offset += 1;
15684
15685 // Unscaled-immediate offsets.
15686
15687 __ ldur(x2, MemOperand(x0, offset), RequireUnscaledOffset);
15688 __ stur(x2, MemOperand(x1, offset), RequireUnscaledOffset);
15689 offset += kXRegSizeInBytes;
15690
15691 __ ldur(d0, MemOperand(x0, offset), RequireUnscaledOffset);
15692 __ stur(d0, MemOperand(x1, offset), RequireUnscaledOffset);
15693 offset += kDRegSizeInBytes;
15694
15695 __ ldur(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15696 __ stur(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15697 offset += kWRegSizeInBytes;
15698
15699 __ ldur(s0, MemOperand(x0, offset), RequireUnscaledOffset);
15700 __ stur(s0, MemOperand(x1, offset), RequireUnscaledOffset);
15701 offset += kSRegSizeInBytes;
15702
15703 __ ldurh(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15704 __ sturh(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15705 offset += 2;
15706
15707 __ ldursh(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15708 __ sturh(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15709 offset += 2;
15710
15711 __ ldurb(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15712 __ sturb(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15713 offset += 1;
15714
15715 __ ldursb(w2, MemOperand(x0, offset), RequireUnscaledOffset);
15716 __ sturb(w2, MemOperand(x1, offset), RequireUnscaledOffset);
15717 offset += 1;
15718
15719 // Extract the tag (so we can test that it was preserved correctly).
15720 __ Ubfx(x0, x0, kAddressTagOffset, kAddressTagWidth);
15721 __ Ubfx(x1, x1, kAddressTagOffset, kAddressTagWidth);
15722
15723 VIXL_ASSERT(kMaxDataLength >= offset);
15724
15725 END();
15726 RUN();
15727
15728 ASSERT_EQUAL_64(src_tag, x0);
15729 ASSERT_EQUAL_64(dst_tag, x1);
15730
15731 for (int k = 0; k < offset; k++) {
15732 VIXL_CHECK(src[k] == dst[k]);
15733 }
15734
15735 TEARDOWN();
15736 }
15737 }
15738}
15739
15740
15741TEST(load_store_tagged_immediate_preindex) {
15742 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15743 int tag_count = sizeof(tags) / sizeof(tags[0]);
15744
15745 const int kMaxDataLength = 128;
15746
15747 for (int i = 0; i < tag_count; i++) {
15748 unsigned char src[kMaxDataLength];
15749 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
15750 uint64_t src_tag = tags[i];
15751 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
15752
15753 for (int k = 0; k < kMaxDataLength; k++) {
15754 src[k] = k + 1;
15755 }
15756
15757 for (int j = 0; j < tag_count; j++) {
15758 unsigned char dst[kMaxDataLength];
15759 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
15760 uint64_t dst_tag = tags[j];
15761 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
15762
15763 for (int k = 0; k < kMaxDataLength; k++) {
15764 dst[k] = 0;
15765 }
15766
15767 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015768 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010015769 START();
15770
15771 // Each MemOperand must apply a pre-index equal to the size of the
15772 // previous access.
15773
15774 // Start with a non-zero preindex.
armvixl5289c592015-03-02 13:52:04 +000015775 int preindex = 62 * kXRegSizeInBytes;
armvixlc68cb642014-09-25 18:49:30 +010015776 int data_length = 0;
armvixl4a102ba2014-07-14 09:02:40 +010015777
15778 __ Mov(x0, src_tagged - preindex);
15779 __ Mov(x1, dst_tagged - preindex);
15780
armvixl5289c592015-03-02 13:52:04 +000015781 __ ldp(q0, q1, MemOperand(x0, preindex, PreIndex));
15782 __ stp(q0, q1, MemOperand(x1, preindex, PreIndex));
15783 preindex = 2 * kQRegSizeInBytes;
15784 data_length = preindex;
15785
armvixl4a102ba2014-07-14 09:02:40 +010015786 __ ldp(x2, x3, MemOperand(x0, preindex, PreIndex));
15787 __ stp(x2, x3, MemOperand(x1, preindex, PreIndex));
15788 preindex = 2 * kXRegSizeInBytes;
armvixl5289c592015-03-02 13:52:04 +000015789 data_length += preindex;
armvixl4a102ba2014-07-14 09:02:40 +010015790
15791 __ ldpsw(x2, x3, MemOperand(x0, preindex, PreIndex));
15792 __ stp(w2, w3, MemOperand(x1, preindex, PreIndex));
15793 preindex = 2 * kWRegSizeInBytes;
15794 data_length += preindex;
15795
15796 __ ldp(d0, d1, MemOperand(x0, preindex, PreIndex));
15797 __ stp(d0, d1, MemOperand(x1, preindex, PreIndex));
15798 preindex = 2 * kDRegSizeInBytes;
15799 data_length += preindex;
15800
15801 __ ldp(w2, w3, MemOperand(x0, preindex, PreIndex));
15802 __ stp(w2, w3, MemOperand(x1, preindex, PreIndex));
15803 preindex = 2 * kWRegSizeInBytes;
15804 data_length += preindex;
15805
15806 __ ldp(s0, s1, MemOperand(x0, preindex, PreIndex));
15807 __ stp(s0, s1, MemOperand(x1, preindex, PreIndex));
15808 preindex = 2 * kSRegSizeInBytes;
15809 data_length += preindex;
15810
15811 __ ldr(x2, MemOperand(x0, preindex, PreIndex));
15812 __ str(x2, MemOperand(x1, preindex, PreIndex));
15813 preindex = kXRegSizeInBytes;
15814 data_length += preindex;
15815
15816 __ ldr(d0, MemOperand(x0, preindex, PreIndex));
15817 __ str(d0, MemOperand(x1, preindex, PreIndex));
15818 preindex = kDRegSizeInBytes;
15819 data_length += preindex;
15820
15821 __ ldr(w2, MemOperand(x0, preindex, PreIndex));
15822 __ str(w2, MemOperand(x1, preindex, PreIndex));
15823 preindex = kWRegSizeInBytes;
15824 data_length += preindex;
15825
15826 __ ldr(s0, MemOperand(x0, preindex, PreIndex));
15827 __ str(s0, MemOperand(x1, preindex, PreIndex));
15828 preindex = kSRegSizeInBytes;
15829 data_length += preindex;
15830
15831 __ ldrh(w2, MemOperand(x0, preindex, PreIndex));
15832 __ strh(w2, MemOperand(x1, preindex, PreIndex));
15833 preindex = 2;
15834 data_length += preindex;
15835
15836 __ ldrsh(w2, MemOperand(x0, preindex, PreIndex));
15837 __ strh(w2, MemOperand(x1, preindex, PreIndex));
15838 preindex = 2;
15839 data_length += preindex;
15840
15841 __ ldrb(w2, MemOperand(x0, preindex, PreIndex));
15842 __ strb(w2, MemOperand(x1, preindex, PreIndex));
15843 preindex = 1;
15844 data_length += preindex;
15845
15846 __ ldrsb(w2, MemOperand(x0, preindex, PreIndex));
15847 __ strb(w2, MemOperand(x1, preindex, PreIndex));
15848 preindex = 1;
15849 data_length += preindex;
15850
15851 VIXL_ASSERT(kMaxDataLength >= data_length);
15852
15853 END();
15854 RUN();
15855
15856 // Check that the preindex was correctly applied in each operation, and
15857 // that the tag was preserved.
15858 ASSERT_EQUAL_64(src_tagged + data_length - preindex, x0);
15859 ASSERT_EQUAL_64(dst_tagged + data_length - preindex, x1);
15860
15861 for (int k = 0; k < data_length; k++) {
15862 VIXL_CHECK(src[k] == dst[k]);
15863 }
15864
15865 TEARDOWN();
15866 }
15867 }
15868}
15869
15870
15871TEST(load_store_tagged_immediate_postindex) {
15872 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15873 int tag_count = sizeof(tags) / sizeof(tags[0]);
15874
15875 const int kMaxDataLength = 128;
15876
15877 for (int i = 0; i < tag_count; i++) {
15878 unsigned char src[kMaxDataLength];
15879 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
15880 uint64_t src_tag = tags[i];
15881 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
15882
15883 for (int k = 0; k < kMaxDataLength; k++) {
15884 src[k] = k + 1;
15885 }
15886
15887 for (int j = 0; j < tag_count; j++) {
15888 unsigned char dst[kMaxDataLength];
15889 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
15890 uint64_t dst_tag = tags[j];
15891 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
15892
15893 for (int k = 0; k < kMaxDataLength; k++) {
15894 dst[k] = 0;
15895 }
15896
15897 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010015898 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010015899 START();
15900
armvixlc68cb642014-09-25 18:49:30 +010015901 int postindex = 2 * kXRegSizeInBytes;
15902 int data_length = 0;
15903
armvixl4a102ba2014-07-14 09:02:40 +010015904 __ Mov(x0, src_tagged);
15905 __ Mov(x1, dst_tagged);
15906
armvixl4a102ba2014-07-14 09:02:40 +010015907 __ ldp(x2, x3, MemOperand(x0, postindex, PostIndex));
15908 __ stp(x2, x3, MemOperand(x1, postindex, PostIndex));
armvixlc68cb642014-09-25 18:49:30 +010015909 data_length = postindex;
armvixl4a102ba2014-07-14 09:02:40 +010015910
armvixl5289c592015-03-02 13:52:04 +000015911 postindex = 2 * kQRegSizeInBytes;
15912 __ ldp(q0, q1, MemOperand(x0, postindex, PostIndex));
15913 __ stp(q0, q1, MemOperand(x1, postindex, PostIndex));
15914 data_length += postindex;
15915
armvixl4a102ba2014-07-14 09:02:40 +010015916 postindex = 2 * kWRegSizeInBytes;
15917 __ ldpsw(x2, x3, MemOperand(x0, postindex, PostIndex));
15918 __ stp(w2, w3, MemOperand(x1, postindex, PostIndex));
15919 data_length += postindex;
15920
15921 postindex = 2 * kDRegSizeInBytes;
15922 __ ldp(d0, d1, MemOperand(x0, postindex, PostIndex));
15923 __ stp(d0, d1, MemOperand(x1, postindex, PostIndex));
15924 data_length += postindex;
15925
15926 postindex = 2 * kWRegSizeInBytes;
15927 __ ldp(w2, w3, MemOperand(x0, postindex, PostIndex));
15928 __ stp(w2, w3, MemOperand(x1, postindex, PostIndex));
15929 data_length += postindex;
15930
15931 postindex = 2 * kSRegSizeInBytes;
15932 __ ldp(s0, s1, MemOperand(x0, postindex, PostIndex));
15933 __ stp(s0, s1, MemOperand(x1, postindex, PostIndex));
15934 data_length += postindex;
15935
15936 postindex = kXRegSizeInBytes;
15937 __ ldr(x2, MemOperand(x0, postindex, PostIndex));
15938 __ str(x2, MemOperand(x1, postindex, PostIndex));
15939 data_length += postindex;
15940
15941 postindex = kDRegSizeInBytes;
15942 __ ldr(d0, MemOperand(x0, postindex, PostIndex));
15943 __ str(d0, MemOperand(x1, postindex, PostIndex));
15944 data_length += postindex;
15945
15946 postindex = kWRegSizeInBytes;
15947 __ ldr(w2, MemOperand(x0, postindex, PostIndex));
15948 __ str(w2, MemOperand(x1, postindex, PostIndex));
15949 data_length += postindex;
15950
15951 postindex = kSRegSizeInBytes;
15952 __ ldr(s0, MemOperand(x0, postindex, PostIndex));
15953 __ str(s0, MemOperand(x1, postindex, PostIndex));
15954 data_length += postindex;
15955
15956 postindex = 2;
15957 __ ldrh(w2, MemOperand(x0, postindex, PostIndex));
15958 __ strh(w2, MemOperand(x1, postindex, PostIndex));
15959 data_length += postindex;
15960
15961 postindex = 2;
15962 __ ldrsh(w2, MemOperand(x0, postindex, PostIndex));
15963 __ strh(w2, MemOperand(x1, postindex, PostIndex));
15964 data_length += postindex;
15965
15966 postindex = 1;
15967 __ ldrb(w2, MemOperand(x0, postindex, PostIndex));
15968 __ strb(w2, MemOperand(x1, postindex, PostIndex));
15969 data_length += postindex;
15970
15971 postindex = 1;
15972 __ ldrsb(w2, MemOperand(x0, postindex, PostIndex));
15973 __ strb(w2, MemOperand(x1, postindex, PostIndex));
15974 data_length += postindex;
15975
15976 VIXL_ASSERT(kMaxDataLength >= data_length);
15977
15978 END();
15979 RUN();
15980
15981 // Check that the postindex was correctly applied in each operation, and
15982 // that the tag was preserved.
15983 ASSERT_EQUAL_64(src_tagged + data_length, x0);
15984 ASSERT_EQUAL_64(dst_tagged + data_length, x1);
15985
15986 for (int k = 0; k < data_length; k++) {
15987 VIXL_CHECK(src[k] == dst[k]);
15988 }
15989
15990 TEARDOWN();
15991 }
15992 }
15993}
15994
15995
15996TEST(load_store_tagged_register_offset) {
15997 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
15998 int tag_count = sizeof(tags) / sizeof(tags[0]);
15999
16000 const int kMaxDataLength = 128;
16001
16002 for (int i = 0; i < tag_count; i++) {
16003 unsigned char src[kMaxDataLength];
16004 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
16005 uint64_t src_tag = tags[i];
16006 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
16007
16008 for (int k = 0; k < kMaxDataLength; k++) {
16009 src[k] = k + 1;
16010 }
16011
16012 for (int j = 0; j < tag_count; j++) {
16013 unsigned char dst[kMaxDataLength];
16014 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
16015 uint64_t dst_tag = tags[j];
16016 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
16017
16018 // Also tag the offset register; the operation should still succeed.
16019 for (int o = 0; o < tag_count; o++) {
16020 uint64_t offset_base = CPU::SetPointerTag(UINT64_C(0), tags[o]);
16021 int data_length = 0;
16022
16023 for (int k = 0; k < kMaxDataLength; k++) {
16024 dst[k] = 0;
16025 }
16026
16027 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010016028 ALLOW_ASM();
armvixl4a102ba2014-07-14 09:02:40 +010016029 START();
16030
16031 __ Mov(x0, src_tagged);
16032 __ Mov(x1, dst_tagged);
16033
16034 __ Mov(x10, offset_base + data_length);
16035 __ ldr(x2, MemOperand(x0, x10));
16036 __ str(x2, MemOperand(x1, x10));
16037 data_length += kXRegSizeInBytes;
16038
16039 __ Mov(x10, offset_base + data_length);
16040 __ ldr(d0, MemOperand(x0, x10));
16041 __ str(d0, MemOperand(x1, x10));
16042 data_length += kDRegSizeInBytes;
16043
16044 __ Mov(x10, offset_base + data_length);
16045 __ ldr(w2, MemOperand(x0, x10));
16046 __ str(w2, MemOperand(x1, x10));
16047 data_length += kWRegSizeInBytes;
16048
16049 __ Mov(x10, offset_base + data_length);
16050 __ ldr(s0, MemOperand(x0, x10));
16051 __ str(s0, MemOperand(x1, x10));
16052 data_length += kSRegSizeInBytes;
16053
16054 __ Mov(x10, offset_base + data_length);
16055 __ ldrh(w2, MemOperand(x0, x10));
16056 __ strh(w2, MemOperand(x1, x10));
16057 data_length += 2;
16058
16059 __ Mov(x10, offset_base + data_length);
16060 __ ldrsh(w2, MemOperand(x0, x10));
16061 __ strh(w2, MemOperand(x1, x10));
16062 data_length += 2;
16063
16064 __ Mov(x10, offset_base + data_length);
16065 __ ldrb(w2, MemOperand(x0, x10));
16066 __ strb(w2, MemOperand(x1, x10));
16067 data_length += 1;
16068
16069 __ Mov(x10, offset_base + data_length);
16070 __ ldrsb(w2, MemOperand(x0, x10));
16071 __ strb(w2, MemOperand(x1, x10));
16072 data_length += 1;
16073
16074 VIXL_ASSERT(kMaxDataLength >= data_length);
16075
16076 END();
16077 RUN();
16078
16079 // Check that the postindex was correctly applied in each operation, and
16080 // that the tag was preserved.
16081 ASSERT_EQUAL_64(src_tagged, x0);
16082 ASSERT_EQUAL_64(dst_tagged, x1);
16083 ASSERT_EQUAL_64(offset_base + data_length - 1, x10);
16084
16085 for (int k = 0; k < data_length; k++) {
16086 VIXL_CHECK(src[k] == dst[k]);
16087 }
16088
16089 TEARDOWN();
16090 }
16091 }
16092 }
16093}
16094
16095
armvixl5289c592015-03-02 13:52:04 +000016096TEST(load_store_tagged_register_postindex) {
16097 uint64_t src[] = { 0x0706050403020100, 0x0f0e0d0c0b0a0908 };
16098 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
16099 int tag_count = sizeof(tags) / sizeof(tags[0]);
16100
16101 for (int j = 0; j < tag_count; j++) {
16102 for (int i = 0; i < tag_count; i++) {
16103 SETUP();
16104 uint64_t src_base = reinterpret_cast<uint64_t>(src);
16105 uint64_t src_tagged = CPU::SetPointerTag(src_base, tags[i]);
16106 uint64_t offset_tagged = CPU::SetPointerTag(UINT64_C(0), tags[j]);
16107
16108 START();
16109 __ Mov(x10, src_tagged);
16110 __ Mov(x11, offset_tagged);
16111 __ Ld1(v0.V16B(), MemOperand(x10, x11, PostIndex));
16112 // TODO: add other instructions (ld2-4, st1-4) as they become available.
16113 END();
16114
16115 RUN();
16116
16117 ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q0);
16118 ASSERT_EQUAL_64(src_tagged + offset_tagged, x10);
16119
16120 TEARDOWN();
16121 }
16122 }
16123}
16124
16125
armvixlc68cb642014-09-25 18:49:30 +010016126TEST(branch_tagged) {
16127 SETUP();
16128 START();
16129
16130 Label loop, loop_entry, done;
16131 __ Adr(x0, &loop);
16132 __ Mov(x1, 0);
16133 __ B(&loop_entry);
16134
16135 __ Bind(&loop);
16136 __ Add(x1, x1, 1); // Count successful jumps.
16137
16138 // Advance to the next tag, then bail out if we've come back around to tag 0.
16139 __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
16140 __ Tst(x0, kAddressTagMask);
16141 __ B(eq, &done);
16142
16143 __ Bind(&loop_entry);
16144 __ Br(x0);
16145
16146 __ Bind(&done);
16147
16148 END();
16149 RUN();
16150
16151 ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
16152
16153 TEARDOWN();
16154}
16155
16156
16157TEST(branch_and_link_tagged) {
16158 SETUP();
16159 START();
16160
16161 Label loop, loop_entry, done;
16162 __ Adr(x0, &loop);
16163 __ Mov(x1, 0);
16164 __ B(&loop_entry);
16165
16166 __ Bind(&loop);
16167
16168 // Bail out (before counting a successful jump) if lr appears to be tagged.
16169 __ Tst(lr, kAddressTagMask);
16170 __ B(ne, &done);
16171
16172 __ Add(x1, x1, 1); // Count successful jumps.
16173
16174 // Advance to the next tag, then bail out if we've come back around to tag 0.
16175 __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
16176 __ Tst(x0, kAddressTagMask);
16177 __ B(eq, &done);
16178
16179 __ Bind(&loop_entry);
16180 __ Blr(x0);
16181
16182 __ Bind(&done);
16183
16184 END();
16185 RUN();
16186
16187 ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
16188
16189 TEARDOWN();
16190}
16191
16192
16193TEST(branch_tagged_and_adr_adrp) {
16194 SETUP_CUSTOM(BUF_SIZE, PageOffsetDependentCode);
16195 START();
16196
16197 Label loop, loop_entry, done;
16198 __ Adr(x0, &loop);
16199 __ Mov(x1, 0);
16200 __ B(&loop_entry);
16201
16202 __ Bind(&loop);
16203
16204 // Bail out (before counting a successful jump) if `adr x10, ...` is tagged.
16205 __ Adr(x10, &done);
16206 __ Tst(x10, kAddressTagMask);
16207 __ B(ne, &done);
16208
16209 // Bail out (before counting a successful jump) if `adrp x11, ...` is tagged.
16210 __ Adrp(x11, &done);
16211 __ Tst(x11, kAddressTagMask);
16212 __ B(ne, &done);
16213
16214 __ Add(x1, x1, 1); // Count successful iterations.
16215
16216 // Advance to the next tag, then bail out if we've come back around to tag 0.
16217 __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
16218 __ Tst(x0, kAddressTagMask);
16219 __ B(eq, &done);
16220
16221 __ Bind(&loop_entry);
16222 __ Br(x0);
16223
16224 __ Bind(&done);
16225
16226 END();
16227 RUN();
16228
16229 ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
16230
armvixldb644342015-07-21 11:37:10 +010016231 TEARDOWN_CUSTOM();
armvixlc68cb642014-09-25 18:49:30 +010016232}
16233
armvixl5289c592015-03-02 13:52:04 +000016234TEST(neon_3same_addp) {
16235 SETUP();
armvixlc68cb642014-09-25 18:49:30 +010016236
armvixl5289c592015-03-02 13:52:04 +000016237 START();
16238
16239 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16240 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16241 __ Addp(v16.V16B(), v0.V16B(), v1.V16B());
16242
16243 END();
16244
16245 RUN();
16246 ASSERT_EQUAL_128(0x00ff54ffff54aaff, 0xffffffffffffffff, q16);
16247 TEARDOWN();
16248}
16249
16250TEST(neon_3same_sqdmulh_sqrdmulh) {
16251 SETUP();
16252
16253 START();
16254
16255 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000040004008000);
16256 __ Movi(v1.V2D(), 0x0000000000000000, 0x0000002000108000);
16257 __ Movi(v2.V2D(), 0x0400000080000000, 0x0400000080000000);
16258 __ Movi(v3.V2D(), 0x0000002080000000, 0x0000001080000000);
16259
16260 __ Sqdmulh(v16.V4H(), v0.V4H(), v1.V4H());
16261 __ Sqdmulh(v17.V4S(), v2.V4S(), v3.V4S());
16262 __ Sqdmulh(h18, h0, h1);
16263 __ Sqdmulh(s19, s2, s3);
16264
16265 __ Sqrdmulh(v20.V4H(), v0.V4H(), v1.V4H());
16266 __ Sqrdmulh(v21.V4S(), v2.V4S(), v3.V4S());
16267 __ Sqrdmulh(h22, h0, h1);
16268 __ Sqrdmulh(s23, s2, s3);
16269
16270 END();
16271
16272 RUN();
16273 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000100007fff, q16);
16274 ASSERT_EQUAL_128(0x000000017fffffff, 0x000000007fffffff, q17);
16275 ASSERT_EQUAL_128(0, 0x7fff, q18);
16276 ASSERT_EQUAL_128(0, 0x7fffffff, q19);
16277 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000100017fff, q20);
16278 ASSERT_EQUAL_128(0x000000017fffffff, 0x000000017fffffff, q21);
16279 ASSERT_EQUAL_128(0, 0x7fff, q22);
16280 ASSERT_EQUAL_128(0, 0x7fffffff, q23);
16281 TEARDOWN();
16282}
16283
16284TEST(neon_byelement_sqdmulh_sqrdmulh) {
16285 SETUP();
16286
16287 START();
16288
16289 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000040004008000);
16290 __ Movi(v1.V2D(), 0x0000000000000000, 0x0000002000108000);
16291 __ Movi(v2.V2D(), 0x0400000080000000, 0x0400000080000000);
16292 __ Movi(v3.V2D(), 0x0000002080000000, 0x0000001080000000);
16293
16294 __ Sqdmulh(v16.V4H(), v0.V4H(), v1.H(), 1);
16295 __ Sqdmulh(v17.V4S(), v2.V4S(), v3.S(), 1);
16296 __ Sqdmulh(h18, h0, v1.H(), 0);
16297 __ Sqdmulh(s19, s2, v3.S(), 0);
16298
16299 __ Sqrdmulh(v20.V4H(), v0.V4H(), v1.H(), 1);
16300 __ Sqrdmulh(v21.V4S(), v2.V4S(), v3.S(), 1);
16301 __ Sqrdmulh(h22, h0, v1.H(), 0);
16302 __ Sqrdmulh(s23, s2, v3.S(), 0);
16303
16304 END();
16305
16306 RUN();
16307 ASSERT_EQUAL_128(0x0000000000000000, 0x000000000000fff0, q16);
16308 ASSERT_EQUAL_128(0x00000000fffffff0, 0x00000000fffffff0, q17);
16309 ASSERT_EQUAL_128(0, 0x7fff, q18);
16310 ASSERT_EQUAL_128(0, 0x7fffffff, q19);
16311 ASSERT_EQUAL_128(0x0000000000000000, 0x000000010001fff0, q20);
16312 ASSERT_EQUAL_128(0x00000001fffffff0, 0x00000001fffffff0, q21);
16313 ASSERT_EQUAL_128(0, 0x7fff, q22);
16314 ASSERT_EQUAL_128(0, 0x7fffffff, q23);
16315 TEARDOWN();
16316}
16317
16318
16319TEST(neon_2regmisc_saddlp) {
16320 SETUP();
16321
16322 START();
16323
16324 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16325
16326 __ Saddlp(v16.V8H(), v0.V16B());
16327 __ Saddlp(v17.V4H(), v0.V8B());
16328
16329 __ Saddlp(v18.V4S(), v0.V8H());
16330 __ Saddlp(v19.V2S(), v0.V4H());
16331
16332 __ Saddlp(v20.V2D(), v0.V4S());
16333 __ Saddlp(v21.V1D(), v0.V2S());
16334
16335 END();
16336
16337 RUN();
16338 ASSERT_EQUAL_128(0x0080ffffff010080, 0xff01ffff0080ff01, q16);
16339 ASSERT_EQUAL_128(0x0000000000000000, 0xff01ffff0080ff01, q17);
16340 ASSERT_EQUAL_128(0x0000800000000081, 0xffff7f81ffff8200, q18);
16341 ASSERT_EQUAL_128(0x0000000000000000, 0xffff7f81ffff8200, q19);
16342 ASSERT_EQUAL_128(0x0000000000818000, 0xffffffff82017f81, q20);
16343 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffff82017f81, q21);
16344 TEARDOWN();
16345}
16346
16347TEST(neon_2regmisc_uaddlp) {
16348 SETUP();
16349
16350 START();
16351
16352 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16353
16354 __ Uaddlp(v16.V8H(), v0.V16B());
16355 __ Uaddlp(v17.V4H(), v0.V8B());
16356
16357 __ Uaddlp(v18.V4S(), v0.V8H());
16358 __ Uaddlp(v19.V2S(), v0.V4H());
16359
16360 __ Uaddlp(v20.V2D(), v0.V4S());
16361 __ Uaddlp(v21.V1D(), v0.V2S());
16362
16363 END();
16364
16365 RUN();
16366 ASSERT_EQUAL_128(0x008000ff01010080, 0x010100ff00800101, q16);
16367 ASSERT_EQUAL_128(0x0000000000000000, 0x010100ff00800101, q17);
16368 ASSERT_EQUAL_128(0x0000800000010081, 0x00017f8100008200, q18);
16369 ASSERT_EQUAL_128(0x0000000000000000, 0x00017f8100008200, q19);
16370 ASSERT_EQUAL_128(0x0000000100818000, 0x0000000082017f81, q20);
16371 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000082017f81, q21);
16372 TEARDOWN();
16373}
16374
16375TEST(neon_2regmisc_sadalp) {
16376 SETUP();
16377
16378 START();
16379
16380 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16381 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
16382 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
16383 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
16384 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
16385
16386 __ Mov(v16.V16B(), v1.V16B());
16387 __ Mov(v17.V16B(), v1.V16B());
16388 __ Sadalp(v16.V8H(), v0.V16B());
16389 __ Sadalp(v17.V4H(), v0.V8B());
16390
16391 __ Mov(v18.V16B(), v2.V16B());
16392 __ Mov(v19.V16B(), v2.V16B());
16393 __ Sadalp(v18.V4S(), v1.V8H());
16394 __ Sadalp(v19.V2S(), v1.V4H());
16395
16396 __ Mov(v20.V16B(), v3.V16B());
16397 __ Mov(v21.V16B(), v4.V16B());
16398 __ Sadalp(v20.V2D(), v2.V4S());
16399 __ Sadalp(v21.V1D(), v2.V2S());
16400
16401 END();
16402
16403 RUN();
16404 ASSERT_EQUAL_128(0x80808000ff000080, 0xff00ffff00817f00, q16);
16405 ASSERT_EQUAL_128(0x0000000000000000, 0xff00ffff00817f00, q17);
16406 ASSERT_EQUAL_128(0x7fff0001fffffffe, 0xffffffff80007fff, q18);
16407 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffff80007fff, q19);
16408 ASSERT_EQUAL_128(0x7fffffff80000000, 0x800000007ffffffe, q20);
16409 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
16410 TEARDOWN();
16411}
16412
16413TEST(neon_2regmisc_uadalp) {
16414 SETUP();
16415
16416 START();
16417
16418 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
16419 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
16420 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
16421 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
16422 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
16423
16424 __ Mov(v16.V16B(), v1.V16B());
16425 __ Mov(v17.V16B(), v1.V16B());
16426 __ Uadalp(v16.V8H(), v0.V16B());
16427 __ Uadalp(v17.V4H(), v0.V8B());
16428
16429 __ Mov(v18.V16B(), v2.V16B());
16430 __ Mov(v19.V16B(), v2.V16B());
16431 __ Uadalp(v18.V4S(), v1.V8H());
16432 __ Uadalp(v19.V2S(), v1.V4H());
16433
16434 __ Mov(v20.V16B(), v3.V16B());
16435 __ Mov(v21.V16B(), v4.V16B());
16436 __ Uadalp(v20.V2D(), v2.V4S());
16437 __ Uadalp(v21.V1D(), v2.V2S());
16438
16439 END();
16440
16441 RUN();
16442 ASSERT_EQUAL_128(0x8080810001000080, 0x010000ff00818100, q16);
16443 ASSERT_EQUAL_128(0x0000000000000000, 0x010000ff00818100, q17);
16444 ASSERT_EQUAL_128(0x800100010000fffe, 0x0000ffff80007fff, q18);
16445 ASSERT_EQUAL_128(0x0000000000000000, 0x0000ffff80007fff, q19);
16446 ASSERT_EQUAL_128(0x8000000180000000, 0x800000007ffffffe, q20);
16447 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
16448 TEARDOWN();
16449}
16450
16451TEST(neon_3same_mul) {
16452 SETUP();
16453
16454 START();
16455
16456 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16457 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16458 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16459 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16460
16461 __ Mla(v16.V16B(), v0.V16B(), v1.V16B());
16462 __ Mls(v17.V16B(), v0.V16B(), v1.V16B());
16463 __ Mul(v18.V16B(), v0.V16B(), v1.V16B());
16464
16465 END();
16466
16467 RUN();
16468 ASSERT_EQUAL_128(0x0102757605b1b208, 0x5f0a61450db90f56, q16);
16469 ASSERT_EQUAL_128(0x01029192055b5c08, 0xb30ab5d30d630faa, q17);
16470 ASSERT_EQUAL_128(0x0000727200abab00, 0x5600563900ab0056, q18);
16471 TEARDOWN();
16472}
16473
16474
16475
16476TEST(neon_3same_absdiff) {
16477 SETUP();
16478
16479 START();
16480
16481 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16482 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16483 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16484 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16485
16486 __ Saba(v16.V16B(), v0.V16B(), v1.V16B());
16487 __ Uaba(v17.V16B(), v0.V16B(), v1.V16B());
16488 __ Sabd(v18.V16B(), v0.V16B(), v1.V16B());
16489 __ Uabd(v19.V16B(), v0.V16B(), v1.V16B());
16490
16491 END();
16492
16493 RUN();
16494 ASSERT_EQUAL_128(0x0202aeaf065c5d5e, 0x5e5f600c62646455, q16);
16495 ASSERT_EQUAL_128(0x0002585904b0b1b2, 0x5e5f600c62b86455, q17);
16496 ASSERT_EQUAL_128(0x0100abab01565656, 0x5555550055565555, q18);
16497 ASSERT_EQUAL_128(0xff005555ffaaaaaa, 0x5555550055aa5555, q19);
16498 TEARDOWN();
16499}
16500
16501
16502TEST(neon_byelement_mul) {
16503 SETUP();
16504
16505 START();
16506
16507 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16508 __ Movi(v1.V2D(), 0x000155aaff55ff00, 0xaa55ff55555500ff);
16509
16510
16511 __ Mul(v16.V4H(), v0.V4H(), v1.H(), 0);
16512 __ Mul(v17.V8H(), v0.V8H(), v1.H(), 7);
16513 __ Mul(v18.V2S(), v0.V2S(), v1.S(), 0);
16514 __ Mul(v19.V4S(), v0.V4S(), v1.S(), 3);
16515
16516 __ Movi(v20.V2D(), 0x0000000000000000, 0x0001000200030004);
16517 __ Movi(v21.V2D(), 0x0005000600070008, 0x0001000200030004);
16518 __ Mla(v20.V4H(), v0.V4H(), v1.H(), 0);
16519 __ Mla(v21.V8H(), v0.V8H(), v1.H(), 7);
16520
16521 __ Movi(v22.V2D(), 0x0000000000000000, 0x0000000200000004);
16522 __ Movi(v23.V2D(), 0x0000000600000008, 0x0000000200000004);
16523 __ Mla(v22.V2S(), v0.V2S(), v1.S(), 0);
16524 __ Mla(v23.V4S(), v0.V4S(), v1.S(), 3);
16525
16526 __ Movi(v24.V2D(), 0x0000000000000000, 0x0100aaabfe015456);
16527 __ Movi(v25.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16528 __ Mls(v24.V4H(), v0.V4H(), v1.H(), 0);
16529 __ Mls(v25.V8H(), v0.V8H(), v1.H(), 7);
16530
16531 __ Movi(v26.V2D(), 0x0000000000000000, 0xc8e2aaabe1c85456);
16532 __ Movi(v27.V2D(), 0x39545572c6aa54e4, 0x39545572c6aa54e4);
16533 __ Mls(v26.V2S(), v0.V2S(), v1.S(), 0);
16534 __ Mls(v27.V4S(), v0.V4S(), v1.S(), 3);
16535
16536 END();
16537
16538 RUN();
16539 ASSERT_EQUAL_128(0x0000000000000000, 0x0100aaabfe015456, q16);
16540 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q17);
16541 ASSERT_EQUAL_128(0x0000000000000000, 0xc8e2aaabe1c85456, q18);
16542 ASSERT_EQUAL_128(0x39545572c6aa54e4, 0x39545572c6aa54e4, q19);
16543
16544 ASSERT_EQUAL_128(0x0000000000000000, 0x0101aaadfe04545a, q20);
16545 ASSERT_EQUAL_128(0xff05aa5b010655b2, 0xff01aa57010255ae, q21);
16546 ASSERT_EQUAL_128(0x0000000000000000, 0xc8e2aaade1c8545a, q22);
16547 ASSERT_EQUAL_128(0x39545578c6aa54ec, 0x39545574c6aa54e8, q23);
16548
16549 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16550 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16551 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q26);
16552 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q27);
16553 TEARDOWN();
16554}
16555
16556
16557TEST(neon_byelement_mull) {
16558 SETUP();
16559
16560 START();
16561
16562 __ Movi(v0.V2D(), 0xaa55ff55555500ff, 0xff00aa5500ff55aa);
16563 __ Movi(v1.V2D(), 0x000155aaff55ff00, 0xaa55ff55555500ff);
16564
16565
16566 __ Smull(v16.V4S(), v0.V4H(), v1.H(), 7);
16567 __ Smull2(v17.V4S(), v0.V8H(), v1.H(), 0);
16568 __ Umull(v18.V4S(), v0.V4H(), v1.H(), 7);
16569 __ Umull2(v19.V4S(), v0.V8H(), v1.H(), 0);
16570
16571 __ Movi(v20.V2D(), 0x0000000100000002, 0x0000000200000001);
16572 __ Movi(v21.V2D(), 0x0000000100000002, 0x0000000200000001);
16573 __ Movi(v22.V2D(), 0x0000000100000002, 0x0000000200000001);
16574 __ Movi(v23.V2D(), 0x0000000100000002, 0x0000000200000001);
16575
16576 __ Smlal(v20.V4S(), v0.V4H(), v1.H(), 7);
16577 __ Smlal2(v21.V4S(), v0.V8H(), v1.H(), 0);
16578 __ Umlal(v22.V4S(), v0.V4H(), v1.H(), 7);
16579 __ Umlal2(v23.V4S(), v0.V8H(), v1.H(), 0);
16580
16581 __ Movi(v24.V2D(), 0xffffff00ffffaa55, 0x000000ff000055aa);
16582 __ Movi(v25.V2D(), 0xffaaaaabffff55ab, 0x0054ffab0000fe01);
16583 __ Movi(v26.V2D(), 0x0000ff000000aa55, 0x000000ff000055aa);
16584 __ Movi(v27.V2D(), 0x00a9aaab00fe55ab, 0x0054ffab0000fe01);
16585
16586 __ Smlsl(v24.V4S(), v0.V4H(), v1.H(), 7);
16587 __ Smlsl2(v25.V4S(), v0.V8H(), v1.H(), 0);
16588 __ Umlsl(v26.V4S(), v0.V4H(), v1.H(), 7);
16589 __ Umlsl2(v27.V4S(), v0.V8H(), v1.H(), 0);
16590
16591 END();
16592
16593 RUN();
16594
16595 ASSERT_EQUAL_128(0xffffff00ffffaa55, 0x000000ff000055aa, q16);
16596 ASSERT_EQUAL_128(0xffaaaaabffff55ab, 0x0054ffab0000fe01, q17);
16597 ASSERT_EQUAL_128(0x0000ff000000aa55, 0x000000ff000055aa, q18);
16598 ASSERT_EQUAL_128(0x00a9aaab00fe55ab, 0x0054ffab0000fe01, q19);
16599
16600 ASSERT_EQUAL_128(0xffffff01ffffaa57, 0x00000101000055ab, q20);
16601 ASSERT_EQUAL_128(0xffaaaaacffff55ad, 0x0054ffad0000fe02, q21);
16602 ASSERT_EQUAL_128(0x0000ff010000aa57, 0x00000101000055ab, q22);
16603 ASSERT_EQUAL_128(0x00a9aaac00fe55ad, 0x0054ffad0000fe02, q23);
16604
16605 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16606 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16607 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q26);
16608 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q27);
16609
16610 TEARDOWN();
16611}
16612
16613
16614TEST(neon_byelement_sqdmull) {
16615 SETUP();
16616
16617 START();
16618
16619 __ Movi(v0.V2D(), 0xaa55ff55555500ff, 0xff00aa5500ff55aa);
16620 __ Movi(v1.V2D(), 0x000155aaff55ff00, 0xaa55ff55555500ff);
16621
16622 __ Sqdmull(v16.V4S(), v0.V4H(), v1.H(), 7);
16623 __ Sqdmull2(v17.V4S(), v0.V8H(), v1.H(), 0);
16624 __ Sqdmull(s18, h0, v1.H(), 7);
16625
16626 __ Movi(v20.V2D(), 0x0000000100000002, 0x0000000200000001);
16627 __ Movi(v21.V2D(), 0x0000000100000002, 0x0000000200000001);
16628 __ Movi(v22.V2D(), 0x0000000100000002, 0x0000000200000001);
16629
16630 __ Sqdmlal(v20.V4S(), v0.V4H(), v1.H(), 7);
16631 __ Sqdmlal2(v21.V4S(), v0.V8H(), v1.H(), 0);
16632 __ Sqdmlal(s22, h0, v1.H(), 7);
16633
16634 __ Movi(v24.V2D(), 0xfffffe00ffff54aa, 0x000001fe0000ab54);
16635 __ Movi(v25.V2D(), 0xff555556fffeab56, 0x00a9ff560001fc02);
16636 __ Movi(v26.V2D(), 0x0000000000000000, 0x000000000000ab54);
16637
16638 __ Sqdmlsl(v24.V4S(), v0.V4H(), v1.H(), 7);
16639 __ Sqdmlsl2(v25.V4S(), v0.V8H(), v1.H(), 0);
16640 __ Sqdmlsl(s26, h0, v1.H(), 7);
16641
16642 END();
16643
16644 RUN();
16645
16646 ASSERT_EQUAL_128(0xfffffe00ffff54aa, 0x000001fe0000ab54, q16);
16647 ASSERT_EQUAL_128(0xff555556fffeab56, 0x00a9ff560001fc02, q17);
16648 ASSERT_EQUAL_128(0, 0x0000ab54, q18);
16649
16650 ASSERT_EQUAL_128(0xfffffe01ffff54ac, 0x000002000000ab55, q20);
16651 ASSERT_EQUAL_128(0xff555557fffeab58, 0x00a9ff580001fc03, q21);
16652 ASSERT_EQUAL_128(0, 0x0000ab55, q22);
16653
16654 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16655 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16656 ASSERT_EQUAL_128(0, 0x00000000, q26);
16657
16658 TEARDOWN();
16659}
16660
16661
16662TEST(neon_3diff_absdiff) {
16663 SETUP();
16664
16665 START();
16666
16667 __ Movi(v0.V2D(), 0xff00aa5500ff55ab, 0xff00aa5500ff55aa);
16668 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16669 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16670 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16671 __ Movi(v18.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16672 __ Movi(v19.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16673
16674 __ Sabal(v16.V8H(), v0.V8B(), v1.V8B());
16675 __ Uabal(v17.V8H(), v0.V8B(), v1.V8B());
16676 __ Sabal2(v18.V8H(), v0.V16B(), v1.V16B());
16677 __ Uabal2(v19.V8H(), v0.V16B(), v1.V16B());
16678
16679 END();
16680
16681 RUN();
16682 ASSERT_EQUAL_128(0x01570359055b0708, 0x095f0b620d630f55, q16);
16683 ASSERT_EQUAL_128(0x01570359055b0708, 0x095f0bb60d630f55, q17);
16684 ASSERT_EQUAL_128(0x0103030405b107b3, 0x090b0b620d640f55, q18);
16685 ASSERT_EQUAL_128(0x02010304055b075d, 0x0a090bb60db80fab, q19);
16686 TEARDOWN();
16687}
16688
16689
16690TEST(neon_3diff_sqdmull) {
16691 SETUP();
16692
16693 START();
16694
16695 __ Movi(v0.V2D(), 0x7fff7fff80008000, 0x80007fff7fff8000);
16696 __ Movi(v1.V2D(), 0x80007fff7fff8000, 0x7fff7fff80008000);
16697 __ Movi(v2.V2D(), 0x800000007fffffff, 0x7fffffff80000000);
16698 __ Movi(v3.V2D(), 0x8000000080000000, 0x8000000080000000);
16699
16700 __ Sqdmull(v16.V4S(), v0.V4H(), v1.V4H());
16701 __ Sqdmull2(v17.V4S(), v0.V8H(), v1.V8H());
16702 __ Sqdmull(v18.V2D(), v2.V2S(), v3.V2S());
16703 __ Sqdmull2(v19.V2D(), v2.V4S(), v3.V4S());
16704 __ Sqdmull(s20, h0, h1);
16705 __ Sqdmull(d21, s2, s3);
16706
16707 END();
16708
16709 RUN();
16710 ASSERT_EQUAL_128(0x800100007ffe0002, 0x800100007fffffff, q16);
16711 ASSERT_EQUAL_128(0x800100007ffe0002, 0x800100007fffffff, q17);
16712 ASSERT_EQUAL_128(0x8000000100000000, 0x7fffffffffffffff, q18);
16713 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x8000000100000000, q19);
16714 ASSERT_EQUAL_128(0, 0x7fffffff, q20);
16715 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q21);
16716 TEARDOWN();
16717}
16718
16719
16720TEST(neon_3diff_sqdmlal) {
16721 SETUP();
16722
16723 START();
16724
16725 __ Movi(v0.V2D(), 0x7fff7fff80008000, 0x80007fff7fff8000);
16726 __ Movi(v1.V2D(), 0x80007fff7fff8000, 0x7fff7fff80008000);
16727 __ Movi(v2.V2D(), 0x800000007fffffff, 0x7fffffff80000000);
16728 __ Movi(v3.V2D(), 0x8000000080000000, 0x8000000080000000);
16729
16730 __ Movi(v16.V2D(), 0xffffffff00000001, 0x8fffffff00000001);
16731 __ Movi(v17.V2D(), 0x00000001ffffffff, 0x00000001ffffffff);
16732 __ Movi(v18.V2D(), 0x8000000000000001, 0x0000000000000001);
16733 __ Movi(v19.V2D(), 0xffffffffffffffff, 0x7fffffffffffffff);
16734 __ Movi(v20.V2D(), 0, 0x00000001);
16735 __ Movi(v21.V2D(), 0, 0x00000001);
16736
16737 __ Sqdmlal(v16.V4S(), v0.V4H(), v1.V4H());
16738 __ Sqdmlal2(v17.V4S(), v0.V8H(), v1.V8H());
16739 __ Sqdmlal(v18.V2D(), v2.V2S(), v3.V2S());
16740 __ Sqdmlal2(v19.V2D(), v2.V4S(), v3.V4S());
16741 __ Sqdmlal(s20, h0, h1);
16742 __ Sqdmlal(d21, s2, s3);
16743
16744 END();
16745
16746 RUN();
16747 ASSERT_EQUAL_128(0x8000ffff7ffe0003, 0x800000007fffffff, q16);
16748 ASSERT_EQUAL_128(0x800100017ffe0001, 0x800100017ffffffe, q17);
16749 ASSERT_EQUAL_128(0x8000000000000000, 0x7fffffffffffffff, q18);
16750 ASSERT_EQUAL_128(0x7ffffffffffffffe, 0x00000000ffffffff, q19);
16751 ASSERT_EQUAL_128(0, 0x7fffffff, q20);
16752 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q21);
16753 TEARDOWN();
16754}
16755
16756
16757TEST(neon_3diff_sqdmlsl) {
16758 SETUP();
16759
16760 START();
16761
16762 __ Movi(v0.V2D(), 0x7fff7fff80008000, 0x80007fff7fff8000);
16763 __ Movi(v1.V2D(), 0x80007fff7fff8000, 0x7fff7fff80008000);
16764 __ Movi(v2.V2D(), 0x800000007fffffff, 0x7fffffff80000000);
16765 __ Movi(v3.V2D(), 0x8000000080000000, 0x8000000080000000);
16766
16767 __ Movi(v16.V2D(), 0xffffffff00000001, 0x7ffffffe80000001);
16768 __ Movi(v17.V2D(), 0x00000001ffffffff, 0x7ffffffe00000001);
16769 __ Movi(v18.V2D(), 0x8000000000000001, 0x8000000000000001);
16770 __ Movi(v19.V2D(), 0xfffffffffffffffe, 0x7fffffffffffffff);
16771 __ Movi(v20.V2D(), 0, 0x00000001);
16772 __ Movi(v21.V2D(), 0, 0x00000001);
16773
16774 __ Sqdmlsl(v16.V4S(), v0.V4H(), v1.V4H());
16775 __ Sqdmlsl2(v17.V4S(), v0.V8H(), v1.V8H());
16776 __ Sqdmlsl(v18.V2D(), v2.V2S(), v3.V2S());
16777 __ Sqdmlsl2(v19.V2D(), v2.V4S(), v3.V4S());
16778 __ Sqdmlsl(s20, h0, h1);
16779 __ Sqdmlsl(d21, s2, s3);
16780
16781 END();
16782
16783 RUN();
16784 ASSERT_EQUAL_128(0x7ffeffff8001ffff, 0x7fffffff80000000, q16);
16785 ASSERT_EQUAL_128(0x7fff00018001fffd, 0x7fffffff80000002, q17);
16786 ASSERT_EQUAL_128(0xffffffff00000001, 0x8000000000000000, q18);
16787 ASSERT_EQUAL_128(0x8000000000000000, 0x7fffffffffffffff, q19);
16788 ASSERT_EQUAL_128(0, 0x80000002, q20);
16789 ASSERT_EQUAL_128(0, 0x8000000000000002, q21);
16790
16791 TEARDOWN();
16792}
16793
16794
16795TEST(neon_3diff_mla) {
16796 SETUP();
16797
16798 START();
16799
16800 __ Movi(v0.V2D(), 0xff00aa5500ff55ab, 0xff00aa5500ff55aa);
16801 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16802 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16803 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16804 __ Movi(v18.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16805 __ Movi(v19.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16806
16807 __ Smlal(v16.V8H(), v0.V8B(), v1.V8B());
16808 __ Umlal(v17.V8H(), v0.V8B(), v1.V8B());
16809 __ Smlal2(v18.V8H(), v0.V16B(), v1.V16B());
16810 __ Umlal2(v19.V8H(), v0.V16B(), v1.V16B());
16811
16812 END();
16813
16814 RUN();
16815 ASSERT_EQUAL_128(0x01580304055c2341, 0x090a0ab70d0e0f56, q16);
16816 ASSERT_EQUAL_128(0xaa580304ae5c2341, 0x090a5fb70d0eb856, q17);
16817 ASSERT_EQUAL_128(0x01020304e878ea7a, 0x090a0ab70cb90f00, q18);
16818 ASSERT_EQUAL_128(0x010203043d783f7a, 0x090a5fb761b90f00, q19);
16819 TEARDOWN();
16820}
16821
16822
16823TEST(neon_3diff_mls) {
16824 SETUP();
16825
16826 START();
16827
16828 __ Movi(v0.V2D(), 0xff00aa5500ff55ab, 0xff00aa5500ff55aa);
16829 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16830 __ Movi(v16.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16831 __ Movi(v17.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16832 __ Movi(v18.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16833 __ Movi(v19.V2D(), 0x0102030405060708, 0x090a0b0c0d0e0f00);
16834
16835 __ Smlsl(v16.V8H(), v0.V8B(), v1.V8B());
16836 __ Umlsl(v17.V8H(), v0.V8B(), v1.V8B());
16837 __ Smlsl2(v18.V8H(), v0.V16B(), v1.V16B());
16838 __ Umlsl2(v19.V8H(), v0.V16B(), v1.V16B());
16839
16840 END();
16841
16842 RUN();
16843 ASSERT_EQUAL_128(0x00ac030404b0eacf, 0x090a0b610d0e0eaa, q16);
16844 ASSERT_EQUAL_128(0x57ac03045bb0eacf, 0x090ab6610d0e65aa, q17);
16845 ASSERT_EQUAL_128(0x0102030421942396, 0x090a0b610d630f00, q18);
16846 ASSERT_EQUAL_128(0x01020304cc94ce96, 0x090ab661b8630f00, q19);
16847 TEARDOWN();
16848}
16849
16850
16851TEST(neon_3same_compare) {
16852 SETUP();
16853
16854 START();
16855
16856 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16857 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16858
16859 __ Cmeq(v16.V16B(), v0.V16B(), v0.V16B());
16860 __ Cmeq(v17.V16B(), v0.V16B(), v1.V16B());
16861 __ Cmge(v18.V16B(), v0.V16B(), v0.V16B());
16862 __ Cmge(v19.V16B(), v0.V16B(), v1.V16B());
16863 __ Cmgt(v20.V16B(), v0.V16B(), v0.V16B());
16864 __ Cmgt(v21.V16B(), v0.V16B(), v1.V16B());
16865 __ Cmhi(v22.V16B(), v0.V16B(), v0.V16B());
16866 __ Cmhi(v23.V16B(), v0.V16B(), v1.V16B());
16867 __ Cmhs(v24.V16B(), v0.V16B(), v0.V16B());
16868 __ Cmhs(v25.V16B(), v0.V16B(), v1.V16B());
16869
16870 END();
16871
16872 RUN();
16873 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q16);
16874 ASSERT_EQUAL_128(0x00ff000000000000, 0x000000ff00000000, q17);
16875 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q18);
16876 ASSERT_EQUAL_128(0x00ff00ffff00ff00, 0xff0000ff0000ff00, q19);
16877 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
16878 ASSERT_EQUAL_128(0x000000ffff00ff00, 0xff0000000000ff00, q21);
16879 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q22);
16880 ASSERT_EQUAL_128(0xff00ff0000ff00ff, 0xff00000000ffff00, q23);
16881 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q24);
16882 ASSERT_EQUAL_128(0xffffff0000ff00ff, 0xff0000ff00ffff00, q25);
16883 TEARDOWN();
16884}
16885
16886
16887TEST(neon_3same_scalar_compare) {
16888 SETUP();
16889
16890 START();
16891
16892 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
16893 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0xaa55ff55555500ff);
16894
16895 __ Cmeq(d16, d0, d0);
16896 __ Cmeq(d17, d0, d1);
16897 __ Cmeq(d18, d1, d0);
16898 __ Cmge(d19, d0, d0);
16899 __ Cmge(d20, d0, d1);
16900 __ Cmge(d21, d1, d0);
16901 __ Cmgt(d22, d0, d0);
16902 __ Cmgt(d23, d0, d1);
16903 __ Cmhi(d24, d0, d0);
16904 __ Cmhi(d25, d0, d1);
16905 __ Cmhs(d26, d0, d0);
16906 __ Cmhs(d27, d0, d1);
16907 __ Cmhs(d28, d1, d0);
16908
16909 END();
16910
16911 RUN();
16912
16913 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q16);
16914 ASSERT_EQUAL_128(0, 0x0000000000000000, q17);
16915 ASSERT_EQUAL_128(0, 0x0000000000000000, q18);
16916 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
16917 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q20);
16918 ASSERT_EQUAL_128(0, 0x0000000000000000, q21);
16919 ASSERT_EQUAL_128(0, 0x0000000000000000, q22);
16920 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q23);
16921 ASSERT_EQUAL_128(0, 0x0000000000000000, q24);
16922 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q25);
16923 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q26);
16924 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q27);
16925 ASSERT_EQUAL_128(0, 0x0000000000000000, q28);
16926
16927 TEARDOWN();
16928}
16929
16930TEST(neon_2regmisc_fcmeq) {
16931 SETUP();
16932
16933 START();
16934
16935 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16936 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16937 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16938 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16939
16940 __ Fcmeq(s16, s0, 0.0);
16941 __ Fcmeq(s17, s1, 0.0);
16942 __ Fcmeq(s18, s2, 0.0);
16943 __ Fcmeq(d19, d0, 0.0);
16944 __ Fcmeq(d20, d1, 0.0);
16945 __ Fcmeq(d21, d2, 0.0);
16946 __ Fcmeq(v22.V2S(), v0.V2S(), 0.0);
16947 __ Fcmeq(v23.V4S(), v1.V4S(), 0.0);
16948 __ Fcmeq(v24.V2D(), v1.V2D(), 0.0);
16949 __ Fcmeq(v25.V2D(), v2.V2D(), 0.0);
16950
16951 END();
16952
16953 RUN();
16954 ASSERT_EQUAL_128(0, 0xffffffff, q16);
16955 ASSERT_EQUAL_128(0, 0x00000000, q17);
16956 ASSERT_EQUAL_128(0, 0x00000000, q18);
16957 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
16958 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16959 ASSERT_EQUAL_128(0, 0x0000000000000000, q21);
16960 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q22);
16961 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16962 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
16963 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
16964 TEARDOWN();
16965}
16966
16967TEST(neon_2regmisc_fcmge) {
16968 SETUP();
16969
16970 START();
16971
16972 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
16973 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
16974 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
16975 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
16976
16977 __ Fcmge(s16, s0, 0.0);
16978 __ Fcmge(s17, s1, 0.0);
16979 __ Fcmge(s18, s2, 0.0);
16980 __ Fcmge(d19, d0, 0.0);
16981 __ Fcmge(d20, d1, 0.0);
16982 __ Fcmge(d21, d3, 0.0);
16983 __ Fcmge(v22.V2S(), v0.V2S(), 0.0);
16984 __ Fcmge(v23.V4S(), v1.V4S(), 0.0);
16985 __ Fcmge(v24.V2D(), v1.V2D(), 0.0);
16986 __ Fcmge(v25.V2D(), v3.V2D(), 0.0);
16987
16988 END();
16989
16990 RUN();
16991 ASSERT_EQUAL_128(0, 0xffffffff, q16);
16992 ASSERT_EQUAL_128(0, 0x00000000, q17);
16993 ASSERT_EQUAL_128(0, 0x00000000, q18);
16994 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
16995 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
16996 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
16997 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q22);
16998 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
16999 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
17000 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
17001 TEARDOWN();
17002}
17003
17004
17005TEST(neon_2regmisc_fcmgt) {
17006 SETUP();
17007
17008 START();
17009
17010 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
17011 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
17012 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
17013 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
17014
17015 __ Fcmgt(s16, s0, 0.0);
17016 __ Fcmgt(s17, s1, 0.0);
17017 __ Fcmgt(s18, s2, 0.0);
17018 __ Fcmgt(d19, d0, 0.0);
17019 __ Fcmgt(d20, d1, 0.0);
17020 __ Fcmgt(d21, d3, 0.0);
17021 __ Fcmgt(v22.V2S(), v0.V2S(), 0.0);
17022 __ Fcmgt(v23.V4S(), v1.V4S(), 0.0);
17023 __ Fcmgt(v24.V2D(), v1.V2D(), 0.0);
17024 __ Fcmgt(v25.V2D(), v3.V2D(), 0.0);
17025
17026 END();
17027
17028 RUN();
17029 ASSERT_EQUAL_128(0, 0x00000000, q16);
17030 ASSERT_EQUAL_128(0, 0x00000000, q17);
17031 ASSERT_EQUAL_128(0, 0x00000000, q18);
17032 ASSERT_EQUAL_128(0, 0x0000000000000000, q19);
17033 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
17034 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
17035 ASSERT_EQUAL_128(0, 0x0000000000000000, q22);
17036 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
17037 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
17038 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
17039 TEARDOWN();
17040}
17041
17042TEST(neon_2regmisc_fcmle) {
17043 SETUP();
17044
17045 START();
17046
17047 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
17048 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
17049 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
17050 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
17051
17052 __ Fcmle(s16, s0, 0.0);
17053 __ Fcmle(s17, s1, 0.0);
17054 __ Fcmle(s18, s3, 0.0);
17055 __ Fcmle(d19, d0, 0.0);
17056 __ Fcmle(d20, d1, 0.0);
17057 __ Fcmle(d21, d2, 0.0);
17058 __ Fcmle(v22.V2S(), v0.V2S(), 0.0);
17059 __ Fcmle(v23.V4S(), v1.V4S(), 0.0);
17060 __ Fcmle(v24.V2D(), v1.V2D(), 0.0);
17061 __ Fcmle(v25.V2D(), v2.V2D(), 0.0);
17062
17063 END();
17064
17065 RUN();
17066 ASSERT_EQUAL_128(0, 0xffffffff, q16);
17067 ASSERT_EQUAL_128(0, 0x00000000, q17);
17068 ASSERT_EQUAL_128(0, 0x00000000, q18);
17069 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q19);
17070 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
17071 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
17072 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q22);
17073 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
17074 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
17075 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
17076 TEARDOWN();
17077}
17078
17079
17080TEST(neon_2regmisc_fcmlt) {
17081 SETUP();
17082
17083 START();
17084
17085 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000); // Zero.
17086 __ Movi(v1.V2D(), 0xffffffffffffffff, 0xffffffffffffffff); // Nan.
17087 __ Movi(v2.V2D(), 0xbf800000bf800000, 0xbf800000bf800000); // < 0.
17088 __ Movi(v3.V2D(), 0x3f8000003f800000, 0x3f8000003f800000); // > 0.
17089
17090 __ Fcmlt(s16, s0, 0.0);
17091 __ Fcmlt(s17, s1, 0.0);
17092 __ Fcmlt(s18, s3, 0.0);
17093 __ Fcmlt(d19, d0, 0.0);
17094 __ Fcmlt(d20, d1, 0.0);
17095 __ Fcmlt(d21, d2, 0.0);
17096 __ Fcmlt(v22.V2S(), v0.V2S(), 0.0);
17097 __ Fcmlt(v23.V4S(), v1.V4S(), 0.0);
17098 __ Fcmlt(v24.V2D(), v1.V2D(), 0.0);
17099 __ Fcmlt(v25.V2D(), v2.V2D(), 0.0);
17100
17101 END();
17102
17103 RUN();
17104 ASSERT_EQUAL_128(0, 0x00000000, q16);
17105 ASSERT_EQUAL_128(0, 0x00000000, q17);
17106 ASSERT_EQUAL_128(0, 0x00000000, q18);
17107 ASSERT_EQUAL_128(0, 0x0000000000000000, q19);
17108 ASSERT_EQUAL_128(0, 0x0000000000000000, q20);
17109 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q21);
17110 ASSERT_EQUAL_128(0, 0x0000000000000000, q22);
17111 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
17112 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q24);
17113 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
17114 TEARDOWN();
17115}
17116
17117TEST(neon_2regmisc_cmeq) {
17118 SETUP();
17119
17120 START();
17121
17122 __ Movi(v0.V2D(), 0x0001000200030004, 0x0000000000000000);
17123 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
17124
17125 __ Cmeq(v16.V8B(), v1.V8B(), 0);
17126 __ Cmeq(v17.V16B(), v1.V16B(), 0);
17127 __ Cmeq(v18.V4H(), v1.V4H(), 0);
17128 __ Cmeq(v19.V8H(), v1.V8H(), 0);
17129 __ Cmeq(v20.V2S(), v0.V2S(), 0);
17130 __ Cmeq(v21.V4S(), v0.V4S(), 0);
17131 __ Cmeq(d22, d0, 0);
17132 __ Cmeq(d23, d1, 0);
17133 __ Cmeq(v24.V2D(), v0.V2D(), 0);
17134
17135 END();
17136
17137 RUN();
17138 ASSERT_EQUAL_128(0x0000000000000000, 0xffff00000000ff00, q16);
17139 ASSERT_EQUAL_128(0xffff0000000000ff, 0xffff00000000ff00, q17);
17140 ASSERT_EQUAL_128(0x0000000000000000, 0xffff000000000000, q18);
17141 ASSERT_EQUAL_128(0xffff000000000000, 0xffff000000000000, q19);
17142 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q20);
17143 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q21);
17144 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
17145 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
17146 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
17147 TEARDOWN();
17148}
17149
17150
17151TEST(neon_2regmisc_cmge) {
17152 SETUP();
17153
17154 START();
17155
17156 __ Movi(v0.V2D(), 0xff01000200030004, 0x0000000000000000);
17157 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
17158
17159 __ Cmge(v16.V8B(), v1.V8B(), 0);
17160 __ Cmge(v17.V16B(), v1.V16B(), 0);
17161 __ Cmge(v18.V4H(), v1.V4H(), 0);
17162 __ Cmge(v19.V8H(), v1.V8H(), 0);
17163 __ Cmge(v20.V2S(), v0.V2S(), 0);
17164 __ Cmge(v21.V4S(), v0.V4S(), 0);
17165 __ Cmge(d22, d0, 0);
17166 __ Cmge(d23, d1, 0);
17167 __ Cmge(v24.V2D(), v0.V2D(), 0);
17168
17169 END();
17170
17171 RUN();
17172 ASSERT_EQUAL_128(0x0000000000000000, 0xffff00ffffffff00, q16);
17173 ASSERT_EQUAL_128(0xffffff0000ff00ff, 0xffff00ffffffff00, q17);
17174 ASSERT_EQUAL_128(0x0000000000000000, 0xffff0000ffffffff, q18);
17175 ASSERT_EQUAL_128(0xffffffff00000000, 0xffff0000ffffffff, q19);
17176 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q20);
17177 ASSERT_EQUAL_128(0x00000000ffffffff, 0xffffffffffffffff, q21);
17178 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
17179 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q23);
17180 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
17181 TEARDOWN();
17182}
17183
17184
17185TEST(neon_2regmisc_cmlt) {
17186 SETUP();
17187
17188 START();
17189
17190 __ Movi(v0.V2D(), 0x0001000200030004, 0xff00000000000000);
17191 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
17192
17193 __ Cmlt(v16.V8B(), v1.V8B(), 0);
17194 __ Cmlt(v17.V16B(), v1.V16B(), 0);
17195 __ Cmlt(v18.V4H(), v1.V4H(), 0);
17196 __ Cmlt(v19.V8H(), v1.V8H(), 0);
17197 __ Cmlt(v20.V2S(), v1.V2S(), 0);
17198 __ Cmlt(v21.V4S(), v1.V4S(), 0);
17199 __ Cmlt(d22, d0, 0);
17200 __ Cmlt(d23, d1, 0);
17201 __ Cmlt(v24.V2D(), v0.V2D(), 0);
17202
17203 END();
17204
17205 RUN();
17206 ASSERT_EQUAL_128(0x0000000000000000, 0x0000ff00000000ff, q16);
17207 ASSERT_EQUAL_128(0x000000ffff00ff00, 0x0000ff00000000ff, q17);
17208 ASSERT_EQUAL_128(0x0000000000000000, 0x0000ffff00000000, q18);
17209 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000ffff00000000, q19);
17210 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
17211 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000000000000000, q21);
17212 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
17213 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
17214 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
17215 TEARDOWN();
17216}
17217
17218
17219TEST(neon_2regmisc_cmle) {
17220 SETUP();
17221
17222 START();
17223
17224 __ Movi(v0.V2D(), 0x0001000200030004, 0x0000000000000000);
17225 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
17226
17227 __ Cmle(v16.V8B(), v1.V8B(), 0);
17228 __ Cmle(v17.V16B(), v1.V16B(), 0);
17229 __ Cmle(v18.V4H(), v1.V4H(), 0);
17230 __ Cmle(v19.V8H(), v1.V8H(), 0);
17231 __ Cmle(v20.V2S(), v1.V2S(), 0);
17232 __ Cmle(v21.V4S(), v1.V4S(), 0);
17233 __ Cmle(d22, d0, 0);
17234 __ Cmle(d23, d1, 0);
17235 __ Cmle(v24.V2D(), v0.V2D(), 0);
17236
17237 END();
17238
17239 RUN();
17240 ASSERT_EQUAL_128(0x0000000000000000, 0xffffff000000ffff, q16);
17241 ASSERT_EQUAL_128(0xffff00ffff00ffff, 0xffffff000000ffff, q17);
17242 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffff00000000, q18);
17243 ASSERT_EQUAL_128(0xffff0000ffffffff, 0xffffffff00000000, q19);
17244 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
17245 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000000000000000, q21);
17246 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q22);
17247 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q23);
17248 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q24);
17249 TEARDOWN();
17250}
17251
17252
17253TEST(neon_2regmisc_cmgt) {
17254 SETUP();
17255
17256 START();
17257
17258 __ Movi(v0.V2D(), 0x0001000200030004, 0x0000000000000000);
17259 __ Movi(v1.V2D(), 0x000055aaff55ff00, 0x0000ff55555500ff);
17260
17261 __ Cmgt(v16.V8B(), v1.V8B(), 0);
17262 __ Cmgt(v17.V16B(), v1.V16B(), 0);
17263 __ Cmgt(v18.V4H(), v1.V4H(), 0);
17264 __ Cmgt(v19.V8H(), v1.V8H(), 0);
17265 __ Cmgt(v20.V2S(), v0.V2S(), 0);
17266 __ Cmgt(v21.V4S(), v0.V4S(), 0);
17267 __ Cmgt(d22, d0, 0);
17268 __ Cmgt(d23, d1, 0);
17269 __ Cmgt(v24.V2D(), v0.V2D(), 0);
17270
17271 END();
17272
17273 RUN();
17274 ASSERT_EQUAL_128(0x0000000000000000, 0x000000ffffff0000, q16);
17275 ASSERT_EQUAL_128(0x0000ff0000ff0000, 0x000000ffffff0000, q17);
17276 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q18);
17277 ASSERT_EQUAL_128(0x0000ffff00000000, 0x00000000ffffffff, q19);
17278 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q20);
17279 ASSERT_EQUAL_128(0xffffffffffffffff, 0x0000000000000000, q21);
17280 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q22);
17281 ASSERT_EQUAL_128(0x0000000000000000, 0xffffffffffffffff, q23);
17282 ASSERT_EQUAL_128(0xffffffffffffffff, 0x0000000000000000, q24);
17283 TEARDOWN();
17284}
17285
17286
17287TEST(neon_2regmisc_neg) {
17288 SETUP();
17289
17290 START();
17291
17292 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17293 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17294 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17295 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17296 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17297
17298 __ Neg(v16.V8B(), v0.V8B());
17299 __ Neg(v17.V16B(), v0.V16B());
17300 __ Neg(v18.V4H(), v1.V4H());
17301 __ Neg(v19.V8H(), v1.V8H());
17302 __ Neg(v20.V2S(), v2.V2S());
17303 __ Neg(v21.V4S(), v2.V4S());
17304 __ Neg(d22, d3);
17305 __ Neg(v23.V2D(), v3.V2D());
17306 __ Neg(v24.V2D(), v4.V2D());
17307
17308 END();
17309
17310 RUN();
17311 ASSERT_EQUAL_128(0x0000000000000000, 0x807f0100ff81807f, q16);
17312 ASSERT_EQUAL_128(0x81ff00017f8081ff, 0x807f0100ff81807f, q17);
17313 ASSERT_EQUAL_128(0x0000000000000000, 0x00010000ffff8001, q18);
17314 ASSERT_EQUAL_128(0x80007fff00010000, 0x00010000ffff8001, q19);
17315 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000001, q20);
17316 ASSERT_EQUAL_128(0x8000000000000001, 0x0000000080000001, q21);
17317 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000000001, q22);
17318 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x8000000000000001, q23);
17319 ASSERT_EQUAL_128(0x8000000000000000, 0x0000000000000000, q24);
17320
17321 TEARDOWN();
17322}
17323
17324
17325TEST(neon_2regmisc_sqneg) {
17326 SETUP();
17327
17328 START();
17329
17330 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17331 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17332 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17333 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17334 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17335
17336 __ Sqneg(v16.V8B(), v0.V8B());
17337 __ Sqneg(v17.V16B(), v0.V16B());
17338 __ Sqneg(v18.V4H(), v1.V4H());
17339 __ Sqneg(v19.V8H(), v1.V8H());
17340 __ Sqneg(v20.V2S(), v2.V2S());
17341 __ Sqneg(v21.V4S(), v2.V4S());
17342 __ Sqneg(v22.V2D(), v3.V2D());
17343 __ Sqneg(v23.V2D(), v4.V2D());
17344
17345 __ Sqneg(b24, b0);
17346 __ Sqneg(h25, h1);
17347 __ Sqneg(s26, s2);
17348 __ Sqneg(d27, d3);
17349
17350 END();
17351
17352 RUN();
17353 ASSERT_EQUAL_128(0x0000000000000000, 0x7f7f0100ff817f7f, q16);
17354 ASSERT_EQUAL_128(0x81ff00017f7f81ff, 0x7f7f0100ff817f7f, q17);
17355 ASSERT_EQUAL_128(0x0000000000000000, 0x00010000ffff8001, q18);
17356 ASSERT_EQUAL_128(0x7fff7fff00010000, 0x00010000ffff8001, q19);
17357 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000001, q20);
17358 ASSERT_EQUAL_128(0x7fffffff00000001, 0x0000000080000001, q21);
17359 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x8000000000000001, q22);
17360 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x0000000000000000, q23);
17361
17362 ASSERT_EQUAL_128(0, 0x7f, q24);
17363 ASSERT_EQUAL_128(0, 0x8001, q25);
17364 ASSERT_EQUAL_128(0, 0x80000001, q26);
17365 ASSERT_EQUAL_128(0, 0x8000000000000001, q27);
17366
17367 TEARDOWN();
17368}
17369
17370
17371TEST(neon_2regmisc_abs) {
17372 SETUP();
17373
17374 START();
17375
17376 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17377 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17378 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17379 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17380 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17381
17382 __ Abs(v16.V8B(), v0.V8B());
17383 __ Abs(v17.V16B(), v0.V16B());
17384 __ Abs(v18.V4H(), v1.V4H());
17385 __ Abs(v19.V8H(), v1.V8H());
17386 __ Abs(v20.V2S(), v2.V2S());
17387 __ Abs(v21.V4S(), v2.V4S());
17388 __ Abs(d22, d3);
17389 __ Abs(v23.V2D(), v3.V2D());
17390 __ Abs(v24.V2D(), v4.V2D());
17391
17392 END();
17393
17394 RUN();
17395 ASSERT_EQUAL_128(0x0000000000000000, 0x807f0100017f807f, q16);
17396 ASSERT_EQUAL_128(0x7f0100017f807f01, 0x807f0100017f807f, q17);
17397 ASSERT_EQUAL_128(0x0000000000000000, 0x0001000000017fff, q18);
17398 ASSERT_EQUAL_128(0x80007fff00010000, 0x0001000000017fff, q19);
17399 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
17400 ASSERT_EQUAL_128(0x8000000000000001, 0x000000007fffffff, q21);
17401 ASSERT_EQUAL_128(0x0000000000000000, 0x7fffffffffffffff, q22);
17402 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x7fffffffffffffff, q23);
17403 ASSERT_EQUAL_128(0x8000000000000000, 0x0000000000000000, q24);
17404
17405 TEARDOWN();
17406}
17407
17408
17409TEST(neon_2regmisc_sqabs) {
17410 SETUP();
17411
17412 START();
17413
17414 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17415 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17416 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17417 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17418 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17419
17420 __ Sqabs(v16.V8B(), v0.V8B());
17421 __ Sqabs(v17.V16B(), v0.V16B());
17422 __ Sqabs(v18.V4H(), v1.V4H());
17423 __ Sqabs(v19.V8H(), v1.V8H());
17424 __ Sqabs(v20.V2S(), v2.V2S());
17425 __ Sqabs(v21.V4S(), v2.V4S());
17426 __ Sqabs(v22.V2D(), v3.V2D());
17427 __ Sqabs(v23.V2D(), v4.V2D());
17428
17429 __ Sqabs(b24, b0);
17430 __ Sqabs(h25, h1);
17431 __ Sqabs(s26, s2);
17432 __ Sqabs(d27, d3);
17433
17434 END();
17435
17436 RUN();
17437 ASSERT_EQUAL_128(0x0000000000000000, 0x7f7f0100017f7f7f, q16);
17438 ASSERT_EQUAL_128(0x7f0100017f7f7f01, 0x7f7f0100017f7f7f, q17);
17439 ASSERT_EQUAL_128(0x0000000000000000, 0x0001000000017fff, q18);
17440 ASSERT_EQUAL_128(0x7fff7fff00010000, 0x0001000000017fff, q19);
17441 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
17442 ASSERT_EQUAL_128(0x7fffffff00000001, 0x000000007fffffff, q21);
17443 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x7fffffffffffffff, q22);
17444 ASSERT_EQUAL_128(0x7fffffffffffffff, 0x0000000000000000, q23);
17445
17446 ASSERT_EQUAL_128(0, 0x7f, q24);
17447 ASSERT_EQUAL_128(0, 0x7fff, q25);
17448 ASSERT_EQUAL_128(0, 0x7fffffff, q26);
17449 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q27);
17450
17451 TEARDOWN();
17452}
17453
17454TEST(neon_2regmisc_suqadd) {
17455 SETUP();
17456
17457 START();
17458
17459 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17460 __ Movi(v1.V2D(), 0x017f8081ff00017f, 0x010080ff7f0180ff);
17461
17462 __ Movi(v2.V2D(), 0x80008001ffff0000, 0xffff000000017ffd);
17463 __ Movi(v3.V2D(), 0xffff000080008001, 0x00017fffffff0001);
17464
17465 __ Movi(v4.V2D(), 0x80000000fffffffe, 0xfffffff17ffffffe);
17466 __ Movi(v5.V2D(), 0xffffffff80000000, 0x7fffffff00000002);
17467
17468 __ Movi(v6.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17469 __ Movi(v7.V2D(), 0x8000000000000000, 0x8000000000000002);
17470
17471 __ Mov(v16.V2D(), v0.V2D());
17472 __ Mov(v17.V2D(), v0.V2D());
17473 __ Mov(v18.V2D(), v2.V2D());
17474 __ Mov(v19.V2D(), v2.V2D());
17475 __ Mov(v20.V2D(), v4.V2D());
17476 __ Mov(v21.V2D(), v4.V2D());
17477 __ Mov(v22.V2D(), v6.V2D());
17478
17479 __ Mov(v23.V2D(), v0.V2D());
17480 __ Mov(v24.V2D(), v2.V2D());
17481 __ Mov(v25.V2D(), v4.V2D());
17482 __ Mov(v26.V2D(), v6.V2D());
17483
17484 __ Suqadd(v16.V8B(), v1.V8B());
17485 __ Suqadd(v17.V16B(), v1.V16B());
17486 __ Suqadd(v18.V4H(), v3.V4H());
17487 __ Suqadd(v19.V8H(), v3.V8H());
17488 __ Suqadd(v20.V2S(), v5.V2S());
17489 __ Suqadd(v21.V4S(), v5.V4S());
17490 __ Suqadd(v22.V2D(), v7.V2D());
17491
17492 __ Suqadd(b23, b1);
17493 __ Suqadd(h24, h3);
17494 __ Suqadd(s25, s5);
17495 __ Suqadd(d26, d7);
17496
17497 END();
17498
17499 RUN();
17500 ASSERT_EQUAL_128(0x0000000000000000, 0x81817f7f7f7f007f, q16);
17501 ASSERT_EQUAL_128(0x7f7f7f7f7f807f7f, 0x81817f7f7f7f007f, q17);
17502 ASSERT_EQUAL_128(0x0000000000000000, 0x00007fff7fff7ffe, q18);
17503 ASSERT_EQUAL_128(0x7fff80017fff7fff, 0x00007fff7fff7ffe, q19);
17504 ASSERT_EQUAL_128(0x0000000000000000, 0x7ffffff07fffffff, q20);
17505 ASSERT_EQUAL_128(0x7fffffff7ffffffe, 0x7ffffff07fffffff, q21);
17506 ASSERT_EQUAL_128(0x0000000000000001, 0x7fffffffffffffff, q22);
17507
17508 ASSERT_EQUAL_128(0, 0x7f, q23);
17509 ASSERT_EQUAL_128(0, 0x7ffe, q24);
17510 ASSERT_EQUAL_128(0, 0x7fffffff, q25);
17511 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q26);
17512 TEARDOWN();
17513}
17514
17515TEST(neon_2regmisc_usqadd) {
17516 SETUP();
17517
17518 START();
17519
17520 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f7ffe);
17521 __ Movi(v1.V2D(), 0x017f8081ff00017f, 0x010080ff7f018002);
17522
17523 __ Movi(v2.V2D(), 0x80008001fffe0000, 0xffff000000017ffd);
17524 __ Movi(v3.V2D(), 0xffff000000028001, 0x00017fffffff0001);
17525
17526 __ Movi(v4.V2D(), 0x80000000fffffffe, 0x00000001fffffffe);
17527 __ Movi(v5.V2D(), 0xffffffff80000000, 0xfffffffe00000002);
17528
17529 __ Movi(v6.V2D(), 0x8000000000000002, 0x7fffffffffffffff);
17530 __ Movi(v7.V2D(), 0x7fffffffffffffff, 0x8000000000000000);
17531
17532 __ Mov(v16.V2D(), v0.V2D());
17533 __ Mov(v17.V2D(), v0.V2D());
17534 __ Mov(v18.V2D(), v2.V2D());
17535 __ Mov(v19.V2D(), v2.V2D());
17536 __ Mov(v20.V2D(), v4.V2D());
17537 __ Mov(v21.V2D(), v4.V2D());
17538 __ Mov(v22.V2D(), v6.V2D());
17539
17540 __ Mov(v23.V2D(), v0.V2D());
17541 __ Mov(v24.V2D(), v2.V2D());
17542 __ Mov(v25.V2D(), v4.V2D());
17543 __ Mov(v26.V2D(), v6.V2D());
17544
17545 __ Usqadd(v16.V8B(), v1.V8B());
17546 __ Usqadd(v17.V16B(), v1.V16B());
17547 __ Usqadd(v18.V4H(), v3.V4H());
17548 __ Usqadd(v19.V8H(), v3.V8H());
17549 __ Usqadd(v20.V2S(), v5.V2S());
17550 __ Usqadd(v21.V4S(), v5.V4S());
17551 __ Usqadd(v22.V2D(), v7.V2D());
17552
17553 __ Usqadd(b23, b1);
17554 __ Usqadd(h24, h3);
17555 __ Usqadd(s25, s5);
17556 __ Usqadd(d26, d7);
17557
17558 END();
17559
17560 RUN();
17561 ASSERT_EQUAL_128(0x0000000000000000, 0x81817f00808000ff, q16);
17562 ASSERT_EQUAL_128(0x8080008080808080, 0x81817f00808000ff, q17);
17563 ASSERT_EQUAL_128(0x0000000000000000, 0xffff7fff00007ffe, q18);
17564 ASSERT_EQUAL_128(0x7fff8001ffff0000, 0xffff7fff00007ffe, q19);
17565 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q20);
17566 ASSERT_EQUAL_128(0x7fffffff7ffffffe, 0x00000000ffffffff, q21);
17567 ASSERT_EQUAL_128(0xffffffffffffffff, 0x0000000000000000, q22);
17568
17569 ASSERT_EQUAL_128(0, 0xff, q23);
17570 ASSERT_EQUAL_128(0, 0x7ffe, q24);
17571 ASSERT_EQUAL_128(0, 0xffffffff, q25);
17572 ASSERT_EQUAL_128(0, 0x0000000000000000, q26);
17573 TEARDOWN();
17574}
17575
17576
17577TEST(system_sys) {
17578 SETUP();
17579 const char* msg = "SYS test!";
17580 uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
17581
17582 START();
17583 __ Mov(x4, msg_addr);
17584 __ Sys(3, 0x7, 0x5, 1, x4);
17585 __ Mov(x3, x4);
17586 __ Sys(3, 0x7, 0xa, 1, x3);
17587 __ Mov(x2, x3);
17588 __ Sys(3, 0x7, 0xb, 1, x2);
17589 __ Mov(x1, x2);
17590 __ Sys(3, 0x7, 0xe, 1, x1);
17591 // TODO: Add tests to check ZVA equivalent.
17592 END();
17593
17594 RUN();
17595
17596 TEARDOWN();
17597}
17598
17599
17600TEST(system_ic) {
17601 SETUP();
17602 const char* msg = "IC test!";
17603 uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
17604
17605 START();
17606 __ Mov(x11, msg_addr);
17607 __ Ic(IVAU, x11);
17608 END();
17609
17610 RUN();
17611
17612 TEARDOWN();
17613}
17614
17615
17616TEST(system_dc) {
17617 SETUP();
17618 const char* msg = "DC test!";
17619 uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
17620
17621 START();
17622 __ Mov(x20, msg_addr);
17623 __ Dc(CVAC, x20);
17624 __ Mov(x21, x20);
17625 __ Dc(CVAU, x21);
17626 __ Mov(x22, x21);
17627 __ Dc(CIVAC, x22);
17628 // TODO: Add tests to check ZVA.
17629 END();
17630
17631 RUN();
17632
17633 TEARDOWN();
17634}
17635
17636
17637TEST(neon_2regmisc_xtn) {
17638 SETUP();
17639
17640 START();
17641
17642 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
17643 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17644 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17645 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17646 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17647
17648 __ Xtn(v16.V8B(), v0.V8H());
17649 __ Xtn2(v16.V16B(), v1.V8H());
17650 __ Xtn(v17.V4H(), v1.V4S());
17651 __ Xtn2(v17.V8H(), v2.V4S());
17652 __ Xtn(v18.V2S(), v3.V2D());
17653 __ Xtn2(v18.V4S(), v4.V2D());
17654
17655 END();
17656
17657 RUN();
17658 ASSERT_EQUAL_128(0x0001ff00ff0001ff, 0x01ff800181007f81, q16);
17659 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x8001000000007fff, q17);
17660 ASSERT_EQUAL_128(0x0000000000000000, 0x00000001ffffffff, q18);
17661 TEARDOWN();
17662}
17663
17664
17665TEST(neon_2regmisc_sqxtn) {
17666 SETUP();
17667
17668 START();
17669
17670 __ Movi(v0.V2D(), 0x7f01007a81807f01, 0x8081ff00017f8081);
17671 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17672 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17673 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17674 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17675
17676 __ Sqxtn(v16.V8B(), v0.V8H());
17677 __ Sqxtn2(v16.V16B(), v1.V8H());
17678 __ Sqxtn(v17.V4H(), v1.V4S());
17679 __ Sqxtn2(v17.V8H(), v2.V4S());
17680 __ Sqxtn(v18.V2S(), v3.V2D());
17681 __ Sqxtn2(v18.V4S(), v4.V2D());
17682 __ Sqxtn(b19, h0);
17683 __ Sqxtn(h20, s0);
17684 __ Sqxtn(s21, d0);
17685
17686 END();
17687
17688 RUN();
17689 ASSERT_EQUAL_128(0x8080ff00ff00017f, 0x7f7a807f80807f80, q16);
17690 ASSERT_EQUAL_128(0x8000ffff00007fff, 0x8000800080007fff, q17);
17691 ASSERT_EQUAL_128(0x8000000000000000, 0x800000007fffffff, q18);
17692 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000080, q19);
17693 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000007fff, q20);
17694 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000000, q21);
17695 TEARDOWN();
17696}
17697
17698
17699TEST(neon_2regmisc_uqxtn) {
17700 SETUP();
17701
17702 START();
17703
17704 __ Movi(v0.V2D(), 0x7f01007a81807f01, 0x8081ff00017f8081);
17705 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17706 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17707 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17708 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17709
17710 __ Uqxtn(v16.V8B(), v0.V8H());
17711 __ Uqxtn2(v16.V16B(), v1.V8H());
17712 __ Uqxtn(v17.V4H(), v1.V4S());
17713 __ Uqxtn2(v17.V8H(), v2.V4S());
17714 __ Uqxtn(v18.V2S(), v3.V2D());
17715 __ Uqxtn2(v18.V4S(), v4.V2D());
17716 __ Uqxtn(b19, h0);
17717 __ Uqxtn(h20, s0);
17718 __ Uqxtn(s21, d0);
17719
17720 END();
17721
17722 RUN();
17723 ASSERT_EQUAL_128(0xffffff00ff0001ff, 0xff7affffffffffff, q16);
17724 ASSERT_EQUAL_128(0xffffffff0000ffff, 0xffffffffffffffff, q17);
17725 ASSERT_EQUAL_128(0xffffffff00000000, 0xffffffffffffffff, q18);
17726 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000000000ff, q19);
17727 ASSERT_EQUAL_128(0x0000000000000000, 0x000000000000ffff, q20);
17728 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q21);
17729 TEARDOWN();
17730}
17731
17732
17733TEST(neon_2regmisc_sqxtun) {
17734 SETUP();
17735
17736 START();
17737
17738 __ Movi(v0.V2D(), 0x7f01007a81807f01, 0x8081ff00017f8081);
17739 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
17740 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
17741 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
17742 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
17743
17744 __ Sqxtun(v16.V8B(), v0.V8H());
17745 __ Sqxtun2(v16.V16B(), v1.V8H());
17746 __ Sqxtun(v17.V4H(), v1.V4S());
17747 __ Sqxtun2(v17.V8H(), v2.V4S());
17748 __ Sqxtun(v18.V2S(), v3.V2D());
17749 __ Sqxtun2(v18.V4S(), v4.V2D());
17750 __ Sqxtun(b19, h0);
17751 __ Sqxtun(h20, s0);
17752 __ Sqxtun(s21, d0);
17753
17754 END();
17755
17756 RUN();
17757 ASSERT_EQUAL_128(0x00000000000001ff, 0xff7a00ff0000ff00, q16);
17758 ASSERT_EQUAL_128(0x000000000000ffff, 0x000000000000ffff, q17);
17759 ASSERT_EQUAL_128(0x0000000000000000, 0x00000000ffffffff, q18);
17760 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q19);
17761 ASSERT_EQUAL_128(0x0000000000000000, 0x000000000000ffff, q20);
17762 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q21);
17763 TEARDOWN();
17764}
17765
17766TEST(neon_3same_and) {
17767 SETUP();
17768
17769 START();
17770
17771 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17772 __ Movi(v1.V2D(), 0x00aa55aaff55ff00, 0xaa55ff00555500ff);
17773
17774 __ And(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17775 __ And(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17776 __ And(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17777 __ And(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17778 END();
17779
17780 RUN();
17781 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q16);
17782 ASSERT_EQUAL_128(0x0000000000555500, 0xaa00aa00005500aa, q17);
17783 ASSERT_EQUAL_128(0, 0xff00aa5500ff55aa, q24);
17784 ASSERT_EQUAL_128(0, 0xaa00aa00005500aa, q25);
17785 TEARDOWN();
17786}
17787
17788TEST(neon_3same_bic) {
17789 SETUP();
17790
17791 START();
17792
17793 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17794 __ Movi(v1.V2D(), 0x00ffaa00aa55aaff, 0xffff005500ff00ff);
17795
17796 __ Bic(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17797 __ Bic(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17798 __ Bic(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17799 __ Bic(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17800 END();
17801
17802 RUN();
17803 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q16);
17804 ASSERT_EQUAL_128(0xff00005500aa5500, 0x0000aa0000005500, q17);
17805 ASSERT_EQUAL_128(0, 0x0000000000000000, q24);
17806 ASSERT_EQUAL_128(0, 0x0000aa0000005500, q25);
17807 TEARDOWN();
17808}
17809
17810TEST(neon_3same_orr) {
17811 SETUP();
17812
17813 START();
17814
17815 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17816 __ Movi(v1.V2D(), 0x00aa55aaff55ff00, 0xaa55ff00555500ff);
17817
17818 __ Orr(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17819 __ Orr(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17820 __ Orr(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17821 __ Orr(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17822 END();
17823
17824 RUN();
17825 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q16);
17826 ASSERT_EQUAL_128(0xffaaffffffffffaa, 0xff55ff5555ff55ff, q17);
17827 ASSERT_EQUAL_128(0, 0xff00aa5500ff55aa, q24);
17828 ASSERT_EQUAL_128(0, 0xff55ff5555ff55ff, q25);
17829 TEARDOWN();
17830}
17831
17832TEST(neon_3same_mov) {
17833 SETUP();
17834
17835 START();
17836
17837 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17838
17839 __ Mov(v16.V16B(), v0.V16B());
17840 __ Mov(v17.V8H(), v0.V8H());
17841 __ Mov(v18.V4S(), v0.V4S());
17842 __ Mov(v19.V2D(), v0.V2D());
17843
17844 __ Mov(v24.V8B(), v0.V8B());
17845 __ Mov(v25.V4H(), v0.V4H());
17846 __ Mov(v26.V2S(), v0.V2S());
17847 END();
17848
17849 RUN();
17850
17851 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q16);
17852 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q17);
17853 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q18);
17854 ASSERT_EQUAL_128(0xff00aa5500ff55aa, 0xff00aa5500ff55aa, q19);
17855
17856 ASSERT_EQUAL_128(0x0, 0xff00aa5500ff55aa, q24);
17857 ASSERT_EQUAL_128(0x0, 0xff00aa5500ff55aa, q25);
17858 ASSERT_EQUAL_128(0x0, 0xff00aa5500ff55aa, q26);
17859
17860 TEARDOWN();
17861}
17862
17863TEST(neon_3same_orn) {
17864 SETUP();
17865
17866 START();
17867
17868 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17869 __ Movi(v1.V2D(), 0x00aa55aaff55ff00, 0xaa55ff00555500ff);
17870
17871 __ Orn(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17872 __ Orn(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17873 __ Orn(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17874 __ Orn(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17875 END();
17876
17877 RUN();
17878 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q16);
17879 ASSERT_EQUAL_128(0xff55aa5500ff55ff, 0xffaaaaffaaffffaa, q17);
17880 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q24);
17881 ASSERT_EQUAL_128(0, 0xffaaaaffaaffffaa, q25);
17882 TEARDOWN();
17883}
17884
17885TEST(neon_3same_eor) {
17886 SETUP();
17887
17888 START();
17889
17890 __ Movi(v0.V2D(), 0xff00aa5500ff55aa, 0xff00aa5500ff55aa);
17891 __ Movi(v1.V2D(), 0x00ffaa00aa55aaff, 0xffff005500ff00ff);
17892
17893 __ Eor(v16.V16B(), v0.V16B(), v0.V16B()); // self test
17894 __ Eor(v17.V16B(), v0.V16B(), v1.V16B()); // all combinations
17895 __ Eor(v24.V8B(), v0.V8B(), v0.V8B()); // self test
17896 __ Eor(v25.V8B(), v0.V8B(), v1.V8B()); // all combinations
17897 END();
17898
17899 RUN();
17900 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q16);
17901 ASSERT_EQUAL_128(0xffff0055aaaaff55, 0x00ffaa0000005555, q17);
17902 ASSERT_EQUAL_128(0, 0x0000000000000000, q24);
17903 ASSERT_EQUAL_128(0, 0x00ffaa0000005555, q25);
17904 TEARDOWN();
17905}
17906
17907TEST(neon_3same_bif) {
17908 SETUP();
17909
17910 START();
17911
17912 __ Movi(v16.V2D(), 0xffff0000ff00ffff, 0xffff00000000aaaa);
17913 __ Movi(v0.V2D(), 0xff00ff00ff005555, 0xaaaa5555aaaaaaaa);
17914 __ Movi(v1.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
17915
17916 __ Movi(v17.V2D(), 0x5555aa55cccccccc, 0x33333333f0f0f0f0);
17917 __ Movi(v2.V2D(), 0x555555aaff00ff00, 0xff00ff00ff00ff00);
17918 __ Movi(v3.V2D(), 0xaa55aa5500ffff00, 0x00ffff0000ffff00);
17919
17920 __ Movi(v18.V2D(), 0, 0xf0f0f0f00f0f0f0f);
17921 __ Movi(v4.V2D(), 0, 0xf0f0f0f0f0f0f0f0);
17922 __ Movi(v5.V2D(), 0, 0x00ffff0000ffff00);
17923
17924 __ Bif(v16.V16B(), v0.V16B(), v1.V16B());
17925 __ Bif(v17.V16B(), v2.V16B(), v3.V16B());
17926 __ Bif(v18.V8B(), v4.V8B(), v5.V8B());
17927 END();
17928
17929 RUN();
17930
17931 ASSERT_EQUAL_128(0xffffff00ff0055ff, 0xffaa0055aa00aaaa, q16);
17932 ASSERT_EQUAL_128(0x5555ffffffcccc00, 0xff333300fff0f000, q17);
17933 ASSERT_EQUAL_128(0, 0xf0f0f0f0f00f0ff0, q18);
17934 TEARDOWN();
17935}
17936
17937TEST(neon_3same_bit) {
17938 SETUP();
17939
17940 START();
17941
17942 __ Movi(v16.V2D(), 0xffff0000ff00ffff, 0xffff00000000aaaa);
17943 __ Movi(v0.V2D(), 0xff00ff00ff005555, 0xaaaa5555aaaaaaaa);
17944 __ Movi(v1.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
17945
17946 __ Movi(v17.V2D(), 0x5555aa55cccccccc, 0x33333333f0f0f0f0);
17947 __ Movi(v2.V2D(), 0x555555aaff00ff00, 0xff00ff00ff00ff00);
17948 __ Movi(v3.V2D(), 0xaa55aa5500ffff00, 0x00ffff0000ffff00);
17949
17950 __ Movi(v18.V2D(), 0, 0xf0f0f0f00f0f0f0f);
17951 __ Movi(v4.V2D(), 0, 0xf0f0f0f0f0f0f0f0);
17952 __ Movi(v5.V2D(), 0, 0x00ffff0000ffff00);
17953
17954 __ Bit(v16.V16B(), v0.V16B(), v1.V16B());
17955 __ Bit(v17.V16B(), v2.V16B(), v3.V16B());
17956 __ Bit(v18.V8B(), v4.V8B(), v5.V8B());
17957 END();
17958
17959 RUN();
17960
17961 ASSERT_EQUAL_128(0xff000000ff00ff55, 0xaaff550000aaaaaa, q16);
17962 ASSERT_EQUAL_128(0x55550000cc00ffcc, 0x3300ff33f000fff0, q17);
17963 ASSERT_EQUAL_128(0, 0xf0f0f0f00ff0f00f, q18);
17964 TEARDOWN();
17965}
17966
17967TEST(neon_3same_bsl) {
17968 SETUP();
17969
17970 START();
17971
17972 __ Movi(v16.V2D(), 0xffff0000ff00ffff, 0xffff00000000aaaa);
17973 __ Movi(v0.V2D(), 0xff00ff00ff005555, 0xaaaa5555aaaaaaaa);
17974 __ Movi(v1.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
17975
17976 __ Movi(v17.V2D(), 0x5555aa55cccccccc, 0x33333333f0f0f0f0);
17977 __ Movi(v2.V2D(), 0x555555aaff00ff00, 0xff00ff00ff00ff00);
17978 __ Movi(v3.V2D(), 0xaa55aa5500ffff00, 0x00ffff0000ffff00);
17979
17980 __ Movi(v18.V2D(), 0, 0xf0f0f0f00f0f0f0f);
17981 __ Movi(v4.V2D(), 0, 0xf0f0f0f0f0f0f0f0);
17982 __ Movi(v5.V2D(), 0, 0x00ffff0000ffff00);
17983
17984 __ Bsl(v16.V16B(), v0.V16B(), v1.V16B());
17985 __ Bsl(v17.V16B(), v2.V16B(), v3.V16B());
17986 __ Bsl(v18.V8B(), v4.V8B(), v5.V8B());
17987 END();
17988
17989 RUN();
17990
17991 ASSERT_EQUAL_128(0xff0000ffff005555, 0xaaaa55aa55aaffaa, q16);
17992 ASSERT_EQUAL_128(0xff550000cc33ff00, 0x33ccff00f00fff00, q17);
17993 ASSERT_EQUAL_128(0, 0xf0fffff000f0f000, q18);
17994 TEARDOWN();
17995}
17996
17997
17998TEST(neon_3same_smax) {
17999 SETUP();
18000
18001 START();
18002
18003 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
18004 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18005
18006 __ Smax(v16.V8B(), v0.V8B(), v1.V8B());
18007 __ Smax(v18.V4H(), v0.V4H(), v1.V4H());
18008 __ Smax(v20.V2S(), v0.V2S(), v1.V2S());
18009
18010 __ Smax(v17.V16B(), v0.V16B(), v1.V16B());
18011 __ Smax(v19.V8H(), v0.V8H(), v1.V8H());
18012 __ Smax(v21.V4S(), v0.V4S(), v1.V4S());
18013 END();
18014
18015 RUN();
18016
18017 ASSERT_EQUAL_128(0x0, 0x0000000000005555, q16);
18018 ASSERT_EQUAL_128(0x0, 0x00000000000055ff, q18);
18019 ASSERT_EQUAL_128(0x0, 0x000000000000aa55, q20);
18020 ASSERT_EQUAL_128(0x55aa555555555555, 0x0000000000005555, q17);
18021 ASSERT_EQUAL_128(0x55aa555555555555, 0x00000000000055ff, q19);
18022 ASSERT_EQUAL_128(0x55aa555555555555, 0x000000000000aa55, q21);
18023 TEARDOWN();
18024}
18025
18026
18027TEST(neon_3same_smaxp) {
18028 SETUP();
18029
18030 START();
18031
18032 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
18033 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18034
18035 __ Smaxp(v16.V8B(), v0.V8B(), v1.V8B());
18036 __ Smaxp(v18.V4H(), v0.V4H(), v1.V4H());
18037 __ Smaxp(v20.V2S(), v0.V2S(), v1.V2S());
18038
18039 __ Smaxp(v17.V16B(), v0.V16B(), v1.V16B());
18040 __ Smaxp(v19.V8H(), v0.V8H(), v1.V8H());
18041 __ Smaxp(v21.V4S(), v0.V4S(), v1.V4S());
18042 END();
18043
18044 RUN();
18045
18046 ASSERT_EQUAL_128(0x0, 0x0000ff55ffff0055, q16);
18047 ASSERT_EQUAL_128(0x0, 0x000055ffffff0000, q18);
18048 ASSERT_EQUAL_128(0x0, 0x000000000000aa55, q20);
18049 ASSERT_EQUAL_128(0x5555aaaa0000ff55, 0xaaaa5555ffff0055, q17);
18050 ASSERT_EQUAL_128(0x55aaaaaa000055ff, 0xaaaa5555ffff0000, q19);
18051 ASSERT_EQUAL_128(0x55aa555500000000, 0x555555550000aa55, q21);
18052 TEARDOWN();
18053}
18054
18055
18056TEST(neon_addp_scalar) {
18057 SETUP();
18058
18059 START();
18060
18061 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
18062 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18063 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
18064
18065 __ Addp(d16, v0.V2D());
18066 __ Addp(d17, v1.V2D());
18067 __ Addp(d18, v2.V2D());
18068
18069 END();
18070
18071 RUN();
18072
18073 ASSERT_EQUAL_128(0x0, 0x00224466ef66fa80, q16);
18074 ASSERT_EQUAL_128(0x0, 0x55aa5556aa5500a9, q17);
18075 ASSERT_EQUAL_128(0x0, 0xaaaaaaa96655ff55, q18);
18076 TEARDOWN();
18077}
18078
18079TEST(neon_acrosslanes_addv) {
18080 SETUP();
18081
18082 START();
18083
18084 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
18085 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18086 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
18087
18088 __ Addv(b16, v0.V8B());
18089 __ Addv(b17, v0.V16B());
18090 __ Addv(h18, v1.V4H());
18091 __ Addv(h19, v1.V8H());
18092 __ Addv(s20, v2.V4S());
18093
18094 END();
18095
18096 RUN();
18097
18098 ASSERT_EQUAL_128(0x0, 0xc7, q16);
18099 ASSERT_EQUAL_128(0x0, 0x99, q17);
18100 ASSERT_EQUAL_128(0x0, 0x55a9, q18);
18101 ASSERT_EQUAL_128(0x0, 0x55fc, q19);
18102 ASSERT_EQUAL_128(0x0, 0x1100a9fe, q20);
18103 TEARDOWN();
18104}
18105
18106
18107TEST(neon_acrosslanes_saddlv) {
18108 SETUP();
18109
18110 START();
18111
18112 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
18113 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18114 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
18115
18116 __ Saddlv(h16, v0.V8B());
18117 __ Saddlv(h17, v0.V16B());
18118 __ Saddlv(s18, v1.V4H());
18119 __ Saddlv(s19, v1.V8H());
18120 __ Saddlv(d20, v2.V4S());
18121
18122 END();
18123
18124 RUN();
18125
18126 ASSERT_EQUAL_128(0x0, 0xffc7, q16);
18127 ASSERT_EQUAL_128(0x0, 0xff99, q17);
18128 ASSERT_EQUAL_128(0x0, 0x000055a9, q18);
18129 ASSERT_EQUAL_128(0x0, 0x000055fc, q19);
18130 ASSERT_EQUAL_128(0x0, 0x0000001100a9fe, q20);
18131 TEARDOWN();
18132}
18133
18134
18135TEST(neon_acrosslanes_uaddlv) {
18136 SETUP();
18137
18138 START();
18139
18140 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
18141 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18142 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
18143
18144 __ Uaddlv(h16, v0.V8B());
18145 __ Uaddlv(h17, v0.V16B());
18146 __ Uaddlv(s18, v1.V4H());
18147 __ Uaddlv(s19, v1.V8H());
18148 __ Uaddlv(d20, v2.V4S());
18149
18150 END();
18151
18152 RUN();
18153
18154 ASSERT_EQUAL_128(0x0, 0x02c7, q16);
18155 ASSERT_EQUAL_128(0x0, 0x0599, q17);
18156 ASSERT_EQUAL_128(0x0, 0x000155a9, q18);
18157 ASSERT_EQUAL_128(0x0, 0x000355fc, q19);
18158 ASSERT_EQUAL_128(0x0, 0x000000021100a9fe, q20);
18159 TEARDOWN();
18160}
18161
18162
18163TEST(neon_acrosslanes_smaxv) {
18164 SETUP();
18165
18166 START();
18167
18168 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
18169 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18170 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
18171
18172 __ Smaxv(b16, v0.V8B());
18173 __ Smaxv(b17, v0.V16B());
18174 __ Smaxv(h18, v1.V4H());
18175 __ Smaxv(h19, v1.V8H());
18176 __ Smaxv(s20, v2.V4S());
18177
18178 END();
18179
18180 RUN();
18181
18182 ASSERT_EQUAL_128(0x0, 0x33, q16);
18183 ASSERT_EQUAL_128(0x0, 0x44, q17);
18184 ASSERT_EQUAL_128(0x0, 0x55ff, q18);
18185 ASSERT_EQUAL_128(0x0, 0x55ff, q19);
18186 ASSERT_EQUAL_128(0x0, 0x66555555, q20);
18187 TEARDOWN();
18188}
18189
18190
18191TEST(neon_acrosslanes_sminv) {
18192 SETUP();
18193
18194 START();
18195
18196 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
18197 __ Movi(v1.V2D(), 0xfffa5555aaaaaaaa, 0x00000000ffaa55ff);
18198 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
18199
18200 __ Sminv(b16, v0.V8B());
18201 __ Sminv(b17, v0.V16B());
18202 __ Sminv(h18, v1.V4H());
18203 __ Sminv(h19, v1.V8H());
18204 __ Sminv(s20, v2.V4S());
18205
18206 END();
18207
18208 RUN();
18209
18210 ASSERT_EQUAL_128(0x0, 0xaa, q16);
18211 ASSERT_EQUAL_128(0x0, 0x80, q17);
18212 ASSERT_EQUAL_128(0x0, 0xffaa, q18);
18213 ASSERT_EQUAL_128(0x0, 0xaaaa, q19);
18214 ASSERT_EQUAL_128(0x0, 0xaaaaaaaa, q20);
18215 TEARDOWN();
18216}
18217
18218TEST(neon_acrosslanes_umaxv) {
18219 SETUP();
18220
18221 START();
18222
18223 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x00112233aabbfc00);
18224 __ Movi(v1.V2D(), 0x55aa5555aaaaffab, 0x00000000ffaa55ff);
18225 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
18226
18227 __ Umaxv(b16, v0.V8B());
18228 __ Umaxv(b17, v0.V16B());
18229 __ Umaxv(h18, v1.V4H());
18230 __ Umaxv(h19, v1.V8H());
18231 __ Umaxv(s20, v2.V4S());
18232
18233 END();
18234
18235 RUN();
18236
18237 ASSERT_EQUAL_128(0x0, 0xfc, q16);
18238 ASSERT_EQUAL_128(0x0, 0xfe, q17);
18239 ASSERT_EQUAL_128(0x0, 0xffaa, q18);
18240 ASSERT_EQUAL_128(0x0, 0xffab, q19);
18241 ASSERT_EQUAL_128(0x0, 0xffffffff, q20);
18242 TEARDOWN();
18243}
18244
18245
18246TEST(neon_acrosslanes_uminv) {
18247 SETUP();
18248
18249 START();
18250
18251 __ Movi(v0.V2D(), 0x0011223344aafe80, 0x02112233aabbfc01);
18252 __ Movi(v1.V2D(), 0xfffa5555aaaa0000, 0x00010003ffaa55ff);
18253 __ Movi(v2.V2D(), 0xaaaaaaaa66555555, 0xffffffff0000aa00);
18254
18255 __ Uminv(b16, v0.V8B());
18256 __ Uminv(b17, v0.V16B());
18257 __ Uminv(h18, v1.V4H());
18258 __ Uminv(h19, v1.V8H());
18259 __ Uminv(s20, v2.V4S());
18260
18261 END();
18262
18263 RUN();
18264
18265 ASSERT_EQUAL_128(0x0, 0x01, q16);
18266 ASSERT_EQUAL_128(0x0, 0x00, q17);
18267 ASSERT_EQUAL_128(0x0, 0x0001, q18);
18268 ASSERT_EQUAL_128(0x0, 0x0000, q19);
18269 ASSERT_EQUAL_128(0x0, 0x0000aa00, q20);
18270 TEARDOWN();
18271}
18272
18273
18274TEST(neon_3same_smin) {
18275 SETUP();
18276
18277 START();
18278
18279 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
18280 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18281
18282 __ Smin(v16.V8B(), v0.V8B(), v1.V8B());
18283 __ Smin(v18.V4H(), v0.V4H(), v1.V4H());
18284 __ Smin(v20.V2S(), v0.V2S(), v1.V2S());
18285
18286 __ Smin(v17.V16B(), v0.V16B(), v1.V16B());
18287 __ Smin(v19.V8H(), v0.V8H(), v1.V8H());
18288 __ Smin(v21.V4S(), v0.V4S(), v1.V4S());
18289 END();
18290
18291 RUN();
18292
18293 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaaff, q16);
18294 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaa55, q18);
18295 ASSERT_EQUAL_128(0x0, 0xffffffffffaa55ff, q20);
18296 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaaff, q17);
18297 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaa55, q19);
18298 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaa55ff, q21);
18299 TEARDOWN();
18300}
18301
18302
18303TEST(neon_3same_umax) {
18304 SETUP();
18305
18306 START();
18307
18308 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
18309 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18310
18311 __ Umax(v16.V8B(), v0.V8B(), v1.V8B());
18312 __ Umax(v18.V4H(), v0.V4H(), v1.V4H());
18313 __ Umax(v20.V2S(), v0.V2S(), v1.V2S());
18314
18315 __ Umax(v17.V16B(), v0.V16B(), v1.V16B());
18316 __ Umax(v19.V8H(), v0.V8H(), v1.V8H());
18317 __ Umax(v21.V4S(), v0.V4S(), v1.V4S());
18318 END();
18319
18320 RUN();
18321
18322 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaaff, q16);
18323 ASSERT_EQUAL_128(0x0, 0xffffffffffaaaa55, q18);
18324 ASSERT_EQUAL_128(0x0, 0xffffffffffaa55ff, q20);
18325 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaaff, q17);
18326 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaaaa55, q19);
18327 ASSERT_EQUAL_128(0xaaaaaaaaaaaaaaaa, 0xffffffffffaa55ff, q21);
18328 TEARDOWN();
18329}
18330
18331
18332TEST(neon_3same_umin) {
18333 SETUP();
18334
18335 START();
18336
18337 __ Movi(v0.V2D(), 0xaaaaaaaa55555555, 0xffffffff0000aa55);
18338 __ Movi(v1.V2D(), 0x55aa5555aaaaaaaa, 0x00000000ffaa55ff);
18339
18340 __ Umin(v16.V8B(), v0.V8B(), v1.V8B());
18341 __ Umin(v18.V4H(), v0.V4H(), v1.V4H());
18342 __ Umin(v20.V2S(), v0.V2S(), v1.V2S());
18343
18344 __ Umin(v17.V16B(), v0.V16B(), v1.V16B());
18345 __ Umin(v19.V8H(), v0.V8H(), v1.V8H());
18346 __ Umin(v21.V4S(), v0.V4S(), v1.V4S());
18347 END();
18348
18349 RUN();
18350
18351 ASSERT_EQUAL_128(0x0, 0x0000000000005555, q16);
18352 ASSERT_EQUAL_128(0x0, 0x00000000000055ff, q18);
18353 ASSERT_EQUAL_128(0x0, 0x000000000000aa55, q20);
18354 ASSERT_EQUAL_128(0x55aa555555555555, 0x0000000000005555, q17);
18355 ASSERT_EQUAL_128(0x55aa555555555555, 0x00000000000055ff, q19);
18356 ASSERT_EQUAL_128(0x55aa555555555555, 0x000000000000aa55, q21);
18357 TEARDOWN();
18358}
18359
18360
18361TEST(neon_2regmisc_mvn) {
18362 SETUP();
18363
18364 START();
18365
18366 __ Movi(v0.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
18367
18368 __ Mvn(v16.V16B(), v0.V16B());
18369 __ Mvn(v17.V8H(), v0.V8H());
18370 __ Mvn(v18.V4S(), v0.V4S());
18371 __ Mvn(v19.V2D(), v0.V2D());
18372
18373 __ Mvn(v24.V8B(), v0.V8B());
18374 __ Mvn(v25.V4H(), v0.V4H());
18375 __ Mvn(v26.V2S(), v0.V2S());
18376
18377 END();
18378
18379 RUN();
18380
18381 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q16);
18382 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q17);
18383 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q18);
18384 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q19);
18385
18386 ASSERT_EQUAL_128(0x0, 0xaa55aa55aa55aa55, q24);
18387 ASSERT_EQUAL_128(0x0, 0xaa55aa55aa55aa55, q25);
18388 ASSERT_EQUAL_128(0x0, 0xaa55aa55aa55aa55, q26);
18389 TEARDOWN();
18390}
18391
18392
18393TEST(neon_2regmisc_not) {
18394 SETUP();
18395
18396 START();
18397
18398 __ Movi(v0.V2D(), 0x00ff00ffff0055aa, 0x55aa55aa55aa55aa);
18399 __ Movi(v1.V2D(), 0, 0x00ffff0000ffff00);
18400
18401 __ Not(v16.V16B(), v0.V16B());
18402 __ Not(v17.V8B(), v1.V8B());
18403 END();
18404
18405 RUN();
18406
18407 ASSERT_EQUAL_128(0xff00ff0000ffaa55, 0xaa55aa55aa55aa55, q16);
18408 ASSERT_EQUAL_128(0x0, 0xff0000ffff0000ff, q17);
18409 TEARDOWN();
18410}
18411
18412TEST(neon_2regmisc_cls_clz_cnt) {
18413 SETUP();
18414
18415 START();
18416
18417 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18418 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18419
18420 __ Cls(v16.V8B() , v1.V8B());
18421 __ Cls(v17.V16B(), v1.V16B());
18422 __ Cls(v18.V4H() , v1.V4H());
18423 __ Cls(v19.V8H() , v1.V8H());
18424 __ Cls(v20.V2S() , v1.V2S());
18425 __ Cls(v21.V4S() , v1.V4S());
18426
18427 __ Clz(v22.V8B() , v0.V8B());
18428 __ Clz(v23.V16B(), v0.V16B());
18429 __ Clz(v24.V4H() , v0.V4H());
18430 __ Clz(v25.V8H() , v0.V8H());
18431 __ Clz(v26.V2S() , v0.V2S());
18432 __ Clz(v27.V4S() , v0.V4S());
18433
18434 __ Cnt(v28.V8B() , v0.V8B());
18435 __ Cnt(v29.V16B(), v1.V16B());
18436
18437 END();
18438
18439 RUN();
18440
18441 ASSERT_EQUAL_128(0x0000000000000000, 0x0601000000000102, q16);
18442 ASSERT_EQUAL_128(0x0601000000000102, 0x0601000000000102, q17);
18443 ASSERT_EQUAL_128(0x0000000000000000, 0x0006000000000001, q18);
18444 ASSERT_EQUAL_128(0x0006000000000001, 0x0006000000000001, q19);
18445 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000600000000, q20);
18446 ASSERT_EQUAL_128(0x0000000600000000, 0x0000000600000000, q21);
18447
18448 ASSERT_EQUAL_128(0x0000000000000000, 0x0404040404040404, q22);
18449 ASSERT_EQUAL_128(0x0807060605050505, 0x0404040404040404, q23);
18450 ASSERT_EQUAL_128(0x0000000000000000, 0x0004000400040004, q24);
18451 ASSERT_EQUAL_128(0x000f000600050005, 0x0004000400040004, q25);
18452 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000400000004, q26);
18453 ASSERT_EQUAL_128(0x0000000f00000005, 0x0000000400000004, q27);
18454
18455 ASSERT_EQUAL_128(0x0000000000000000, 0x0102020302030304, q28);
18456 ASSERT_EQUAL_128(0x0705050305030301, 0x0103030503050507, q29);
18457
18458 TEARDOWN();
18459}
18460
18461TEST(neon_2regmisc_rev) {
18462 SETUP();
18463
18464 START();
18465
18466 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18467 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18468
18469 __ Rev16(v16.V8B() , v0.V8B());
18470 __ Rev16(v17.V16B(), v0.V16B());
18471
18472 __ Rev32(v18.V8B() , v0.V8B());
18473 __ Rev32(v19.V16B(), v0.V16B());
18474 __ Rev32(v20.V4H() , v0.V4H());
18475 __ Rev32(v21.V8H() , v0.V8H());
18476
18477 __ Rev64(v22.V8B() , v0.V8B());
18478 __ Rev64(v23.V16B(), v0.V16B());
18479 __ Rev64(v24.V4H() , v0.V4H());
18480 __ Rev64(v25.V8H() , v0.V8H());
18481 __ Rev64(v26.V2S() , v0.V2S());
18482 __ Rev64(v27.V4S() , v0.V4S());
18483
18484 __ Rbit(v28.V8B() , v1.V8B());
18485 __ Rbit(v29.V16B(), v1.V16B());
18486
18487 END();
18488
18489 RUN();
18490
18491 ASSERT_EQUAL_128(0x0000000000000000, 0x09080b0a0d0c0f0e, q16);
18492 ASSERT_EQUAL_128(0x0100030205040706, 0x09080b0a0d0c0f0e, q17);
18493
18494 ASSERT_EQUAL_128(0x0000000000000000, 0x0b0a09080f0e0d0c, q18);
18495 ASSERT_EQUAL_128(0x0302010007060504, 0x0b0a09080f0e0d0c, q19);
18496 ASSERT_EQUAL_128(0x0000000000000000, 0x0a0b08090e0f0c0d, q20);
18497 ASSERT_EQUAL_128(0x0203000106070405, 0x0a0b08090e0f0c0d, q21);
18498
18499 ASSERT_EQUAL_128(0x0000000000000000, 0x0f0e0d0c0b0a0908, q22);
18500 ASSERT_EQUAL_128(0x0706050403020100, 0x0f0e0d0c0b0a0908, q23);
18501 ASSERT_EQUAL_128(0x0000000000000000, 0x0e0f0c0d0a0b0809, q24);
18502 ASSERT_EQUAL_128(0x0607040502030001, 0x0e0f0c0d0a0b0809, q25);
18503 ASSERT_EQUAL_128(0x0000000000000000, 0x0c0d0e0f08090a0b, q26);
18504 ASSERT_EQUAL_128(0x0405060700010203, 0x0c0d0e0f08090a0b, q27);
18505
18506 ASSERT_EQUAL_128(0x0000000000000000, 0x80c4a2e691d5b3f7, q28);
18507 ASSERT_EQUAL_128(0x7f3b5d196e2a4c08, 0x80c4a2e691d5b3f7, q29);
18508
18509 TEARDOWN();
18510}
18511
18512
18513TEST(neon_sli) {
18514 SETUP();
18515
18516 START();
18517
18518 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18519 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18520
18521 __ Mov(v16.V2D(), v0.V2D());
18522 __ Mov(v17.V2D(), v0.V2D());
18523 __ Mov(v18.V2D(), v0.V2D());
18524 __ Mov(v19.V2D(), v0.V2D());
18525 __ Mov(v20.V2D(), v0.V2D());
18526 __ Mov(v21.V2D(), v0.V2D());
18527 __ Mov(v22.V2D(), v0.V2D());
18528 __ Mov(v23.V2D(), v0.V2D());
18529
18530 __ Sli(v16.V8B(), v1.V8B(), 4);
18531 __ Sli(v17.V16B(), v1.V16B(), 7);
18532 __ Sli(v18.V4H(), v1.V4H(), 8);
18533 __ Sli(v19.V8H(), v1.V8H(), 15);
18534 __ Sli(v20.V2S(), v1.V2S(), 0);
18535 __ Sli(v21.V4S(), v1.V4S(), 31);
18536 __ Sli(v22.V2D(), v1.V2D(), 48);
18537
18538 __ Sli(d23, d1, 48);
18539
18540 END();
18541
18542 RUN();
18543
18544 ASSERT_EQUAL_128(0x0000000000000000, 0x18395a7b9cbddeff, q16);
18545 ASSERT_EQUAL_128(0x0001020304050607, 0x88898a8b8c8d8e8f, q17);
18546 ASSERT_EQUAL_128(0x0000000000000000, 0x2309670bab0def0f, q18);
18547 ASSERT_EQUAL_128(0x0001020304050607, 0x88098a0b8c0d8e0f, q19);
18548 ASSERT_EQUAL_128(0x0000000000000000, 0x0123456789abcdef, q20);
18549 ASSERT_EQUAL_128(0x0001020304050607, 0x88090a0b8c0d0e0f, q21);
18550 ASSERT_EQUAL_128(0x3210020304050607, 0xcdef0a0b0c0d0e0f, q22);
18551
18552 ASSERT_EQUAL_128(0x0000000000000000, 0xcdef0a0b0c0d0e0f, q23);
18553
18554
18555 TEARDOWN();
18556}
18557
18558
18559TEST(neon_sri) {
18560 SETUP();
18561
18562 START();
18563
18564 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
18565 __ Movi(v1.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
18566
18567 __ Mov(v16.V2D(), v0.V2D());
18568 __ Mov(v17.V2D(), v0.V2D());
18569 __ Mov(v18.V2D(), v0.V2D());
18570 __ Mov(v19.V2D(), v0.V2D());
18571 __ Mov(v20.V2D(), v0.V2D());
18572 __ Mov(v21.V2D(), v0.V2D());
18573 __ Mov(v22.V2D(), v0.V2D());
18574 __ Mov(v23.V2D(), v0.V2D());
18575
18576 __ Sri(v16.V8B(), v1.V8B(), 4);
18577 __ Sri(v17.V16B(), v1.V16B(), 7);
18578 __ Sri(v18.V4H(), v1.V4H(), 8);
18579 __ Sri(v19.V8H(), v1.V8H(), 15);
18580 __ Sri(v20.V2S(), v1.V2S(), 1);
18581 __ Sri(v21.V4S(), v1.V4S(), 31);
18582 __ Sri(v22.V2D(), v1.V2D(), 48);
18583
18584 __ Sri(d23, d1, 48);
18585
18586 END();
18587
18588 RUN();
18589
18590 ASSERT_EQUAL_128(0x0000000000000000, 0x00020406080a0c0e, q16);
18591 ASSERT_EQUAL_128(0x0101030304040606, 0x08080a0a0d0d0f0f, q17);
18592 ASSERT_EQUAL_128(0x0000000000000000, 0x08010a450c890ecd, q18);
18593 ASSERT_EQUAL_128(0x0001020304040606, 0x08080a0a0c0d0e0f, q19);
18594 ASSERT_EQUAL_128(0x0000000000000000, 0x0091a2b344d5e6f7, q20);
18595 ASSERT_EQUAL_128(0x0001020304050606, 0x08090a0a0c0d0e0f, q21);
18596 ASSERT_EQUAL_128(0x000102030405fedc, 0x08090a0b0c0d0123, q22);
18597
18598 ASSERT_EQUAL_128(0x0000000000000000, 0x08090a0b0c0d0123, q23);
18599
18600
18601 TEARDOWN();
18602}
18603
18604
18605TEST(neon_shrn) {
18606 SETUP();
18607
18608 START();
18609
18610 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18611 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18612 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18613 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18614 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18615
18616 __ Shrn(v16.V8B(), v0.V8H(), 8);
18617 __ Shrn2(v16.V16B(), v1.V8H(), 1);
18618 __ Shrn(v17.V4H(), v1.V4S(), 16);
18619 __ Shrn2(v17.V8H(), v2.V4S(), 1);
18620 __ Shrn(v18.V2S(), v3.V2D(), 32);
18621 __ Shrn2(v18.V4S(), v3.V2D(), 1);
18622
18623 END();
18624
18625 RUN();
18626 ASSERT_EQUAL_128(0x0000ff00ff0000ff, 0x7f00817f80ff0180, q16);
18627 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x8000ffffffff0001, q17);
18628 ASSERT_EQUAL_128(0x00000000ffffffff, 0x800000007fffffff, q18);
18629 TEARDOWN();
18630}
18631
18632
18633TEST(neon_rshrn) {
18634 SETUP();
18635
18636 START();
18637
18638 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18639 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18640 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18641 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18642 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18643
18644 __ Rshrn(v16.V8B(), v0.V8H(), 8);
18645 __ Rshrn2(v16.V16B(), v1.V8H(), 1);
18646 __ Rshrn(v17.V4H(), v1.V4S(), 16);
18647 __ Rshrn2(v17.V8H(), v2.V4S(), 1);
18648 __ Rshrn(v18.V2S(), v3.V2D(), 32);
18649 __ Rshrn2(v18.V4S(), v3.V2D(), 1);
18650
18651 END();
18652
18653 RUN();
18654 ASSERT_EQUAL_128(0x0001000000000100, 0x7f01827f81ff0181, q16);
18655 ASSERT_EQUAL_128(0x0000000000000000, 0x8001ffffffff0001, q17);
18656 ASSERT_EQUAL_128(0x0000000100000000, 0x8000000080000000, q18);
18657 TEARDOWN();
18658}
18659
18660
18661TEST(neon_uqshrn) {
18662 SETUP();
18663
18664 START();
18665
18666 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18667 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18668 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18669 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18670 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18671
18672 __ Uqshrn(v16.V8B(), v0.V8H(), 8);
18673 __ Uqshrn2(v16.V16B(), v1.V8H(), 1);
18674 __ Uqshrn(v17.V4H(), v1.V4S(), 16);
18675 __ Uqshrn2(v17.V8H(), v2.V4S(), 1);
18676 __ Uqshrn(v18.V2S(), v3.V2D(), 32);
18677 __ Uqshrn2(v18.V4S(), v3.V2D(), 1);
18678
18679 __ Uqshrn(b19, h0, 8);
18680 __ Uqshrn(h20, s1, 16);
18681 __ Uqshrn(s21, d3, 32);
18682
18683 END();
18684
18685 RUN();
18686 ASSERT_EQUAL_128(0xffffff00ff0000ff, 0x7f00817f80ff0180, q16);
18687 ASSERT_EQUAL_128(0xffffffff0000ffff, 0x8000ffffffff0001, q17);
18688 ASSERT_EQUAL_128(0xffffffffffffffff, 0x800000007fffffff, q18);
18689 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000080, q19);
18690 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18691 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18692 TEARDOWN();
18693}
18694
18695
18696TEST(neon_uqrshrn) {
18697 SETUP();
18698
18699 START();
18700
18701 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18702 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18703 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18704 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18705 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18706
18707 __ Uqrshrn(v16.V8B(), v0.V8H(), 8);
18708 __ Uqrshrn2(v16.V16B(), v1.V8H(), 1);
18709 __ Uqrshrn(v17.V4H(), v1.V4S(), 16);
18710 __ Uqrshrn2(v17.V8H(), v2.V4S(), 1);
18711 __ Uqrshrn(v18.V2S(), v3.V2D(), 32);
18712 __ Uqrshrn2(v18.V4S(), v3.V2D(), 1);
18713
18714 __ Uqrshrn(b19, h0, 8);
18715 __ Uqrshrn(h20, s1, 16);
18716 __ Uqrshrn(s21, d3, 32);
18717
18718 END();
18719
18720 RUN();
18721 ASSERT_EQUAL_128(0xffffff00ff0001ff, 0x7f01827f81ff0181, q16);
18722 ASSERT_EQUAL_128(0xffffffff0000ffff, 0x8001ffffffff0001, q17);
18723 ASSERT_EQUAL_128(0xffffffffffffffff, 0x8000000080000000, q18);
18724 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000081, q19);
18725 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18726 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000000, q21);
18727 TEARDOWN();
18728}
18729
18730
18731TEST(neon_sqshrn) {
18732 SETUP();
18733
18734 START();
18735
18736 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18737 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18738 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18739 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18740 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18741
18742 __ Sqshrn(v16.V8B(), v0.V8H(), 8);
18743 __ Sqshrn2(v16.V16B(), v1.V8H(), 1);
18744 __ Sqshrn(v17.V4H(), v1.V4S(), 16);
18745 __ Sqshrn2(v17.V8H(), v2.V4S(), 1);
18746 __ Sqshrn(v18.V2S(), v3.V2D(), 32);
18747 __ Sqshrn2(v18.V4S(), v3.V2D(), 1);
18748
18749 __ Sqshrn(b19, h0, 8);
18750 __ Sqshrn(h20, s1, 16);
18751 __ Sqshrn(s21, d3, 32);
18752
18753 END();
18754
18755 RUN();
18756 ASSERT_EQUAL_128(0x8080ff00ff00007f, 0x7f00817f80ff0180, q16);
18757 ASSERT_EQUAL_128(0x8000ffff00007fff, 0x8000ffffffff0001, q17);
18758 ASSERT_EQUAL_128(0x800000007fffffff, 0x800000007fffffff, q18);
18759 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000080, q19);
18760 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18761 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18762 TEARDOWN();
18763}
18764
18765
18766TEST(neon_sqrshrn) {
18767 SETUP();
18768
18769 START();
18770
18771 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18772 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18773 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18774 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18775 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18776
18777 __ Sqrshrn(v16.V8B(), v0.V8H(), 8);
18778 __ Sqrshrn2(v16.V16B(), v1.V8H(), 1);
18779 __ Sqrshrn(v17.V4H(), v1.V4S(), 16);
18780 __ Sqrshrn2(v17.V8H(), v2.V4S(), 1);
18781 __ Sqrshrn(v18.V2S(), v3.V2D(), 32);
18782 __ Sqrshrn2(v18.V4S(), v3.V2D(), 1);
18783
18784 __ Sqrshrn(b19, h0, 8);
18785 __ Sqrshrn(h20, s1, 16);
18786 __ Sqrshrn(s21, d3, 32);
18787
18788 END();
18789
18790 RUN();
18791 ASSERT_EQUAL_128(0x808000000000017f, 0x7f01827f81ff0181, q16);
18792 ASSERT_EQUAL_128(0x8000000000007fff, 0x8001ffffffff0001, q17);
18793 ASSERT_EQUAL_128(0x800000007fffffff, 0x800000007fffffff, q18);
18794 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000081, q19);
18795 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18796 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18797 TEARDOWN();
18798}
18799
18800
18801TEST(neon_sqshrun) {
18802 SETUP();
18803
18804 START();
18805
18806 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18807 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18808 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18809 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18810 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18811
18812 __ Sqshrun(v16.V8B(), v0.V8H(), 8);
18813 __ Sqshrun2(v16.V16B(), v1.V8H(), 1);
18814 __ Sqshrun(v17.V4H(), v1.V4S(), 16);
18815 __ Sqshrun2(v17.V8H(), v2.V4S(), 1);
18816 __ Sqshrun(v18.V2S(), v3.V2D(), 32);
18817 __ Sqshrun2(v18.V4S(), v3.V2D(), 1);
18818
18819 __ Sqshrun(b19, h0, 8);
18820 __ Sqshrun(h20, s1, 16);
18821 __ Sqshrun(s21, d3, 32);
18822
18823 END();
18824
18825 RUN();
18826 ASSERT_EQUAL_128(0x00000000000000ff, 0x7f00007f00000100, q16);
18827 ASSERT_EQUAL_128(0x000000000000ffff, 0x0000000000000001, q17);
18828 ASSERT_EQUAL_128(0x00000000ffffffff, 0x000000007fffffff, q18);
18829 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q19);
18830 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18831 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q21);
18832 TEARDOWN();
18833}
18834
18835
18836TEST(neon_sqrshrun) {
18837 SETUP();
18838
18839 START();
18840
18841 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
18842 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
18843 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
18844 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
18845 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
18846
18847 __ Sqrshrun(v16.V8B(), v0.V8H(), 8);
18848 __ Sqrshrun2(v16.V16B(), v1.V8H(), 1);
18849 __ Sqrshrun(v17.V4H(), v1.V4S(), 16);
18850 __ Sqrshrun2(v17.V8H(), v2.V4S(), 1);
18851 __ Sqrshrun(v18.V2S(), v3.V2D(), 32);
18852 __ Sqrshrun2(v18.V4S(), v3.V2D(), 1);
18853
18854 __ Sqrshrun(b19, h0, 8);
18855 __ Sqrshrun(h20, s1, 16);
18856 __ Sqrshrun(s21, d3, 32);
18857
18858 END();
18859
18860 RUN();
18861 ASSERT_EQUAL_128(0x00000000000001ff, 0x7f01007f00000100, q16);
18862 ASSERT_EQUAL_128(0x000000000000ffff, 0x0000000000000001, q17);
18863 ASSERT_EQUAL_128(0x00000000ffffffff, 0x0000000080000000, q18);
18864 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q19);
18865 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000001, q20);
18866 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080000000, q21);
18867 TEARDOWN();
18868}
18869
18870TEST(neon_modimm_bic) {
18871 SETUP();
18872
18873 START();
18874
18875 __ Movi(v16.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18876 __ Movi(v17.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18877 __ Movi(v18.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18878 __ Movi(v19.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18879 __ Movi(v20.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18880 __ Movi(v21.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18881 __ Movi(v22.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18882 __ Movi(v23.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18883 __ Movi(v24.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18884 __ Movi(v25.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18885 __ Movi(v26.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18886 __ Movi(v27.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
18887
18888 __ Bic(v16.V4H(), 0x00, 0);
18889 __ Bic(v17.V4H(), 0xff, 8);
18890 __ Bic(v18.V8H(), 0x00, 0);
18891 __ Bic(v19.V8H(), 0xff, 8);
18892
18893 __ Bic(v20.V2S(), 0x00, 0);
18894 __ Bic(v21.V2S(), 0xff, 8);
18895 __ Bic(v22.V2S(), 0x00, 16);
18896 __ Bic(v23.V2S(), 0xff, 24);
18897
18898 __ Bic(v24.V4S(), 0xff, 0);
18899 __ Bic(v25.V4S(), 0x00, 8);
18900 __ Bic(v26.V4S(), 0xff, 16);
18901 __ Bic(v27.V4S(), 0x00, 24);
18902
18903 END();
18904
18905 RUN();
18906
18907 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q16);
18908 ASSERT_EQUAL_128(0x0, 0x005500ff000000aa, q17);
18909 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q18);
18910 ASSERT_EQUAL_128(0x00aa0055000000aa, 0x005500ff000000aa, q19);
18911
18912 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q20);
18913 ASSERT_EQUAL_128(0x0, 0x555500ff000000aa, q21);
18914 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q22);
18915 ASSERT_EQUAL_128(0x0, 0x0055ffff0000aaaa, q23);
18916
18917 ASSERT_EQUAL_128(0x00aaff00ff005500, 0x5555ff000000aa00, q24);
18918 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q25);
18919 ASSERT_EQUAL_128(0x0000ff55ff0055aa, 0x5500ffff0000aaaa, q26);
18920 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q27);
18921
18922 TEARDOWN();
18923}
18924
18925
18926TEST(neon_modimm_movi_16bit_any) {
18927 SETUP();
18928
18929 START();
18930
18931 __ Movi(v0.V4H(), 0xabab);
18932 __ Movi(v1.V4H(), 0xab00);
18933 __ Movi(v2.V4H(), 0xabff);
18934 __ Movi(v3.V8H(), 0x00ab);
18935 __ Movi(v4.V8H(), 0xffab);
18936 __ Movi(v5.V8H(), 0xabcd);
18937
18938 END();
18939
18940 RUN();
18941
18942 ASSERT_EQUAL_128(0x0, 0xabababababababab, q0);
18943 ASSERT_EQUAL_128(0x0, 0xab00ab00ab00ab00, q1);
18944 ASSERT_EQUAL_128(0x0, 0xabffabffabffabff, q2);
18945 ASSERT_EQUAL_128(0x00ab00ab00ab00ab, 0x00ab00ab00ab00ab, q3);
18946 ASSERT_EQUAL_128(0xffabffabffabffab, 0xffabffabffabffab, q4);
18947 ASSERT_EQUAL_128(0xabcdabcdabcdabcd, 0xabcdabcdabcdabcd, q5);
18948
18949 TEARDOWN();
18950}
18951
18952
18953TEST(neon_modimm_movi_32bit_any) {
18954 SETUP();
18955
18956 START();
18957
18958 __ Movi(v0.V2S(), 0x000000ab);
18959 __ Movi(v1.V2S(), 0x0000ab00);
18960 __ Movi(v2.V4S(), 0x00ab0000);
18961 __ Movi(v3.V4S(), 0xab000000);
18962
18963 __ Movi(v4.V2S(), 0xffffffab);
18964 __ Movi(v5.V2S(), 0xffffabff);
18965 __ Movi(v6.V4S(), 0xffabffff);
18966 __ Movi(v7.V4S(), 0xabffffff);
18967
18968 __ Movi(v16.V2S(), 0x0000abff);
18969 __ Movi(v17.V2S(), 0x00abffff);
18970 __ Movi(v18.V4S(), 0xffab0000);
18971 __ Movi(v19.V4S(), 0xffffab00);
18972
18973 __ Movi(v20.V4S(), 0xabababab);
18974 __ Movi(v21.V4S(), 0xabcdabcd);
18975 __ Movi(v22.V4S(), 0xabcdef01);
18976 __ Movi(v23.V4S(), 0x00ffff00);
18977
18978 END();
18979
18980 RUN();
18981
18982 ASSERT_EQUAL_128(0x0, 0x000000ab000000ab, q0);
18983 ASSERT_EQUAL_128(0x0, 0x0000ab000000ab00, q1);
18984 ASSERT_EQUAL_128(0x00ab000000ab0000, 0x00ab000000ab0000, q2);
18985 ASSERT_EQUAL_128(0xab000000ab000000, 0xab000000ab000000, q3);
18986
18987 ASSERT_EQUAL_128(0x0, 0xffffffabffffffab, q4);
18988 ASSERT_EQUAL_128(0x0, 0xffffabffffffabff, q5);
18989 ASSERT_EQUAL_128(0xffabffffffabffff, 0xffabffffffabffff, q6);
18990 ASSERT_EQUAL_128(0xabffffffabffffff, 0xabffffffabffffff, q7);
18991
18992 ASSERT_EQUAL_128(0x0, 0x0000abff0000abff, q16);
18993 ASSERT_EQUAL_128(0x0, 0x00abffff00abffff, q17);
18994 ASSERT_EQUAL_128(0xffab0000ffab0000, 0xffab0000ffab0000, q18);
18995 ASSERT_EQUAL_128(0xffffab00ffffab00, 0xffffab00ffffab00, q19);
18996
18997 ASSERT_EQUAL_128(0xabababababababab, 0xabababababababab, q20);
18998 ASSERT_EQUAL_128(0xabcdabcdabcdabcd, 0xabcdabcdabcdabcd, q21);
18999 ASSERT_EQUAL_128(0xabcdef01abcdef01, 0xabcdef01abcdef01, q22);
19000 ASSERT_EQUAL_128(0x00ffff0000ffff00, 0x00ffff0000ffff00, q23);
19001 TEARDOWN();
19002}
19003
19004
19005TEST(neon_modimm_movi_64bit_any) {
19006 SETUP();
19007
19008 START();
19009
19010 __ Movi(v0.V1D(), 0x00ffff0000ffffff);
19011 __ Movi(v1.V2D(), 0xabababababababab);
19012 __ Movi(v2.V2D(), 0xabcdabcdabcdabcd);
19013 __ Movi(v3.V2D(), 0xabcdef01abcdef01);
19014 __ Movi(v4.V1D(), 0xabcdef0123456789);
19015 __ Movi(v5.V2D(), 0xabcdef0123456789);
19016
19017 END();
19018
19019 RUN();
19020
19021 ASSERT_EQUAL_128(0x0, 0x00ffff0000ffffff, q0);
19022 ASSERT_EQUAL_128(0xabababababababab, 0xabababababababab, q1);
19023 ASSERT_EQUAL_128(0xabcdabcdabcdabcd, 0xabcdabcdabcdabcd, q2);
19024 ASSERT_EQUAL_128(0xabcdef01abcdef01, 0xabcdef01abcdef01, q3);
19025 ASSERT_EQUAL_128(0x0, 0xabcdef0123456789, q4);
19026 ASSERT_EQUAL_128(0xabcdef0123456789, 0xabcdef0123456789, q5);
19027
19028 TEARDOWN();
19029}
19030
19031
19032TEST(neon_modimm_movi) {
19033 SETUP();
19034
19035 START();
19036
19037 __ Movi(v0.V8B(), 0xaa);
19038 __ Movi(v1.V16B(), 0x55);
19039
19040 __ Movi(d2, 0x00ffff0000ffffff);
19041 __ Movi(v3.V2D(), 0x00ffff0000ffffff);
19042
19043 __ Movi(v16.V4H(), 0x00, LSL, 0);
19044 __ Movi(v17.V4H(), 0xff, LSL, 8);
19045 __ Movi(v18.V8H(), 0x00, LSL, 0);
19046 __ Movi(v19.V8H(), 0xff, LSL, 8);
19047
19048 __ Movi(v20.V2S(), 0x00, LSL, 0);
19049 __ Movi(v21.V2S(), 0xff, LSL, 8);
19050 __ Movi(v22.V2S(), 0x00, LSL, 16);
19051 __ Movi(v23.V2S(), 0xff, LSL, 24);
19052
19053 __ Movi(v24.V4S(), 0xff, LSL, 0);
19054 __ Movi(v25.V4S(), 0x00, LSL, 8);
19055 __ Movi(v26.V4S(), 0xff, LSL, 16);
19056 __ Movi(v27.V4S(), 0x00, LSL, 24);
19057
19058 __ Movi(v28.V2S(), 0xaa, MSL, 8);
19059 __ Movi(v29.V2S(), 0x55, MSL, 16);
19060 __ Movi(v30.V4S(), 0xff, MSL, 8);
19061 __ Movi(v31.V4S(), 0x00, MSL, 16);
19062
19063 END();
19064
19065 RUN();
19066
19067 ASSERT_EQUAL_128(0x0, 0xaaaaaaaaaaaaaaaa, q0);
19068 ASSERT_EQUAL_128(0x5555555555555555, 0x5555555555555555, q1);
19069
19070 ASSERT_EQUAL_128(0x0, 0x00ffff0000ffffff, q2);
19071 ASSERT_EQUAL_128(0x00ffff0000ffffff, 0x00ffff0000ffffff, q3);
19072
19073 ASSERT_EQUAL_128(0x0, 0x0000000000000000, q16);
19074 ASSERT_EQUAL_128(0x0, 0xff00ff00ff00ff00, q17);
19075 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q18);
19076 ASSERT_EQUAL_128(0xff00ff00ff00ff00, 0xff00ff00ff00ff00, q19);
19077
19078 ASSERT_EQUAL_128(0x0, 0x0000000000000000, q20);
19079 ASSERT_EQUAL_128(0x0, 0x0000ff000000ff00, q21);
19080 ASSERT_EQUAL_128(0x0, 0x0000000000000000, q22);
19081 ASSERT_EQUAL_128(0x0, 0xff000000ff000000, q23);
19082
19083 ASSERT_EQUAL_128(0x000000ff000000ff, 0x000000ff000000ff, q24);
19084 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q25);
19085 ASSERT_EQUAL_128(0x00ff000000ff0000, 0x00ff000000ff0000, q26);
19086 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000000000000, q27);
19087
19088 ASSERT_EQUAL_128(0x0, 0x0000aaff0000aaff, q28);
19089 ASSERT_EQUAL_128(0x0, 0x0055ffff0055ffff, q29);
19090 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x0000ffff0000ffff, q30);
19091 ASSERT_EQUAL_128(0x0000ffff0000ffff, 0x0000ffff0000ffff, q31);
19092
19093 TEARDOWN();
19094}
19095
19096
19097TEST(neon_modimm_mvni) {
19098 SETUP();
19099
19100 START();
19101
19102 __ Mvni(v16.V4H(), 0x00, LSL, 0);
19103 __ Mvni(v17.V4H(), 0xff, LSL, 8);
19104 __ Mvni(v18.V8H(), 0x00, LSL, 0);
19105 __ Mvni(v19.V8H(), 0xff, LSL, 8);
19106
19107 __ Mvni(v20.V2S(), 0x00, LSL, 0);
19108 __ Mvni(v21.V2S(), 0xff, LSL, 8);
19109 __ Mvni(v22.V2S(), 0x00, LSL, 16);
19110 __ Mvni(v23.V2S(), 0xff, LSL, 24);
19111
19112 __ Mvni(v24.V4S(), 0xff, LSL, 0);
19113 __ Mvni(v25.V4S(), 0x00, LSL, 8);
19114 __ Mvni(v26.V4S(), 0xff, LSL, 16);
19115 __ Mvni(v27.V4S(), 0x00, LSL, 24);
19116
19117 __ Mvni(v28.V2S(), 0xaa, MSL, 8);
19118 __ Mvni(v29.V2S(), 0x55, MSL, 16);
19119 __ Mvni(v30.V4S(), 0xff, MSL, 8);
19120 __ Mvni(v31.V4S(), 0x00, MSL, 16);
19121
19122 END();
19123
19124 RUN();
19125
19126 ASSERT_EQUAL_128(0x0, 0xffffffffffffffff, q16);
19127 ASSERT_EQUAL_128(0x0, 0x00ff00ff00ff00ff, q17);
19128 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q18);
19129 ASSERT_EQUAL_128(0x00ff00ff00ff00ff, 0x00ff00ff00ff00ff, q19);
19130
19131 ASSERT_EQUAL_128(0x0, 0xffffffffffffffff, q20);
19132 ASSERT_EQUAL_128(0x0, 0xffff00ffffff00ff, q21);
19133 ASSERT_EQUAL_128(0x0, 0xffffffffffffffff, q22);
19134 ASSERT_EQUAL_128(0x0, 0x00ffffff00ffffff, q23);
19135
19136 ASSERT_EQUAL_128(0xffffff00ffffff00, 0xffffff00ffffff00, q24);
19137 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q25);
19138 ASSERT_EQUAL_128(0xff00ffffff00ffff, 0xff00ffffff00ffff, q26);
19139 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q27);
19140
19141 ASSERT_EQUAL_128(0x0, 0xffff5500ffff5500, q28);
19142 ASSERT_EQUAL_128(0x0, 0xffaa0000ffaa0000, q29);
19143 ASSERT_EQUAL_128(0xffff0000ffff0000, 0xffff0000ffff0000, q30);
19144 ASSERT_EQUAL_128(0xffff0000ffff0000, 0xffff0000ffff0000, q31);
19145
19146 TEARDOWN();
19147}
19148
19149
19150TEST(neon_modimm_orr) {
19151 SETUP();
19152
19153 START();
19154
19155 __ Movi(v16.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19156 __ Movi(v17.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19157 __ Movi(v18.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19158 __ Movi(v19.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19159 __ Movi(v20.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19160 __ Movi(v21.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19161 __ Movi(v22.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19162 __ Movi(v23.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19163 __ Movi(v24.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19164 __ Movi(v25.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19165 __ Movi(v26.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19166 __ Movi(v27.V2D(), 0x00aaff55ff0055aa, 0x5555ffff0000aaaa);
19167
19168 __ Orr(v16.V4H(), 0x00, 0);
19169 __ Orr(v17.V4H(), 0xff, 8);
19170 __ Orr(v18.V8H(), 0x00, 0);
19171 __ Orr(v19.V8H(), 0xff, 8);
19172
19173 __ Orr(v20.V2S(), 0x00, 0);
19174 __ Orr(v21.V2S(), 0xff, 8);
19175 __ Orr(v22.V2S(), 0x00, 16);
19176 __ Orr(v23.V2S(), 0xff, 24);
19177
19178 __ Orr(v24.V4S(), 0xff, 0);
19179 __ Orr(v25.V4S(), 0x00, 8);
19180 __ Orr(v26.V4S(), 0xff, 16);
19181 __ Orr(v27.V4S(), 0x00, 24);
19182
19183 END();
19184
19185 RUN();
19186
19187 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q16);
19188 ASSERT_EQUAL_128(0x0, 0xff55ffffff00ffaa, q17);
19189 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q18);
19190 ASSERT_EQUAL_128(0xffaaff55ff00ffaa, 0xff55ffffff00ffaa, q19);
19191
19192 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q20);
19193 ASSERT_EQUAL_128(0x0, 0x5555ffff0000ffaa, q21);
19194 ASSERT_EQUAL_128(0x0, 0x5555ffff0000aaaa, q22);
19195 ASSERT_EQUAL_128(0x0, 0xff55ffffff00aaaa, q23);
19196
19197 ASSERT_EQUAL_128(0x00aaffffff0055ff, 0x5555ffff0000aaff, q24);
19198 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q25);
19199 ASSERT_EQUAL_128(0x00ffff55ffff55aa, 0x55ffffff00ffaaaa, q26);
19200 ASSERT_EQUAL_128(0x00aaff55ff0055aa, 0x5555ffff0000aaaa, q27);
19201
19202 TEARDOWN();
19203}
19204
19205
19206// TODO: add arbitrary values once load literal to Q registers is supported.
19207TEST(neon_modimm_fmov) {
19208 SETUP();
19209
19210 // Immediates which can be encoded in the instructions.
19211 const float kOne = 1.0f;
19212 const float kPointFive = 0.5f;
19213 const double kMinusThirteen = -13.0;
19214 // Immediates which cannot be encoded in the instructions.
19215 const float kNonImmFP32 = 255.0f;
19216 const double kNonImmFP64 = 12.3456;
19217
19218 START();
19219 __ Fmov(v11.V2S(), kOne);
19220 __ Fmov(v12.V4S(), kPointFive);
19221 __ Fmov(v22.V2D(), kMinusThirteen);
19222 __ Fmov(v13.V2S(), kNonImmFP32);
19223 __ Fmov(v14.V4S(), kNonImmFP32);
19224 __ Fmov(v23.V2D(), kNonImmFP64);
19225 __ Fmov(v1.V2S(), 0.0);
19226 __ Fmov(v2.V4S(), 0.0);
19227 __ Fmov(v3.V2D(), 0.0);
19228 __ Fmov(v4.V2S(), kFP32PositiveInfinity);
19229 __ Fmov(v5.V4S(), kFP32PositiveInfinity);
19230 __ Fmov(v6.V2D(), kFP64PositiveInfinity);
19231 END();
19232
19233 RUN();
19234
19235 const uint64_t kOne1S = float_to_rawbits(1.0);
19236 const uint64_t kOne2S = (kOne1S << 32) | kOne1S;
19237 const uint64_t kPointFive1S = float_to_rawbits(0.5);
19238 const uint64_t kPointFive2S = (kPointFive1S << 32) | kPointFive1S;
19239 const uint64_t kMinusThirteen1D = double_to_rawbits(-13.0);
19240 const uint64_t kNonImmFP321S = float_to_rawbits(kNonImmFP32);
19241 const uint64_t kNonImmFP322S = (kNonImmFP321S << 32) | kNonImmFP321S;
19242 const uint64_t kNonImmFP641D = double_to_rawbits(kNonImmFP64);
19243 const uint64_t kFP32Inf1S = float_to_rawbits(kFP32PositiveInfinity);
19244 const uint64_t kFP32Inf2S = (kFP32Inf1S << 32) | kFP32Inf1S;
19245 const uint64_t kFP64Inf1D = double_to_rawbits(kFP64PositiveInfinity);
19246
19247 ASSERT_EQUAL_128(0x0, kOne2S, q11);
19248 ASSERT_EQUAL_128(kPointFive2S, kPointFive2S, q12);
19249 ASSERT_EQUAL_128(kMinusThirteen1D, kMinusThirteen1D, q22);
19250 ASSERT_EQUAL_128(0x0, kNonImmFP322S, q13);
19251 ASSERT_EQUAL_128(kNonImmFP322S, kNonImmFP322S, q14);
19252 ASSERT_EQUAL_128(kNonImmFP641D, kNonImmFP641D, q23);
19253 ASSERT_EQUAL_128(0x0, 0x0, q1);
19254 ASSERT_EQUAL_128(0x0, 0x0, q2);
19255 ASSERT_EQUAL_128(0x0, 0x0, q3);
19256 ASSERT_EQUAL_128(0x0, kFP32Inf2S, q4);
19257 ASSERT_EQUAL_128(kFP32Inf2S, kFP32Inf2S, q5);
19258 ASSERT_EQUAL_128(kFP64Inf1D, kFP64Inf1D, q6);
19259
19260 TEARDOWN();
19261}
19262
19263
19264TEST(neon_perm) {
19265 SETUP();
19266
19267 START();
19268
19269 __ Movi(v0.V2D(), 0x0001020304050607, 0x08090a0b0c0d0e0f);
19270 __ Movi(v1.V2D(), 0x1011121314151617, 0x18191a1b1c1d1e1f);
19271
19272 __ Trn1(v16.V16B(), v0.V16B(), v1.V16B());
19273 __ Trn2(v17.V16B(), v0.V16B(), v1.V16B());
19274 __ Zip1(v18.V16B(), v0.V16B(), v1.V16B());
19275 __ Zip2(v19.V16B(), v0.V16B(), v1.V16B());
19276 __ Uzp1(v20.V16B(), v0.V16B(), v1.V16B());
19277 __ Uzp2(v21.V16B(), v0.V16B(), v1.V16B());
19278
19279 END();
19280
19281 RUN();
19282
19283 ASSERT_EQUAL_128(0x1101130315051707, 0x19091b0b1d0d1f0f, q16);
19284 ASSERT_EQUAL_128(0x1000120214041606, 0x18081a0a1c0c1e0e, q17);
19285 ASSERT_EQUAL_128(0x180819091a0a1b0b, 0x1c0c1d0d1e0e1f0f, q18);
19286 ASSERT_EQUAL_128(0x1000110112021303, 0x1404150516061707, q19);
19287 ASSERT_EQUAL_128(0x11131517191b1d1f, 0x01030507090b0d0f, q20);
19288 ASSERT_EQUAL_128(0x10121416181a1c1e, 0x00020406080a0c0e, q21);
19289
19290 TEARDOWN();
19291}
19292
19293
19294TEST(neon_copy_dup_element) {
19295 SETUP();
19296
19297 START();
19298
19299 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19300 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19301 __ Movi(v2.V2D(), 0xffeddccbbaae9988, 0x0011223344556677);
19302 __ Movi(v3.V2D(), 0x7766554433221100, 0x8899aabbccddeeff);
19303 __ Movi(v4.V2D(), 0x7766554433221100, 0x0123456789abcdef);
19304 __ Movi(v5.V2D(), 0x0011223344556677, 0x0123456789abcdef);
19305
19306 __ Dup(v16.V16B(), v0.B(), 0);
19307 __ Dup(v17.V8H(), v1.H(), 7);
19308 __ Dup(v18.V4S(), v1.S(), 3);
19309 __ Dup(v19.V2D(), v0.D(), 0);
19310
19311 __ Dup(v20.V8B(), v0.B(), 0);
19312 __ Dup(v21.V4H(), v1.H(), 7);
19313 __ Dup(v22.V2S(), v1.S(), 3);
19314
19315 __ Dup(v23.B(), v0.B(), 0);
19316 __ Dup(v24.H(), v1.H(), 7);
19317 __ Dup(v25.S(), v1.S(), 3);
19318 __ Dup(v26.D(), v0.D(), 0);
19319
19320 __ Dup(v2.V16B(), v2.B(), 0);
19321 __ Dup(v3.V8H(), v3.H(), 7);
19322 __ Dup(v4.V4S(), v4.S(), 0);
19323 __ Dup(v5.V2D(), v5.D(), 1);
19324
19325 END();
19326
19327 RUN();
19328
19329 ASSERT_EQUAL_128(0xffffffffffffffff, 0xffffffffffffffff, q16);
19330 ASSERT_EQUAL_128(0xffedffedffedffed, 0xffedffedffedffed, q17);
19331 ASSERT_EQUAL_128(0xffeddccbffeddccb, 0xffeddccbffeddccb, q18);
19332 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x8899aabbccddeeff, q19);
19333
19334 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q20);
19335 ASSERT_EQUAL_128(0, 0xffedffedffedffed, q21);
19336 ASSERT_EQUAL_128(0, 0xffeddccbffeddccb, q22);
19337
19338 ASSERT_EQUAL_128(0, 0x00000000000000ff, q23);
19339 ASSERT_EQUAL_128(0, 0x000000000000ffed, q24);
19340 ASSERT_EQUAL_128(0, 0x00000000ffeddccb, q25);
19341 ASSERT_EQUAL_128(0, 0x8899aabbccddeeff, q26);
19342
19343 ASSERT_EQUAL_128(0x7777777777777777, 0x7777777777777777, q2);
19344 ASSERT_EQUAL_128(0x7766776677667766, 0x7766776677667766, q3);
19345 ASSERT_EQUAL_128(0x89abcdef89abcdef, 0x89abcdef89abcdef, q4);
19346 ASSERT_EQUAL_128(0x0011223344556677, 0x0011223344556677, q5);
19347 TEARDOWN();
19348}
19349
19350
19351TEST(neon_copy_dup_general) {
19352 SETUP();
19353
19354 START();
19355
19356 __ Mov(x0, 0x0011223344556677);
19357
19358 __ Dup(v16.V16B(), w0);
19359 __ Dup(v17.V8H(), w0);
19360 __ Dup(v18.V4S(), w0);
19361 __ Dup(v19.V2D(), x0);
19362
19363 __ Dup(v20.V8B(), w0);
19364 __ Dup(v21.V4H(), w0);
19365 __ Dup(v22.V2S(), w0);
19366
19367 __ Dup(v2.V16B(), wzr);
19368 __ Dup(v3.V8H(), wzr);
19369 __ Dup(v4.V4S(), wzr);
19370 __ Dup(v5.V2D(), xzr);
19371
19372 END();
19373
19374 RUN();
19375
19376 ASSERT_EQUAL_128(0x7777777777777777, 0x7777777777777777, q16);
19377 ASSERT_EQUAL_128(0x6677667766776677, 0x6677667766776677, q17);
19378 ASSERT_EQUAL_128(0x4455667744556677, 0x4455667744556677, q18);
19379 ASSERT_EQUAL_128(0x0011223344556677, 0x0011223344556677, q19);
19380
19381 ASSERT_EQUAL_128(0, 0x7777777777777777, q20);
19382 ASSERT_EQUAL_128(0, 0x6677667766776677, q21);
19383 ASSERT_EQUAL_128(0, 0x4455667744556677, q22);
19384
19385 ASSERT_EQUAL_128(0, 0, q2);
19386 ASSERT_EQUAL_128(0, 0, q3);
19387 ASSERT_EQUAL_128(0, 0, q4);
19388 ASSERT_EQUAL_128(0, 0, q5);
19389 TEARDOWN();
19390}
19391
19392
19393TEST(neon_copy_ins_element) {
19394 SETUP();
19395
19396 START();
19397
19398 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19399 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19400 __ Movi(v16.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19401 __ Movi(v17.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
19402 __ Movi(v18.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19403 __ Movi(v19.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19404
19405 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19406 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19407 __ Movi(v4.V2D(), 0, 0x0123456789abcdef);
19408 __ Movi(v5.V2D(), 0, 0x0123456789abcdef);
19409
19410 __ Ins(v16.V16B(), 15, v0.V16B(), 0);
19411 __ Ins(v17.V8H(), 0, v1.V8H(), 7);
19412 __ Ins(v18.V4S(), 3, v1.V4S(), 0);
19413 __ Ins(v19.V2D(), 1, v0.V2D(), 0);
19414
19415 __ Ins(v2.V16B(), 2, v2.V16B(), 0);
19416 __ Ins(v3.V8H(), 0, v3.V8H(), 7);
19417 __ Ins(v4.V4S(), 3, v4.V4S(), 0);
19418 __ Ins(v5.V2D(), 0, v5.V2D(), 1);
19419
19420 END();
19421
19422 RUN();
19423
19424 ASSERT_EQUAL_128(0xff23456789abcdef, 0xfedcba9876543210, q16);
19425 ASSERT_EQUAL_128(0xfedcba9876543210, 0x0123456789abffed, q17);
19426 ASSERT_EQUAL_128(0x3322110044556677, 0x8899aabbccddeeff, q18);
19427 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x8899aabbccddeeff, q19);
19428
19429 ASSERT_EQUAL_128(0, 0x0011223344776677, q2);
19430 ASSERT_EQUAL_128(0, 0x8899aabbccdd0000, q3);
19431 ASSERT_EQUAL_128(0x89abcdef00000000, 0x0123456789abcdef, q4);
19432 ASSERT_EQUAL_128(0, 0, q5);
19433 TEARDOWN();
19434}
19435
19436
19437TEST(neon_copy_mov_element) {
19438 SETUP();
19439
19440 START();
19441
19442 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19443 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19444 __ Movi(v16.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19445 __ Movi(v17.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
19446 __ Movi(v18.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19447 __ Movi(v19.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19448
19449 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19450 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19451 __ Movi(v4.V2D(), 0, 0x0123456789abcdef);
19452 __ Movi(v5.V2D(), 0, 0x0123456789abcdef);
19453
19454 __ Mov(v16.V16B(), 15, v0.V16B(), 0);
19455 __ Mov(v17.V8H(), 0, v1.V8H(), 7);
19456 __ Mov(v18.V4S(), 3, v1.V4S(), 0);
19457 __ Mov(v19.V2D(), 1, v0.V2D(), 0);
19458
19459 __ Mov(v2.V16B(), 2, v2.V16B(), 0);
19460 __ Mov(v3.V8H(), 0, v3.V8H(), 7);
19461 __ Mov(v4.V4S(), 3, v4.V4S(), 0);
19462 __ Mov(v5.V2D(), 0, v5.V2D(), 1);
19463
19464 END();
19465
19466 RUN();
19467
19468 ASSERT_EQUAL_128(0xff23456789abcdef, 0xfedcba9876543210, q16);
19469 ASSERT_EQUAL_128(0xfedcba9876543210, 0x0123456789abffed, q17);
19470 ASSERT_EQUAL_128(0x3322110044556677, 0x8899aabbccddeeff, q18);
19471 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x8899aabbccddeeff, q19);
19472
19473 ASSERT_EQUAL_128(0, 0x0011223344776677, q2);
19474 ASSERT_EQUAL_128(0, 0x8899aabbccdd0000, q3);
19475 ASSERT_EQUAL_128(0x89abcdef00000000, 0x0123456789abcdef, q4);
19476 ASSERT_EQUAL_128(0, 0, q5);
19477 TEARDOWN();
19478}
19479
19480
19481TEST(neon_copy_smov) {
19482 SETUP();
19483
19484 START();
19485
19486 __ Movi(v0.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19487
19488 __ Smov(w0, v0.B(), 7);
19489 __ Smov(w1, v0.B(), 15);
19490
19491 __ Smov(w2, v0.H(), 0);
19492 __ Smov(w3, v0.H(), 3);
19493
19494 __ Smov(x4, v0.B(), 7);
19495 __ Smov(x5, v0.B(), 15);
19496
19497 __ Smov(x6, v0.H(), 0);
19498 __ Smov(x7, v0.H(), 3);
19499
19500 __ Smov(x16, v0.S(), 0);
19501 __ Smov(x17, v0.S(), 1);
19502
19503 END();
19504
19505 RUN();
19506
19507 ASSERT_EQUAL_32(0xfffffffe, w0);
19508 ASSERT_EQUAL_32(0x00000001, w1);
19509 ASSERT_EQUAL_32(0x00003210, w2);
19510 ASSERT_EQUAL_32(0xfffffedc, w3);
19511 ASSERT_EQUAL_64(0xfffffffffffffffe, x4);
19512 ASSERT_EQUAL_64(0x0000000000000001, x5);
19513 ASSERT_EQUAL_64(0x0000000000003210, x6);
19514 ASSERT_EQUAL_64(0xfffffffffffffedc, x7);
19515 ASSERT_EQUAL_64(0x0000000076543210, x16);
19516 ASSERT_EQUAL_64(0xfffffffffedcba98, x17);
19517
19518 TEARDOWN();
19519}
19520
19521
19522TEST(neon_copy_umov_mov) {
19523 SETUP();
19524
19525 START();
19526
19527 __ Movi(v0.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19528
19529 __ Umov(w0, v0.B(), 15);
19530 __ Umov(w1, v0.H(), 0);
19531 __ Umov(w2, v0.S(), 3);
19532 __ Umov(x3, v0.D(), 1);
19533
19534 __ Mov(w4, v0.S(), 3);
19535 __ Mov(x5, v0.D(), 1);
19536
19537 END();
19538
19539 RUN();
19540
19541 ASSERT_EQUAL_32(0x00000001, w0);
19542 ASSERT_EQUAL_32(0x00003210, w1);
19543 ASSERT_EQUAL_32(0x01234567, w2);
19544 ASSERT_EQUAL_64(0x0123456789abcdef, x3);
19545 ASSERT_EQUAL_32(0x01234567, w4);
19546 ASSERT_EQUAL_64(0x0123456789abcdef, x5);
19547
19548 TEARDOWN();
19549}
19550
19551
19552TEST(neon_copy_ins_general) {
19553 SETUP();
19554
19555 START();
19556
19557 __ Mov(x0, 0x0011223344556677);
19558 __ Movi(v16.V2D(), 0x0123456789abcdef, 0xfedcba9876543210);
19559 __ Movi(v17.V2D(), 0xfedcba9876543210, 0x0123456789abcdef);
19560 __ Movi(v18.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19561 __ Movi(v19.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19562
19563 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19564 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19565 __ Movi(v4.V2D(), 0, 0x0123456789abcdef);
19566 __ Movi(v5.V2D(), 0, 0x0123456789abcdef);
19567
19568 __ Ins(v16.V16B(), 15, w0);
19569 __ Ins(v17.V8H(), 0, w0);
19570 __ Ins(v18.V4S(), 3, w0);
19571 __ Ins(v19.V2D(), 0, x0);
19572
19573 __ Ins(v2.V16B(), 2, w0);
19574 __ Ins(v3.V8H(), 0, w0);
19575 __ Ins(v4.V4S(), 3, w0);
19576 __ Ins(v5.V2D(), 1, x0);
19577
19578 END();
19579
19580 RUN();
19581
19582 ASSERT_EQUAL_128(0x7723456789abcdef, 0xfedcba9876543210, q16);
19583 ASSERT_EQUAL_128(0xfedcba9876543210, 0x0123456789ab6677, q17);
19584 ASSERT_EQUAL_128(0x4455667744556677, 0x8899aabbccddeeff, q18);
19585 ASSERT_EQUAL_128(0x0011223344556677, 0x0011223344556677, q19);
19586
19587 ASSERT_EQUAL_128(0, 0x0011223344776677, q2);
19588 ASSERT_EQUAL_128(0, 0x8899aabbccdd6677, q3);
19589 ASSERT_EQUAL_128(0x4455667700000000, 0x0123456789abcdef, q4);
19590 ASSERT_EQUAL_128(0x0011223344556677, 0x0123456789abcdef, q5);
19591 TEARDOWN();
19592}
19593
19594
19595TEST(neon_extract_ext) {
19596 SETUP();
19597
19598 START();
19599
19600 __ Movi(v0.V2D(), 0x0011223344556677, 0x8899aabbccddeeff);
19601 __ Movi(v1.V2D(), 0xffeddccbbaae9988, 0x7766554433221100);
19602
19603 __ Movi(v2.V2D(), 0, 0x0011223344556677);
19604 __ Movi(v3.V2D(), 0, 0x8899aabbccddeeff);
19605
19606 __ Ext(v16.V16B(), v0.V16B(), v1.V16B(), 0);
19607 __ Ext(v17.V16B(), v0.V16B(), v1.V16B(), 15);
19608 __ Ext(v1.V16B(), v0.V16B(), v1.V16B(), 8); // Dest is same as one Src
19609 __ Ext(v0.V16B(), v0.V16B(), v0.V16B(), 8); // All reg are the same
19610
19611 __ Ext(v18.V8B(), v2.V8B(), v3.V8B(), 0);
19612 __ Ext(v19.V8B(), v2.V8B(), v3.V8B(), 7);
19613 __ Ext(v2.V8B(), v2.V8B(), v3.V8B(), 4); // Dest is same as one Src
19614 __ Ext(v3.V8B(), v3.V8B(), v3.V8B(), 4); // All reg are the same
19615
19616 END();
19617
19618 RUN();
19619
19620 ASSERT_EQUAL_128(0x0011223344556677, 0x8899aabbccddeeff, q16);
19621 ASSERT_EQUAL_128(0xeddccbbaae998877, 0x6655443322110000, q17);
19622 ASSERT_EQUAL_128(0x7766554433221100, 0x0011223344556677, q1);
19623 ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x0011223344556677, q0);
19624
19625 ASSERT_EQUAL_128(0, 0x0011223344556677, q18);
19626 ASSERT_EQUAL_128(0, 0x99aabbccddeeff00, q19);
19627 ASSERT_EQUAL_128(0, 0xccddeeff00112233, q2);
19628 ASSERT_EQUAL_128(0, 0xccddeeff8899aabb, q3);
19629 TEARDOWN();
19630}
19631
19632
19633TEST(neon_3different_uaddl) {
19634 SETUP();
19635
19636 START();
19637
19638 __ Movi(v0.V2D(), 0x0000000000000000, 0x0000000000000000);
19639 __ Movi(v1.V2D(), 0, 0x00010280810e0fff);
19640 __ Movi(v2.V2D(), 0, 0x0101010101010101);
19641
19642 __ Movi(v3.V2D(), 0x0000000000000000, 0x0000000000000000);
19643 __ Movi(v4.V2D(), 0x0000000000000000, 0x0000000000000000);
19644 __ Movi(v5.V2D(), 0, 0x0000000180008001);
19645 __ Movi(v6.V2D(), 0, 0x000e000ff000ffff);
19646 __ Movi(v7.V2D(), 0, 0x0001000100010001);
19647
19648 __ Movi(v16.V2D(), 0x0000000000000000, 0x0000000000000000);
19649 __ Movi(v17.V2D(), 0x0000000000000000, 0x0000000000000000);
19650 __ Movi(v18.V2D(), 0, 0x0000000000000001);
19651 __ Movi(v19.V2D(), 0, 0x80000001ffffffff);
19652 __ Movi(v20.V2D(), 0, 0x0000000100000001);
19653
19654 __ Uaddl(v0.V8H(), v1.V8B(), v2.V8B());
19655
19656 __ Uaddl(v3.V4S(), v5.V4H(), v7.V4H());
19657 __ Uaddl(v4.V4S(), v6.V4H(), v7.V4H());
19658
19659 __ Uaddl(v16.V2D(), v18.V2S(), v20.V2S());
19660 __ Uaddl(v17.V2D(), v19.V2S(), v20.V2S());
19661
19662
19663 END();
19664
19665 RUN();
19666
19667 ASSERT_EQUAL_128(0x0001000200030081, 0x0082000f00100100, q0);
19668 ASSERT_EQUAL_128(0x0000000100000002, 0x0000800100008002, q3);
19669 ASSERT_EQUAL_128(0x0000000f00000010, 0x0000f00100010000, q4);
19670 ASSERT_EQUAL_128(0x0000000000000001, 0x0000000000000002, q16);
19671 ASSERT_EQUAL_128(0x0000000080000002, 0x0000000100000000, q17);
19672 TEARDOWN();
19673}
19674
19675
19676TEST(neon_3different_addhn_subhn) {
19677 SETUP();
19678
19679 START();
19680
19681 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19682 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19683 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19684 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
19685 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
19686
19687 __ Addhn(v16.V8B(), v0.V8H(), v1.V8H());
19688 __ Addhn2(v16.V16B(), v2.V8H(), v3.V8H());
19689 __ Raddhn(v17.V8B(), v0.V8H(), v1.V8H());
19690 __ Raddhn2(v17.V16B(), v2.V8H(), v3.V8H());
19691 __ Subhn(v18.V8B(), v0.V8H(), v1.V8H());
19692 __ Subhn2(v18.V16B(), v2.V8H(), v3.V8H());
19693 __ Rsubhn(v19.V8B(), v0.V8H(), v1.V8H());
19694 __ Rsubhn2(v19.V16B(), v2.V8H(), v3.V8H());
19695
19696 END();
19697
19698 RUN();
19699
19700 ASSERT_EQUAL_128(0x0000ff007fff7fff, 0xff81817f80ff0100, q16);
19701 ASSERT_EQUAL_128(0x0000000080008000, 0xff81817f81ff0201, q17);
19702 ASSERT_EQUAL_128(0x0000ffff80008000, 0xff80817f80ff0100, q18);
19703 ASSERT_EQUAL_128(0x0000000080008000, 0xff81827f81ff0101, q19);
19704 TEARDOWN();
19705}
19706
19707TEST(neon_d_only_scalar) {
19708 SETUP();
19709
19710 START();
19711
19712 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
19713 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
19714 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x1000000010001010);
19715 __ Movi(v3.V2D(), 0xffffffffffffffff, 2);
19716 __ Movi(v4.V2D(), 0xffffffffffffffff, -2);
19717
19718 __ Add(d16, d0, d0);
19719 __ Add(d17, d1, d1);
19720 __ Add(d18, d2, d2);
19721 __ Sub(d19, d0, d0);
19722 __ Sub(d20, d0, d1);
19723 __ Sub(d21, d1, d0);
19724 __ Ushl(d22, d0, d3);
19725 __ Ushl(d23, d0, d4);
19726 __ Sshl(d24, d0, d3);
19727 __ Sshl(d25, d0, d4);
19728 __ Ushr(d26, d0, 1);
19729 __ Sshr(d27, d0, 3);
19730 __ Shl(d28, d0, 0);
19731 __ Shl(d29, d0, 16);
19732
19733 END();
19734
19735 RUN();
19736
19737 ASSERT_EQUAL_128(0, 0xe0000001e001e1e0, q16);
19738 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q17);
19739 ASSERT_EQUAL_128(0, 0x2000000020002020, q18);
19740 ASSERT_EQUAL_128(0, 0, q19);
19741 ASSERT_EQUAL_128(0, 0x7000000170017171, q20);
19742 ASSERT_EQUAL_128(0, 0x8ffffffe8ffe8e8f, q21);
19743 ASSERT_EQUAL_128(0, 0xc0000003c003c3c0, q22);
19744 ASSERT_EQUAL_128(0, 0x3c0000003c003c3c, q23);
19745 ASSERT_EQUAL_128(0, 0xc0000003c003c3c0, q24);
19746 ASSERT_EQUAL_128(0, 0xfc0000003c003c3c, q25);
19747 ASSERT_EQUAL_128(0, 0x7800000078007878, q26);
19748 ASSERT_EQUAL_128(0, 0xfe0000001e001e1e, q27);
19749 ASSERT_EQUAL_128(0, 0xf0000000f000f0f0, q28);
19750 ASSERT_EQUAL_128(0, 0x0000f000f0f00000, q29);
19751
19752 TEARDOWN();
19753}
19754
19755
19756TEST(neon_sqshl_imm_scalar) {
19757 SETUP();
19758
19759 START();
19760
19761 __ Movi(v0.V2D(), 0x0, 0x7f);
19762 __ Movi(v1.V2D(), 0x0, 0x80);
19763 __ Movi(v2.V2D(), 0x0, 0x01);
19764 __ Sqshl(b16, b0, 1);
19765 __ Sqshl(b17, b1, 1);
19766 __ Sqshl(b18, b2, 1);
19767
19768 __ Movi(v0.V2D(), 0x0, 0x7fff);
19769 __ Movi(v1.V2D(), 0x0, 0x8000);
19770 __ Movi(v2.V2D(), 0x0, 0x0001);
19771 __ Sqshl(h19, h0, 1);
19772 __ Sqshl(h20, h1, 1);
19773 __ Sqshl(h21, h2, 1);
19774
19775 __ Movi(v0.V2D(), 0x0, 0x7fffffff);
19776 __ Movi(v1.V2D(), 0x0, 0x80000000);
19777 __ Movi(v2.V2D(), 0x0, 0x00000001);
19778 __ Sqshl(s22, s0, 1);
19779 __ Sqshl(s23, s1, 1);
19780 __ Sqshl(s24, s2, 1);
19781
19782 __ Movi(v0.V2D(), 0x0, 0x7fffffffffffffff);
19783 __ Movi(v1.V2D(), 0x0, 0x8000000000000000);
19784 __ Movi(v2.V2D(), 0x0, 0x0000000000000001);
19785 __ Sqshl(d25, d0, 1);
19786 __ Sqshl(d26, d1, 1);
19787 __ Sqshl(d27, d2, 1);
19788
19789 END();
19790
19791 RUN();
19792
19793 ASSERT_EQUAL_128(0, 0x7f, q16);
19794 ASSERT_EQUAL_128(0, 0x80, q17);
19795 ASSERT_EQUAL_128(0, 0x02, q18);
19796
19797 ASSERT_EQUAL_128(0, 0x7fff, q19);
19798 ASSERT_EQUAL_128(0, 0x8000, q20);
19799 ASSERT_EQUAL_128(0, 0x0002, q21);
19800
19801 ASSERT_EQUAL_128(0, 0x7fffffff, q22);
19802 ASSERT_EQUAL_128(0, 0x80000000, q23);
19803 ASSERT_EQUAL_128(0, 0x00000002, q24);
19804
19805 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q25);
19806 ASSERT_EQUAL_128(0, 0x8000000000000000, q26);
19807 ASSERT_EQUAL_128(0, 0x0000000000000002, q27);
19808
19809 TEARDOWN();
19810}
19811
19812
19813TEST(neon_uqshl_imm_scalar) {
19814 SETUP();
19815
19816 START();
19817
19818 __ Movi(v0.V2D(), 0x0, 0x7f);
19819 __ Movi(v1.V2D(), 0x0, 0x80);
19820 __ Movi(v2.V2D(), 0x0, 0x01);
19821 __ Uqshl(b16, b0, 1);
19822 __ Uqshl(b17, b1, 1);
19823 __ Uqshl(b18, b2, 1);
19824
19825 __ Movi(v0.V2D(), 0x0, 0x7fff);
19826 __ Movi(v1.V2D(), 0x0, 0x8000);
19827 __ Movi(v2.V2D(), 0x0, 0x0001);
19828 __ Uqshl(h19, h0, 1);
19829 __ Uqshl(h20, h1, 1);
19830 __ Uqshl(h21, h2, 1);
19831
19832 __ Movi(v0.V2D(), 0x0, 0x7fffffff);
19833 __ Movi(v1.V2D(), 0x0, 0x80000000);
19834 __ Movi(v2.V2D(), 0x0, 0x00000001);
19835 __ Uqshl(s22, s0, 1);
19836 __ Uqshl(s23, s1, 1);
19837 __ Uqshl(s24, s2, 1);
19838
19839 __ Movi(v0.V2D(), 0x0, 0x7fffffffffffffff);
19840 __ Movi(v1.V2D(), 0x0, 0x8000000000000000);
19841 __ Movi(v2.V2D(), 0x0, 0x0000000000000001);
19842 __ Uqshl(d25, d0, 1);
19843 __ Uqshl(d26, d1, 1);
19844 __ Uqshl(d27, d2, 1);
19845
19846 END();
19847
19848 RUN();
19849
19850 ASSERT_EQUAL_128(0, 0xfe, q16);
19851 ASSERT_EQUAL_128(0, 0xff, q17);
19852 ASSERT_EQUAL_128(0, 0x02, q18);
19853
19854 ASSERT_EQUAL_128(0, 0xfffe, q19);
19855 ASSERT_EQUAL_128(0, 0xffff, q20);
19856 ASSERT_EQUAL_128(0, 0x0002, q21);
19857
19858 ASSERT_EQUAL_128(0, 0xfffffffe, q22);
19859 ASSERT_EQUAL_128(0, 0xffffffff, q23);
19860 ASSERT_EQUAL_128(0, 0x00000002, q24);
19861
19862 ASSERT_EQUAL_128(0, 0xfffffffffffffffe, q25);
19863 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q26);
19864 ASSERT_EQUAL_128(0, 0x0000000000000002, q27);
19865
19866 TEARDOWN();
19867}
19868
19869
19870TEST(neon_sqshlu_scalar) {
19871 SETUP();
19872
19873 START();
19874
19875 __ Movi(v0.V2D(), 0x0, 0x7f);
19876 __ Movi(v1.V2D(), 0x0, 0x80);
19877 __ Movi(v2.V2D(), 0x0, 0x01);
19878 __ Sqshlu(b16, b0, 2);
19879 __ Sqshlu(b17, b1, 2);
19880 __ Sqshlu(b18, b2, 2);
19881
19882 __ Movi(v0.V2D(), 0x0, 0x7fff);
19883 __ Movi(v1.V2D(), 0x0, 0x8000);
19884 __ Movi(v2.V2D(), 0x0, 0x0001);
19885 __ Sqshlu(h19, h0, 2);
19886 __ Sqshlu(h20, h1, 2);
19887 __ Sqshlu(h21, h2, 2);
19888
19889 __ Movi(v0.V2D(), 0x0, 0x7fffffff);
19890 __ Movi(v1.V2D(), 0x0, 0x80000000);
19891 __ Movi(v2.V2D(), 0x0, 0x00000001);
19892 __ Sqshlu(s22, s0, 2);
19893 __ Sqshlu(s23, s1, 2);
19894 __ Sqshlu(s24, s2, 2);
19895
19896 __ Movi(v0.V2D(), 0x0, 0x7fffffffffffffff);
19897 __ Movi(v1.V2D(), 0x0, 0x8000000000000000);
19898 __ Movi(v2.V2D(), 0x0, 0x0000000000000001);
19899 __ Sqshlu(d25, d0, 2);
19900 __ Sqshlu(d26, d1, 2);
19901 __ Sqshlu(d27, d2, 2);
19902
19903 END();
19904
19905 RUN();
19906
19907 ASSERT_EQUAL_128(0, 0xff, q16);
19908 ASSERT_EQUAL_128(0, 0x00, q17);
19909 ASSERT_EQUAL_128(0, 0x04, q18);
19910
19911 ASSERT_EQUAL_128(0, 0xffff, q19);
19912 ASSERT_EQUAL_128(0, 0x0000, q20);
19913 ASSERT_EQUAL_128(0, 0x0004, q21);
19914
19915 ASSERT_EQUAL_128(0, 0xffffffff, q22);
19916 ASSERT_EQUAL_128(0, 0x00000000, q23);
19917 ASSERT_EQUAL_128(0, 0x00000004, q24);
19918
19919 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q25);
19920 ASSERT_EQUAL_128(0, 0x0000000000000000, q26);
19921 ASSERT_EQUAL_128(0, 0x0000000000000004, q27);
19922
19923 TEARDOWN();
19924}
19925
19926
19927TEST(neon_sshll) {
19928 SETUP();
19929
19930 START();
19931
19932 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19933 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19934 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19935
19936 __ Sshll(v16.V8H(), v0.V8B(), 4);
19937 __ Sshll2(v17.V8H(), v0.V16B(), 4);
19938
19939 __ Sshll(v18.V4S(), v1.V4H(), 8);
19940 __ Sshll2(v19.V4S(), v1.V8H(), 8);
19941
19942 __ Sshll(v20.V2D(), v2.V2S(), 16);
19943 __ Sshll2(v21.V2D(), v2.V4S(), 16);
19944
19945 END();
19946
19947 RUN();
19948
19949 ASSERT_EQUAL_128(0xf800f810fff00000, 0x001007f0f800f810, q16);
19950 ASSERT_EQUAL_128(0x07f000100000fff0, 0xf810f80007f00010, q17);
19951 ASSERT_EQUAL_128(0xffffff0000000000, 0x00000100007fff00, q18);
19952 ASSERT_EQUAL_128(0xff800000ff800100, 0xffffff0000000000, q19);
19953 ASSERT_EQUAL_128(0x0000000000000000, 0x00007fffffff0000, q20);
19954 ASSERT_EQUAL_128(0xffff800000000000, 0xffffffffffff0000, q21);
19955 TEARDOWN();
19956}
19957
19958TEST(neon_shll) {
19959 SETUP();
19960
19961 START();
19962
19963 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19964 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19965 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19966
19967 __ Shll(v16.V8H(), v0.V8B(), 8);
19968 __ Shll2(v17.V8H(), v0.V16B(), 8);
19969
19970 __ Shll(v18.V4S(), v1.V4H(), 16);
19971 __ Shll2(v19.V4S(), v1.V8H(), 16);
19972
19973 __ Shll(v20.V2D(), v2.V2S(), 32);
19974 __ Shll2(v21.V2D(), v2.V4S(), 32);
19975
19976 END();
19977
19978 RUN();
19979
19980 ASSERT_EQUAL_128(0x80008100ff000000, 0x01007f0080008100, q16);
19981 ASSERT_EQUAL_128(0x7f0001000000ff00, 0x810080007f000100, q17);
19982 ASSERT_EQUAL_128(0xffff000000000000, 0x000100007fff0000, q18);
19983 ASSERT_EQUAL_128(0x8000000080010000, 0xffff000000000000, q19);
19984 ASSERT_EQUAL_128(0x0000000000000000, 0x7fffffff00000000, q20);
19985 ASSERT_EQUAL_128(0x8000000000000000, 0xffffffff00000000, q21);
19986 TEARDOWN();
19987}
19988
19989TEST(neon_ushll) {
19990 SETUP();
19991
19992 START();
19993
19994 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
19995 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
19996 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
19997
19998 __ Ushll(v16.V8H(), v0.V8B(), 4);
19999 __ Ushll2(v17.V8H(), v0.V16B(), 4);
20000
20001 __ Ushll(v18.V4S(), v1.V4H(), 8);
20002 __ Ushll2(v19.V4S(), v1.V8H(), 8);
20003
20004 __ Ushll(v20.V2D(), v2.V2S(), 16);
20005 __ Ushll2(v21.V2D(), v2.V4S(), 16);
20006
20007 END();
20008
20009 RUN();
20010
20011 ASSERT_EQUAL_128(0x080008100ff00000, 0x001007f008000810, q16);
20012 ASSERT_EQUAL_128(0x07f0001000000ff0, 0x0810080007f00010, q17);
20013 ASSERT_EQUAL_128(0x00ffff0000000000, 0x00000100007fff00, q18);
20014 ASSERT_EQUAL_128(0x0080000000800100, 0x00ffff0000000000, q19);
20015 ASSERT_EQUAL_128(0x0000000000000000, 0x00007fffffff0000, q20);
20016 ASSERT_EQUAL_128(0x0000800000000000, 0x0000ffffffff0000, q21);
20017 TEARDOWN();
20018}
20019
20020
20021TEST(neon_sxtl) {
20022 SETUP();
20023
20024 START();
20025
20026 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
20027 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
20028 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
20029
20030 __ Sxtl(v16.V8H(), v0.V8B());
20031 __ Sxtl2(v17.V8H(), v0.V16B());
20032
20033 __ Sxtl(v18.V4S(), v1.V4H());
20034 __ Sxtl2(v19.V4S(), v1.V8H());
20035
20036 __ Sxtl(v20.V2D(), v2.V2S());
20037 __ Sxtl2(v21.V2D(), v2.V4S());
20038
20039 END();
20040
20041 RUN();
20042
20043 ASSERT_EQUAL_128(0xff80ff81ffff0000, 0x0001007fff80ff81, q16);
20044 ASSERT_EQUAL_128(0x007f00010000ffff, 0xff81ff80007f0001, q17);
20045 ASSERT_EQUAL_128(0xffffffff00000000, 0x0000000100007fff, q18);
20046 ASSERT_EQUAL_128(0xffff8000ffff8001, 0xffffffff00000000, q19);
20047 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
20048 ASSERT_EQUAL_128(0xffffffff80000000, 0xffffffffffffffff, q21);
20049 TEARDOWN();
20050}
20051
20052
20053TEST(neon_uxtl) {
20054 SETUP();
20055
20056 START();
20057
20058 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
20059 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
20060 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
20061
20062 __ Uxtl(v16.V8H(), v0.V8B());
20063 __ Uxtl2(v17.V8H(), v0.V16B());
20064
20065 __ Uxtl(v18.V4S(), v1.V4H());
20066 __ Uxtl2(v19.V4S(), v1.V8H());
20067
20068 __ Uxtl(v20.V2D(), v2.V2S());
20069 __ Uxtl2(v21.V2D(), v2.V4S());
20070
20071 END();
20072
20073 RUN();
20074
20075 ASSERT_EQUAL_128(0x0080008100ff0000, 0x0001007f00800081, q16);
20076 ASSERT_EQUAL_128(0x007f0001000000ff, 0x00810080007f0001, q17);
20077 ASSERT_EQUAL_128(0x0000ffff00000000, 0x0000000100007fff, q18);
20078 ASSERT_EQUAL_128(0x0000800000008001, 0x0000ffff00000000, q19);
20079 ASSERT_EQUAL_128(0x0000000000000000, 0x000000007fffffff, q20);
20080 ASSERT_EQUAL_128(0x0000000080000000, 0x00000000ffffffff, q21);
20081 TEARDOWN();
20082}
20083
20084
20085TEST(neon_ssra) {
20086 SETUP();
20087
20088 START();
20089
20090 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
20091 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
20092 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
20093 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
20094 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
20095
20096 __ Mov(v16.V2D(), v0.V2D());
20097 __ Mov(v17.V2D(), v0.V2D());
20098 __ Mov(v18.V2D(), v1.V2D());
20099 __ Mov(v19.V2D(), v1.V2D());
20100 __ Mov(v20.V2D(), v2.V2D());
20101 __ Mov(v21.V2D(), v2.V2D());
20102 __ Mov(v22.V2D(), v3.V2D());
20103 __ Mov(v23.V2D(), v4.V2D());
20104 __ Mov(v24.V2D(), v3.V2D());
20105 __ Mov(v25.V2D(), v4.V2D());
20106
20107 __ Ssra(v16.V8B(), v0.V8B(), 4);
20108 __ Ssra(v17.V16B(), v0.V16B(), 4);
20109
20110 __ Ssra(v18.V4H(), v1.V4H(), 8);
20111 __ Ssra(v19.V8H(), v1.V8H(), 8);
20112
20113 __ Ssra(v20.V2S(), v2.V2S(), 16);
20114 __ Ssra(v21.V4S(), v2.V4S(), 16);
20115
20116 __ Ssra(v22.V2D(), v3.V2D(), 32);
20117 __ Ssra(v23.V2D(), v4.V2D(), 32);
20118
20119 __ Ssra(d24, d3, 48);
20120
20121 END();
20122
20123 RUN();
20124
20125 ASSERT_EQUAL_128(0x0000000000000000, 0x7879fe0001867879, q16);
20126 ASSERT_EQUAL_128(0x860100fe79788601, 0x7879fe0001867879, q17);
20127 ASSERT_EQUAL_128(0x0000000000000000, 0xfffe00000001807e, q18);
20128 ASSERT_EQUAL_128(0x7f807f81fffe0000, 0xfffe00000001807e, q19);
20129 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007ffe, q20);
20130 ASSERT_EQUAL_128(0x7fff8000fffffffe, 0x0000000080007ffe, q21);
20131 ASSERT_EQUAL_128(0x7fffffff80000001, 0x800000007ffffffe, q22);
20132 ASSERT_EQUAL_128(0x7fffffff80000000, 0x0000000000000000, q23);
20133 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007ffe, q24);
20134 TEARDOWN();
20135}
20136
20137TEST(neon_srsra) {
20138 SETUP();
20139
20140 START();
20141
20142 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
20143 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
20144 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
20145 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
20146 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
20147
20148 __ Mov(v16.V2D(), v0.V2D());
20149 __ Mov(v17.V2D(), v0.V2D());
20150 __ Mov(v18.V2D(), v1.V2D());
20151 __ Mov(v19.V2D(), v1.V2D());
20152 __ Mov(v20.V2D(), v2.V2D());
20153 __ Mov(v21.V2D(), v2.V2D());
20154 __ Mov(v22.V2D(), v3.V2D());
20155 __ Mov(v23.V2D(), v4.V2D());
20156 __ Mov(v24.V2D(), v3.V2D());
20157 __ Mov(v25.V2D(), v4.V2D());
20158
20159 __ Srsra(v16.V8B(), v0.V8B(), 4);
20160 __ Srsra(v17.V16B(), v0.V16B(), 4);
20161
20162 __ Srsra(v18.V4H(), v1.V4H(), 8);
20163 __ Srsra(v19.V8H(), v1.V8H(), 8);
20164
20165 __ Srsra(v20.V2S(), v2.V2S(), 16);
20166 __ Srsra(v21.V4S(), v2.V4S(), 16);
20167
20168 __ Srsra(v22.V2D(), v3.V2D(), 32);
20169 __ Srsra(v23.V2D(), v4.V2D(), 32);
20170
20171 __ Srsra(d24, d3, 48);
20172
20173 END();
20174
20175 RUN();
20176
20177 ASSERT_EQUAL_128(0x0000000000000000, 0x7879ff0001877879, q16);
20178 ASSERT_EQUAL_128(0x870100ff79788701, 0x7879ff0001877879, q17);
20179 ASSERT_EQUAL_128(0x0000000000000000, 0xffff00000001807f, q18);
20180 ASSERT_EQUAL_128(0x7f807f81ffff0000, 0xffff00000001807f, q19);
20181 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007fff, q20);
20182 ASSERT_EQUAL_128(0x7fff8000ffffffff, 0x0000000080007fff, q21);
20183 ASSERT_EQUAL_128(0x7fffffff80000001, 0x800000007fffffff, q22);
20184 ASSERT_EQUAL_128(0x7fffffff80000000, 0x0000000000000000, q23);
20185 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007fff, q24);
20186
20187 TEARDOWN();
20188}
20189
20190TEST(neon_usra) {
20191 SETUP();
20192
20193 START();
20194
20195 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
20196 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
20197 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
20198 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
20199 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
20200
20201 __ Mov(v16.V2D(), v0.V2D());
20202 __ Mov(v17.V2D(), v0.V2D());
20203 __ Mov(v18.V2D(), v1.V2D());
20204 __ Mov(v19.V2D(), v1.V2D());
20205 __ Mov(v20.V2D(), v2.V2D());
20206 __ Mov(v21.V2D(), v2.V2D());
20207 __ Mov(v22.V2D(), v3.V2D());
20208 __ Mov(v23.V2D(), v4.V2D());
20209 __ Mov(v24.V2D(), v3.V2D());
20210 __ Mov(v25.V2D(), v4.V2D());
20211
20212 __ Usra(v16.V8B(), v0.V8B(), 4);
20213 __ Usra(v17.V16B(), v0.V16B(), 4);
20214
20215 __ Usra(v18.V4H(), v1.V4H(), 8);
20216 __ Usra(v19.V8H(), v1.V8H(), 8);
20217
20218 __ Usra(v20.V2S(), v2.V2S(), 16);
20219 __ Usra(v21.V4S(), v2.V4S(), 16);
20220
20221 __ Usra(v22.V2D(), v3.V2D(), 32);
20222 __ Usra(v23.V2D(), v4.V2D(), 32);
20223
20224 __ Usra(d24, d3, 48);
20225
20226 END();
20227
20228 RUN();
20229
20230 ASSERT_EQUAL_128(0x0000000000000000, 0x88890e0001868889, q16);
20231 ASSERT_EQUAL_128(0x8601000e89888601, 0x88890e0001868889, q17);
20232 ASSERT_EQUAL_128(0x0000000000000000, 0x00fe00000001807e, q18);
20233 ASSERT_EQUAL_128(0x8080808100fe0000, 0x00fe00000001807e, q19);
20234 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007ffe, q20);
20235 ASSERT_EQUAL_128(0x800080000000fffe, 0x0000000080007ffe, q21);
20236 ASSERT_EQUAL_128(0x8000000080000001, 0x800000007ffffffe, q22);
20237 ASSERT_EQUAL_128(0x8000000080000000, 0x0000000000000000, q23);
20238 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007ffe, q24);
20239
20240 TEARDOWN();
20241}
20242
20243TEST(neon_ursra) {
20244 SETUP();
20245
20246 START();
20247
20248 __ Movi(v0.V2D(), 0x7f0100ff81807f01, 0x8081ff00017f8081);
20249 __ Movi(v1.V2D(), 0x80008001ffff0000, 0xffff000000017fff);
20250 __ Movi(v2.V2D(), 0x80000000ffffffff, 0x000000007fffffff);
20251 __ Movi(v3.V2D(), 0x8000000000000001, 0x7fffffffffffffff);
20252 __ Movi(v4.V2D(), 0x8000000000000000, 0x0000000000000000);
20253
20254 __ Mov(v16.V2D(), v0.V2D());
20255 __ Mov(v17.V2D(), v0.V2D());
20256 __ Mov(v18.V2D(), v1.V2D());
20257 __ Mov(v19.V2D(), v1.V2D());
20258 __ Mov(v20.V2D(), v2.V2D());
20259 __ Mov(v21.V2D(), v2.V2D());
20260 __ Mov(v22.V2D(), v3.V2D());
20261 __ Mov(v23.V2D(), v4.V2D());
20262 __ Mov(v24.V2D(), v3.V2D());
20263 __ Mov(v25.V2D(), v4.V2D());
20264
20265 __ Ursra(v16.V8B(), v0.V8B(), 4);
20266 __ Ursra(v17.V16B(), v0.V16B(), 4);
20267
20268 __ Ursra(v18.V4H(), v1.V4H(), 8);
20269 __ Ursra(v19.V8H(), v1.V8H(), 8);
20270
20271 __ Ursra(v20.V2S(), v2.V2S(), 16);
20272 __ Ursra(v21.V4S(), v2.V4S(), 16);
20273
20274 __ Ursra(v22.V2D(), v3.V2D(), 32);
20275 __ Ursra(v23.V2D(), v4.V2D(), 32);
20276
20277 __ Ursra(d24, d3, 48);
20278
20279 END();
20280
20281 RUN();
20282
20283 ASSERT_EQUAL_128(0x0000000000000000, 0x88890f0001878889, q16);
20284 ASSERT_EQUAL_128(0x8701000f89888701, 0x88890f0001878889, q17);
20285 ASSERT_EQUAL_128(0x0000000000000000, 0x00ff00000001807f, q18);
20286 ASSERT_EQUAL_128(0x8080808100ff0000, 0x00ff00000001807f, q19);
20287 ASSERT_EQUAL_128(0x0000000000000000, 0x0000000080007fff, q20);
20288 ASSERT_EQUAL_128(0x800080000000ffff, 0x0000000080007fff, q21);
20289 ASSERT_EQUAL_128(0x8000000080000001, 0x800000007fffffff, q22);
20290 ASSERT_EQUAL_128(0x8000000080000000, 0x0000000000000000, q23);
20291 ASSERT_EQUAL_128(0x0000000000000000, 0x8000000000007fff, q24);
20292 TEARDOWN();
20293}
20294
20295
20296TEST(neon_uqshl_scalar) {
20297 SETUP();
20298
20299 START();
20300
20301 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20302 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20303 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20304 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20305
20306 __ Uqshl(b16, b0, b2);
20307 __ Uqshl(b17, b0, b3);
20308 __ Uqshl(b18, b1, b2);
20309 __ Uqshl(b19, b1, b3);
20310 __ Uqshl(h20, h0, h2);
20311 __ Uqshl(h21, h0, h3);
20312 __ Uqshl(h22, h1, h2);
20313 __ Uqshl(h23, h1, h3);
20314 __ Uqshl(s24, s0, s2);
20315 __ Uqshl(s25, s0, s3);
20316 __ Uqshl(s26, s1, s2);
20317 __ Uqshl(s27, s1, s3);
20318 __ Uqshl(d28, d0, d2);
20319 __ Uqshl(d29, d0, d3);
20320 __ Uqshl(d30, d1, d2);
20321 __ Uqshl(d31, d1, d3);
20322
20323 END();
20324
20325 RUN();
20326
20327 ASSERT_EQUAL_128(0, 0xff, q16);
20328 ASSERT_EQUAL_128(0, 0x78, q17);
20329 ASSERT_EQUAL_128(0, 0xfe, q18);
20330 ASSERT_EQUAL_128(0, 0x3f, q19);
20331 ASSERT_EQUAL_128(0, 0xffff, q20);
20332 ASSERT_EQUAL_128(0, 0x7878, q21);
20333 ASSERT_EQUAL_128(0, 0xfefe, q22);
20334 ASSERT_EQUAL_128(0, 0x3fbf, q23);
20335 ASSERT_EQUAL_128(0, 0xffffffff, q24);
20336 ASSERT_EQUAL_128(0, 0x78007878, q25);
20337 ASSERT_EQUAL_128(0, 0xfffefefe, q26);
20338 ASSERT_EQUAL_128(0, 0x3fffbfbf, q27);
20339 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q28);
20340 ASSERT_EQUAL_128(0, 0x7800000078007878, q29);
20341 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q30);
20342 ASSERT_EQUAL_128(0, 0x3fffffffbfffbfbf, q31);
20343
20344 TEARDOWN();
20345}
20346
20347
20348TEST(neon_sqshl_scalar) {
20349 SETUP();
20350
20351 START();
20352
20353 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xbfffffffbfffbfbf);
20354 __ Movi(v1.V2D(), 0x5555555555555555, 0x4000000040004040);
20355 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20356 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20357
20358 __ Sqshl(b16, b0, b2);
20359 __ Sqshl(b17, b0, b3);
20360 __ Sqshl(b18, b1, b2);
20361 __ Sqshl(b19, b1, b3);
20362 __ Sqshl(h20, h0, h2);
20363 __ Sqshl(h21, h0, h3);
20364 __ Sqshl(h22, h1, h2);
20365 __ Sqshl(h23, h1, h3);
20366 __ Sqshl(s24, s0, s2);
20367 __ Sqshl(s25, s0, s3);
20368 __ Sqshl(s26, s1, s2);
20369 __ Sqshl(s27, s1, s3);
20370 __ Sqshl(d28, d0, d2);
20371 __ Sqshl(d29, d0, d3);
20372 __ Sqshl(d30, d1, d2);
20373 __ Sqshl(d31, d1, d3);
20374
20375 END();
20376
20377 RUN();
20378
20379 ASSERT_EQUAL_128(0, 0x80, q16);
20380 ASSERT_EQUAL_128(0, 0xdf, q17);
20381 ASSERT_EQUAL_128(0, 0x7f, q18);
20382 ASSERT_EQUAL_128(0, 0x20, q19);
20383 ASSERT_EQUAL_128(0, 0x8000, q20);
20384 ASSERT_EQUAL_128(0, 0xdfdf, q21);
20385 ASSERT_EQUAL_128(0, 0x7fff, q22);
20386 ASSERT_EQUAL_128(0, 0x2020, q23);
20387 ASSERT_EQUAL_128(0, 0x80000000, q24);
20388 ASSERT_EQUAL_128(0, 0xdfffdfdf, q25);
20389 ASSERT_EQUAL_128(0, 0x7fffffff, q26);
20390 ASSERT_EQUAL_128(0, 0x20002020, q27);
20391 ASSERT_EQUAL_128(0, 0x8000000000000000, q28);
20392 ASSERT_EQUAL_128(0, 0xdfffffffdfffdfdf, q29);
20393 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q30);
20394 ASSERT_EQUAL_128(0, 0x2000000020002020, q31);
20395
20396 TEARDOWN();
20397}
20398
20399
20400TEST(neon_urshl_scalar) {
20401 SETUP();
20402
20403 START();
20404
20405 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20406 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20407 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20408 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20409
20410 __ Urshl(d28, d0, d2);
20411 __ Urshl(d29, d0, d3);
20412 __ Urshl(d30, d1, d2);
20413 __ Urshl(d31, d1, d3);
20414
20415 END();
20416
20417 RUN();
20418
20419 ASSERT_EQUAL_128(0, 0xe0000001e001e1e0, q28);
20420 ASSERT_EQUAL_128(0, 0x7800000078007878, q29);
20421 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q30);
20422 ASSERT_EQUAL_128(0, 0x3fffffffbfffbfc0, q31);
20423
20424 TEARDOWN();
20425}
20426
20427
20428TEST(neon_srshl_scalar) {
20429 SETUP();
20430
20431 START();
20432
20433 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xbfffffffbfffbfbf);
20434 __ Movi(v1.V2D(), 0x5555555555555555, 0x4000000040004040);
20435 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20436 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20437
20438 __ Srshl(d28, d0, d2);
20439 __ Srshl(d29, d0, d3);
20440 __ Srshl(d30, d1, d2);
20441 __ Srshl(d31, d1, d3);
20442
20443 END();
20444
20445 RUN();
20446
20447 ASSERT_EQUAL_128(0, 0x7fffffff7fff7f7e, q28);
20448 ASSERT_EQUAL_128(0, 0xdfffffffdfffdfe0, q29);
20449 ASSERT_EQUAL_128(0, 0x8000000080008080, q30);
20450 ASSERT_EQUAL_128(0, 0x2000000020002020, q31);
20451
20452 TEARDOWN();
20453}
20454
20455
20456TEST(neon_uqrshl_scalar) {
20457 SETUP();
20458
20459 START();
20460
20461 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20462 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20463 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20464 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20465
20466 __ Uqrshl(b16, b0, b2);
20467 __ Uqrshl(b17, b0, b3);
20468 __ Uqrshl(b18, b1, b2);
20469 __ Uqrshl(b19, b1, b3);
20470 __ Uqrshl(h20, h0, h2);
20471 __ Uqrshl(h21, h0, h3);
20472 __ Uqrshl(h22, h1, h2);
20473 __ Uqrshl(h23, h1, h3);
20474 __ Uqrshl(s24, s0, s2);
20475 __ Uqrshl(s25, s0, s3);
20476 __ Uqrshl(s26, s1, s2);
20477 __ Uqrshl(s27, s1, s3);
20478 __ Uqrshl(d28, d0, d2);
20479 __ Uqrshl(d29, d0, d3);
20480 __ Uqrshl(d30, d1, d2);
20481 __ Uqrshl(d31, d1, d3);
20482
20483 END();
20484
20485 RUN();
20486
20487 ASSERT_EQUAL_128(0, 0xff, q16);
20488 ASSERT_EQUAL_128(0, 0x78, q17);
20489 ASSERT_EQUAL_128(0, 0xfe, q18);
20490 ASSERT_EQUAL_128(0, 0x40, q19);
20491 ASSERT_EQUAL_128(0, 0xffff, q20);
20492 ASSERT_EQUAL_128(0, 0x7878, q21);
20493 ASSERT_EQUAL_128(0, 0xfefe, q22);
20494 ASSERT_EQUAL_128(0, 0x3fc0, q23);
20495 ASSERT_EQUAL_128(0, 0xffffffff, q24);
20496 ASSERT_EQUAL_128(0, 0x78007878, q25);
20497 ASSERT_EQUAL_128(0, 0xfffefefe, q26);
20498 ASSERT_EQUAL_128(0, 0x3fffbfc0, q27);
20499 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q28);
20500 ASSERT_EQUAL_128(0, 0x7800000078007878, q29);
20501 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q30);
20502 ASSERT_EQUAL_128(0, 0x3fffffffbfffbfc0, q31);
20503
20504 TEARDOWN();
20505}
20506
20507
20508TEST(neon_sqrshl_scalar) {
20509 SETUP();
20510
20511 START();
20512
20513 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xbfffffffbfffbfbf);
20514 __ Movi(v1.V2D(), 0x5555555555555555, 0x4000000040004040);
20515 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x0000000000000001);
20516 __ Movi(v3.V2D(), 0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff);
20517
20518 __ Sqrshl(b16, b0, b2);
20519 __ Sqrshl(b17, b0, b3);
20520 __ Sqrshl(b18, b1, b2);
20521 __ Sqrshl(b19, b1, b3);
20522 __ Sqrshl(h20, h0, h2);
20523 __ Sqrshl(h21, h0, h3);
20524 __ Sqrshl(h22, h1, h2);
20525 __ Sqrshl(h23, h1, h3);
20526 __ Sqrshl(s24, s0, s2);
20527 __ Sqrshl(s25, s0, s3);
20528 __ Sqrshl(s26, s1, s2);
20529 __ Sqrshl(s27, s1, s3);
20530 __ Sqrshl(d28, d0, d2);
20531 __ Sqrshl(d29, d0, d3);
20532 __ Sqrshl(d30, d1, d2);
20533 __ Sqrshl(d31, d1, d3);
20534
20535 END();
20536
20537 RUN();
20538
20539 ASSERT_EQUAL_128(0, 0x80, q16);
20540 ASSERT_EQUAL_128(0, 0xe0, q17);
20541 ASSERT_EQUAL_128(0, 0x7f, q18);
20542 ASSERT_EQUAL_128(0, 0x20, q19);
20543 ASSERT_EQUAL_128(0, 0x8000, q20);
20544 ASSERT_EQUAL_128(0, 0xdfe0, q21);
20545 ASSERT_EQUAL_128(0, 0x7fff, q22);
20546 ASSERT_EQUAL_128(0, 0x2020, q23);
20547 ASSERT_EQUAL_128(0, 0x80000000, q24);
20548 ASSERT_EQUAL_128(0, 0xdfffdfe0, q25);
20549 ASSERT_EQUAL_128(0, 0x7fffffff, q26);
20550 ASSERT_EQUAL_128(0, 0x20002020, q27);
20551 ASSERT_EQUAL_128(0, 0x8000000000000000, q28);
20552 ASSERT_EQUAL_128(0, 0xdfffffffdfffdfe0, q29);
20553 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q30);
20554 ASSERT_EQUAL_128(0, 0x2000000020002020, q31);
20555
20556 TEARDOWN();
20557}
20558
20559
20560TEST(neon_uqadd_scalar) {
20561 SETUP();
20562
20563 START();
20564
20565 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20566 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20567 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x1000000010001010);
20568
20569 __ Uqadd(b16, b0, b0);
20570 __ Uqadd(b17, b1, b1);
20571 __ Uqadd(b18, b2, b2);
20572 __ Uqadd(h19, h0, h0);
20573 __ Uqadd(h20, h1, h1);
20574 __ Uqadd(h21, h2, h2);
20575 __ Uqadd(s22, s0, s0);
20576 __ Uqadd(s23, s1, s1);
20577 __ Uqadd(s24, s2, s2);
20578 __ Uqadd(d25, d0, d0);
20579 __ Uqadd(d26, d1, d1);
20580 __ Uqadd(d27, d2, d2);
20581
20582 END();
20583
20584 RUN();
20585
20586 ASSERT_EQUAL_128(0, 0xff, q16);
20587 ASSERT_EQUAL_128(0, 0xfe, q17);
20588 ASSERT_EQUAL_128(0, 0x20, q18);
20589 ASSERT_EQUAL_128(0, 0xffff, q19);
20590 ASSERT_EQUAL_128(0, 0xfefe, q20);
20591 ASSERT_EQUAL_128(0, 0x2020, q21);
20592 ASSERT_EQUAL_128(0, 0xffffffff, q22);
20593 ASSERT_EQUAL_128(0, 0xfffefefe, q23);
20594 ASSERT_EQUAL_128(0, 0x20002020, q24);
20595 ASSERT_EQUAL_128(0, 0xffffffffffffffff, q25);
20596 ASSERT_EQUAL_128(0, 0xfffffffefffefefe, q26);
20597 ASSERT_EQUAL_128(0, 0x2000000020002020, q27);
20598
20599 TEARDOWN();
20600}
20601
20602
20603TEST(neon_sqadd_scalar) {
20604 SETUP();
20605
20606 START();
20607
20608 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0x8000000180018181);
20609 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20610 __ Movi(v2.V2D(), 0xaaaaaaaaaaaaaaaa, 0x1000000010001010);
20611
20612 __ Sqadd(b16, b0, b0);
20613 __ Sqadd(b17, b1, b1);
20614 __ Sqadd(b18, b2, b2);
20615 __ Sqadd(h19, h0, h0);
20616 __ Sqadd(h20, h1, h1);
20617 __ Sqadd(h21, h2, h2);
20618 __ Sqadd(s22, s0, s0);
20619 __ Sqadd(s23, s1, s1);
20620 __ Sqadd(s24, s2, s2);
20621 __ Sqadd(d25, d0, d0);
20622 __ Sqadd(d26, d1, d1);
20623 __ Sqadd(d27, d2, d2);
20624
20625 END();
20626
20627 RUN();
20628
20629 ASSERT_EQUAL_128(0, 0x80, q16);
20630 ASSERT_EQUAL_128(0, 0x7f, q17);
20631 ASSERT_EQUAL_128(0, 0x20, q18);
20632 ASSERT_EQUAL_128(0, 0x8000, q19);
20633 ASSERT_EQUAL_128(0, 0x7fff, q20);
20634 ASSERT_EQUAL_128(0, 0x2020, q21);
20635 ASSERT_EQUAL_128(0, 0x80000000, q22);
20636 ASSERT_EQUAL_128(0, 0x7fffffff, q23);
20637 ASSERT_EQUAL_128(0, 0x20002020, q24);
20638 ASSERT_EQUAL_128(0, 0x8000000000000000, q25);
20639 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q26);
20640 ASSERT_EQUAL_128(0, 0x2000000020002020, q27);
20641
20642 TEARDOWN();
20643}
20644
20645
20646TEST(neon_uqsub_scalar) {
20647 SETUP();
20648
20649 START();
20650
20651 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20652 __ Movi(v1.V2D(), 0x5555555555555555, 0x7fffffff7fff7f7f);
20653
20654 __ Uqsub(b16, b0, b0);
20655 __ Uqsub(b17, b0, b1);
20656 __ Uqsub(b18, b1, b0);
20657 __ Uqsub(h19, h0, h0);
20658 __ Uqsub(h20, h0, h1);
20659 __ Uqsub(h21, h1, h0);
20660 __ Uqsub(s22, s0, s0);
20661 __ Uqsub(s23, s0, s1);
20662 __ Uqsub(s24, s1, s0);
20663 __ Uqsub(d25, d0, d0);
20664 __ Uqsub(d26, d0, d1);
20665 __ Uqsub(d27, d1, d0);
20666
20667 END();
20668
20669 RUN();
20670
20671 ASSERT_EQUAL_128(0, 0, q16);
20672 ASSERT_EQUAL_128(0, 0x71, q17);
20673 ASSERT_EQUAL_128(0, 0, q18);
20674
20675 ASSERT_EQUAL_128(0, 0, q19);
20676 ASSERT_EQUAL_128(0, 0x7171, q20);
20677 ASSERT_EQUAL_128(0, 0, q21);
20678
20679 ASSERT_EQUAL_128(0, 0, q22);
20680 ASSERT_EQUAL_128(0, 0x70017171, q23);
20681 ASSERT_EQUAL_128(0, 0, q24);
20682
20683 ASSERT_EQUAL_128(0, 0, q25);
20684 ASSERT_EQUAL_128(0, 0x7000000170017171, q26);
20685 ASSERT_EQUAL_128(0, 0, q27);
20686
20687 TEARDOWN();
20688}
20689
20690
20691TEST(neon_sqsub_scalar) {
20692 SETUP();
20693
20694 START();
20695
20696 __ Movi(v0.V2D(), 0xaaaaaaaaaaaaaaaa, 0xf0000000f000f0f0);
20697 __ Movi(v1.V2D(), 0x5555555555555555, 0x7eeeeeee7eee7e7e);
20698
20699 __ Sqsub(b16, b0, b0);
20700 __ Sqsub(b17, b0, b1);
20701 __ Sqsub(b18, b1, b0);
20702 __ Sqsub(h19, h0, h0);
20703 __ Sqsub(h20, h0, h1);
20704 __ Sqsub(h21, h1, h0);
20705 __ Sqsub(s22, s0, s0);
20706 __ Sqsub(s23, s0, s1);
20707 __ Sqsub(s24, s1, s0);
20708 __ Sqsub(d25, d0, d0);
20709 __ Sqsub(d26, d0, d1);
20710 __ Sqsub(d27, d1, d0);
20711
20712 END();
20713
20714 RUN();
20715
20716 ASSERT_EQUAL_128(0, 0, q16);
20717 ASSERT_EQUAL_128(0, 0x80, q17);
20718 ASSERT_EQUAL_128(0, 0x7f, q18);
20719
20720 ASSERT_EQUAL_128(0, 0, q19);
20721 ASSERT_EQUAL_128(0, 0x8000, q20);
20722 ASSERT_EQUAL_128(0, 0x7fff, q21);
20723
20724 ASSERT_EQUAL_128(0, 0, q22);
20725 ASSERT_EQUAL_128(0, 0x80000000, q23);
20726 ASSERT_EQUAL_128(0, 0x7fffffff, q24);
20727
20728 ASSERT_EQUAL_128(0, 0, q25);
20729 ASSERT_EQUAL_128(0, 0x8000000000000000, q26);
20730 ASSERT_EQUAL_128(0, 0x7fffffffffffffff, q27);
20731
20732 TEARDOWN();
20733}
20734
20735
20736TEST(neon_fmla_fmls) {
20737 SETUP();
20738
20739 START();
20740 __ Movi(v0.V2D(), 0x3f80000040000000, 0x4100000000000000);
20741 __ Movi(v1.V2D(), 0x400000003f800000, 0x000000003f800000);
20742 __ Movi(v2.V2D(), 0x3f800000ffffffff, 0x7f800000ff800000);
20743 __ Mov(v16.V16B(), v0.V16B());
20744 __ Mov(v17.V16B(), v0.V16B());
20745 __ Mov(v18.V16B(), v0.V16B());
20746 __ Mov(v19.V16B(), v0.V16B());
20747 __ Mov(v20.V16B(), v0.V16B());
20748 __ Mov(v21.V16B(), v0.V16B());
20749
20750 __ Fmla(v16.V2S(), v1.V2S(), v2.V2S());
20751 __ Fmla(v17.V4S(), v1.V4S(), v2.V4S());
20752 __ Fmla(v18.V2D(), v1.V2D(), v2.V2D());
20753 __ Fmls(v19.V2S(), v1.V2S(), v2.V2S());
20754 __ Fmls(v20.V4S(), v1.V4S(), v2.V4S());
20755 __ Fmls(v21.V2D(), v1.V2D(), v2.V2D());
20756 END();
20757
20758 RUN();
20759
20760 ASSERT_EQUAL_128(0x0000000000000000, 0x7fc00000ff800000, q16);
20761 ASSERT_EQUAL_128(0x40400000ffffffff, 0x7fc00000ff800000, q17);
20762 ASSERT_EQUAL_128(0x3f9800015f8003f7, 0x41000000000000fe, q18);
20763 ASSERT_EQUAL_128(0x0000000000000000, 0x7fc000007f800000, q19);
20764 ASSERT_EQUAL_128(0xbf800000ffffffff, 0x7fc000007f800000, q20);
20765 ASSERT_EQUAL_128(0xbf8000023f0007ee, 0x40fffffffffffe04, q21);
20766
20767 TEARDOWN();
20768}
20769
20770
20771TEST(neon_fmulx_scalar) {
20772 SETUP();
20773
20774 START();
20775 __ Fmov(s0, 2.0);
20776 __ Fmov(s1, 0.5);
20777 __ Fmov(s2, 0.0);
20778 __ Fmov(s3, -0.0);
20779 __ Fmov(s4, kFP32PositiveInfinity);
20780 __ Fmov(s5, kFP32NegativeInfinity);
20781 __ Fmulx(s16, s0, s1);
20782 __ Fmulx(s17, s2, s4);
20783 __ Fmulx(s18, s2, s5);
20784 __ Fmulx(s19, s3, s4);
20785 __ Fmulx(s20, s3, s5);
20786
20787 __ Fmov(d21, 2.0);
20788 __ Fmov(d22, 0.5);
20789 __ Fmov(d23, 0.0);
20790 __ Fmov(d24, -0.0);
20791 __ Fmov(d25, kFP64PositiveInfinity);
20792 __ Fmov(d26, kFP64NegativeInfinity);
20793 __ Fmulx(d27, d21, d22);
20794 __ Fmulx(d28, d23, d25);
20795 __ Fmulx(d29, d23, d26);
20796 __ Fmulx(d30, d24, d25);
20797 __ Fmulx(d31, d24, d26);
20798 END();
20799
20800 RUN();
20801
20802 ASSERT_EQUAL_FP32(1.0, s16);
20803 ASSERT_EQUAL_FP32(2.0, s17);
20804 ASSERT_EQUAL_FP32(-2.0, s18);
20805 ASSERT_EQUAL_FP32(-2.0, s19);
20806 ASSERT_EQUAL_FP32(2.0, s20);
20807 ASSERT_EQUAL_FP64(1.0, d27);
20808 ASSERT_EQUAL_FP64(2.0, d28);
20809 ASSERT_EQUAL_FP64(-2.0, d29);
20810 ASSERT_EQUAL_FP64(-2.0, d30);
20811 ASSERT_EQUAL_FP64(2.0, d31);
20812
20813 TEARDOWN();
20814}
20815
20816
20817TEST(crc32b) {
20818 SETUP();
20819 START();
20820
20821 __ Mov(w0, 0);
20822 __ Mov(w1, 0);
20823 __ Crc32b(w10, w0, w1);
20824
20825 __ Mov(w0, 0x1);
20826 __ Mov(w1, 0x138);
20827 __ Crc32b(w11, w0, w1);
20828
20829 __ Mov(w0, 0x1);
20830 __ Mov(w1, 0x38);
20831 __ Crc32b(w12, w0, w1);
20832
20833 __ Mov(w0, 0);
20834 __ Mov(w1, 128);
20835 __ Crc32b(w13, w0, w1);
20836
20837 __ Mov(w0, UINT32_MAX);
20838 __ Mov(w1, 255);
20839 __ Crc32b(w14, w0, w1);
20840
20841 __ Mov(w0, 0x00010001);
20842 __ Mov(w1, 0x10001000);
20843 __ Crc32b(w15, w0, w1);
20844
20845 END();
20846 RUN();
20847
20848 ASSERT_EQUAL_64(0x0, x10);
20849 ASSERT_EQUAL_64(0x5f058808, x11);
20850 ASSERT_EQUAL_64(0x5f058808, x12);
20851 ASSERT_EQUAL_64(0xedb88320, x13);
20852 ASSERT_EQUAL_64(0x00ffffff, x14);
20853 ASSERT_EQUAL_64(0x77073196, x15);
20854
20855 TEARDOWN();
20856}
20857
20858
20859TEST(crc32h) {
20860 SETUP();
20861 START();
20862
20863 __ Mov(w0, 0);
20864 __ Mov(w1, 0);
20865 __ Crc32h(w10, w0, w1);
20866
20867 __ Mov(w0, 0x1);
20868 __ Mov(w1, 0x10038);
20869 __ Crc32h(w11, w0, w1);
20870
20871 __ Mov(w0, 0x1);
20872 __ Mov(w1, 0x38);
20873 __ Crc32h(w12, w0, w1);
20874
20875 __ Mov(w0, 0);
20876 __ Mov(w1, 128);
20877 __ Crc32h(w13, w0, w1);
20878
20879 __ Mov(w0, UINT32_MAX);
20880 __ Mov(w1, 255);
20881 __ Crc32h(w14, w0, w1);
20882
20883 __ Mov(w0, 0x00010001);
20884 __ Mov(w1, 0x10001000);
20885 __ Crc32h(w15, w0, w1);
20886
20887 END();
20888 RUN();
20889
20890 ASSERT_EQUAL_64(0x0, x10);
20891 ASSERT_EQUAL_64(0x0e848dba, x11);
20892 ASSERT_EQUAL_64(0x0e848dba, x12);
20893 ASSERT_EQUAL_64(0x3b83984b, x13);
20894 ASSERT_EQUAL_64(0x2d021072, x14);
20895 ASSERT_EQUAL_64(0x04ac2124, x15);
20896
20897 TEARDOWN();
20898}
20899
20900
20901TEST(crc32w) {
20902 SETUP();
20903 START();
20904
20905 __ Mov(w0, 0);
20906 __ Mov(w1, 0);
20907 __ Crc32w(w10, w0, w1);
20908
20909 __ Mov(w0, 0x1);
20910 __ Mov(w1, 0x80000031);
20911 __ Crc32w(w11, w0, w1);
20912
20913 __ Mov(w0, 0);
20914 __ Mov(w1, 128);
20915 __ Crc32w(w13, w0, w1);
20916
20917 __ Mov(w0, UINT32_MAX);
20918 __ Mov(w1, 255);
20919 __ Crc32w(w14, w0, w1);
20920
20921 __ Mov(w0, 0x00010001);
20922 __ Mov(w1, 0x10001000);
20923 __ Crc32w(w15, w0, w1);
20924
20925 END();
20926 RUN();
20927
20928 ASSERT_EQUAL_64(0x0, x10);
20929 ASSERT_EQUAL_64(0x1d937b81, x11);
20930 ASSERT_EQUAL_64(0xed59b63b, x13);
20931 ASSERT_EQUAL_64(0x00be2612, x14);
20932 ASSERT_EQUAL_64(0xa036e530, x15);
20933
20934 TEARDOWN();
20935}
20936
20937
20938TEST(crc32x) {
20939 SETUP();
20940 START();
20941
20942 __ Mov(w0, 0);
20943 __ Mov(x1, 0);
20944 __ Crc32x(w10, w0, x1);
20945
20946 __ Mov(w0, 0x1);
20947 __ Mov(x1, UINT64_C(0x0000000800000031));
20948 __ Crc32x(w11, w0, x1);
20949
20950 __ Mov(w0, 0);
20951 __ Mov(x1, 128);
20952 __ Crc32x(w13, w0, x1);
20953
20954 __ Mov(w0, UINT32_MAX);
20955 __ Mov(x1, 255);
20956 __ Crc32x(w14, w0, x1);
20957
20958 __ Mov(w0, 0x00010001);
20959 __ Mov(x1, UINT64_C(0x1000100000000000));
20960 __ Crc32x(w15, w0, x1);
20961
20962 END();
20963 RUN();
20964
20965 ASSERT_EQUAL_64(0x0, x10);
20966 ASSERT_EQUAL_64(0x40797b92, x11);
20967 ASSERT_EQUAL_64(0x533b85da, x13);
20968 ASSERT_EQUAL_64(0xbc962670, x14);
20969 ASSERT_EQUAL_64(0x0667602f, x15);
20970
20971 TEARDOWN();
20972}
20973
20974
20975TEST(crc32cb) {
20976 SETUP();
20977 START();
20978
20979 __ Mov(w0, 0);
20980 __ Mov(w1, 0);
20981 __ Crc32cb(w10, w0, w1);
20982
20983 __ Mov(w0, 0x1);
20984 __ Mov(w1, 0x138);
20985 __ Crc32cb(w11, w0, w1);
20986
20987 __ Mov(w0, 0x1);
20988 __ Mov(w1, 0x38);
20989 __ Crc32cb(w12, w0, w1);
20990
20991 __ Mov(w0, 0);
20992 __ Mov(w1, 128);
20993 __ Crc32cb(w13, w0, w1);
20994
20995 __ Mov(w0, UINT32_MAX);
20996 __ Mov(w1, 255);
20997 __ Crc32cb(w14, w0, w1);
20998
20999 __ Mov(w0, 0x00010001);
21000 __ Mov(w1, 0x10001000);
21001 __ Crc32cb(w15, w0, w1);
21002
21003 END();
21004 RUN();
21005
21006 ASSERT_EQUAL_64(0x0, x10);
21007 ASSERT_EQUAL_64(0x4851927d, x11);
21008 ASSERT_EQUAL_64(0x4851927d, x12);
21009 ASSERT_EQUAL_64(0x82f63b78, x13);
21010 ASSERT_EQUAL_64(0x00ffffff, x14);
21011 ASSERT_EQUAL_64(0xf26b8203, x15);
21012
21013 TEARDOWN();
21014}
21015
21016
21017TEST(crc32ch) {
21018 SETUP();
21019 START();
21020
21021 __ Mov(w0, 0);
21022 __ Mov(w1, 0);
21023 __ Crc32ch(w10, w0, w1);
21024
21025 __ Mov(w0, 0x1);
21026 __ Mov(w1, 0x10038);
21027 __ Crc32ch(w11, w0, w1);
21028
21029 __ Mov(w0, 0x1);
21030 __ Mov(w1, 0x38);
21031 __ Crc32ch(w12, w0, w1);
21032
21033 __ Mov(w0, 0);
21034 __ Mov(w1, 128);
21035 __ Crc32ch(w13, w0, w1);
21036
21037 __ Mov(w0, UINT32_MAX);
21038 __ Mov(w1, 255);
21039 __ Crc32ch(w14, w0, w1);
21040
21041 __ Mov(w0, 0x00010001);
21042 __ Mov(w1, 0x10001000);
21043 __ Crc32ch(w15, w0, w1);
21044
21045 END();
21046 RUN();
21047
21048 ASSERT_EQUAL_64(0x0, x10);
21049 ASSERT_EQUAL_64(0xcef8494c, x11);
21050 ASSERT_EQUAL_64(0xcef8494c, x12);
21051 ASSERT_EQUAL_64(0xfbc3faf9, x13);
21052 ASSERT_EQUAL_64(0xad7dacae, x14);
21053 ASSERT_EQUAL_64(0x03fc5f19, x15);
21054
21055 TEARDOWN();
21056}
21057
21058
21059TEST(crc32cw) {
21060 SETUP();
21061 START();
21062
21063 __ Mov(w0, 0);
21064 __ Mov(w1, 0);
21065 __ Crc32cw(w10, w0, w1);
21066
21067 __ Mov(w0, 0x1);
21068 __ Mov(w1, 0x80000031);
21069 __ Crc32cw(w11, w0, w1);
21070
21071 __ Mov(w0, 0);
21072 __ Mov(w1, 128);
21073 __ Crc32cw(w13, w0, w1);
21074
21075 __ Mov(w0, UINT32_MAX);
21076 __ Mov(w1, 255);
21077 __ Crc32cw(w14, w0, w1);
21078
21079 __ Mov(w0, 0x00010001);
21080 __ Mov(w1, 0x10001000);
21081 __ Crc32cw(w15, w0, w1);
21082
21083 END();
21084 RUN();
21085
21086 ASSERT_EQUAL_64(0x0, x10);
21087 ASSERT_EQUAL_64(0xbcb79ece, x11);
21088 ASSERT_EQUAL_64(0x52a0c93f, x13);
21089 ASSERT_EQUAL_64(0x9f9b5c7a, x14);
21090 ASSERT_EQUAL_64(0xae1b882a, x15);
21091
21092 TEARDOWN();
21093}
21094
21095
21096TEST(crc32cx) {
21097 SETUP();
21098 START();
21099
21100 __ Mov(w0, 0);
21101 __ Mov(x1, 0);
21102 __ Crc32cx(w10, w0, x1);
21103
21104 __ Mov(w0, 0x1);
21105 __ Mov(x1, UINT64_C(0x0000000800000031));
21106 __ Crc32cx(w11, w0, x1);
21107
21108 __ Mov(w0, 0);
21109 __ Mov(x1, 128);
21110 __ Crc32cx(w13, w0, x1);
21111
21112 __ Mov(w0, UINT32_MAX);
21113 __ Mov(x1, 255);
21114 __ Crc32cx(w14, w0, x1);
21115
21116 __ Mov(w0, 0x00010001);
21117 __ Mov(x1, UINT64_C(0x1000100000000000));
21118 __ Crc32cx(w15, w0, x1);
21119
21120 END();
21121 RUN();
21122
21123 ASSERT_EQUAL_64(0x0, x10);
21124 ASSERT_EQUAL_64(0x7f320fcb, x11);
21125 ASSERT_EQUAL_64(0x34019664, x13);
21126 ASSERT_EQUAL_64(0x6cc27dd0, x14);
21127 ASSERT_EQUAL_64(0xc6f0acdb, x15);
21128
21129 TEARDOWN();
21130}
21131
21132
21133TEST(neon_fabd_scalar) {
21134 SETUP();
21135
21136 START();
21137 __ Fmov(s0, 2.0);
21138 __ Fmov(s1, 0.5);
21139 __ Fmov(s2, 0.0);
21140 __ Fmov(s3, -0.0);
21141 __ Fmov(s4, kFP32PositiveInfinity);
21142 __ Fmov(s5, kFP32NegativeInfinity);
21143 __ Fabd(s16, s1, s0);
21144 __ Fabd(s17, s2, s3);
21145 __ Fabd(s18, s2, s5);
21146 __ Fabd(s19, s3, s4);
21147 __ Fabd(s20, s3, s5);
21148
21149 __ Fmov(d21, 2.0);
21150 __ Fmov(d22, 0.5);
21151 __ Fmov(d23, 0.0);
21152 __ Fmov(d24, -0.0);
21153 __ Fmov(d25, kFP64PositiveInfinity);
21154 __ Fmov(d26, kFP64NegativeInfinity);
21155 __ Fabd(d27, d21, d22);
21156 __ Fabd(d28, d23, d24);
21157 __ Fabd(d29, d23, d26);
21158 __ Fabd(d30, d24, d25);
21159 __ Fabd(d31, d24, d26);
21160 END();
21161
21162 RUN();
21163
21164 ASSERT_EQUAL_FP32(1.5, s16);
21165 ASSERT_EQUAL_FP32(0.0, s17);
21166 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s18);
21167 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s19);
21168 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s20);
21169 ASSERT_EQUAL_FP64(1.5, d27);
21170 ASSERT_EQUAL_FP64(0.0, d28);
21171 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d29);
21172 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d30);
21173 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d31);
21174
21175 TEARDOWN();
21176}
21177
21178
21179TEST(neon_faddp_scalar) {
21180 SETUP();
21181
21182 START();
21183 __ Movi(d0, 0x3f80000040000000);
21184 __ Movi(d1, 0xff8000007f800000);
21185 __ Movi(d2, 0x0000000080000000);
21186 __ Faddp(s0, v0.V2S());
21187 __ Faddp(s1, v1.V2S());
21188 __ Faddp(s2, v2.V2S());
21189
21190 __ Movi(v3.V2D(), 0xc000000000000000, 0x4000000000000000);
21191 __ Movi(v4.V2D(), 0xfff8000000000000, 0x7ff8000000000000);
21192 __ Movi(v5.V2D(), 0x0000000000000000, 0x8000000000000000);
21193 __ Faddp(d3, v3.V2D());
21194 __ Faddp(d4, v4.V2D());
21195 __ Faddp(d5, v5.V2D());
21196 END();
21197
21198 RUN();
21199
21200 ASSERT_EQUAL_FP32(3.0, s0);
21201 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s1);
21202 ASSERT_EQUAL_FP32(0.0, s2);
21203 ASSERT_EQUAL_FP64(0.0, d3);
21204 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d4);
21205 ASSERT_EQUAL_FP64(0.0, d5);
21206
21207 TEARDOWN();
21208}
21209
21210
21211TEST(neon_fmaxp_scalar) {
21212 SETUP();
21213
21214 START();
21215 __ Movi(d0, 0x3f80000040000000);
21216 __ Movi(d1, 0xff8000007f800000);
21217 __ Movi(d2, 0x7fc00000ff800000);
21218 __ Fmaxp(s0, v0.V2S());
21219 __ Fmaxp(s1, v1.V2S());
21220 __ Fmaxp(s2, v2.V2S());
21221
21222 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
21223 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
21224 __ Movi(v5.V2D(), 0x7ff0000000000000, 0x7ff8000000000000);
21225 __ Fmaxp(d3, v3.V2D());
21226 __ Fmaxp(d4, v4.V2D());
21227 __ Fmaxp(d5, v5.V2D());
21228 END();
21229
21230 RUN();
21231
21232 ASSERT_EQUAL_FP32(2.0, s0);
21233 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s1);
21234 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s2);
21235 ASSERT_EQUAL_FP64(2.0, d3);
21236 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d4);
21237 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d5);
21238
21239 TEARDOWN();
21240}
21241
21242
21243TEST(neon_fmaxnmp_scalar) {
21244 SETUP();
21245
21246 START();
21247 __ Movi(d0, 0x3f80000040000000);
21248 __ Movi(d1, 0xff8000007f800000);
21249 __ Movi(d2, 0x7fc00000ff800000);
21250 __ Fmaxnmp(s0, v0.V2S());
21251 __ Fmaxnmp(s1, v1.V2S());
21252 __ Fmaxnmp(s2, v2.V2S());
21253
21254 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
21255 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
21256 __ Movi(v5.V2D(), 0x7ff8000000000000, 0xfff0000000000000);
21257 __ Fmaxnmp(d3, v3.V2D());
21258 __ Fmaxnmp(d4, v4.V2D());
21259 __ Fmaxnmp(d5, v5.V2D());
21260 END();
21261
21262 RUN();
21263
21264 ASSERT_EQUAL_FP32(2.0, s0);
21265 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s1);
21266 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s2);
21267 ASSERT_EQUAL_FP64(2.0, d3);
21268 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d4);
21269 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d5);
21270
21271 TEARDOWN();
21272}
21273
21274
21275TEST(neon_fminp_scalar) {
21276 SETUP();
21277
21278 START();
21279 __ Movi(d0, 0x3f80000040000000);
21280 __ Movi(d1, 0xff8000007f800000);
21281 __ Movi(d2, 0x7fc00000ff800000);
21282 __ Fminp(s0, v0.V2S());
21283 __ Fminp(s1, v1.V2S());
21284 __ Fminp(s2, v2.V2S());
21285
21286 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
21287 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
21288 __ Movi(v5.V2D(), 0x7ff0000000000000, 0x7ff8000000000000);
21289 __ Fminp(d3, v3.V2D());
21290 __ Fminp(d4, v4.V2D());
21291 __ Fminp(d5, v5.V2D());
21292 END();
21293
21294 RUN();
21295
21296 ASSERT_EQUAL_FP32(1.0, s0);
21297 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s1);
21298 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s2);
21299 ASSERT_EQUAL_FP64(1.0, d3);
21300 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d4);
21301 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d5);
21302
21303 TEARDOWN();
21304}
21305
21306
21307TEST(neon_fminnmp_scalar) {
21308 SETUP();
21309
21310 START();
21311 __ Movi(d0, 0x3f80000040000000);
21312 __ Movi(d1, 0xff8000007f800000);
21313 __ Movi(d2, 0x7fc00000ff800000);
21314 __ Fminnmp(s0, v0.V2S());
21315 __ Fminnmp(s1, v1.V2S());
21316 __ Fminnmp(s2, v2.V2S());
21317
21318 __ Movi(v3.V2D(), 0x3ff0000000000000, 0x4000000000000000);
21319 __ Movi(v4.V2D(), 0xfff0000000000000, 0x7ff0000000000000);
21320 __ Movi(v5.V2D(), 0x7ff8000000000000, 0xfff0000000000000);
21321 __ Fminnmp(d3, v3.V2D());
21322 __ Fminnmp(d4, v4.V2D());
21323 __ Fminnmp(d5, v5.V2D());
21324 END();
21325
21326 RUN();
21327
21328 ASSERT_EQUAL_FP32(1.0, s0);
21329 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s1);
21330 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s2);
21331 ASSERT_EQUAL_FP64(1.0, d3);
21332 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d4);
21333 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d5);
21334
21335 TEARDOWN();
21336}
21337
21338
21339TEST(neon_tbl) {
21340 SETUP();
21341
21342 START();
21343 __ Movi(v30.V2D(), 0xbf561e188b1280e9, 0xbd542b8cbd24e8e8);
21344 __ Movi(v31.V2D(), 0xb5e9883d2c88a46d, 0x12276d5b614c915e);
21345 __ Movi(v0.V2D(), 0xc45b7782bc5ecd72, 0x5dd4fe5a4bc6bf5e);
21346 __ Movi(v1.V2D(), 0x1e3254094bd1746a, 0xf099ecf50e861c80);
21347
21348 __ Movi(v4.V2D(), 0xf80c030100031f16, 0x00070504031201ff);
21349 __ Movi(v5.V2D(), 0x1f01001afc14202a, 0x2a081e1b0c02020c);
21350 __ Movi(v6.V2D(), 0x353f1a13022a2360, 0x2c464a00203a0a33);
21351 __ Movi(v7.V2D(), 0x64801a1c054cf30d, 0x793a2c052e213739);
21352
21353 __ Movi(v8.V2D(), 0xb7f60ad7d7d88f13, 0x13eefc240496e842);
21354 __ Movi(v9.V2D(), 0x1be199c7c69b47ec, 0x8e4b9919f6eed443);
21355 __ Movi(v10.V2D(), 0x9bd2e1654c69e48f, 0x2143d089e426c6d2);
21356 __ Movi(v11.V2D(), 0xc31dbdc4a0393065, 0x1ecc2077caaf64d8);
21357 __ Movi(v12.V2D(), 0x29b24463967bc6eb, 0xdaf59970df01c93b);
21358 __ Movi(v13.V2D(), 0x3e20a4a4cb6813f4, 0x20a5832713dae669);
21359 __ Movi(v14.V2D(), 0xc5ff9a94041b1fdf, 0x2f46cde38cba2682);
21360 __ Movi(v15.V2D(), 0xd8cc5b0e61f387e6, 0xe69d6d314971e8fd);
21361
21362 __ Tbl(v8.V16B(), v1.V16B(), v4.V16B());
21363 __ Tbl(v9.V16B(), v0.V16B(), v1.V16B(), v5.V16B());
21364 __ Tbl(v10.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V16B());
21365 __ Tbl(v11.V16B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V16B());
21366 __ Tbl(v12.V8B(), v1.V16B(), v4.V8B());
21367 __ Tbl(v13.V8B(), v0.V16B(), v1.V16B(), v5.V8B());
21368 __ Tbl(v14.V8B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V8B());
21369 __ Tbl(v15.V8B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V8B());
21370
21371 __ Movi(v16.V2D(), 0xb7f60ad7d7d88f13, 0x13eefc240496e842);
21372 __ Movi(v17.V2D(), 0x1be199c7c69b47ec, 0x8e4b9919f6eed443);
21373 __ Movi(v18.V2D(), 0x9bd2e1654c69e48f, 0x2143d089e426c6d2);
21374 __ Movi(v19.V2D(), 0xc31dbdc4a0393065, 0x1ecc2077caaf64d8);
21375 __ Movi(v20.V2D(), 0x29b24463967bc6eb, 0xdaf59970df01c93b);
21376 __ Movi(v21.V2D(), 0x3e20a4a4cb6813f4, 0x20a5832713dae669);
21377 __ Movi(v22.V2D(), 0xc5ff9a94041b1fdf, 0x2f46cde38cba2682);
21378 __ Movi(v23.V2D(), 0xd8cc5b0e61f387e6, 0xe69d6d314971e8fd);
21379
21380 __ Tbx(v16.V16B(), v1.V16B(), v4.V16B());
21381 __ Tbx(v17.V16B(), v0.V16B(), v1.V16B(), v5.V16B());
21382 __ Tbx(v18.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V16B());
21383 __ Tbx(v19.V16B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V16B());
21384 __ Tbx(v20.V8B(), v1.V16B(), v4.V8B());
21385 __ Tbx(v21.V8B(), v0.V16B(), v1.V16B(), v5.V8B());
21386 __ Tbx(v22.V8B(), v31.V16B(), v0.V16B(), v1.V16B(), v6.V8B());
21387 __ Tbx(v23.V8B(), v30.V16B(), v31.V16B(), v0.V16B(), v1.V16B(), v7.V8B());
21388 END();
21389
21390 RUN();
21391
21392 ASSERT_EQUAL_128(0x00090e1c800e0000, 0x80f0ecf50e001c00, v8);
21393 ASSERT_EQUAL_128(0x1ebf5ed100f50000, 0x0072324b82c6c682, v9);
21394 ASSERT_EQUAL_128(0x00005e4b4cd10e00, 0x0900005e80008800, v10);
21395 ASSERT_EQUAL_128(0x0000883d2b00001e, 0x00d1822b5bbff074, v11);
21396 ASSERT_EQUAL_128(0x0000000000000000, 0x80f0ecf50e001c00, v12);
21397 ASSERT_EQUAL_128(0x0000000000000000, 0x0072324b82c6c682, v13);
21398 ASSERT_EQUAL_128(0x0000000000000000, 0x0900005e80008800, v14);
21399 ASSERT_EQUAL_128(0x0000000000000000, 0x00d1822b5bbff074, v15);
21400
21401 ASSERT_EQUAL_128(0xb7090e1c800e8f13, 0x80f0ecf50e961c42, v16);
21402 ASSERT_EQUAL_128(0x1ebf5ed1c6f547ec, 0x8e72324b82c6c682, v17);
21403 ASSERT_EQUAL_128(0x9bd25e4b4cd10e8f, 0x0943d05e802688d2, v18);
21404 ASSERT_EQUAL_128(0xc31d883d2b39301e, 0x1ed1822b5bbff074, v19);
21405 ASSERT_EQUAL_128(0x0000000000000000, 0x80f0ecf50e011c3b, v20);
21406 ASSERT_EQUAL_128(0x0000000000000000, 0x2072324b82c6c682, v21);
21407 ASSERT_EQUAL_128(0x0000000000000000, 0x0946cd5e80ba8882, v22);
21408 ASSERT_EQUAL_128(0x0000000000000000, 0xe6d1822b5bbff074, v23);
21409
21410 TEARDOWN();
21411}
21412
21413
21414TEST(regress_cmp_shift_imm) {
21415 SETUP();
21416
21417 START();
21418
21419 __ Mov(x0, 0x3d720c8d);
21420 __ Cmp(x0, Operand(0x3d720c8d));
21421
21422 END();
21423 RUN();
21424
21425 ASSERT_EQUAL_NZCV(ZCFlag);
21426
21427 TEARDOWN();
21428}
21429
21430
21431TEST(compute_address) {
21432 SETUP();
21433
21434 START();
21435 int64_t base_address = INT64_C(0x123000000abc);
21436 int64_t reg_offset = INT64_C(0x1087654321);
21437 Register base = x0;
21438 Register offset = x1;
21439
21440 __ Mov(base, base_address);
21441 __ Mov(offset, reg_offset);
21442
21443
21444 __ ComputeAddress(x2, MemOperand(base, 0));
21445 __ ComputeAddress(x3, MemOperand(base, 8));
21446 __ ComputeAddress(x4, MemOperand(base, -100));
21447
21448 __ ComputeAddress(x5, MemOperand(base, offset));
21449 __ ComputeAddress(x6, MemOperand(base, offset, LSL, 2));
21450 __ ComputeAddress(x7, MemOperand(base, offset, LSL, 4));
21451 __ ComputeAddress(x8, MemOperand(base, offset, LSL, 8));
21452
21453 __ ComputeAddress(x9, MemOperand(base, offset, SXTW));
21454 __ ComputeAddress(x10, MemOperand(base, offset, UXTW, 1));
21455 __ ComputeAddress(x11, MemOperand(base, offset, SXTW, 2));
21456 __ ComputeAddress(x12, MemOperand(base, offset, UXTW, 3));
21457
21458 END();
21459
21460 RUN();
21461
21462 ASSERT_EQUAL_64(base_address, base);
21463
21464 ASSERT_EQUAL_64(INT64_C(0x123000000abc), x2);
21465 ASSERT_EQUAL_64(INT64_C(0x123000000ac4), x3);
21466 ASSERT_EQUAL_64(INT64_C(0x123000000a58), x4);
21467
21468 ASSERT_EQUAL_64(INT64_C(0x124087654ddd), x5);
21469 ASSERT_EQUAL_64(INT64_C(0x12721d951740), x6);
21470 ASSERT_EQUAL_64(INT64_C(0x133876543ccc), x7);
21471 ASSERT_EQUAL_64(INT64_C(0x22b765432bbc), x8);
21472
21473 ASSERT_EQUAL_64(INT64_C(0x122f87654ddd), x9);
21474 ASSERT_EQUAL_64(INT64_C(0x12310eca90fe), x10);
21475 ASSERT_EQUAL_64(INT64_C(0x122e1d951740), x11);
21476 ASSERT_EQUAL_64(INT64_C(0x12343b2a23c4), x12);
21477
21478 TEARDOWN();
21479}
21480
21481
21482TEST(far_branch_backward) {
21483 // Test that the MacroAssembler correctly resolves backward branches to labels
21484 // that are outside the immediate range of branch instructions.
21485 // Take into account that backward branches can reach one instruction further
21486 // than forward branches.
21487 const int overflow_size = kInstructionSize +
21488 std::max(Instruction::ImmBranchForwardRange(TestBranchType),
21489 std::max(Instruction::ImmBranchForwardRange(CompareBranchType),
21490 Instruction::ImmBranchForwardRange(CondBranchType)));
21491
21492 SETUP();
21493 START();
21494
21495 Label done, fail;
21496 Label test_tbz, test_cbz, test_bcond;
21497 Label success_tbz, success_cbz, success_bcond;
21498
21499 __ Mov(x0, 0);
21500 __ Mov(x1, 1);
21501 __ Mov(x10, 0);
21502
21503 __ B(&test_tbz);
21504 __ Bind(&success_tbz);
21505 __ Orr(x0, x0, 1 << 0);
21506 __ B(&test_cbz);
21507 __ Bind(&success_cbz);
21508 __ Orr(x0, x0, 1 << 1);
21509 __ B(&test_bcond);
21510 __ Bind(&success_bcond);
21511 __ Orr(x0, x0, 1 << 2);
21512
21513 __ B(&done);
21514
21515 // Generate enough code to overflow the immediate range of the three types of
21516 // branches below.
21517 for (unsigned i = 0; i < overflow_size / kInstructionSize; ++i) {
21518 if (i % 100 == 0) {
21519 // If we do land in this code, we do not want to execute so many nops
21520 // before reaching the end of test (especially if tracing is activated).
21521 __ B(&fail);
21522 } else {
21523 __ Nop();
21524 }
21525 }
21526 __ B(&fail);
21527
21528 __ Bind(&test_tbz);
21529 __ Tbz(x10, 7, &success_tbz);
21530 __ Bind(&test_cbz);
21531 __ Cbz(x10, &success_cbz);
21532 __ Bind(&test_bcond);
21533 __ Cmp(x10, 0);
21534 __ B(eq, &success_bcond);
21535
21536 // For each out-of-range branch instructions, at least two instructions should
21537 // have been generated.
21538 VIXL_CHECK(masm.SizeOfCodeGeneratedSince(&test_tbz) >= 7 * kInstructionSize);
21539
21540 __ Bind(&fail);
21541 __ Mov(x1, 0);
21542 __ Bind(&done);
21543
21544 END();
21545 RUN();
21546
21547 ASSERT_EQUAL_64(0x7, x0);
21548 ASSERT_EQUAL_64(0x1, x1);
21549
21550 TEARDOWN();
21551}
21552
21553
21554TEST(single_veneer) {
21555 SETUP();
21556 START();
21557
21558 const int max_range = Instruction::ImmBranchForwardRange(TestBranchType);
21559
21560 Label success, fail, done;
21561
21562 __ Mov(x0, 0);
21563 __ Mov(x1, 1);
21564 __ Mov(x10, 0);
21565
21566 __ Tbz(x10, 7, &success);
21567
21568 // Generate enough code to overflow the immediate range of the `tbz`.
21569 for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
21570 if (i % 100 == 0) {
21571 // If we do land in this code, we do not want to execute so many nops
21572 // before reaching the end of test (especially if tracing is activated).
21573 __ B(&fail);
21574 } else {
21575 __ Nop();
21576 }
21577 }
21578 __ B(&fail);
21579
21580 __ Bind(&success);
21581 __ Mov(x0, 1);
21582
21583 __ B(&done);
21584 __ Bind(&fail);
21585 __ Mov(x1, 0);
21586 __ Bind(&done);
21587
21588 END();
21589 RUN();
21590
21591 ASSERT_EQUAL_64(1, x0);
21592 ASSERT_EQUAL_64(1, x1);
21593
21594 TEARDOWN();
21595}
21596
21597
21598TEST(simple_veneers) {
21599 // Test that the MacroAssembler correctly emits veneers for forward branches
21600 // to labels that are outside the immediate range of branch instructions.
21601 const int max_range =
21602 std::max(Instruction::ImmBranchForwardRange(TestBranchType),
21603 std::max(Instruction::ImmBranchForwardRange(CompareBranchType),
21604 Instruction::ImmBranchForwardRange(CondBranchType)));
21605
21606 SETUP();
21607 START();
21608
21609 Label done, fail;
21610 Label test_tbz, test_cbz, test_bcond;
21611 Label success_tbz, success_cbz, success_bcond;
21612
21613 __ Mov(x0, 0);
21614 __ Mov(x1, 1);
21615 __ Mov(x10, 0);
21616
21617 __ Bind(&test_tbz);
21618 __ Tbz(x10, 7, &success_tbz);
21619 __ Bind(&test_cbz);
21620 __ Cbz(x10, &success_cbz);
21621 __ Bind(&test_bcond);
21622 __ Cmp(x10, 0);
21623 __ B(eq, &success_bcond);
21624
21625 // Generate enough code to overflow the immediate range of the three types of
21626 // branches below.
21627 for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
21628 if (i % 100 == 0) {
21629 // If we do land in this code, we do not want to execute so many nops
21630 // before reaching the end of test (especially if tracing is activated).
21631 __ B(&fail);
21632 } else {
21633 __ Nop();
21634 }
21635 }
21636 __ B(&fail);
21637
21638 __ Bind(&success_tbz);
21639 __ Orr(x0, x0, 1 << 0);
21640 __ B(&test_cbz);
21641 __ Bind(&success_cbz);
21642 __ Orr(x0, x0, 1 << 1);
21643 __ B(&test_bcond);
21644 __ Bind(&success_bcond);
21645 __ Orr(x0, x0, 1 << 2);
21646
21647 __ B(&done);
21648 __ Bind(&fail);
21649 __ Mov(x1, 0);
21650 __ Bind(&done);
21651
21652 END();
21653 RUN();
21654
21655 ASSERT_EQUAL_64(0x7, x0);
21656 ASSERT_EQUAL_64(0x1, x1);
21657
21658 TEARDOWN();
21659}
21660
21661
21662TEST(veneers_stress) {
21663 SETUP();
21664 START();
21665
21666 // This is a code generation test stressing the emission of veneers. The code
21667 // generated is not executed.
21668
21669 Label target;
21670 const unsigned max_range = Instruction::ImmBranchForwardRange(CondBranchType);
21671 const unsigned iterations =
21672 (max_range + max_range / 4) / (4 * kInstructionSize);
21673 for (unsigned i = 0; i < iterations; i++) {
21674 __ B(&target);
21675 __ B(eq, &target);
21676 __ Cbz(x0, &target);
21677 __ Tbz(x0, 0, &target);
21678 }
21679 __ Bind(&target);
21680
21681 END();
21682 TEARDOWN();
21683}
21684
21685
21686TEST(veneers_two_out_of_range) {
21687 SETUP();
21688 START();
21689
21690 // This is a code generation test. The code generated is not executed.
21691 // Ensure that the MacroAssembler considers unresolved branches to chose when
21692 // a veneer pool should be emitted. We generate two branches that go out of
21693 // range at the same offset. When the MacroAssembler decides to emit the
21694 // veneer pool, the emission of a first veneer should not cause the other
21695 // branch to go out of range.
21696
21697 int range_cbz = Instruction::ImmBranchForwardRange(CompareBranchType);
21698 int range_tbz = Instruction::ImmBranchForwardRange(TestBranchType);
armvixldb644342015-07-21 11:37:10 +010021699 int max_target = static_cast<int>(masm.CursorOffset()) + range_cbz;
armvixl5289c592015-03-02 13:52:04 +000021700
21701 Label done;
21702
21703 // We use different labels to prevent the MacroAssembler from sharing veneers.
21704 Label target_cbz, target_tbz;
21705
21706 __ Cbz(x0, &target_cbz);
21707 while (masm.CursorOffset() < max_target - range_tbz) {
21708 __ Nop();
21709 }
21710 __ Tbz(x0, 0, &target_tbz);
21711 while (masm.CursorOffset() < max_target) {
21712 __ Nop();
21713 }
21714
21715 // This additional nop makes the branches go out of range.
21716 __ Nop();
21717
21718 __ Bind(&target_cbz);
21719 __ Bind(&target_tbz);
21720
21721 END();
21722 TEARDOWN();
21723}
21724
21725
21726TEST(veneers_hanging) {
21727 SETUP();
21728 START();
21729
21730 // This is a code generation test. The code generated is not executed.
21731 // Ensure that the MacroAssembler considers unresolved branches to chose when
21732 // a veneer pool should be emitted. This is similar to the
21733 // 'veneers_two_out_of_range' test. We try to trigger the following situation:
21734 // b.eq label
21735 // b.eq label
21736 // ...
21737 // nop
21738 // ...
21739 // cbz x0, label
21740 // cbz x0, label
21741 // ...
21742 // tbz x0, 0 label
21743 // nop
21744 // ...
21745 // nop <- From here the `b.eq` and `cbz` instructions run out of range,
21746 // so a literal pool is required.
21747 // veneer
21748 // veneer
21749 // veneer <- The `tbz` runs out of range somewhere in the middle of the
21750 // veneer veneer pool.
21751 // veneer
21752
21753 const int range_bcond = Instruction::ImmBranchForwardRange(CondBranchType);
21754 const int range_cbz = Instruction::ImmBranchForwardRange(CompareBranchType);
21755 const int range_tbz = Instruction::ImmBranchForwardRange(TestBranchType);
armvixldb644342015-07-21 11:37:10 +010021756 const int max_target = static_cast<int>(masm.CursorOffset()) + range_bcond;
armvixl5289c592015-03-02 13:52:04 +000021757
21758 Label done;
21759 const int n_bcond = 100;
21760 const int n_cbz = 100;
21761 const int n_tbz = 1;
21762 const int kNTotalBranches = n_bcond + n_cbz + n_tbz;
21763
21764 // We use different labels to prevent the MacroAssembler from sharing veneers.
21765 Label labels[kNTotalBranches];
21766 for (int i = 0; i < kNTotalBranches; i++) {
21767 new(&labels[i]) Label();
21768 }
21769
21770 for (int i = 0; i < n_bcond; i++) {
21771 __ B(eq, &labels[i]);
21772 }
21773
21774 while (masm.CursorOffset() < max_target - range_cbz) {
21775 __ Nop();
21776 }
21777
21778 for (int i = 0; i < n_cbz; i++) {
21779 __ Cbz(x0, &labels[n_bcond + i]);
21780 }
21781
21782 // Ensure the 'tbz' will go out of range after some of the previously
21783 // generated branches.
21784 int margin = (n_bcond / 2) * kInstructionSize;
21785 while (masm.CursorOffset() < max_target - range_tbz + margin) {
21786 __ Nop();
21787 }
21788
21789 __ Tbz(x0, 0, &labels[n_bcond + n_cbz]);
21790
21791 while (masm.CursorOffset() < max_target) {
21792 __ Nop();
21793 }
21794
21795 // This additional nop makes the 'b.eq' and 'cbz' instructions go out of range
21796 // and forces the emission of a veneer pool. The 'tbz' is not yet out of
21797 // range, but will go out of range while veneers are emitted for the other
21798 // branches.
21799 // The MacroAssembler should ensure that veneers are correctly emitted for all
21800 // the branches, including the 'tbz'. Checks will fail if the target of a
21801 // branch is out of range.
21802 __ Nop();
21803
21804 for (int i = 0; i < kNTotalBranches; i++) {
21805 __ Bind(&labels[i]);
21806 }
21807
21808 END();
21809 TEARDOWN();
21810}
21811
21812
21813TEST(collision_literal_veneer_pools) {
21814 SETUP();
21815 START();
21816
21817 // This is a code generation test. The code generated is not executed.
21818
21819 // Make sure the literal pool is empty;
21820 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21821 ASSERT_LITERAL_POOL_SIZE(0);
21822
21823 // We chose the offsets below to (try to) trigger the following situation:
21824 // buffer offset
21825 // 0: tbz x0, 0, target_tbz ----------------------------------.
21826 // 4: nop |
21827 // ... |
21828 // nop |
21829 // literal gen: ldr s0, [pc + ...] ; load from `pool start + 0` |
21830 // ldr s0, [pc + ...] ; load from `pool start + 4` |
21831 // ... |
21832 // ldr s0, [pc + ...] |
21833 // pool start: floating-point literal (0.1) |
21834 // floating-point literal (1.1) |
21835 // ... |
21836 // floating-point literal (<n>.1) <-----tbz-max-range--'
21837 // floating-point literal (<n+1>.1)
21838 // ...
21839
21840 const int range_tbz = Instruction::ImmBranchForwardRange(TestBranchType);
armvixldb644342015-07-21 11:37:10 +010021841 const int max_target = static_cast<int>(masm.CursorOffset()) + range_tbz;
armvixl5289c592015-03-02 13:52:04 +000021842
21843 const size_t target_literal_pool_size = 100 * kInstructionSize;
21844 const int offset_start_literal_gen =
21845 target_literal_pool_size + target_literal_pool_size / 2;
21846
21847
21848 Label target_tbz;
21849
21850 __ Tbz(x0, 0, &target_tbz);
21851 VIXL_CHECK(masm.NumberOfPotentialVeneers() == 1);
21852 while (masm.CursorOffset() < max_target - offset_start_literal_gen) {
21853 __ Nop();
21854 }
21855 VIXL_CHECK(masm.NumberOfPotentialVeneers() == 1);
21856
21857 for (int i = 0; i < 100; i++) {
21858 // Use a different value to force one literal pool entry per iteration.
21859 __ Ldr(s0, i + 0.1);
21860 }
21861 VIXL_CHECK(masm.LiteralPoolSize() >= target_literal_pool_size);
21862
21863 // Force emission of a literal pool.
21864 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21865 ASSERT_LITERAL_POOL_SIZE(0);
21866
21867 // The branch should not have gone out of range during the emission of the
21868 // literal pool.
21869 __ Bind(&target_tbz);
21870
21871 VIXL_CHECK(masm.NumberOfPotentialVeneers() == 0);
21872
21873 END();
21874 TEARDOWN();
21875}
armvixldb644342015-07-21 11:37:10 +010021876
21877
21878TEST(ldr_literal_explicit) {
21879 SETUP();
21880
21881 START();
21882 Literal<int64_t> automatically_placed_literal(1, masm.GetLiteralPool());
21883 Literal<int64_t> manually_placed_literal(2);
21884 {
21885 CodeBufferCheckScope scope(&masm,
21886 kInstructionSize + sizeof(int64_t),
21887 CodeBufferCheckScope::kCheck,
21888 CodeBufferCheckScope::kExactSize);
21889 Label over_literal;
21890 __ b(&over_literal);
21891 __ place(&manually_placed_literal);
21892 __ bind(&over_literal);
21893 }
21894 __ Ldr(x1, &manually_placed_literal);
21895 __ Ldr(x2, &automatically_placed_literal);
21896 __ Add(x0, x1, x2);
21897 END();
21898
21899 RUN();
21900
21901 ASSERT_EQUAL_64(3, x0);
21902
21903 TEARDOWN();
21904}
21905
21906
21907TEST(ldr_literal_automatically_placed) {
21908 SETUP();
21909
21910 START();
21911
21912 // We start with an empty literal pool.
21913 ASSERT_LITERAL_POOL_SIZE(0);
21914
21915 // Create a literal that should be placed by the literal pool.
21916 Literal<int64_t> explicit_literal(2, masm.GetLiteralPool());
21917 // It should not appear in the literal pool until its first use.
21918 ASSERT_LITERAL_POOL_SIZE(0);
21919
21920 // Check that using standard literals does not break the use of explicitly
21921 // created literals.
21922 __ Ldr(d1, 1.1);
21923 ASSERT_LITERAL_POOL_SIZE(8);
21924 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21925 ASSERT_LITERAL_POOL_SIZE(0);
21926
21927 __ Ldr(x2, &explicit_literal);
21928 ASSERT_LITERAL_POOL_SIZE(8);
21929 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21930 ASSERT_LITERAL_POOL_SIZE(0);
21931
21932 __ Ldr(d3, 3.3);
21933 ASSERT_LITERAL_POOL_SIZE(8);
21934 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21935 ASSERT_LITERAL_POOL_SIZE(0);
21936
21937 // Re-use our explicitly created literal. It has already been placed, so it
21938 // should not impact the literal pool.
21939 __ Ldr(x4, &explicit_literal);
21940 ASSERT_LITERAL_POOL_SIZE(0);
21941
21942 END();
21943
21944 RUN();
21945
21946 ASSERT_EQUAL_FP64(1.1, d1);
21947 ASSERT_EQUAL_64(2, x2);
21948 ASSERT_EQUAL_FP64(3.3, d3);
21949 ASSERT_EQUAL_64(2, x4);
21950
21951 TEARDOWN();
21952}
21953
21954
21955TEST(literal_update_overwrite) {
21956 SETUP();
21957
21958 START();
21959
21960 ASSERT_LITERAL_POOL_SIZE(0);
21961 LiteralPool* literal_pool = masm.GetLiteralPool();
21962
21963 Literal<int32_t> lit_32_update_before_pool(0xbad, literal_pool);
21964 Literal<int32_t> lit_32_update_after_pool(0xbad, literal_pool);
21965 Literal<int64_t> lit_64_update_before_pool(0xbad, literal_pool);
21966 Literal<int64_t> lit_64_update_after_pool(0xbad, literal_pool);
21967
21968 ASSERT_LITERAL_POOL_SIZE(0);
21969
21970 lit_32_update_before_pool.UpdateValue(32);
21971 lit_64_update_before_pool.UpdateValue(64);
21972
21973 __ Ldr(w1, &lit_32_update_before_pool);
21974 __ Ldr(x2, &lit_64_update_before_pool);
21975 __ Ldr(w3, &lit_32_update_after_pool);
21976 __ Ldr(x4, &lit_64_update_after_pool);
21977
21978 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
21979
21980 VIXL_ASSERT(lit_32_update_after_pool.IsPlaced());
21981 VIXL_ASSERT(lit_64_update_after_pool.IsPlaced());
21982 lit_32_update_after_pool.UpdateValue(128, &masm);
21983 lit_64_update_after_pool.UpdateValue(256, &masm);
21984
21985 END();
21986
21987 RUN();
21988
21989 ASSERT_EQUAL_64(32, x1);
21990 ASSERT_EQUAL_64(64, x2);
21991 ASSERT_EQUAL_64(128, x3);
21992 ASSERT_EQUAL_64(256, x4);
21993
21994 TEARDOWN();
21995}
21996
21997
21998TEST(literal_deletion_policies) {
21999 SETUP();
22000
22001 START();
22002
22003 // We cannot check exactly when the deletion of the literals occur, but we
22004 // check that usage of the deletion policies is not broken.
22005
22006 ASSERT_LITERAL_POOL_SIZE(0);
22007 LiteralPool* literal_pool = masm.GetLiteralPool();
22008
22009 Literal<int32_t> lit_manual(0xbad, literal_pool);
22010 Literal<int32_t>* lit_deleted_on_placement =
22011 new Literal<int32_t>(0xbad,
22012 literal_pool,
22013 RawLiteral::kDeletedOnPlacementByPool);
22014 Literal<int32_t>* lit_deleted_on_pool_destruction =
22015 new Literal<int32_t>(0xbad,
22016 literal_pool,
22017 RawLiteral::kDeletedOnPoolDestruction);
22018
22019 ASSERT_LITERAL_POOL_SIZE(0);
22020
22021 lit_manual.UpdateValue(32);
22022 lit_deleted_on_placement->UpdateValue(64);
22023
22024 __ Ldr(w1, &lit_manual);
22025 __ Ldr(w2, lit_deleted_on_placement);
22026 __ Ldr(w3, lit_deleted_on_pool_destruction);
22027
22028 masm.EmitLiteralPool(LiteralPool::kBranchRequired);
22029
22030 VIXL_ASSERT(lit_manual.IsPlaced());
armvixldb644342015-07-21 11:37:10 +010022031 VIXL_ASSERT(lit_deleted_on_pool_destruction->IsPlaced());
22032 lit_deleted_on_pool_destruction->UpdateValue(128, &masm);
22033
22034 END();
22035
22036 RUN();
22037
22038 ASSERT_EQUAL_64(32, x1);
22039 ASSERT_EQUAL_64(64, x2);
22040 ASSERT_EQUAL_64(128, x3);
22041
22042 TEARDOWN();
22043}
22044
22045
armvixl0f35e362016-05-10 13:57:58 +010022046TEST(move_immediate_helpers) {
22047 // Using these helpers to query information (without generating code) should
22048 // not crash.
22049 MacroAssembler::MoveImmediateHelper(NULL, x0, 0x12345678);
22050 MacroAssembler::OneInstrMoveImmediateHelper(NULL, x1, 0xabcdef);
22051}
22052
22053
armvixlad96eda2013-06-14 11:42:37 +010022054} // namespace vixl