blob: bc59e99d171497c3c2c895696370c5ed10002dcc [file] [log] [blame]
armvixlad96eda2013-06-14 11:42:37 +01001// Copyright 2013, ARM Limited
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7// * Redistributions of source code must retain the above copyright notice,
8// this list of conditions and the following disclaimer.
9// * Redistributions in binary form must reproduce the above copyright notice,
10// this list of conditions and the following disclaimer in the documentation
11// and/or other materials provided with the distribution.
12// * Neither the name of ARM Limited nor the names of its contributors may be
13// used to endorse or promote products derived from this software without
14// specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27#include <stdio.h>
armvixlf37fdc02014-02-05 13:22:16 +000028#include <stdlib.h>
armvixlad96eda2013-06-14 11:42:37 +010029#include <string.h>
armvixl578645f2013-08-15 17:21:42 +010030#include <math.h>
31#include <float.h>
armvixlad96eda2013-06-14 11:42:37 +010032
33#include "cctest.h"
34#include "test-utils-a64.h"
35#include "a64/macro-assembler-a64.h"
36#include "a64/simulator-a64.h"
37#include "a64/debugger-a64.h"
38#include "a64/disasm-a64.h"
39#include "a64/cpu-a64.h"
40
41namespace vixl {
42
43// Test infrastructure.
44//
45// Tests are functions which accept no parameters and have no return values.
46// The testing code should not perform an explicit return once completed. For
47// example to test the mov immediate instruction a very simple test would be:
48//
49// TEST(mov_x0_one) {
50// SETUP();
51//
52// START();
53// __ mov(x0, Operand(1));
54// END();
55//
56// RUN();
57//
58// ASSERT_EQUAL_64(1, x0);
59//
60// TEARDOWN();
61// }
62//
63// Within a START ... END block all registers but sp can be modified. sp has to
64// be explicitly saved/restored. The END() macro replaces the function return
65// so it may appear multiple times in a test if the test has multiple exit
66// points.
67//
68// Once the test has been run all integer and floating point registers as well
69// as flags are accessible through a RegisterDump instance, see
70// utils-a64.cc for more info on RegisterDump.
71//
72// We provide some helper assert to handle common cases:
73//
74// ASSERT_EQUAL_32(int32_t, int_32t)
75// ASSERT_EQUAL_FP32(float, float)
76// ASSERT_EQUAL_32(int32_t, W register)
77// ASSERT_EQUAL_FP32(float, S register)
78// ASSERT_EQUAL_64(int64_t, int_64t)
79// ASSERT_EQUAL_FP64(double, double)
80// ASSERT_EQUAL_64(int64_t, X register)
81// ASSERT_EQUAL_64(X register, X register)
82// ASSERT_EQUAL_FP64(double, D register)
83//
84// e.g. ASSERT_EQUAL_64(0.5, d30);
85//
armvixl578645f2013-08-15 17:21:42 +010086// If more advanced computation is required before the assert then access the
armvixlad96eda2013-06-14 11:42:37 +010087// RegisterDump named core directly:
88//
89// ASSERT_EQUAL_64(0x1234, core->reg_x0() & 0xffff);
90
91
92#define __ masm.
93#define TEST(name) TEST_(ASM_##name)
94
95#define BUF_SIZE (4096)
96
armvixl4a102ba2014-07-14 09:02:40 +010097#define SETUP() SETUP_CUSTOM(BUF_SIZE, PositionIndependentCode)
armvixlad96eda2013-06-14 11:42:37 +010098
99#ifdef USE_SIMULATOR
100
101// Run tests with the simulator.
armvixl4a102ba2014-07-14 09:02:40 +0100102#define SETUP_CUSTOM(buf_size, pic) \
armvixlad96eda2013-06-14 11:42:37 +0100103 byte* buf = new byte[buf_size]; \
armvixl4a102ba2014-07-14 09:02:40 +0100104 MacroAssembler masm(buf, buf_size, pic); \
armvixlad96eda2013-06-14 11:42:37 +0100105 Decoder decoder; \
106 Simulator* simulator = NULL; \
107 if (Cctest::run_debugger()) { \
108 simulator = new Debugger(&decoder); \
109 } else { \
110 simulator = new Simulator(&decoder); \
111 simulator->set_disasm_trace(Cctest::trace_sim()); \
112 } \
113 simulator->set_coloured_trace(Cctest::coloured_trace()); \
armvixl578645f2013-08-15 17:21:42 +0100114 simulator->set_instruction_stats(Cctest::instruction_stats()); \
armvixlad96eda2013-06-14 11:42:37 +0100115 RegisterDump core
116
117#define START() \
118 masm.Reset(); \
119 simulator->ResetState(); \
120 __ PushCalleeSavedRegisters(); \
121 if (Cctest::run_debugger()) { \
122 if (Cctest::trace_reg()) { \
123 __ Trace(LOG_STATE, TRACE_ENABLE); \
124 } \
125 if (Cctest::trace_sim()) { \
126 __ Trace(LOG_DISASM, TRACE_ENABLE); \
127 } \
armvixl578645f2013-08-15 17:21:42 +0100128 } \
129 if (Cctest::instruction_stats()) { \
130 __ EnableInstrumentation(); \
armvixlad96eda2013-06-14 11:42:37 +0100131 }
132
133#define END() \
armvixl578645f2013-08-15 17:21:42 +0100134 if (Cctest::instruction_stats()) { \
135 __ DisableInstrumentation(); \
136 } \
armvixlad96eda2013-06-14 11:42:37 +0100137 if (Cctest::run_debugger()) { \
138 __ Trace(LOG_ALL, TRACE_DISABLE); \
139 } \
140 core.Dump(&masm); \
141 __ PopCalleeSavedRegisters(); \
142 __ Ret(); \
143 masm.FinalizeCode()
144
145#define RUN() \
146 simulator->RunFrom(reinterpret_cast<Instruction*>(buf))
147
148#define TEARDOWN() \
149 delete simulator; \
150 delete[] buf;
151
152#else // ifdef USE_SIMULATOR.
153// Run the test on real hardware or models.
armvixl4a102ba2014-07-14 09:02:40 +0100154#define SETUP_CUSTOM(buf_size, pic) \
armvixlad96eda2013-06-14 11:42:37 +0100155 byte* buf = new byte[buf_size]; \
armvixl4a102ba2014-07-14 09:02:40 +0100156 MacroAssembler masm(buf, buf_size, pic); \
armvixlad96eda2013-06-14 11:42:37 +0100157 RegisterDump core; \
158 CPU::SetUp()
159
160#define START() \
161 masm.Reset(); \
162 __ PushCalleeSavedRegisters()
163
164#define END() \
165 core.Dump(&masm); \
166 __ PopCalleeSavedRegisters(); \
167 __ Ret(); \
168 masm.FinalizeCode()
169
170#define RUN() \
armvixl4a102ba2014-07-14 09:02:40 +0100171 CPU::EnsureIAndDCacheCoherency(buf, masm.SizeOfCodeGenerated()); \
armvixlad96eda2013-06-14 11:42:37 +0100172 { \
173 void (*test_function)(void); \
armvixlb0c8ae22014-03-21 14:03:59 +0000174 VIXL_ASSERT(sizeof(buf) == sizeof(test_function)); \
armvixlad96eda2013-06-14 11:42:37 +0100175 memcpy(&test_function, &buf, sizeof(buf)); \
176 test_function(); \
177 }
178
179#define TEARDOWN() \
180 delete[] buf;
181
182#endif // ifdef USE_SIMULATOR.
183
184#define ASSERT_EQUAL_NZCV(expected) \
185 assert(EqualNzcv(expected, core.flags_nzcv()))
186
187#define ASSERT_EQUAL_REGISTERS(expected) \
188 assert(EqualRegisters(&expected, &core))
189
190#define ASSERT_EQUAL_32(expected, result) \
191 assert(Equal32(static_cast<uint32_t>(expected), &core, result))
192
193#define ASSERT_EQUAL_FP32(expected, result) \
194 assert(EqualFP32(expected, &core, result))
195
196#define ASSERT_EQUAL_64(expected, result) \
197 assert(Equal64(expected, &core, result))
198
199#define ASSERT_EQUAL_FP64(expected, result) \
200 assert(EqualFP64(expected, &core, result))
201
202#define ASSERT_LITERAL_POOL_SIZE(expected) \
203 assert((expected) == (__ LiteralPoolSize()))
204
205
206TEST(stack_ops) {
207 SETUP();
208
209 START();
210 // save sp.
211 __ Mov(x29, sp);
212
213 // Set the sp to a known value.
214 __ Mov(sp, 0x1004);
215 __ Mov(x0, sp);
216
217 // Add immediate to the sp, and move the result to a normal register.
armvixlb0c8ae22014-03-21 14:03:59 +0000218 __ Add(sp, sp, 0x50);
armvixlad96eda2013-06-14 11:42:37 +0100219 __ Mov(x1, sp);
220
221 // Add extended to the sp, and move the result to a normal register.
222 __ Mov(x17, 0xfff);
223 __ Add(sp, sp, Operand(x17, SXTB));
224 __ Mov(x2, sp);
225
226 // Create an sp using a logical instruction, and move to normal register.
armvixlb0c8ae22014-03-21 14:03:59 +0000227 __ Orr(sp, xzr, 0x1fff);
armvixlad96eda2013-06-14 11:42:37 +0100228 __ Mov(x3, sp);
229
230 // Write wsp using a logical instruction.
armvixlb0c8ae22014-03-21 14:03:59 +0000231 __ Orr(wsp, wzr, 0xfffffff8);
armvixlad96eda2013-06-14 11:42:37 +0100232 __ Mov(x4, sp);
233
234 // Write sp, and read back wsp.
armvixlb0c8ae22014-03-21 14:03:59 +0000235 __ Orr(sp, xzr, 0xfffffff8);
armvixlad96eda2013-06-14 11:42:37 +0100236 __ Mov(w5, wsp);
237
238 // restore sp.
239 __ Mov(sp, x29);
240 END();
241
242 RUN();
243
244 ASSERT_EQUAL_64(0x1004, x0);
245 ASSERT_EQUAL_64(0x1054, x1);
246 ASSERT_EQUAL_64(0x1053, x2);
247 ASSERT_EQUAL_64(0x1fff, x3);
248 ASSERT_EQUAL_64(0xfffffff8, x4);
249 ASSERT_EQUAL_64(0xfffffff8, x5);
250
251 TEARDOWN();
252}
253
254
255TEST(mvn) {
256 SETUP();
257
258 START();
259 __ Mvn(w0, 0xfff);
260 __ Mvn(x1, 0xfff);
261 __ Mvn(w2, Operand(w0, LSL, 1));
262 __ Mvn(x3, Operand(x1, LSL, 2));
263 __ Mvn(w4, Operand(w0, LSR, 3));
264 __ Mvn(x5, Operand(x1, LSR, 4));
265 __ Mvn(w6, Operand(w0, ASR, 11));
266 __ Mvn(x7, Operand(x1, ASR, 12));
267 __ Mvn(w8, Operand(w0, ROR, 13));
268 __ Mvn(x9, Operand(x1, ROR, 14));
269 __ Mvn(w10, Operand(w2, UXTB));
270 __ Mvn(x11, Operand(x2, SXTB, 1));
271 __ Mvn(w12, Operand(w2, UXTH, 2));
272 __ Mvn(x13, Operand(x2, SXTH, 3));
273 __ Mvn(x14, Operand(w2, UXTW, 4));
274 __ Mvn(x15, Operand(w2, SXTW, 4));
275 END();
276
277 RUN();
278
279 ASSERT_EQUAL_64(0xfffff000, x0);
armvixlb0c8ae22014-03-21 14:03:59 +0000280 ASSERT_EQUAL_64(0xfffffffffffff000, x1);
armvixlad96eda2013-06-14 11:42:37 +0100281 ASSERT_EQUAL_64(0x00001fff, x2);
armvixlb0c8ae22014-03-21 14:03:59 +0000282 ASSERT_EQUAL_64(0x0000000000003fff, x3);
armvixlad96eda2013-06-14 11:42:37 +0100283 ASSERT_EQUAL_64(0xe00001ff, x4);
armvixlb0c8ae22014-03-21 14:03:59 +0000284 ASSERT_EQUAL_64(0xf0000000000000ff, x5);
armvixlad96eda2013-06-14 11:42:37 +0100285 ASSERT_EQUAL_64(0x00000001, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000286 ASSERT_EQUAL_64(0x0000000000000000, x7);
armvixlad96eda2013-06-14 11:42:37 +0100287 ASSERT_EQUAL_64(0x7ff80000, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000288 ASSERT_EQUAL_64(0x3ffc000000000000, x9);
armvixlad96eda2013-06-14 11:42:37 +0100289 ASSERT_EQUAL_64(0xffffff00, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000290 ASSERT_EQUAL_64(0x0000000000000001, x11);
armvixlad96eda2013-06-14 11:42:37 +0100291 ASSERT_EQUAL_64(0xffff8003, x12);
armvixlb0c8ae22014-03-21 14:03:59 +0000292 ASSERT_EQUAL_64(0xffffffffffff0007, x13);
293 ASSERT_EQUAL_64(0xfffffffffffe000f, x14);
294 ASSERT_EQUAL_64(0xfffffffffffe000f, x15);
armvixlad96eda2013-06-14 11:42:37 +0100295
296 TEARDOWN();
297}
298
299
armvixlf37fdc02014-02-05 13:22:16 +0000300TEST(mov_imm_w) {
301 SETUP();
302
303 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000304 __ Mov(w0, 0xffffffff);
305 __ Mov(w1, 0xffff1234);
306 __ Mov(w2, 0x1234ffff);
307 __ Mov(w3, 0x00000000);
308 __ Mov(w4, 0x00001234);
309 __ Mov(w5, 0x12340000);
310 __ Mov(w6, 0x12345678);
armvixl4a102ba2014-07-14 09:02:40 +0100311 __ Mov(w7, (int32_t)0x80000000);
312 __ Mov(w8, (int32_t)0xffff0000);
313 __ Mov(w9, kWMinInt);
armvixlf37fdc02014-02-05 13:22:16 +0000314 END();
315
316 RUN();
317
armvixlb0c8ae22014-03-21 14:03:59 +0000318 ASSERT_EQUAL_64(0xffffffff, x0);
319 ASSERT_EQUAL_64(0xffff1234, x1);
320 ASSERT_EQUAL_64(0x1234ffff, x2);
321 ASSERT_EQUAL_64(0x00000000, x3);
322 ASSERT_EQUAL_64(0x00001234, x4);
323 ASSERT_EQUAL_64(0x12340000, x5);
324 ASSERT_EQUAL_64(0x12345678, x6);
armvixl4a102ba2014-07-14 09:02:40 +0100325 ASSERT_EQUAL_64(0x80000000, x7);
326 ASSERT_EQUAL_64(0xffff0000, x8);
327 ASSERT_EQUAL_32(kWMinInt, w9);
armvixlf37fdc02014-02-05 13:22:16 +0000328
329 TEARDOWN();
330}
331
332
333TEST(mov_imm_x) {
334 SETUP();
335
336 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000337 __ Mov(x0, 0xffffffffffffffff);
338 __ Mov(x1, 0xffffffffffff1234);
339 __ Mov(x2, 0xffffffff12345678);
340 __ Mov(x3, 0xffff1234ffff5678);
341 __ Mov(x4, 0x1234ffffffff5678);
342 __ Mov(x5, 0x1234ffff5678ffff);
343 __ Mov(x6, 0x12345678ffffffff);
344 __ Mov(x7, 0x1234ffffffffffff);
345 __ Mov(x8, 0x123456789abcffff);
346 __ Mov(x9, 0x12345678ffff9abc);
347 __ Mov(x10, 0x1234ffff56789abc);
348 __ Mov(x11, 0xffff123456789abc);
349 __ Mov(x12, 0x0000000000000000);
350 __ Mov(x13, 0x0000000000001234);
351 __ Mov(x14, 0x0000000012345678);
352 __ Mov(x15, 0x0000123400005678);
353 __ Mov(x18, 0x1234000000005678);
354 __ Mov(x19, 0x1234000056780000);
355 __ Mov(x20, 0x1234567800000000);
356 __ Mov(x21, 0x1234000000000000);
357 __ Mov(x22, 0x123456789abc0000);
358 __ Mov(x23, 0x1234567800009abc);
359 __ Mov(x24, 0x1234000056789abc);
360 __ Mov(x25, 0x0000123456789abc);
361 __ Mov(x26, 0x123456789abcdef0);
362 __ Mov(x27, 0xffff000000000001);
363 __ Mov(x28, 0x8000ffff00000000);
armvixlf37fdc02014-02-05 13:22:16 +0000364 END();
365
366 RUN();
367
armvixlb0c8ae22014-03-21 14:03:59 +0000368 ASSERT_EQUAL_64(0xffffffffffff1234, x1);
369 ASSERT_EQUAL_64(0xffffffff12345678, x2);
370 ASSERT_EQUAL_64(0xffff1234ffff5678, x3);
371 ASSERT_EQUAL_64(0x1234ffffffff5678, x4);
372 ASSERT_EQUAL_64(0x1234ffff5678ffff, x5);
373 ASSERT_EQUAL_64(0x12345678ffffffff, x6);
374 ASSERT_EQUAL_64(0x1234ffffffffffff, x7);
375 ASSERT_EQUAL_64(0x123456789abcffff, x8);
376 ASSERT_EQUAL_64(0x12345678ffff9abc, x9);
377 ASSERT_EQUAL_64(0x1234ffff56789abc, x10);
378 ASSERT_EQUAL_64(0xffff123456789abc, x11);
379 ASSERT_EQUAL_64(0x0000000000000000, x12);
380 ASSERT_EQUAL_64(0x0000000000001234, x13);
381 ASSERT_EQUAL_64(0x0000000012345678, x14);
382 ASSERT_EQUAL_64(0x0000123400005678, x15);
383 ASSERT_EQUAL_64(0x1234000000005678, x18);
384 ASSERT_EQUAL_64(0x1234000056780000, x19);
385 ASSERT_EQUAL_64(0x1234567800000000, x20);
386 ASSERT_EQUAL_64(0x1234000000000000, x21);
387 ASSERT_EQUAL_64(0x123456789abc0000, x22);
388 ASSERT_EQUAL_64(0x1234567800009abc, x23);
389 ASSERT_EQUAL_64(0x1234000056789abc, x24);
390 ASSERT_EQUAL_64(0x0000123456789abc, x25);
391 ASSERT_EQUAL_64(0x123456789abcdef0, x26);
392 ASSERT_EQUAL_64(0xffff000000000001, x27);
393 ASSERT_EQUAL_64(0x8000ffff00000000, x28);
armvixlf37fdc02014-02-05 13:22:16 +0000394
395
396 TEARDOWN();
397}
398
399
armvixlad96eda2013-06-14 11:42:37 +0100400TEST(mov) {
401 SETUP();
402
403 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000404 __ Mov(x0, 0xffffffffffffffff);
405 __ Mov(x1, 0xffffffffffffffff);
406 __ Mov(x2, 0xffffffffffffffff);
407 __ Mov(x3, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +0100408
armvixlb0c8ae22014-03-21 14:03:59 +0000409 __ Mov(x0, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100410
armvixlb0c8ae22014-03-21 14:03:59 +0000411 __ movz(x1, UINT64_C(0xabcd) << 16);
412 __ movk(x2, UINT64_C(0xabcd) << 32);
413 __ movn(x3, UINT64_C(0xabcd) << 48);
armvixlad96eda2013-06-14 11:42:37 +0100414
armvixlb0c8ae22014-03-21 14:03:59 +0000415 __ Mov(x4, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100416 __ Mov(x5, x4);
417
418 __ Mov(w6, -1);
419
420 // Test that moves back to the same register have the desired effect. This
421 // is a no-op for X registers, and a truncation for W registers.
armvixlb0c8ae22014-03-21 14:03:59 +0000422 __ Mov(x7, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100423 __ Mov(x7, x7);
armvixlb0c8ae22014-03-21 14:03:59 +0000424 __ Mov(x8, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100425 __ Mov(w8, w8);
armvixlb0c8ae22014-03-21 14:03:59 +0000426 __ Mov(x9, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100427 __ Mov(x9, Operand(x9));
armvixlb0c8ae22014-03-21 14:03:59 +0000428 __ Mov(x10, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +0100429 __ Mov(w10, Operand(w10));
430
431 __ Mov(w11, 0xfff);
432 __ Mov(x12, 0xfff);
433 __ Mov(w13, Operand(w11, LSL, 1));
434 __ Mov(x14, Operand(x12, LSL, 2));
435 __ Mov(w15, Operand(w11, LSR, 3));
436 __ Mov(x18, Operand(x12, LSR, 4));
437 __ Mov(w19, Operand(w11, ASR, 11));
438 __ Mov(x20, Operand(x12, ASR, 12));
439 __ Mov(w21, Operand(w11, ROR, 13));
440 __ Mov(x22, Operand(x12, ROR, 14));
441 __ Mov(w23, Operand(w13, UXTB));
442 __ Mov(x24, Operand(x13, SXTB, 1));
443 __ Mov(w25, Operand(w13, UXTH, 2));
444 __ Mov(x26, Operand(x13, SXTH, 3));
445 __ Mov(x27, Operand(w13, UXTW, 4));
armvixlf37fdc02014-02-05 13:22:16 +0000446
armvixlb0c8ae22014-03-21 14:03:59 +0000447 __ Mov(x28, 0x0123456789abcdef);
armvixlf37fdc02014-02-05 13:22:16 +0000448 __ Mov(w28, w28, kDiscardForSameWReg);
armvixlad96eda2013-06-14 11:42:37 +0100449 END();
450
451 RUN();
452
armvixlb0c8ae22014-03-21 14:03:59 +0000453 ASSERT_EQUAL_64(0x0123456789abcdef, x0);
454 ASSERT_EQUAL_64(0x00000000abcd0000, x1);
455 ASSERT_EQUAL_64(0xffffabcdffffffff, x2);
456 ASSERT_EQUAL_64(0x5432ffffffffffff, x3);
armvixlad96eda2013-06-14 11:42:37 +0100457 ASSERT_EQUAL_64(x4, x5);
458 ASSERT_EQUAL_32(-1, w6);
armvixlb0c8ae22014-03-21 14:03:59 +0000459 ASSERT_EQUAL_64(0x0123456789abcdef, x7);
460 ASSERT_EQUAL_32(0x89abcdef, w8);
461 ASSERT_EQUAL_64(0x0123456789abcdef, x9);
462 ASSERT_EQUAL_32(0x89abcdef, w10);
armvixlad96eda2013-06-14 11:42:37 +0100463 ASSERT_EQUAL_64(0x00000fff, x11);
armvixlb0c8ae22014-03-21 14:03:59 +0000464 ASSERT_EQUAL_64(0x0000000000000fff, x12);
armvixlad96eda2013-06-14 11:42:37 +0100465 ASSERT_EQUAL_64(0x00001ffe, x13);
armvixlb0c8ae22014-03-21 14:03:59 +0000466 ASSERT_EQUAL_64(0x0000000000003ffc, x14);
armvixlad96eda2013-06-14 11:42:37 +0100467 ASSERT_EQUAL_64(0x000001ff, x15);
armvixlb0c8ae22014-03-21 14:03:59 +0000468 ASSERT_EQUAL_64(0x00000000000000ff, x18);
armvixlad96eda2013-06-14 11:42:37 +0100469 ASSERT_EQUAL_64(0x00000001, x19);
armvixlb0c8ae22014-03-21 14:03:59 +0000470 ASSERT_EQUAL_64(0x0000000000000000, x20);
armvixlad96eda2013-06-14 11:42:37 +0100471 ASSERT_EQUAL_64(0x7ff80000, x21);
armvixlb0c8ae22014-03-21 14:03:59 +0000472 ASSERT_EQUAL_64(0x3ffc000000000000, x22);
armvixlad96eda2013-06-14 11:42:37 +0100473 ASSERT_EQUAL_64(0x000000fe, x23);
armvixlb0c8ae22014-03-21 14:03:59 +0000474 ASSERT_EQUAL_64(0xfffffffffffffffc, x24);
armvixlad96eda2013-06-14 11:42:37 +0100475 ASSERT_EQUAL_64(0x00007ff8, x25);
armvixlb0c8ae22014-03-21 14:03:59 +0000476 ASSERT_EQUAL_64(0x000000000000fff0, x26);
477 ASSERT_EQUAL_64(0x000000000001ffe0, x27);
478 ASSERT_EQUAL_64(0x0123456789abcdef, x28);
armvixlad96eda2013-06-14 11:42:37 +0100479
480 TEARDOWN();
481}
482
483
484TEST(orr) {
485 SETUP();
486
487 START();
488 __ Mov(x0, 0xf0f0);
489 __ Mov(x1, 0xf00000ff);
490
491 __ Orr(x2, x0, Operand(x1));
492 __ Orr(w3, w0, Operand(w1, LSL, 28));
493 __ Orr(x4, x0, Operand(x1, LSL, 32));
494 __ Orr(x5, x0, Operand(x1, LSR, 4));
495 __ Orr(w6, w0, Operand(w1, ASR, 4));
496 __ Orr(x7, x0, Operand(x1, ASR, 4));
497 __ Orr(w8, w0, Operand(w1, ROR, 12));
498 __ Orr(x9, x0, Operand(x1, ROR, 12));
armvixlb0c8ae22014-03-21 14:03:59 +0000499 __ Orr(w10, w0, 0xf);
500 __ Orr(x11, x0, 0xf0000000f0000000);
armvixlad96eda2013-06-14 11:42:37 +0100501 END();
502
503 RUN();
504
armvixlb0c8ae22014-03-21 14:03:59 +0000505 ASSERT_EQUAL_64(0x00000000f000f0ff, x2);
armvixlad96eda2013-06-14 11:42:37 +0100506 ASSERT_EQUAL_64(0xf000f0f0, x3);
armvixlb0c8ae22014-03-21 14:03:59 +0000507 ASSERT_EQUAL_64(0xf00000ff0000f0f0, x4);
508 ASSERT_EQUAL_64(0x000000000f00f0ff, x5);
armvixlad96eda2013-06-14 11:42:37 +0100509 ASSERT_EQUAL_64(0xff00f0ff, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000510 ASSERT_EQUAL_64(0x000000000f00f0ff, x7);
armvixlad96eda2013-06-14 11:42:37 +0100511 ASSERT_EQUAL_64(0x0ffff0f0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000512 ASSERT_EQUAL_64(0x0ff00000000ff0f0, x9);
513 ASSERT_EQUAL_64(0x0000f0ff, x10);
514 ASSERT_EQUAL_64(0xf0000000f000f0f0, x11);
armvixlad96eda2013-06-14 11:42:37 +0100515
516 TEARDOWN();
517}
518
519
520TEST(orr_extend) {
521 SETUP();
522
523 START();
524 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +0000525 __ Mov(x1, 0x8000000080008080);
armvixlad96eda2013-06-14 11:42:37 +0100526 __ Orr(w6, w0, Operand(w1, UXTB));
527 __ Orr(x7, x0, Operand(x1, UXTH, 1));
528 __ Orr(w8, w0, Operand(w1, UXTW, 2));
529 __ Orr(x9, x0, Operand(x1, UXTX, 3));
530 __ Orr(w10, w0, Operand(w1, SXTB));
531 __ Orr(x11, x0, Operand(x1, SXTH, 1));
532 __ Orr(x12, x0, Operand(x1, SXTW, 2));
533 __ Orr(x13, x0, Operand(x1, SXTX, 3));
534 END();
535
536 RUN();
537
538 ASSERT_EQUAL_64(0x00000081, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000539 ASSERT_EQUAL_64(0x0000000000010101, x7);
armvixlad96eda2013-06-14 11:42:37 +0100540 ASSERT_EQUAL_64(0x00020201, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000541 ASSERT_EQUAL_64(0x0000000400040401, x9);
542 ASSERT_EQUAL_64(0xffffff81, x10);
543 ASSERT_EQUAL_64(0xffffffffffff0101, x11);
544 ASSERT_EQUAL_64(0xfffffffe00020201, x12);
545 ASSERT_EQUAL_64(0x0000000400040401, x13);
armvixlad96eda2013-06-14 11:42:37 +0100546
547 TEARDOWN();
548}
549
550
551TEST(bitwise_wide_imm) {
552 SETUP();
553
554 START();
555 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +0000556 __ Mov(x1, 0xf0f0f0f0f0f0f0f0);
armvixlad96eda2013-06-14 11:42:37 +0100557
armvixlb0c8ae22014-03-21 14:03:59 +0000558 __ Orr(x10, x0, 0x1234567890abcdef);
559 __ Orr(w11, w1, 0x90abcdef);
armvixl4a102ba2014-07-14 09:02:40 +0100560
561 __ Orr(w12, w0, kWMinInt);
562 __ Eor(w13, w0, kWMinInt);
armvixlad96eda2013-06-14 11:42:37 +0100563 END();
564
565 RUN();
566
567 ASSERT_EQUAL_64(0, x0);
armvixlb0c8ae22014-03-21 14:03:59 +0000568 ASSERT_EQUAL_64(0xf0f0f0f0f0f0f0f0, x1);
569 ASSERT_EQUAL_64(0x1234567890abcdef, x10);
570 ASSERT_EQUAL_64(0x00000000f0fbfdff, x11);
armvixl4a102ba2014-07-14 09:02:40 +0100571 ASSERT_EQUAL_32(kWMinInt, w12);
572 ASSERT_EQUAL_32(kWMinInt, w13);
armvixlad96eda2013-06-14 11:42:37 +0100573
574 TEARDOWN();
575}
576
577
578TEST(orn) {
579 SETUP();
580
581 START();
582 __ Mov(x0, 0xf0f0);
583 __ Mov(x1, 0xf00000ff);
584
585 __ Orn(x2, x0, Operand(x1));
586 __ Orn(w3, w0, Operand(w1, LSL, 4));
587 __ Orn(x4, x0, Operand(x1, LSL, 4));
588 __ Orn(x5, x0, Operand(x1, LSR, 1));
589 __ Orn(w6, w0, Operand(w1, ASR, 1));
590 __ Orn(x7, x0, Operand(x1, ASR, 1));
591 __ Orn(w8, w0, Operand(w1, ROR, 16));
592 __ Orn(x9, x0, Operand(x1, ROR, 16));
armvixlb0c8ae22014-03-21 14:03:59 +0000593 __ Orn(w10, w0, 0x0000ffff);
594 __ Orn(x11, x0, 0x0000ffff0000ffff);
armvixlad96eda2013-06-14 11:42:37 +0100595 END();
596
597 RUN();
598
armvixlb0c8ae22014-03-21 14:03:59 +0000599 ASSERT_EQUAL_64(0xffffffff0ffffff0, x2);
armvixlad96eda2013-06-14 11:42:37 +0100600 ASSERT_EQUAL_64(0xfffff0ff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +0000601 ASSERT_EQUAL_64(0xfffffff0fffff0ff, x4);
602 ASSERT_EQUAL_64(0xffffffff87fffff0, x5);
armvixlad96eda2013-06-14 11:42:37 +0100603 ASSERT_EQUAL_64(0x07fffff0, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000604 ASSERT_EQUAL_64(0xffffffff87fffff0, x7);
armvixlad96eda2013-06-14 11:42:37 +0100605 ASSERT_EQUAL_64(0xff00ffff, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000606 ASSERT_EQUAL_64(0xff00ffffffffffff, x9);
armvixlad96eda2013-06-14 11:42:37 +0100607 ASSERT_EQUAL_64(0xfffff0f0, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000608 ASSERT_EQUAL_64(0xffff0000fffff0f0, x11);
armvixlad96eda2013-06-14 11:42:37 +0100609
610 TEARDOWN();
611}
612
613
614TEST(orn_extend) {
615 SETUP();
616
617 START();
618 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +0000619 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100620 __ Orn(w6, w0, Operand(w1, UXTB));
621 __ Orn(x7, x0, Operand(x1, UXTH, 1));
622 __ Orn(w8, w0, Operand(w1, UXTW, 2));
623 __ Orn(x9, x0, Operand(x1, UXTX, 3));
624 __ Orn(w10, w0, Operand(w1, SXTB));
625 __ Orn(x11, x0, Operand(x1, SXTH, 1));
626 __ Orn(x12, x0, Operand(x1, SXTW, 2));
627 __ Orn(x13, x0, Operand(x1, SXTX, 3));
628 END();
629
630 RUN();
631
632 ASSERT_EQUAL_64(0xffffff7f, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000633 ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
armvixlad96eda2013-06-14 11:42:37 +0100634 ASSERT_EQUAL_64(0xfffdfdfb, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000635 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
armvixlad96eda2013-06-14 11:42:37 +0100636 ASSERT_EQUAL_64(0x0000007f, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000637 ASSERT_EQUAL_64(0x000000000000fefd, x11);
638 ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
639 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
armvixlad96eda2013-06-14 11:42:37 +0100640
641 TEARDOWN();
642}
643
644
645TEST(and_) {
646 SETUP();
647
648 START();
649 __ Mov(x0, 0xfff0);
650 __ Mov(x1, 0xf00000ff);
651
652 __ And(x2, x0, Operand(x1));
653 __ And(w3, w0, Operand(w1, LSL, 4));
654 __ And(x4, x0, Operand(x1, LSL, 4));
655 __ And(x5, x0, Operand(x1, LSR, 1));
656 __ And(w6, w0, Operand(w1, ASR, 20));
657 __ And(x7, x0, Operand(x1, ASR, 20));
658 __ And(w8, w0, Operand(w1, ROR, 28));
659 __ And(x9, x0, Operand(x1, ROR, 28));
660 __ And(w10, w0, Operand(0xff00));
661 __ And(x11, x0, Operand(0xff));
662 END();
663
664 RUN();
665
666 ASSERT_EQUAL_64(0x000000f0, x2);
667 ASSERT_EQUAL_64(0x00000ff0, x3);
668 ASSERT_EQUAL_64(0x00000ff0, x4);
669 ASSERT_EQUAL_64(0x00000070, x5);
670 ASSERT_EQUAL_64(0x0000ff00, x6);
671 ASSERT_EQUAL_64(0x00000f00, x7);
672 ASSERT_EQUAL_64(0x00000ff0, x8);
673 ASSERT_EQUAL_64(0x00000000, x9);
674 ASSERT_EQUAL_64(0x0000ff00, x10);
675 ASSERT_EQUAL_64(0x000000f0, x11);
676
677 TEARDOWN();
678}
679
680
681TEST(and_extend) {
682 SETUP();
683
684 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000685 __ Mov(x0, 0xffffffffffffffff);
686 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100687 __ And(w6, w0, Operand(w1, UXTB));
688 __ And(x7, x0, Operand(x1, UXTH, 1));
689 __ And(w8, w0, Operand(w1, UXTW, 2));
690 __ And(x9, x0, Operand(x1, UXTX, 3));
691 __ And(w10, w0, Operand(w1, SXTB));
692 __ And(x11, x0, Operand(x1, SXTH, 1));
693 __ And(x12, x0, Operand(x1, SXTW, 2));
694 __ And(x13, x0, Operand(x1, SXTX, 3));
695 END();
696
697 RUN();
698
699 ASSERT_EQUAL_64(0x00000081, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000700 ASSERT_EQUAL_64(0x0000000000010102, x7);
armvixlad96eda2013-06-14 11:42:37 +0100701 ASSERT_EQUAL_64(0x00020204, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000702 ASSERT_EQUAL_64(0x0000000400040408, x9);
armvixlad96eda2013-06-14 11:42:37 +0100703 ASSERT_EQUAL_64(0xffffff81, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000704 ASSERT_EQUAL_64(0xffffffffffff0102, x11);
705 ASSERT_EQUAL_64(0xfffffffe00020204, x12);
706 ASSERT_EQUAL_64(0x0000000400040408, x13);
armvixlad96eda2013-06-14 11:42:37 +0100707
708 TEARDOWN();
709}
710
711
712TEST(ands) {
713 SETUP();
714
715 START();
716 __ Mov(x1, 0xf00000ff);
armvixlf37fdc02014-02-05 13:22:16 +0000717 __ Ands(w0, w1, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +0100718 END();
719
720 RUN();
721
722 ASSERT_EQUAL_NZCV(NFlag);
723 ASSERT_EQUAL_64(0xf00000ff, x0);
724
725 START();
726 __ Mov(x0, 0xfff0);
727 __ Mov(x1, 0xf00000ff);
armvixlf37fdc02014-02-05 13:22:16 +0000728 __ Ands(w0, w0, Operand(w1, LSR, 4));
armvixlad96eda2013-06-14 11:42:37 +0100729 END();
730
731 RUN();
732
733 ASSERT_EQUAL_NZCV(ZFlag);
734 ASSERT_EQUAL_64(0x00000000, x0);
735
736 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000737 __ Mov(x0, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +0100738 __ Mov(x1, 0x00000001);
armvixlf37fdc02014-02-05 13:22:16 +0000739 __ Ands(x0, x0, Operand(x1, ROR, 1));
armvixlad96eda2013-06-14 11:42:37 +0100740 END();
741
742 RUN();
743
744 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +0000745 ASSERT_EQUAL_64(0x8000000000000000, x0);
armvixlad96eda2013-06-14 11:42:37 +0100746
747 START();
748 __ Mov(x0, 0xfff0);
armvixlf37fdc02014-02-05 13:22:16 +0000749 __ Ands(w0, w0, Operand(0xf));
armvixlad96eda2013-06-14 11:42:37 +0100750 END();
751
752 RUN();
753
754 ASSERT_EQUAL_NZCV(ZFlag);
755 ASSERT_EQUAL_64(0x00000000, x0);
756
757 START();
758 __ Mov(x0, 0xff000000);
armvixlf37fdc02014-02-05 13:22:16 +0000759 __ Ands(w0, w0, Operand(0x80000000));
armvixlad96eda2013-06-14 11:42:37 +0100760 END();
761
762 RUN();
763
764 ASSERT_EQUAL_NZCV(NFlag);
765 ASSERT_EQUAL_64(0x80000000, x0);
766
767 TEARDOWN();
768}
769
770
771TEST(bic) {
772 SETUP();
773
774 START();
775 __ Mov(x0, 0xfff0);
776 __ Mov(x1, 0xf00000ff);
777
778 __ Bic(x2, x0, Operand(x1));
779 __ Bic(w3, w0, Operand(w1, LSL, 4));
780 __ Bic(x4, x0, Operand(x1, LSL, 4));
781 __ Bic(x5, x0, Operand(x1, LSR, 1));
782 __ Bic(w6, w0, Operand(w1, ASR, 20));
783 __ Bic(x7, x0, Operand(x1, ASR, 20));
784 __ Bic(w8, w0, Operand(w1, ROR, 28));
785 __ Bic(x9, x0, Operand(x1, ROR, 24));
786 __ Bic(x10, x0, Operand(0x1f));
787 __ Bic(x11, x0, Operand(0x100));
788
789 // Test bic into sp when the constant cannot be encoded in the immediate
790 // field.
791 // Use x20 to preserve sp. We check for the result via x21 because the
792 // test infrastructure requires that sp be restored to its original value.
793 __ Mov(x20, sp);
794 __ Mov(x0, 0xffffff);
795 __ Bic(sp, x0, Operand(0xabcdef));
796 __ Mov(x21, sp);
797 __ Mov(sp, x20);
798 END();
799
800 RUN();
801
802 ASSERT_EQUAL_64(0x0000ff00, x2);
803 ASSERT_EQUAL_64(0x0000f000, x3);
804 ASSERT_EQUAL_64(0x0000f000, x4);
805 ASSERT_EQUAL_64(0x0000ff80, x5);
806 ASSERT_EQUAL_64(0x000000f0, x6);
807 ASSERT_EQUAL_64(0x0000f0f0, x7);
808 ASSERT_EQUAL_64(0x0000f000, x8);
809 ASSERT_EQUAL_64(0x0000ff00, x9);
810 ASSERT_EQUAL_64(0x0000ffe0, x10);
811 ASSERT_EQUAL_64(0x0000fef0, x11);
812
813 ASSERT_EQUAL_64(0x543210, x21);
814
815 TEARDOWN();
816}
817
818
819TEST(bic_extend) {
820 SETUP();
821
822 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000823 __ Mov(x0, 0xffffffffffffffff);
824 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100825 __ Bic(w6, w0, Operand(w1, UXTB));
826 __ Bic(x7, x0, Operand(x1, UXTH, 1));
827 __ Bic(w8, w0, Operand(w1, UXTW, 2));
828 __ Bic(x9, x0, Operand(x1, UXTX, 3));
829 __ Bic(w10, w0, Operand(w1, SXTB));
830 __ Bic(x11, x0, Operand(x1, SXTH, 1));
831 __ Bic(x12, x0, Operand(x1, SXTW, 2));
832 __ Bic(x13, x0, Operand(x1, SXTX, 3));
833 END();
834
835 RUN();
836
837 ASSERT_EQUAL_64(0xffffff7e, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000838 ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
armvixlad96eda2013-06-14 11:42:37 +0100839 ASSERT_EQUAL_64(0xfffdfdfb, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000840 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
armvixlad96eda2013-06-14 11:42:37 +0100841 ASSERT_EQUAL_64(0x0000007e, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000842 ASSERT_EQUAL_64(0x000000000000fefd, x11);
843 ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
844 ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
armvixlad96eda2013-06-14 11:42:37 +0100845
846 TEARDOWN();
847}
848
849
850TEST(bics) {
851 SETUP();
852
853 START();
854 __ Mov(x1, 0xffff);
armvixlf37fdc02014-02-05 13:22:16 +0000855 __ Bics(w0, w1, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +0100856 END();
857
858 RUN();
859
860 ASSERT_EQUAL_NZCV(ZFlag);
861 ASSERT_EQUAL_64(0x00000000, x0);
862
863 START();
864 __ Mov(x0, 0xffffffff);
armvixlf37fdc02014-02-05 13:22:16 +0000865 __ Bics(w0, w0, Operand(w0, LSR, 1));
armvixlad96eda2013-06-14 11:42:37 +0100866 END();
867
868 RUN();
869
870 ASSERT_EQUAL_NZCV(NFlag);
871 ASSERT_EQUAL_64(0x80000000, x0);
872
873 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000874 __ Mov(x0, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +0100875 __ Mov(x1, 0x00000001);
armvixlf37fdc02014-02-05 13:22:16 +0000876 __ Bics(x0, x0, Operand(x1, ROR, 1));
armvixlad96eda2013-06-14 11:42:37 +0100877 END();
878
879 RUN();
880
881 ASSERT_EQUAL_NZCV(ZFlag);
882 ASSERT_EQUAL_64(0x00000000, x0);
883
884 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000885 __ Mov(x0, 0xffffffffffffffff);
886 __ Bics(x0, x0, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +0100887 END();
888
889 RUN();
890
891 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +0000892 ASSERT_EQUAL_64(0x8000000000000000, x0);
armvixlad96eda2013-06-14 11:42:37 +0100893
894 START();
895 __ Mov(w0, 0xffff0000);
armvixlb0c8ae22014-03-21 14:03:59 +0000896 __ Bics(w0, w0, 0xfffffff0);
armvixlad96eda2013-06-14 11:42:37 +0100897 END();
898
899 RUN();
900
901 ASSERT_EQUAL_NZCV(ZFlag);
902 ASSERT_EQUAL_64(0x00000000, x0);
903
904 TEARDOWN();
905}
906
907
908TEST(eor) {
909 SETUP();
910
911 START();
912 __ Mov(x0, 0xfff0);
913 __ Mov(x1, 0xf00000ff);
914
915 __ Eor(x2, x0, Operand(x1));
916 __ Eor(w3, w0, Operand(w1, LSL, 4));
917 __ Eor(x4, x0, Operand(x1, LSL, 4));
918 __ Eor(x5, x0, Operand(x1, LSR, 1));
919 __ Eor(w6, w0, Operand(w1, ASR, 20));
920 __ Eor(x7, x0, Operand(x1, ASR, 20));
921 __ Eor(w8, w0, Operand(w1, ROR, 28));
922 __ Eor(x9, x0, Operand(x1, ROR, 28));
armvixlb0c8ae22014-03-21 14:03:59 +0000923 __ Eor(w10, w0, 0xff00ff00);
924 __ Eor(x11, x0, 0xff00ff00ff00ff00);
armvixlad96eda2013-06-14 11:42:37 +0100925 END();
926
927 RUN();
928
armvixlb0c8ae22014-03-21 14:03:59 +0000929 ASSERT_EQUAL_64(0x00000000f000ff0f, x2);
armvixlad96eda2013-06-14 11:42:37 +0100930 ASSERT_EQUAL_64(0x0000f000, x3);
armvixlb0c8ae22014-03-21 14:03:59 +0000931 ASSERT_EQUAL_64(0x0000000f0000f000, x4);
932 ASSERT_EQUAL_64(0x000000007800ff8f, x5);
armvixlad96eda2013-06-14 11:42:37 +0100933 ASSERT_EQUAL_64(0xffff00f0, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000934 ASSERT_EQUAL_64(0x000000000000f0f0, x7);
armvixlad96eda2013-06-14 11:42:37 +0100935 ASSERT_EQUAL_64(0x0000f00f, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000936 ASSERT_EQUAL_64(0x00000ff00000ffff, x9);
armvixlad96eda2013-06-14 11:42:37 +0100937 ASSERT_EQUAL_64(0xff0000f0, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000938 ASSERT_EQUAL_64(0xff00ff00ff0000f0, x11);
armvixlad96eda2013-06-14 11:42:37 +0100939
940 TEARDOWN();
941}
942
943TEST(eor_extend) {
944 SETUP();
945
946 START();
armvixlb0c8ae22014-03-21 14:03:59 +0000947 __ Mov(x0, 0x1111111111111111);
948 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +0100949 __ Eor(w6, w0, Operand(w1, UXTB));
950 __ Eor(x7, x0, Operand(x1, UXTH, 1));
951 __ Eor(w8, w0, Operand(w1, UXTW, 2));
952 __ Eor(x9, x0, Operand(x1, UXTX, 3));
953 __ Eor(w10, w0, Operand(w1, SXTB));
954 __ Eor(x11, x0, Operand(x1, SXTH, 1));
955 __ Eor(x12, x0, Operand(x1, SXTW, 2));
956 __ Eor(x13, x0, Operand(x1, SXTX, 3));
957 END();
958
959 RUN();
960
961 ASSERT_EQUAL_64(0x11111190, x6);
armvixlb0c8ae22014-03-21 14:03:59 +0000962 ASSERT_EQUAL_64(0x1111111111101013, x7);
armvixlad96eda2013-06-14 11:42:37 +0100963 ASSERT_EQUAL_64(0x11131315, x8);
armvixlb0c8ae22014-03-21 14:03:59 +0000964 ASSERT_EQUAL_64(0x1111111511151519, x9);
armvixlad96eda2013-06-14 11:42:37 +0100965 ASSERT_EQUAL_64(0xeeeeee90, x10);
armvixlb0c8ae22014-03-21 14:03:59 +0000966 ASSERT_EQUAL_64(0xeeeeeeeeeeee1013, x11);
967 ASSERT_EQUAL_64(0xeeeeeeef11131315, x12);
968 ASSERT_EQUAL_64(0x1111111511151519, x13);
armvixlad96eda2013-06-14 11:42:37 +0100969
970 TEARDOWN();
971}
972
973
974TEST(eon) {
975 SETUP();
976
977 START();
978 __ Mov(x0, 0xfff0);
979 __ Mov(x1, 0xf00000ff);
980
981 __ Eon(x2, x0, Operand(x1));
982 __ Eon(w3, w0, Operand(w1, LSL, 4));
983 __ Eon(x4, x0, Operand(x1, LSL, 4));
984 __ Eon(x5, x0, Operand(x1, LSR, 1));
985 __ Eon(w6, w0, Operand(w1, ASR, 20));
986 __ Eon(x7, x0, Operand(x1, ASR, 20));
987 __ Eon(w8, w0, Operand(w1, ROR, 28));
988 __ Eon(x9, x0, Operand(x1, ROR, 28));
armvixlb0c8ae22014-03-21 14:03:59 +0000989 __ Eon(w10, w0, 0x03c003c0);
990 __ Eon(x11, x0, 0x0000100000001000);
armvixlad96eda2013-06-14 11:42:37 +0100991 END();
992
993 RUN();
994
armvixlb0c8ae22014-03-21 14:03:59 +0000995 ASSERT_EQUAL_64(0xffffffff0fff00f0, x2);
armvixlad96eda2013-06-14 11:42:37 +0100996 ASSERT_EQUAL_64(0xffff0fff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +0000997 ASSERT_EQUAL_64(0xfffffff0ffff0fff, x4);
998 ASSERT_EQUAL_64(0xffffffff87ff0070, x5);
armvixlad96eda2013-06-14 11:42:37 +0100999 ASSERT_EQUAL_64(0x0000ff0f, x6);
armvixlb0c8ae22014-03-21 14:03:59 +00001000 ASSERT_EQUAL_64(0xffffffffffff0f0f, x7);
armvixlad96eda2013-06-14 11:42:37 +01001001 ASSERT_EQUAL_64(0xffff0ff0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001002 ASSERT_EQUAL_64(0xfffff00fffff0000, x9);
armvixlad96eda2013-06-14 11:42:37 +01001003 ASSERT_EQUAL_64(0xfc3f03cf, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00001004 ASSERT_EQUAL_64(0xffffefffffff100f, x11);
armvixlad96eda2013-06-14 11:42:37 +01001005
1006 TEARDOWN();
1007}
1008
1009
1010TEST(eon_extend) {
1011 SETUP();
1012
1013 START();
armvixlb0c8ae22014-03-21 14:03:59 +00001014 __ Mov(x0, 0x1111111111111111);
1015 __ Mov(x1, 0x8000000080008081);
armvixlad96eda2013-06-14 11:42:37 +01001016 __ Eon(w6, w0, Operand(w1, UXTB));
1017 __ Eon(x7, x0, Operand(x1, UXTH, 1));
1018 __ Eon(w8, w0, Operand(w1, UXTW, 2));
1019 __ Eon(x9, x0, Operand(x1, UXTX, 3));
1020 __ Eon(w10, w0, Operand(w1, SXTB));
1021 __ Eon(x11, x0, Operand(x1, SXTH, 1));
1022 __ Eon(x12, x0, Operand(x1, SXTW, 2));
1023 __ Eon(x13, x0, Operand(x1, SXTX, 3));
1024 END();
1025
1026 RUN();
1027
1028 ASSERT_EQUAL_64(0xeeeeee6f, x6);
armvixlb0c8ae22014-03-21 14:03:59 +00001029 ASSERT_EQUAL_64(0xeeeeeeeeeeefefec, x7);
armvixlad96eda2013-06-14 11:42:37 +01001030 ASSERT_EQUAL_64(0xeeececea, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001031 ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x9);
armvixlad96eda2013-06-14 11:42:37 +01001032 ASSERT_EQUAL_64(0x1111116f, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00001033 ASSERT_EQUAL_64(0x111111111111efec, x11);
1034 ASSERT_EQUAL_64(0x11111110eeececea, x12);
1035 ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x13);
armvixlad96eda2013-06-14 11:42:37 +01001036
1037 TEARDOWN();
1038}
1039
1040
1041TEST(mul) {
1042 SETUP();
1043
1044 START();
1045 __ Mov(x16, 0);
1046 __ Mov(x17, 1);
1047 __ Mov(x18, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001048 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001049
1050 __ Mul(w0, w16, w16);
1051 __ Mul(w1, w16, w17);
1052 __ Mul(w2, w17, w18);
1053 __ Mul(w3, w18, w19);
1054 __ Mul(x4, x16, x16);
1055 __ Mul(x5, x17, x18);
1056 __ Mul(x6, x18, x19);
1057 __ Mul(x7, x19, x19);
1058 __ Smull(x8, w17, w18);
1059 __ Smull(x9, w18, w18);
1060 __ Smull(x10, w19, w19);
1061 __ Mneg(w11, w16, w16);
1062 __ Mneg(w12, w16, w17);
1063 __ Mneg(w13, w17, w18);
1064 __ Mneg(w14, w18, w19);
1065 __ Mneg(x20, x16, x16);
1066 __ Mneg(x21, x17, x18);
1067 __ Mneg(x22, x18, x19);
1068 __ Mneg(x23, x19, x19);
1069 END();
1070
1071 RUN();
1072
1073 ASSERT_EQUAL_64(0, x0);
1074 ASSERT_EQUAL_64(0, x1);
1075 ASSERT_EQUAL_64(0xffffffff, x2);
1076 ASSERT_EQUAL_64(1, x3);
1077 ASSERT_EQUAL_64(0, x4);
1078 ASSERT_EQUAL_64(0xffffffff, x5);
armvixlb0c8ae22014-03-21 14:03:59 +00001079 ASSERT_EQUAL_64(0xffffffff00000001, x6);
armvixlad96eda2013-06-14 11:42:37 +01001080 ASSERT_EQUAL_64(1, x7);
armvixlb0c8ae22014-03-21 14:03:59 +00001081 ASSERT_EQUAL_64(0xffffffffffffffff, x8);
armvixlad96eda2013-06-14 11:42:37 +01001082 ASSERT_EQUAL_64(1, x9);
1083 ASSERT_EQUAL_64(1, x10);
1084 ASSERT_EQUAL_64(0, x11);
1085 ASSERT_EQUAL_64(0, x12);
1086 ASSERT_EQUAL_64(1, x13);
1087 ASSERT_EQUAL_64(0xffffffff, x14);
1088 ASSERT_EQUAL_64(0, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00001089 ASSERT_EQUAL_64(0xffffffff00000001, x21);
armvixlad96eda2013-06-14 11:42:37 +01001090 ASSERT_EQUAL_64(0xffffffff, x22);
armvixlb0c8ae22014-03-21 14:03:59 +00001091 ASSERT_EQUAL_64(0xffffffffffffffff, x23);
armvixlad96eda2013-06-14 11:42:37 +01001092
1093 TEARDOWN();
1094}
1095
1096
armvixlf37fdc02014-02-05 13:22:16 +00001097static void SmullHelper(int64_t expected, int64_t a, int64_t b) {
1098 SETUP();
1099 START();
1100 __ Mov(w0, a);
1101 __ Mov(w1, b);
1102 __ Smull(x2, w0, w1);
1103 END();
1104 RUN();
1105 ASSERT_EQUAL_64(expected, x2);
1106 TEARDOWN();
1107}
1108
1109
1110TEST(smull) {
1111 SmullHelper(0, 0, 0);
1112 SmullHelper(1, 1, 1);
1113 SmullHelper(-1, -1, 1);
1114 SmullHelper(1, -1, -1);
1115 SmullHelper(0xffffffff80000000, 0x80000000, 1);
1116 SmullHelper(0x0000000080000000, 0x00010000, 0x00008000);
1117}
1118
1119
armvixlad96eda2013-06-14 11:42:37 +01001120TEST(madd) {
1121 SETUP();
1122
1123 START();
1124 __ Mov(x16, 0);
1125 __ Mov(x17, 1);
1126 __ Mov(x18, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001127 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001128
1129 __ Madd(w0, w16, w16, w16);
1130 __ Madd(w1, w16, w16, w17);
1131 __ Madd(w2, w16, w16, w18);
1132 __ Madd(w3, w16, w16, w19);
1133 __ Madd(w4, w16, w17, w17);
1134 __ Madd(w5, w17, w17, w18);
1135 __ Madd(w6, w17, w17, w19);
1136 __ Madd(w7, w17, w18, w16);
1137 __ Madd(w8, w17, w18, w18);
1138 __ Madd(w9, w18, w18, w17);
1139 __ Madd(w10, w18, w19, w18);
1140 __ Madd(w11, w19, w19, w19);
1141
1142 __ Madd(x12, x16, x16, x16);
1143 __ Madd(x13, x16, x16, x17);
1144 __ Madd(x14, x16, x16, x18);
1145 __ Madd(x15, x16, x16, x19);
1146 __ Madd(x20, x16, x17, x17);
1147 __ Madd(x21, x17, x17, x18);
1148 __ Madd(x22, x17, x17, x19);
1149 __ Madd(x23, x17, x18, x16);
1150 __ Madd(x24, x17, x18, x18);
1151 __ Madd(x25, x18, x18, x17);
1152 __ Madd(x26, x18, x19, x18);
1153 __ Madd(x27, x19, x19, x19);
1154
1155 END();
1156
1157 RUN();
1158
1159 ASSERT_EQUAL_64(0, x0);
1160 ASSERT_EQUAL_64(1, x1);
1161 ASSERT_EQUAL_64(0xffffffff, x2);
1162 ASSERT_EQUAL_64(0xffffffff, x3);
1163 ASSERT_EQUAL_64(1, x4);
1164 ASSERT_EQUAL_64(0, x5);
1165 ASSERT_EQUAL_64(0, x6);
1166 ASSERT_EQUAL_64(0xffffffff, x7);
1167 ASSERT_EQUAL_64(0xfffffffe, x8);
1168 ASSERT_EQUAL_64(2, x9);
1169 ASSERT_EQUAL_64(0, x10);
1170 ASSERT_EQUAL_64(0, x11);
1171
1172 ASSERT_EQUAL_64(0, x12);
1173 ASSERT_EQUAL_64(1, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00001174 ASSERT_EQUAL_64(0x00000000ffffffff, x14);
armvixlad96eda2013-06-14 11:42:37 +01001175 ASSERT_EQUAL_64(0xffffffffffffffff, x15);
1176 ASSERT_EQUAL_64(1, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00001177 ASSERT_EQUAL_64(0x0000000100000000, x21);
armvixlad96eda2013-06-14 11:42:37 +01001178 ASSERT_EQUAL_64(0, x22);
armvixlb0c8ae22014-03-21 14:03:59 +00001179 ASSERT_EQUAL_64(0x00000000ffffffff, x23);
1180 ASSERT_EQUAL_64(0x00000001fffffffe, x24);
1181 ASSERT_EQUAL_64(0xfffffffe00000002, x25);
armvixlad96eda2013-06-14 11:42:37 +01001182 ASSERT_EQUAL_64(0, x26);
1183 ASSERT_EQUAL_64(0, x27);
1184
1185 TEARDOWN();
1186}
1187
1188
1189TEST(msub) {
1190 SETUP();
1191
1192 START();
1193 __ Mov(x16, 0);
1194 __ Mov(x17, 1);
1195 __ Mov(x18, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001196 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001197
1198 __ Msub(w0, w16, w16, w16);
1199 __ Msub(w1, w16, w16, w17);
1200 __ Msub(w2, w16, w16, w18);
1201 __ Msub(w3, w16, w16, w19);
1202 __ Msub(w4, w16, w17, w17);
1203 __ Msub(w5, w17, w17, w18);
1204 __ Msub(w6, w17, w17, w19);
1205 __ Msub(w7, w17, w18, w16);
1206 __ Msub(w8, w17, w18, w18);
1207 __ Msub(w9, w18, w18, w17);
1208 __ Msub(w10, w18, w19, w18);
1209 __ Msub(w11, w19, w19, w19);
1210
1211 __ Msub(x12, x16, x16, x16);
1212 __ Msub(x13, x16, x16, x17);
1213 __ Msub(x14, x16, x16, x18);
1214 __ Msub(x15, x16, x16, x19);
1215 __ Msub(x20, x16, x17, x17);
1216 __ Msub(x21, x17, x17, x18);
1217 __ Msub(x22, x17, x17, x19);
1218 __ Msub(x23, x17, x18, x16);
1219 __ Msub(x24, x17, x18, x18);
1220 __ Msub(x25, x18, x18, x17);
1221 __ Msub(x26, x18, x19, x18);
1222 __ Msub(x27, x19, x19, x19);
1223
1224 END();
1225
1226 RUN();
1227
1228 ASSERT_EQUAL_64(0, x0);
1229 ASSERT_EQUAL_64(1, x1);
1230 ASSERT_EQUAL_64(0xffffffff, x2);
1231 ASSERT_EQUAL_64(0xffffffff, x3);
1232 ASSERT_EQUAL_64(1, x4);
1233 ASSERT_EQUAL_64(0xfffffffe, x5);
1234 ASSERT_EQUAL_64(0xfffffffe, x6);
1235 ASSERT_EQUAL_64(1, x7);
1236 ASSERT_EQUAL_64(0, x8);
1237 ASSERT_EQUAL_64(0, x9);
1238 ASSERT_EQUAL_64(0xfffffffe, x10);
1239 ASSERT_EQUAL_64(0xfffffffe, x11);
1240
1241 ASSERT_EQUAL_64(0, x12);
1242 ASSERT_EQUAL_64(1, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00001243 ASSERT_EQUAL_64(0x00000000ffffffff, x14);
1244 ASSERT_EQUAL_64(0xffffffffffffffff, x15);
armvixlad96eda2013-06-14 11:42:37 +01001245 ASSERT_EQUAL_64(1, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00001246 ASSERT_EQUAL_64(0x00000000fffffffe, x21);
1247 ASSERT_EQUAL_64(0xfffffffffffffffe, x22);
1248 ASSERT_EQUAL_64(0xffffffff00000001, x23);
armvixlad96eda2013-06-14 11:42:37 +01001249 ASSERT_EQUAL_64(0, x24);
armvixlb0c8ae22014-03-21 14:03:59 +00001250 ASSERT_EQUAL_64(0x0000000200000000, x25);
1251 ASSERT_EQUAL_64(0x00000001fffffffe, x26);
1252 ASSERT_EQUAL_64(0xfffffffffffffffe, x27);
armvixlad96eda2013-06-14 11:42:37 +01001253
1254 TEARDOWN();
1255}
1256
1257
1258TEST(smulh) {
1259 SETUP();
1260
1261 START();
1262 __ Mov(x20, 0);
1263 __ Mov(x21, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00001264 __ Mov(x22, 0x0000000100000000);
1265 __ Mov(x23, 0x0000000012345678);
1266 __ Mov(x24, 0x0123456789abcdef);
1267 __ Mov(x25, 0x0000000200000000);
1268 __ Mov(x26, 0x8000000000000000);
1269 __ Mov(x27, 0xffffffffffffffff);
1270 __ Mov(x28, 0x5555555555555555);
1271 __ Mov(x29, 0xaaaaaaaaaaaaaaaa);
armvixlad96eda2013-06-14 11:42:37 +01001272
1273 __ Smulh(x0, x20, x24);
1274 __ Smulh(x1, x21, x24);
1275 __ Smulh(x2, x22, x23);
1276 __ Smulh(x3, x22, x24);
1277 __ Smulh(x4, x24, x25);
1278 __ Smulh(x5, x23, x27);
1279 __ Smulh(x6, x26, x26);
1280 __ Smulh(x7, x26, x27);
1281 __ Smulh(x8, x27, x27);
1282 __ Smulh(x9, x28, x28);
1283 __ Smulh(x10, x28, x29);
1284 __ Smulh(x11, x29, x29);
1285 END();
1286
1287 RUN();
1288
1289 ASSERT_EQUAL_64(0, x0);
1290 ASSERT_EQUAL_64(0, x1);
1291 ASSERT_EQUAL_64(0, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00001292 ASSERT_EQUAL_64(0x0000000001234567, x3);
1293 ASSERT_EQUAL_64(0x0000000002468acf, x4);
1294 ASSERT_EQUAL_64(0xffffffffffffffff, x5);
1295 ASSERT_EQUAL_64(0x4000000000000000, x6);
armvixlad96eda2013-06-14 11:42:37 +01001296 ASSERT_EQUAL_64(0, x7);
1297 ASSERT_EQUAL_64(0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001298 ASSERT_EQUAL_64(0x1c71c71c71c71c71, x9);
1299 ASSERT_EQUAL_64(0xe38e38e38e38e38e, x10);
1300 ASSERT_EQUAL_64(0x1c71c71c71c71c72, x11);
armvixlad96eda2013-06-14 11:42:37 +01001301
1302 TEARDOWN();
1303}
1304
1305
1306TEST(smaddl_umaddl) {
1307 SETUP();
1308
1309 START();
1310 __ Mov(x17, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00001311 __ Mov(x18, 0x00000000ffffffff);
1312 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001313 __ Mov(x20, 4);
armvixlb0c8ae22014-03-21 14:03:59 +00001314 __ Mov(x21, 0x0000000200000000);
armvixlad96eda2013-06-14 11:42:37 +01001315
1316 __ Smaddl(x9, w17, w18, x20);
1317 __ Smaddl(x10, w18, w18, x20);
1318 __ Smaddl(x11, w19, w19, x20);
1319 __ Smaddl(x12, w19, w19, x21);
1320 __ Umaddl(x13, w17, w18, x20);
1321 __ Umaddl(x14, w18, w18, x20);
1322 __ Umaddl(x15, w19, w19, x20);
1323 __ Umaddl(x22, w19, w19, x21);
1324 END();
1325
1326 RUN();
1327
1328 ASSERT_EQUAL_64(3, x9);
1329 ASSERT_EQUAL_64(5, x10);
1330 ASSERT_EQUAL_64(5, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00001331 ASSERT_EQUAL_64(0x0000000200000001, x12);
1332 ASSERT_EQUAL_64(0x0000000100000003, x13);
1333 ASSERT_EQUAL_64(0xfffffffe00000005, x14);
1334 ASSERT_EQUAL_64(0xfffffffe00000005, x15);
1335 ASSERT_EQUAL_64(1, x22);
armvixlad96eda2013-06-14 11:42:37 +01001336
1337 TEARDOWN();
1338}
1339
1340
1341TEST(smsubl_umsubl) {
1342 SETUP();
1343
1344 START();
1345 __ Mov(x17, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00001346 __ Mov(x18, 0x00000000ffffffff);
1347 __ Mov(x19, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001348 __ Mov(x20, 4);
armvixlb0c8ae22014-03-21 14:03:59 +00001349 __ Mov(x21, 0x0000000200000000);
armvixlad96eda2013-06-14 11:42:37 +01001350
1351 __ Smsubl(x9, w17, w18, x20);
1352 __ Smsubl(x10, w18, w18, x20);
1353 __ Smsubl(x11, w19, w19, x20);
1354 __ Smsubl(x12, w19, w19, x21);
1355 __ Umsubl(x13, w17, w18, x20);
1356 __ Umsubl(x14, w18, w18, x20);
1357 __ Umsubl(x15, w19, w19, x20);
1358 __ Umsubl(x22, w19, w19, x21);
1359 END();
1360
1361 RUN();
1362
1363 ASSERT_EQUAL_64(5, x9);
1364 ASSERT_EQUAL_64(3, x10);
1365 ASSERT_EQUAL_64(3, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00001366 ASSERT_EQUAL_64(0x00000001ffffffff, x12);
1367 ASSERT_EQUAL_64(0xffffffff00000005, x13);
1368 ASSERT_EQUAL_64(0x0000000200000003, x14);
1369 ASSERT_EQUAL_64(0x0000000200000003, x15);
1370 ASSERT_EQUAL_64(0x00000003ffffffff, x22);
armvixlad96eda2013-06-14 11:42:37 +01001371
1372 TEARDOWN();
1373}
1374
1375
1376TEST(div) {
1377 SETUP();
1378
1379 START();
1380 __ Mov(x16, 1);
1381 __ Mov(x17, 0xffffffff);
armvixlb0c8ae22014-03-21 14:03:59 +00001382 __ Mov(x18, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01001383 __ Mov(x19, 0x80000000);
armvixlb0c8ae22014-03-21 14:03:59 +00001384 __ Mov(x20, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01001385 __ Mov(x21, 2);
1386
1387 __ Udiv(w0, w16, w16);
1388 __ Udiv(w1, w17, w16);
1389 __ Sdiv(w2, w16, w16);
1390 __ Sdiv(w3, w16, w17);
1391 __ Sdiv(w4, w17, w18);
1392
1393 __ Udiv(x5, x16, x16);
1394 __ Udiv(x6, x17, x18);
1395 __ Sdiv(x7, x16, x16);
1396 __ Sdiv(x8, x16, x17);
1397 __ Sdiv(x9, x17, x18);
1398
1399 __ Udiv(w10, w19, w21);
1400 __ Sdiv(w11, w19, w21);
1401 __ Udiv(x12, x19, x21);
1402 __ Sdiv(x13, x19, x21);
1403 __ Udiv(x14, x20, x21);
1404 __ Sdiv(x15, x20, x21);
armvixlf37fdc02014-02-05 13:22:16 +00001405
1406 __ Udiv(w22, w19, w17);
1407 __ Sdiv(w23, w19, w17);
1408 __ Udiv(x24, x20, x18);
1409 __ Sdiv(x25, x20, x18);
1410
1411 __ Udiv(x26, x16, x21);
1412 __ Sdiv(x27, x16, x21);
1413 __ Udiv(x28, x18, x21);
1414 __ Sdiv(x29, x18, x21);
1415
1416 __ Mov(x17, 0);
1417 __ Udiv(w18, w16, w17);
1418 __ Sdiv(w19, w16, w17);
1419 __ Udiv(x20, x16, x17);
1420 __ Sdiv(x21, x16, x17);
armvixlad96eda2013-06-14 11:42:37 +01001421 END();
1422
1423 RUN();
1424
1425 ASSERT_EQUAL_64(1, x0);
1426 ASSERT_EQUAL_64(0xffffffff, x1);
1427 ASSERT_EQUAL_64(1, x2);
1428 ASSERT_EQUAL_64(0xffffffff, x3);
1429 ASSERT_EQUAL_64(1, x4);
1430 ASSERT_EQUAL_64(1, x5);
1431 ASSERT_EQUAL_64(0, x6);
1432 ASSERT_EQUAL_64(1, x7);
1433 ASSERT_EQUAL_64(0, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00001434 ASSERT_EQUAL_64(0xffffffff00000001, x9);
armvixlad96eda2013-06-14 11:42:37 +01001435 ASSERT_EQUAL_64(0x40000000, x10);
1436 ASSERT_EQUAL_64(0xC0000000, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00001437 ASSERT_EQUAL_64(0x0000000040000000, x12);
1438 ASSERT_EQUAL_64(0x0000000040000000, x13);
1439 ASSERT_EQUAL_64(0x4000000000000000, x14);
1440 ASSERT_EQUAL_64(0xC000000000000000, x15);
armvixlf37fdc02014-02-05 13:22:16 +00001441 ASSERT_EQUAL_64(0, x22);
1442 ASSERT_EQUAL_64(0x80000000, x23);
1443 ASSERT_EQUAL_64(0, x24);
armvixlb0c8ae22014-03-21 14:03:59 +00001444 ASSERT_EQUAL_64(0x8000000000000000, x25);
armvixlf37fdc02014-02-05 13:22:16 +00001445 ASSERT_EQUAL_64(0, x26);
1446 ASSERT_EQUAL_64(0, x27);
armvixlb0c8ae22014-03-21 14:03:59 +00001447 ASSERT_EQUAL_64(0x7fffffffffffffff, x28);
armvixlf37fdc02014-02-05 13:22:16 +00001448 ASSERT_EQUAL_64(0, x29);
1449 ASSERT_EQUAL_64(0, x18);
1450 ASSERT_EQUAL_64(0, x19);
1451 ASSERT_EQUAL_64(0, x20);
1452 ASSERT_EQUAL_64(0, x21);
armvixlad96eda2013-06-14 11:42:37 +01001453
1454 TEARDOWN();
1455}
1456
1457
1458TEST(rbit_rev) {
1459 SETUP();
1460
1461 START();
armvixlb0c8ae22014-03-21 14:03:59 +00001462 __ Mov(x24, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01001463 __ Rbit(w0, w24);
1464 __ Rbit(x1, x24);
1465 __ Rev16(w2, w24);
1466 __ Rev16(x3, x24);
1467 __ Rev(w4, w24);
1468 __ Rev32(x5, x24);
1469 __ Rev(x6, x24);
1470 END();
1471
1472 RUN();
1473
1474 ASSERT_EQUAL_64(0x084c2a6e, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00001475 ASSERT_EQUAL_64(0x084c2a6e195d3b7f, x1);
armvixlad96eda2013-06-14 11:42:37 +01001476 ASSERT_EQUAL_64(0x54761032, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00001477 ASSERT_EQUAL_64(0xdcfe98ba54761032, x3);
armvixlad96eda2013-06-14 11:42:37 +01001478 ASSERT_EQUAL_64(0x10325476, x4);
armvixlb0c8ae22014-03-21 14:03:59 +00001479 ASSERT_EQUAL_64(0x98badcfe10325476, x5);
1480 ASSERT_EQUAL_64(0x1032547698badcfe, x6);
armvixlad96eda2013-06-14 11:42:37 +01001481
1482 TEARDOWN();
1483}
1484
1485
1486TEST(clz_cls) {
1487 SETUP();
1488
1489 START();
armvixlb0c8ae22014-03-21 14:03:59 +00001490 __ Mov(x24, 0x0008000000800000);
1491 __ Mov(x25, 0xff800000fff80000);
armvixlad96eda2013-06-14 11:42:37 +01001492 __ Mov(x26, 0);
1493 __ Clz(w0, w24);
1494 __ Clz(x1, x24);
1495 __ Clz(w2, w25);
1496 __ Clz(x3, x25);
1497 __ Clz(w4, w26);
1498 __ Clz(x5, x26);
1499 __ Cls(w6, w24);
1500 __ Cls(x7, x24);
1501 __ Cls(w8, w25);
1502 __ Cls(x9, x25);
1503 __ Cls(w10, w26);
1504 __ Cls(x11, x26);
1505 END();
1506
1507 RUN();
1508
1509 ASSERT_EQUAL_64(8, x0);
1510 ASSERT_EQUAL_64(12, x1);
1511 ASSERT_EQUAL_64(0, x2);
1512 ASSERT_EQUAL_64(0, x3);
1513 ASSERT_EQUAL_64(32, x4);
1514 ASSERT_EQUAL_64(64, x5);
1515 ASSERT_EQUAL_64(7, x6);
1516 ASSERT_EQUAL_64(11, x7);
1517 ASSERT_EQUAL_64(12, x8);
1518 ASSERT_EQUAL_64(8, x9);
1519 ASSERT_EQUAL_64(31, x10);
1520 ASSERT_EQUAL_64(63, x11);
1521
1522 TEARDOWN();
1523}
1524
1525
1526TEST(label) {
1527 SETUP();
1528
1529 Label label_1, label_2, label_3, label_4;
1530
1531 START();
1532 __ Mov(x0, 0x1);
1533 __ Mov(x1, 0x0);
1534 __ Mov(x22, lr); // Save lr.
1535
1536 __ B(&label_1);
1537 __ B(&label_1);
1538 __ B(&label_1); // Multiple branches to the same label.
1539 __ Mov(x0, 0x0);
1540 __ Bind(&label_2);
1541 __ B(&label_3); // Forward branch.
1542 __ Mov(x0, 0x0);
1543 __ Bind(&label_1);
1544 __ B(&label_2); // Backward branch.
1545 __ Mov(x0, 0x0);
1546 __ Bind(&label_3);
1547 __ Bl(&label_4);
1548 END();
1549
1550 __ Bind(&label_4);
1551 __ Mov(x1, 0x1);
1552 __ Mov(lr, x22);
1553 END();
1554
1555 RUN();
1556
1557 ASSERT_EQUAL_64(0x1, x0);
1558 ASSERT_EQUAL_64(0x1, x1);
1559
1560 TEARDOWN();
1561}
1562
1563
1564TEST(adr) {
1565 SETUP();
1566
1567 Label label_1, label_2, label_3, label_4;
1568
1569 START();
1570 __ Mov(x0, 0x0); // Set to non-zero to indicate failure.
1571 __ Adr(x1, &label_3); // Set to zero to indicate success.
1572
1573 __ Adr(x2, &label_1); // Multiple forward references to the same label.
1574 __ Adr(x3, &label_1);
1575 __ Adr(x4, &label_1);
1576
1577 __ Bind(&label_2);
1578 __ Eor(x5, x2, Operand(x3)); // Ensure that x2,x3 and x4 are identical.
1579 __ Eor(x6, x2, Operand(x4));
1580 __ Orr(x0, x0, Operand(x5));
1581 __ Orr(x0, x0, Operand(x6));
1582 __ Br(x2); // label_1, label_3
1583
1584 __ Bind(&label_3);
1585 __ Adr(x2, &label_3); // Self-reference (offset 0).
1586 __ Eor(x1, x1, Operand(x2));
1587 __ Adr(x2, &label_4); // Simple forward reference.
1588 __ Br(x2); // label_4
1589
1590 __ Bind(&label_1);
1591 __ Adr(x2, &label_3); // Multiple reverse references to the same label.
1592 __ Adr(x3, &label_3);
1593 __ Adr(x4, &label_3);
1594 __ Adr(x5, &label_2); // Simple reverse reference.
1595 __ Br(x5); // label_2
1596
1597 __ Bind(&label_4);
1598 END();
1599
1600 RUN();
1601
1602 ASSERT_EQUAL_64(0x0, x0);
1603 ASSERT_EQUAL_64(0x0, x1);
1604
1605 TEARDOWN();
1606}
1607
1608
armvixl4a102ba2014-07-14 09:02:40 +01001609// Simple adrp tests: check that labels are linked and handled properly.
1610// This is similar to the adr test, but all the adrp instructions are put on the
1611// same page so that they return the same value.
1612TEST(adrp) {
1613 Label start;
1614 Label label_1, label_2, label_3;
1615
1616 SETUP_CUSTOM(2 * kPageSize, PageOffsetDependentCode);
1617 START();
1618
1619 // Waste space until the start of a page.
1620 { InstructionAccurateScope scope(&masm);
1621 const uintptr_t kPageOffsetMask = kPageSize - 1;
1622 while ((GetPCAddress<uintptr_t>(&masm, buf) & kPageOffsetMask) != 0) {
1623 __ b(&start);
1624 }
1625 __ bind(&start);
1626 }
1627
1628 // Simple forward reference.
1629 __ Adrp(x0, &label_2);
1630
1631 __ Bind(&label_1);
1632
1633 // Multiple forward references to the same label.
1634 __ Adrp(x1, &label_3);
1635 __ Adrp(x2, &label_3);
1636 __ Adrp(x3, &label_3);
1637
1638 __ Bind(&label_2);
1639
1640 // Self-reference (offset 0).
1641 __ Adrp(x4, &label_2);
1642
1643 __ Bind(&label_3);
1644
1645 // Simple reverse reference.
1646 __ Adrp(x5, &label_1);
1647
1648 // Multiple reverse references to the same label.
1649 __ Adrp(x6, &label_2);
1650 __ Adrp(x7, &label_2);
1651 __ Adrp(x8, &label_2);
1652
1653 VIXL_ASSERT(masm.SizeOfCodeGeneratedSince(&start) < kPageSize);
1654 END();
1655 RUN();
1656
1657 uint64_t expected = reinterpret_cast<uint64_t>(
1658 AlignDown(masm.GetLabelAddress<uint64_t*>(&start), kPageSize));
1659 ASSERT_EQUAL_64(expected, x0);
1660 ASSERT_EQUAL_64(expected, x1);
1661 ASSERT_EQUAL_64(expected, x2);
1662 ASSERT_EQUAL_64(expected, x3);
1663 ASSERT_EQUAL_64(expected, x4);
1664 ASSERT_EQUAL_64(expected, x5);
1665 ASSERT_EQUAL_64(expected, x6);
1666 ASSERT_EQUAL_64(expected, x7);
1667 ASSERT_EQUAL_64(expected, x8);
1668
1669 TEARDOWN();
1670}
1671
1672
1673static void AdrpPageBoundaryHelper(unsigned offset_into_page) {
1674 VIXL_ASSERT(offset_into_page < kPageSize);
1675 VIXL_ASSERT((offset_into_page % kInstructionSize) == 0);
1676
1677 const uintptr_t kPageOffsetMask = kPageSize - 1;
1678
1679 // The test label is always bound on page 0. Adrp instructions are generated
1680 // on pages from kStartPage to kEndPage (inclusive).
1681 const int kStartPage = -16;
1682 const int kEndPage = 16;
1683
1684 SETUP_CUSTOM((kEndPage - kStartPage + 3) * kPageSize,
1685 PageOffsetDependentCode);
1686 START();
1687
1688 // Initialize NZCV with `eq` flags.
1689 __ Cmp(wzr, wzr);
1690
1691 Label test;
1692 { InstructionAccurateScope scope(&masm);
1693 Label start;
1694
1695 // Waste space until the start of a page.
1696 while ((GetPCAddress<uintptr_t>(&masm, buf) & kPageOffsetMask) != 0) {
1697 __ b(&start);
1698 }
1699
1700 // The first page.
1701 VIXL_STATIC_ASSERT(kStartPage < 0);
1702 { InstructionAccurateScope scope_page(&masm, kPageSize / kInstructionSize);
1703 __ bind(&start);
1704 __ adrp(x0, &test);
1705 __ adrp(x1, &test);
1706 for (size_t i = 2; i < (kPageSize / kInstructionSize); i += 2) {
1707 __ ccmp(x0, x1, NoFlag, eq);
1708 __ adrp(x1, &test);
1709 }
1710 }
1711
1712 // Subsequent pages.
1713 VIXL_STATIC_ASSERT(kEndPage >= 0);
1714 for (int page = (kStartPage + 1); page <= kEndPage; page++) {
1715 InstructionAccurateScope scope_page(&masm, kPageSize / kInstructionSize);
1716 if (page == 0) {
1717 for (size_t i = 0; i < (kPageSize / kInstructionSize);) {
1718 if (i++ == (offset_into_page / kInstructionSize)) __ bind(&test);
1719 __ ccmp(x0, x1, NoFlag, eq);
1720 if (i++ == (offset_into_page / kInstructionSize)) __ bind(&test);
1721 __ adrp(x1, &test);
1722 }
1723 } else {
1724 for (size_t i = 0; i < (kPageSize / kInstructionSize); i += 2) {
1725 __ ccmp(x0, x1, NoFlag, eq);
1726 __ adrp(x1, &test);
1727 }
1728 }
1729 }
1730
1731 // Every adrp instruction pointed to the same label (`test`), so they should
1732 // all have produced the same result.
1733 }
1734
1735 END();
1736 RUN();
1737
1738 uintptr_t expected =
1739 AlignDown(masm.GetLabelAddress<uintptr_t>(&test), kPageSize);
1740 ASSERT_EQUAL_64(expected, x0);
1741 ASSERT_EQUAL_64(expected, x1);
1742 ASSERT_EQUAL_NZCV(ZCFlag);
1743
1744 TEARDOWN();
1745}
1746
1747
1748// Test that labels are correctly referenced by adrp across page boundaries.
1749TEST(adrp_page_boundaries) {
1750 VIXL_STATIC_ASSERT(kPageSize == 4096);
1751 AdrpPageBoundaryHelper(kInstructionSize * 0);
1752 AdrpPageBoundaryHelper(kInstructionSize * 1);
1753 AdrpPageBoundaryHelper(kInstructionSize * 512);
1754 AdrpPageBoundaryHelper(kInstructionSize * 1022);
1755 AdrpPageBoundaryHelper(kInstructionSize * 1023);
1756}
1757
1758
1759static void AdrpOffsetHelper(int64_t imm21) {
1760 const size_t kPageOffsetMask = kPageSize - 1;
1761
1762 SETUP_CUSTOM(kPageSize * 4, PageOffsetDependentCode);
1763 START();
1764
1765 // Initialize NZCV with `eq` flags.
1766 __ Cmp(wzr, wzr);
1767
1768 Label page;
1769 { InstructionAccurateScope scope(&masm);
1770 // Waste space until the start of a page.
1771 while ((GetPCAddress<uintptr_t>(&masm, buf) & kPageOffsetMask) != 0) {
1772 __ b(&page);
1773 }
1774 __ bind(&page);
1775
1776 { InstructionAccurateScope scope_page(&masm, kPageSize / kInstructionSize);
1777 // Every adrp instruction on this page should return the same value.
1778 __ adrp(x0, imm21);
1779 __ adrp(x1, imm21);
1780 for (size_t i = 2; i < kPageSize / kInstructionSize; i += 2) {
1781 __ ccmp(x0, x1, NoFlag, eq);
1782 __ adrp(x1, imm21);
1783 }
1784 }
1785 }
1786
1787 END();
1788 RUN();
1789
1790 uintptr_t expected =
1791 masm.GetLabelAddress<uintptr_t>(&page) + (kPageSize * imm21);
1792 ASSERT_EQUAL_64(expected, x0);
1793 ASSERT_EQUAL_64(expected, x1);
1794 ASSERT_EQUAL_NZCV(ZCFlag);
1795
1796 TEARDOWN();
1797}
1798
1799
1800// Check that adrp produces the correct result for a specific offset.
1801TEST(adrp_offset) {
1802 AdrpOffsetHelper(0);
1803 AdrpOffsetHelper(1);
1804 AdrpOffsetHelper(-1);
1805 AdrpOffsetHelper(4);
1806 AdrpOffsetHelper(-4);
1807 AdrpOffsetHelper(0x000fffff);
1808 AdrpOffsetHelper(-0x000fffff);
1809 AdrpOffsetHelper(-0x00100000);
1810}
1811
1812
armvixlad96eda2013-06-14 11:42:37 +01001813TEST(branch_cond) {
1814 SETUP();
1815
1816 Label wrong;
1817
1818 START();
1819 __ Mov(x0, 0x1);
1820 __ Mov(x1, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00001821 __ Mov(x2, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01001822
1823 // For each 'cmp' instruction below, condition codes other than the ones
1824 // following it would branch.
1825
armvixl578645f2013-08-15 17:21:42 +01001826 __ Cmp(x1, 0);
armvixlad96eda2013-06-14 11:42:37 +01001827 __ B(&wrong, eq);
1828 __ B(&wrong, lo);
1829 __ B(&wrong, mi);
1830 __ B(&wrong, vs);
1831 __ B(&wrong, ls);
1832 __ B(&wrong, lt);
1833 __ B(&wrong, le);
1834 Label ok_1;
1835 __ B(&ok_1, ne);
1836 __ Mov(x0, 0x0);
1837 __ Bind(&ok_1);
1838
armvixl578645f2013-08-15 17:21:42 +01001839 __ Cmp(x1, 1);
armvixlad96eda2013-06-14 11:42:37 +01001840 __ B(&wrong, ne);
1841 __ B(&wrong, lo);
1842 __ B(&wrong, mi);
1843 __ B(&wrong, vs);
1844 __ B(&wrong, hi);
1845 __ B(&wrong, lt);
1846 __ B(&wrong, gt);
1847 Label ok_2;
1848 __ B(&ok_2, pl);
1849 __ Mov(x0, 0x0);
1850 __ Bind(&ok_2);
1851
armvixl578645f2013-08-15 17:21:42 +01001852 __ Cmp(x1, 2);
armvixlad96eda2013-06-14 11:42:37 +01001853 __ B(&wrong, eq);
1854 __ B(&wrong, hs);
1855 __ B(&wrong, pl);
1856 __ B(&wrong, vs);
1857 __ B(&wrong, hi);
1858 __ B(&wrong, ge);
1859 __ B(&wrong, gt);
1860 Label ok_3;
1861 __ B(&ok_3, vc);
1862 __ Mov(x0, 0x0);
1863 __ Bind(&ok_3);
1864
armvixl578645f2013-08-15 17:21:42 +01001865 __ Cmp(x2, 1);
armvixlad96eda2013-06-14 11:42:37 +01001866 __ B(&wrong, eq);
1867 __ B(&wrong, lo);
1868 __ B(&wrong, mi);
1869 __ B(&wrong, vc);
1870 __ B(&wrong, ls);
1871 __ B(&wrong, ge);
1872 __ B(&wrong, gt);
1873 Label ok_4;
1874 __ B(&ok_4, le);
1875 __ Mov(x0, 0x0);
1876 __ Bind(&ok_4);
armvixl578645f2013-08-15 17:21:42 +01001877
1878 Label ok_5;
1879 __ b(&ok_5, al);
1880 __ Mov(x0, 0x0);
1881 __ Bind(&ok_5);
1882
1883 Label ok_6;
1884 __ b(&ok_6, nv);
1885 __ Mov(x0, 0x0);
1886 __ Bind(&ok_6);
1887
armvixlad96eda2013-06-14 11:42:37 +01001888 END();
1889
1890 __ Bind(&wrong);
1891 __ Mov(x0, 0x0);
1892 END();
1893
1894 RUN();
1895
1896 ASSERT_EQUAL_64(0x1, x0);
1897
1898 TEARDOWN();
1899}
1900
1901
1902TEST(branch_to_reg) {
1903 SETUP();
1904
1905 // Test br.
1906 Label fn1, after_fn1;
1907
1908 START();
1909 __ Mov(x29, lr);
1910
1911 __ Mov(x1, 0);
1912 __ B(&after_fn1);
1913
1914 __ Bind(&fn1);
1915 __ Mov(x0, lr);
1916 __ Mov(x1, 42);
1917 __ Br(x0);
1918
1919 __ Bind(&after_fn1);
1920 __ Bl(&fn1);
1921
1922 // Test blr.
1923 Label fn2, after_fn2;
1924
1925 __ Mov(x2, 0);
1926 __ B(&after_fn2);
1927
1928 __ Bind(&fn2);
1929 __ Mov(x0, lr);
1930 __ Mov(x2, 84);
1931 __ Blr(x0);
1932
1933 __ Bind(&after_fn2);
1934 __ Bl(&fn2);
1935 __ Mov(x3, lr);
1936
1937 __ Mov(lr, x29);
1938 END();
1939
1940 RUN();
1941
1942 ASSERT_EQUAL_64(core.xreg(3) + kInstructionSize, x0);
1943 ASSERT_EQUAL_64(42, x1);
1944 ASSERT_EQUAL_64(84, x2);
1945
1946 TEARDOWN();
1947}
1948
1949
1950TEST(compare_branch) {
1951 SETUP();
1952
1953 START();
1954 __ Mov(x0, 0);
1955 __ Mov(x1, 0);
1956 __ Mov(x2, 0);
1957 __ Mov(x3, 0);
1958 __ Mov(x4, 0);
1959 __ Mov(x5, 0);
1960 __ Mov(x16, 0);
1961 __ Mov(x17, 42);
1962
1963 Label zt, zt_end;
1964 __ Cbz(w16, &zt);
1965 __ B(&zt_end);
1966 __ Bind(&zt);
1967 __ Mov(x0, 1);
1968 __ Bind(&zt_end);
1969
1970 Label zf, zf_end;
1971 __ Cbz(x17, &zf);
1972 __ B(&zf_end);
1973 __ Bind(&zf);
1974 __ Mov(x1, 1);
1975 __ Bind(&zf_end);
1976
1977 Label nzt, nzt_end;
1978 __ Cbnz(w17, &nzt);
1979 __ B(&nzt_end);
1980 __ Bind(&nzt);
1981 __ Mov(x2, 1);
1982 __ Bind(&nzt_end);
1983
1984 Label nzf, nzf_end;
1985 __ Cbnz(x16, &nzf);
1986 __ B(&nzf_end);
1987 __ Bind(&nzf);
1988 __ Mov(x3, 1);
1989 __ Bind(&nzf_end);
1990
armvixlb0c8ae22014-03-21 14:03:59 +00001991 __ Mov(x18, 0xffffffff00000000);
armvixlad96eda2013-06-14 11:42:37 +01001992
1993 Label a, a_end;
1994 __ Cbz(w18, &a);
1995 __ B(&a_end);
1996 __ Bind(&a);
1997 __ Mov(x4, 1);
1998 __ Bind(&a_end);
1999
2000 Label b, b_end;
2001 __ Cbnz(w18, &b);
2002 __ B(&b_end);
2003 __ Bind(&b);
2004 __ Mov(x5, 1);
2005 __ Bind(&b_end);
2006
2007 END();
2008
2009 RUN();
2010
2011 ASSERT_EQUAL_64(1, x0);
2012 ASSERT_EQUAL_64(0, x1);
2013 ASSERT_EQUAL_64(1, x2);
2014 ASSERT_EQUAL_64(0, x3);
2015 ASSERT_EQUAL_64(1, x4);
2016 ASSERT_EQUAL_64(0, x5);
2017
2018 TEARDOWN();
2019}
2020
2021
2022TEST(test_branch) {
2023 SETUP();
2024
2025 START();
2026 __ Mov(x0, 0);
2027 __ Mov(x1, 0);
2028 __ Mov(x2, 0);
2029 __ Mov(x3, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00002030 __ Mov(x16, 0xaaaaaaaaaaaaaaaa);
armvixlad96eda2013-06-14 11:42:37 +01002031
2032 Label bz, bz_end;
armvixlf37fdc02014-02-05 13:22:16 +00002033 __ Tbz(w16, 0, &bz);
armvixlad96eda2013-06-14 11:42:37 +01002034 __ B(&bz_end);
2035 __ Bind(&bz);
2036 __ Mov(x0, 1);
2037 __ Bind(&bz_end);
2038
2039 Label bo, bo_end;
2040 __ Tbz(x16, 63, &bo);
2041 __ B(&bo_end);
2042 __ Bind(&bo);
2043 __ Mov(x1, 1);
2044 __ Bind(&bo_end);
2045
2046 Label nbz, nbz_end;
2047 __ Tbnz(x16, 61, &nbz);
2048 __ B(&nbz_end);
2049 __ Bind(&nbz);
2050 __ Mov(x2, 1);
2051 __ Bind(&nbz_end);
2052
2053 Label nbo, nbo_end;
armvixlf37fdc02014-02-05 13:22:16 +00002054 __ Tbnz(w16, 2, &nbo);
armvixlad96eda2013-06-14 11:42:37 +01002055 __ B(&nbo_end);
2056 __ Bind(&nbo);
2057 __ Mov(x3, 1);
2058 __ Bind(&nbo_end);
2059 END();
2060
2061 RUN();
2062
2063 ASSERT_EQUAL_64(1, x0);
2064 ASSERT_EQUAL_64(0, x1);
2065 ASSERT_EQUAL_64(1, x2);
2066 ASSERT_EQUAL_64(0, x3);
2067
2068 TEARDOWN();
2069}
2070
2071
armvixlb0c8ae22014-03-21 14:03:59 +00002072TEST(branch_type) {
2073 SETUP();
2074
2075 Label fail, done;
2076
2077 START();
2078 __ Mov(x0, 0x0);
2079 __ Mov(x10, 0x7);
2080 __ Mov(x11, 0x0);
2081
2082 // Test non taken branches.
2083 __ Cmp(x10, 0x7);
2084 __ B(&fail, ne);
2085 __ B(&fail, never);
2086 __ B(&fail, reg_zero, x10);
2087 __ B(&fail, reg_not_zero, x11);
2088 __ B(&fail, reg_bit_clear, x10, 0);
2089 __ B(&fail, reg_bit_set, x10, 3);
2090
2091 // Test taken branches.
2092 Label l1, l2, l3, l4, l5;
2093 __ Cmp(x10, 0x7);
2094 __ B(&l1, eq);
2095 __ B(&fail);
2096 __ Bind(&l1);
2097 __ B(&l2, always);
2098 __ B(&fail);
2099 __ Bind(&l2);
2100 __ B(&l3, reg_not_zero, x10);
2101 __ B(&fail);
2102 __ Bind(&l3);
2103 __ B(&l4, reg_bit_clear, x10, 15);
2104 __ B(&fail);
2105 __ Bind(&l4);
2106 __ B(&l5, reg_bit_set, x10, 1);
2107 __ B(&fail);
2108 __ Bind(&l5);
2109
2110 __ B(&done);
2111
2112 __ Bind(&fail);
2113 __ Mov(x0, 0x1);
2114
2115 __ Bind(&done);
2116
2117 END();
2118
2119 RUN();
2120
2121 ASSERT_EQUAL_64(0x0, x0);
2122
2123 TEARDOWN();
2124}
2125
2126
armvixlad96eda2013-06-14 11:42:37 +01002127TEST(ldr_str_offset) {
2128 SETUP();
2129
armvixlb0c8ae22014-03-21 14:03:59 +00002130 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002131 uint64_t dst[5] = {0, 0, 0, 0, 0};
2132 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2133 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2134
2135 START();
2136 __ Mov(x17, src_base);
2137 __ Mov(x18, dst_base);
2138 __ Ldr(w0, MemOperand(x17));
2139 __ Str(w0, MemOperand(x18));
2140 __ Ldr(w1, MemOperand(x17, 4));
2141 __ Str(w1, MemOperand(x18, 12));
2142 __ Ldr(x2, MemOperand(x17, 8));
2143 __ Str(x2, MemOperand(x18, 16));
2144 __ Ldrb(w3, MemOperand(x17, 1));
2145 __ Strb(w3, MemOperand(x18, 25));
2146 __ Ldrh(w4, MemOperand(x17, 2));
2147 __ Strh(w4, MemOperand(x18, 33));
2148 END();
2149
2150 RUN();
2151
2152 ASSERT_EQUAL_64(0x76543210, x0);
2153 ASSERT_EQUAL_64(0x76543210, dst[0]);
2154 ASSERT_EQUAL_64(0xfedcba98, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00002155 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2156 ASSERT_EQUAL_64(0x0123456789abcdef, x2);
2157 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
armvixlad96eda2013-06-14 11:42:37 +01002158 ASSERT_EQUAL_64(0x32, x3);
2159 ASSERT_EQUAL_64(0x3200, dst[3]);
2160 ASSERT_EQUAL_64(0x7654, x4);
2161 ASSERT_EQUAL_64(0x765400, dst[4]);
2162 ASSERT_EQUAL_64(src_base, x17);
2163 ASSERT_EQUAL_64(dst_base, x18);
2164
2165 TEARDOWN();
2166}
2167
2168
2169TEST(ldr_str_wide) {
2170 SETUP();
2171
2172 uint32_t src[8192];
2173 uint32_t dst[8192];
2174 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2175 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2176 memset(src, 0xaa, 8192 * sizeof(src[0]));
2177 memset(dst, 0xaa, 8192 * sizeof(dst[0]));
2178 src[0] = 0;
2179 src[6144] = 6144;
2180 src[8191] = 8191;
2181
2182 START();
2183 __ Mov(x22, src_base);
2184 __ Mov(x23, dst_base);
2185 __ Mov(x24, src_base);
2186 __ Mov(x25, dst_base);
2187 __ Mov(x26, src_base);
2188 __ Mov(x27, dst_base);
2189
2190 __ Ldr(w0, MemOperand(x22, 8191 * sizeof(src[0])));
2191 __ Str(w0, MemOperand(x23, 8191 * sizeof(dst[0])));
2192 __ Ldr(w1, MemOperand(x24, 4096 * sizeof(src[0]), PostIndex));
2193 __ Str(w1, MemOperand(x25, 4096 * sizeof(dst[0]), PostIndex));
2194 __ Ldr(w2, MemOperand(x26, 6144 * sizeof(src[0]), PreIndex));
2195 __ Str(w2, MemOperand(x27, 6144 * sizeof(dst[0]), PreIndex));
2196 END();
2197
2198 RUN();
2199
2200 ASSERT_EQUAL_32(8191, w0);
2201 ASSERT_EQUAL_32(8191, dst[8191]);
2202 ASSERT_EQUAL_64(src_base, x22);
2203 ASSERT_EQUAL_64(dst_base, x23);
2204 ASSERT_EQUAL_32(0, w1);
2205 ASSERT_EQUAL_32(0, dst[0]);
2206 ASSERT_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24);
2207 ASSERT_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25);
2208 ASSERT_EQUAL_32(6144, w2);
2209 ASSERT_EQUAL_32(6144, dst[6144]);
2210 ASSERT_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26);
2211 ASSERT_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27);
2212
2213 TEARDOWN();
2214}
2215
2216
2217TEST(ldr_str_preindex) {
2218 SETUP();
2219
armvixlb0c8ae22014-03-21 14:03:59 +00002220 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002221 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2222 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2223 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2224
2225 START();
2226 __ Mov(x17, src_base);
2227 __ Mov(x18, dst_base);
2228 __ Mov(x19, src_base);
2229 __ Mov(x20, dst_base);
2230 __ Mov(x21, src_base + 16);
2231 __ Mov(x22, dst_base + 40);
2232 __ Mov(x23, src_base);
2233 __ Mov(x24, dst_base);
2234 __ Mov(x25, src_base);
2235 __ Mov(x26, dst_base);
2236 __ Ldr(w0, MemOperand(x17, 4, PreIndex));
2237 __ Str(w0, MemOperand(x18, 12, PreIndex));
2238 __ Ldr(x1, MemOperand(x19, 8, PreIndex));
2239 __ Str(x1, MemOperand(x20, 16, PreIndex));
2240 __ Ldr(w2, MemOperand(x21, -4, PreIndex));
2241 __ Str(w2, MemOperand(x22, -4, PreIndex));
2242 __ Ldrb(w3, MemOperand(x23, 1, PreIndex));
2243 __ Strb(w3, MemOperand(x24, 25, PreIndex));
2244 __ Ldrh(w4, MemOperand(x25, 3, PreIndex));
2245 __ Strh(w4, MemOperand(x26, 41, PreIndex));
2246 END();
2247
2248 RUN();
2249
2250 ASSERT_EQUAL_64(0xfedcba98, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002251 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2252 ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2253 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
armvixlad96eda2013-06-14 11:42:37 +01002254 ASSERT_EQUAL_64(0x01234567, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00002255 ASSERT_EQUAL_64(0x0123456700000000, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01002256 ASSERT_EQUAL_64(0x32, x3);
2257 ASSERT_EQUAL_64(0x3200, dst[3]);
2258 ASSERT_EQUAL_64(0x9876, x4);
2259 ASSERT_EQUAL_64(0x987600, dst[5]);
2260 ASSERT_EQUAL_64(src_base + 4, x17);
2261 ASSERT_EQUAL_64(dst_base + 12, x18);
2262 ASSERT_EQUAL_64(src_base + 8, x19);
2263 ASSERT_EQUAL_64(dst_base + 16, x20);
2264 ASSERT_EQUAL_64(src_base + 12, x21);
2265 ASSERT_EQUAL_64(dst_base + 36, x22);
2266 ASSERT_EQUAL_64(src_base + 1, x23);
2267 ASSERT_EQUAL_64(dst_base + 25, x24);
2268 ASSERT_EQUAL_64(src_base + 3, x25);
2269 ASSERT_EQUAL_64(dst_base + 41, x26);
2270
2271 TEARDOWN();
2272}
2273
2274
2275TEST(ldr_str_postindex) {
2276 SETUP();
2277
armvixlb0c8ae22014-03-21 14:03:59 +00002278 uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002279 uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
2280 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2281 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2282
2283 START();
2284 __ Mov(x17, src_base + 4);
2285 __ Mov(x18, dst_base + 12);
2286 __ Mov(x19, src_base + 8);
2287 __ Mov(x20, dst_base + 16);
2288 __ Mov(x21, src_base + 8);
2289 __ Mov(x22, dst_base + 32);
2290 __ Mov(x23, src_base + 1);
2291 __ Mov(x24, dst_base + 25);
2292 __ Mov(x25, src_base + 3);
2293 __ Mov(x26, dst_base + 41);
2294 __ Ldr(w0, MemOperand(x17, 4, PostIndex));
2295 __ Str(w0, MemOperand(x18, 12, PostIndex));
2296 __ Ldr(x1, MemOperand(x19, 8, PostIndex));
2297 __ Str(x1, MemOperand(x20, 16, PostIndex));
2298 __ Ldr(x2, MemOperand(x21, -8, PostIndex));
2299 __ Str(x2, MemOperand(x22, -32, PostIndex));
2300 __ Ldrb(w3, MemOperand(x23, 1, PostIndex));
2301 __ Strb(w3, MemOperand(x24, 5, PostIndex));
2302 __ Ldrh(w4, MemOperand(x25, -3, PostIndex));
2303 __ Strh(w4, MemOperand(x26, -41, PostIndex));
2304 END();
2305
2306 RUN();
2307
2308 ASSERT_EQUAL_64(0xfedcba98, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002309 ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
2310 ASSERT_EQUAL_64(0x0123456789abcdef, x1);
2311 ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
2312 ASSERT_EQUAL_64(0x0123456789abcdef, x2);
2313 ASSERT_EQUAL_64(0x0123456789abcdef, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01002314 ASSERT_EQUAL_64(0x32, x3);
2315 ASSERT_EQUAL_64(0x3200, dst[3]);
2316 ASSERT_EQUAL_64(0x9876, x4);
2317 ASSERT_EQUAL_64(0x987600, dst[5]);
2318 ASSERT_EQUAL_64(src_base + 8, x17);
2319 ASSERT_EQUAL_64(dst_base + 24, x18);
2320 ASSERT_EQUAL_64(src_base + 16, x19);
2321 ASSERT_EQUAL_64(dst_base + 32, x20);
2322 ASSERT_EQUAL_64(src_base, x21);
2323 ASSERT_EQUAL_64(dst_base, x22);
2324 ASSERT_EQUAL_64(src_base + 2, x23);
2325 ASSERT_EQUAL_64(dst_base + 30, x24);
2326 ASSERT_EQUAL_64(src_base, x25);
2327 ASSERT_EQUAL_64(dst_base, x26);
2328
2329 TEARDOWN();
2330}
2331
2332
2333TEST(ldr_str_largeindex) {
2334 SETUP();
2335
2336 // This value won't fit in the immediate offset field of ldr/str instructions.
2337 int largeoffset = 0xabcdef;
2338
2339 int64_t data[3] = { 0x1122334455667788, 0, 0 };
armvixlb0c8ae22014-03-21 14:03:59 +00002340 uint64_t base_addr = reinterpret_cast<uintptr_t>(data);
2341 uint64_t drifted_addr = base_addr - largeoffset;
armvixlad96eda2013-06-14 11:42:37 +01002342
2343 // This test checks that we we can use large immediate offsets when
2344 // using PreIndex or PostIndex addressing mode of the MacroAssembler
2345 // Ldr/Str instructions.
2346
2347 START();
armvixlad96eda2013-06-14 11:42:37 +01002348 __ Mov(x19, drifted_addr);
armvixlb0c8ae22014-03-21 14:03:59 +00002349 __ Ldr(x0, MemOperand(x19, largeoffset, PreIndex));
armvixlad96eda2013-06-14 11:42:37 +01002350
armvixlb0c8ae22014-03-21 14:03:59 +00002351 __ Mov(x20, base_addr);
2352 __ Ldr(x1, MemOperand(x20, largeoffset, PostIndex));
2353
2354 __ Mov(x21, drifted_addr);
2355 __ Str(x0, MemOperand(x21, largeoffset + 8, PreIndex));
2356
2357 __ Mov(x22, base_addr + 16);
2358 __ Str(x0, MemOperand(x22, largeoffset, PostIndex));
armvixlad96eda2013-06-14 11:42:37 +01002359 END();
2360
2361 RUN();
2362
2363 ASSERT_EQUAL_64(0x1122334455667788, data[0]);
2364 ASSERT_EQUAL_64(0x1122334455667788, data[1]);
2365 ASSERT_EQUAL_64(0x1122334455667788, data[2]);
2366 ASSERT_EQUAL_64(0x1122334455667788, x0);
2367 ASSERT_EQUAL_64(0x1122334455667788, x1);
2368
armvixlb0c8ae22014-03-21 14:03:59 +00002369 ASSERT_EQUAL_64(base_addr, x19);
2370 ASSERT_EQUAL_64(base_addr + largeoffset, x20);
2371 ASSERT_EQUAL_64(base_addr + 8, x21);
2372 ASSERT_EQUAL_64(base_addr + 16 + largeoffset, x22);
armvixlad96eda2013-06-14 11:42:37 +01002373
2374 TEARDOWN();
2375}
2376
2377
2378TEST(load_signed) {
2379 SETUP();
2380
2381 uint32_t src[2] = {0x80008080, 0x7fff7f7f};
2382 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2383
2384 START();
2385 __ Mov(x24, src_base);
2386 __ Ldrsb(w0, MemOperand(x24));
2387 __ Ldrsb(w1, MemOperand(x24, 4));
2388 __ Ldrsh(w2, MemOperand(x24));
2389 __ Ldrsh(w3, MemOperand(x24, 4));
2390 __ Ldrsb(x4, MemOperand(x24));
2391 __ Ldrsb(x5, MemOperand(x24, 4));
2392 __ Ldrsh(x6, MemOperand(x24));
2393 __ Ldrsh(x7, MemOperand(x24, 4));
2394 __ Ldrsw(x8, MemOperand(x24));
2395 __ Ldrsw(x9, MemOperand(x24, 4));
2396 END();
2397
2398 RUN();
2399
2400 ASSERT_EQUAL_64(0xffffff80, x0);
2401 ASSERT_EQUAL_64(0x0000007f, x1);
2402 ASSERT_EQUAL_64(0xffff8080, x2);
2403 ASSERT_EQUAL_64(0x00007f7f, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00002404 ASSERT_EQUAL_64(0xffffffffffffff80, x4);
2405 ASSERT_EQUAL_64(0x000000000000007f, x5);
2406 ASSERT_EQUAL_64(0xffffffffffff8080, x6);
2407 ASSERT_EQUAL_64(0x0000000000007f7f, x7);
2408 ASSERT_EQUAL_64(0xffffffff80008080, x8);
2409 ASSERT_EQUAL_64(0x000000007fff7f7f, x9);
armvixlad96eda2013-06-14 11:42:37 +01002410
2411 TEARDOWN();
2412}
2413
2414
2415TEST(load_store_regoffset) {
2416 SETUP();
2417
2418 uint32_t src[3] = {1, 2, 3};
2419 uint32_t dst[4] = {0, 0, 0, 0};
2420 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2421 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2422
2423 START();
2424 __ Mov(x16, src_base);
2425 __ Mov(x17, dst_base);
2426 __ Mov(x18, src_base + 3 * sizeof(src[0]));
2427 __ Mov(x19, dst_base + 3 * sizeof(dst[0]));
2428 __ Mov(x20, dst_base + 4 * sizeof(dst[0]));
2429 __ Mov(x24, 0);
2430 __ Mov(x25, 4);
2431 __ Mov(x26, -4);
2432 __ Mov(x27, 0xfffffffc); // 32-bit -4.
2433 __ Mov(x28, 0xfffffffe); // 32-bit -2.
2434 __ Mov(x29, 0xffffffff); // 32-bit -1.
2435
2436 __ Ldr(w0, MemOperand(x16, x24));
2437 __ Ldr(x1, MemOperand(x16, x25));
2438 __ Ldr(w2, MemOperand(x18, x26));
2439 __ Ldr(w3, MemOperand(x18, x27, SXTW));
2440 __ Ldr(w4, MemOperand(x18, x28, SXTW, 2));
2441 __ Str(w0, MemOperand(x17, x24));
2442 __ Str(x1, MemOperand(x17, x25));
2443 __ Str(w2, MemOperand(x20, x29, SXTW, 2));
2444 END();
2445
2446 RUN();
2447
2448 ASSERT_EQUAL_64(1, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002449 ASSERT_EQUAL_64(0x0000000300000002, x1);
armvixlad96eda2013-06-14 11:42:37 +01002450 ASSERT_EQUAL_64(3, x2);
2451 ASSERT_EQUAL_64(3, x3);
2452 ASSERT_EQUAL_64(2, x4);
2453 ASSERT_EQUAL_32(1, dst[0]);
2454 ASSERT_EQUAL_32(2, dst[1]);
2455 ASSERT_EQUAL_32(3, dst[2]);
2456 ASSERT_EQUAL_32(3, dst[3]);
2457
2458 TEARDOWN();
2459}
2460
2461
2462TEST(load_store_float) {
2463 SETUP();
2464
2465 float src[3] = {1.0, 2.0, 3.0};
2466 float dst[3] = {0.0, 0.0, 0.0};
2467 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2468 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2469
2470 START();
2471 __ Mov(x17, src_base);
2472 __ Mov(x18, dst_base);
2473 __ Mov(x19, src_base);
2474 __ Mov(x20, dst_base);
2475 __ Mov(x21, src_base);
2476 __ Mov(x22, dst_base);
2477 __ Ldr(s0, MemOperand(x17, sizeof(src[0])));
2478 __ Str(s0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2479 __ Ldr(s1, MemOperand(x19, sizeof(src[0]), PostIndex));
2480 __ Str(s1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2481 __ Ldr(s2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2482 __ Str(s2, MemOperand(x22, sizeof(dst[0])));
2483 END();
2484
2485 RUN();
2486
2487 ASSERT_EQUAL_FP32(2.0, s0);
2488 ASSERT_EQUAL_FP32(2.0, dst[0]);
2489 ASSERT_EQUAL_FP32(1.0, s1);
2490 ASSERT_EQUAL_FP32(1.0, dst[2]);
2491 ASSERT_EQUAL_FP32(3.0, s2);
2492 ASSERT_EQUAL_FP32(3.0, dst[1]);
2493 ASSERT_EQUAL_64(src_base, x17);
2494 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2495 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2496 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2497 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2498 ASSERT_EQUAL_64(dst_base, x22);
2499
2500 TEARDOWN();
2501}
2502
2503
2504TEST(load_store_double) {
2505 SETUP();
2506
2507 double src[3] = {1.0, 2.0, 3.0};
2508 double dst[3] = {0.0, 0.0, 0.0};
2509 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2510 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2511
2512 START();
2513 __ Mov(x17, src_base);
2514 __ Mov(x18, dst_base);
2515 __ Mov(x19, src_base);
2516 __ Mov(x20, dst_base);
2517 __ Mov(x21, src_base);
2518 __ Mov(x22, dst_base);
2519 __ Ldr(d0, MemOperand(x17, sizeof(src[0])));
2520 __ Str(d0, MemOperand(x18, sizeof(dst[0]), PostIndex));
2521 __ Ldr(d1, MemOperand(x19, sizeof(src[0]), PostIndex));
2522 __ Str(d1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
2523 __ Ldr(d2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
2524 __ Str(d2, MemOperand(x22, sizeof(dst[0])));
2525 END();
2526
2527 RUN();
2528
2529 ASSERT_EQUAL_FP64(2.0, d0);
2530 ASSERT_EQUAL_FP64(2.0, dst[0]);
2531 ASSERT_EQUAL_FP64(1.0, d1);
2532 ASSERT_EQUAL_FP64(1.0, dst[2]);
2533 ASSERT_EQUAL_FP64(3.0, d2);
2534 ASSERT_EQUAL_FP64(3.0, dst[1]);
2535 ASSERT_EQUAL_64(src_base, x17);
2536 ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
2537 ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
2538 ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
2539 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
2540 ASSERT_EQUAL_64(dst_base, x22);
2541
2542 TEARDOWN();
2543}
2544
2545
2546TEST(ldp_stp_float) {
2547 SETUP();
2548
2549 float src[2] = {1.0, 2.0};
2550 float dst[3] = {0.0, 0.0, 0.0};
2551 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2552 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2553
2554 START();
2555 __ Mov(x16, src_base);
2556 __ Mov(x17, dst_base);
2557 __ Ldp(s31, s0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
2558 __ Stp(s0, s31, MemOperand(x17, sizeof(dst[1]), PreIndex));
2559 END();
2560
2561 RUN();
2562
2563 ASSERT_EQUAL_FP32(1.0, s31);
2564 ASSERT_EQUAL_FP32(2.0, s0);
2565 ASSERT_EQUAL_FP32(0.0, dst[0]);
2566 ASSERT_EQUAL_FP32(2.0, dst[1]);
2567 ASSERT_EQUAL_FP32(1.0, dst[2]);
2568 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
2569 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
2570
2571 TEARDOWN();
2572}
2573
2574
2575TEST(ldp_stp_double) {
2576 SETUP();
2577
2578 double src[2] = {1.0, 2.0};
2579 double dst[3] = {0.0, 0.0, 0.0};
2580 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2581 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2582
2583 START();
2584 __ Mov(x16, src_base);
2585 __ Mov(x17, dst_base);
2586 __ Ldp(d31, d0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
2587 __ Stp(d0, d31, MemOperand(x17, sizeof(dst[1]), PreIndex));
2588 END();
2589
2590 RUN();
2591
2592 ASSERT_EQUAL_FP64(1.0, d31);
2593 ASSERT_EQUAL_FP64(2.0, d0);
2594 ASSERT_EQUAL_FP64(0.0, dst[0]);
2595 ASSERT_EQUAL_FP64(2.0, dst[1]);
2596 ASSERT_EQUAL_FP64(1.0, dst[2]);
2597 ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
2598 ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
2599
2600 TEARDOWN();
2601}
2602
2603
2604TEST(ldp_stp_offset) {
2605 SETUP();
2606
armvixlb0c8ae22014-03-21 14:03:59 +00002607 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
2608 0xffeeddccbbaa9988};
armvixlad96eda2013-06-14 11:42:37 +01002609 uint64_t dst[7] = {0, 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(x16, src_base);
2615 __ Mov(x17, dst_base);
2616 __ Mov(x18, src_base + 24);
2617 __ Mov(x19, dst_base + 56);
2618 __ Ldp(w0, w1, MemOperand(x16));
2619 __ Ldp(w2, w3, MemOperand(x16, 4));
2620 __ Ldp(x4, x5, MemOperand(x16, 8));
2621 __ Ldp(w6, w7, MemOperand(x18, -12));
2622 __ Ldp(x8, x9, MemOperand(x18, -16));
2623 __ Stp(w0, w1, MemOperand(x17));
2624 __ Stp(w2, w3, MemOperand(x17, 8));
2625 __ Stp(x4, x5, MemOperand(x17, 16));
2626 __ Stp(w6, w7, MemOperand(x19, -24));
2627 __ Stp(x8, x9, MemOperand(x19, -16));
2628 END();
2629
2630 RUN();
2631
2632 ASSERT_EQUAL_64(0x44556677, x0);
2633 ASSERT_EQUAL_64(0x00112233, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00002634 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
armvixlad96eda2013-06-14 11:42:37 +01002635 ASSERT_EQUAL_64(0x00112233, x2);
2636 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00002637 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
2638 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
2639 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
2640 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
2641 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01002642 ASSERT_EQUAL_64(0x8899aabb, x6);
2643 ASSERT_EQUAL_64(0xbbaa9988, x7);
armvixlb0c8ae22014-03-21 14:03:59 +00002644 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
2645 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
2646 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
2647 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
2648 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
armvixlad96eda2013-06-14 11:42:37 +01002649 ASSERT_EQUAL_64(src_base, x16);
2650 ASSERT_EQUAL_64(dst_base, x17);
2651 ASSERT_EQUAL_64(src_base + 24, x18);
2652 ASSERT_EQUAL_64(dst_base + 56, x19);
2653
2654 TEARDOWN();
2655}
2656
2657
2658TEST(ldnp_stnp_offset) {
2659 SETUP();
2660
armvixlb0c8ae22014-03-21 14:03:59 +00002661 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
2662 0xffeeddccbbaa9988};
armvixlad96eda2013-06-14 11:42:37 +01002663 uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
2664 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2665 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2666
2667 START();
2668 __ Mov(x16, src_base);
2669 __ Mov(x17, dst_base);
2670 __ Mov(x18, src_base + 24);
2671 __ Mov(x19, dst_base + 56);
2672 __ Ldnp(w0, w1, MemOperand(x16));
2673 __ Ldnp(w2, w3, MemOperand(x16, 4));
2674 __ Ldnp(x4, x5, MemOperand(x16, 8));
2675 __ Ldnp(w6, w7, MemOperand(x18, -12));
2676 __ Ldnp(x8, x9, MemOperand(x18, -16));
2677 __ Stnp(w0, w1, MemOperand(x17));
2678 __ Stnp(w2, w3, MemOperand(x17, 8));
2679 __ Stnp(x4, x5, MemOperand(x17, 16));
2680 __ Stnp(w6, w7, MemOperand(x19, -24));
2681 __ Stnp(x8, x9, MemOperand(x19, -16));
2682 END();
2683
2684 RUN();
2685
2686 ASSERT_EQUAL_64(0x44556677, x0);
2687 ASSERT_EQUAL_64(0x00112233, x1);
armvixlb0c8ae22014-03-21 14:03:59 +00002688 ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
armvixlad96eda2013-06-14 11:42:37 +01002689 ASSERT_EQUAL_64(0x00112233, x2);
2690 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00002691 ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
2692 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
2693 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
2694 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
2695 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01002696 ASSERT_EQUAL_64(0x8899aabb, x6);
2697 ASSERT_EQUAL_64(0xbbaa9988, x7);
armvixlb0c8ae22014-03-21 14:03:59 +00002698 ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
2699 ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
2700 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
2701 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
2702 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
armvixlad96eda2013-06-14 11:42:37 +01002703 ASSERT_EQUAL_64(src_base, x16);
2704 ASSERT_EQUAL_64(dst_base, x17);
2705 ASSERT_EQUAL_64(src_base + 24, x18);
2706 ASSERT_EQUAL_64(dst_base + 56, x19);
2707
2708 TEARDOWN();
2709}
2710
2711
2712TEST(ldp_stp_preindex) {
2713 SETUP();
2714
armvixlb0c8ae22014-03-21 14:03:59 +00002715 uint64_t src[3] = {0x0011223344556677, 0x8899aabbccddeeff,
2716 0xffeeddccbbaa9988};
armvixlad96eda2013-06-14 11:42:37 +01002717 uint64_t dst[5] = {0, 0, 0, 0, 0};
2718 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2719 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2720
2721 START();
2722 __ Mov(x16, src_base);
2723 __ Mov(x17, dst_base);
2724 __ Mov(x18, dst_base + 16);
2725 __ Ldp(w0, w1, MemOperand(x16, 4, PreIndex));
2726 __ Mov(x19, x16);
2727 __ Ldp(w2, w3, MemOperand(x16, -4, PreIndex));
2728 __ Stp(w2, w3, MemOperand(x17, 4, PreIndex));
2729 __ Mov(x20, x17);
2730 __ Stp(w0, w1, MemOperand(x17, -4, PreIndex));
2731 __ Ldp(x4, x5, MemOperand(x16, 8, PreIndex));
2732 __ Mov(x21, x16);
2733 __ Ldp(x6, x7, MemOperand(x16, -8, PreIndex));
2734 __ Stp(x7, x6, MemOperand(x18, 8, PreIndex));
2735 __ Mov(x22, x18);
2736 __ Stp(x5, x4, MemOperand(x18, -8, PreIndex));
2737 END();
2738
2739 RUN();
2740
2741 ASSERT_EQUAL_64(0x00112233, x0);
2742 ASSERT_EQUAL_64(0xccddeeff, x1);
2743 ASSERT_EQUAL_64(0x44556677, x2);
2744 ASSERT_EQUAL_64(0x00112233, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00002745 ASSERT_EQUAL_64(0xccddeeff00112233, dst[0]);
2746 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
2747 ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
2748 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
2749 ASSERT_EQUAL_64(0x0011223344556677, x6);
2750 ASSERT_EQUAL_64(0x8899aabbccddeeff, x7);
2751 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
2752 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
2753 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01002754 ASSERT_EQUAL_64(src_base, x16);
2755 ASSERT_EQUAL_64(dst_base, x17);
2756 ASSERT_EQUAL_64(dst_base + 16, x18);
2757 ASSERT_EQUAL_64(src_base + 4, x19);
2758 ASSERT_EQUAL_64(dst_base + 4, x20);
2759 ASSERT_EQUAL_64(src_base + 8, x21);
2760 ASSERT_EQUAL_64(dst_base + 24, x22);
2761
2762 TEARDOWN();
2763}
2764
2765
2766TEST(ldp_stp_postindex) {
2767 SETUP();
2768
armvixlb0c8ae22014-03-21 14:03:59 +00002769 uint64_t src[4] = {0x0011223344556677, 0x8899aabbccddeeff,
2770 0xffeeddccbbaa9988, 0x7766554433221100};
armvixlad96eda2013-06-14 11:42:37 +01002771 uint64_t dst[5] = {0, 0, 0, 0, 0};
2772 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2773 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2774
2775 START();
2776 __ Mov(x16, src_base);
2777 __ Mov(x17, dst_base);
2778 __ Mov(x18, dst_base + 16);
2779 __ Ldp(w0, w1, MemOperand(x16, 4, PostIndex));
2780 __ Mov(x19, x16);
2781 __ Ldp(w2, w3, MemOperand(x16, -4, PostIndex));
2782 __ Stp(w2, w3, MemOperand(x17, 4, PostIndex));
2783 __ Mov(x20, x17);
2784 __ Stp(w0, w1, MemOperand(x17, -4, PostIndex));
2785 __ Ldp(x4, x5, MemOperand(x16, 8, PostIndex));
2786 __ Mov(x21, x16);
2787 __ Ldp(x6, x7, MemOperand(x16, -8, PostIndex));
2788 __ Stp(x7, x6, MemOperand(x18, 8, PostIndex));
2789 __ Mov(x22, x18);
2790 __ Stp(x5, x4, MemOperand(x18, -8, PostIndex));
2791 END();
2792
2793 RUN();
2794
2795 ASSERT_EQUAL_64(0x44556677, x0);
2796 ASSERT_EQUAL_64(0x00112233, x1);
2797 ASSERT_EQUAL_64(0x00112233, x2);
2798 ASSERT_EQUAL_64(0xccddeeff, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00002799 ASSERT_EQUAL_64(0x4455667700112233, dst[0]);
2800 ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
2801 ASSERT_EQUAL_64(0x0011223344556677, x4);
2802 ASSERT_EQUAL_64(0x8899aabbccddeeff, x5);
2803 ASSERT_EQUAL_64(0x8899aabbccddeeff, x6);
2804 ASSERT_EQUAL_64(0xffeeddccbbaa9988, x7);
2805 ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
2806 ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
2807 ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01002808 ASSERT_EQUAL_64(src_base, x16);
2809 ASSERT_EQUAL_64(dst_base, x17);
2810 ASSERT_EQUAL_64(dst_base + 16, x18);
2811 ASSERT_EQUAL_64(src_base + 4, x19);
2812 ASSERT_EQUAL_64(dst_base + 4, x20);
2813 ASSERT_EQUAL_64(src_base + 8, x21);
2814 ASSERT_EQUAL_64(dst_base + 24, x22);
2815
2816 TEARDOWN();
2817}
2818
2819
2820TEST(ldp_sign_extend) {
2821 SETUP();
2822
2823 uint32_t src[2] = {0x80000000, 0x7fffffff};
2824 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2825
2826 START();
2827 __ Mov(x24, src_base);
2828 __ Ldpsw(x0, x1, MemOperand(x24));
2829 END();
2830
2831 RUN();
2832
armvixlb0c8ae22014-03-21 14:03:59 +00002833 ASSERT_EQUAL_64(0xffffffff80000000, x0);
2834 ASSERT_EQUAL_64(0x000000007fffffff, x1);
armvixlad96eda2013-06-14 11:42:37 +01002835
2836 TEARDOWN();
2837}
2838
2839
2840TEST(ldur_stur) {
2841 SETUP();
2842
armvixlb0c8ae22014-03-21 14:03:59 +00002843 int64_t src[2] = {0x0123456789abcdef, 0x0123456789abcdef};
armvixlad96eda2013-06-14 11:42:37 +01002844 int64_t dst[5] = {0, 0, 0, 0, 0};
2845 uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
2846 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
2847
2848 START();
2849 __ Mov(x17, src_base);
2850 __ Mov(x18, dst_base);
2851 __ Mov(x19, src_base + 16);
2852 __ Mov(x20, dst_base + 32);
2853 __ Mov(x21, dst_base + 40);
2854 __ Ldr(w0, MemOperand(x17, 1));
2855 __ Str(w0, MemOperand(x18, 2));
2856 __ Ldr(x1, MemOperand(x17, 3));
2857 __ Str(x1, MemOperand(x18, 9));
2858 __ Ldr(w2, MemOperand(x19, -9));
2859 __ Str(w2, MemOperand(x20, -5));
2860 __ Ldrb(w3, MemOperand(x19, -1));
2861 __ Strb(w3, MemOperand(x21, -1));
2862 END();
2863
2864 RUN();
2865
2866 ASSERT_EQUAL_64(0x6789abcd, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00002867 ASSERT_EQUAL_64(0x00006789abcd0000, dst[0]);
2868 ASSERT_EQUAL_64(0xabcdef0123456789, x1);
2869 ASSERT_EQUAL_64(0xcdef012345678900, dst[1]);
armvixlad96eda2013-06-14 11:42:37 +01002870 ASSERT_EQUAL_64(0x000000ab, dst[2]);
2871 ASSERT_EQUAL_64(0xabcdef01, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00002872 ASSERT_EQUAL_64(0x00abcdef01000000, dst[3]);
armvixlad96eda2013-06-14 11:42:37 +01002873 ASSERT_EQUAL_64(0x00000001, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00002874 ASSERT_EQUAL_64(0x0100000000000000, dst[4]);
armvixlad96eda2013-06-14 11:42:37 +01002875 ASSERT_EQUAL_64(src_base, x17);
2876 ASSERT_EQUAL_64(dst_base, x18);
2877 ASSERT_EQUAL_64(src_base + 16, x19);
2878 ASSERT_EQUAL_64(dst_base + 32, x20);
2879
2880 TEARDOWN();
2881}
2882
2883
2884TEST(ldr_literal) {
2885 SETUP();
2886
2887 START();
armvixlb0c8ae22014-03-21 14:03:59 +00002888 __ Ldr(x2, 0x1234567890abcdef);
armvixlad96eda2013-06-14 11:42:37 +01002889 __ Ldr(w3, 0xfedcba09);
2890 __ Ldr(d13, 1.234);
2891 __ Ldr(s25, 2.5);
2892 END();
2893
2894 RUN();
2895
armvixlb0c8ae22014-03-21 14:03:59 +00002896 ASSERT_EQUAL_64(0x1234567890abcdef, x2);
armvixlad96eda2013-06-14 11:42:37 +01002897 ASSERT_EQUAL_64(0xfedcba09, x3);
2898 ASSERT_EQUAL_FP64(1.234, d13);
2899 ASSERT_EQUAL_FP32(2.5, s25);
2900
2901 TEARDOWN();
2902}
2903
2904
2905static void LdrLiteralRangeHelper(ptrdiff_t range_,
2906 LiteralPoolEmitOption option,
2907 bool expect_dump) {
armvixlb0c8ae22014-03-21 14:03:59 +00002908 VIXL_ASSERT(range_ > 0);
armvixl4a102ba2014-07-14 09:02:40 +01002909 SETUP_CUSTOM(range_ + 1024, PositionIndependentCode);
armvixlad96eda2013-06-14 11:42:37 +01002910
2911 Label label_1, label_2;
2912
2913 size_t range = static_cast<size_t>(range_);
2914 size_t code_size = 0;
2915 size_t pool_guard_size;
2916
2917 if (option == NoJumpRequired) {
2918 // Space for an explicit branch.
2919 pool_guard_size = sizeof(Instr);
2920 } else {
2921 pool_guard_size = 0;
2922 }
2923
2924 START();
2925 // Force a pool dump so the pool starts off empty.
2926 __ EmitLiteralPool(JumpRequired);
2927 ASSERT_LITERAL_POOL_SIZE(0);
2928
armvixlb0c8ae22014-03-21 14:03:59 +00002929 __ Ldr(x0, 0x1234567890abcdef);
armvixlad96eda2013-06-14 11:42:37 +01002930 __ Ldr(w1, 0xfedcba09);
2931 __ Ldr(d0, 1.234);
2932 __ Ldr(s1, 2.5);
2933 ASSERT_LITERAL_POOL_SIZE(24);
2934
2935 code_size += 4 * sizeof(Instr);
2936
2937 // Check that the requested range (allowing space for a branch over the pool)
2938 // can be handled by this test.
armvixlb0c8ae22014-03-21 14:03:59 +00002939 VIXL_ASSERT((code_size + pool_guard_size) <= range);
armvixlad96eda2013-06-14 11:42:37 +01002940
2941 // Emit NOPs up to 'range', leaving space for the pool guard.
2942 while ((code_size + pool_guard_size) < range) {
2943 __ Nop();
2944 code_size += sizeof(Instr);
2945 }
2946
2947 // Emit the guard sequence before the literal pool.
2948 if (option == NoJumpRequired) {
2949 __ B(&label_1);
2950 code_size += sizeof(Instr);
2951 }
2952
armvixlb0c8ae22014-03-21 14:03:59 +00002953 VIXL_ASSERT(code_size == range);
armvixlad96eda2013-06-14 11:42:37 +01002954 ASSERT_LITERAL_POOL_SIZE(24);
2955
2956 // Possibly generate a literal pool.
2957 __ CheckLiteralPool(option);
2958 __ Bind(&label_1);
2959 if (expect_dump) {
2960 ASSERT_LITERAL_POOL_SIZE(0);
2961 } else {
2962 ASSERT_LITERAL_POOL_SIZE(24);
2963 }
2964
2965 // Force a pool flush to check that a second pool functions correctly.
2966 __ EmitLiteralPool(JumpRequired);
2967 ASSERT_LITERAL_POOL_SIZE(0);
2968
2969 // These loads should be after the pool (and will require a new one).
armvixlb0c8ae22014-03-21 14:03:59 +00002970 __ Ldr(x4, 0x34567890abcdef12);
armvixlad96eda2013-06-14 11:42:37 +01002971 __ Ldr(w5, 0xdcba09fe);
2972 __ Ldr(d4, 123.4);
2973 __ Ldr(s5, 250.0);
2974 ASSERT_LITERAL_POOL_SIZE(24);
2975 END();
2976
2977 RUN();
2978
2979 // Check that the literals loaded correctly.
armvixlb0c8ae22014-03-21 14:03:59 +00002980 ASSERT_EQUAL_64(0x1234567890abcdef, x0);
armvixlad96eda2013-06-14 11:42:37 +01002981 ASSERT_EQUAL_64(0xfedcba09, x1);
2982 ASSERT_EQUAL_FP64(1.234, d0);
2983 ASSERT_EQUAL_FP32(2.5, s1);
armvixlb0c8ae22014-03-21 14:03:59 +00002984 ASSERT_EQUAL_64(0x34567890abcdef12, x4);
armvixlad96eda2013-06-14 11:42:37 +01002985 ASSERT_EQUAL_64(0xdcba09fe, x5);
2986 ASSERT_EQUAL_FP64(123.4, d4);
2987 ASSERT_EQUAL_FP32(250.0, s5);
2988
2989 TEARDOWN();
2990}
2991
2992
2993TEST(ldr_literal_range_1) {
2994 LdrLiteralRangeHelper(kRecommendedLiteralPoolRange,
2995 NoJumpRequired,
2996 true);
2997}
2998
2999
3000TEST(ldr_literal_range_2) {
3001 LdrLiteralRangeHelper(kRecommendedLiteralPoolRange-sizeof(Instr),
3002 NoJumpRequired,
3003 false);
3004}
3005
3006
3007TEST(ldr_literal_range_3) {
3008 LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange,
3009 JumpRequired,
3010 true);
3011}
3012
3013
3014TEST(ldr_literal_range_4) {
3015 LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange-sizeof(Instr),
3016 JumpRequired,
3017 false);
3018}
3019
3020
3021TEST(ldr_literal_range_5) {
3022 LdrLiteralRangeHelper(kLiteralPoolCheckInterval,
3023 JumpRequired,
3024 false);
3025}
3026
3027
3028TEST(ldr_literal_range_6) {
3029 LdrLiteralRangeHelper(kLiteralPoolCheckInterval-sizeof(Instr),
3030 JumpRequired,
3031 false);
3032}
3033
3034
3035TEST(add_sub_imm) {
3036 SETUP();
3037
3038 START();
3039 __ Mov(x0, 0x0);
3040 __ Mov(x1, 0x1111);
armvixlb0c8ae22014-03-21 14:03:59 +00003041 __ Mov(x2, 0xffffffffffffffff);
3042 __ Mov(x3, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01003043
3044 __ Add(x10, x0, Operand(0x123));
3045 __ Add(x11, x1, Operand(0x122000));
3046 __ Add(x12, x0, Operand(0xabc << 12));
3047 __ Add(x13, x2, Operand(1));
3048
3049 __ Add(w14, w0, Operand(0x123));
3050 __ Add(w15, w1, Operand(0x122000));
3051 __ Add(w16, w0, Operand(0xabc << 12));
3052 __ Add(w17, w2, Operand(1));
3053
3054 __ Sub(x20, x0, Operand(0x1));
3055 __ Sub(x21, x1, Operand(0x111));
3056 __ Sub(x22, x1, Operand(0x1 << 12));
3057 __ Sub(x23, x3, Operand(1));
3058
3059 __ Sub(w24, w0, Operand(0x1));
3060 __ Sub(w25, w1, Operand(0x111));
3061 __ Sub(w26, w1, Operand(0x1 << 12));
3062 __ Sub(w27, w3, Operand(1));
3063 END();
3064
3065 RUN();
3066
3067 ASSERT_EQUAL_64(0x123, x10);
3068 ASSERT_EQUAL_64(0x123111, x11);
3069 ASSERT_EQUAL_64(0xabc000, x12);
3070 ASSERT_EQUAL_64(0x0, x13);
3071
3072 ASSERT_EQUAL_32(0x123, w14);
3073 ASSERT_EQUAL_32(0x123111, w15);
3074 ASSERT_EQUAL_32(0xabc000, w16);
3075 ASSERT_EQUAL_32(0x0, w17);
3076
armvixlb0c8ae22014-03-21 14:03:59 +00003077 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlad96eda2013-06-14 11:42:37 +01003078 ASSERT_EQUAL_64(0x1000, x21);
3079 ASSERT_EQUAL_64(0x111, x22);
armvixlb0c8ae22014-03-21 14:03:59 +00003080 ASSERT_EQUAL_64(0x7fffffffffffffff, x23);
armvixlad96eda2013-06-14 11:42:37 +01003081
3082 ASSERT_EQUAL_32(0xffffffff, w24);
3083 ASSERT_EQUAL_32(0x1000, w25);
3084 ASSERT_EQUAL_32(0x111, w26);
3085 ASSERT_EQUAL_32(0xffffffff, w27);
3086
3087 TEARDOWN();
3088}
3089
3090
3091TEST(add_sub_wide_imm) {
3092 SETUP();
3093
3094 START();
3095 __ Mov(x0, 0x0);
3096 __ Mov(x1, 0x1);
3097
armvixlb0c8ae22014-03-21 14:03:59 +00003098 __ Add(x10, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01003099 __ Add(x11, x1, Operand(0xffffffff));
3100
3101 __ Add(w12, w0, Operand(0x12345678));
3102 __ Add(w13, w1, Operand(0xffffffff));
3103
armvixl4a102ba2014-07-14 09:02:40 +01003104 __ Add(w18, w0, Operand(kWMinInt));
3105 __ Sub(w19, w0, Operand(kWMinInt));
armvixlad96eda2013-06-14 11:42:37 +01003106
armvixl4a102ba2014-07-14 09:02:40 +01003107 __ Sub(x20, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01003108 __ Sub(w21, w0, Operand(0x12345678));
armvixl4a102ba2014-07-14 09:02:40 +01003109
armvixlad96eda2013-06-14 11:42:37 +01003110 END();
3111
3112 RUN();
3113
armvixlb0c8ae22014-03-21 14:03:59 +00003114 ASSERT_EQUAL_64(0x1234567890abcdef, x10);
3115 ASSERT_EQUAL_64(0x100000000, x11);
armvixlad96eda2013-06-14 11:42:37 +01003116
3117 ASSERT_EQUAL_32(0x12345678, w12);
3118 ASSERT_EQUAL_64(0x0, x13);
3119
armvixl4a102ba2014-07-14 09:02:40 +01003120 ASSERT_EQUAL_32(kWMinInt, w18);
3121 ASSERT_EQUAL_32(kWMinInt, w19);
armvixlad96eda2013-06-14 11:42:37 +01003122
armvixl4a102ba2014-07-14 09:02:40 +01003123 ASSERT_EQUAL_64(-0x1234567890abcdef, x20);
armvixlad96eda2013-06-14 11:42:37 +01003124 ASSERT_EQUAL_32(-0x12345678, w21);
3125
3126 TEARDOWN();
3127}
3128
3129
3130TEST(add_sub_shifted) {
3131 SETUP();
3132
3133 START();
3134 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00003135 __ Mov(x1, 0x0123456789abcdef);
3136 __ Mov(x2, 0xfedcba9876543210);
3137 __ Mov(x3, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01003138
3139 __ Add(x10, x1, Operand(x2));
3140 __ Add(x11, x0, Operand(x1, LSL, 8));
3141 __ Add(x12, x0, Operand(x1, LSR, 8));
3142 __ Add(x13, x0, Operand(x1, ASR, 8));
3143 __ Add(x14, x0, Operand(x2, ASR, 8));
3144 __ Add(w15, w0, Operand(w1, ASR, 8));
3145 __ Add(w18, w3, Operand(w1, ROR, 8));
3146 __ Add(x19, x3, Operand(x1, ROR, 8));
3147
3148 __ Sub(x20, x3, Operand(x2));
3149 __ Sub(x21, x3, Operand(x1, LSL, 8));
3150 __ Sub(x22, x3, Operand(x1, LSR, 8));
3151 __ Sub(x23, x3, Operand(x1, ASR, 8));
3152 __ Sub(x24, x3, Operand(x2, ASR, 8));
3153 __ Sub(w25, w3, Operand(w1, ASR, 8));
3154 __ Sub(w26, w3, Operand(w1, ROR, 8));
3155 __ Sub(x27, x3, Operand(x1, ROR, 8));
3156 END();
3157
3158 RUN();
3159
armvixlb0c8ae22014-03-21 14:03:59 +00003160 ASSERT_EQUAL_64(0xffffffffffffffff, x10);
3161 ASSERT_EQUAL_64(0x23456789abcdef00, x11);
3162 ASSERT_EQUAL_64(0x000123456789abcd, x12);
3163 ASSERT_EQUAL_64(0x000123456789abcd, x13);
3164 ASSERT_EQUAL_64(0xfffedcba98765432, x14);
armvixlad96eda2013-06-14 11:42:37 +01003165 ASSERT_EQUAL_64(0xff89abcd, x15);
3166 ASSERT_EQUAL_64(0xef89abcc, x18);
armvixlb0c8ae22014-03-21 14:03:59 +00003167 ASSERT_EQUAL_64(0xef0123456789abcc, x19);
armvixlad96eda2013-06-14 11:42:37 +01003168
armvixlb0c8ae22014-03-21 14:03:59 +00003169 ASSERT_EQUAL_64(0x0123456789abcdef, x20);
3170 ASSERT_EQUAL_64(0xdcba9876543210ff, x21);
3171 ASSERT_EQUAL_64(0xfffedcba98765432, x22);
3172 ASSERT_EQUAL_64(0xfffedcba98765432, x23);
3173 ASSERT_EQUAL_64(0x000123456789abcd, x24);
armvixlad96eda2013-06-14 11:42:37 +01003174 ASSERT_EQUAL_64(0x00765432, x25);
3175 ASSERT_EQUAL_64(0x10765432, x26);
armvixlb0c8ae22014-03-21 14:03:59 +00003176 ASSERT_EQUAL_64(0x10fedcba98765432, x27);
armvixlad96eda2013-06-14 11:42:37 +01003177
3178 TEARDOWN();
3179}
3180
3181
3182TEST(add_sub_extended) {
3183 SETUP();
3184
3185 START();
3186 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00003187 __ Mov(x1, 0x0123456789abcdef);
3188 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01003189 __ Mov(w3, 0x80);
3190
3191 __ Add(x10, x0, Operand(x1, UXTB, 0));
3192 __ Add(x11, x0, Operand(x1, UXTB, 1));
3193 __ Add(x12, x0, Operand(x1, UXTH, 2));
3194 __ Add(x13, x0, Operand(x1, UXTW, 4));
3195
3196 __ Add(x14, x0, Operand(x1, SXTB, 0));
3197 __ Add(x15, x0, Operand(x1, SXTB, 1));
3198 __ Add(x16, x0, Operand(x1, SXTH, 2));
3199 __ Add(x17, x0, Operand(x1, SXTW, 3));
3200 __ Add(x18, x0, Operand(x2, SXTB, 0));
3201 __ Add(x19, x0, Operand(x2, SXTB, 1));
3202 __ Add(x20, x0, Operand(x2, SXTH, 2));
3203 __ Add(x21, x0, Operand(x2, SXTW, 3));
3204
3205 __ Add(x22, x1, Operand(x2, SXTB, 1));
3206 __ Sub(x23, x1, Operand(x2, SXTB, 1));
3207
3208 __ Add(w24, w1, Operand(w2, UXTB, 2));
3209 __ Add(w25, w0, Operand(w1, SXTB, 0));
3210 __ Add(w26, w0, Operand(w1, SXTB, 1));
3211 __ Add(w27, w2, Operand(w1, SXTW, 3));
3212
3213 __ Add(w28, w0, Operand(w1, SXTW, 3));
3214 __ Add(x29, x0, Operand(w1, SXTW, 3));
3215
3216 __ Sub(x30, x0, Operand(w3, SXTB, 1));
3217 END();
3218
3219 RUN();
3220
armvixlb0c8ae22014-03-21 14:03:59 +00003221 ASSERT_EQUAL_64(0xef, x10);
3222 ASSERT_EQUAL_64(0x1de, x11);
3223 ASSERT_EQUAL_64(0x337bc, x12);
3224 ASSERT_EQUAL_64(0x89abcdef0, x13);
armvixlad96eda2013-06-14 11:42:37 +01003225
armvixlb0c8ae22014-03-21 14:03:59 +00003226 ASSERT_EQUAL_64(0xffffffffffffffef, x14);
3227 ASSERT_EQUAL_64(0xffffffffffffffde, x15);
3228 ASSERT_EQUAL_64(0xffffffffffff37bc, x16);
3229 ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x17);
3230 ASSERT_EQUAL_64(0x10, x18);
3231 ASSERT_EQUAL_64(0x20, x19);
3232 ASSERT_EQUAL_64(0xc840, x20);
3233 ASSERT_EQUAL_64(0x3b2a19080, x21);
armvixlad96eda2013-06-14 11:42:37 +01003234
armvixlb0c8ae22014-03-21 14:03:59 +00003235 ASSERT_EQUAL_64(0x0123456789abce0f, x22);
3236 ASSERT_EQUAL_64(0x0123456789abcdcf, x23);
armvixlad96eda2013-06-14 11:42:37 +01003237
3238 ASSERT_EQUAL_32(0x89abce2f, w24);
3239 ASSERT_EQUAL_32(0xffffffef, w25);
3240 ASSERT_EQUAL_32(0xffffffde, w26);
3241 ASSERT_EQUAL_32(0xc3b2a188, w27);
3242
3243 ASSERT_EQUAL_32(0x4d5e6f78, w28);
armvixlb0c8ae22014-03-21 14:03:59 +00003244 ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x29);
armvixlad96eda2013-06-14 11:42:37 +01003245
3246 ASSERT_EQUAL_64(256, x30);
3247
3248 TEARDOWN();
3249}
3250
3251
3252TEST(add_sub_negative) {
3253 SETUP();
3254
3255 START();
3256 __ Mov(x0, 0);
3257 __ Mov(x1, 4687);
3258 __ Mov(x2, 0x1122334455667788);
3259 __ Mov(w3, 0x11223344);
3260 __ Mov(w4, 400000);
3261
3262 __ Add(x10, x0, -42);
3263 __ Add(x11, x1, -687);
3264 __ Add(x12, x2, -0x88);
3265
3266 __ Sub(x13, x0, -600);
3267 __ Sub(x14, x1, -313);
3268 __ Sub(x15, x2, -0x555);
3269
3270 __ Add(w19, w3, -0x344);
3271 __ Add(w20, w4, -2000);
3272
3273 __ Sub(w21, w3, -0xbc);
3274 __ Sub(w22, w4, -2000);
3275 END();
3276
3277 RUN();
3278
3279 ASSERT_EQUAL_64(-42, x10);
3280 ASSERT_EQUAL_64(4000, x11);
3281 ASSERT_EQUAL_64(0x1122334455667700, x12);
3282
3283 ASSERT_EQUAL_64(600, x13);
3284 ASSERT_EQUAL_64(5000, x14);
3285 ASSERT_EQUAL_64(0x1122334455667cdd, x15);
3286
3287 ASSERT_EQUAL_32(0x11223000, w19);
3288 ASSERT_EQUAL_32(398000, w20);
3289
3290 ASSERT_EQUAL_32(0x11223400, w21);
3291 ASSERT_EQUAL_32(402000, w22);
3292
3293 TEARDOWN();
3294}
3295
3296
armvixlf37fdc02014-02-05 13:22:16 +00003297TEST(add_sub_zero) {
3298 SETUP();
3299
3300 START();
3301 __ Mov(x0, 0);
3302 __ Mov(x1, 0);
3303 __ Mov(x2, 0);
3304
3305 Label blob1;
3306 __ Bind(&blob1);
3307 __ Add(x0, x0, 0);
3308 __ Sub(x1, x1, 0);
3309 __ Sub(x2, x2, xzr);
armvixlb0c8ae22014-03-21 14:03:59 +00003310 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob1) == 0);
armvixlf37fdc02014-02-05 13:22:16 +00003311
3312 Label blob2;
3313 __ Bind(&blob2);
3314 __ Add(w3, w3, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00003315 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob2) != 0);
armvixlf37fdc02014-02-05 13:22:16 +00003316
3317 Label blob3;
3318 __ Bind(&blob3);
3319 __ Sub(w3, w3, wzr);
armvixlb0c8ae22014-03-21 14:03:59 +00003320 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&blob3) != 0);
armvixlf37fdc02014-02-05 13:22:16 +00003321
3322 END();
3323
3324 RUN();
3325
3326 ASSERT_EQUAL_64(0, x0);
3327 ASSERT_EQUAL_64(0, x1);
3328 ASSERT_EQUAL_64(0, x2);
3329
3330 TEARDOWN();
3331}
3332
3333
3334TEST(claim_drop_zero) {
3335 SETUP();
3336
3337 START();
3338
3339 Label start;
3340 __ Bind(&start);
3341 __ Claim(Operand(0));
3342 __ Drop(Operand(0));
3343 __ Claim(Operand(xzr));
3344 __ Drop(Operand(xzr));
armvixlb0c8ae22014-03-21 14:03:59 +00003345 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlf37fdc02014-02-05 13:22:16 +00003346
3347 END();
3348
3349 RUN();
3350
3351 TEARDOWN();
3352}
3353
3354
armvixlad96eda2013-06-14 11:42:37 +01003355TEST(neg) {
3356 SETUP();
3357
3358 START();
armvixlb0c8ae22014-03-21 14:03:59 +00003359 __ Mov(x0, 0xf123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01003360
3361 // Immediate.
3362 __ Neg(x1, 0x123);
3363 __ Neg(w2, 0x123);
3364
3365 // Shifted.
3366 __ Neg(x3, Operand(x0, LSL, 1));
3367 __ Neg(w4, Operand(w0, LSL, 2));
3368 __ Neg(x5, Operand(x0, LSR, 3));
3369 __ Neg(w6, Operand(w0, LSR, 4));
3370 __ Neg(x7, Operand(x0, ASR, 5));
3371 __ Neg(w8, Operand(w0, ASR, 6));
3372
3373 // Extended.
3374 __ Neg(w9, Operand(w0, UXTB));
3375 __ Neg(x10, Operand(x0, SXTB, 1));
3376 __ Neg(w11, Operand(w0, UXTH, 2));
3377 __ Neg(x12, Operand(x0, SXTH, 3));
3378 __ Neg(w13, Operand(w0, UXTW, 4));
3379 __ Neg(x14, Operand(x0, SXTW, 4));
3380 END();
3381
3382 RUN();
3383
armvixlb0c8ae22014-03-21 14:03:59 +00003384 ASSERT_EQUAL_64(0xfffffffffffffedd, x1);
armvixlad96eda2013-06-14 11:42:37 +01003385 ASSERT_EQUAL_64(0xfffffedd, x2);
armvixlb0c8ae22014-03-21 14:03:59 +00003386 ASSERT_EQUAL_64(0x1db97530eca86422, x3);
armvixlad96eda2013-06-14 11:42:37 +01003387 ASSERT_EQUAL_64(0xd950c844, x4);
armvixlb0c8ae22014-03-21 14:03:59 +00003388 ASSERT_EQUAL_64(0xe1db97530eca8643, x5);
armvixlad96eda2013-06-14 11:42:37 +01003389 ASSERT_EQUAL_64(0xf7654322, x6);
armvixlb0c8ae22014-03-21 14:03:59 +00003390 ASSERT_EQUAL_64(0x0076e5d4c3b2a191, x7);
armvixlad96eda2013-06-14 11:42:37 +01003391 ASSERT_EQUAL_64(0x01d950c9, x8);
3392 ASSERT_EQUAL_64(0xffffff11, x9);
armvixlb0c8ae22014-03-21 14:03:59 +00003393 ASSERT_EQUAL_64(0x0000000000000022, x10);
armvixlad96eda2013-06-14 11:42:37 +01003394 ASSERT_EQUAL_64(0xfffcc844, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00003395 ASSERT_EQUAL_64(0x0000000000019088, x12);
armvixlad96eda2013-06-14 11:42:37 +01003396 ASSERT_EQUAL_64(0x65432110, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00003397 ASSERT_EQUAL_64(0x0000000765432110, x14);
armvixlad96eda2013-06-14 11:42:37 +01003398
3399 TEARDOWN();
3400}
3401
3402
3403TEST(adc_sbc_shift) {
3404 SETUP();
3405
3406 START();
3407 __ Mov(x0, 0);
3408 __ Mov(x1, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00003409 __ Mov(x2, 0x0123456789abcdef);
3410 __ Mov(x3, 0xfedcba9876543210);
3411 __ Mov(x4, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01003412
3413 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00003414 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01003415
3416 __ Adc(x5, x2, Operand(x3));
3417 __ Adc(x6, x0, Operand(x1, LSL, 60));
3418 __ Sbc(x7, x4, Operand(x3, LSR, 4));
3419 __ Adc(x8, x2, Operand(x3, ASR, 4));
3420 __ Adc(x9, x2, Operand(x3, ROR, 8));
3421
3422 __ Adc(w10, w2, Operand(w3));
3423 __ Adc(w11, w0, Operand(w1, LSL, 30));
3424 __ Sbc(w12, w4, Operand(w3, LSR, 4));
3425 __ Adc(w13, w2, Operand(w3, ASR, 4));
3426 __ Adc(w14, w2, Operand(w3, ROR, 8));
3427
3428 // Set the C flag.
3429 __ Cmp(w0, Operand(w0));
3430
3431 __ Adc(x18, x2, Operand(x3));
3432 __ Adc(x19, x0, Operand(x1, LSL, 60));
3433 __ Sbc(x20, x4, Operand(x3, LSR, 4));
3434 __ Adc(x21, x2, Operand(x3, ASR, 4));
3435 __ Adc(x22, x2, Operand(x3, ROR, 8));
3436
3437 __ Adc(w23, w2, Operand(w3));
3438 __ Adc(w24, w0, Operand(w1, LSL, 30));
3439 __ Sbc(w25, w4, Operand(w3, LSR, 4));
3440 __ Adc(w26, w2, Operand(w3, ASR, 4));
3441 __ Adc(w27, w2, Operand(w3, ROR, 8));
3442 END();
3443
3444 RUN();
3445
armvixlb0c8ae22014-03-21 14:03:59 +00003446 ASSERT_EQUAL_64(0xffffffffffffffff, x5);
3447 ASSERT_EQUAL_64(INT64_C(1) << 60, x6);
3448 ASSERT_EQUAL_64(0xf0123456789abcdd, x7);
3449 ASSERT_EQUAL_64(0x0111111111111110, x8);
3450 ASSERT_EQUAL_64(0x1222222222222221, x9);
armvixlad96eda2013-06-14 11:42:37 +01003451
3452 ASSERT_EQUAL_32(0xffffffff, w10);
armvixlb0c8ae22014-03-21 14:03:59 +00003453 ASSERT_EQUAL_32(INT32_C(1) << 30, w11);
armvixlad96eda2013-06-14 11:42:37 +01003454 ASSERT_EQUAL_32(0xf89abcdd, w12);
3455 ASSERT_EQUAL_32(0x91111110, w13);
3456 ASSERT_EQUAL_32(0x9a222221, w14);
3457
armvixlb0c8ae22014-03-21 14:03:59 +00003458 ASSERT_EQUAL_64(0xffffffffffffffff + 1, x18);
3459 ASSERT_EQUAL_64((INT64_C(1) << 60) + 1, x19);
3460 ASSERT_EQUAL_64(0xf0123456789abcdd + 1, x20);
3461 ASSERT_EQUAL_64(0x0111111111111110 + 1, x21);
3462 ASSERT_EQUAL_64(0x1222222222222221 + 1, x22);
armvixlad96eda2013-06-14 11:42:37 +01003463
3464 ASSERT_EQUAL_32(0xffffffff + 1, w23);
armvixlb0c8ae22014-03-21 14:03:59 +00003465 ASSERT_EQUAL_32((INT32_C(1) << 30) + 1, w24);
armvixlad96eda2013-06-14 11:42:37 +01003466 ASSERT_EQUAL_32(0xf89abcdd + 1, w25);
3467 ASSERT_EQUAL_32(0x91111110 + 1, w26);
3468 ASSERT_EQUAL_32(0x9a222221 + 1, w27);
3469
3470 // Check that adc correctly sets the condition flags.
3471 START();
3472 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00003473 __ Mov(x1, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01003474 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00003475 __ Adds(x0, x0, Operand(0));
3476 __ Adcs(x10, x0, Operand(x1));
armvixlad96eda2013-06-14 11:42:37 +01003477 END();
3478
3479 RUN();
3480
3481 ASSERT_EQUAL_NZCV(ZCFlag);
armvixlf37fdc02014-02-05 13:22:16 +00003482 ASSERT_EQUAL_64(0, x10);
armvixlad96eda2013-06-14 11:42:37 +01003483
3484 START();
3485 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00003486 __ Mov(x1, 0x8000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01003487 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00003488 __ Adds(x0, x0, Operand(0));
3489 __ Adcs(x10, x0, Operand(x1, ASR, 63));
armvixlad96eda2013-06-14 11:42:37 +01003490 END();
3491
3492 RUN();
3493
3494 ASSERT_EQUAL_NZCV(ZCFlag);
armvixlf37fdc02014-02-05 13:22:16 +00003495 ASSERT_EQUAL_64(0, x10);
armvixlad96eda2013-06-14 11:42:37 +01003496
3497 START();
3498 __ Mov(x0, 0x10);
armvixlb0c8ae22014-03-21 14:03:59 +00003499 __ Mov(x1, 0x07ffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01003500 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00003501 __ Adds(x0, x0, Operand(0));
3502 __ Adcs(x10, x0, Operand(x1, LSL, 4));
armvixlad96eda2013-06-14 11:42:37 +01003503 END();
3504
3505 RUN();
3506
3507 ASSERT_EQUAL_NZCV(NVFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00003508 ASSERT_EQUAL_64(0x8000000000000000, x10);
armvixlf37fdc02014-02-05 13:22:16 +00003509
3510 // Check that sbc correctly sets the condition flags.
3511 START();
3512 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00003513 __ Mov(x1, 0xffffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00003514 // Clear the C flag.
3515 __ Adds(x0, x0, Operand(0));
3516 __ Sbcs(x10, x0, Operand(x1));
3517 END();
3518
3519 RUN();
3520
3521 ASSERT_EQUAL_NZCV(ZFlag);
3522 ASSERT_EQUAL_64(0, x10);
3523
3524 START();
3525 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00003526 __ Mov(x1, 0xffffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00003527 // Clear the C flag.
3528 __ Adds(x0, x0, Operand(0));
3529 __ Sbcs(x10, x0, Operand(x1, LSR, 1));
3530 END();
3531
3532 RUN();
3533
3534 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00003535 ASSERT_EQUAL_64(0x8000000000000001, x10);
armvixlf37fdc02014-02-05 13:22:16 +00003536
3537 START();
3538 __ Mov(x0, 0);
3539 // Clear the C flag.
3540 __ Adds(x0, x0, Operand(0));
armvixlb0c8ae22014-03-21 14:03:59 +00003541 __ Sbcs(x10, x0, Operand(0xffffffffffffffff));
armvixlf37fdc02014-02-05 13:22:16 +00003542 END();
3543
3544 RUN();
3545
3546 ASSERT_EQUAL_NZCV(ZFlag);
3547 ASSERT_EQUAL_64(0, x10);
3548
armvixlb0c8ae22014-03-21 14:03:59 +00003549 START();
armvixlf37fdc02014-02-05 13:22:16 +00003550 __ Mov(w0, 0x7fffffff);
3551 // Clear the C flag.
3552 __ Adds(x0, x0, Operand(0));
3553 __ Ngcs(w10, w0);
3554 END();
3555
3556 RUN();
3557
3558 ASSERT_EQUAL_NZCV(NFlag);
3559 ASSERT_EQUAL_64(0x80000000, x10);
3560
3561 START();
3562 // Clear the C flag.
3563 __ Adds(x0, x0, Operand(0));
armvixlb0c8ae22014-03-21 14:03:59 +00003564 __ Ngcs(x10, 0x7fffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00003565 END();
3566
3567 RUN();
3568
3569 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00003570 ASSERT_EQUAL_64(0x8000000000000000, x10);
armvixlf37fdc02014-02-05 13:22:16 +00003571
armvixlb0c8ae22014-03-21 14:03:59 +00003572 START();
armvixlf37fdc02014-02-05 13:22:16 +00003573 __ Mov(x0, 0);
3574 // Set the C flag.
3575 __ Cmp(x0, Operand(x0));
3576 __ Sbcs(x10, x0, Operand(1));
3577 END();
3578
3579 RUN();
3580
3581 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00003582 ASSERT_EQUAL_64(0xffffffffffffffff, x10);
armvixlf37fdc02014-02-05 13:22:16 +00003583
armvixlb0c8ae22014-03-21 14:03:59 +00003584 START();
armvixlf37fdc02014-02-05 13:22:16 +00003585 __ Mov(x0, 0);
3586 // Set the C flag.
3587 __ Cmp(x0, Operand(x0));
armvixlb0c8ae22014-03-21 14:03:59 +00003588 __ Ngcs(x10, 0x7fffffffffffffff);
armvixlf37fdc02014-02-05 13:22:16 +00003589 END();
3590
3591 RUN();
3592
3593 ASSERT_EQUAL_NZCV(NFlag);
armvixlb0c8ae22014-03-21 14:03:59 +00003594 ASSERT_EQUAL_64(0x8000000000000001, x10);
armvixlad96eda2013-06-14 11:42:37 +01003595
3596 TEARDOWN();
3597}
3598
3599
3600TEST(adc_sbc_extend) {
3601 SETUP();
3602
3603 START();
3604 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00003605 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01003606
3607 __ Mov(x0, 0);
3608 __ Mov(x1, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00003609 __ Mov(x2, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01003610
3611 __ Adc(x10, x1, Operand(w2, UXTB, 1));
3612 __ Adc(x11, x1, Operand(x2, SXTH, 2));
3613 __ Sbc(x12, x1, Operand(w2, UXTW, 4));
3614 __ Adc(x13, x1, Operand(x2, UXTX, 4));
3615
3616 __ Adc(w14, w1, Operand(w2, UXTB, 1));
3617 __ Adc(w15, w1, Operand(w2, SXTH, 2));
3618 __ Adc(w9, w1, Operand(w2, UXTW, 4));
3619
3620 // Set the C flag.
3621 __ Cmp(w0, Operand(w0));
3622
3623 __ Adc(x20, x1, Operand(w2, UXTB, 1));
3624 __ Adc(x21, x1, Operand(x2, SXTH, 2));
3625 __ Sbc(x22, x1, Operand(w2, UXTW, 4));
3626 __ Adc(x23, x1, Operand(x2, UXTX, 4));
3627
3628 __ Adc(w24, w1, Operand(w2, UXTB, 1));
3629 __ Adc(w25, w1, Operand(w2, SXTH, 2));
3630 __ Adc(w26, w1, Operand(w2, UXTW, 4));
3631 END();
3632
3633 RUN();
3634
3635 ASSERT_EQUAL_64(0x1df, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00003636 ASSERT_EQUAL_64(0xffffffffffff37bd, x11);
3637 ASSERT_EQUAL_64(0xfffffff765432110, x12);
3638 ASSERT_EQUAL_64(0x123456789abcdef1, x13);
armvixlad96eda2013-06-14 11:42:37 +01003639
3640 ASSERT_EQUAL_32(0x1df, w14);
3641 ASSERT_EQUAL_32(0xffff37bd, w15);
3642 ASSERT_EQUAL_32(0x9abcdef1, w9);
3643
3644 ASSERT_EQUAL_64(0x1df + 1, x20);
armvixlb0c8ae22014-03-21 14:03:59 +00003645 ASSERT_EQUAL_64(0xffffffffffff37bd + 1, x21);
3646 ASSERT_EQUAL_64(0xfffffff765432110 + 1, x22);
3647 ASSERT_EQUAL_64(0x123456789abcdef1 + 1, x23);
armvixlad96eda2013-06-14 11:42:37 +01003648
3649 ASSERT_EQUAL_32(0x1df + 1, w24);
3650 ASSERT_EQUAL_32(0xffff37bd + 1, w25);
3651 ASSERT_EQUAL_32(0x9abcdef1 + 1, w26);
3652
3653 // Check that adc correctly sets the condition flags.
3654 START();
3655 __ Mov(x0, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00003656 __ Mov(x1, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01003657 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00003658 __ Adds(x0, x0, Operand(0));
3659 __ Adcs(x10, x0, Operand(x1, SXTX, 1));
armvixlad96eda2013-06-14 11:42:37 +01003660 END();
3661
3662 RUN();
3663
3664 ASSERT_EQUAL_NZCV(CFlag);
3665
3666 START();
armvixlb0c8ae22014-03-21 14:03:59 +00003667 __ Mov(x0, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01003668 __ Mov(x1, 1);
3669 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00003670 __ Adds(x0, x0, Operand(0));
3671 __ Adcs(x10, x0, Operand(x1, UXTB, 2));
armvixlad96eda2013-06-14 11:42:37 +01003672 END();
3673
3674 RUN();
3675
3676 ASSERT_EQUAL_NZCV(NVFlag);
3677
3678 START();
armvixlb0c8ae22014-03-21 14:03:59 +00003679 __ Mov(x0, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01003680 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00003681 __ Adds(x0, x0, Operand(0));
3682 __ Adcs(x10, x0, Operand(1));
armvixlad96eda2013-06-14 11:42:37 +01003683 END();
3684
3685 RUN();
3686
3687 ASSERT_EQUAL_NZCV(NVFlag);
3688
3689 TEARDOWN();
3690}
3691
3692
3693TEST(adc_sbc_wide_imm) {
3694 SETUP();
3695
3696 START();
3697 __ Mov(x0, 0);
3698
3699 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00003700 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01003701
armvixlb0c8ae22014-03-21 14:03:59 +00003702 __ Adc(x7, x0, Operand(0x1234567890abcdef));
armvixlad96eda2013-06-14 11:42:37 +01003703 __ Adc(w8, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00003704 __ Sbc(x9, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00003705 __ Sbc(w10, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00003706 __ Ngc(x11, Operand(0xffffffff00000000));
armvixlf37fdc02014-02-05 13:22:16 +00003707 __ Ngc(w12, Operand(0xffff0000));
armvixlad96eda2013-06-14 11:42:37 +01003708
3709 // Set the C flag.
3710 __ Cmp(w0, Operand(w0));
3711
armvixlb0c8ae22014-03-21 14:03:59 +00003712 __ Adc(x18, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00003713 __ Adc(w19, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00003714 __ Sbc(x20, x0, Operand(0x1234567890abcdef));
armvixlf37fdc02014-02-05 13:22:16 +00003715 __ Sbc(w21, w0, Operand(0xffffffff));
armvixlb0c8ae22014-03-21 14:03:59 +00003716 __ Ngc(x22, Operand(0xffffffff00000000));
armvixlf37fdc02014-02-05 13:22:16 +00003717 __ Ngc(w23, Operand(0xffff0000));
armvixlad96eda2013-06-14 11:42:37 +01003718 END();
3719
3720 RUN();
3721
armvixlb0c8ae22014-03-21 14:03:59 +00003722 ASSERT_EQUAL_64(0x1234567890abcdef, x7);
armvixlad96eda2013-06-14 11:42:37 +01003723 ASSERT_EQUAL_64(0xffffffff, x8);
armvixlb0c8ae22014-03-21 14:03:59 +00003724 ASSERT_EQUAL_64(0xedcba9876f543210, x9);
armvixlf37fdc02014-02-05 13:22:16 +00003725 ASSERT_EQUAL_64(0, x10);
3726 ASSERT_EQUAL_64(0xffffffff, x11);
3727 ASSERT_EQUAL_64(0xffff, x12);
3728
armvixlb0c8ae22014-03-21 14:03:59 +00003729 ASSERT_EQUAL_64(0x1234567890abcdef + 1, x18);
armvixlf37fdc02014-02-05 13:22:16 +00003730 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +00003731 ASSERT_EQUAL_64(0xedcba9876f543211, x20);
armvixlf37fdc02014-02-05 13:22:16 +00003732 ASSERT_EQUAL_64(1, x21);
armvixlb0c8ae22014-03-21 14:03:59 +00003733 ASSERT_EQUAL_64(0x0000000100000000, x22);
3734 ASSERT_EQUAL_64(0x0000000000010000, x23);
armvixlad96eda2013-06-14 11:42:37 +01003735
3736 TEARDOWN();
3737}
3738
3739TEST(flags) {
3740 SETUP();
3741
3742 START();
3743 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00003744 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01003745 __ Neg(x10, Operand(x0));
3746 __ Neg(x11, Operand(x1));
3747 __ Neg(w12, Operand(w1));
3748 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00003749 __ Adds(x0, x0, Operand(0));
armvixlad96eda2013-06-14 11:42:37 +01003750 __ Ngc(x13, Operand(x0));
3751 // Set the C flag.
3752 __ Cmp(x0, Operand(x0));
3753 __ Ngc(w14, Operand(w0));
3754 END();
3755
3756 RUN();
3757
3758 ASSERT_EQUAL_64(0, x10);
armvixlb0c8ae22014-03-21 14:03:59 +00003759 ASSERT_EQUAL_64(-0x1111111111111111, x11);
armvixlad96eda2013-06-14 11:42:37 +01003760 ASSERT_EQUAL_32(-0x11111111, w12);
armvixlb0c8ae22014-03-21 14:03:59 +00003761 ASSERT_EQUAL_64(-1, x13);
armvixlad96eda2013-06-14 11:42:37 +01003762 ASSERT_EQUAL_32(0, w14);
3763
3764 START();
3765 __ Mov(x0, 0);
3766 __ Cmp(x0, Operand(x0));
3767 END();
3768
3769 RUN();
3770
3771 ASSERT_EQUAL_NZCV(ZCFlag);
3772
3773 START();
3774 __ Mov(w0, 0);
3775 __ Cmp(w0, Operand(w0));
3776 END();
3777
3778 RUN();
3779
3780 ASSERT_EQUAL_NZCV(ZCFlag);
3781
3782 START();
3783 __ Mov(x0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00003784 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01003785 __ Cmp(x0, Operand(x1));
3786 END();
3787
3788 RUN();
3789
3790 ASSERT_EQUAL_NZCV(NFlag);
3791
3792 START();
3793 __ Mov(w0, 0);
3794 __ Mov(w1, 0x11111111);
3795 __ Cmp(w0, Operand(w1));
3796 END();
3797
3798 RUN();
3799
3800 ASSERT_EQUAL_NZCV(NFlag);
3801
3802 START();
armvixlb0c8ae22014-03-21 14:03:59 +00003803 __ Mov(x1, 0x1111111111111111);
armvixlad96eda2013-06-14 11:42:37 +01003804 __ Cmp(x1, Operand(0));
3805 END();
3806
3807 RUN();
3808
3809 ASSERT_EQUAL_NZCV(CFlag);
3810
3811 START();
3812 __ Mov(w1, 0x11111111);
3813 __ Cmp(w1, Operand(0));
3814 END();
3815
3816 RUN();
3817
3818 ASSERT_EQUAL_NZCV(CFlag);
3819
3820 START();
3821 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00003822 __ Mov(x1, 0x7fffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01003823 __ Cmn(x1, Operand(x0));
3824 END();
3825
3826 RUN();
3827
3828 ASSERT_EQUAL_NZCV(NVFlag);
3829
3830 START();
3831 __ Mov(w0, 1);
3832 __ Mov(w1, 0x7fffffff);
3833 __ Cmn(w1, Operand(w0));
3834 END();
3835
3836 RUN();
3837
3838 ASSERT_EQUAL_NZCV(NVFlag);
3839
3840 START();
3841 __ Mov(x0, 1);
armvixlb0c8ae22014-03-21 14:03:59 +00003842 __ Mov(x1, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01003843 __ Cmn(x1, Operand(x0));
3844 END();
3845
3846 RUN();
3847
3848 ASSERT_EQUAL_NZCV(ZCFlag);
3849
3850 START();
3851 __ Mov(w0, 1);
3852 __ Mov(w1, 0xffffffff);
3853 __ Cmn(w1, Operand(w0));
3854 END();
3855
3856 RUN();
3857
3858 ASSERT_EQUAL_NZCV(ZCFlag);
3859
3860 START();
3861 __ Mov(w0, 0);
3862 __ Mov(w1, 1);
3863 // Clear the C flag.
armvixlf37fdc02014-02-05 13:22:16 +00003864 __ Adds(w0, w0, Operand(0));
3865 __ Ngcs(w0, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +01003866 END();
3867
3868 RUN();
3869
3870 ASSERT_EQUAL_NZCV(NFlag);
3871
3872 START();
3873 __ Mov(w0, 0);
3874 __ Mov(w1, 0);
3875 // Set the C flag.
3876 __ Cmp(w0, Operand(w0));
armvixlf37fdc02014-02-05 13:22:16 +00003877 __ Ngcs(w0, Operand(w1));
armvixlad96eda2013-06-14 11:42:37 +01003878 END();
3879
3880 RUN();
3881
3882 ASSERT_EQUAL_NZCV(ZCFlag);
3883
3884 TEARDOWN();
3885}
3886
3887
3888TEST(cmp_shift) {
3889 SETUP();
3890
3891 START();
3892 __ Mov(x18, 0xf0000000);
armvixlb0c8ae22014-03-21 14:03:59 +00003893 __ Mov(x19, 0xf000000010000000);
3894 __ Mov(x20, 0xf0000000f0000000);
3895 __ Mov(x21, 0x7800000078000000);
3896 __ Mov(x22, 0x3c0000003c000000);
3897 __ Mov(x23, 0x8000000780000000);
3898 __ Mov(x24, 0x0000000f00000000);
3899 __ Mov(x25, 0x00000003c0000000);
3900 __ Mov(x26, 0x8000000780000000);
armvixlad96eda2013-06-14 11:42:37 +01003901 __ Mov(x27, 0xc0000003);
3902
3903 __ Cmp(w20, Operand(w21, LSL, 1));
3904 __ Mrs(x0, NZCV);
3905
3906 __ Cmp(x20, Operand(x22, LSL, 2));
3907 __ Mrs(x1, NZCV);
3908
3909 __ Cmp(w19, Operand(w23, LSR, 3));
3910 __ Mrs(x2, NZCV);
3911
3912 __ Cmp(x18, Operand(x24, LSR, 4));
3913 __ Mrs(x3, NZCV);
3914
3915 __ Cmp(w20, Operand(w25, ASR, 2));
3916 __ Mrs(x4, NZCV);
3917
3918 __ Cmp(x20, Operand(x26, ASR, 3));
3919 __ Mrs(x5, NZCV);
3920
3921 __ Cmp(w27, Operand(w22, ROR, 28));
3922 __ Mrs(x6, NZCV);
3923
3924 __ Cmp(x20, Operand(x21, ROR, 31));
3925 __ Mrs(x7, NZCV);
3926 END();
3927
3928 RUN();
3929
3930 ASSERT_EQUAL_32(ZCFlag, w0);
3931 ASSERT_EQUAL_32(ZCFlag, w1);
3932 ASSERT_EQUAL_32(ZCFlag, w2);
3933 ASSERT_EQUAL_32(ZCFlag, w3);
3934 ASSERT_EQUAL_32(ZCFlag, w4);
3935 ASSERT_EQUAL_32(ZCFlag, w5);
3936 ASSERT_EQUAL_32(ZCFlag, w6);
3937 ASSERT_EQUAL_32(ZCFlag, w7);
3938
3939 TEARDOWN();
3940}
3941
3942
3943TEST(cmp_extend) {
3944 SETUP();
3945
3946 START();
3947 __ Mov(w20, 0x2);
3948 __ Mov(w21, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00003949 __ Mov(x22, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01003950 __ Mov(x23, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00003951 __ Mov(x24, 0xfffffffffffffffe);
armvixlad96eda2013-06-14 11:42:37 +01003952 __ Mov(x25, 0xffff);
3953 __ Mov(x26, 0xffffffff);
3954
3955 __ Cmp(w20, Operand(w21, LSL, 1));
3956 __ Mrs(x0, NZCV);
3957
3958 __ Cmp(x22, Operand(x23, SXTB, 0));
3959 __ Mrs(x1, NZCV);
3960
3961 __ Cmp(x24, Operand(x23, SXTB, 1));
3962 __ Mrs(x2, NZCV);
3963
3964 __ Cmp(x24, Operand(x23, UXTB, 1));
3965 __ Mrs(x3, NZCV);
3966
3967 __ Cmp(w22, Operand(w25, UXTH));
3968 __ Mrs(x4, NZCV);
3969
3970 __ Cmp(x22, Operand(x25, SXTH));
3971 __ Mrs(x5, NZCV);
3972
3973 __ Cmp(x22, Operand(x26, UXTW));
3974 __ Mrs(x6, NZCV);
3975
3976 __ Cmp(x24, Operand(x26, SXTW, 1));
3977 __ Mrs(x7, NZCV);
3978 END();
3979
3980 RUN();
3981
3982 ASSERT_EQUAL_32(ZCFlag, w0);
3983 ASSERT_EQUAL_32(ZCFlag, w1);
3984 ASSERT_EQUAL_32(ZCFlag, w2);
3985 ASSERT_EQUAL_32(NCFlag, w3);
3986 ASSERT_EQUAL_32(NCFlag, w4);
3987 ASSERT_EQUAL_32(ZCFlag, w5);
3988 ASSERT_EQUAL_32(NCFlag, w6);
3989 ASSERT_EQUAL_32(ZCFlag, w7);
3990
3991 TEARDOWN();
3992}
3993
3994
3995TEST(ccmp) {
3996 SETUP();
3997
3998 START();
3999 __ Mov(w16, 0);
4000 __ Mov(w17, 1);
armvixl578645f2013-08-15 17:21:42 +01004001 __ Cmp(w16, w16);
4002 __ Ccmp(w16, w17, NCFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01004003 __ Mrs(x0, NZCV);
4004
armvixl578645f2013-08-15 17:21:42 +01004005 __ Cmp(w16, w16);
4006 __ Ccmp(w16, w17, NCFlag, ne);
armvixlad96eda2013-06-14 11:42:37 +01004007 __ Mrs(x1, NZCV);
4008
armvixl578645f2013-08-15 17:21:42 +01004009 __ Cmp(x16, x16);
4010 __ Ccmn(x16, 2, NZCVFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01004011 __ Mrs(x2, NZCV);
4012
armvixl578645f2013-08-15 17:21:42 +01004013 __ Cmp(x16, x16);
4014 __ Ccmn(x16, 2, NZCVFlag, ne);
armvixlad96eda2013-06-14 11:42:37 +01004015 __ Mrs(x3, NZCV);
armvixl578645f2013-08-15 17:21:42 +01004016
4017 __ ccmp(x16, x16, NZCVFlag, al);
4018 __ Mrs(x4, NZCV);
4019
4020 __ ccmp(x16, x16, NZCVFlag, nv);
4021 __ Mrs(x5, NZCV);
4022
armvixlad96eda2013-06-14 11:42:37 +01004023 END();
4024
4025 RUN();
4026
4027 ASSERT_EQUAL_32(NFlag, w0);
4028 ASSERT_EQUAL_32(NCFlag, w1);
4029 ASSERT_EQUAL_32(NoFlag, w2);
4030 ASSERT_EQUAL_32(NZCVFlag, w3);
armvixl578645f2013-08-15 17:21:42 +01004031 ASSERT_EQUAL_32(ZCFlag, w4);
4032 ASSERT_EQUAL_32(ZCFlag, w5);
armvixlad96eda2013-06-14 11:42:37 +01004033
4034 TEARDOWN();
4035}
4036
4037
4038TEST(ccmp_wide_imm) {
4039 SETUP();
4040
4041 START();
4042 __ Mov(w20, 0);
4043
4044 __ Cmp(w20, Operand(w20));
4045 __ Ccmp(w20, Operand(0x12345678), NZCVFlag, eq);
4046 __ Mrs(x0, NZCV);
4047
4048 __ Cmp(w20, Operand(w20));
armvixlb0c8ae22014-03-21 14:03:59 +00004049 __ Ccmp(x20, Operand(0xffffffffffffffff), NZCVFlag, eq);
armvixlad96eda2013-06-14 11:42:37 +01004050 __ Mrs(x1, NZCV);
4051 END();
4052
4053 RUN();
4054
4055 ASSERT_EQUAL_32(NFlag, w0);
4056 ASSERT_EQUAL_32(NoFlag, w1);
4057
4058 TEARDOWN();
4059}
4060
4061
4062TEST(ccmp_shift_extend) {
4063 SETUP();
4064
4065 START();
4066 __ Mov(w20, 0x2);
4067 __ Mov(w21, 0x1);
armvixlb0c8ae22014-03-21 14:03:59 +00004068 __ Mov(x22, 0xffffffffffffffff);
armvixlad96eda2013-06-14 11:42:37 +01004069 __ Mov(x23, 0xff);
armvixlb0c8ae22014-03-21 14:03:59 +00004070 __ Mov(x24, 0xfffffffffffffffe);
armvixlad96eda2013-06-14 11:42:37 +01004071
4072 __ Cmp(w20, Operand(w20));
4073 __ Ccmp(w20, Operand(w21, LSL, 1), NZCVFlag, eq);
4074 __ Mrs(x0, NZCV);
4075
4076 __ Cmp(w20, Operand(w20));
4077 __ Ccmp(x22, Operand(x23, SXTB, 0), NZCVFlag, eq);
4078 __ Mrs(x1, NZCV);
4079
4080 __ Cmp(w20, Operand(w20));
4081 __ Ccmp(x24, Operand(x23, SXTB, 1), NZCVFlag, eq);
4082 __ Mrs(x2, NZCV);
4083
4084 __ Cmp(w20, Operand(w20));
4085 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, eq);
4086 __ Mrs(x3, NZCV);
4087
4088 __ Cmp(w20, Operand(w20));
4089 __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, ne);
4090 __ Mrs(x4, NZCV);
4091 END();
4092
4093 RUN();
4094
4095 ASSERT_EQUAL_32(ZCFlag, w0);
4096 ASSERT_EQUAL_32(ZCFlag, w1);
4097 ASSERT_EQUAL_32(ZCFlag, w2);
4098 ASSERT_EQUAL_32(NCFlag, w3);
4099 ASSERT_EQUAL_32(NZCVFlag, w4);
4100
4101 TEARDOWN();
4102}
4103
4104
4105TEST(csel) {
4106 SETUP();
4107
4108 START();
4109 __ Mov(x16, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00004110 __ Mov(x24, 0x0000000f0000000f);
4111 __ Mov(x25, 0x0000001f0000001f);
armvixlad96eda2013-06-14 11:42:37 +01004112
4113 __ Cmp(w16, Operand(0));
4114 __ Csel(w0, w24, w25, eq);
4115 __ Csel(w1, w24, w25, ne);
4116 __ Csinc(w2, w24, w25, mi);
4117 __ Csinc(w3, w24, w25, pl);
4118
armvixl578645f2013-08-15 17:21:42 +01004119 __ csel(w13, w24, w25, al);
4120 __ csel(x14, x24, x25, nv);
4121
armvixlad96eda2013-06-14 11:42:37 +01004122 __ Cmp(x16, Operand(1));
4123 __ Csinv(x4, x24, x25, gt);
4124 __ Csinv(x5, x24, x25, le);
4125 __ Csneg(x6, x24, x25, hs);
4126 __ Csneg(x7, x24, x25, lo);
4127
4128 __ Cset(w8, ne);
4129 __ Csetm(w9, ne);
4130 __ Cinc(x10, x25, ne);
4131 __ Cinv(x11, x24, ne);
4132 __ Cneg(x12, x24, ne);
armvixl578645f2013-08-15 17:21:42 +01004133
4134 __ csel(w15, w24, w25, al);
4135 __ csel(x17, x24, x25, nv);
4136
armvixlad96eda2013-06-14 11:42:37 +01004137 END();
4138
4139 RUN();
4140
4141 ASSERT_EQUAL_64(0x0000000f, x0);
4142 ASSERT_EQUAL_64(0x0000001f, x1);
4143 ASSERT_EQUAL_64(0x00000020, x2);
4144 ASSERT_EQUAL_64(0x0000000f, x3);
armvixlb0c8ae22014-03-21 14:03:59 +00004145 ASSERT_EQUAL_64(0xffffffe0ffffffe0, x4);
4146 ASSERT_EQUAL_64(0x0000000f0000000f, x5);
4147 ASSERT_EQUAL_64(0xffffffe0ffffffe1, x6);
4148 ASSERT_EQUAL_64(0x0000000f0000000f, x7);
armvixlad96eda2013-06-14 11:42:37 +01004149 ASSERT_EQUAL_64(0x00000001, x8);
4150 ASSERT_EQUAL_64(0xffffffff, x9);
armvixlb0c8ae22014-03-21 14:03:59 +00004151 ASSERT_EQUAL_64(0x0000001f00000020, x10);
4152 ASSERT_EQUAL_64(0xfffffff0fffffff0, x11);
4153 ASSERT_EQUAL_64(0xfffffff0fffffff1, x12);
armvixl578645f2013-08-15 17:21:42 +01004154 ASSERT_EQUAL_64(0x0000000f, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00004155 ASSERT_EQUAL_64(0x0000000f0000000f, x14);
armvixl578645f2013-08-15 17:21:42 +01004156 ASSERT_EQUAL_64(0x0000000f, x15);
armvixlb0c8ae22014-03-21 14:03:59 +00004157 ASSERT_EQUAL_64(0x0000000f0000000f, x17);
armvixlad96eda2013-06-14 11:42:37 +01004158
4159 TEARDOWN();
4160}
4161
4162
armvixlf37fdc02014-02-05 13:22:16 +00004163TEST(csel_imm) {
4164 SETUP();
4165
4166 START();
4167 __ Mov(x18, 0);
4168 __ Mov(x19, 0x80000000);
armvixlb0c8ae22014-03-21 14:03:59 +00004169 __ Mov(x20, 0x8000000000000000);
armvixlf37fdc02014-02-05 13:22:16 +00004170
4171 __ Cmp(x18, Operand(0));
4172 __ Csel(w0, w19, -2, ne);
4173 __ Csel(w1, w19, -1, ne);
4174 __ Csel(w2, w19, 0, ne);
4175 __ Csel(w3, w19, 1, ne);
4176 __ Csel(w4, w19, 2, ne);
4177 __ Csel(w5, w19, Operand(w19, ASR, 31), ne);
4178 __ Csel(w6, w19, Operand(w19, ROR, 1), ne);
4179 __ Csel(w7, w19, 3, eq);
4180
4181 __ Csel(x8, x20, -2, ne);
4182 __ Csel(x9, x20, -1, ne);
4183 __ Csel(x10, x20, 0, ne);
4184 __ Csel(x11, x20, 1, ne);
4185 __ Csel(x12, x20, 2, ne);
4186 __ Csel(x13, x20, Operand(x20, ASR, 63), ne);
4187 __ Csel(x14, x20, Operand(x20, ROR, 1), ne);
4188 __ Csel(x15, x20, 3, eq);
4189
4190 END();
4191
4192 RUN();
4193
4194 ASSERT_EQUAL_32(-2, w0);
4195 ASSERT_EQUAL_32(-1, w1);
4196 ASSERT_EQUAL_32(0, w2);
4197 ASSERT_EQUAL_32(1, w3);
4198 ASSERT_EQUAL_32(2, w4);
4199 ASSERT_EQUAL_32(-1, w5);
4200 ASSERT_EQUAL_32(0x40000000, w6);
4201 ASSERT_EQUAL_32(0x80000000, w7);
4202
4203 ASSERT_EQUAL_64(-2, x8);
4204 ASSERT_EQUAL_64(-1, x9);
4205 ASSERT_EQUAL_64(0, x10);
4206 ASSERT_EQUAL_64(1, x11);
4207 ASSERT_EQUAL_64(2, x12);
4208 ASSERT_EQUAL_64(-1, x13);
armvixlb0c8ae22014-03-21 14:03:59 +00004209 ASSERT_EQUAL_64(0x4000000000000000, x14);
4210 ASSERT_EQUAL_64(0x8000000000000000, x15);
armvixlf37fdc02014-02-05 13:22:16 +00004211
4212 TEARDOWN();
4213}
4214
4215
armvixlad96eda2013-06-14 11:42:37 +01004216TEST(lslv) {
4217 SETUP();
4218
armvixlb0c8ae22014-03-21 14:03:59 +00004219 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01004220 int shift[] = {1, 3, 5, 9, 17, 33};
4221
4222 START();
4223 __ Mov(x0, value);
4224 __ Mov(w1, shift[0]);
4225 __ Mov(w2, shift[1]);
4226 __ Mov(w3, shift[2]);
4227 __ Mov(w4, shift[3]);
4228 __ Mov(w5, shift[4]);
4229 __ Mov(w6, shift[5]);
4230
4231 __ lslv(x0, x0, xzr);
4232
4233 __ Lsl(x16, x0, x1);
4234 __ Lsl(x17, x0, x2);
4235 __ Lsl(x18, x0, x3);
4236 __ Lsl(x19, x0, x4);
4237 __ Lsl(x20, x0, x5);
4238 __ Lsl(x21, x0, x6);
4239
4240 __ Lsl(w22, w0, w1);
4241 __ Lsl(w23, w0, w2);
4242 __ Lsl(w24, w0, w3);
4243 __ Lsl(w25, w0, w4);
4244 __ Lsl(w26, w0, w5);
4245 __ Lsl(w27, w0, w6);
4246 END();
4247
4248 RUN();
4249
4250 ASSERT_EQUAL_64(value, x0);
4251 ASSERT_EQUAL_64(value << (shift[0] & 63), x16);
4252 ASSERT_EQUAL_64(value << (shift[1] & 63), x17);
4253 ASSERT_EQUAL_64(value << (shift[2] & 63), x18);
4254 ASSERT_EQUAL_64(value << (shift[3] & 63), x19);
4255 ASSERT_EQUAL_64(value << (shift[4] & 63), x20);
4256 ASSERT_EQUAL_64(value << (shift[5] & 63), x21);
4257 ASSERT_EQUAL_32(value << (shift[0] & 31), w22);
4258 ASSERT_EQUAL_32(value << (shift[1] & 31), w23);
4259 ASSERT_EQUAL_32(value << (shift[2] & 31), w24);
4260 ASSERT_EQUAL_32(value << (shift[3] & 31), w25);
4261 ASSERT_EQUAL_32(value << (shift[4] & 31), w26);
4262 ASSERT_EQUAL_32(value << (shift[5] & 31), w27);
4263
4264 TEARDOWN();
4265}
4266
4267
4268TEST(lsrv) {
4269 SETUP();
4270
armvixlb0c8ae22014-03-21 14:03:59 +00004271 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01004272 int shift[] = {1, 3, 5, 9, 17, 33};
4273
4274 START();
4275 __ Mov(x0, value);
4276 __ Mov(w1, shift[0]);
4277 __ Mov(w2, shift[1]);
4278 __ Mov(w3, shift[2]);
4279 __ Mov(w4, shift[3]);
4280 __ Mov(w5, shift[4]);
4281 __ Mov(w6, shift[5]);
4282
4283 __ lsrv(x0, x0, xzr);
4284
4285 __ Lsr(x16, x0, x1);
4286 __ Lsr(x17, x0, x2);
4287 __ Lsr(x18, x0, x3);
4288 __ Lsr(x19, x0, x4);
4289 __ Lsr(x20, x0, x5);
4290 __ Lsr(x21, x0, x6);
4291
4292 __ Lsr(w22, w0, w1);
4293 __ Lsr(w23, w0, w2);
4294 __ Lsr(w24, w0, w3);
4295 __ Lsr(w25, w0, w4);
4296 __ Lsr(w26, w0, w5);
4297 __ Lsr(w27, w0, w6);
4298 END();
4299
4300 RUN();
4301
4302 ASSERT_EQUAL_64(value, x0);
4303 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
4304 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
4305 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
4306 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
4307 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
4308 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
4309
armvixlb0c8ae22014-03-21 14:03:59 +00004310 value &= 0xffffffff;
armvixlad96eda2013-06-14 11:42:37 +01004311 ASSERT_EQUAL_32(value >> (shift[0] & 31), w22);
4312 ASSERT_EQUAL_32(value >> (shift[1] & 31), w23);
4313 ASSERT_EQUAL_32(value >> (shift[2] & 31), w24);
4314 ASSERT_EQUAL_32(value >> (shift[3] & 31), w25);
4315 ASSERT_EQUAL_32(value >> (shift[4] & 31), w26);
4316 ASSERT_EQUAL_32(value >> (shift[5] & 31), w27);
4317
4318 TEARDOWN();
4319}
4320
4321
4322TEST(asrv) {
4323 SETUP();
4324
armvixlb0c8ae22014-03-21 14:03:59 +00004325 int64_t value = 0xfedcba98fedcba98;
armvixlad96eda2013-06-14 11:42:37 +01004326 int shift[] = {1, 3, 5, 9, 17, 33};
4327
4328 START();
4329 __ Mov(x0, value);
4330 __ Mov(w1, shift[0]);
4331 __ Mov(w2, shift[1]);
4332 __ Mov(w3, shift[2]);
4333 __ Mov(w4, shift[3]);
4334 __ Mov(w5, shift[4]);
4335 __ Mov(w6, shift[5]);
4336
4337 __ asrv(x0, x0, xzr);
4338
4339 __ Asr(x16, x0, x1);
4340 __ Asr(x17, x0, x2);
4341 __ Asr(x18, x0, x3);
4342 __ Asr(x19, x0, x4);
4343 __ Asr(x20, x0, x5);
4344 __ Asr(x21, x0, x6);
4345
4346 __ Asr(w22, w0, w1);
4347 __ Asr(w23, w0, w2);
4348 __ Asr(w24, w0, w3);
4349 __ Asr(w25, w0, w4);
4350 __ Asr(w26, w0, w5);
4351 __ Asr(w27, w0, w6);
4352 END();
4353
4354 RUN();
4355
4356 ASSERT_EQUAL_64(value, x0);
4357 ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
4358 ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
4359 ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
4360 ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
4361 ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
4362 ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
4363
armvixlb0c8ae22014-03-21 14:03:59 +00004364 int32_t value32 = static_cast<int32_t>(value & 0xffffffff);
armvixlad96eda2013-06-14 11:42:37 +01004365 ASSERT_EQUAL_32(value32 >> (shift[0] & 31), w22);
4366 ASSERT_EQUAL_32(value32 >> (shift[1] & 31), w23);
4367 ASSERT_EQUAL_32(value32 >> (shift[2] & 31), w24);
4368 ASSERT_EQUAL_32(value32 >> (shift[3] & 31), w25);
4369 ASSERT_EQUAL_32(value32 >> (shift[4] & 31), w26);
4370 ASSERT_EQUAL_32(value32 >> (shift[5] & 31), w27);
4371
4372 TEARDOWN();
4373}
4374
4375
4376TEST(rorv) {
4377 SETUP();
4378
armvixlb0c8ae22014-03-21 14:03:59 +00004379 uint64_t value = 0x0123456789abcdef;
armvixlad96eda2013-06-14 11:42:37 +01004380 int shift[] = {4, 8, 12, 16, 24, 36};
4381
4382 START();
4383 __ Mov(x0, value);
4384 __ Mov(w1, shift[0]);
4385 __ Mov(w2, shift[1]);
4386 __ Mov(w3, shift[2]);
4387 __ Mov(w4, shift[3]);
4388 __ Mov(w5, shift[4]);
4389 __ Mov(w6, shift[5]);
4390
4391 __ rorv(x0, x0, xzr);
4392
4393 __ Ror(x16, x0, x1);
4394 __ Ror(x17, x0, x2);
4395 __ Ror(x18, x0, x3);
4396 __ Ror(x19, x0, x4);
4397 __ Ror(x20, x0, x5);
4398 __ Ror(x21, x0, x6);
4399
4400 __ Ror(w22, w0, w1);
4401 __ Ror(w23, w0, w2);
4402 __ Ror(w24, w0, w3);
4403 __ Ror(w25, w0, w4);
4404 __ Ror(w26, w0, w5);
4405 __ Ror(w27, w0, w6);
4406 END();
4407
4408 RUN();
4409
4410 ASSERT_EQUAL_64(value, x0);
armvixlb0c8ae22014-03-21 14:03:59 +00004411 ASSERT_EQUAL_64(0xf0123456789abcde, x16);
4412 ASSERT_EQUAL_64(0xef0123456789abcd, x17);
4413 ASSERT_EQUAL_64(0xdef0123456789abc, x18);
4414 ASSERT_EQUAL_64(0xcdef0123456789ab, x19);
4415 ASSERT_EQUAL_64(0xabcdef0123456789, x20);
4416 ASSERT_EQUAL_64(0x789abcdef0123456, x21);
armvixlad96eda2013-06-14 11:42:37 +01004417 ASSERT_EQUAL_32(0xf89abcde, w22);
4418 ASSERT_EQUAL_32(0xef89abcd, w23);
4419 ASSERT_EQUAL_32(0xdef89abc, w24);
4420 ASSERT_EQUAL_32(0xcdef89ab, w25);
4421 ASSERT_EQUAL_32(0xabcdef89, w26);
4422 ASSERT_EQUAL_32(0xf89abcde, w27);
4423
4424 TEARDOWN();
4425}
4426
4427
4428TEST(bfm) {
4429 SETUP();
4430
4431 START();
armvixlb0c8ae22014-03-21 14:03:59 +00004432 __ Mov(x1, 0x0123456789abcdef);
armvixlad96eda2013-06-14 11:42:37 +01004433
armvixlb0c8ae22014-03-21 14:03:59 +00004434 __ Mov(x10, 0x8888888888888888);
4435 __ Mov(x11, 0x8888888888888888);
4436 __ Mov(x12, 0x8888888888888888);
4437 __ Mov(x13, 0x8888888888888888);
armvixlad96eda2013-06-14 11:42:37 +01004438 __ Mov(w20, 0x88888888);
4439 __ Mov(w21, 0x88888888);
4440
4441 __ bfm(x10, x1, 16, 31);
4442 __ bfm(x11, x1, 32, 15);
4443
4444 __ bfm(w20, w1, 16, 23);
4445 __ bfm(w21, w1, 24, 15);
4446
4447 // Aliases.
4448 __ Bfi(x12, x1, 16, 8);
4449 __ Bfxil(x13, x1, 16, 8);
4450 END();
4451
4452 RUN();
4453
4454
armvixlb0c8ae22014-03-21 14:03:59 +00004455 ASSERT_EQUAL_64(0x88888888888889ab, x10);
4456 ASSERT_EQUAL_64(0x8888cdef88888888, x11);
armvixlad96eda2013-06-14 11:42:37 +01004457
4458 ASSERT_EQUAL_32(0x888888ab, w20);
4459 ASSERT_EQUAL_32(0x88cdef88, w21);
4460
armvixlb0c8ae22014-03-21 14:03:59 +00004461 ASSERT_EQUAL_64(0x8888888888ef8888, x12);
4462 ASSERT_EQUAL_64(0x88888888888888ab, x13);
armvixlad96eda2013-06-14 11:42:37 +01004463
4464 TEARDOWN();
4465}
4466
4467
4468TEST(sbfm) {
4469 SETUP();
4470
4471 START();
armvixlb0c8ae22014-03-21 14:03:59 +00004472 __ Mov(x1, 0x0123456789abcdef);
4473 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01004474
4475 __ sbfm(x10, x1, 16, 31);
4476 __ sbfm(x11, x1, 32, 15);
4477 __ sbfm(x12, x1, 32, 47);
4478 __ sbfm(x13, x1, 48, 35);
4479
4480 __ sbfm(w14, w1, 16, 23);
4481 __ sbfm(w15, w1, 24, 15);
4482 __ sbfm(w16, w2, 16, 23);
4483 __ sbfm(w17, w2, 24, 15);
4484
4485 // Aliases.
4486 __ Asr(x18, x1, 32);
4487 __ Asr(x19, x2, 32);
4488 __ Sbfiz(x20, x1, 8, 16);
4489 __ Sbfiz(x21, x2, 8, 16);
4490 __ Sbfx(x22, x1, 8, 16);
4491 __ Sbfx(x23, x2, 8, 16);
armvixlf37fdc02014-02-05 13:22:16 +00004492 __ Sxtb(x24, w1);
armvixlad96eda2013-06-14 11:42:37 +01004493 __ Sxtb(x25, x2);
armvixlf37fdc02014-02-05 13:22:16 +00004494 __ Sxth(x26, w1);
armvixlad96eda2013-06-14 11:42:37 +01004495 __ Sxth(x27, x2);
armvixlf37fdc02014-02-05 13:22:16 +00004496 __ Sxtw(x28, w1);
armvixlad96eda2013-06-14 11:42:37 +01004497 __ Sxtw(x29, x2);
4498 END();
4499
4500 RUN();
4501
4502
armvixlb0c8ae22014-03-21 14:03:59 +00004503 ASSERT_EQUAL_64(0xffffffffffff89ab, x10);
4504 ASSERT_EQUAL_64(0xffffcdef00000000, x11);
4505 ASSERT_EQUAL_64(0x0000000000004567, x12);
4506 ASSERT_EQUAL_64(0x000789abcdef0000, x13);
armvixlad96eda2013-06-14 11:42:37 +01004507
4508 ASSERT_EQUAL_32(0xffffffab, w14);
4509 ASSERT_EQUAL_32(0xffcdef00, w15);
armvixlb0c8ae22014-03-21 14:03:59 +00004510 ASSERT_EQUAL_32(0x00000054, w16);
armvixlad96eda2013-06-14 11:42:37 +01004511 ASSERT_EQUAL_32(0x00321000, w17);
4512
armvixlb0c8ae22014-03-21 14:03:59 +00004513 ASSERT_EQUAL_64(0x0000000001234567, x18);
4514 ASSERT_EQUAL_64(0xfffffffffedcba98, x19);
4515 ASSERT_EQUAL_64(0xffffffffffcdef00, x20);
4516 ASSERT_EQUAL_64(0x0000000000321000, x21);
4517 ASSERT_EQUAL_64(0xffffffffffffabcd, x22);
4518 ASSERT_EQUAL_64(0x0000000000005432, x23);
4519 ASSERT_EQUAL_64(0xffffffffffffffef, x24);
4520 ASSERT_EQUAL_64(0x0000000000000010, x25);
4521 ASSERT_EQUAL_64(0xffffffffffffcdef, x26);
4522 ASSERT_EQUAL_64(0x0000000000003210, x27);
4523 ASSERT_EQUAL_64(0xffffffff89abcdef, x28);
4524 ASSERT_EQUAL_64(0x0000000076543210, x29);
armvixlad96eda2013-06-14 11:42:37 +01004525
4526 TEARDOWN();
4527}
4528
4529
4530TEST(ubfm) {
4531 SETUP();
4532
4533 START();
armvixlb0c8ae22014-03-21 14:03:59 +00004534 __ Mov(x1, 0x0123456789abcdef);
4535 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01004536
armvixlb0c8ae22014-03-21 14:03:59 +00004537 __ Mov(x10, 0x8888888888888888);
4538 __ Mov(x11, 0x8888888888888888);
armvixlad96eda2013-06-14 11:42:37 +01004539
4540 __ ubfm(x10, x1, 16, 31);
4541 __ ubfm(x11, x1, 32, 15);
4542 __ ubfm(x12, x1, 32, 47);
4543 __ ubfm(x13, x1, 48, 35);
4544
4545 __ ubfm(w25, w1, 16, 23);
4546 __ ubfm(w26, w1, 24, 15);
4547 __ ubfm(w27, w2, 16, 23);
4548 __ ubfm(w28, w2, 24, 15);
4549
4550 // Aliases
4551 __ Lsl(x15, x1, 63);
4552 __ Lsl(x16, x1, 0);
4553 __ Lsr(x17, x1, 32);
4554 __ Ubfiz(x18, x1, 8, 16);
4555 __ Ubfx(x19, x1, 8, 16);
4556 __ Uxtb(x20, x1);
4557 __ Uxth(x21, x1);
4558 __ Uxtw(x22, x1);
4559 END();
4560
4561 RUN();
4562
armvixlb0c8ae22014-03-21 14:03:59 +00004563 ASSERT_EQUAL_64(0x00000000000089ab, x10);
4564 ASSERT_EQUAL_64(0x0000cdef00000000, x11);
4565 ASSERT_EQUAL_64(0x0000000000004567, x12);
4566 ASSERT_EQUAL_64(0x000789abcdef0000, x13);
armvixlad96eda2013-06-14 11:42:37 +01004567
4568 ASSERT_EQUAL_32(0x000000ab, w25);
4569 ASSERT_EQUAL_32(0x00cdef00, w26);
armvixlb0c8ae22014-03-21 14:03:59 +00004570 ASSERT_EQUAL_32(0x00000054, w27);
armvixlad96eda2013-06-14 11:42:37 +01004571 ASSERT_EQUAL_32(0x00321000, w28);
4572
armvixlb0c8ae22014-03-21 14:03:59 +00004573 ASSERT_EQUAL_64(0x8000000000000000, x15);
4574 ASSERT_EQUAL_64(0x0123456789abcdef, x16);
4575 ASSERT_EQUAL_64(0x0000000001234567, x17);
4576 ASSERT_EQUAL_64(0x0000000000cdef00, x18);
4577 ASSERT_EQUAL_64(0x000000000000abcd, x19);
4578 ASSERT_EQUAL_64(0x00000000000000ef, x20);
4579 ASSERT_EQUAL_64(0x000000000000cdef, x21);
4580 ASSERT_EQUAL_64(0x0000000089abcdef, x22);
armvixlad96eda2013-06-14 11:42:37 +01004581
4582 TEARDOWN();
4583}
4584
4585
4586TEST(extr) {
4587 SETUP();
4588
4589 START();
armvixlb0c8ae22014-03-21 14:03:59 +00004590 __ Mov(x1, 0x0123456789abcdef);
4591 __ Mov(x2, 0xfedcba9876543210);
armvixlad96eda2013-06-14 11:42:37 +01004592
4593 __ Extr(w10, w1, w2, 0);
4594 __ Extr(w11, w1, w2, 1);
4595 __ Extr(x12, x2, x1, 2);
4596
4597 __ Ror(w13, w1, 0);
4598 __ Ror(w14, w2, 17);
4599 __ Ror(w15, w1, 31);
armvixl4a102ba2014-07-14 09:02:40 +01004600 __ Ror(x18, x2, 0);
4601 __ Ror(x19, x2, 1);
4602 __ Ror(x20, x1, 63);
armvixlad96eda2013-06-14 11:42:37 +01004603 END();
4604
4605 RUN();
4606
4607 ASSERT_EQUAL_64(0x76543210, x10);
4608 ASSERT_EQUAL_64(0xbb2a1908, x11);
armvixlb0c8ae22014-03-21 14:03:59 +00004609 ASSERT_EQUAL_64(0x0048d159e26af37b, x12);
armvixlad96eda2013-06-14 11:42:37 +01004610 ASSERT_EQUAL_64(0x89abcdef, x13);
4611 ASSERT_EQUAL_64(0x19083b2a, x14);
4612 ASSERT_EQUAL_64(0x13579bdf, x15);
armvixl4a102ba2014-07-14 09:02:40 +01004613 ASSERT_EQUAL_64(0xfedcba9876543210, x18);
4614 ASSERT_EQUAL_64(0x7f6e5d4c3b2a1908, x19);
4615 ASSERT_EQUAL_64(0x02468acf13579bde, x20);
armvixlad96eda2013-06-14 11:42:37 +01004616
4617 TEARDOWN();
4618}
4619
4620
4621TEST(fmov_imm) {
4622 SETUP();
4623
4624 START();
4625 __ Fmov(s11, 1.0);
4626 __ Fmov(d22, -13.0);
4627 __ Fmov(s1, 255.0);
4628 __ Fmov(d2, 12.34567);
4629 __ Fmov(s3, 0.0);
4630 __ Fmov(d4, 0.0);
4631 __ Fmov(s5, kFP32PositiveInfinity);
4632 __ Fmov(d6, kFP64NegativeInfinity);
4633 END();
4634
4635 RUN();
4636
4637 ASSERT_EQUAL_FP32(1.0, s11);
4638 ASSERT_EQUAL_FP64(-13.0, d22);
4639 ASSERT_EQUAL_FP32(255.0, s1);
4640 ASSERT_EQUAL_FP64(12.34567, d2);
4641 ASSERT_EQUAL_FP32(0.0, s3);
4642 ASSERT_EQUAL_FP64(0.0, d4);
4643 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
4644 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d6);
4645
4646 TEARDOWN();
4647}
4648
4649
4650TEST(fmov_reg) {
4651 SETUP();
4652
4653 START();
4654 __ Fmov(s20, 1.0);
4655 __ Fmov(w10, s20);
4656 __ Fmov(s30, w10);
4657 __ Fmov(s5, s20);
4658 __ Fmov(d1, -13.0);
4659 __ Fmov(x1, d1);
4660 __ Fmov(d2, x1);
4661 __ Fmov(d4, d1);
armvixlb0c8ae22014-03-21 14:03:59 +00004662 __ Fmov(d6, rawbits_to_double(0x0123456789abcdef));
armvixlad96eda2013-06-14 11:42:37 +01004663 __ Fmov(s6, s6);
4664 END();
4665
4666 RUN();
4667
4668 ASSERT_EQUAL_32(float_to_rawbits(1.0), w10);
4669 ASSERT_EQUAL_FP32(1.0, s30);
4670 ASSERT_EQUAL_FP32(1.0, s5);
4671 ASSERT_EQUAL_64(double_to_rawbits(-13.0), x1);
4672 ASSERT_EQUAL_FP64(-13.0, d2);
4673 ASSERT_EQUAL_FP64(-13.0, d4);
4674 ASSERT_EQUAL_FP32(rawbits_to_float(0x89abcdef), s6);
4675
4676 TEARDOWN();
4677}
4678
4679
4680TEST(fadd) {
4681 SETUP();
4682
4683 START();
armvixlb0c8ae22014-03-21 14:03:59 +00004684 __ Fmov(s14, -0.0f);
4685 __ Fmov(s15, kFP32PositiveInfinity);
4686 __ Fmov(s16, kFP32NegativeInfinity);
4687 __ Fmov(s17, 3.25f);
4688 __ Fmov(s18, 1.0f);
4689 __ Fmov(s19, 0.0f);
armvixlad96eda2013-06-14 11:42:37 +01004690
4691 __ Fmov(d26, -0.0);
4692 __ Fmov(d27, kFP64PositiveInfinity);
4693 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00004694 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01004695 __ Fmov(d30, -2.0);
4696 __ Fmov(d31, 2.25);
4697
armvixlb0c8ae22014-03-21 14:03:59 +00004698 __ Fadd(s0, s17, s18);
4699 __ Fadd(s1, s18, s19);
4700 __ Fadd(s2, s14, s18);
4701 __ Fadd(s3, s15, s18);
4702 __ Fadd(s4, s16, s18);
4703 __ Fadd(s5, s15, s16);
4704 __ Fadd(s6, s16, s15);
armvixlad96eda2013-06-14 11:42:37 +01004705
armvixlb0c8ae22014-03-21 14:03:59 +00004706 __ Fadd(d7, d30, d31);
4707 __ Fadd(d8, d29, d31);
4708 __ Fadd(d9, d26, d31);
4709 __ Fadd(d10, d27, d31);
4710 __ Fadd(d11, d28, d31);
4711 __ Fadd(d12, d27, d28);
4712 __ Fadd(d13, d28, d27);
armvixlad96eda2013-06-14 11:42:37 +01004713 END();
4714
4715 RUN();
4716
4717 ASSERT_EQUAL_FP32(4.25, s0);
4718 ASSERT_EQUAL_FP32(1.0, s1);
4719 ASSERT_EQUAL_FP32(1.0, s2);
4720 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
4721 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00004722 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
4723 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
4724 ASSERT_EQUAL_FP64(0.25, d7);
4725 ASSERT_EQUAL_FP64(2.25, d8);
4726 ASSERT_EQUAL_FP64(2.25, d9);
4727 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d10);
4728 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d11);
4729 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
4730 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01004731
4732 TEARDOWN();
4733}
4734
4735
4736TEST(fsub) {
4737 SETUP();
4738
4739 START();
armvixlb0c8ae22014-03-21 14:03:59 +00004740 __ Fmov(s14, -0.0f);
4741 __ Fmov(s15, kFP32PositiveInfinity);
4742 __ Fmov(s16, kFP32NegativeInfinity);
4743 __ Fmov(s17, 3.25f);
4744 __ Fmov(s18, 1.0f);
4745 __ Fmov(s19, 0.0f);
armvixlad96eda2013-06-14 11:42:37 +01004746
4747 __ Fmov(d26, -0.0);
4748 __ Fmov(d27, kFP64PositiveInfinity);
4749 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00004750 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01004751 __ Fmov(d30, -2.0);
4752 __ Fmov(d31, 2.25);
4753
armvixlb0c8ae22014-03-21 14:03:59 +00004754 __ Fsub(s0, s17, s18);
4755 __ Fsub(s1, s18, s19);
4756 __ Fsub(s2, s14, s18);
4757 __ Fsub(s3, s18, s15);
4758 __ Fsub(s4, s18, s16);
4759 __ Fsub(s5, s15, s15);
4760 __ Fsub(s6, s16, s16);
armvixlad96eda2013-06-14 11:42:37 +01004761
armvixlb0c8ae22014-03-21 14:03:59 +00004762 __ Fsub(d7, d30, d31);
4763 __ Fsub(d8, d29, d31);
4764 __ Fsub(d9, d26, d31);
4765 __ Fsub(d10, d31, d27);
4766 __ Fsub(d11, d31, d28);
4767 __ Fsub(d12, d27, d27);
4768 __ Fsub(d13, d28, d28);
armvixlad96eda2013-06-14 11:42:37 +01004769 END();
4770
4771 RUN();
4772
4773 ASSERT_EQUAL_FP32(2.25, s0);
4774 ASSERT_EQUAL_FP32(1.0, s1);
4775 ASSERT_EQUAL_FP32(-1.0, s2);
4776 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
4777 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00004778 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
4779 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
4780 ASSERT_EQUAL_FP64(-4.25, d7);
4781 ASSERT_EQUAL_FP64(-2.25, d8);
4782 ASSERT_EQUAL_FP64(-2.25, d9);
4783 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
4784 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
4785 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
4786 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01004787
4788 TEARDOWN();
4789}
4790
4791
4792TEST(fmul) {
4793 SETUP();
4794
4795 START();
armvixlb0c8ae22014-03-21 14:03:59 +00004796 __ Fmov(s14, -0.0f);
4797 __ Fmov(s15, kFP32PositiveInfinity);
4798 __ Fmov(s16, kFP32NegativeInfinity);
4799 __ Fmov(s17, 3.25f);
4800 __ Fmov(s18, 2.0f);
4801 __ Fmov(s19, 0.0f);
4802 __ Fmov(s20, -2.0f);
armvixlad96eda2013-06-14 11:42:37 +01004803
4804 __ Fmov(d26, -0.0);
4805 __ Fmov(d27, kFP64PositiveInfinity);
4806 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00004807 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01004808 __ Fmov(d30, -2.0);
4809 __ Fmov(d31, 2.25);
4810
armvixlb0c8ae22014-03-21 14:03:59 +00004811 __ Fmul(s0, s17, s18);
4812 __ Fmul(s1, s18, s19);
4813 __ Fmul(s2, s14, s14);
4814 __ Fmul(s3, s15, s20);
4815 __ Fmul(s4, s16, s20);
4816 __ Fmul(s5, s15, s19);
4817 __ Fmul(s6, s19, s16);
armvixlad96eda2013-06-14 11:42:37 +01004818
armvixlb0c8ae22014-03-21 14:03:59 +00004819 __ Fmul(d7, d30, d31);
4820 __ Fmul(d8, d29, d31);
4821 __ Fmul(d9, d26, d26);
4822 __ Fmul(d10, d27, d30);
4823 __ Fmul(d11, d28, d30);
4824 __ Fmul(d12, d27, d29);
4825 __ Fmul(d13, d29, d28);
armvixlad96eda2013-06-14 11:42:37 +01004826 END();
4827
4828 RUN();
4829
4830 ASSERT_EQUAL_FP32(6.5, s0);
4831 ASSERT_EQUAL_FP32(0.0, s1);
4832 ASSERT_EQUAL_FP32(0.0, s2);
4833 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
4834 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
armvixlb0c8ae22014-03-21 14:03:59 +00004835 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
4836 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
4837 ASSERT_EQUAL_FP64(-4.5, d7);
4838 ASSERT_EQUAL_FP64(0.0, d8);
4839 ASSERT_EQUAL_FP64(0.0, d9);
4840 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
4841 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
4842 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
4843 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01004844
4845 TEARDOWN();
4846}
4847
4848
armvixlb0c8ae22014-03-21 14:03:59 +00004849static void FmaddFmsubHelper(double n, double m, double a,
4850 double fmadd, double fmsub,
4851 double fnmadd, double fnmsub) {
armvixlad96eda2013-06-14 11:42:37 +01004852 SETUP();
armvixlad96eda2013-06-14 11:42:37 +01004853 START();
armvixlad96eda2013-06-14 11:42:37 +01004854
armvixlf37fdc02014-02-05 13:22:16 +00004855 __ Fmov(d0, n);
4856 __ Fmov(d1, m);
4857 __ Fmov(d2, a);
4858 __ Fmadd(d28, d0, d1, d2);
4859 __ Fmsub(d29, d0, d1, d2);
4860 __ Fnmadd(d30, d0, d1, d2);
4861 __ Fnmsub(d31, d0, d1, d2);
armvixlad96eda2013-06-14 11:42:37 +01004862
armvixlad96eda2013-06-14 11:42:37 +01004863 END();
armvixlad96eda2013-06-14 11:42:37 +01004864 RUN();
4865
armvixlf37fdc02014-02-05 13:22:16 +00004866 ASSERT_EQUAL_FP64(fmadd, d28);
4867 ASSERT_EQUAL_FP64(fmsub, d29);
armvixlb0c8ae22014-03-21 14:03:59 +00004868 ASSERT_EQUAL_FP64(fnmadd, d30);
4869 ASSERT_EQUAL_FP64(fnmsub, d31);
armvixlad96eda2013-06-14 11:42:37 +01004870
4871 TEARDOWN();
4872}
4873
4874
armvixlf37fdc02014-02-05 13:22:16 +00004875TEST(fmadd_fmsub_double) {
armvixlb0c8ae22014-03-21 14:03:59 +00004876 // It's hard to check the result of fused operations because the only way to
4877 // calculate the result is using fma, which is what the simulator uses anyway.
4878 // TODO(jbramley): Add tests to check behaviour against a hardware trace.
armvixlf37fdc02014-02-05 13:22:16 +00004879
armvixlb0c8ae22014-03-21 14:03:59 +00004880 // Basic operation.
4881 FmaddFmsubHelper(1.0, 2.0, 3.0, 5.0, 1.0, -5.0, -1.0);
4882 FmaddFmsubHelper(-1.0, 2.0, 3.0, 1.0, 5.0, -1.0, -5.0);
armvixlf37fdc02014-02-05 13:22:16 +00004883
armvixlb0c8ae22014-03-21 14:03:59 +00004884 // Check the sign of exact zeroes.
4885 // n m a fmadd fmsub fnmadd fnmsub
4886 FmaddFmsubHelper(-0.0, +0.0, -0.0, -0.0, +0.0, +0.0, +0.0);
4887 FmaddFmsubHelper(+0.0, +0.0, -0.0, +0.0, -0.0, +0.0, +0.0);
4888 FmaddFmsubHelper(+0.0, +0.0, +0.0, +0.0, +0.0, -0.0, +0.0);
4889 FmaddFmsubHelper(-0.0, +0.0, +0.0, +0.0, +0.0, +0.0, -0.0);
4890 FmaddFmsubHelper(+0.0, -0.0, -0.0, -0.0, +0.0, +0.0, +0.0);
4891 FmaddFmsubHelper(-0.0, -0.0, -0.0, +0.0, -0.0, +0.0, +0.0);
4892 FmaddFmsubHelper(-0.0, -0.0, +0.0, +0.0, +0.0, -0.0, +0.0);
4893 FmaddFmsubHelper(+0.0, -0.0, +0.0, +0.0, +0.0, +0.0, -0.0);
4894
4895 // Check NaN generation.
4896 FmaddFmsubHelper(kFP64PositiveInfinity, 0.0, 42.0,
4897 kFP64DefaultNaN, kFP64DefaultNaN,
4898 kFP64DefaultNaN, kFP64DefaultNaN);
4899 FmaddFmsubHelper(0.0, kFP64PositiveInfinity, 42.0,
4900 kFP64DefaultNaN, kFP64DefaultNaN,
4901 kFP64DefaultNaN, kFP64DefaultNaN);
4902 FmaddFmsubHelper(kFP64PositiveInfinity, 1.0, kFP64PositiveInfinity,
4903 kFP64PositiveInfinity, // inf + ( inf * 1) = inf
4904 kFP64DefaultNaN, // inf + (-inf * 1) = NaN
4905 kFP64NegativeInfinity, // -inf + (-inf * 1) = -inf
4906 kFP64DefaultNaN); // -inf + ( inf * 1) = NaN
4907 FmaddFmsubHelper(kFP64NegativeInfinity, 1.0, kFP64PositiveInfinity,
4908 kFP64DefaultNaN, // inf + (-inf * 1) = NaN
4909 kFP64PositiveInfinity, // inf + ( inf * 1) = inf
4910 kFP64DefaultNaN, // -inf + ( inf * 1) = NaN
4911 kFP64NegativeInfinity); // -inf + (-inf * 1) = -inf
armvixlf37fdc02014-02-05 13:22:16 +00004912}
4913
4914
armvixlb0c8ae22014-03-21 14:03:59 +00004915static void FmaddFmsubHelper(float n, float m, float a,
4916 float fmadd, float fmsub,
4917 float fnmadd, float fnmsub) {
armvixlf37fdc02014-02-05 13:22:16 +00004918 SETUP();
4919 START();
4920
4921 __ Fmov(s0, n);
4922 __ Fmov(s1, m);
4923 __ Fmov(s2, a);
armvixlb0c8ae22014-03-21 14:03:59 +00004924 __ Fmadd(s28, s0, s1, s2);
4925 __ Fmsub(s29, s0, s1, s2);
4926 __ Fnmadd(s30, s0, s1, s2);
4927 __ Fnmsub(s31, s0, s1, s2);
armvixlf37fdc02014-02-05 13:22:16 +00004928
4929 END();
4930 RUN();
4931
armvixlb0c8ae22014-03-21 14:03:59 +00004932 ASSERT_EQUAL_FP32(fmadd, s28);
4933 ASSERT_EQUAL_FP32(fmsub, s29);
4934 ASSERT_EQUAL_FP32(fnmadd, s30);
4935 ASSERT_EQUAL_FP32(fnmsub, s31);
armvixlf37fdc02014-02-05 13:22:16 +00004936
4937 TEARDOWN();
4938}
4939
4940
4941TEST(fmadd_fmsub_float) {
armvixlb0c8ae22014-03-21 14:03:59 +00004942 // It's hard to check the result of fused operations because the only way to
4943 // calculate the result is using fma, which is what the simulator uses anyway.
4944 // TODO(jbramley): Add tests to check behaviour against a hardware trace.
armvixlf37fdc02014-02-05 13:22:16 +00004945
armvixlb0c8ae22014-03-21 14:03:59 +00004946 // Basic operation.
4947 FmaddFmsubHelper(1.0f, 2.0f, 3.0f, 5.0f, 1.0f, -5.0f, -1.0f);
4948 FmaddFmsubHelper(-1.0f, 2.0f, 3.0f, 1.0f, 5.0f, -1.0f, -5.0f);
armvixlf37fdc02014-02-05 13:22:16 +00004949
armvixlb0c8ae22014-03-21 14:03:59 +00004950 // Check the sign of exact zeroes.
4951 // n m a fmadd fmsub fnmadd fnmsub
4952 FmaddFmsubHelper(-0.0f, +0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
4953 FmaddFmsubHelper(+0.0f, +0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
4954 FmaddFmsubHelper(+0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
4955 FmaddFmsubHelper(-0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
4956 FmaddFmsubHelper(+0.0f, -0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
4957 FmaddFmsubHelper(-0.0f, -0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
4958 FmaddFmsubHelper(-0.0f, -0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
4959 FmaddFmsubHelper(+0.0f, -0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
4960
4961 // Check NaN generation.
4962 FmaddFmsubHelper(kFP32PositiveInfinity, 0.0f, 42.0f,
4963 kFP32DefaultNaN, kFP32DefaultNaN,
4964 kFP32DefaultNaN, kFP32DefaultNaN);
4965 FmaddFmsubHelper(0.0f, kFP32PositiveInfinity, 42.0f,
4966 kFP32DefaultNaN, kFP32DefaultNaN,
4967 kFP32DefaultNaN, kFP32DefaultNaN);
4968 FmaddFmsubHelper(kFP32PositiveInfinity, 1.0f, kFP32PositiveInfinity,
4969 kFP32PositiveInfinity, // inf + ( inf * 1) = inf
4970 kFP32DefaultNaN, // inf + (-inf * 1) = NaN
4971 kFP32NegativeInfinity, // -inf + (-inf * 1) = -inf
4972 kFP32DefaultNaN); // -inf + ( inf * 1) = NaN
4973 FmaddFmsubHelper(kFP32NegativeInfinity, 1.0f, kFP32PositiveInfinity,
4974 kFP32DefaultNaN, // inf + (-inf * 1) = NaN
4975 kFP32PositiveInfinity, // inf + ( inf * 1) = inf
4976 kFP32DefaultNaN, // -inf + ( inf * 1) = NaN
4977 kFP32NegativeInfinity); // -inf + (-inf * 1) = -inf
armvixlf37fdc02014-02-05 13:22:16 +00004978}
4979
4980
armvixlb0c8ae22014-03-21 14:03:59 +00004981TEST(fmadd_fmsub_double_nans) {
4982 // Make sure that NaN propagation works correctly.
4983 double s1 = rawbits_to_double(0x7ff5555511111111);
4984 double s2 = rawbits_to_double(0x7ff5555522222222);
4985 double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
4986 double q1 = rawbits_to_double(0x7ffaaaaa11111111);
4987 double q2 = rawbits_to_double(0x7ffaaaaa22222222);
4988 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
4989 VIXL_ASSERT(IsSignallingNaN(s1));
4990 VIXL_ASSERT(IsSignallingNaN(s2));
4991 VIXL_ASSERT(IsSignallingNaN(sa));
4992 VIXL_ASSERT(IsQuietNaN(q1));
4993 VIXL_ASSERT(IsQuietNaN(q2));
4994 VIXL_ASSERT(IsQuietNaN(qa));
armvixlf37fdc02014-02-05 13:22:16 +00004995
armvixlb0c8ae22014-03-21 14:03:59 +00004996 // The input NaNs after passing through ProcessNaN.
4997 double s1_proc = rawbits_to_double(0x7ffd555511111111);
4998 double s2_proc = rawbits_to_double(0x7ffd555522222222);
4999 double sa_proc = rawbits_to_double(0x7ffd5555aaaaaaaa);
5000 double q1_proc = q1;
5001 double q2_proc = q2;
5002 double qa_proc = qa;
5003 VIXL_ASSERT(IsQuietNaN(s1_proc));
5004 VIXL_ASSERT(IsQuietNaN(s2_proc));
5005 VIXL_ASSERT(IsQuietNaN(sa_proc));
5006 VIXL_ASSERT(IsQuietNaN(q1_proc));
5007 VIXL_ASSERT(IsQuietNaN(q2_proc));
5008 VIXL_ASSERT(IsQuietNaN(qa_proc));
armvixlf37fdc02014-02-05 13:22:16 +00005009
armvixl5799d6c2014-05-01 11:05:00 +01005010 // Negated NaNs as it would be done on ARMv8 hardware.
5011 double s1_proc_neg = rawbits_to_double(0xfffd555511111111);
5012 double sa_proc_neg = rawbits_to_double(0xfffd5555aaaaaaaa);
5013 double q1_proc_neg = rawbits_to_double(0xfffaaaaa11111111);
5014 double qa_proc_neg = rawbits_to_double(0xfffaaaaaaaaaaaaa);
5015 VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
5016 VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
5017 VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
5018 VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
5019
armvixlb0c8ae22014-03-21 14:03:59 +00005020 // Quiet NaNs are propagated.
armvixl5799d6c2014-05-01 11:05:00 +01005021 FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00005022 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01005023 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
5024 FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
5025 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
5026 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
5027 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00005028
armvixlb0c8ae22014-03-21 14:03:59 +00005029 // Signalling NaNs are propagated, and made quiet.
armvixl5799d6c2014-05-01 11:05:00 +01005030 FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00005031 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01005032 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5033 FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
5034 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5035 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5036 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00005037
armvixlb0c8ae22014-03-21 14:03:59 +00005038 // Signalling NaNs take precedence over quiet NaNs.
armvixl5799d6c2014-05-01 11:05:00 +01005039 FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00005040 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01005041 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5042 FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
5043 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5044 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5045 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlf37fdc02014-02-05 13:22:16 +00005046
armvixlb0c8ae22014-03-21 14:03:59 +00005047 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
5048 FmaddFmsubHelper(0, kFP64PositiveInfinity, qa,
5049 kFP64DefaultNaN, kFP64DefaultNaN,
5050 kFP64DefaultNaN, kFP64DefaultNaN);
5051 FmaddFmsubHelper(kFP64PositiveInfinity, 0, qa,
5052 kFP64DefaultNaN, kFP64DefaultNaN,
5053 kFP64DefaultNaN, kFP64DefaultNaN);
5054 FmaddFmsubHelper(0, kFP64NegativeInfinity, qa,
5055 kFP64DefaultNaN, kFP64DefaultNaN,
5056 kFP64DefaultNaN, kFP64DefaultNaN);
5057 FmaddFmsubHelper(kFP64NegativeInfinity, 0, qa,
5058 kFP64DefaultNaN, kFP64DefaultNaN,
5059 kFP64DefaultNaN, kFP64DefaultNaN);
5060}
armvixlf37fdc02014-02-05 13:22:16 +00005061
armvixlf37fdc02014-02-05 13:22:16 +00005062
armvixlb0c8ae22014-03-21 14:03:59 +00005063TEST(fmadd_fmsub_float_nans) {
5064 // Make sure that NaN propagation works correctly.
5065 float s1 = rawbits_to_float(0x7f951111);
5066 float s2 = rawbits_to_float(0x7f952222);
5067 float sa = rawbits_to_float(0x7f95aaaa);
5068 float q1 = rawbits_to_float(0x7fea1111);
5069 float q2 = rawbits_to_float(0x7fea2222);
5070 float qa = rawbits_to_float(0x7feaaaaa);
5071 VIXL_ASSERT(IsSignallingNaN(s1));
5072 VIXL_ASSERT(IsSignallingNaN(s2));
5073 VIXL_ASSERT(IsSignallingNaN(sa));
5074 VIXL_ASSERT(IsQuietNaN(q1));
5075 VIXL_ASSERT(IsQuietNaN(q2));
5076 VIXL_ASSERT(IsQuietNaN(qa));
armvixlf37fdc02014-02-05 13:22:16 +00005077
armvixlb0c8ae22014-03-21 14:03:59 +00005078 // The input NaNs after passing through ProcessNaN.
5079 float s1_proc = rawbits_to_float(0x7fd51111);
5080 float s2_proc = rawbits_to_float(0x7fd52222);
5081 float sa_proc = rawbits_to_float(0x7fd5aaaa);
5082 float q1_proc = q1;
5083 float q2_proc = q2;
5084 float qa_proc = qa;
5085 VIXL_ASSERT(IsQuietNaN(s1_proc));
5086 VIXL_ASSERT(IsQuietNaN(s2_proc));
5087 VIXL_ASSERT(IsQuietNaN(sa_proc));
5088 VIXL_ASSERT(IsQuietNaN(q1_proc));
5089 VIXL_ASSERT(IsQuietNaN(q2_proc));
5090 VIXL_ASSERT(IsQuietNaN(qa_proc));
5091
armvixl5799d6c2014-05-01 11:05:00 +01005092 // Negated NaNs as it would be done on ARMv8 hardware.
5093 float s1_proc_neg = rawbits_to_float(0xffd51111);
5094 float sa_proc_neg = rawbits_to_float(0xffd5aaaa);
5095 float q1_proc_neg = rawbits_to_float(0xffea1111);
5096 float qa_proc_neg = rawbits_to_float(0xffeaaaaa);
5097 VIXL_ASSERT(IsQuietNaN(s1_proc_neg));
5098 VIXL_ASSERT(IsQuietNaN(sa_proc_neg));
5099 VIXL_ASSERT(IsQuietNaN(q1_proc_neg));
5100 VIXL_ASSERT(IsQuietNaN(qa_proc_neg));
5101
armvixlb0c8ae22014-03-21 14:03:59 +00005102 // Quiet NaNs are propagated.
armvixl5799d6c2014-05-01 11:05:00 +01005103 FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00005104 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01005105 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
5106 FmaddFmsubHelper(q1, q2, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc);
5107 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
5108 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
5109 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, qa_proc_neg, qa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00005110
5111 // Signalling NaNs are propagated, and made quiet.
armvixl5799d6c2014-05-01 11:05:00 +01005112 FmaddFmsubHelper(s1, 0, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00005113 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01005114 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5115 FmaddFmsubHelper(s1, s2, 0, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
5116 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5117 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5118 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00005119
5120 // Signalling NaNs take precedence over quiet NaNs.
armvixl5799d6c2014-05-01 11:05:00 +01005121 FmaddFmsubHelper(s1, q2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
armvixlb0c8ae22014-03-21 14:03:59 +00005122 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc);
armvixl5799d6c2014-05-01 11:05:00 +01005123 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5124 FmaddFmsubHelper(s1, s2, qa, s1_proc, s1_proc_neg, s1_proc_neg, s1_proc);
5125 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5126 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
5127 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, sa_proc_neg, sa_proc_neg);
armvixlb0c8ae22014-03-21 14:03:59 +00005128
5129 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
5130 FmaddFmsubHelper(0, kFP32PositiveInfinity, qa,
5131 kFP32DefaultNaN, kFP32DefaultNaN,
5132 kFP32DefaultNaN, kFP32DefaultNaN);
5133 FmaddFmsubHelper(kFP32PositiveInfinity, 0, qa,
5134 kFP32DefaultNaN, kFP32DefaultNaN,
5135 kFP32DefaultNaN, kFP32DefaultNaN);
5136 FmaddFmsubHelper(0, kFP32NegativeInfinity, qa,
5137 kFP32DefaultNaN, kFP32DefaultNaN,
5138 kFP32DefaultNaN, kFP32DefaultNaN);
5139 FmaddFmsubHelper(kFP32NegativeInfinity, 0, qa,
5140 kFP32DefaultNaN, kFP32DefaultNaN,
5141 kFP32DefaultNaN, kFP32DefaultNaN);
armvixlf37fdc02014-02-05 13:22:16 +00005142}
5143
5144
armvixlad96eda2013-06-14 11:42:37 +01005145TEST(fdiv) {
5146 SETUP();
5147
5148 START();
armvixlb0c8ae22014-03-21 14:03:59 +00005149 __ Fmov(s14, -0.0f);
5150 __ Fmov(s15, kFP32PositiveInfinity);
5151 __ Fmov(s16, kFP32NegativeInfinity);
5152 __ Fmov(s17, 3.25f);
5153 __ Fmov(s18, 2.0f);
5154 __ Fmov(s19, 2.0f);
5155 __ Fmov(s20, -2.0f);
armvixlad96eda2013-06-14 11:42:37 +01005156
5157 __ Fmov(d26, -0.0);
5158 __ Fmov(d27, kFP64PositiveInfinity);
5159 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00005160 __ Fmov(d29, 0.0);
armvixlad96eda2013-06-14 11:42:37 +01005161 __ Fmov(d30, -2.0);
5162 __ Fmov(d31, 2.25);
5163
armvixlb0c8ae22014-03-21 14:03:59 +00005164 __ Fdiv(s0, s17, s18);
5165 __ Fdiv(s1, s18, s19);
5166 __ Fdiv(s2, s14, s18);
5167 __ Fdiv(s3, s18, s15);
5168 __ Fdiv(s4, s18, s16);
5169 __ Fdiv(s5, s15, s16);
5170 __ Fdiv(s6, s14, s14);
5171
5172 __ Fdiv(d7, d31, d30);
5173 __ Fdiv(d8, d29, d31);
5174 __ Fdiv(d9, d26, d31);
5175 __ Fdiv(d10, d31, d27);
5176 __ Fdiv(d11, d31, d28);
5177 __ Fdiv(d12, d28, d27);
5178 __ Fdiv(d13, d29, d29);
armvixlad96eda2013-06-14 11:42:37 +01005179 END();
5180
5181 RUN();
5182
armvixlb0c8ae22014-03-21 14:03:59 +00005183 ASSERT_EQUAL_FP32(1.625f, s0);
5184 ASSERT_EQUAL_FP32(1.0f, s1);
5185 ASSERT_EQUAL_FP32(-0.0f, s2);
5186 ASSERT_EQUAL_FP32(0.0f, s3);
5187 ASSERT_EQUAL_FP32(-0.0f, s4);
5188 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
5189 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
5190 ASSERT_EQUAL_FP64(-1.125, d7);
armvixlad96eda2013-06-14 11:42:37 +01005191 ASSERT_EQUAL_FP64(0.0, d8);
5192 ASSERT_EQUAL_FP64(-0.0, d9);
armvixlb0c8ae22014-03-21 14:03:59 +00005193 ASSERT_EQUAL_FP64(0.0, d10);
5194 ASSERT_EQUAL_FP64(-0.0, d11);
5195 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
5196 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01005197
5198 TEARDOWN();
5199}
5200
5201
armvixlf37fdc02014-02-05 13:22:16 +00005202static float MinMaxHelper(float n,
5203 float m,
5204 bool min,
5205 float quiet_nan_substitute = 0.0) {
armvixlb0c8ae22014-03-21 14:03:59 +00005206 const uint64_t kFP32QuietNaNMask = 0x00400000;
armvixlf37fdc02014-02-05 13:22:16 +00005207 uint32_t raw_n = float_to_rawbits(n);
5208 uint32_t raw_m = float_to_rawbits(m);
armvixlad96eda2013-06-14 11:42:37 +01005209
armvixlf37fdc02014-02-05 13:22:16 +00005210 if (isnan(n) && ((raw_n & kFP32QuietNaNMask) == 0)) {
5211 // n is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00005212 return rawbits_to_float(raw_n | kFP32QuietNaNMask);
armvixlf37fdc02014-02-05 13:22:16 +00005213 } else if (isnan(m) && ((raw_m & kFP32QuietNaNMask) == 0)) {
5214 // m is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00005215 return rawbits_to_float(raw_m | kFP32QuietNaNMask);
armvixlf37fdc02014-02-05 13:22:16 +00005216 } else if (quiet_nan_substitute == 0.0) {
5217 if (isnan(n)) {
5218 // n is quiet NaN.
5219 return n;
5220 } else if (isnan(m)) {
5221 // m is quiet NaN.
5222 return m;
5223 }
5224 } else {
5225 // Substitute n or m if one is quiet, but not both.
5226 if (isnan(n) && !isnan(m)) {
5227 // n is quiet NaN: replace with substitute.
5228 n = quiet_nan_substitute;
5229 } else if (!isnan(n) && isnan(m)) {
5230 // m is quiet NaN: replace with substitute.
5231 m = quiet_nan_substitute;
armvixlad96eda2013-06-14 11:42:37 +01005232 }
5233 }
armvixlad96eda2013-06-14 11:42:37 +01005234
armvixlf37fdc02014-02-05 13:22:16 +00005235 if ((n == 0.0) && (m == 0.0) &&
5236 (copysign(1.0, n) != copysign(1.0, m))) {
5237 return min ? -0.0 : 0.0;
5238 }
armvixlad96eda2013-06-14 11:42:37 +01005239
armvixlf37fdc02014-02-05 13:22:16 +00005240 return min ? fminf(n, m) : fmaxf(n, m);
armvixlad96eda2013-06-14 11:42:37 +01005241}
5242
5243
armvixlf37fdc02014-02-05 13:22:16 +00005244static double MinMaxHelper(double n,
5245 double m,
5246 bool min,
5247 double quiet_nan_substitute = 0.0) {
armvixlb0c8ae22014-03-21 14:03:59 +00005248 const uint64_t kFP64QuietNaNMask = 0x0008000000000000;
armvixlf37fdc02014-02-05 13:22:16 +00005249 uint64_t raw_n = double_to_rawbits(n);
5250 uint64_t raw_m = double_to_rawbits(m);
armvixlad96eda2013-06-14 11:42:37 +01005251
armvixlf37fdc02014-02-05 13:22:16 +00005252 if (isnan(n) && ((raw_n & kFP64QuietNaNMask) == 0)) {
5253 // n is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00005254 return rawbits_to_double(raw_n | kFP64QuietNaNMask);
armvixlf37fdc02014-02-05 13:22:16 +00005255 } else if (isnan(m) && ((raw_m & kFP64QuietNaNMask) == 0)) {
5256 // m is signalling NaN.
armvixlb0c8ae22014-03-21 14:03:59 +00005257 return rawbits_to_double(raw_m | kFP64QuietNaNMask);
armvixlf37fdc02014-02-05 13:22:16 +00005258 } else if (quiet_nan_substitute == 0.0) {
5259 if (isnan(n)) {
5260 // n is quiet NaN.
5261 return n;
5262 } else if (isnan(m)) {
5263 // m is quiet NaN.
5264 return m;
5265 }
5266 } else {
5267 // Substitute n or m if one is quiet, but not both.
5268 if (isnan(n) && !isnan(m)) {
5269 // n is quiet NaN: replace with substitute.
5270 n = quiet_nan_substitute;
5271 } else if (!isnan(n) && isnan(m)) {
5272 // m is quiet NaN: replace with substitute.
5273 m = quiet_nan_substitute;
armvixlad96eda2013-06-14 11:42:37 +01005274 }
5275 }
armvixlf37fdc02014-02-05 13:22:16 +00005276
5277 if ((n == 0.0) && (m == 0.0) &&
5278 (copysign(1.0, n) != copysign(1.0, m))) {
5279 return min ? -0.0 : 0.0;
5280 }
5281
5282 return min ? fmin(n, m) : fmax(n, m);
5283}
5284
5285
5286static void FminFmaxDoubleHelper(double n, double m, double min, double max,
5287 double minnm, double maxnm) {
5288 SETUP();
5289
5290 START();
5291 __ Fmov(d0, n);
5292 __ Fmov(d1, m);
5293 __ Fmin(d28, d0, d1);
5294 __ Fmax(d29, d0, d1);
5295 __ Fminnm(d30, d0, d1);
5296 __ Fmaxnm(d31, d0, d1);
armvixlad96eda2013-06-14 11:42:37 +01005297 END();
5298
5299 RUN();
5300
armvixlf37fdc02014-02-05 13:22:16 +00005301 ASSERT_EQUAL_FP64(min, d28);
5302 ASSERT_EQUAL_FP64(max, d29);
5303 ASSERT_EQUAL_FP64(minnm, d30);
5304 ASSERT_EQUAL_FP64(maxnm, d31);
armvixlad96eda2013-06-14 11:42:37 +01005305
5306 TEARDOWN();
5307}
5308
5309
armvixlf37fdc02014-02-05 13:22:16 +00005310TEST(fmax_fmin_d) {
armvixlb0c8ae22014-03-21 14:03:59 +00005311 // Use non-standard NaNs to check that the payload bits are preserved.
5312 double snan = rawbits_to_double(0x7ff5555512345678);
5313 double qnan = rawbits_to_double(0x7ffaaaaa87654321);
5314
5315 double snan_processed = rawbits_to_double(0x7ffd555512345678);
5316 double qnan_processed = qnan;
5317
5318 VIXL_ASSERT(IsSignallingNaN(snan));
5319 VIXL_ASSERT(IsQuietNaN(qnan));
5320 VIXL_ASSERT(IsQuietNaN(snan_processed));
5321 VIXL_ASSERT(IsQuietNaN(qnan_processed));
5322
armvixlf37fdc02014-02-05 13:22:16 +00005323 // Bootstrap tests.
5324 FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0);
5325 FminFmaxDoubleHelper(0, 1, 0, 1, 0, 1);
5326 FminFmaxDoubleHelper(kFP64PositiveInfinity, kFP64NegativeInfinity,
5327 kFP64NegativeInfinity, kFP64PositiveInfinity,
5328 kFP64NegativeInfinity, kFP64PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00005329 FminFmaxDoubleHelper(snan, 0,
5330 snan_processed, snan_processed,
5331 snan_processed, snan_processed);
5332 FminFmaxDoubleHelper(0, snan,
5333 snan_processed, snan_processed,
5334 snan_processed, snan_processed);
5335 FminFmaxDoubleHelper(qnan, 0,
5336 qnan_processed, qnan_processed,
armvixlf37fdc02014-02-05 13:22:16 +00005337 0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00005338 FminFmaxDoubleHelper(0, qnan,
5339 qnan_processed, qnan_processed,
5340 0, 0);
5341 FminFmaxDoubleHelper(qnan, snan,
5342 snan_processed, snan_processed,
5343 snan_processed, snan_processed);
5344 FminFmaxDoubleHelper(snan, qnan,
5345 snan_processed, snan_processed,
5346 snan_processed, snan_processed);
armvixlf37fdc02014-02-05 13:22:16 +00005347
5348 // Iterate over all combinations of inputs.
5349 double inputs[] = { DBL_MAX, DBL_MIN, 1.0, 0.0,
5350 -DBL_MAX, -DBL_MIN, -1.0, -0.0,
5351 kFP64PositiveInfinity, kFP64NegativeInfinity,
5352 kFP64QuietNaN, kFP64SignallingNaN };
5353
5354 const int count = sizeof(inputs) / sizeof(inputs[0]);
5355
5356 for (int in = 0; in < count; in++) {
5357 double n = inputs[in];
5358 for (int im = 0; im < count; im++) {
5359 double m = inputs[im];
5360 FminFmaxDoubleHelper(n, m,
5361 MinMaxHelper(n, m, true),
5362 MinMaxHelper(n, m, false),
5363 MinMaxHelper(n, m, true, kFP64PositiveInfinity),
5364 MinMaxHelper(n, m, false, kFP64NegativeInfinity));
5365 }
5366 }
5367}
5368
5369
5370static void FminFmaxFloatHelper(float n, float m, float min, float max,
5371 float minnm, float maxnm) {
5372 SETUP();
5373
5374 START();
armvixlb0c8ae22014-03-21 14:03:59 +00005375 __ Fmov(s0, n);
5376 __ Fmov(s1, m);
armvixlf37fdc02014-02-05 13:22:16 +00005377 __ Fmin(s28, s0, s1);
5378 __ Fmax(s29, s0, s1);
5379 __ Fminnm(s30, s0, s1);
5380 __ Fmaxnm(s31, s0, s1);
5381 END();
5382
5383 RUN();
5384
5385 ASSERT_EQUAL_FP32(min, s28);
5386 ASSERT_EQUAL_FP32(max, s29);
5387 ASSERT_EQUAL_FP32(minnm, s30);
5388 ASSERT_EQUAL_FP32(maxnm, s31);
5389
5390 TEARDOWN();
5391}
5392
5393
5394TEST(fmax_fmin_s) {
armvixlb0c8ae22014-03-21 14:03:59 +00005395 // Use non-standard NaNs to check that the payload bits are preserved.
5396 float snan = rawbits_to_float(0x7f951234);
5397 float qnan = rawbits_to_float(0x7fea8765);
5398
5399 float snan_processed = rawbits_to_float(0x7fd51234);
5400 float qnan_processed = qnan;
5401
5402 VIXL_ASSERT(IsSignallingNaN(snan));
5403 VIXL_ASSERT(IsQuietNaN(qnan));
5404 VIXL_ASSERT(IsQuietNaN(snan_processed));
5405 VIXL_ASSERT(IsQuietNaN(qnan_processed));
5406
armvixlf37fdc02014-02-05 13:22:16 +00005407 // Bootstrap tests.
5408 FminFmaxFloatHelper(0, 0, 0, 0, 0, 0);
5409 FminFmaxFloatHelper(0, 1, 0, 1, 0, 1);
5410 FminFmaxFloatHelper(kFP32PositiveInfinity, kFP32NegativeInfinity,
5411 kFP32NegativeInfinity, kFP32PositiveInfinity,
5412 kFP32NegativeInfinity, kFP32PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00005413 FminFmaxFloatHelper(snan, 0,
5414 snan_processed, snan_processed,
5415 snan_processed, snan_processed);
5416 FminFmaxFloatHelper(0, snan,
5417 snan_processed, snan_processed,
5418 snan_processed, snan_processed);
5419 FminFmaxFloatHelper(qnan, 0,
5420 qnan_processed, qnan_processed,
armvixlf37fdc02014-02-05 13:22:16 +00005421 0, 0);
armvixlb0c8ae22014-03-21 14:03:59 +00005422 FminFmaxFloatHelper(0, qnan,
5423 qnan_processed, qnan_processed,
5424 0, 0);
5425 FminFmaxFloatHelper(qnan, snan,
5426 snan_processed, snan_processed,
5427 snan_processed, snan_processed);
5428 FminFmaxFloatHelper(snan, qnan,
5429 snan_processed, snan_processed,
5430 snan_processed, snan_processed);
armvixlf37fdc02014-02-05 13:22:16 +00005431
5432 // Iterate over all combinations of inputs.
5433 float inputs[] = { FLT_MAX, FLT_MIN, 1.0, 0.0,
5434 -FLT_MAX, -FLT_MIN, -1.0, -0.0,
5435 kFP32PositiveInfinity, kFP32NegativeInfinity,
5436 kFP32QuietNaN, kFP32SignallingNaN };
5437
5438 const int count = sizeof(inputs) / sizeof(inputs[0]);
5439
5440 for (int in = 0; in < count; in++) {
5441 float n = inputs[in];
5442 for (int im = 0; im < count; im++) {
5443 float m = inputs[im];
5444 FminFmaxFloatHelper(n, m,
5445 MinMaxHelper(n, m, true),
5446 MinMaxHelper(n, m, false),
5447 MinMaxHelper(n, m, true, kFP32PositiveInfinity),
5448 MinMaxHelper(n, m, false, kFP32NegativeInfinity));
5449 }
5450 }
5451}
5452
5453
armvixlad96eda2013-06-14 11:42:37 +01005454TEST(fccmp) {
5455 SETUP();
5456
5457 START();
5458 __ Fmov(s16, 0.0);
5459 __ Fmov(s17, 0.5);
5460 __ Fmov(d18, -0.5);
5461 __ Fmov(d19, -1.0);
5462 __ Mov(x20, 0);
5463
armvixl578645f2013-08-15 17:21:42 +01005464 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01005465 __ Fccmp(s16, s16, NoFlag, eq);
5466 __ Mrs(x0, NZCV);
5467
armvixl578645f2013-08-15 17:21:42 +01005468 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01005469 __ Fccmp(s16, s16, VFlag, ne);
5470 __ Mrs(x1, NZCV);
5471
armvixl578645f2013-08-15 17:21:42 +01005472 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01005473 __ Fccmp(s16, s17, CFlag, ge);
5474 __ Mrs(x2, NZCV);
5475
armvixl578645f2013-08-15 17:21:42 +01005476 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01005477 __ Fccmp(s16, s17, CVFlag, lt);
5478 __ Mrs(x3, NZCV);
5479
armvixl578645f2013-08-15 17:21:42 +01005480 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01005481 __ Fccmp(d18, d18, ZFlag, le);
5482 __ Mrs(x4, NZCV);
5483
armvixl578645f2013-08-15 17:21:42 +01005484 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01005485 __ Fccmp(d18, d18, ZVFlag, gt);
5486 __ Mrs(x5, NZCV);
5487
armvixl578645f2013-08-15 17:21:42 +01005488 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01005489 __ Fccmp(d18, d19, ZCVFlag, ls);
5490 __ Mrs(x6, NZCV);
5491
armvixl578645f2013-08-15 17:21:42 +01005492 __ Cmp(x20, 0);
armvixlad96eda2013-06-14 11:42:37 +01005493 __ Fccmp(d18, d19, NFlag, hi);
5494 __ Mrs(x7, NZCV);
armvixl578645f2013-08-15 17:21:42 +01005495
5496 __ fccmp(s16, s16, NFlag, al);
5497 __ Mrs(x8, NZCV);
5498
5499 __ fccmp(d18, d18, NFlag, nv);
5500 __ Mrs(x9, NZCV);
armvixlad96eda2013-06-14 11:42:37 +01005501 END();
5502
5503 RUN();
5504
5505 ASSERT_EQUAL_32(ZCFlag, w0);
5506 ASSERT_EQUAL_32(VFlag, w1);
5507 ASSERT_EQUAL_32(NFlag, w2);
5508 ASSERT_EQUAL_32(CVFlag, w3);
5509 ASSERT_EQUAL_32(ZCFlag, w4);
5510 ASSERT_EQUAL_32(ZVFlag, w5);
5511 ASSERT_EQUAL_32(CFlag, w6);
5512 ASSERT_EQUAL_32(NFlag, w7);
armvixl578645f2013-08-15 17:21:42 +01005513 ASSERT_EQUAL_32(ZCFlag, w8);
5514 ASSERT_EQUAL_32(ZCFlag, w9);
armvixlad96eda2013-06-14 11:42:37 +01005515
5516 TEARDOWN();
5517}
5518
5519
5520TEST(fcmp) {
5521 SETUP();
5522
5523 START();
armvixlf37fdc02014-02-05 13:22:16 +00005524
5525 // Some of these tests require a floating-point scratch register assigned to
5526 // the macro assembler, but most do not.
armvixlb0c8ae22014-03-21 14:03:59 +00005527 {
5528 UseScratchRegisterScope temps(&masm);
5529 temps.ExcludeAll();
5530 temps.Include(ip0, ip1);
armvixlf37fdc02014-02-05 13:22:16 +00005531
armvixlb0c8ae22014-03-21 14:03:59 +00005532 __ Fmov(s8, 0.0);
5533 __ Fmov(s9, 0.5);
5534 __ Mov(w18, 0x7f800001); // Single precision NaN.
5535 __ Fmov(s18, w18);
armvixlad96eda2013-06-14 11:42:37 +01005536
armvixlb0c8ae22014-03-21 14:03:59 +00005537 __ Fcmp(s8, s8);
5538 __ Mrs(x0, NZCV);
5539 __ Fcmp(s8, s9);
5540 __ Mrs(x1, NZCV);
5541 __ Fcmp(s9, s8);
5542 __ Mrs(x2, NZCV);
5543 __ Fcmp(s8, s18);
5544 __ Mrs(x3, NZCV);
5545 __ Fcmp(s18, s18);
5546 __ Mrs(x4, NZCV);
5547 __ Fcmp(s8, 0.0);
5548 __ Mrs(x5, NZCV);
5549 temps.Include(d0);
5550 __ Fcmp(s8, 255.0);
5551 temps.Exclude(d0);
5552 __ Mrs(x6, NZCV);
armvixlad96eda2013-06-14 11:42:37 +01005553
armvixlb0c8ae22014-03-21 14:03:59 +00005554 __ Fmov(d19, 0.0);
5555 __ Fmov(d20, 0.5);
5556 __ Mov(x21, 0x7ff0000000000001); // Double precision NaN.
5557 __ Fmov(d21, x21);
armvixlad96eda2013-06-14 11:42:37 +01005558
armvixlb0c8ae22014-03-21 14:03:59 +00005559 __ Fcmp(d19, d19);
5560 __ Mrs(x10, NZCV);
5561 __ Fcmp(d19, d20);
5562 __ Mrs(x11, NZCV);
5563 __ Fcmp(d20, d19);
5564 __ Mrs(x12, NZCV);
5565 __ Fcmp(d19, d21);
5566 __ Mrs(x13, NZCV);
5567 __ Fcmp(d21, d21);
5568 __ Mrs(x14, NZCV);
5569 __ Fcmp(d19, 0.0);
5570 __ Mrs(x15, NZCV);
5571 temps.Include(d0);
5572 __ Fcmp(d19, 12.3456);
5573 temps.Exclude(d0);
5574 __ Mrs(x16, NZCV);
5575 }
5576
armvixlad96eda2013-06-14 11:42:37 +01005577 END();
5578
5579 RUN();
5580
5581 ASSERT_EQUAL_32(ZCFlag, w0);
5582 ASSERT_EQUAL_32(NFlag, w1);
5583 ASSERT_EQUAL_32(CFlag, w2);
5584 ASSERT_EQUAL_32(CVFlag, w3);
5585 ASSERT_EQUAL_32(CVFlag, w4);
5586 ASSERT_EQUAL_32(ZCFlag, w5);
5587 ASSERT_EQUAL_32(NFlag, w6);
5588 ASSERT_EQUAL_32(ZCFlag, w10);
5589 ASSERT_EQUAL_32(NFlag, w11);
5590 ASSERT_EQUAL_32(CFlag, w12);
5591 ASSERT_EQUAL_32(CVFlag, w13);
5592 ASSERT_EQUAL_32(CVFlag, w14);
5593 ASSERT_EQUAL_32(ZCFlag, w15);
5594 ASSERT_EQUAL_32(NFlag, w16);
5595
5596 TEARDOWN();
5597}
5598
5599
5600TEST(fcsel) {
5601 SETUP();
5602
5603 START();
5604 __ Mov(x16, 0);
5605 __ Fmov(s16, 1.0);
5606 __ Fmov(s17, 2.0);
5607 __ Fmov(d18, 3.0);
5608 __ Fmov(d19, 4.0);
5609
armvixl578645f2013-08-15 17:21:42 +01005610 __ Cmp(x16, 0);
armvixlad96eda2013-06-14 11:42:37 +01005611 __ Fcsel(s0, s16, s17, eq);
5612 __ Fcsel(s1, s16, s17, ne);
5613 __ Fcsel(d2, d18, d19, eq);
5614 __ Fcsel(d3, d18, d19, ne);
armvixl578645f2013-08-15 17:21:42 +01005615 __ fcsel(s4, s16, s17, al);
5616 __ fcsel(d5, d18, d19, nv);
armvixlad96eda2013-06-14 11:42:37 +01005617 END();
5618
5619 RUN();
5620
5621 ASSERT_EQUAL_FP32(1.0, s0);
5622 ASSERT_EQUAL_FP32(2.0, s1);
5623 ASSERT_EQUAL_FP64(3.0, d2);
5624 ASSERT_EQUAL_FP64(4.0, d3);
armvixl578645f2013-08-15 17:21:42 +01005625 ASSERT_EQUAL_FP32(1.0, s4);
5626 ASSERT_EQUAL_FP64(3.0, d5);
armvixlad96eda2013-06-14 11:42:37 +01005627
5628 TEARDOWN();
5629}
5630
5631
5632TEST(fneg) {
5633 SETUP();
5634
5635 START();
5636 __ Fmov(s16, 1.0);
5637 __ Fmov(s17, 0.0);
5638 __ Fmov(s18, kFP32PositiveInfinity);
5639 __ Fmov(d19, 1.0);
5640 __ Fmov(d20, 0.0);
5641 __ Fmov(d21, kFP64PositiveInfinity);
5642
5643 __ Fneg(s0, s16);
5644 __ Fneg(s1, s0);
5645 __ Fneg(s2, s17);
5646 __ Fneg(s3, s2);
5647 __ Fneg(s4, s18);
5648 __ Fneg(s5, s4);
5649 __ Fneg(d6, d19);
5650 __ Fneg(d7, d6);
5651 __ Fneg(d8, d20);
5652 __ Fneg(d9, d8);
5653 __ Fneg(d10, d21);
5654 __ Fneg(d11, d10);
5655 END();
5656
5657 RUN();
5658
5659 ASSERT_EQUAL_FP32(-1.0, s0);
5660 ASSERT_EQUAL_FP32(1.0, s1);
5661 ASSERT_EQUAL_FP32(-0.0, s2);
5662 ASSERT_EQUAL_FP32(0.0, s3);
5663 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
5664 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
5665 ASSERT_EQUAL_FP64(-1.0, d6);
5666 ASSERT_EQUAL_FP64(1.0, d7);
5667 ASSERT_EQUAL_FP64(-0.0, d8);
5668 ASSERT_EQUAL_FP64(0.0, d9);
5669 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
5670 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
5671
5672 TEARDOWN();
5673}
5674
5675
5676TEST(fabs) {
5677 SETUP();
5678
5679 START();
5680 __ Fmov(s16, -1.0);
5681 __ Fmov(s17, -0.0);
5682 __ Fmov(s18, kFP32NegativeInfinity);
5683 __ Fmov(d19, -1.0);
5684 __ Fmov(d20, -0.0);
5685 __ Fmov(d21, kFP64NegativeInfinity);
5686
5687 __ Fabs(s0, s16);
5688 __ Fabs(s1, s0);
5689 __ Fabs(s2, s17);
5690 __ Fabs(s3, s18);
5691 __ Fabs(d4, d19);
5692 __ Fabs(d5, d4);
5693 __ Fabs(d6, d20);
5694 __ Fabs(d7, d21);
5695 END();
5696
5697 RUN();
5698
5699 ASSERT_EQUAL_FP32(1.0, s0);
5700 ASSERT_EQUAL_FP32(1.0, s1);
5701 ASSERT_EQUAL_FP32(0.0, s2);
5702 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
5703 ASSERT_EQUAL_FP64(1.0, d4);
5704 ASSERT_EQUAL_FP64(1.0, d5);
5705 ASSERT_EQUAL_FP64(0.0, d6);
5706 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
5707
5708 TEARDOWN();
5709}
5710
5711
5712TEST(fsqrt) {
5713 SETUP();
5714
5715 START();
5716 __ Fmov(s16, 0.0);
5717 __ Fmov(s17, 1.0);
5718 __ Fmov(s18, 0.25);
5719 __ Fmov(s19, 65536.0);
5720 __ Fmov(s20, -0.0);
5721 __ Fmov(s21, kFP32PositiveInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00005722 __ Fmov(s22, -1.0);
5723 __ Fmov(d23, 0.0);
5724 __ Fmov(d24, 1.0);
5725 __ Fmov(d25, 0.25);
5726 __ Fmov(d26, 4294967296.0);
5727 __ Fmov(d27, -0.0);
5728 __ Fmov(d28, kFP64PositiveInfinity);
5729 __ Fmov(d29, -1.0);
armvixlad96eda2013-06-14 11:42:37 +01005730
5731 __ Fsqrt(s0, s16);
5732 __ Fsqrt(s1, s17);
5733 __ Fsqrt(s2, s18);
5734 __ Fsqrt(s3, s19);
5735 __ Fsqrt(s4, s20);
5736 __ Fsqrt(s5, s21);
armvixlb0c8ae22014-03-21 14:03:59 +00005737 __ Fsqrt(s6, s22);
armvixlad96eda2013-06-14 11:42:37 +01005738 __ Fsqrt(d7, d23);
5739 __ Fsqrt(d8, d24);
5740 __ Fsqrt(d9, d25);
5741 __ Fsqrt(d10, d26);
5742 __ Fsqrt(d11, d27);
armvixlb0c8ae22014-03-21 14:03:59 +00005743 __ Fsqrt(d12, d28);
5744 __ Fsqrt(d13, d29);
armvixlad96eda2013-06-14 11:42:37 +01005745 END();
5746
5747 RUN();
5748
5749 ASSERT_EQUAL_FP32(0.0, s0);
5750 ASSERT_EQUAL_FP32(1.0, s1);
5751 ASSERT_EQUAL_FP32(0.5, s2);
5752 ASSERT_EQUAL_FP32(256.0, s3);
5753 ASSERT_EQUAL_FP32(-0.0, s4);
5754 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
armvixlb0c8ae22014-03-21 14:03:59 +00005755 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
5756 ASSERT_EQUAL_FP64(0.0, d7);
5757 ASSERT_EQUAL_FP64(1.0, d8);
5758 ASSERT_EQUAL_FP64(0.5, d9);
5759 ASSERT_EQUAL_FP64(65536.0, d10);
5760 ASSERT_EQUAL_FP64(-0.0, d11);
5761 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d12);
5762 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
armvixlad96eda2013-06-14 11:42:37 +01005763
5764 TEARDOWN();
5765}
5766
5767
armvixlf37fdc02014-02-05 13:22:16 +00005768TEST(frinta) {
5769 SETUP();
5770
5771 START();
5772 __ Fmov(s16, 1.0);
5773 __ Fmov(s17, 1.1);
5774 __ Fmov(s18, 1.5);
5775 __ Fmov(s19, 1.9);
5776 __ Fmov(s20, 2.5);
5777 __ Fmov(s21, -1.5);
5778 __ Fmov(s22, -2.5);
5779 __ Fmov(s23, kFP32PositiveInfinity);
5780 __ Fmov(s24, kFP32NegativeInfinity);
5781 __ Fmov(s25, 0.0);
5782 __ Fmov(s26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +01005783 __ Fmov(s27, -0.2);
armvixlf37fdc02014-02-05 13:22:16 +00005784
5785 __ Frinta(s0, s16);
5786 __ Frinta(s1, s17);
5787 __ Frinta(s2, s18);
5788 __ Frinta(s3, s19);
5789 __ Frinta(s4, s20);
5790 __ Frinta(s5, s21);
5791 __ Frinta(s6, s22);
5792 __ Frinta(s7, s23);
5793 __ Frinta(s8, s24);
5794 __ Frinta(s9, s25);
5795 __ Frinta(s10, s26);
armvixl5799d6c2014-05-01 11:05:00 +01005796 __ Frinta(s11, s27);
armvixlf37fdc02014-02-05 13:22:16 +00005797
5798 __ Fmov(d16, 1.0);
5799 __ Fmov(d17, 1.1);
5800 __ Fmov(d18, 1.5);
5801 __ Fmov(d19, 1.9);
5802 __ Fmov(d20, 2.5);
5803 __ Fmov(d21, -1.5);
5804 __ Fmov(d22, -2.5);
5805 __ Fmov(d23, kFP32PositiveInfinity);
5806 __ Fmov(d24, kFP32NegativeInfinity);
5807 __ Fmov(d25, 0.0);
5808 __ Fmov(d26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +01005809 __ Fmov(d27, -0.2);
armvixlf37fdc02014-02-05 13:22:16 +00005810
armvixl5799d6c2014-05-01 11:05:00 +01005811 __ Frinta(d12, d16);
5812 __ Frinta(d13, d17);
5813 __ Frinta(d14, d18);
5814 __ Frinta(d15, d19);
5815 __ Frinta(d16, d20);
5816 __ Frinta(d17, d21);
5817 __ Frinta(d18, d22);
5818 __ Frinta(d19, d23);
5819 __ Frinta(d20, d24);
5820 __ Frinta(d21, d25);
5821 __ Frinta(d22, d26);
5822 __ Frinta(d23, d27);
armvixlf37fdc02014-02-05 13:22:16 +00005823 END();
5824
5825 RUN();
5826
5827 ASSERT_EQUAL_FP32(1.0, s0);
5828 ASSERT_EQUAL_FP32(1.0, s1);
5829 ASSERT_EQUAL_FP32(2.0, s2);
5830 ASSERT_EQUAL_FP32(2.0, s3);
5831 ASSERT_EQUAL_FP32(3.0, s4);
5832 ASSERT_EQUAL_FP32(-2.0, s5);
5833 ASSERT_EQUAL_FP32(-3.0, s6);
5834 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
5835 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
5836 ASSERT_EQUAL_FP32(0.0, s9);
5837 ASSERT_EQUAL_FP32(-0.0, s10);
armvixl5799d6c2014-05-01 11:05:00 +01005838 ASSERT_EQUAL_FP32(-0.0, s11);
armvixlf37fdc02014-02-05 13:22:16 +00005839 ASSERT_EQUAL_FP64(1.0, d12);
armvixl5799d6c2014-05-01 11:05:00 +01005840 ASSERT_EQUAL_FP64(1.0, d13);
armvixlf37fdc02014-02-05 13:22:16 +00005841 ASSERT_EQUAL_FP64(2.0, d14);
armvixl5799d6c2014-05-01 11:05:00 +01005842 ASSERT_EQUAL_FP64(2.0, d15);
5843 ASSERT_EQUAL_FP64(3.0, d16);
5844 ASSERT_EQUAL_FP64(-2.0, d17);
5845 ASSERT_EQUAL_FP64(-3.0, d18);
5846 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
5847 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
5848 ASSERT_EQUAL_FP64(0.0, d21);
5849 ASSERT_EQUAL_FP64(-0.0, d22);
5850 ASSERT_EQUAL_FP64(-0.0, d23);
5851
5852 TEARDOWN();
5853}
5854
5855
5856TEST(frintm) {
5857 SETUP();
5858
5859 START();
5860 __ Fmov(s16, 1.0);
5861 __ Fmov(s17, 1.1);
5862 __ Fmov(s18, 1.5);
5863 __ Fmov(s19, 1.9);
5864 __ Fmov(s20, 2.5);
5865 __ Fmov(s21, -1.5);
5866 __ Fmov(s22, -2.5);
5867 __ Fmov(s23, kFP32PositiveInfinity);
5868 __ Fmov(s24, kFP32NegativeInfinity);
5869 __ Fmov(s25, 0.0);
5870 __ Fmov(s26, -0.0);
5871 __ Fmov(s27, -0.2);
5872
5873 __ Frintm(s0, s16);
5874 __ Frintm(s1, s17);
5875 __ Frintm(s2, s18);
5876 __ Frintm(s3, s19);
5877 __ Frintm(s4, s20);
5878 __ Frintm(s5, s21);
5879 __ Frintm(s6, s22);
5880 __ Frintm(s7, s23);
5881 __ Frintm(s8, s24);
5882 __ Frintm(s9, s25);
5883 __ Frintm(s10, s26);
5884 __ Frintm(s11, s27);
5885
5886 __ Fmov(d16, 1.0);
5887 __ Fmov(d17, 1.1);
5888 __ Fmov(d18, 1.5);
5889 __ Fmov(d19, 1.9);
5890 __ Fmov(d20, 2.5);
5891 __ Fmov(d21, -1.5);
5892 __ Fmov(d22, -2.5);
5893 __ Fmov(d23, kFP32PositiveInfinity);
5894 __ Fmov(d24, kFP32NegativeInfinity);
5895 __ Fmov(d25, 0.0);
5896 __ Fmov(d26, -0.0);
5897 __ Fmov(d27, -0.2);
5898
5899 __ Frintm(d12, d16);
5900 __ Frintm(d13, d17);
5901 __ Frintm(d14, d18);
5902 __ Frintm(d15, d19);
5903 __ Frintm(d16, d20);
5904 __ Frintm(d17, d21);
5905 __ Frintm(d18, d22);
5906 __ Frintm(d19, d23);
5907 __ Frintm(d20, d24);
5908 __ Frintm(d21, d25);
5909 __ Frintm(d22, d26);
5910 __ Frintm(d23, d27);
5911 END();
5912
5913 RUN();
5914
5915 ASSERT_EQUAL_FP32(1.0, s0);
5916 ASSERT_EQUAL_FP32(1.0, s1);
5917 ASSERT_EQUAL_FP32(1.0, s2);
5918 ASSERT_EQUAL_FP32(1.0, s3);
5919 ASSERT_EQUAL_FP32(2.0, s4);
5920 ASSERT_EQUAL_FP32(-2.0, s5);
5921 ASSERT_EQUAL_FP32(-3.0, s6);
5922 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
5923 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
5924 ASSERT_EQUAL_FP32(0.0, s9);
5925 ASSERT_EQUAL_FP32(-0.0, s10);
5926 ASSERT_EQUAL_FP32(-1.0, s11);
5927 ASSERT_EQUAL_FP64(1.0, d12);
5928 ASSERT_EQUAL_FP64(1.0, d13);
5929 ASSERT_EQUAL_FP64(1.0, d14);
5930 ASSERT_EQUAL_FP64(1.0, d15);
5931 ASSERT_EQUAL_FP64(2.0, d16);
5932 ASSERT_EQUAL_FP64(-2.0, d17);
5933 ASSERT_EQUAL_FP64(-3.0, d18);
5934 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
5935 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
5936 ASSERT_EQUAL_FP64(0.0, d21);
5937 ASSERT_EQUAL_FP64(-0.0, d22);
5938 ASSERT_EQUAL_FP64(-1.0, d23);
armvixlf37fdc02014-02-05 13:22:16 +00005939
5940 TEARDOWN();
5941}
5942
5943
armvixlad96eda2013-06-14 11:42:37 +01005944TEST(frintn) {
5945 SETUP();
5946
5947 START();
5948 __ Fmov(s16, 1.0);
5949 __ Fmov(s17, 1.1);
5950 __ Fmov(s18, 1.5);
5951 __ Fmov(s19, 1.9);
5952 __ Fmov(s20, 2.5);
5953 __ Fmov(s21, -1.5);
5954 __ Fmov(s22, -2.5);
5955 __ Fmov(s23, kFP32PositiveInfinity);
5956 __ Fmov(s24, kFP32NegativeInfinity);
5957 __ Fmov(s25, 0.0);
5958 __ Fmov(s26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +01005959 __ Fmov(s27, -0.2);
armvixlad96eda2013-06-14 11:42:37 +01005960
5961 __ Frintn(s0, s16);
5962 __ Frintn(s1, s17);
5963 __ Frintn(s2, s18);
5964 __ Frintn(s3, s19);
5965 __ Frintn(s4, s20);
5966 __ Frintn(s5, s21);
5967 __ Frintn(s6, s22);
5968 __ Frintn(s7, s23);
5969 __ Frintn(s8, s24);
5970 __ Frintn(s9, s25);
5971 __ Frintn(s10, s26);
armvixl5799d6c2014-05-01 11:05:00 +01005972 __ Frintn(s11, s27);
armvixlad96eda2013-06-14 11:42:37 +01005973
5974 __ Fmov(d16, 1.0);
5975 __ Fmov(d17, 1.1);
5976 __ Fmov(d18, 1.5);
5977 __ Fmov(d19, 1.9);
5978 __ Fmov(d20, 2.5);
5979 __ Fmov(d21, -1.5);
5980 __ Fmov(d22, -2.5);
5981 __ Fmov(d23, kFP32PositiveInfinity);
5982 __ Fmov(d24, kFP32NegativeInfinity);
5983 __ Fmov(d25, 0.0);
5984 __ Fmov(d26, -0.0);
armvixl5799d6c2014-05-01 11:05:00 +01005985 __ Fmov(d27, -0.2);
armvixlad96eda2013-06-14 11:42:37 +01005986
armvixl5799d6c2014-05-01 11:05:00 +01005987 __ Frintn(d12, d16);
5988 __ Frintn(d13, d17);
5989 __ Frintn(d14, d18);
5990 __ Frintn(d15, d19);
5991 __ Frintn(d16, d20);
5992 __ Frintn(d17, d21);
5993 __ Frintn(d18, d22);
5994 __ Frintn(d19, d23);
5995 __ Frintn(d20, d24);
5996 __ Frintn(d21, d25);
5997 __ Frintn(d22, d26);
5998 __ Frintn(d23, d27);
armvixlad96eda2013-06-14 11:42:37 +01005999 END();
6000
6001 RUN();
6002
6003 ASSERT_EQUAL_FP32(1.0, s0);
6004 ASSERT_EQUAL_FP32(1.0, s1);
6005 ASSERT_EQUAL_FP32(2.0, s2);
6006 ASSERT_EQUAL_FP32(2.0, s3);
6007 ASSERT_EQUAL_FP32(2.0, s4);
6008 ASSERT_EQUAL_FP32(-2.0, s5);
6009 ASSERT_EQUAL_FP32(-2.0, s6);
6010 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
6011 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
6012 ASSERT_EQUAL_FP32(0.0, s9);
6013 ASSERT_EQUAL_FP32(-0.0, s10);
armvixl5799d6c2014-05-01 11:05:00 +01006014 ASSERT_EQUAL_FP32(-0.0, s11);
armvixlad96eda2013-06-14 11:42:37 +01006015 ASSERT_EQUAL_FP64(1.0, d12);
armvixl5799d6c2014-05-01 11:05:00 +01006016 ASSERT_EQUAL_FP64(1.0, d13);
armvixlad96eda2013-06-14 11:42:37 +01006017 ASSERT_EQUAL_FP64(2.0, d14);
6018 ASSERT_EQUAL_FP64(2.0, d15);
armvixl5799d6c2014-05-01 11:05:00 +01006019 ASSERT_EQUAL_FP64(2.0, d16);
armvixlad96eda2013-06-14 11:42:37 +01006020 ASSERT_EQUAL_FP64(-2.0, d17);
armvixl5799d6c2014-05-01 11:05:00 +01006021 ASSERT_EQUAL_FP64(-2.0, d18);
6022 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
6023 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
6024 ASSERT_EQUAL_FP64(0.0, d21);
6025 ASSERT_EQUAL_FP64(-0.0, d22);
6026 ASSERT_EQUAL_FP64(-0.0, d23);
armvixlad96eda2013-06-14 11:42:37 +01006027
6028 TEARDOWN();
6029}
6030
6031
6032TEST(frintz) {
6033 SETUP();
6034
6035 START();
6036 __ Fmov(s16, 1.0);
6037 __ Fmov(s17, 1.1);
6038 __ Fmov(s18, 1.5);
6039 __ Fmov(s19, 1.9);
6040 __ Fmov(s20, 2.5);
6041 __ Fmov(s21, -1.5);
6042 __ Fmov(s22, -2.5);
6043 __ Fmov(s23, kFP32PositiveInfinity);
6044 __ Fmov(s24, kFP32NegativeInfinity);
6045 __ Fmov(s25, 0.0);
6046 __ Fmov(s26, -0.0);
6047
6048 __ Frintz(s0, s16);
6049 __ Frintz(s1, s17);
6050 __ Frintz(s2, s18);
6051 __ Frintz(s3, s19);
6052 __ Frintz(s4, s20);
6053 __ Frintz(s5, s21);
6054 __ Frintz(s6, s22);
6055 __ Frintz(s7, s23);
6056 __ Frintz(s8, s24);
6057 __ Frintz(s9, s25);
6058 __ Frintz(s10, s26);
6059
6060 __ Fmov(d16, 1.0);
6061 __ Fmov(d17, 1.1);
6062 __ Fmov(d18, 1.5);
6063 __ Fmov(d19, 1.9);
6064 __ Fmov(d20, 2.5);
6065 __ Fmov(d21, -1.5);
6066 __ Fmov(d22, -2.5);
6067 __ Fmov(d23, kFP32PositiveInfinity);
6068 __ Fmov(d24, kFP32NegativeInfinity);
6069 __ Fmov(d25, 0.0);
6070 __ Fmov(d26, -0.0);
6071
6072 __ Frintz(d11, d16);
6073 __ Frintz(d12, d17);
6074 __ Frintz(d13, d18);
6075 __ Frintz(d14, d19);
6076 __ Frintz(d15, d20);
6077 __ Frintz(d16, d21);
6078 __ Frintz(d17, d22);
6079 __ Frintz(d18, d23);
6080 __ Frintz(d19, d24);
6081 __ Frintz(d20, d25);
6082 __ Frintz(d21, d26);
6083 END();
6084
6085 RUN();
6086
6087 ASSERT_EQUAL_FP32(1.0, s0);
6088 ASSERT_EQUAL_FP32(1.0, s1);
6089 ASSERT_EQUAL_FP32(1.0, s2);
6090 ASSERT_EQUAL_FP32(1.0, s3);
6091 ASSERT_EQUAL_FP32(2.0, s4);
6092 ASSERT_EQUAL_FP32(-1.0, s5);
6093 ASSERT_EQUAL_FP32(-2.0, s6);
6094 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
6095 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
6096 ASSERT_EQUAL_FP32(0.0, s9);
6097 ASSERT_EQUAL_FP32(-0.0, s10);
6098 ASSERT_EQUAL_FP64(1.0, d11);
6099 ASSERT_EQUAL_FP64(1.0, d12);
6100 ASSERT_EQUAL_FP64(1.0, d13);
6101 ASSERT_EQUAL_FP64(1.0, d14);
6102 ASSERT_EQUAL_FP64(2.0, d15);
6103 ASSERT_EQUAL_FP64(-1.0, d16);
6104 ASSERT_EQUAL_FP64(-2.0, d17);
6105 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
6106 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
6107 ASSERT_EQUAL_FP64(0.0, d20);
6108 ASSERT_EQUAL_FP64(-0.0, d21);
6109
6110 TEARDOWN();
6111}
6112
6113
armvixl578645f2013-08-15 17:21:42 +01006114TEST(fcvt_ds) {
armvixlad96eda2013-06-14 11:42:37 +01006115 SETUP();
6116
6117 START();
6118 __ Fmov(s16, 1.0);
6119 __ Fmov(s17, 1.1);
6120 __ Fmov(s18, 1.5);
6121 __ Fmov(s19, 1.9);
6122 __ Fmov(s20, 2.5);
6123 __ Fmov(s21, -1.5);
6124 __ Fmov(s22, -2.5);
6125 __ Fmov(s23, kFP32PositiveInfinity);
6126 __ Fmov(s24, kFP32NegativeInfinity);
6127 __ Fmov(s25, 0.0);
6128 __ Fmov(s26, -0.0);
armvixl578645f2013-08-15 17:21:42 +01006129 __ Fmov(s27, FLT_MAX);
6130 __ Fmov(s28, FLT_MIN);
6131 __ Fmov(s29, rawbits_to_float(0x7fc12345)); // Quiet NaN.
6132 __ Fmov(s30, rawbits_to_float(0x7f812345)); // Signalling NaN.
armvixlad96eda2013-06-14 11:42:37 +01006133
6134 __ Fcvt(d0, s16);
6135 __ Fcvt(d1, s17);
6136 __ Fcvt(d2, s18);
6137 __ Fcvt(d3, s19);
6138 __ Fcvt(d4, s20);
6139 __ Fcvt(d5, s21);
6140 __ Fcvt(d6, s22);
6141 __ Fcvt(d7, s23);
6142 __ Fcvt(d8, s24);
6143 __ Fcvt(d9, s25);
6144 __ Fcvt(d10, s26);
armvixl578645f2013-08-15 17:21:42 +01006145 __ Fcvt(d11, s27);
6146 __ Fcvt(d12, s28);
6147 __ Fcvt(d13, s29);
6148 __ Fcvt(d14, s30);
armvixlad96eda2013-06-14 11:42:37 +01006149 END();
6150
6151 RUN();
6152
6153 ASSERT_EQUAL_FP64(1.0f, d0);
6154 ASSERT_EQUAL_FP64(1.1f, d1);
6155 ASSERT_EQUAL_FP64(1.5f, d2);
6156 ASSERT_EQUAL_FP64(1.9f, d3);
6157 ASSERT_EQUAL_FP64(2.5f, d4);
6158 ASSERT_EQUAL_FP64(-1.5f, d5);
6159 ASSERT_EQUAL_FP64(-2.5f, d6);
6160 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
6161 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8);
6162 ASSERT_EQUAL_FP64(0.0f, d9);
6163 ASSERT_EQUAL_FP64(-0.0f, d10);
armvixl578645f2013-08-15 17:21:42 +01006164 ASSERT_EQUAL_FP64(FLT_MAX, d11);
6165 ASSERT_EQUAL_FP64(FLT_MIN, d12);
6166
6167 // Check that the NaN payload is preserved according to A64 conversion rules:
6168 // - The sign bit is preserved.
6169 // - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
6170 // - The remaining mantissa bits are copied until they run out.
6171 // - The low-order bits that haven't already been assigned are set to 0.
6172 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d13);
6173 ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d14);
armvixlad96eda2013-06-14 11:42:37 +01006174
6175 TEARDOWN();
6176}
6177
6178
armvixl578645f2013-08-15 17:21:42 +01006179TEST(fcvt_sd) {
armvixl5799d6c2014-05-01 11:05:00 +01006180 // Test simple conversions here. Complex behaviour (such as rounding
6181 // specifics) are tested in the simulator tests.
armvixl578645f2013-08-15 17:21:42 +01006182
armvixl5799d6c2014-05-01 11:05:00 +01006183 SETUP();
armvixl578645f2013-08-15 17:21:42 +01006184
armvixl5799d6c2014-05-01 11:05:00 +01006185 START();
6186 __ Fmov(d16, 1.0);
6187 __ Fmov(d17, 1.1);
6188 __ Fmov(d18, 1.5);
6189 __ Fmov(d19, 1.9);
6190 __ Fmov(d20, 2.5);
6191 __ Fmov(d21, -1.5);
6192 __ Fmov(d22, -2.5);
6193 __ Fmov(d23, kFP32PositiveInfinity);
6194 __ Fmov(d24, kFP32NegativeInfinity);
6195 __ Fmov(d25, 0.0);
6196 __ Fmov(d26, -0.0);
6197 __ Fmov(d27, FLT_MAX);
6198 __ Fmov(d28, FLT_MIN);
6199 __ Fmov(d29, rawbits_to_double(0x7ff82468a0000000)); // Quiet NaN.
6200 __ Fmov(d30, rawbits_to_double(0x7ff02468a0000000)); // Signalling NaN.
armvixl578645f2013-08-15 17:21:42 +01006201
armvixl5799d6c2014-05-01 11:05:00 +01006202 __ Fcvt(s0, d16);
6203 __ Fcvt(s1, d17);
6204 __ Fcvt(s2, d18);
6205 __ Fcvt(s3, d19);
6206 __ Fcvt(s4, d20);
6207 __ Fcvt(s5, d21);
6208 __ Fcvt(s6, d22);
6209 __ Fcvt(s7, d23);
6210 __ Fcvt(s8, d24);
6211 __ Fcvt(s9, d25);
6212 __ Fcvt(s10, d26);
6213 __ Fcvt(s11, d27);
6214 __ Fcvt(s12, d28);
6215 __ Fcvt(s13, d29);
6216 __ Fcvt(s14, d30);
6217 END();
armvixl578645f2013-08-15 17:21:42 +01006218
armvixl5799d6c2014-05-01 11:05:00 +01006219 RUN();
armvixl578645f2013-08-15 17:21:42 +01006220
armvixl5799d6c2014-05-01 11:05:00 +01006221 ASSERT_EQUAL_FP32(1.0f, s0);
6222 ASSERT_EQUAL_FP32(1.1f, s1);
6223 ASSERT_EQUAL_FP32(1.5f, s2);
6224 ASSERT_EQUAL_FP32(1.9f, s3);
6225 ASSERT_EQUAL_FP32(2.5f, s4);
6226 ASSERT_EQUAL_FP32(-1.5f, s5);
6227 ASSERT_EQUAL_FP32(-2.5f, s6);
6228 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
6229 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
6230 ASSERT_EQUAL_FP32(0.0f, s9);
6231 ASSERT_EQUAL_FP32(-0.0f, s10);
6232 ASSERT_EQUAL_FP32(FLT_MAX, s11);
6233 ASSERT_EQUAL_FP32(FLT_MIN, s12);
armvixl578645f2013-08-15 17:21:42 +01006234
armvixl5799d6c2014-05-01 11:05:00 +01006235 // Check that the NaN payload is preserved according to A64 conversion rules:
6236 // - The sign bit is preserved.
6237 // - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
6238 // - The remaining mantissa bits are copied until they run out.
6239 // - The low-order bits that haven't already been assigned are set to 0.
6240 ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s13);
6241 ASSERT_EQUAL_FP32(rawbits_to_float(0x7fc12345), s14);
armvixl578645f2013-08-15 17:21:42 +01006242
armvixl5799d6c2014-05-01 11:05:00 +01006243 TEARDOWN();
armvixl578645f2013-08-15 17:21:42 +01006244}
6245
6246
armvixlf37fdc02014-02-05 13:22:16 +00006247TEST(fcvtas) {
6248 SETUP();
6249
6250 START();
6251 __ Fmov(s0, 1.0);
6252 __ Fmov(s1, 1.1);
6253 __ Fmov(s2, 2.5);
6254 __ Fmov(s3, -2.5);
6255 __ Fmov(s4, kFP32PositiveInfinity);
6256 __ Fmov(s5, kFP32NegativeInfinity);
6257 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6258 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
6259 __ Fmov(d8, 1.0);
6260 __ Fmov(d9, 1.1);
6261 __ Fmov(d10, 2.5);
6262 __ Fmov(d11, -2.5);
6263 __ Fmov(d12, kFP64PositiveInfinity);
6264 __ Fmov(d13, kFP64NegativeInfinity);
6265 __ Fmov(d14, kWMaxInt - 1);
6266 __ Fmov(d15, kWMinInt + 1);
6267 __ Fmov(s17, 1.1);
6268 __ Fmov(s18, 2.5);
6269 __ Fmov(s19, -2.5);
6270 __ Fmov(s20, kFP32PositiveInfinity);
6271 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006272 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +00006273 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
6274 __ Fmov(d24, 1.1);
6275 __ Fmov(d25, 2.5);
6276 __ Fmov(d26, -2.5);
6277 __ Fmov(d27, kFP64PositiveInfinity);
6278 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006279 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +00006280 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
6281
6282 __ Fcvtas(w0, s0);
6283 __ Fcvtas(w1, s1);
6284 __ Fcvtas(w2, s2);
6285 __ Fcvtas(w3, s3);
6286 __ Fcvtas(w4, s4);
6287 __ Fcvtas(w5, s5);
6288 __ Fcvtas(w6, s6);
6289 __ Fcvtas(w7, s7);
6290 __ Fcvtas(w8, d8);
6291 __ Fcvtas(w9, d9);
6292 __ Fcvtas(w10, d10);
6293 __ Fcvtas(w11, d11);
6294 __ Fcvtas(w12, d12);
6295 __ Fcvtas(w13, d13);
6296 __ Fcvtas(w14, d14);
6297 __ Fcvtas(w15, d15);
6298 __ Fcvtas(x17, s17);
6299 __ Fcvtas(x18, s18);
6300 __ Fcvtas(x19, s19);
6301 __ Fcvtas(x20, s20);
6302 __ Fcvtas(x21, s21);
6303 __ Fcvtas(x22, s22);
6304 __ Fcvtas(x23, s23);
6305 __ Fcvtas(x24, d24);
6306 __ Fcvtas(x25, d25);
6307 __ Fcvtas(x26, d26);
6308 __ Fcvtas(x27, d27);
6309 __ Fcvtas(x28, d28);
6310 __ Fcvtas(x29, d29);
6311 __ Fcvtas(x30, d30);
6312 END();
6313
6314 RUN();
6315
6316 ASSERT_EQUAL_64(1, x0);
6317 ASSERT_EQUAL_64(1, x1);
6318 ASSERT_EQUAL_64(3, x2);
6319 ASSERT_EQUAL_64(0xfffffffd, x3);
6320 ASSERT_EQUAL_64(0x7fffffff, x4);
6321 ASSERT_EQUAL_64(0x80000000, x5);
6322 ASSERT_EQUAL_64(0x7fffff80, x6);
6323 ASSERT_EQUAL_64(0x80000080, x7);
6324 ASSERT_EQUAL_64(1, x8);
6325 ASSERT_EQUAL_64(1, x9);
6326 ASSERT_EQUAL_64(3, x10);
6327 ASSERT_EQUAL_64(0xfffffffd, x11);
6328 ASSERT_EQUAL_64(0x7fffffff, x12);
6329 ASSERT_EQUAL_64(0x80000000, x13);
6330 ASSERT_EQUAL_64(0x7ffffffe, x14);
6331 ASSERT_EQUAL_64(0x80000001, x15);
6332 ASSERT_EQUAL_64(1, x17);
6333 ASSERT_EQUAL_64(3, x18);
armvixlb0c8ae22014-03-21 14:03:59 +00006334 ASSERT_EQUAL_64(0xfffffffffffffffd, x19);
6335 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6336 ASSERT_EQUAL_64(0x8000000000000000, x21);
6337 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6338 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlf37fdc02014-02-05 13:22:16 +00006339 ASSERT_EQUAL_64(1, x24);
6340 ASSERT_EQUAL_64(3, x25);
armvixlb0c8ae22014-03-21 14:03:59 +00006341 ASSERT_EQUAL_64(0xfffffffffffffffd, x26);
6342 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6343 ASSERT_EQUAL_64(0x8000000000000000, x28);
6344 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6345 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlf37fdc02014-02-05 13:22:16 +00006346
6347 TEARDOWN();
6348}
6349
6350
6351TEST(fcvtau) {
6352 SETUP();
6353
6354 START();
6355 __ Fmov(s0, 1.0);
6356 __ Fmov(s1, 1.1);
6357 __ Fmov(s2, 2.5);
6358 __ Fmov(s3, -2.5);
6359 __ Fmov(s4, kFP32PositiveInfinity);
6360 __ Fmov(s5, kFP32NegativeInfinity);
6361 __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX.
6362 __ Fmov(d8, 1.0);
6363 __ Fmov(d9, 1.1);
6364 __ Fmov(d10, 2.5);
6365 __ Fmov(d11, -2.5);
6366 __ Fmov(d12, kFP64PositiveInfinity);
6367 __ Fmov(d13, kFP64NegativeInfinity);
6368 __ Fmov(d14, 0xfffffffe);
6369 __ Fmov(s16, 1.0);
6370 __ Fmov(s17, 1.1);
6371 __ Fmov(s18, 2.5);
6372 __ Fmov(s19, -2.5);
6373 __ Fmov(s20, kFP32PositiveInfinity);
6374 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006375 __ Fmov(s22, 0xffffff0000000000); // Largest float < UINT64_MAX.
armvixlf37fdc02014-02-05 13:22:16 +00006376 __ Fmov(d24, 1.1);
6377 __ Fmov(d25, 2.5);
6378 __ Fmov(d26, -2.5);
6379 __ Fmov(d27, kFP64PositiveInfinity);
6380 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006381 __ Fmov(d29, 0xfffffffffffff800); // Largest double < UINT64_MAX.
6382 __ Fmov(s30, 0x100000000);
armvixlf37fdc02014-02-05 13:22:16 +00006383
6384 __ Fcvtau(w0, s0);
6385 __ Fcvtau(w1, s1);
6386 __ Fcvtau(w2, s2);
6387 __ Fcvtau(w3, s3);
6388 __ Fcvtau(w4, s4);
6389 __ Fcvtau(w5, s5);
6390 __ Fcvtau(w6, s6);
6391 __ Fcvtau(w8, d8);
6392 __ Fcvtau(w9, d9);
6393 __ Fcvtau(w10, d10);
6394 __ Fcvtau(w11, d11);
6395 __ Fcvtau(w12, d12);
6396 __ Fcvtau(w13, d13);
6397 __ Fcvtau(w14, d14);
6398 __ Fcvtau(w15, d15);
6399 __ Fcvtau(x16, s16);
6400 __ Fcvtau(x17, s17);
6401 __ Fcvtau(x18, s18);
6402 __ Fcvtau(x19, s19);
6403 __ Fcvtau(x20, s20);
6404 __ Fcvtau(x21, s21);
6405 __ Fcvtau(x22, s22);
6406 __ Fcvtau(x24, d24);
6407 __ Fcvtau(x25, d25);
6408 __ Fcvtau(x26, d26);
6409 __ Fcvtau(x27, d27);
6410 __ Fcvtau(x28, d28);
6411 __ Fcvtau(x29, d29);
6412 __ Fcvtau(w30, s30);
6413 END();
6414
6415 RUN();
6416
6417 ASSERT_EQUAL_64(1, x0);
6418 ASSERT_EQUAL_64(1, x1);
6419 ASSERT_EQUAL_64(3, x2);
6420 ASSERT_EQUAL_64(0, x3);
6421 ASSERT_EQUAL_64(0xffffffff, x4);
6422 ASSERT_EQUAL_64(0, x5);
6423 ASSERT_EQUAL_64(0xffffff00, x6);
6424 ASSERT_EQUAL_64(1, x8);
6425 ASSERT_EQUAL_64(1, x9);
6426 ASSERT_EQUAL_64(3, x10);
6427 ASSERT_EQUAL_64(0, x11);
6428 ASSERT_EQUAL_64(0xffffffff, x12);
6429 ASSERT_EQUAL_64(0, x13);
6430 ASSERT_EQUAL_64(0xfffffffe, x14);
6431 ASSERT_EQUAL_64(1, x16);
6432 ASSERT_EQUAL_64(1, x17);
6433 ASSERT_EQUAL_64(3, x18);
6434 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +00006435 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlf37fdc02014-02-05 13:22:16 +00006436 ASSERT_EQUAL_64(0, x21);
armvixlb0c8ae22014-03-21 14:03:59 +00006437 ASSERT_EQUAL_64(0xffffff0000000000, x22);
armvixlf37fdc02014-02-05 13:22:16 +00006438 ASSERT_EQUAL_64(1, x24);
6439 ASSERT_EQUAL_64(3, x25);
6440 ASSERT_EQUAL_64(0, x26);
armvixlb0c8ae22014-03-21 14:03:59 +00006441 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
armvixlf37fdc02014-02-05 13:22:16 +00006442 ASSERT_EQUAL_64(0, x28);
armvixlb0c8ae22014-03-21 14:03:59 +00006443 ASSERT_EQUAL_64(0xfffffffffffff800, x29);
armvixlf37fdc02014-02-05 13:22:16 +00006444 ASSERT_EQUAL_64(0xffffffff, x30);
6445
6446 TEARDOWN();
6447}
6448
6449
armvixlad96eda2013-06-14 11:42:37 +01006450TEST(fcvtms) {
6451 SETUP();
6452
6453 START();
6454 __ Fmov(s0, 1.0);
6455 __ Fmov(s1, 1.1);
6456 __ Fmov(s2, 1.5);
6457 __ Fmov(s3, -1.5);
6458 __ Fmov(s4, kFP32PositiveInfinity);
6459 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006460 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6461 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006462 __ Fmov(d8, 1.0);
6463 __ Fmov(d9, 1.1);
6464 __ Fmov(d10, 1.5);
6465 __ Fmov(d11, -1.5);
6466 __ Fmov(d12, kFP64PositiveInfinity);
6467 __ Fmov(d13, kFP64NegativeInfinity);
6468 __ Fmov(d14, kWMaxInt - 1);
6469 __ Fmov(d15, kWMinInt + 1);
6470 __ Fmov(s17, 1.1);
6471 __ Fmov(s18, 1.5);
6472 __ Fmov(s19, -1.5);
6473 __ Fmov(s20, kFP32PositiveInfinity);
6474 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006475 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
6476 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006477 __ Fmov(d24, 1.1);
6478 __ Fmov(d25, 1.5);
6479 __ Fmov(d26, -1.5);
6480 __ Fmov(d27, kFP64PositiveInfinity);
6481 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006482 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
6483 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006484
6485 __ Fcvtms(w0, s0);
6486 __ Fcvtms(w1, s1);
6487 __ Fcvtms(w2, s2);
6488 __ Fcvtms(w3, s3);
6489 __ Fcvtms(w4, s4);
6490 __ Fcvtms(w5, s5);
6491 __ Fcvtms(w6, s6);
6492 __ Fcvtms(w7, s7);
6493 __ Fcvtms(w8, d8);
6494 __ Fcvtms(w9, d9);
6495 __ Fcvtms(w10, d10);
6496 __ Fcvtms(w11, d11);
6497 __ Fcvtms(w12, d12);
6498 __ Fcvtms(w13, d13);
6499 __ Fcvtms(w14, d14);
6500 __ Fcvtms(w15, d15);
6501 __ Fcvtms(x17, s17);
6502 __ Fcvtms(x18, s18);
6503 __ Fcvtms(x19, s19);
6504 __ Fcvtms(x20, s20);
6505 __ Fcvtms(x21, s21);
6506 __ Fcvtms(x22, s22);
6507 __ Fcvtms(x23, s23);
6508 __ Fcvtms(x24, d24);
6509 __ Fcvtms(x25, d25);
6510 __ Fcvtms(x26, d26);
6511 __ Fcvtms(x27, d27);
6512 __ Fcvtms(x28, d28);
6513 __ Fcvtms(x29, d29);
6514 __ Fcvtms(x30, d30);
6515 END();
6516
6517 RUN();
6518
6519 ASSERT_EQUAL_64(1, x0);
6520 ASSERT_EQUAL_64(1, x1);
6521 ASSERT_EQUAL_64(1, x2);
6522 ASSERT_EQUAL_64(0xfffffffe, x3);
6523 ASSERT_EQUAL_64(0x7fffffff, x4);
6524 ASSERT_EQUAL_64(0x80000000, x5);
6525 ASSERT_EQUAL_64(0x7fffff80, x6);
6526 ASSERT_EQUAL_64(0x80000080, x7);
6527 ASSERT_EQUAL_64(1, x8);
6528 ASSERT_EQUAL_64(1, x9);
6529 ASSERT_EQUAL_64(1, x10);
6530 ASSERT_EQUAL_64(0xfffffffe, x11);
6531 ASSERT_EQUAL_64(0x7fffffff, x12);
6532 ASSERT_EQUAL_64(0x80000000, x13);
6533 ASSERT_EQUAL_64(0x7ffffffe, x14);
6534 ASSERT_EQUAL_64(0x80000001, x15);
6535 ASSERT_EQUAL_64(1, x17);
6536 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +00006537 ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
6538 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6539 ASSERT_EQUAL_64(0x8000000000000000, x21);
6540 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6541 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +01006542 ASSERT_EQUAL_64(1, x24);
6543 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +00006544 ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
6545 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6546 ASSERT_EQUAL_64(0x8000000000000000, x28);
6547 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6548 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +01006549
6550 TEARDOWN();
6551}
6552
6553
6554TEST(fcvtmu) {
6555 SETUP();
6556
6557 START();
6558 __ Fmov(s0, 1.0);
6559 __ Fmov(s1, 1.1);
6560 __ Fmov(s2, 1.5);
6561 __ Fmov(s3, -1.5);
6562 __ Fmov(s4, kFP32PositiveInfinity);
6563 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006564 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6565 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006566 __ Fmov(d8, 1.0);
6567 __ Fmov(d9, 1.1);
6568 __ Fmov(d10, 1.5);
6569 __ Fmov(d11, -1.5);
6570 __ Fmov(d12, kFP64PositiveInfinity);
6571 __ Fmov(d13, kFP64NegativeInfinity);
6572 __ Fmov(d14, kWMaxInt - 1);
6573 __ Fmov(d15, kWMinInt + 1);
6574 __ Fmov(s17, 1.1);
6575 __ Fmov(s18, 1.5);
6576 __ Fmov(s19, -1.5);
6577 __ Fmov(s20, kFP32PositiveInfinity);
6578 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006579 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
6580 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006581 __ Fmov(d24, 1.1);
6582 __ Fmov(d25, 1.5);
6583 __ Fmov(d26, -1.5);
6584 __ Fmov(d27, kFP64PositiveInfinity);
6585 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006586 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
6587 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006588
6589 __ Fcvtmu(w0, s0);
6590 __ Fcvtmu(w1, s1);
6591 __ Fcvtmu(w2, s2);
6592 __ Fcvtmu(w3, s3);
6593 __ Fcvtmu(w4, s4);
6594 __ Fcvtmu(w5, s5);
6595 __ Fcvtmu(w6, s6);
6596 __ Fcvtmu(w7, s7);
6597 __ Fcvtmu(w8, d8);
6598 __ Fcvtmu(w9, d9);
6599 __ Fcvtmu(w10, d10);
6600 __ Fcvtmu(w11, d11);
6601 __ Fcvtmu(w12, d12);
6602 __ Fcvtmu(w13, d13);
6603 __ Fcvtmu(w14, d14);
6604 __ Fcvtmu(x17, s17);
6605 __ Fcvtmu(x18, s18);
6606 __ Fcvtmu(x19, s19);
6607 __ Fcvtmu(x20, s20);
6608 __ Fcvtmu(x21, s21);
6609 __ Fcvtmu(x22, s22);
6610 __ Fcvtmu(x23, s23);
6611 __ Fcvtmu(x24, d24);
6612 __ Fcvtmu(x25, d25);
6613 __ Fcvtmu(x26, d26);
6614 __ Fcvtmu(x27, d27);
6615 __ Fcvtmu(x28, d28);
6616 __ Fcvtmu(x29, d29);
6617 __ Fcvtmu(x30, d30);
6618 END();
6619
6620 RUN();
6621
6622 ASSERT_EQUAL_64(1, x0);
6623 ASSERT_EQUAL_64(1, x1);
6624 ASSERT_EQUAL_64(1, x2);
6625 ASSERT_EQUAL_64(0, x3);
6626 ASSERT_EQUAL_64(0xffffffff, x4);
6627 ASSERT_EQUAL_64(0, x5);
6628 ASSERT_EQUAL_64(0x7fffff80, x6);
6629 ASSERT_EQUAL_64(0, x7);
6630 ASSERT_EQUAL_64(1, x8);
6631 ASSERT_EQUAL_64(1, x9);
6632 ASSERT_EQUAL_64(1, x10);
6633 ASSERT_EQUAL_64(0, x11);
6634 ASSERT_EQUAL_64(0xffffffff, x12);
6635 ASSERT_EQUAL_64(0, x13);
6636 ASSERT_EQUAL_64(0x7ffffffe, x14);
6637 ASSERT_EQUAL_64(1, x17);
6638 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +00006639 ASSERT_EQUAL_64(0, x19);
6640 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
6641 ASSERT_EQUAL_64(0, x21);
6642 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6643 ASSERT_EQUAL_64(0, x23);
armvixlad96eda2013-06-14 11:42:37 +01006644 ASSERT_EQUAL_64(1, x24);
6645 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +00006646 ASSERT_EQUAL_64(0, x26);
6647 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
6648 ASSERT_EQUAL_64(0, x28);
6649 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6650 ASSERT_EQUAL_64(0, x30);
armvixlad96eda2013-06-14 11:42:37 +01006651
6652 TEARDOWN();
6653}
6654
6655
6656TEST(fcvtns) {
6657 SETUP();
6658
6659 START();
6660 __ Fmov(s0, 1.0);
6661 __ Fmov(s1, 1.1);
6662 __ Fmov(s2, 1.5);
6663 __ Fmov(s3, -1.5);
6664 __ Fmov(s4, kFP32PositiveInfinity);
6665 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006666 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6667 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006668 __ Fmov(d8, 1.0);
6669 __ Fmov(d9, 1.1);
6670 __ Fmov(d10, 1.5);
6671 __ Fmov(d11, -1.5);
6672 __ Fmov(d12, kFP64PositiveInfinity);
6673 __ Fmov(d13, kFP64NegativeInfinity);
6674 __ Fmov(d14, kWMaxInt - 1);
6675 __ Fmov(d15, kWMinInt + 1);
6676 __ Fmov(s17, 1.1);
6677 __ Fmov(s18, 1.5);
6678 __ Fmov(s19, -1.5);
6679 __ Fmov(s20, kFP32PositiveInfinity);
6680 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006681 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
6682 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006683 __ Fmov(d24, 1.1);
6684 __ Fmov(d25, 1.5);
6685 __ Fmov(d26, -1.5);
6686 __ Fmov(d27, kFP64PositiveInfinity);
6687 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006688 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
6689 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006690
6691 __ Fcvtns(w0, s0);
6692 __ Fcvtns(w1, s1);
6693 __ Fcvtns(w2, s2);
6694 __ Fcvtns(w3, s3);
6695 __ Fcvtns(w4, s4);
6696 __ Fcvtns(w5, s5);
6697 __ Fcvtns(w6, s6);
6698 __ Fcvtns(w7, s7);
6699 __ Fcvtns(w8, d8);
6700 __ Fcvtns(w9, d9);
6701 __ Fcvtns(w10, d10);
6702 __ Fcvtns(w11, d11);
6703 __ Fcvtns(w12, d12);
6704 __ Fcvtns(w13, d13);
6705 __ Fcvtns(w14, d14);
6706 __ Fcvtns(w15, d15);
6707 __ Fcvtns(x17, s17);
6708 __ Fcvtns(x18, s18);
6709 __ Fcvtns(x19, s19);
6710 __ Fcvtns(x20, s20);
6711 __ Fcvtns(x21, s21);
6712 __ Fcvtns(x22, s22);
6713 __ Fcvtns(x23, s23);
6714 __ Fcvtns(x24, d24);
6715 __ Fcvtns(x25, d25);
6716 __ Fcvtns(x26, d26);
6717 __ Fcvtns(x27, d27);
6718 __ Fcvtns(x28, d28);
6719 __ Fcvtns(x29, d29);
6720 __ Fcvtns(x30, d30);
6721 END();
6722
6723 RUN();
6724
6725 ASSERT_EQUAL_64(1, x0);
6726 ASSERT_EQUAL_64(1, x1);
6727 ASSERT_EQUAL_64(2, x2);
6728 ASSERT_EQUAL_64(0xfffffffe, x3);
6729 ASSERT_EQUAL_64(0x7fffffff, x4);
6730 ASSERT_EQUAL_64(0x80000000, x5);
6731 ASSERT_EQUAL_64(0x7fffff80, x6);
6732 ASSERT_EQUAL_64(0x80000080, x7);
6733 ASSERT_EQUAL_64(1, x8);
6734 ASSERT_EQUAL_64(1, x9);
6735 ASSERT_EQUAL_64(2, x10);
6736 ASSERT_EQUAL_64(0xfffffffe, x11);
6737 ASSERT_EQUAL_64(0x7fffffff, x12);
6738 ASSERT_EQUAL_64(0x80000000, x13);
6739 ASSERT_EQUAL_64(0x7ffffffe, x14);
6740 ASSERT_EQUAL_64(0x80000001, x15);
6741 ASSERT_EQUAL_64(1, x17);
6742 ASSERT_EQUAL_64(2, x18);
armvixlb0c8ae22014-03-21 14:03:59 +00006743 ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
6744 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6745 ASSERT_EQUAL_64(0x8000000000000000, x21);
6746 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6747 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +01006748 ASSERT_EQUAL_64(1, x24);
6749 ASSERT_EQUAL_64(2, x25);
armvixlb0c8ae22014-03-21 14:03:59 +00006750 ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
6751 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6752 ASSERT_EQUAL_64(0x8000000000000000, x28);
6753 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6754 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +01006755
6756 TEARDOWN();
6757}
6758
6759
6760TEST(fcvtnu) {
6761 SETUP();
6762
6763 START();
6764 __ Fmov(s0, 1.0);
6765 __ Fmov(s1, 1.1);
6766 __ Fmov(s2, 1.5);
6767 __ Fmov(s3, -1.5);
6768 __ Fmov(s4, kFP32PositiveInfinity);
6769 __ Fmov(s5, kFP32NegativeInfinity);
6770 __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX.
6771 __ Fmov(d8, 1.0);
6772 __ Fmov(d9, 1.1);
6773 __ Fmov(d10, 1.5);
6774 __ Fmov(d11, -1.5);
6775 __ Fmov(d12, kFP64PositiveInfinity);
6776 __ Fmov(d13, kFP64NegativeInfinity);
6777 __ Fmov(d14, 0xfffffffe);
6778 __ Fmov(s16, 1.0);
6779 __ Fmov(s17, 1.1);
6780 __ Fmov(s18, 1.5);
6781 __ Fmov(s19, -1.5);
6782 __ Fmov(s20, kFP32PositiveInfinity);
6783 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006784 __ Fmov(s22, 0xffffff0000000000); // Largest float < UINT64_MAX.
armvixlad96eda2013-06-14 11:42:37 +01006785 __ Fmov(d24, 1.1);
6786 __ Fmov(d25, 1.5);
6787 __ Fmov(d26, -1.5);
6788 __ Fmov(d27, kFP64PositiveInfinity);
6789 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006790 __ Fmov(d29, 0xfffffffffffff800); // Largest double < UINT64_MAX.
6791 __ Fmov(s30, 0x100000000);
armvixlad96eda2013-06-14 11:42:37 +01006792
6793 __ Fcvtnu(w0, s0);
6794 __ Fcvtnu(w1, s1);
6795 __ Fcvtnu(w2, s2);
6796 __ Fcvtnu(w3, s3);
6797 __ Fcvtnu(w4, s4);
6798 __ Fcvtnu(w5, s5);
6799 __ Fcvtnu(w6, s6);
6800 __ Fcvtnu(w8, d8);
6801 __ Fcvtnu(w9, d9);
6802 __ Fcvtnu(w10, d10);
6803 __ Fcvtnu(w11, d11);
6804 __ Fcvtnu(w12, d12);
6805 __ Fcvtnu(w13, d13);
6806 __ Fcvtnu(w14, d14);
6807 __ Fcvtnu(w15, d15);
6808 __ Fcvtnu(x16, s16);
6809 __ Fcvtnu(x17, s17);
6810 __ Fcvtnu(x18, s18);
6811 __ Fcvtnu(x19, s19);
6812 __ Fcvtnu(x20, s20);
6813 __ Fcvtnu(x21, s21);
6814 __ Fcvtnu(x22, s22);
6815 __ Fcvtnu(x24, d24);
6816 __ Fcvtnu(x25, d25);
6817 __ Fcvtnu(x26, d26);
6818 __ Fcvtnu(x27, d27);
6819 __ Fcvtnu(x28, d28);
6820 __ Fcvtnu(x29, d29);
6821 __ Fcvtnu(w30, s30);
6822 END();
6823
6824 RUN();
6825
6826 ASSERT_EQUAL_64(1, x0);
6827 ASSERT_EQUAL_64(1, x1);
6828 ASSERT_EQUAL_64(2, x2);
6829 ASSERT_EQUAL_64(0, x3);
6830 ASSERT_EQUAL_64(0xffffffff, x4);
6831 ASSERT_EQUAL_64(0, x5);
6832 ASSERT_EQUAL_64(0xffffff00, x6);
6833 ASSERT_EQUAL_64(1, x8);
6834 ASSERT_EQUAL_64(1, x9);
6835 ASSERT_EQUAL_64(2, x10);
6836 ASSERT_EQUAL_64(0, x11);
6837 ASSERT_EQUAL_64(0xffffffff, x12);
6838 ASSERT_EQUAL_64(0, x13);
6839 ASSERT_EQUAL_64(0xfffffffe, x14);
6840 ASSERT_EQUAL_64(1, x16);
6841 ASSERT_EQUAL_64(1, x17);
6842 ASSERT_EQUAL_64(2, x18);
6843 ASSERT_EQUAL_64(0, x19);
armvixlb0c8ae22014-03-21 14:03:59 +00006844 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
armvixlad96eda2013-06-14 11:42:37 +01006845 ASSERT_EQUAL_64(0, x21);
armvixlb0c8ae22014-03-21 14:03:59 +00006846 ASSERT_EQUAL_64(0xffffff0000000000, x22);
armvixlad96eda2013-06-14 11:42:37 +01006847 ASSERT_EQUAL_64(1, x24);
6848 ASSERT_EQUAL_64(2, x25);
6849 ASSERT_EQUAL_64(0, x26);
armvixlb0c8ae22014-03-21 14:03:59 +00006850 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
armvixlad96eda2013-06-14 11:42:37 +01006851 ASSERT_EQUAL_64(0, x28);
armvixlb0c8ae22014-03-21 14:03:59 +00006852 ASSERT_EQUAL_64(0xfffffffffffff800, x29);
armvixlad96eda2013-06-14 11:42:37 +01006853 ASSERT_EQUAL_64(0xffffffff, x30);
6854
6855 TEARDOWN();
6856}
6857
6858
6859TEST(fcvtzs) {
6860 SETUP();
6861
6862 START();
6863 __ Fmov(s0, 1.0);
6864 __ Fmov(s1, 1.1);
6865 __ Fmov(s2, 1.5);
6866 __ Fmov(s3, -1.5);
6867 __ Fmov(s4, kFP32PositiveInfinity);
6868 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006869 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6870 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006871 __ Fmov(d8, 1.0);
6872 __ Fmov(d9, 1.1);
6873 __ Fmov(d10, 1.5);
6874 __ Fmov(d11, -1.5);
6875 __ Fmov(d12, kFP64PositiveInfinity);
6876 __ Fmov(d13, kFP64NegativeInfinity);
6877 __ Fmov(d14, kWMaxInt - 1);
6878 __ Fmov(d15, kWMinInt + 1);
6879 __ Fmov(s17, 1.1);
6880 __ Fmov(s18, 1.5);
6881 __ Fmov(s19, -1.5);
6882 __ Fmov(s20, kFP32PositiveInfinity);
6883 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006884 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
6885 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006886 __ Fmov(d24, 1.1);
6887 __ Fmov(d25, 1.5);
6888 __ Fmov(d26, -1.5);
6889 __ Fmov(d27, kFP64PositiveInfinity);
6890 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006891 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
6892 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006893
6894 __ Fcvtzs(w0, s0);
6895 __ Fcvtzs(w1, s1);
6896 __ Fcvtzs(w2, s2);
6897 __ Fcvtzs(w3, s3);
6898 __ Fcvtzs(w4, s4);
6899 __ Fcvtzs(w5, s5);
6900 __ Fcvtzs(w6, s6);
6901 __ Fcvtzs(w7, s7);
6902 __ Fcvtzs(w8, d8);
6903 __ Fcvtzs(w9, d9);
6904 __ Fcvtzs(w10, d10);
6905 __ Fcvtzs(w11, d11);
6906 __ Fcvtzs(w12, d12);
6907 __ Fcvtzs(w13, d13);
6908 __ Fcvtzs(w14, d14);
6909 __ Fcvtzs(w15, d15);
6910 __ Fcvtzs(x17, s17);
6911 __ Fcvtzs(x18, s18);
6912 __ Fcvtzs(x19, s19);
6913 __ Fcvtzs(x20, s20);
6914 __ Fcvtzs(x21, s21);
6915 __ Fcvtzs(x22, s22);
6916 __ Fcvtzs(x23, s23);
6917 __ Fcvtzs(x24, d24);
6918 __ Fcvtzs(x25, d25);
6919 __ Fcvtzs(x26, d26);
6920 __ Fcvtzs(x27, d27);
6921 __ Fcvtzs(x28, d28);
6922 __ Fcvtzs(x29, d29);
6923 __ Fcvtzs(x30, d30);
6924 END();
6925
6926 RUN();
6927
6928 ASSERT_EQUAL_64(1, x0);
6929 ASSERT_EQUAL_64(1, x1);
6930 ASSERT_EQUAL_64(1, x2);
6931 ASSERT_EQUAL_64(0xffffffff, x3);
6932 ASSERT_EQUAL_64(0x7fffffff, x4);
6933 ASSERT_EQUAL_64(0x80000000, x5);
6934 ASSERT_EQUAL_64(0x7fffff80, x6);
6935 ASSERT_EQUAL_64(0x80000080, x7);
6936 ASSERT_EQUAL_64(1, x8);
6937 ASSERT_EQUAL_64(1, x9);
6938 ASSERT_EQUAL_64(1, x10);
6939 ASSERT_EQUAL_64(0xffffffff, x11);
6940 ASSERT_EQUAL_64(0x7fffffff, x12);
6941 ASSERT_EQUAL_64(0x80000000, x13);
6942 ASSERT_EQUAL_64(0x7ffffffe, x14);
6943 ASSERT_EQUAL_64(0x80000001, x15);
6944 ASSERT_EQUAL_64(1, x17);
6945 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +00006946 ASSERT_EQUAL_64(0xffffffffffffffff, x19);
6947 ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
6948 ASSERT_EQUAL_64(0x8000000000000000, x21);
6949 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
6950 ASSERT_EQUAL_64(0x8000008000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +01006951 ASSERT_EQUAL_64(1, x24);
6952 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +00006953 ASSERT_EQUAL_64(0xffffffffffffffff, x26);
6954 ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
6955 ASSERT_EQUAL_64(0x8000000000000000, x28);
6956 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
6957 ASSERT_EQUAL_64(0x8000000000000400, x30);
armvixlad96eda2013-06-14 11:42:37 +01006958
6959 TEARDOWN();
6960}
6961
6962TEST(fcvtzu) {
6963 SETUP();
6964
6965 START();
6966 __ Fmov(s0, 1.0);
6967 __ Fmov(s1, 1.1);
6968 __ Fmov(s2, 1.5);
6969 __ Fmov(s3, -1.5);
6970 __ Fmov(s4, kFP32PositiveInfinity);
6971 __ Fmov(s5, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006972 __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX.
6973 __ Fneg(s7, s6); // Smallest float > INT32_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006974 __ Fmov(d8, 1.0);
6975 __ Fmov(d9, 1.1);
6976 __ Fmov(d10, 1.5);
6977 __ Fmov(d11, -1.5);
6978 __ Fmov(d12, kFP64PositiveInfinity);
6979 __ Fmov(d13, kFP64NegativeInfinity);
6980 __ Fmov(d14, kWMaxInt - 1);
6981 __ Fmov(d15, kWMinInt + 1);
6982 __ Fmov(s17, 1.1);
6983 __ Fmov(s18, 1.5);
6984 __ Fmov(s19, -1.5);
6985 __ Fmov(s20, kFP32PositiveInfinity);
6986 __ Fmov(s21, kFP32NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006987 __ Fmov(s22, 0x7fffff8000000000); // Largest float < INT64_MAX.
6988 __ Fneg(s23, s22); // Smallest float > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006989 __ Fmov(d24, 1.1);
6990 __ Fmov(d25, 1.5);
6991 __ Fmov(d26, -1.5);
6992 __ Fmov(d27, kFP64PositiveInfinity);
6993 __ Fmov(d28, kFP64NegativeInfinity);
armvixlb0c8ae22014-03-21 14:03:59 +00006994 __ Fmov(d29, 0x7ffffffffffffc00); // Largest double < INT64_MAX.
6995 __ Fneg(d30, d29); // Smallest double > INT64_MIN.
armvixlad96eda2013-06-14 11:42:37 +01006996
6997 __ Fcvtzu(w0, s0);
6998 __ Fcvtzu(w1, s1);
6999 __ Fcvtzu(w2, s2);
7000 __ Fcvtzu(w3, s3);
7001 __ Fcvtzu(w4, s4);
7002 __ Fcvtzu(w5, s5);
7003 __ Fcvtzu(w6, s6);
7004 __ Fcvtzu(w7, s7);
7005 __ Fcvtzu(w8, d8);
7006 __ Fcvtzu(w9, d9);
7007 __ Fcvtzu(w10, d10);
7008 __ Fcvtzu(w11, d11);
7009 __ Fcvtzu(w12, d12);
7010 __ Fcvtzu(w13, d13);
7011 __ Fcvtzu(w14, d14);
7012 __ Fcvtzu(x17, s17);
7013 __ Fcvtzu(x18, s18);
7014 __ Fcvtzu(x19, s19);
7015 __ Fcvtzu(x20, s20);
7016 __ Fcvtzu(x21, s21);
7017 __ Fcvtzu(x22, s22);
7018 __ Fcvtzu(x23, s23);
7019 __ Fcvtzu(x24, d24);
7020 __ Fcvtzu(x25, d25);
7021 __ Fcvtzu(x26, d26);
7022 __ Fcvtzu(x27, d27);
7023 __ Fcvtzu(x28, d28);
7024 __ Fcvtzu(x29, d29);
7025 __ Fcvtzu(x30, d30);
7026 END();
7027
7028 RUN();
7029
7030 ASSERT_EQUAL_64(1, x0);
7031 ASSERT_EQUAL_64(1, x1);
7032 ASSERT_EQUAL_64(1, x2);
7033 ASSERT_EQUAL_64(0, x3);
7034 ASSERT_EQUAL_64(0xffffffff, x4);
7035 ASSERT_EQUAL_64(0, x5);
7036 ASSERT_EQUAL_64(0x7fffff80, x6);
7037 ASSERT_EQUAL_64(0, x7);
7038 ASSERT_EQUAL_64(1, x8);
7039 ASSERT_EQUAL_64(1, x9);
7040 ASSERT_EQUAL_64(1, x10);
7041 ASSERT_EQUAL_64(0, x11);
7042 ASSERT_EQUAL_64(0xffffffff, x12);
7043 ASSERT_EQUAL_64(0, x13);
7044 ASSERT_EQUAL_64(0x7ffffffe, x14);
7045 ASSERT_EQUAL_64(1, x17);
7046 ASSERT_EQUAL_64(1, x18);
armvixlb0c8ae22014-03-21 14:03:59 +00007047 ASSERT_EQUAL_64(0, x19);
7048 ASSERT_EQUAL_64(0xffffffffffffffff, x20);
7049 ASSERT_EQUAL_64(0, x21);
7050 ASSERT_EQUAL_64(0x7fffff8000000000, x22);
7051 ASSERT_EQUAL_64(0, x23);
armvixlad96eda2013-06-14 11:42:37 +01007052 ASSERT_EQUAL_64(1, x24);
7053 ASSERT_EQUAL_64(1, x25);
armvixlb0c8ae22014-03-21 14:03:59 +00007054 ASSERT_EQUAL_64(0, x26);
7055 ASSERT_EQUAL_64(0xffffffffffffffff, x27);
7056 ASSERT_EQUAL_64(0, x28);
7057 ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
7058 ASSERT_EQUAL_64(0, x30);
armvixlad96eda2013-06-14 11:42:37 +01007059
7060 TEARDOWN();
7061}
7062
7063
armvixl578645f2013-08-15 17:21:42 +01007064// Test that scvtf and ucvtf can convert the 64-bit input into the expected
7065// value. All possible values of 'fbits' are tested. The expected value is
7066// modified accordingly in each case.
7067//
7068// The expected value is specified as the bit encoding of the expected double
7069// produced by scvtf (expected_scvtf_bits) as well as ucvtf
7070// (expected_ucvtf_bits).
7071//
7072// Where the input value is representable by int32_t or uint32_t, conversions
7073// from W registers will also be tested.
7074static void TestUScvtfHelper(uint64_t in,
7075 uint64_t expected_scvtf_bits,
7076 uint64_t expected_ucvtf_bits) {
7077 uint64_t u64 = in;
7078 uint32_t u32 = u64 & 0xffffffff;
7079 int64_t s64 = static_cast<int64_t>(in);
7080 int32_t s32 = s64 & 0x7fffffff;
7081
7082 bool cvtf_s32 = (s64 == s32);
7083 bool cvtf_u32 = (u64 == u32);
7084
7085 double results_scvtf_x[65];
7086 double results_ucvtf_x[65];
7087 double results_scvtf_w[33];
7088 double results_ucvtf_w[33];
7089
armvixlad96eda2013-06-14 11:42:37 +01007090 SETUP();
armvixlad96eda2013-06-14 11:42:37 +01007091 START();
armvixlad96eda2013-06-14 11:42:37 +01007092
armvixlb0c8ae22014-03-21 14:03:59 +00007093 __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
7094 __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
7095 __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
7096 __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
armvixl578645f2013-08-15 17:21:42 +01007097
7098 __ Mov(x10, s64);
7099
7100 // Corrupt the top word, in case it is accidentally used during W-register
7101 // conversions.
7102 __ Mov(x11, 0x5555555555555555);
7103 __ Bfi(x11, x10, 0, kWRegSize);
7104
7105 // Test integer conversions.
7106 __ Scvtf(d0, x10);
7107 __ Ucvtf(d1, x10);
7108 __ Scvtf(d2, w11);
7109 __ Ucvtf(d3, w11);
7110 __ Str(d0, MemOperand(x0));
7111 __ Str(d1, MemOperand(x1));
7112 __ Str(d2, MemOperand(x2));
7113 __ Str(d3, MemOperand(x3));
7114
7115 // Test all possible values of fbits.
7116 for (int fbits = 1; fbits <= 32; fbits++) {
7117 __ Scvtf(d0, x10, fbits);
7118 __ Ucvtf(d1, x10, fbits);
7119 __ Scvtf(d2, w11, fbits);
7120 __ Ucvtf(d3, w11, fbits);
7121 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
7122 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
7123 __ Str(d2, MemOperand(x2, fbits * kDRegSizeInBytes));
7124 __ Str(d3, MemOperand(x3, fbits * kDRegSizeInBytes));
7125 }
7126
7127 // Conversions from W registers can only handle fbits values <= 32, so just
7128 // test conversions from X registers for 32 < fbits <= 64.
7129 for (int fbits = 33; fbits <= 64; fbits++) {
7130 __ Scvtf(d0, x10, fbits);
7131 __ Ucvtf(d1, x10, fbits);
7132 __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
7133 __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
7134 }
7135
7136 END();
armvixlad96eda2013-06-14 11:42:37 +01007137 RUN();
7138
armvixl578645f2013-08-15 17:21:42 +01007139 // Check the results.
7140 double expected_scvtf_base = rawbits_to_double(expected_scvtf_bits);
7141 double expected_ucvtf_base = rawbits_to_double(expected_ucvtf_bits);
7142
7143 for (int fbits = 0; fbits <= 32; fbits++) {
7144 double expected_scvtf = expected_scvtf_base / pow(2, fbits);
7145 double expected_ucvtf = expected_ucvtf_base / pow(2, fbits);
7146 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
7147 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
7148 if (cvtf_s32) ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_w[fbits]);
7149 if (cvtf_u32) ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_w[fbits]);
7150 }
7151 for (int fbits = 33; fbits <= 64; fbits++) {
7152 double expected_scvtf = expected_scvtf_base / pow(2, fbits);
7153 double expected_ucvtf = expected_ucvtf_base / pow(2, fbits);
7154 ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
7155 ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
7156 }
armvixlad96eda2013-06-14 11:42:37 +01007157
7158 TEARDOWN();
7159}
7160
7161
armvixl578645f2013-08-15 17:21:42 +01007162TEST(scvtf_ucvtf_double) {
7163 // Simple conversions of positive numbers which require no rounding; the
7164 // results should not depened on the rounding mode, and ucvtf and scvtf should
7165 // produce the same result.
7166 TestUScvtfHelper(0x0000000000000000, 0x0000000000000000, 0x0000000000000000);
7167 TestUScvtfHelper(0x0000000000000001, 0x3ff0000000000000, 0x3ff0000000000000);
7168 TestUScvtfHelper(0x0000000040000000, 0x41d0000000000000, 0x41d0000000000000);
7169 TestUScvtfHelper(0x0000000100000000, 0x41f0000000000000, 0x41f0000000000000);
7170 TestUScvtfHelper(0x4000000000000000, 0x43d0000000000000, 0x43d0000000000000);
7171 // Test mantissa extremities.
7172 TestUScvtfHelper(0x4000000000000400, 0x43d0000000000001, 0x43d0000000000001);
7173 // The largest int32_t that fits in a double.
7174 TestUScvtfHelper(0x000000007fffffff, 0x41dfffffffc00000, 0x41dfffffffc00000);
7175 // Values that would be negative if treated as an int32_t.
7176 TestUScvtfHelper(0x00000000ffffffff, 0x41efffffffe00000, 0x41efffffffe00000);
7177 TestUScvtfHelper(0x0000000080000000, 0x41e0000000000000, 0x41e0000000000000);
7178 TestUScvtfHelper(0x0000000080000001, 0x41e0000000200000, 0x41e0000000200000);
7179 // The largest int64_t that fits in a double.
7180 TestUScvtfHelper(0x7ffffffffffffc00, 0x43dfffffffffffff, 0x43dfffffffffffff);
7181 // Check for bit pattern reproduction.
7182 TestUScvtfHelper(0x0123456789abcde0, 0x43723456789abcde, 0x43723456789abcde);
7183 TestUScvtfHelper(0x0000000012345678, 0x41b2345678000000, 0x41b2345678000000);
7184
7185 // Simple conversions of negative int64_t values. These require no rounding,
7186 // and the results should not depend on the rounding mode.
7187 TestUScvtfHelper(0xffffffffc0000000, 0xc1d0000000000000, 0x43effffffff80000);
7188 TestUScvtfHelper(0xffffffff00000000, 0xc1f0000000000000, 0x43efffffffe00000);
7189 TestUScvtfHelper(0xc000000000000000, 0xc3d0000000000000, 0x43e8000000000000);
7190
7191 // Conversions which require rounding.
7192 TestUScvtfHelper(0x1000000000000000, 0x43b0000000000000, 0x43b0000000000000);
7193 TestUScvtfHelper(0x1000000000000001, 0x43b0000000000000, 0x43b0000000000000);
7194 TestUScvtfHelper(0x1000000000000080, 0x43b0000000000000, 0x43b0000000000000);
7195 TestUScvtfHelper(0x1000000000000081, 0x43b0000000000001, 0x43b0000000000001);
7196 TestUScvtfHelper(0x1000000000000100, 0x43b0000000000001, 0x43b0000000000001);
7197 TestUScvtfHelper(0x1000000000000101, 0x43b0000000000001, 0x43b0000000000001);
7198 TestUScvtfHelper(0x1000000000000180, 0x43b0000000000002, 0x43b0000000000002);
7199 TestUScvtfHelper(0x1000000000000181, 0x43b0000000000002, 0x43b0000000000002);
7200 TestUScvtfHelper(0x1000000000000200, 0x43b0000000000002, 0x43b0000000000002);
7201 TestUScvtfHelper(0x1000000000000201, 0x43b0000000000002, 0x43b0000000000002);
7202 TestUScvtfHelper(0x1000000000000280, 0x43b0000000000002, 0x43b0000000000002);
7203 TestUScvtfHelper(0x1000000000000281, 0x43b0000000000003, 0x43b0000000000003);
7204 TestUScvtfHelper(0x1000000000000300, 0x43b0000000000003, 0x43b0000000000003);
7205 // Check rounding of negative int64_t values (and large uint64_t values).
7206 TestUScvtfHelper(0x8000000000000000, 0xc3e0000000000000, 0x43e0000000000000);
7207 TestUScvtfHelper(0x8000000000000001, 0xc3e0000000000000, 0x43e0000000000000);
7208 TestUScvtfHelper(0x8000000000000200, 0xc3e0000000000000, 0x43e0000000000000);
7209 TestUScvtfHelper(0x8000000000000201, 0xc3dfffffffffffff, 0x43e0000000000000);
7210 TestUScvtfHelper(0x8000000000000400, 0xc3dfffffffffffff, 0x43e0000000000000);
7211 TestUScvtfHelper(0x8000000000000401, 0xc3dfffffffffffff, 0x43e0000000000001);
7212 TestUScvtfHelper(0x8000000000000600, 0xc3dffffffffffffe, 0x43e0000000000001);
7213 TestUScvtfHelper(0x8000000000000601, 0xc3dffffffffffffe, 0x43e0000000000001);
7214 TestUScvtfHelper(0x8000000000000800, 0xc3dffffffffffffe, 0x43e0000000000001);
7215 TestUScvtfHelper(0x8000000000000801, 0xc3dffffffffffffe, 0x43e0000000000001);
7216 TestUScvtfHelper(0x8000000000000a00, 0xc3dffffffffffffe, 0x43e0000000000001);
7217 TestUScvtfHelper(0x8000000000000a01, 0xc3dffffffffffffd, 0x43e0000000000001);
7218 TestUScvtfHelper(0x8000000000000c00, 0xc3dffffffffffffd, 0x43e0000000000002);
7219 // Round up to produce a result that's too big for the input to represent.
7220 TestUScvtfHelper(0x7ffffffffffffe00, 0x43e0000000000000, 0x43e0000000000000);
7221 TestUScvtfHelper(0x7fffffffffffffff, 0x43e0000000000000, 0x43e0000000000000);
7222 TestUScvtfHelper(0xfffffffffffffc00, 0xc090000000000000, 0x43f0000000000000);
7223 TestUScvtfHelper(0xffffffffffffffff, 0xbff0000000000000, 0x43f0000000000000);
7224}
7225
7226
7227// The same as TestUScvtfHelper, but convert to floats.
7228static void TestUScvtf32Helper(uint64_t in,
7229 uint32_t expected_scvtf_bits,
7230 uint32_t expected_ucvtf_bits) {
7231 uint64_t u64 = in;
7232 uint32_t u32 = u64 & 0xffffffff;
7233 int64_t s64 = static_cast<int64_t>(in);
7234 int32_t s32 = s64 & 0x7fffffff;
7235
7236 bool cvtf_s32 = (s64 == s32);
7237 bool cvtf_u32 = (u64 == u32);
7238
7239 float results_scvtf_x[65];
7240 float results_ucvtf_x[65];
7241 float results_scvtf_w[33];
7242 float results_ucvtf_w[33];
7243
armvixlad96eda2013-06-14 11:42:37 +01007244 SETUP();
armvixlad96eda2013-06-14 11:42:37 +01007245 START();
armvixlad96eda2013-06-14 11:42:37 +01007246
armvixlb0c8ae22014-03-21 14:03:59 +00007247 __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
7248 __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
7249 __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
7250 __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
armvixl578645f2013-08-15 17:21:42 +01007251
7252 __ Mov(x10, s64);
7253
7254 // Corrupt the top word, in case it is accidentally used during W-register
7255 // conversions.
7256 __ Mov(x11, 0x5555555555555555);
7257 __ Bfi(x11, x10, 0, kWRegSize);
7258
7259 // Test integer conversions.
7260 __ Scvtf(s0, x10);
7261 __ Ucvtf(s1, x10);
7262 __ Scvtf(s2, w11);
7263 __ Ucvtf(s3, w11);
7264 __ Str(s0, MemOperand(x0));
7265 __ Str(s1, MemOperand(x1));
7266 __ Str(s2, MemOperand(x2));
7267 __ Str(s3, MemOperand(x3));
7268
7269 // Test all possible values of fbits.
7270 for (int fbits = 1; fbits <= 32; fbits++) {
7271 __ Scvtf(s0, x10, fbits);
7272 __ Ucvtf(s1, x10, fbits);
7273 __ Scvtf(s2, w11, fbits);
7274 __ Ucvtf(s3, w11, fbits);
7275 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
7276 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
7277 __ Str(s2, MemOperand(x2, fbits * kSRegSizeInBytes));
7278 __ Str(s3, MemOperand(x3, fbits * kSRegSizeInBytes));
7279 }
7280
7281 // Conversions from W registers can only handle fbits values <= 32, so just
7282 // test conversions from X registers for 32 < fbits <= 64.
7283 for (int fbits = 33; fbits <= 64; fbits++) {
7284 __ Scvtf(s0, x10, fbits);
7285 __ Ucvtf(s1, x10, fbits);
7286 __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
7287 __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
7288 }
armvixlad96eda2013-06-14 11:42:37 +01007289
7290 END();
armvixlad96eda2013-06-14 11:42:37 +01007291 RUN();
7292
armvixl578645f2013-08-15 17:21:42 +01007293 // Check the results.
7294 float expected_scvtf_base = rawbits_to_float(expected_scvtf_bits);
7295 float expected_ucvtf_base = rawbits_to_float(expected_ucvtf_bits);
armvixlad96eda2013-06-14 11:42:37 +01007296
armvixl578645f2013-08-15 17:21:42 +01007297 for (int fbits = 0; fbits <= 32; fbits++) {
armvixlf37fdc02014-02-05 13:22:16 +00007298 float expected_scvtf = expected_scvtf_base / powf(2, fbits);
7299 float expected_ucvtf = expected_ucvtf_base / powf(2, fbits);
armvixl578645f2013-08-15 17:21:42 +01007300 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
7301 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
7302 if (cvtf_s32) ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_w[fbits]);
7303 if (cvtf_u32) ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_w[fbits]);
7304 break;
7305 }
7306 for (int fbits = 33; fbits <= 64; fbits++) {
7307 break;
armvixlf37fdc02014-02-05 13:22:16 +00007308 float expected_scvtf = expected_scvtf_base / powf(2, fbits);
7309 float expected_ucvtf = expected_ucvtf_base / powf(2, fbits);
armvixl578645f2013-08-15 17:21:42 +01007310 ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
7311 ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
7312 }
armvixlad96eda2013-06-14 11:42:37 +01007313
7314 TEARDOWN();
7315}
7316
7317
armvixl578645f2013-08-15 17:21:42 +01007318TEST(scvtf_ucvtf_float) {
7319 // Simple conversions of positive numbers which require no rounding; the
7320 // results should not depened on the rounding mode, and ucvtf and scvtf should
7321 // produce the same result.
7322 TestUScvtf32Helper(0x0000000000000000, 0x00000000, 0x00000000);
7323 TestUScvtf32Helper(0x0000000000000001, 0x3f800000, 0x3f800000);
7324 TestUScvtf32Helper(0x0000000040000000, 0x4e800000, 0x4e800000);
7325 TestUScvtf32Helper(0x0000000100000000, 0x4f800000, 0x4f800000);
7326 TestUScvtf32Helper(0x4000000000000000, 0x5e800000, 0x5e800000);
7327 // Test mantissa extremities.
7328 TestUScvtf32Helper(0x0000000000800001, 0x4b000001, 0x4b000001);
7329 TestUScvtf32Helper(0x4000008000000000, 0x5e800001, 0x5e800001);
7330 // The largest int32_t that fits in a float.
7331 TestUScvtf32Helper(0x000000007fffff80, 0x4effffff, 0x4effffff);
7332 // Values that would be negative if treated as an int32_t.
7333 TestUScvtf32Helper(0x00000000ffffff00, 0x4f7fffff, 0x4f7fffff);
7334 TestUScvtf32Helper(0x0000000080000000, 0x4f000000, 0x4f000000);
7335 TestUScvtf32Helper(0x0000000080000100, 0x4f000001, 0x4f000001);
7336 // The largest int64_t that fits in a float.
7337 TestUScvtf32Helper(0x7fffff8000000000, 0x5effffff, 0x5effffff);
7338 // Check for bit pattern reproduction.
7339 TestUScvtf32Helper(0x0000000000876543, 0x4b076543, 0x4b076543);
7340
7341 // Simple conversions of negative int64_t values. These require no rounding,
7342 // and the results should not depend on the rounding mode.
7343 TestUScvtf32Helper(0xfffffc0000000000, 0xd4800000, 0x5f7ffffc);
7344 TestUScvtf32Helper(0xc000000000000000, 0xde800000, 0x5f400000);
7345
7346 // Conversions which require rounding.
7347 TestUScvtf32Helper(0x0000800000000000, 0x57000000, 0x57000000);
7348 TestUScvtf32Helper(0x0000800000000001, 0x57000000, 0x57000000);
7349 TestUScvtf32Helper(0x0000800000800000, 0x57000000, 0x57000000);
7350 TestUScvtf32Helper(0x0000800000800001, 0x57000001, 0x57000001);
7351 TestUScvtf32Helper(0x0000800001000000, 0x57000001, 0x57000001);
7352 TestUScvtf32Helper(0x0000800001000001, 0x57000001, 0x57000001);
7353 TestUScvtf32Helper(0x0000800001800000, 0x57000002, 0x57000002);
7354 TestUScvtf32Helper(0x0000800001800001, 0x57000002, 0x57000002);
7355 TestUScvtf32Helper(0x0000800002000000, 0x57000002, 0x57000002);
7356 TestUScvtf32Helper(0x0000800002000001, 0x57000002, 0x57000002);
7357 TestUScvtf32Helper(0x0000800002800000, 0x57000002, 0x57000002);
7358 TestUScvtf32Helper(0x0000800002800001, 0x57000003, 0x57000003);
7359 TestUScvtf32Helper(0x0000800003000000, 0x57000003, 0x57000003);
7360 // Check rounding of negative int64_t values (and large uint64_t values).
7361 TestUScvtf32Helper(0x8000000000000000, 0xdf000000, 0x5f000000);
7362 TestUScvtf32Helper(0x8000000000000001, 0xdf000000, 0x5f000000);
7363 TestUScvtf32Helper(0x8000004000000000, 0xdf000000, 0x5f000000);
7364 TestUScvtf32Helper(0x8000004000000001, 0xdeffffff, 0x5f000000);
7365 TestUScvtf32Helper(0x8000008000000000, 0xdeffffff, 0x5f000000);
7366 TestUScvtf32Helper(0x8000008000000001, 0xdeffffff, 0x5f000001);
7367 TestUScvtf32Helper(0x800000c000000000, 0xdefffffe, 0x5f000001);
7368 TestUScvtf32Helper(0x800000c000000001, 0xdefffffe, 0x5f000001);
7369 TestUScvtf32Helper(0x8000010000000000, 0xdefffffe, 0x5f000001);
7370 TestUScvtf32Helper(0x8000010000000001, 0xdefffffe, 0x5f000001);
7371 TestUScvtf32Helper(0x8000014000000000, 0xdefffffe, 0x5f000001);
7372 TestUScvtf32Helper(0x8000014000000001, 0xdefffffd, 0x5f000001);
7373 TestUScvtf32Helper(0x8000018000000000, 0xdefffffd, 0x5f000002);
7374 // Round up to produce a result that's too big for the input to represent.
7375 TestUScvtf32Helper(0x000000007fffffc0, 0x4f000000, 0x4f000000);
7376 TestUScvtf32Helper(0x000000007fffffff, 0x4f000000, 0x4f000000);
7377 TestUScvtf32Helper(0x00000000ffffff80, 0x4f800000, 0x4f800000);
7378 TestUScvtf32Helper(0x00000000ffffffff, 0x4f800000, 0x4f800000);
7379 TestUScvtf32Helper(0x7fffffc000000000, 0x5f000000, 0x5f000000);
7380 TestUScvtf32Helper(0x7fffffffffffffff, 0x5f000000, 0x5f000000);
7381 TestUScvtf32Helper(0xffffff8000000000, 0xd3000000, 0x5f800000);
7382 TestUScvtf32Helper(0xffffffffffffffff, 0xbf800000, 0x5f800000);
7383}
7384
7385
armvixlad96eda2013-06-14 11:42:37 +01007386TEST(system_mrs) {
7387 SETUP();
7388
7389 START();
7390 __ Mov(w0, 0);
7391 __ Mov(w1, 1);
7392 __ Mov(w2, 0x80000000);
7393
7394 // Set the Z and C flags.
7395 __ Cmp(w0, w0);
7396 __ Mrs(x3, NZCV);
7397
7398 // Set the N flag.
7399 __ Cmp(w0, w1);
7400 __ Mrs(x4, NZCV);
7401
7402 // Set the Z, C and V flags.
armvixlf37fdc02014-02-05 13:22:16 +00007403 __ Adds(w0, w2, w2);
armvixlad96eda2013-06-14 11:42:37 +01007404 __ Mrs(x5, NZCV);
armvixl578645f2013-08-15 17:21:42 +01007405
7406 // Read the default FPCR.
7407 __ Mrs(x6, FPCR);
armvixlad96eda2013-06-14 11:42:37 +01007408 END();
7409
7410 RUN();
7411
armvixl578645f2013-08-15 17:21:42 +01007412 // NZCV
armvixlad96eda2013-06-14 11:42:37 +01007413 ASSERT_EQUAL_32(ZCFlag, w3);
7414 ASSERT_EQUAL_32(NFlag, w4);
7415 ASSERT_EQUAL_32(ZCVFlag, w5);
7416
armvixl578645f2013-08-15 17:21:42 +01007417 // FPCR
7418 // The default FPCR on Linux-based platforms is 0.
7419 ASSERT_EQUAL_32(0, w6);
7420
armvixlad96eda2013-06-14 11:42:37 +01007421 TEARDOWN();
7422}
7423
7424
7425TEST(system_msr) {
armvixl578645f2013-08-15 17:21:42 +01007426 // All FPCR fields that must be implemented: AHP, DN, FZ, RMode
7427 const uint64_t fpcr_core = 0x07c00000;
7428
7429 // All FPCR fields (including fields which may be read-as-zero):
7430 // Stride, Len
7431 // IDE, IXE, UFE, OFE, DZE, IOE
7432 const uint64_t fpcr_all = fpcr_core | 0x00379f00;
7433
armvixlad96eda2013-06-14 11:42:37 +01007434 SETUP();
7435
7436 START();
7437 __ Mov(w0, 0);
7438 __ Mov(w1, 0x7fffffff);
7439
7440 __ Mov(x7, 0);
7441
7442 __ Mov(x10, NVFlag);
7443 __ Cmp(w0, w0); // Set Z and C.
7444 __ Msr(NZCV, x10); // Set N and V.
7445 // The Msr should have overwritten every flag set by the Cmp.
7446 __ Cinc(x7, x7, mi); // N
7447 __ Cinc(x7, x7, ne); // !Z
7448 __ Cinc(x7, x7, lo); // !C
7449 __ Cinc(x7, x7, vs); // V
7450
7451 __ Mov(x10, ZCFlag);
7452 __ Cmn(w1, w1); // Set N and V.
7453 __ Msr(NZCV, x10); // Set Z and C.
7454 // The Msr should have overwritten every flag set by the Cmn.
7455 __ Cinc(x7, x7, pl); // !N
7456 __ Cinc(x7, x7, eq); // Z
7457 __ Cinc(x7, x7, hs); // C
7458 __ Cinc(x7, x7, vc); // !V
7459
armvixl578645f2013-08-15 17:21:42 +01007460 // All core FPCR fields must be writable.
7461 __ Mov(x8, fpcr_core);
7462 __ Msr(FPCR, x8);
7463 __ Mrs(x8, FPCR);
7464
7465 // All FPCR fields, including optional ones. This part of the test doesn't
7466 // achieve much other than ensuring that supported fields can be cleared by
7467 // the next test.
7468 __ Mov(x9, fpcr_all);
7469 __ Msr(FPCR, x9);
7470 __ Mrs(x9, FPCR);
7471 __ And(x9, x9, fpcr_core);
7472
7473 // The undefined bits must ignore writes.
7474 // It's conceivable that a future version of the architecture could use these
7475 // fields (making this test fail), but in the meantime this is a useful test
7476 // for the simulator.
7477 __ Mov(x10, ~fpcr_all);
7478 __ Msr(FPCR, x10);
7479 __ Mrs(x10, FPCR);
7480
armvixlad96eda2013-06-14 11:42:37 +01007481 END();
7482
7483 RUN();
7484
7485 // We should have incremented x7 (from 0) exactly 8 times.
7486 ASSERT_EQUAL_64(8, x7);
7487
armvixl578645f2013-08-15 17:21:42 +01007488 ASSERT_EQUAL_64(fpcr_core, x8);
7489 ASSERT_EQUAL_64(fpcr_core, x9);
7490 ASSERT_EQUAL_64(0, x10);
7491
armvixlad96eda2013-06-14 11:42:37 +01007492 TEARDOWN();
7493}
7494
7495
7496TEST(system_nop) {
7497 SETUP();
7498 RegisterDump before;
7499
7500 START();
7501 before.Dump(&masm);
7502 __ Nop();
7503 END();
7504
7505 RUN();
7506
7507 ASSERT_EQUAL_REGISTERS(before);
7508 ASSERT_EQUAL_NZCV(before.flags_nzcv());
7509
7510 TEARDOWN();
7511}
7512
7513
7514TEST(zero_dest) {
7515 SETUP();
7516 RegisterDump before;
7517
7518 START();
7519 // Preserve the stack pointer, in case we clobber it.
7520 __ Mov(x30, sp);
7521 // Initialize the other registers used in this test.
armvixlb0c8ae22014-03-21 14:03:59 +00007522 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +01007523 __ Mov(x0, 0);
7524 __ Mov(x1, literal_base);
7525 for (unsigned i = 2; i < x30.code(); i++) {
7526 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
7527 }
7528 before.Dump(&masm);
7529
7530 // All of these instructions should be NOPs in these forms, but have
7531 // alternate forms which can write into the stack pointer.
7532 __ add(xzr, x0, x1);
7533 __ add(xzr, x1, xzr);
7534 __ add(xzr, xzr, x1);
7535
7536 __ and_(xzr, x0, x2);
7537 __ and_(xzr, x2, xzr);
7538 __ and_(xzr, xzr, x2);
7539
7540 __ bic(xzr, x0, x3);
7541 __ bic(xzr, x3, xzr);
7542 __ bic(xzr, xzr, x3);
7543
7544 __ eon(xzr, x0, x4);
7545 __ eon(xzr, x4, xzr);
7546 __ eon(xzr, xzr, x4);
7547
7548 __ eor(xzr, x0, x5);
7549 __ eor(xzr, x5, xzr);
7550 __ eor(xzr, xzr, x5);
7551
7552 __ orr(xzr, x0, x6);
7553 __ orr(xzr, x6, xzr);
7554 __ orr(xzr, xzr, x6);
7555
7556 __ sub(xzr, x0, x7);
7557 __ sub(xzr, x7, xzr);
7558 __ sub(xzr, xzr, x7);
7559
7560 // Swap the saved stack pointer with the real one. If sp was written
7561 // during the test, it will show up in x30. This is done because the test
7562 // framework assumes that sp will be valid at the end of the test.
7563 __ Mov(x29, x30);
7564 __ Mov(x30, sp);
7565 __ Mov(sp, x29);
7566 // We used x29 as a scratch register, so reset it to make sure it doesn't
7567 // trigger a test failure.
7568 __ Add(x29, x28, x1);
7569 END();
7570
7571 RUN();
7572
7573 ASSERT_EQUAL_REGISTERS(before);
7574 ASSERT_EQUAL_NZCV(before.flags_nzcv());
7575
7576 TEARDOWN();
7577}
7578
7579
7580TEST(zero_dest_setflags) {
7581 SETUP();
7582 RegisterDump before;
7583
7584 START();
7585 // Preserve the stack pointer, in case we clobber it.
7586 __ Mov(x30, sp);
7587 // Initialize the other registers used in this test.
armvixlb0c8ae22014-03-21 14:03:59 +00007588 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +01007589 __ Mov(x0, 0);
7590 __ Mov(x1, literal_base);
7591 for (int i = 2; i < 30; i++) {
7592 __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1);
7593 }
7594 before.Dump(&masm);
7595
7596 // All of these instructions should only write to the flags in these forms,
7597 // but have alternate forms which can write into the stack pointer.
armvixlf37fdc02014-02-05 13:22:16 +00007598 __ adds(xzr, x0, Operand(x1, UXTX));
7599 __ adds(xzr, x1, Operand(xzr, UXTX));
7600 __ adds(xzr, x1, 1234);
7601 __ adds(xzr, x0, x1);
7602 __ adds(xzr, x1, xzr);
7603 __ adds(xzr, xzr, x1);
armvixlad96eda2013-06-14 11:42:37 +01007604
armvixlf37fdc02014-02-05 13:22:16 +00007605 __ ands(xzr, x2, ~0xf);
7606 __ ands(xzr, xzr, ~0xf);
7607 __ ands(xzr, x0, x2);
7608 __ ands(xzr, x2, xzr);
7609 __ ands(xzr, xzr, x2);
armvixlad96eda2013-06-14 11:42:37 +01007610
armvixlf37fdc02014-02-05 13:22:16 +00007611 __ bics(xzr, x3, ~0xf);
7612 __ bics(xzr, xzr, ~0xf);
7613 __ bics(xzr, x0, x3);
7614 __ bics(xzr, x3, xzr);
7615 __ bics(xzr, xzr, x3);
armvixlad96eda2013-06-14 11:42:37 +01007616
armvixlf37fdc02014-02-05 13:22:16 +00007617 __ subs(xzr, x0, Operand(x3, UXTX));
7618 __ subs(xzr, x3, Operand(xzr, UXTX));
7619 __ subs(xzr, x3, 1234);
7620 __ subs(xzr, x0, x3);
7621 __ subs(xzr, x3, xzr);
7622 __ subs(xzr, xzr, x3);
armvixlad96eda2013-06-14 11:42:37 +01007623
7624 // Swap the saved stack pointer with the real one. If sp was written
7625 // during the test, it will show up in x30. This is done because the test
7626 // framework assumes that sp will be valid at the end of the test.
7627 __ Mov(x29, x30);
7628 __ Mov(x30, sp);
7629 __ Mov(sp, x29);
7630 // We used x29 as a scratch register, so reset it to make sure it doesn't
7631 // trigger a test failure.
7632 __ Add(x29, x28, x1);
7633 END();
7634
7635 RUN();
7636
7637 ASSERT_EQUAL_REGISTERS(before);
7638
7639 TEARDOWN();
7640}
7641
7642
7643TEST(register_bit) {
7644 // No code generation takes place in this test, so no need to setup and
7645 // teardown.
7646
7647 // Simple tests.
armvixlb0c8ae22014-03-21 14:03:59 +00007648 assert(x0.Bit() == (UINT64_C(1) << 0));
7649 assert(x1.Bit() == (UINT64_C(1) << 1));
7650 assert(x10.Bit() == (UINT64_C(1) << 10));
armvixlad96eda2013-06-14 11:42:37 +01007651
7652 // AAPCS64 definitions.
armvixlb0c8ae22014-03-21 14:03:59 +00007653 assert(lr.Bit() == (UINT64_C(1) << kLinkRegCode));
armvixlad96eda2013-06-14 11:42:37 +01007654
7655 // Fixed (hardware) definitions.
armvixlb0c8ae22014-03-21 14:03:59 +00007656 assert(xzr.Bit() == (UINT64_C(1) << kZeroRegCode));
armvixlad96eda2013-06-14 11:42:37 +01007657
7658 // Internal ABI definitions.
armvixlb0c8ae22014-03-21 14:03:59 +00007659 assert(sp.Bit() == (UINT64_C(1) << kSPRegInternalCode));
armvixlad96eda2013-06-14 11:42:37 +01007660 assert(sp.Bit() != xzr.Bit());
7661
7662 // xn.Bit() == wn.Bit() at all times, for the same n.
7663 assert(x0.Bit() == w0.Bit());
7664 assert(x1.Bit() == w1.Bit());
7665 assert(x10.Bit() == w10.Bit());
7666 assert(xzr.Bit() == wzr.Bit());
7667 assert(sp.Bit() == wsp.Bit());
7668}
7669
7670
7671TEST(stack_pointer_override) {
7672 // This test generates some stack maintenance code, but the test only checks
7673 // the reported state.
7674 SETUP();
7675 START();
7676
7677 // The default stack pointer in VIXL is sp.
7678 assert(sp.Is(__ StackPointer()));
7679 __ SetStackPointer(x0);
7680 assert(x0.Is(__ StackPointer()));
7681 __ SetStackPointer(x28);
7682 assert(x28.Is(__ StackPointer()));
7683 __ SetStackPointer(sp);
7684 assert(sp.Is(__ StackPointer()));
7685
7686 END();
7687 RUN();
7688 TEARDOWN();
7689}
7690
7691
7692TEST(peek_poke_simple) {
7693 SETUP();
7694 START();
7695
7696 static const RegList x0_to_x3 = x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit();
7697 static const RegList x10_to_x13 = x10.Bit() | x11.Bit() |
7698 x12.Bit() | x13.Bit();
7699
7700 // The literal base is chosen to have two useful properties:
7701 // * When multiplied by small values (such as a register index), this value
7702 // is clearly readable in the result.
7703 // * The value is not formed from repeating fixed-size smaller values, so it
7704 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +00007705 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +01007706
7707 // Initialize the registers.
7708 __ Mov(x0, literal_base);
7709 __ Add(x1, x0, x0);
7710 __ Add(x2, x1, x0);
7711 __ Add(x3, x2, x0);
7712
7713 __ Claim(32);
7714
7715 // Simple exchange.
7716 // After this test:
7717 // x0-x3 should be unchanged.
7718 // w10-w13 should contain the lower words of x0-x3.
7719 __ Poke(x0, 0);
7720 __ Poke(x1, 8);
7721 __ Poke(x2, 16);
7722 __ Poke(x3, 24);
7723 Clobber(&masm, x0_to_x3);
7724 __ Peek(x0, 0);
7725 __ Peek(x1, 8);
7726 __ Peek(x2, 16);
7727 __ Peek(x3, 24);
7728
7729 __ Poke(w0, 0);
7730 __ Poke(w1, 4);
7731 __ Poke(w2, 8);
7732 __ Poke(w3, 12);
7733 Clobber(&masm, x10_to_x13);
7734 __ Peek(w10, 0);
7735 __ Peek(w11, 4);
7736 __ Peek(w12, 8);
7737 __ Peek(w13, 12);
7738
7739 __ Drop(32);
7740
7741 END();
7742 RUN();
7743
7744 ASSERT_EQUAL_64(literal_base * 1, x0);
7745 ASSERT_EQUAL_64(literal_base * 2, x1);
7746 ASSERT_EQUAL_64(literal_base * 3, x2);
7747 ASSERT_EQUAL_64(literal_base * 4, x3);
7748
7749 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
7750 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
7751 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
7752 ASSERT_EQUAL_64((literal_base * 4) & 0xffffffff, x13);
7753
7754 TEARDOWN();
7755}
7756
7757
7758TEST(peek_poke_unaligned) {
7759 SETUP();
7760 START();
7761
7762 // The literal base is chosen to have two useful properties:
7763 // * When multiplied by small values (such as a register index), this value
7764 // is clearly readable in the result.
7765 // * The value is not formed from repeating fixed-size smaller values, so it
7766 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +00007767 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +01007768
7769 // Initialize the registers.
7770 __ Mov(x0, literal_base);
7771 __ Add(x1, x0, x0);
7772 __ Add(x2, x1, x0);
7773 __ Add(x3, x2, x0);
7774 __ Add(x4, x3, x0);
7775 __ Add(x5, x4, x0);
7776 __ Add(x6, x5, x0);
7777
7778 __ Claim(32);
7779
7780 // Unaligned exchanges.
7781 // After this test:
7782 // x0-x6 should be unchanged.
7783 // w10-w12 should contain the lower words of x0-x2.
7784 __ Poke(x0, 1);
7785 Clobber(&masm, x0.Bit());
7786 __ Peek(x0, 1);
7787 __ Poke(x1, 2);
7788 Clobber(&masm, x1.Bit());
7789 __ Peek(x1, 2);
7790 __ Poke(x2, 3);
7791 Clobber(&masm, x2.Bit());
7792 __ Peek(x2, 3);
7793 __ Poke(x3, 4);
7794 Clobber(&masm, x3.Bit());
7795 __ Peek(x3, 4);
7796 __ Poke(x4, 5);
7797 Clobber(&masm, x4.Bit());
7798 __ Peek(x4, 5);
7799 __ Poke(x5, 6);
7800 Clobber(&masm, x5.Bit());
7801 __ Peek(x5, 6);
7802 __ Poke(x6, 7);
7803 Clobber(&masm, x6.Bit());
7804 __ Peek(x6, 7);
7805
7806 __ Poke(w0, 1);
7807 Clobber(&masm, w10.Bit());
7808 __ Peek(w10, 1);
7809 __ Poke(w1, 2);
7810 Clobber(&masm, w11.Bit());
7811 __ Peek(w11, 2);
7812 __ Poke(w2, 3);
7813 Clobber(&masm, w12.Bit());
7814 __ Peek(w12, 3);
7815
7816 __ Drop(32);
7817
7818 END();
7819 RUN();
7820
7821 ASSERT_EQUAL_64(literal_base * 1, x0);
7822 ASSERT_EQUAL_64(literal_base * 2, x1);
7823 ASSERT_EQUAL_64(literal_base * 3, x2);
7824 ASSERT_EQUAL_64(literal_base * 4, x3);
7825 ASSERT_EQUAL_64(literal_base * 5, x4);
7826 ASSERT_EQUAL_64(literal_base * 6, x5);
7827 ASSERT_EQUAL_64(literal_base * 7, x6);
7828
7829 ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
7830 ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
7831 ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
7832
7833 TEARDOWN();
7834}
7835
7836
7837TEST(peek_poke_endianness) {
7838 SETUP();
7839 START();
7840
7841 // The literal base is chosen to have two useful properties:
7842 // * When multiplied by small values (such as a register index), this value
7843 // is clearly readable in the result.
7844 // * The value is not formed from repeating fixed-size smaller values, so it
7845 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +00007846 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +01007847
7848 // Initialize the registers.
7849 __ Mov(x0, literal_base);
7850 __ Add(x1, x0, x0);
7851
7852 __ Claim(32);
7853
7854 // Endianness tests.
7855 // After this section:
7856 // x4 should match x0[31:0]:x0[63:32]
7857 // w5 should match w1[15:0]:w1[31:16]
7858 __ Poke(x0, 0);
7859 __ Poke(x0, 8);
7860 __ Peek(x4, 4);
7861
7862 __ Poke(w1, 0);
7863 __ Poke(w1, 4);
7864 __ Peek(w5, 2);
7865
7866 __ Drop(32);
7867
7868 END();
7869 RUN();
7870
7871 uint64_t x0_expected = literal_base * 1;
7872 uint64_t x1_expected = literal_base * 2;
7873 uint64_t x4_expected = (x0_expected << 32) | (x0_expected >> 32);
7874 uint64_t x5_expected = ((x1_expected << 16) & 0xffff0000) |
7875 ((x1_expected >> 16) & 0x0000ffff);
7876
7877 ASSERT_EQUAL_64(x0_expected, x0);
7878 ASSERT_EQUAL_64(x1_expected, x1);
7879 ASSERT_EQUAL_64(x4_expected, x4);
7880 ASSERT_EQUAL_64(x5_expected, x5);
7881
7882 TEARDOWN();
7883}
7884
7885
7886TEST(peek_poke_mixed) {
7887 SETUP();
7888 START();
7889
7890 // The literal base is chosen to have two useful properties:
7891 // * When multiplied by small values (such as a register index), this value
7892 // is clearly readable in the result.
7893 // * The value is not formed from repeating fixed-size smaller values, so it
7894 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +00007895 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +01007896
7897 // Initialize the registers.
7898 __ Mov(x0, literal_base);
7899 __ Add(x1, x0, x0);
7900 __ Add(x2, x1, x0);
7901 __ Add(x3, x2, x0);
7902
7903 __ Claim(32);
7904
7905 // Mix with other stack operations.
7906 // After this section:
7907 // x0-x3 should be unchanged.
7908 // x6 should match x1[31:0]:x0[63:32]
7909 // w7 should match x1[15:0]:x0[63:48]
7910 __ Poke(x1, 8);
7911 __ Poke(x0, 0);
7912 {
armvixlb0c8ae22014-03-21 14:03:59 +00007913 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +01007914 __ Mov(x4, __ StackPointer());
7915 __ SetStackPointer(x4);
7916
7917 __ Poke(wzr, 0); // Clobber the space we're about to drop.
7918 __ Drop(4);
7919 __ Peek(x6, 0);
7920 __ Claim(8);
7921 __ Peek(w7, 10);
7922 __ Poke(x3, 28);
7923 __ Poke(xzr, 0); // Clobber the space we're about to drop.
7924 __ Drop(8);
7925 __ Poke(x2, 12);
7926 __ Push(w0);
7927
7928 __ Mov(sp, __ StackPointer());
7929 __ SetStackPointer(sp);
7930 }
7931
7932 __ Pop(x0, x1, x2, x3);
7933
7934 END();
7935 RUN();
7936
7937 uint64_t x0_expected = literal_base * 1;
7938 uint64_t x1_expected = literal_base * 2;
7939 uint64_t x2_expected = literal_base * 3;
7940 uint64_t x3_expected = literal_base * 4;
7941 uint64_t x6_expected = (x1_expected << 32) | (x0_expected >> 32);
7942 uint64_t x7_expected = ((x1_expected << 16) & 0xffff0000) |
7943 ((x0_expected >> 48) & 0x0000ffff);
7944
7945 ASSERT_EQUAL_64(x0_expected, x0);
7946 ASSERT_EQUAL_64(x1_expected, x1);
7947 ASSERT_EQUAL_64(x2_expected, x2);
7948 ASSERT_EQUAL_64(x3_expected, x3);
7949 ASSERT_EQUAL_64(x6_expected, x6);
7950 ASSERT_EQUAL_64(x7_expected, x7);
7951
7952 TEARDOWN();
7953}
7954
7955
7956// This enum is used only as an argument to the push-pop test helpers.
7957enum PushPopMethod {
7958 // Push or Pop using the Push and Pop methods, with blocks of up to four
7959 // registers. (Smaller blocks will be used if necessary.)
7960 PushPopByFour,
7961
7962 // Use Push<Size>RegList and Pop<Size>RegList to transfer the registers.
7963 PushPopRegList
7964};
7965
7966
7967// The maximum number of registers that can be used by the PushPopXReg* tests,
7968// where a reg_count field is provided.
7969static int const kPushPopXRegMaxRegCount = -1;
7970
7971// Test a simple push-pop pattern:
7972// * Claim <claim> bytes to set the stack alignment.
7973// * Push <reg_count> registers with size <reg_size>.
7974// * Clobber the register contents.
7975// * Pop <reg_count> registers to restore the original contents.
7976// * Drop <claim> bytes to restore the original stack pointer.
7977//
7978// Different push and pop methods can be specified independently to test for
7979// proper word-endian behaviour.
7980static void PushPopXRegSimpleHelper(int reg_count,
7981 int claim,
7982 int reg_size,
7983 PushPopMethod push_method,
7984 PushPopMethod pop_method) {
7985 SETUP();
7986
7987 START();
7988
7989 // Arbitrarily pick a register to use as a stack pointer.
7990 const Register& stack_pointer = x20;
7991 const RegList allowed = ~stack_pointer.Bit();
7992 if (reg_count == kPushPopXRegMaxRegCount) {
7993 reg_count = CountSetBits(allowed, kNumberOfRegisters);
7994 }
7995 // Work out which registers to use, based on reg_size.
7996 Register r[kNumberOfRegisters];
7997 Register x[kNumberOfRegisters];
7998 RegList list = PopulateRegisterArray(NULL, x, r, reg_size, reg_count,
7999 allowed);
8000
8001 // The literal base is chosen to have two useful properties:
8002 // * When multiplied by small values (such as a register index), this value
8003 // is clearly readable in the result.
8004 // * The value is not formed from repeating fixed-size smaller values, so it
8005 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +00008006 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +01008007
8008 {
armvixlb0c8ae22014-03-21 14:03:59 +00008009 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +01008010 __ Mov(stack_pointer, __ StackPointer());
8011 __ SetStackPointer(stack_pointer);
8012
8013 int i;
8014
8015 // Initialize the registers.
8016 for (i = 0; i < reg_count; i++) {
8017 // Always write into the X register, to ensure that the upper word is
8018 // properly ignored by Push when testing W registers.
8019 __ Mov(x[i], literal_base * i);
8020 }
8021
8022 // Claim memory first, as requested.
8023 __ Claim(claim);
8024
8025 switch (push_method) {
8026 case PushPopByFour:
8027 // Push high-numbered registers first (to the highest addresses).
8028 for (i = reg_count; i >= 4; i -= 4) {
8029 __ Push(r[i-1], r[i-2], r[i-3], r[i-4]);
8030 }
8031 // Finish off the leftovers.
8032 switch (i) {
8033 case 3: __ Push(r[2], r[1], r[0]); break;
8034 case 2: __ Push(r[1], r[0]); break;
8035 case 1: __ Push(r[0]); break;
armvixlb0c8ae22014-03-21 14:03:59 +00008036 default: VIXL_ASSERT(i == 0); break;
armvixlad96eda2013-06-14 11:42:37 +01008037 }
8038 break;
8039 case PushPopRegList:
8040 __ PushSizeRegList(list, reg_size);
8041 break;
8042 }
8043
8044 // Clobber all the registers, to ensure that they get repopulated by Pop.
8045 Clobber(&masm, list);
8046
8047 switch (pop_method) {
8048 case PushPopByFour:
8049 // Pop low-numbered registers first (from the lowest addresses).
8050 for (i = 0; i <= (reg_count-4); i += 4) {
8051 __ Pop(r[i], r[i+1], r[i+2], r[i+3]);
8052 }
8053 // Finish off the leftovers.
8054 switch (reg_count - i) {
8055 case 3: __ Pop(r[i], r[i+1], r[i+2]); break;
8056 case 2: __ Pop(r[i], r[i+1]); break;
8057 case 1: __ Pop(r[i]); break;
armvixlb0c8ae22014-03-21 14:03:59 +00008058 default: VIXL_ASSERT(i == reg_count); break;
armvixlad96eda2013-06-14 11:42:37 +01008059 }
8060 break;
8061 case PushPopRegList:
8062 __ PopSizeRegList(list, reg_size);
8063 break;
8064 }
8065
8066 // Drop memory to restore stack_pointer.
8067 __ Drop(claim);
8068
8069 __ Mov(sp, __ StackPointer());
8070 __ SetStackPointer(sp);
8071 }
8072
8073 END();
8074
8075 RUN();
8076
8077 // Check that the register contents were preserved.
8078 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
8079 // that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +00008080 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +01008081 for (int i = 0; i < reg_count; i++) {
8082 if (x[i].Is(xzr)) {
8083 ASSERT_EQUAL_64(0, x[i]);
8084 } else {
8085 ASSERT_EQUAL_64(literal_base * i, x[i]);
8086 }
8087 }
8088
8089 TEARDOWN();
8090}
8091
8092
8093TEST(push_pop_xreg_simple_32) {
8094 for (int claim = 0; claim <= 8; claim++) {
8095 for (int count = 0; count <= 8; count++) {
8096 PushPopXRegSimpleHelper(count, claim, kWRegSize,
8097 PushPopByFour, PushPopByFour);
8098 PushPopXRegSimpleHelper(count, claim, kWRegSize,
8099 PushPopByFour, PushPopRegList);
8100 PushPopXRegSimpleHelper(count, claim, kWRegSize,
8101 PushPopRegList, PushPopByFour);
8102 PushPopXRegSimpleHelper(count, claim, kWRegSize,
8103 PushPopRegList, PushPopRegList);
8104 }
8105 // Test with the maximum number of registers.
8106 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
8107 claim, kWRegSize, PushPopByFour, PushPopByFour);
8108 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
8109 claim, kWRegSize, PushPopByFour, PushPopRegList);
8110 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
8111 claim, kWRegSize, PushPopRegList, PushPopByFour);
8112 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
8113 claim, kWRegSize, PushPopRegList, PushPopRegList);
8114 }
8115}
8116
8117
8118TEST(push_pop_xreg_simple_64) {
8119 for (int claim = 0; claim <= 8; claim++) {
8120 for (int count = 0; count <= 8; count++) {
8121 PushPopXRegSimpleHelper(count, claim, kXRegSize,
8122 PushPopByFour, PushPopByFour);
8123 PushPopXRegSimpleHelper(count, claim, kXRegSize,
8124 PushPopByFour, PushPopRegList);
8125 PushPopXRegSimpleHelper(count, claim, kXRegSize,
8126 PushPopRegList, PushPopByFour);
8127 PushPopXRegSimpleHelper(count, claim, kXRegSize,
8128 PushPopRegList, PushPopRegList);
8129 }
8130 // Test with the maximum number of registers.
8131 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
8132 claim, kXRegSize, PushPopByFour, PushPopByFour);
8133 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
8134 claim, kXRegSize, PushPopByFour, PushPopRegList);
8135 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
8136 claim, kXRegSize, PushPopRegList, PushPopByFour);
8137 PushPopXRegSimpleHelper(kPushPopXRegMaxRegCount,
8138 claim, kXRegSize, PushPopRegList, PushPopRegList);
8139 }
8140}
8141
8142
8143// The maximum number of registers that can be used by the PushPopFPXReg* tests,
8144// where a reg_count field is provided.
8145static int const kPushPopFPXRegMaxRegCount = -1;
8146
8147// Test a simple push-pop pattern:
8148// * Claim <claim> bytes to set the stack alignment.
8149// * Push <reg_count> FP registers with size <reg_size>.
8150// * Clobber the register contents.
8151// * Pop <reg_count> FP registers to restore the original contents.
8152// * Drop <claim> bytes to restore the original stack pointer.
8153//
8154// Different push and pop methods can be specified independently to test for
8155// proper word-endian behaviour.
8156static void PushPopFPXRegSimpleHelper(int reg_count,
8157 int claim,
8158 int reg_size,
8159 PushPopMethod push_method,
8160 PushPopMethod pop_method) {
8161 SETUP();
8162
8163 START();
8164
8165 // We can use any floating-point register. None of them are reserved for
8166 // debug code, for example.
8167 static RegList const allowed = ~0;
8168 if (reg_count == kPushPopFPXRegMaxRegCount) {
8169 reg_count = CountSetBits(allowed, kNumberOfFPRegisters);
8170 }
8171 // Work out which registers to use, based on reg_size.
8172 FPRegister v[kNumberOfRegisters];
8173 FPRegister d[kNumberOfRegisters];
8174 RegList list = PopulateFPRegisterArray(NULL, d, v, reg_size, reg_count,
8175 allowed);
8176
8177 // Arbitrarily pick a register to use as a stack pointer.
8178 const Register& stack_pointer = x10;
8179
8180 // The literal base is chosen to have two useful properties:
8181 // * When multiplied (using an integer) by small values (such as a register
8182 // index), this value is clearly readable in the result.
8183 // * The value is not formed from repeating fixed-size smaller values, so it
8184 // can be used to detect endianness-related errors.
8185 // * It is never a floating-point NaN, and will therefore always compare
8186 // equal to itself.
armvixlb0c8ae22014-03-21 14:03:59 +00008187 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +01008188
8189 {
armvixlb0c8ae22014-03-21 14:03:59 +00008190 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +01008191 __ Mov(stack_pointer, __ StackPointer());
8192 __ SetStackPointer(stack_pointer);
8193
8194 int i;
8195
8196 // Initialize the registers, using X registers to load the literal.
8197 __ Mov(x0, 0);
8198 __ Mov(x1, literal_base);
8199 for (i = 0; i < reg_count; i++) {
8200 // Always write into the D register, to ensure that the upper word is
8201 // properly ignored by Push when testing S registers.
8202 __ Fmov(d[i], x0);
8203 // Calculate the next literal.
8204 __ Add(x0, x0, x1);
8205 }
8206
8207 // Claim memory first, as requested.
8208 __ Claim(claim);
8209
8210 switch (push_method) {
8211 case PushPopByFour:
8212 // Push high-numbered registers first (to the highest addresses).
8213 for (i = reg_count; i >= 4; i -= 4) {
8214 __ Push(v[i-1], v[i-2], v[i-3], v[i-4]);
8215 }
8216 // Finish off the leftovers.
8217 switch (i) {
8218 case 3: __ Push(v[2], v[1], v[0]); break;
8219 case 2: __ Push(v[1], v[0]); break;
8220 case 1: __ Push(v[0]); break;
armvixlb0c8ae22014-03-21 14:03:59 +00008221 default: VIXL_ASSERT(i == 0); break;
armvixlad96eda2013-06-14 11:42:37 +01008222 }
8223 break;
8224 case PushPopRegList:
8225 __ PushSizeRegList(list, reg_size, CPURegister::kFPRegister);
8226 break;
8227 }
8228
8229 // Clobber all the registers, to ensure that they get repopulated by Pop.
8230 ClobberFP(&masm, list);
8231
8232 switch (pop_method) {
8233 case PushPopByFour:
8234 // Pop low-numbered registers first (from the lowest addresses).
8235 for (i = 0; i <= (reg_count-4); i += 4) {
8236 __ Pop(v[i], v[i+1], v[i+2], v[i+3]);
8237 }
8238 // Finish off the leftovers.
8239 switch (reg_count - i) {
8240 case 3: __ Pop(v[i], v[i+1], v[i+2]); break;
8241 case 2: __ Pop(v[i], v[i+1]); break;
8242 case 1: __ Pop(v[i]); break;
armvixlb0c8ae22014-03-21 14:03:59 +00008243 default: VIXL_ASSERT(i == reg_count); break;
armvixlad96eda2013-06-14 11:42:37 +01008244 }
8245 break;
8246 case PushPopRegList:
8247 __ PopSizeRegList(list, reg_size, CPURegister::kFPRegister);
8248 break;
8249 }
8250
8251 // Drop memory to restore the stack pointer.
8252 __ Drop(claim);
8253
8254 __ Mov(sp, __ StackPointer());
8255 __ SetStackPointer(sp);
8256 }
8257
8258 END();
8259
8260 RUN();
8261
8262 // Check that the register contents were preserved.
8263 // Always use ASSERT_EQUAL_FP64, even when testing S registers, so we can
8264 // test that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +00008265 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +01008266 for (int i = 0; i < reg_count; i++) {
8267 uint64_t literal = literal_base * i;
8268 double expected;
8269 memcpy(&expected, &literal, sizeof(expected));
8270 ASSERT_EQUAL_FP64(expected, d[i]);
8271 }
8272
8273 TEARDOWN();
8274}
8275
8276
8277TEST(push_pop_fp_xreg_simple_32) {
8278 for (int claim = 0; claim <= 8; claim++) {
8279 for (int count = 0; count <= 8; count++) {
8280 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8281 PushPopByFour, PushPopByFour);
8282 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8283 PushPopByFour, PushPopRegList);
8284 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8285 PushPopRegList, PushPopByFour);
8286 PushPopFPXRegSimpleHelper(count, claim, kSRegSize,
8287 PushPopRegList, PushPopRegList);
8288 }
8289 // Test with the maximum number of registers.
8290 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8291 PushPopByFour, PushPopByFour);
8292 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8293 PushPopByFour, PushPopRegList);
8294 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8295 PushPopRegList, PushPopByFour);
8296 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kSRegSize,
8297 PushPopRegList, PushPopRegList);
8298 }
8299}
8300
8301
8302TEST(push_pop_fp_xreg_simple_64) {
8303 for (int claim = 0; claim <= 8; claim++) {
8304 for (int count = 0; count <= 8; count++) {
8305 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8306 PushPopByFour, PushPopByFour);
8307 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8308 PushPopByFour, PushPopRegList);
8309 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8310 PushPopRegList, PushPopByFour);
8311 PushPopFPXRegSimpleHelper(count, claim, kDRegSize,
8312 PushPopRegList, PushPopRegList);
8313 }
8314 // Test with the maximum number of registers.
8315 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8316 PushPopByFour, PushPopByFour);
8317 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8318 PushPopByFour, PushPopRegList);
8319 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8320 PushPopRegList, PushPopByFour);
8321 PushPopFPXRegSimpleHelper(kPushPopFPXRegMaxRegCount, claim, kDRegSize,
8322 PushPopRegList, PushPopRegList);
8323 }
8324}
8325
8326
8327// Push and pop data using an overlapping combination of Push/Pop and
8328// RegList-based methods.
8329static void PushPopXRegMixedMethodsHelper(int claim, int reg_size) {
8330 SETUP();
8331
8332 // Arbitrarily pick a register to use as a stack pointer.
8333 const Register& stack_pointer = x5;
8334 const RegList allowed = ~stack_pointer.Bit();
8335 // Work out which registers to use, based on reg_size.
8336 Register r[10];
8337 Register x[10];
8338 PopulateRegisterArray(NULL, x, r, reg_size, 10, allowed);
8339
8340 // Calculate some handy register lists.
8341 RegList r0_to_r3 = 0;
8342 for (int i = 0; i <= 3; i++) {
8343 r0_to_r3 |= x[i].Bit();
8344 }
8345 RegList r4_to_r5 = 0;
8346 for (int i = 4; i <= 5; i++) {
8347 r4_to_r5 |= x[i].Bit();
8348 }
8349 RegList r6_to_r9 = 0;
8350 for (int i = 6; i <= 9; i++) {
8351 r6_to_r9 |= x[i].Bit();
8352 }
8353
8354 // The literal base is chosen to have two useful properties:
8355 // * When multiplied by small values (such as a register index), this value
8356 // is clearly readable in the result.
8357 // * The value is not formed from repeating fixed-size smaller values, so it
8358 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +00008359 uint64_t literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +01008360
8361 START();
8362 {
armvixlb0c8ae22014-03-21 14:03:59 +00008363 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +01008364 __ Mov(stack_pointer, __ StackPointer());
8365 __ SetStackPointer(stack_pointer);
8366
8367 // Claim memory first, as requested.
8368 __ Claim(claim);
8369
8370 __ Mov(x[3], literal_base * 3);
8371 __ Mov(x[2], literal_base * 2);
8372 __ Mov(x[1], literal_base * 1);
8373 __ Mov(x[0], literal_base * 0);
8374
8375 __ PushSizeRegList(r0_to_r3, reg_size);
8376 __ Push(r[3], r[2]);
8377
8378 Clobber(&masm, r0_to_r3);
8379 __ PopSizeRegList(r0_to_r3, reg_size);
8380
8381 __ Push(r[2], r[1], r[3], r[0]);
8382
8383 Clobber(&masm, r4_to_r5);
8384 __ Pop(r[4], r[5]);
8385 Clobber(&masm, r6_to_r9);
8386 __ Pop(r[6], r[7], r[8], r[9]);
8387
8388 // Drop memory to restore stack_pointer.
8389 __ Drop(claim);
8390
8391 __ Mov(sp, __ StackPointer());
8392 __ SetStackPointer(sp);
8393 }
8394
8395 END();
8396
8397 RUN();
8398
8399 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
8400 // that the upper word was properly cleared by Pop.
armvixlb0c8ae22014-03-21 14:03:59 +00008401 literal_base &= (0xffffffffffffffff >> (64-reg_size));
armvixlad96eda2013-06-14 11:42:37 +01008402
8403 ASSERT_EQUAL_64(literal_base * 3, x[9]);
8404 ASSERT_EQUAL_64(literal_base * 2, x[8]);
8405 ASSERT_EQUAL_64(literal_base * 0, x[7]);
8406 ASSERT_EQUAL_64(literal_base * 3, x[6]);
8407 ASSERT_EQUAL_64(literal_base * 1, x[5]);
8408 ASSERT_EQUAL_64(literal_base * 2, x[4]);
8409
8410 TEARDOWN();
8411}
8412
8413
8414TEST(push_pop_xreg_mixed_methods_64) {
8415 for (int claim = 0; claim <= 8; claim++) {
8416 PushPopXRegMixedMethodsHelper(claim, kXRegSize);
8417 }
8418}
8419
8420
8421TEST(push_pop_xreg_mixed_methods_32) {
8422 for (int claim = 0; claim <= 8; claim++) {
8423 PushPopXRegMixedMethodsHelper(claim, kWRegSize);
8424 }
8425}
8426
8427
8428// Push and pop data using overlapping X- and W-sized quantities.
8429static void PushPopXRegWXOverlapHelper(int reg_count, int claim) {
8430 SETUP();
8431
8432 // Arbitrarily pick a register to use as a stack pointer.
8433 const Register& stack_pointer = x10;
8434 const RegList allowed = ~stack_pointer.Bit();
8435 if (reg_count == kPushPopXRegMaxRegCount) {
8436 reg_count = CountSetBits(allowed, kNumberOfRegisters);
8437 }
8438 // Work out which registers to use, based on reg_size.
8439 Register w[kNumberOfRegisters];
8440 Register x[kNumberOfRegisters];
8441 RegList list = PopulateRegisterArray(w, x, NULL, 0, reg_count, allowed);
8442
8443 // The number of W-sized slots we expect to pop. When we pop, we alternate
8444 // between W and X registers, so we need reg_count*1.5 W-sized slots.
8445 int const requested_w_slots = reg_count + reg_count / 2;
8446
8447 // Track what _should_ be on the stack, using W-sized slots.
8448 static int const kMaxWSlots = kNumberOfRegisters + kNumberOfRegisters / 2;
8449 uint32_t stack[kMaxWSlots];
8450 for (int i = 0; i < kMaxWSlots; i++) {
8451 stack[i] = 0xdeadbeef;
8452 }
8453
8454 // The literal base is chosen to have two useful properties:
8455 // * When multiplied by small values (such as a register index), this value
8456 // is clearly readable in the result.
8457 // * The value is not formed from repeating fixed-size smaller values, so it
8458 // can be used to detect endianness-related errors.
armvixlb0c8ae22014-03-21 14:03:59 +00008459 static uint64_t const literal_base = 0x0100001000100101;
armvixlad96eda2013-06-14 11:42:37 +01008460 static uint64_t const literal_base_hi = literal_base >> 32;
8461 static uint64_t const literal_base_lo = literal_base & 0xffffffff;
8462 static uint64_t const literal_base_w = literal_base & 0xffffffff;
8463
8464 START();
8465 {
armvixlb0c8ae22014-03-21 14:03:59 +00008466 VIXL_ASSERT(__ StackPointer().Is(sp));
armvixlad96eda2013-06-14 11:42:37 +01008467 __ Mov(stack_pointer, __ StackPointer());
8468 __ SetStackPointer(stack_pointer);
8469
8470 // Initialize the registers.
8471 for (int i = 0; i < reg_count; i++) {
8472 // Always write into the X register, to ensure that the upper word is
8473 // properly ignored by Push when testing W registers.
8474 __ Mov(x[i], literal_base * i);
8475 }
8476
8477 // Claim memory first, as requested.
8478 __ Claim(claim);
8479
8480 // The push-pop pattern is as follows:
8481 // Push: Pop:
8482 // x[0](hi) -> w[0]
8483 // x[0](lo) -> x[1](hi)
8484 // w[1] -> x[1](lo)
8485 // w[1] -> w[2]
8486 // x[2](hi) -> x[2](hi)
8487 // x[2](lo) -> x[2](lo)
8488 // x[2](hi) -> w[3]
8489 // x[2](lo) -> x[4](hi)
8490 // x[2](hi) -> x[4](lo)
8491 // x[2](lo) -> w[5]
8492 // w[3] -> x[5](hi)
8493 // w[3] -> x[6](lo)
8494 // w[3] -> w[7]
8495 // w[3] -> x[8](hi)
8496 // x[4](hi) -> x[8](lo)
8497 // x[4](lo) -> w[9]
8498 // ... pattern continues ...
8499 //
8500 // That is, registers are pushed starting with the lower numbers,
8501 // alternating between x and w registers, and pushing i%4+1 copies of each,
8502 // where i is the register number.
8503 // Registers are popped starting with the higher numbers one-by-one,
8504 // alternating between x and w registers, but only popping one at a time.
8505 //
8506 // This pattern provides a wide variety of alignment effects and overlaps.
8507
8508 // ---- Push ----
8509
8510 int active_w_slots = 0;
8511 for (int i = 0; active_w_slots < requested_w_slots; i++) {
armvixlb0c8ae22014-03-21 14:03:59 +00008512 VIXL_ASSERT(i < reg_count);
armvixlad96eda2013-06-14 11:42:37 +01008513 // In order to test various arguments to PushMultipleTimes, and to try to
8514 // exercise different alignment and overlap effects, we push each
8515 // register a different number of times.
8516 int times = i % 4 + 1;
8517 if (i & 1) {
8518 // Push odd-numbered registers as W registers.
8519 __ PushMultipleTimes(times, w[i]);
8520 // Fill in the expected stack slots.
8521 for (int j = 0; j < times; j++) {
8522 if (w[i].Is(wzr)) {
8523 // The zero register always writes zeroes.
8524 stack[active_w_slots++] = 0;
8525 } else {
8526 stack[active_w_slots++] = literal_base_w * i;
8527 }
8528 }
8529 } else {
8530 // Push even-numbered registers as X registers.
8531 __ PushMultipleTimes(times, x[i]);
8532 // Fill in the expected stack slots.
8533 for (int j = 0; j < times; j++) {
8534 if (x[i].Is(xzr)) {
8535 // The zero register always writes zeroes.
8536 stack[active_w_slots++] = 0;
8537 stack[active_w_slots++] = 0;
8538 } else {
8539 stack[active_w_slots++] = literal_base_hi * i;
8540 stack[active_w_slots++] = literal_base_lo * i;
8541 }
8542 }
8543 }
8544 }
8545 // Because we were pushing several registers at a time, we probably pushed
8546 // more than we needed to.
8547 if (active_w_slots > requested_w_slots) {
8548 __ Drop((active_w_slots - requested_w_slots) * kWRegSizeInBytes);
8549 // Bump the number of active W-sized slots back to where it should be,
8550 // and fill the empty space with a dummy value.
8551 do {
8552 stack[active_w_slots--] = 0xdeadbeef;
8553 } while (active_w_slots > requested_w_slots);
8554 }
8555
8556 // ---- Pop ----
8557
8558 Clobber(&masm, list);
8559
8560 // If popping an even number of registers, the first one will be X-sized.
8561 // Otherwise, the first one will be W-sized.
8562 bool next_is_64 = !(reg_count & 1);
8563 for (int i = reg_count-1; i >= 0; i--) {
8564 if (next_is_64) {
8565 __ Pop(x[i]);
8566 active_w_slots -= 2;
8567 } else {
8568 __ Pop(w[i]);
8569 active_w_slots -= 1;
8570 }
8571 next_is_64 = !next_is_64;
8572 }
armvixlb0c8ae22014-03-21 14:03:59 +00008573 VIXL_ASSERT(active_w_slots == 0);
armvixlad96eda2013-06-14 11:42:37 +01008574
8575 // Drop memory to restore stack_pointer.
8576 __ Drop(claim);
8577
8578 __ Mov(sp, __ StackPointer());
8579 __ SetStackPointer(sp);
8580 }
8581
8582 END();
8583
8584 RUN();
8585
8586 int slot = 0;
8587 for (int i = 0; i < reg_count; i++) {
8588 // Even-numbered registers were written as W registers.
8589 // Odd-numbered registers were written as X registers.
8590 bool expect_64 = (i & 1);
8591 uint64_t expected;
8592
8593 if (expect_64) {
8594 uint64_t hi = stack[slot++];
8595 uint64_t lo = stack[slot++];
8596 expected = (hi << 32) | lo;
8597 } else {
8598 expected = stack[slot++];
8599 }
8600
8601 // Always use ASSERT_EQUAL_64, even when testing W registers, so we can
8602 // test that the upper word was properly cleared by Pop.
8603 if (x[i].Is(xzr)) {
8604 ASSERT_EQUAL_64(0, x[i]);
8605 } else {
8606 ASSERT_EQUAL_64(expected, x[i]);
8607 }
8608 }
armvixlb0c8ae22014-03-21 14:03:59 +00008609 VIXL_ASSERT(slot == requested_w_slots);
armvixlad96eda2013-06-14 11:42:37 +01008610
8611 TEARDOWN();
8612}
8613
8614
8615TEST(push_pop_xreg_wx_overlap) {
8616 for (int claim = 0; claim <= 8; claim++) {
8617 for (int count = 1; count <= 8; count++) {
8618 PushPopXRegWXOverlapHelper(count, claim);
8619 }
8620 // Test with the maximum number of registers.
8621 PushPopXRegWXOverlapHelper(kPushPopXRegMaxRegCount, claim);
8622 }
8623}
8624
8625
8626TEST(push_pop_sp) {
8627 SETUP();
8628
8629 START();
8630
armvixlb0c8ae22014-03-21 14:03:59 +00008631 VIXL_ASSERT(sp.Is(__ StackPointer()));
armvixlad96eda2013-06-14 11:42:37 +01008632
armvixlb0c8ae22014-03-21 14:03:59 +00008633 __ Mov(x3, 0x3333333333333333);
8634 __ Mov(x2, 0x2222222222222222);
8635 __ Mov(x1, 0x1111111111111111);
8636 __ Mov(x0, 0x0000000000000000);
armvixlad96eda2013-06-14 11:42:37 +01008637 __ Claim(2 * kXRegSizeInBytes);
8638 __ PushXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
8639 __ Push(x3, x2);
8640 __ PopXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit());
8641 __ Push(x2, x1, x3, x0);
8642 __ Pop(x4, x5);
8643 __ Pop(x6, x7, x8, x9);
8644
8645 __ Claim(2 * kXRegSizeInBytes);
8646 __ PushWRegList(w0.Bit() | w1.Bit() | w2.Bit() | w3.Bit());
8647 __ Push(w3, w1, w2, w0);
8648 __ PopWRegList(w10.Bit() | w11.Bit() | w12.Bit() | w13.Bit());
8649 __ Pop(w14, w15, w16, w17);
8650
8651 __ Claim(2 * kXRegSizeInBytes);
8652 __ Push(w2, w2, w1, w1);
8653 __ Push(x3, x3);
8654 __ Pop(w18, w19, w20, w21);
8655 __ Pop(x22, x23);
8656
8657 __ Claim(2 * kXRegSizeInBytes);
8658 __ PushXRegList(x1.Bit() | x22.Bit());
8659 __ PopXRegList(x24.Bit() | x26.Bit());
8660
8661 __ Claim(2 * kXRegSizeInBytes);
8662 __ PushWRegList(w1.Bit() | w2.Bit() | w4.Bit() | w22.Bit());
8663 __ PopWRegList(w25.Bit() | w27.Bit() | w28.Bit() | w29.Bit());
8664
8665 __ Claim(2 * kXRegSizeInBytes);
8666 __ PushXRegList(0);
8667 __ PopXRegList(0);
8668 __ PushXRegList(0xffffffff);
8669 __ PopXRegList(0xffffffff);
8670 __ Drop(12 * kXRegSizeInBytes);
8671 END();
8672
8673 RUN();
8674
armvixlb0c8ae22014-03-21 14:03:59 +00008675 ASSERT_EQUAL_64(0x1111111111111111, x3);
8676 ASSERT_EQUAL_64(0x0000000000000000, x2);
8677 ASSERT_EQUAL_64(0x3333333333333333, x1);
8678 ASSERT_EQUAL_64(0x2222222222222222, x0);
8679 ASSERT_EQUAL_64(0x3333333333333333, x9);
8680 ASSERT_EQUAL_64(0x2222222222222222, x8);
8681 ASSERT_EQUAL_64(0x0000000000000000, x7);
8682 ASSERT_EQUAL_64(0x3333333333333333, x6);
8683 ASSERT_EQUAL_64(0x1111111111111111, x5);
8684 ASSERT_EQUAL_64(0x2222222222222222, x4);
armvixlad96eda2013-06-14 11:42:37 +01008685
8686 ASSERT_EQUAL_32(0x11111111U, w13);
8687 ASSERT_EQUAL_32(0x33333333U, w12);
8688 ASSERT_EQUAL_32(0x00000000U, w11);
8689 ASSERT_EQUAL_32(0x22222222U, w10);
8690 ASSERT_EQUAL_32(0x11111111U, w17);
8691 ASSERT_EQUAL_32(0x00000000U, w16);
8692 ASSERT_EQUAL_32(0x33333333U, w15);
8693 ASSERT_EQUAL_32(0x22222222U, w14);
8694
8695 ASSERT_EQUAL_32(0x11111111U, w18);
8696 ASSERT_EQUAL_32(0x11111111U, w19);
8697 ASSERT_EQUAL_32(0x11111111U, w20);
8698 ASSERT_EQUAL_32(0x11111111U, w21);
armvixlb0c8ae22014-03-21 14:03:59 +00008699 ASSERT_EQUAL_64(0x3333333333333333, x22);
8700 ASSERT_EQUAL_64(0x0000000000000000, x23);
armvixlad96eda2013-06-14 11:42:37 +01008701
armvixlb0c8ae22014-03-21 14:03:59 +00008702 ASSERT_EQUAL_64(0x3333333333333333, x24);
8703 ASSERT_EQUAL_64(0x3333333333333333, x26);
armvixlad96eda2013-06-14 11:42:37 +01008704
8705 ASSERT_EQUAL_32(0x33333333U, w25);
8706 ASSERT_EQUAL_32(0x00000000U, w27);
8707 ASSERT_EQUAL_32(0x22222222U, w28);
8708 ASSERT_EQUAL_32(0x33333333U, w29);
8709 TEARDOWN();
8710}
8711
8712
8713TEST(noreg) {
8714 // This test doesn't generate any code, but it verifies some invariants
8715 // related to NoReg.
armvixlb0c8ae22014-03-21 14:03:59 +00008716 VIXL_CHECK(NoReg.Is(NoFPReg));
8717 VIXL_CHECK(NoFPReg.Is(NoReg));
8718 VIXL_CHECK(NoReg.Is(NoCPUReg));
8719 VIXL_CHECK(NoCPUReg.Is(NoReg));
8720 VIXL_CHECK(NoFPReg.Is(NoCPUReg));
8721 VIXL_CHECK(NoCPUReg.Is(NoFPReg));
armvixlad96eda2013-06-14 11:42:37 +01008722
armvixlb0c8ae22014-03-21 14:03:59 +00008723 VIXL_CHECK(NoReg.IsNone());
8724 VIXL_CHECK(NoFPReg.IsNone());
8725 VIXL_CHECK(NoCPUReg.IsNone());
armvixlad96eda2013-06-14 11:42:37 +01008726}
8727
8728
8729TEST(isvalid) {
8730 // This test doesn't generate any code, but it verifies some invariants
8731 // related to IsValid().
armvixlb0c8ae22014-03-21 14:03:59 +00008732 VIXL_CHECK(!NoReg.IsValid());
8733 VIXL_CHECK(!NoFPReg.IsValid());
8734 VIXL_CHECK(!NoCPUReg.IsValid());
armvixlad96eda2013-06-14 11:42:37 +01008735
armvixlb0c8ae22014-03-21 14:03:59 +00008736 VIXL_CHECK(x0.IsValid());
8737 VIXL_CHECK(w0.IsValid());
8738 VIXL_CHECK(x30.IsValid());
8739 VIXL_CHECK(w30.IsValid());
8740 VIXL_CHECK(xzr.IsValid());
8741 VIXL_CHECK(wzr.IsValid());
armvixlad96eda2013-06-14 11:42:37 +01008742
armvixlb0c8ae22014-03-21 14:03:59 +00008743 VIXL_CHECK(sp.IsValid());
8744 VIXL_CHECK(wsp.IsValid());
armvixlad96eda2013-06-14 11:42:37 +01008745
armvixlb0c8ae22014-03-21 14:03:59 +00008746 VIXL_CHECK(d0.IsValid());
8747 VIXL_CHECK(s0.IsValid());
8748 VIXL_CHECK(d31.IsValid());
8749 VIXL_CHECK(s31.IsValid());
armvixlad96eda2013-06-14 11:42:37 +01008750
armvixlb0c8ae22014-03-21 14:03:59 +00008751 VIXL_CHECK(x0.IsValidRegister());
8752 VIXL_CHECK(w0.IsValidRegister());
8753 VIXL_CHECK(xzr.IsValidRegister());
8754 VIXL_CHECK(wzr.IsValidRegister());
8755 VIXL_CHECK(sp.IsValidRegister());
8756 VIXL_CHECK(wsp.IsValidRegister());
8757 VIXL_CHECK(!x0.IsValidFPRegister());
8758 VIXL_CHECK(!w0.IsValidFPRegister());
8759 VIXL_CHECK(!xzr.IsValidFPRegister());
8760 VIXL_CHECK(!wzr.IsValidFPRegister());
8761 VIXL_CHECK(!sp.IsValidFPRegister());
8762 VIXL_CHECK(!wsp.IsValidFPRegister());
armvixlad96eda2013-06-14 11:42:37 +01008763
armvixlb0c8ae22014-03-21 14:03:59 +00008764 VIXL_CHECK(d0.IsValidFPRegister());
8765 VIXL_CHECK(s0.IsValidFPRegister());
8766 VIXL_CHECK(!d0.IsValidRegister());
8767 VIXL_CHECK(!s0.IsValidRegister());
armvixlad96eda2013-06-14 11:42:37 +01008768
8769 // Test the same as before, but using CPURegister types. This shouldn't make
8770 // any difference.
armvixlb0c8ae22014-03-21 14:03:59 +00008771 VIXL_CHECK(static_cast<CPURegister>(x0).IsValid());
8772 VIXL_CHECK(static_cast<CPURegister>(w0).IsValid());
8773 VIXL_CHECK(static_cast<CPURegister>(x30).IsValid());
8774 VIXL_CHECK(static_cast<CPURegister>(w30).IsValid());
8775 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValid());
8776 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValid());
armvixlad96eda2013-06-14 11:42:37 +01008777
armvixlb0c8ae22014-03-21 14:03:59 +00008778 VIXL_CHECK(static_cast<CPURegister>(sp).IsValid());
8779 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValid());
armvixlad96eda2013-06-14 11:42:37 +01008780
armvixlb0c8ae22014-03-21 14:03:59 +00008781 VIXL_CHECK(static_cast<CPURegister>(d0).IsValid());
8782 VIXL_CHECK(static_cast<CPURegister>(s0).IsValid());
8783 VIXL_CHECK(static_cast<CPURegister>(d31).IsValid());
8784 VIXL_CHECK(static_cast<CPURegister>(s31).IsValid());
armvixlad96eda2013-06-14 11:42:37 +01008785
armvixlb0c8ae22014-03-21 14:03:59 +00008786 VIXL_CHECK(static_cast<CPURegister>(x0).IsValidRegister());
8787 VIXL_CHECK(static_cast<CPURegister>(w0).IsValidRegister());
8788 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValidRegister());
8789 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValidRegister());
8790 VIXL_CHECK(static_cast<CPURegister>(sp).IsValidRegister());
8791 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValidRegister());
8792 VIXL_CHECK(!static_cast<CPURegister>(x0).IsValidFPRegister());
8793 VIXL_CHECK(!static_cast<CPURegister>(w0).IsValidFPRegister());
8794 VIXL_CHECK(!static_cast<CPURegister>(xzr).IsValidFPRegister());
8795 VIXL_CHECK(!static_cast<CPURegister>(wzr).IsValidFPRegister());
8796 VIXL_CHECK(!static_cast<CPURegister>(sp).IsValidFPRegister());
8797 VIXL_CHECK(!static_cast<CPURegister>(wsp).IsValidFPRegister());
armvixlad96eda2013-06-14 11:42:37 +01008798
armvixlb0c8ae22014-03-21 14:03:59 +00008799 VIXL_CHECK(static_cast<CPURegister>(d0).IsValidFPRegister());
8800 VIXL_CHECK(static_cast<CPURegister>(s0).IsValidFPRegister());
8801 VIXL_CHECK(!static_cast<CPURegister>(d0).IsValidRegister());
8802 VIXL_CHECK(!static_cast<CPURegister>(s0).IsValidRegister());
armvixlad96eda2013-06-14 11:42:37 +01008803}
8804
8805
8806TEST(printf) {
armvixl4a102ba2014-07-14 09:02:40 +01008807 SETUP_CUSTOM(BUF_SIZE * 2, PositionIndependentCode);
armvixlad96eda2013-06-14 11:42:37 +01008808 START();
8809
8810 char const * test_plain_string = "Printf with no arguments.\n";
8811 char const * test_substring = "'This is a substring.'";
8812 RegisterDump before;
8813
8814 // Initialize x29 to the value of the stack pointer. We will use x29 as a
8815 // temporary stack pointer later, and initializing it in this way allows the
8816 // RegisterDump check to pass.
8817 __ Mov(x29, __ StackPointer());
8818
8819 // Test simple integer arguments.
8820 __ Mov(x0, 1234);
8821 __ Mov(x1, 0x1234);
8822
8823 // Test simple floating-point arguments.
8824 __ Fmov(d0, 1.234);
8825
8826 // Test pointer (string) arguments.
8827 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
8828
8829 // Test the maximum number of arguments, and sign extension.
8830 __ Mov(w3, 0xffffffff);
8831 __ Mov(w4, 0xffffffff);
8832 __ Mov(x5, 0xffffffffffffffff);
8833 __ Mov(x6, 0xffffffffffffffff);
8834 __ Fmov(s1, 1.234);
8835 __ Fmov(s2, 2.345);
8836 __ Fmov(d3, 3.456);
8837 __ Fmov(d4, 4.567);
8838
8839 // Test printing callee-saved registers.
8840 __ Mov(x28, 0x123456789abcdef);
8841 __ Fmov(d10, 42.0);
8842
8843 // Test with three arguments.
8844 __ Mov(x10, 3);
8845 __ Mov(x11, 40);
8846 __ Mov(x12, 500);
8847
armvixl5799d6c2014-05-01 11:05:00 +01008848 // A single character.
8849 __ Mov(w13, 'x');
8850
8851 // Check that we don't clobber any registers.
armvixlad96eda2013-06-14 11:42:37 +01008852 before.Dump(&masm);
8853
8854 __ Printf(test_plain_string); // NOLINT(runtime/printf)
armvixl5799d6c2014-05-01 11:05:00 +01008855 __ Printf("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1);
8856 __ Printf("w5: %" PRId32 ", x5: %" PRId64"\n", w5, x5);
armvixlad96eda2013-06-14 11:42:37 +01008857 __ Printf("d0: %f\n", d0);
8858 __ Printf("Test %%s: %s\n", x2);
8859 __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
8860 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
8861 w3, w4, x5, x6);
8862 __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
armvixl5799d6c2014-05-01 11:05:00 +01008863 __ Printf("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
armvixlad96eda2013-06-14 11:42:37 +01008864 __ Printf("%g\n", d10);
armvixl5799d6c2014-05-01 11:05:00 +01008865 __ Printf("%%%%%s%%%c%%\n", x2, w13);
8866
8867 // Print the stack pointer (sp).
8868 __ Printf("StackPointer(sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
8869 __ StackPointer(), __ StackPointer().W());
armvixlad96eda2013-06-14 11:42:37 +01008870
8871 // Test with a different stack pointer.
8872 const Register old_stack_pointer = __ StackPointer();
armvixl5799d6c2014-05-01 11:05:00 +01008873 __ Mov(x29, old_stack_pointer);
armvixlad96eda2013-06-14 11:42:37 +01008874 __ SetStackPointer(x29);
armvixl5799d6c2014-05-01 11:05:00 +01008875 // Print the stack pointer (not sp).
8876 __ Printf("StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
8877 __ StackPointer(), __ StackPointer().W());
8878 __ Mov(old_stack_pointer, __ StackPointer());
armvixlad96eda2013-06-14 11:42:37 +01008879 __ SetStackPointer(old_stack_pointer);
8880
armvixl5799d6c2014-05-01 11:05:00 +01008881 // Test with three arguments.
armvixlad96eda2013-06-14 11:42:37 +01008882 __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12);
8883
armvixl5799d6c2014-05-01 11:05:00 +01008884 // Mixed argument types.
8885 __ Printf("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
8886 w3, s1, x5, d3);
8887 __ Printf("s1: %f, d3: %f, w3: %" PRId32 ", x5: %" PRId64 "\n",
8888 s1, d3, w3, x5);
8889
armvixlad96eda2013-06-14 11:42:37 +01008890 END();
8891 RUN();
8892
8893 // We cannot easily test the output of the Printf sequences, and because
8894 // Printf preserves all registers by default, we can't look at the number of
8895 // bytes that were printed. However, the printf_no_preserve test should check
8896 // that, and here we just test that we didn't clobber any registers.
8897 ASSERT_EQUAL_REGISTERS(before);
8898
8899 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +01008900}
8901
8902
8903TEST(printf_no_preserve) {
armvixlad96eda2013-06-14 11:42:37 +01008904 SETUP();
8905 START();
8906
8907 char const * test_plain_string = "Printf with no arguments.\n";
8908 char const * test_substring = "'This is a substring.'";
8909
8910 __ PrintfNoPreserve(test_plain_string);
8911 __ Mov(x19, x0);
8912
8913 // Test simple integer arguments.
8914 __ Mov(x0, 1234);
8915 __ Mov(x1, 0x1234);
8916 __ PrintfNoPreserve("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1);
8917 __ Mov(x20, x0);
8918
8919 // Test simple floating-point arguments.
8920 __ Fmov(d0, 1.234);
8921 __ PrintfNoPreserve("d0: %f\n", d0);
8922 __ Mov(x21, x0);
8923
8924 // Test pointer (string) arguments.
8925 __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
8926 __ PrintfNoPreserve("Test %%s: %s\n", x2);
8927 __ Mov(x22, x0);
8928
8929 // Test the maximum number of arguments, and sign extension.
8930 __ Mov(w3, 0xffffffff);
8931 __ Mov(w4, 0xffffffff);
8932 __ Mov(x5, 0xffffffffffffffff);
8933 __ Mov(x6, 0xffffffffffffffff);
8934 __ PrintfNoPreserve("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n"
8935 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
8936 w3, w4, x5, x6);
8937 __ Mov(x23, x0);
8938
8939 __ Fmov(s1, 1.234);
8940 __ Fmov(s2, 2.345);
8941 __ Fmov(d3, 3.456);
8942 __ Fmov(d4, 4.567);
8943 __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
8944 __ Mov(x24, x0);
8945
8946 // Test printing callee-saved registers.
8947 __ Mov(x28, 0x123456789abcdef);
armvixl5799d6c2014-05-01 11:05:00 +01008948 __ PrintfNoPreserve("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
armvixlad96eda2013-06-14 11:42:37 +01008949 __ Mov(x25, x0);
8950
8951 __ Fmov(d10, 42.0);
8952 __ PrintfNoPreserve("%g\n", d10);
8953 __ Mov(x26, x0);
8954
8955 // Test with a different stack pointer.
8956 const Register old_stack_pointer = __ StackPointer();
8957 __ Mov(x29, old_stack_pointer);
8958 __ SetStackPointer(x29);
armvixl5799d6c2014-05-01 11:05:00 +01008959 // Print the stack pointer (not sp).
8960 __ PrintfNoPreserve(
8961 "StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
8962 __ StackPointer(), __ StackPointer().W());
armvixlad96eda2013-06-14 11:42:37 +01008963 __ Mov(x27, x0);
armvixlad96eda2013-06-14 11:42:37 +01008964 __ Mov(old_stack_pointer, __ StackPointer());
8965 __ SetStackPointer(old_stack_pointer);
8966
8967 // Test with three arguments.
8968 __ Mov(x3, 3);
8969 __ Mov(x4, 40);
8970 __ Mov(x5, 500);
8971 __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5);
8972 __ Mov(x28, x0);
8973
armvixl5799d6c2014-05-01 11:05:00 +01008974 // Mixed argument types.
8975 __ Mov(w3, 0xffffffff);
8976 __ Fmov(s1, 1.234);
8977 __ Mov(x5, 0xffffffffffffffff);
8978 __ Fmov(d3, 3.456);
8979 __ PrintfNoPreserve("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
8980 w3, s1, x5, d3);
8981 __ Mov(x29, x0);
8982
armvixlad96eda2013-06-14 11:42:37 +01008983 END();
8984 RUN();
8985
8986 // We cannot easily test the exact output of the Printf sequences, but we can
8987 // use the return code to check that the string length was correct.
8988
8989 // Printf with no arguments.
8990 ASSERT_EQUAL_64(strlen(test_plain_string), x19);
8991 // x0: 1234, x1: 0x00001234
8992 ASSERT_EQUAL_64(25, x20);
8993 // d0: 1.234000
8994 ASSERT_EQUAL_64(13, x21);
8995 // Test %s: 'This is a substring.'
8996 ASSERT_EQUAL_64(32, x22);
8997 // w3(uint32): 4294967295
8998 // w4(int32): -1
8999 // x5(uint64): 18446744073709551615
9000 // x6(int64): -1
9001 ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23);
9002 // %f: 1.234000
9003 // %g: 2.345
9004 // %e: 3.456000e+00
9005 // %E: 4.567000E+00
9006 ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24);
armvixl5799d6c2014-05-01 11:05:00 +01009007 // 0x89abcdef, 0x123456789abcdef
9008 ASSERT_EQUAL_64(30, x25);
armvixlad96eda2013-06-14 11:42:37 +01009009 // 42
9010 ASSERT_EQUAL_64(3, x26);
armvixl5799d6c2014-05-01 11:05:00 +01009011 // StackPointer(not sp): 0x00007fb037ae2370, 0x37ae2370
armvixlad96eda2013-06-14 11:42:37 +01009012 // Note: This is an example value, but the field width is fixed here so the
9013 // string length is still predictable.
armvixl5799d6c2014-05-01 11:05:00 +01009014 ASSERT_EQUAL_64(53, x27);
armvixlad96eda2013-06-14 11:42:37 +01009015 // 3=3, 4=40, 5=500
9016 ASSERT_EQUAL_64(17, x28);
armvixl5799d6c2014-05-01 11:05:00 +01009017 // w3: 4294967295, s1: 1.234000, x5: 18446744073709551615, d3: 3.456000
9018 ASSERT_EQUAL_64(69, x29);
armvixlad96eda2013-06-14 11:42:37 +01009019
9020 TEARDOWN();
armvixlad96eda2013-06-14 11:42:37 +01009021}
9022
9023
9024#ifndef USE_SIMULATOR
9025TEST(trace) {
9026 // The Trace helper should not generate any code unless the simulator (or
9027 // debugger) is being used.
9028 SETUP();
9029 START();
9030
9031 Label start;
9032 __ Bind(&start);
9033 __ Trace(LOG_ALL, TRACE_ENABLE);
9034 __ Trace(LOG_ALL, TRACE_DISABLE);
armvixlb0c8ae22014-03-21 14:03:59 +00009035 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlad96eda2013-06-14 11:42:37 +01009036
9037 END();
9038 TEARDOWN();
9039}
9040#endif
9041
9042
9043#ifndef USE_SIMULATOR
9044TEST(log) {
9045 // The Log helper should not generate any code unless the simulator (or
9046 // debugger) is being used.
9047 SETUP();
9048 START();
9049
9050 Label start;
9051 __ Bind(&start);
9052 __ Log(LOG_ALL);
armvixlb0c8ae22014-03-21 14:03:59 +00009053 VIXL_CHECK(__ SizeOfCodeGeneratedSince(&start) == 0);
armvixlad96eda2013-06-14 11:42:37 +01009054
9055 END();
9056 TEARDOWN();
9057}
9058#endif
9059
9060
9061TEST(instruction_accurate_scope) {
9062 SETUP();
9063 START();
9064
9065 // By default macro instructions are allowed.
armvixlb0c8ae22014-03-21 14:03:59 +00009066 VIXL_ASSERT(masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +01009067 {
9068 InstructionAccurateScope scope1(&masm);
armvixlb0c8ae22014-03-21 14:03:59 +00009069 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +01009070 {
9071 InstructionAccurateScope scope2(&masm);
armvixlb0c8ae22014-03-21 14:03:59 +00009072 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +01009073 }
armvixlb0c8ae22014-03-21 14:03:59 +00009074 VIXL_ASSERT(!masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +01009075 }
armvixlb0c8ae22014-03-21 14:03:59 +00009076 VIXL_ASSERT(masm.AllowMacroInstructions());
armvixlad96eda2013-06-14 11:42:37 +01009077
9078 {
9079 InstructionAccurateScope scope(&masm, 2);
9080 __ add(x0, x0, x0);
9081 __ sub(x0, x0, x0);
9082 }
9083
9084 END();
9085 RUN();
9086 TEARDOWN();
9087}
9088
9089
9090TEST(blr_lr) {
9091 // A simple test to check that the simulator correcty handle "blr lr".
9092 SETUP();
9093
9094 START();
9095 Label target;
9096 Label end;
9097
9098 __ Mov(x0, 0x0);
9099 __ Adr(lr, &target);
9100
9101 __ Blr(lr);
9102 __ Mov(x0, 0xdeadbeef);
9103 __ B(&end);
9104
9105 __ Bind(&target);
9106 __ Mov(x0, 0xc001c0de);
9107
9108 __ Bind(&end);
9109 END();
9110
9111 RUN();
9112
9113 ASSERT_EQUAL_64(0xc001c0de, x0);
9114
9115 TEARDOWN();
9116}
9117
armvixlf37fdc02014-02-05 13:22:16 +00009118
9119TEST(barriers) {
9120 // Generate all supported barriers, this is just a smoke test
9121 SETUP();
9122
9123 START();
9124
9125 // DMB
9126 __ Dmb(FullSystem, BarrierAll);
9127 __ Dmb(FullSystem, BarrierReads);
9128 __ Dmb(FullSystem, BarrierWrites);
9129 __ Dmb(FullSystem, BarrierOther);
9130
9131 __ Dmb(InnerShareable, BarrierAll);
9132 __ Dmb(InnerShareable, BarrierReads);
9133 __ Dmb(InnerShareable, BarrierWrites);
9134 __ Dmb(InnerShareable, BarrierOther);
9135
9136 __ Dmb(NonShareable, BarrierAll);
9137 __ Dmb(NonShareable, BarrierReads);
9138 __ Dmb(NonShareable, BarrierWrites);
9139 __ Dmb(NonShareable, BarrierOther);
9140
9141 __ Dmb(OuterShareable, BarrierAll);
9142 __ Dmb(OuterShareable, BarrierReads);
9143 __ Dmb(OuterShareable, BarrierWrites);
9144 __ Dmb(OuterShareable, BarrierOther);
9145
9146 // DSB
9147 __ Dsb(FullSystem, BarrierAll);
9148 __ Dsb(FullSystem, BarrierReads);
9149 __ Dsb(FullSystem, BarrierWrites);
9150 __ Dsb(FullSystem, BarrierOther);
9151
9152 __ Dsb(InnerShareable, BarrierAll);
9153 __ Dsb(InnerShareable, BarrierReads);
9154 __ Dsb(InnerShareable, BarrierWrites);
9155 __ Dsb(InnerShareable, BarrierOther);
9156
9157 __ Dsb(NonShareable, BarrierAll);
9158 __ Dsb(NonShareable, BarrierReads);
9159 __ Dsb(NonShareable, BarrierWrites);
9160 __ Dsb(NonShareable, BarrierOther);
9161
9162 __ Dsb(OuterShareable, BarrierAll);
9163 __ Dsb(OuterShareable, BarrierReads);
9164 __ Dsb(OuterShareable, BarrierWrites);
9165 __ Dsb(OuterShareable, BarrierOther);
9166
9167 // ISB
9168 __ Isb();
9169
9170 END();
9171
9172 RUN();
9173
9174 TEARDOWN();
9175}
9176
armvixlb0c8ae22014-03-21 14:03:59 +00009177
9178TEST(process_nan_double) {
9179 // Make sure that NaN propagation works correctly.
9180 double sn = rawbits_to_double(0x7ff5555511111111);
9181 double qn = rawbits_to_double(0x7ffaaaaa11111111);
9182 VIXL_ASSERT(IsSignallingNaN(sn));
9183 VIXL_ASSERT(IsQuietNaN(qn));
9184
9185 // The input NaNs after passing through ProcessNaN.
9186 double sn_proc = rawbits_to_double(0x7ffd555511111111);
9187 double qn_proc = qn;
9188 VIXL_ASSERT(IsQuietNaN(sn_proc));
9189 VIXL_ASSERT(IsQuietNaN(qn_proc));
9190
9191 SETUP();
9192 START();
9193
9194 // Execute a number of instructions which all use ProcessNaN, and check that
9195 // they all handle the NaN correctly.
9196 __ Fmov(d0, sn);
9197 __ Fmov(d10, qn);
9198
9199 // Operations that always propagate NaNs unchanged, even signalling NaNs.
9200 // - Signalling NaN
9201 __ Fmov(d1, d0);
9202 __ Fabs(d2, d0);
9203 __ Fneg(d3, d0);
9204 // - Quiet NaN
9205 __ Fmov(d11, d10);
9206 __ Fabs(d12, d10);
9207 __ Fneg(d13, d10);
9208
9209 // Operations that use ProcessNaN.
9210 // - Signalling NaN
9211 __ Fsqrt(d4, d0);
9212 __ Frinta(d5, d0);
9213 __ Frintn(d6, d0);
9214 __ Frintz(d7, d0);
9215 // - Quiet NaN
9216 __ Fsqrt(d14, d10);
9217 __ Frinta(d15, d10);
9218 __ Frintn(d16, d10);
9219 __ Frintz(d17, d10);
9220
9221 // The behaviour of fcvt is checked in TEST(fcvt_sd).
9222
9223 END();
9224 RUN();
9225
9226 uint64_t qn_raw = double_to_rawbits(qn);
9227 uint64_t sn_raw = double_to_rawbits(sn);
9228
9229 // - Signalling NaN
9230 ASSERT_EQUAL_FP64(sn, d1);
9231 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw & ~kDSignMask), d2);
9232 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw ^ kDSignMask), d3);
9233 // - Quiet NaN
9234 ASSERT_EQUAL_FP64(qn, d11);
9235 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw & ~kDSignMask), d12);
9236 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw ^ kDSignMask), d13);
9237
9238 // - Signalling NaN
9239 ASSERT_EQUAL_FP64(sn_proc, d4);
9240 ASSERT_EQUAL_FP64(sn_proc, d5);
9241 ASSERT_EQUAL_FP64(sn_proc, d6);
9242 ASSERT_EQUAL_FP64(sn_proc, d7);
9243 // - Quiet NaN
9244 ASSERT_EQUAL_FP64(qn_proc, d14);
9245 ASSERT_EQUAL_FP64(qn_proc, d15);
9246 ASSERT_EQUAL_FP64(qn_proc, d16);
9247 ASSERT_EQUAL_FP64(qn_proc, d17);
9248
9249 TEARDOWN();
9250}
9251
9252
9253TEST(process_nan_float) {
9254 // Make sure that NaN propagation works correctly.
9255 float sn = rawbits_to_float(0x7f951111);
9256 float qn = rawbits_to_float(0x7fea1111);
9257 VIXL_ASSERT(IsSignallingNaN(sn));
9258 VIXL_ASSERT(IsQuietNaN(qn));
9259
9260 // The input NaNs after passing through ProcessNaN.
9261 float sn_proc = rawbits_to_float(0x7fd51111);
9262 float qn_proc = qn;
9263 VIXL_ASSERT(IsQuietNaN(sn_proc));
9264 VIXL_ASSERT(IsQuietNaN(qn_proc));
9265
9266 SETUP();
9267 START();
9268
9269 // Execute a number of instructions which all use ProcessNaN, and check that
9270 // they all handle the NaN correctly.
9271 __ Fmov(s0, sn);
9272 __ Fmov(s10, qn);
9273
9274 // Operations that always propagate NaNs unchanged, even signalling NaNs.
9275 // - Signalling NaN
9276 __ Fmov(s1, s0);
9277 __ Fabs(s2, s0);
9278 __ Fneg(s3, s0);
9279 // - Quiet NaN
9280 __ Fmov(s11, s10);
9281 __ Fabs(s12, s10);
9282 __ Fneg(s13, s10);
9283
9284 // Operations that use ProcessNaN.
9285 // - Signalling NaN
9286 __ Fsqrt(s4, s0);
9287 __ Frinta(s5, s0);
9288 __ Frintn(s6, s0);
9289 __ Frintz(s7, s0);
9290 // - Quiet NaN
9291 __ Fsqrt(s14, s10);
9292 __ Frinta(s15, s10);
9293 __ Frintn(s16, s10);
9294 __ Frintz(s17, s10);
9295
9296 // The behaviour of fcvt is checked in TEST(fcvt_sd).
9297
9298 END();
9299 RUN();
9300
9301 uint32_t qn_raw = float_to_rawbits(qn);
9302 uint32_t sn_raw = float_to_rawbits(sn);
9303
9304 // - Signalling NaN
9305 ASSERT_EQUAL_FP32(sn, s1);
9306 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw & ~kSSignMask), s2);
9307 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw ^ kSSignMask), s3);
9308 // - Quiet NaN
9309 ASSERT_EQUAL_FP32(qn, s11);
9310 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw & ~kSSignMask), s12);
9311 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw ^ kSSignMask), s13);
9312
9313 // - Signalling NaN
9314 ASSERT_EQUAL_FP32(sn_proc, s4);
9315 ASSERT_EQUAL_FP32(sn_proc, s5);
9316 ASSERT_EQUAL_FP32(sn_proc, s6);
9317 ASSERT_EQUAL_FP32(sn_proc, s7);
9318 // - Quiet NaN
9319 ASSERT_EQUAL_FP32(qn_proc, s14);
9320 ASSERT_EQUAL_FP32(qn_proc, s15);
9321 ASSERT_EQUAL_FP32(qn_proc, s16);
9322 ASSERT_EQUAL_FP32(qn_proc, s17);
9323
9324 TEARDOWN();
9325}
9326
9327
9328static void ProcessNaNsHelper(double n, double m, double expected) {
9329 VIXL_ASSERT(isnan(n) || isnan(m));
9330 VIXL_ASSERT(isnan(expected));
9331
9332 SETUP();
9333 START();
9334
9335 // Execute a number of instructions which all use ProcessNaNs, and check that
9336 // they all propagate NaNs correctly.
9337 __ Fmov(d0, n);
9338 __ Fmov(d1, m);
9339
9340 __ Fadd(d2, d0, d1);
9341 __ Fsub(d3, d0, d1);
9342 __ Fmul(d4, d0, d1);
9343 __ Fdiv(d5, d0, d1);
9344 __ Fmax(d6, d0, d1);
9345 __ Fmin(d7, d0, d1);
9346
9347 END();
9348 RUN();
9349
9350 ASSERT_EQUAL_FP64(expected, d2);
9351 ASSERT_EQUAL_FP64(expected, d3);
9352 ASSERT_EQUAL_FP64(expected, d4);
9353 ASSERT_EQUAL_FP64(expected, d5);
9354 ASSERT_EQUAL_FP64(expected, d6);
9355 ASSERT_EQUAL_FP64(expected, d7);
9356
9357 TEARDOWN();
9358}
9359
9360
9361TEST(process_nans_double) {
9362 // Make sure that NaN propagation works correctly.
9363 double sn = rawbits_to_double(0x7ff5555511111111);
9364 double sm = rawbits_to_double(0x7ff5555522222222);
9365 double qn = rawbits_to_double(0x7ffaaaaa11111111);
9366 double qm = rawbits_to_double(0x7ffaaaaa22222222);
9367 VIXL_ASSERT(IsSignallingNaN(sn));
9368 VIXL_ASSERT(IsSignallingNaN(sm));
9369 VIXL_ASSERT(IsQuietNaN(qn));
9370 VIXL_ASSERT(IsQuietNaN(qm));
9371
9372 // The input NaNs after passing through ProcessNaN.
9373 double sn_proc = rawbits_to_double(0x7ffd555511111111);
9374 double sm_proc = rawbits_to_double(0x7ffd555522222222);
9375 double qn_proc = qn;
9376 double qm_proc = qm;
9377 VIXL_ASSERT(IsQuietNaN(sn_proc));
9378 VIXL_ASSERT(IsQuietNaN(sm_proc));
9379 VIXL_ASSERT(IsQuietNaN(qn_proc));
9380 VIXL_ASSERT(IsQuietNaN(qm_proc));
9381
9382 // Quiet NaNs are propagated.
9383 ProcessNaNsHelper(qn, 0, qn_proc);
9384 ProcessNaNsHelper(0, qm, qm_proc);
9385 ProcessNaNsHelper(qn, qm, qn_proc);
9386
9387 // Signalling NaNs are propagated, and made quiet.
9388 ProcessNaNsHelper(sn, 0, sn_proc);
9389 ProcessNaNsHelper(0, sm, sm_proc);
9390 ProcessNaNsHelper(sn, sm, sn_proc);
9391
9392 // Signalling NaNs take precedence over quiet NaNs.
9393 ProcessNaNsHelper(sn, qm, sn_proc);
9394 ProcessNaNsHelper(qn, sm, sm_proc);
9395 ProcessNaNsHelper(sn, sm, sn_proc);
9396}
9397
9398
9399static void ProcessNaNsHelper(float n, float m, float expected) {
9400 VIXL_ASSERT(isnan(n) || isnan(m));
9401 VIXL_ASSERT(isnan(expected));
9402
9403 SETUP();
9404 START();
9405
9406 // Execute a number of instructions which all use ProcessNaNs, and check that
9407 // they all propagate NaNs correctly.
9408 __ Fmov(s0, n);
9409 __ Fmov(s1, m);
9410
9411 __ Fadd(s2, s0, s1);
9412 __ Fsub(s3, s0, s1);
9413 __ Fmul(s4, s0, s1);
9414 __ Fdiv(s5, s0, s1);
9415 __ Fmax(s6, s0, s1);
9416 __ Fmin(s7, s0, s1);
9417
9418 END();
9419 RUN();
9420
9421 ASSERT_EQUAL_FP32(expected, s2);
9422 ASSERT_EQUAL_FP32(expected, s3);
9423 ASSERT_EQUAL_FP32(expected, s4);
9424 ASSERT_EQUAL_FP32(expected, s5);
9425 ASSERT_EQUAL_FP32(expected, s6);
9426 ASSERT_EQUAL_FP32(expected, s7);
9427
9428 TEARDOWN();
9429}
9430
9431
9432TEST(process_nans_float) {
9433 // Make sure that NaN propagation works correctly.
9434 float sn = rawbits_to_float(0x7f951111);
9435 float sm = rawbits_to_float(0x7f952222);
9436 float qn = rawbits_to_float(0x7fea1111);
9437 float qm = rawbits_to_float(0x7fea2222);
9438 VIXL_ASSERT(IsSignallingNaN(sn));
9439 VIXL_ASSERT(IsSignallingNaN(sm));
9440 VIXL_ASSERT(IsQuietNaN(qn));
9441 VIXL_ASSERT(IsQuietNaN(qm));
9442
9443 // The input NaNs after passing through ProcessNaN.
9444 float sn_proc = rawbits_to_float(0x7fd51111);
9445 float sm_proc = rawbits_to_float(0x7fd52222);
9446 float qn_proc = qn;
9447 float qm_proc = qm;
9448 VIXL_ASSERT(IsQuietNaN(sn_proc));
9449 VIXL_ASSERT(IsQuietNaN(sm_proc));
9450 VIXL_ASSERT(IsQuietNaN(qn_proc));
9451 VIXL_ASSERT(IsQuietNaN(qm_proc));
9452
9453 // Quiet NaNs are propagated.
9454 ProcessNaNsHelper(qn, 0, qn_proc);
9455 ProcessNaNsHelper(0, qm, qm_proc);
9456 ProcessNaNsHelper(qn, qm, qn_proc);
9457
9458 // Signalling NaNs are propagated, and made quiet.
9459 ProcessNaNsHelper(sn, 0, sn_proc);
9460 ProcessNaNsHelper(0, sm, sm_proc);
9461 ProcessNaNsHelper(sn, sm, sn_proc);
9462
9463 // Signalling NaNs take precedence over quiet NaNs.
9464 ProcessNaNsHelper(sn, qm, sn_proc);
9465 ProcessNaNsHelper(qn, sm, sm_proc);
9466 ProcessNaNsHelper(sn, sm, sn_proc);
9467}
9468
9469
9470static void DefaultNaNHelper(float n, float m, float a) {
9471 VIXL_ASSERT(isnan(n) || isnan(m) || isnan(a));
9472
9473 bool test_1op = isnan(n);
9474 bool test_2op = isnan(n) || isnan(m);
9475
9476 SETUP();
9477 START();
9478
9479 // Enable Default-NaN mode in the FPCR.
9480 __ Mrs(x0, FPCR);
9481 __ Orr(x1, x0, DN_mask);
9482 __ Msr(FPCR, x1);
9483
9484 // Execute a number of instructions which all use ProcessNaNs, and check that
9485 // they all produce the default NaN.
9486 __ Fmov(s0, n);
9487 __ Fmov(s1, m);
9488 __ Fmov(s2, a);
9489
9490 if (test_1op) {
9491 // Operations that always propagate NaNs unchanged, even signalling NaNs.
9492 __ Fmov(s10, s0);
9493 __ Fabs(s11, s0);
9494 __ Fneg(s12, s0);
9495
9496 // Operations that use ProcessNaN.
9497 __ Fsqrt(s13, s0);
9498 __ Frinta(s14, s0);
9499 __ Frintn(s15, s0);
9500 __ Frintz(s16, s0);
9501
9502 // Fcvt usually has special NaN handling, but it respects default-NaN mode.
9503 __ Fcvt(d17, s0);
9504 }
9505
9506 if (test_2op) {
9507 __ Fadd(s18, s0, s1);
9508 __ Fsub(s19, s0, s1);
9509 __ Fmul(s20, s0, s1);
9510 __ Fdiv(s21, s0, s1);
9511 __ Fmax(s22, s0, s1);
9512 __ Fmin(s23, s0, s1);
9513 }
9514
9515 __ Fmadd(s24, s0, s1, s2);
9516 __ Fmsub(s25, s0, s1, s2);
9517 __ Fnmadd(s26, s0, s1, s2);
9518 __ Fnmsub(s27, s0, s1, s2);
9519
9520 // Restore FPCR.
9521 __ Msr(FPCR, x0);
9522
9523 END();
9524 RUN();
9525
9526 if (test_1op) {
9527 uint32_t n_raw = float_to_rawbits(n);
9528 ASSERT_EQUAL_FP32(n, s10);
9529 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw & ~kSSignMask), s11);
9530 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw ^ kSSignMask), s12);
9531 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s13);
9532 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s14);
9533 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s15);
9534 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s16);
9535 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d17);
9536 }
9537
9538 if (test_2op) {
9539 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s18);
9540 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s19);
9541 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s20);
9542 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s21);
9543 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s22);
9544 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s23);
9545 }
9546
9547 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s24);
9548 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s25);
9549 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s26);
9550 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s27);
9551
9552 TEARDOWN();
9553}
9554
9555
9556TEST(default_nan_float) {
9557 float sn = rawbits_to_float(0x7f951111);
9558 float sm = rawbits_to_float(0x7f952222);
9559 float sa = rawbits_to_float(0x7f95aaaa);
9560 float qn = rawbits_to_float(0x7fea1111);
9561 float qm = rawbits_to_float(0x7fea2222);
9562 float qa = rawbits_to_float(0x7feaaaaa);
9563 VIXL_ASSERT(IsSignallingNaN(sn));
9564 VIXL_ASSERT(IsSignallingNaN(sm));
9565 VIXL_ASSERT(IsSignallingNaN(sa));
9566 VIXL_ASSERT(IsQuietNaN(qn));
9567 VIXL_ASSERT(IsQuietNaN(qm));
9568 VIXL_ASSERT(IsQuietNaN(qa));
9569
9570 // - Signalling NaNs
9571 DefaultNaNHelper(sn, 0.0f, 0.0f);
9572 DefaultNaNHelper(0.0f, sm, 0.0f);
9573 DefaultNaNHelper(0.0f, 0.0f, sa);
9574 DefaultNaNHelper(sn, sm, 0.0f);
9575 DefaultNaNHelper(0.0f, sm, sa);
9576 DefaultNaNHelper(sn, 0.0f, sa);
9577 DefaultNaNHelper(sn, sm, sa);
9578 // - Quiet NaNs
9579 DefaultNaNHelper(qn, 0.0f, 0.0f);
9580 DefaultNaNHelper(0.0f, qm, 0.0f);
9581 DefaultNaNHelper(0.0f, 0.0f, qa);
9582 DefaultNaNHelper(qn, qm, 0.0f);
9583 DefaultNaNHelper(0.0f, qm, qa);
9584 DefaultNaNHelper(qn, 0.0f, qa);
9585 DefaultNaNHelper(qn, qm, qa);
9586 // - Mixed NaNs
9587 DefaultNaNHelper(qn, sm, sa);
9588 DefaultNaNHelper(sn, qm, sa);
9589 DefaultNaNHelper(sn, sm, qa);
9590 DefaultNaNHelper(qn, qm, sa);
9591 DefaultNaNHelper(sn, qm, qa);
9592 DefaultNaNHelper(qn, sm, qa);
9593 DefaultNaNHelper(qn, qm, qa);
9594}
9595
9596
9597static void DefaultNaNHelper(double n, double m, double a) {
9598 VIXL_ASSERT(isnan(n) || isnan(m) || isnan(a));
9599
9600 bool test_1op = isnan(n);
9601 bool test_2op = isnan(n) || isnan(m);
9602
9603 SETUP();
9604 START();
9605
9606 // Enable Default-NaN mode in the FPCR.
9607 __ Mrs(x0, FPCR);
9608 __ Orr(x1, x0, DN_mask);
9609 __ Msr(FPCR, x1);
9610
9611 // Execute a number of instructions which all use ProcessNaNs, and check that
9612 // they all produce the default NaN.
9613 __ Fmov(d0, n);
9614 __ Fmov(d1, m);
9615 __ Fmov(d2, a);
9616
9617 if (test_1op) {
9618 // Operations that always propagate NaNs unchanged, even signalling NaNs.
9619 __ Fmov(d10, d0);
9620 __ Fabs(d11, d0);
9621 __ Fneg(d12, d0);
9622
9623 // Operations that use ProcessNaN.
9624 __ Fsqrt(d13, d0);
9625 __ Frinta(d14, d0);
9626 __ Frintn(d15, d0);
9627 __ Frintz(d16, d0);
9628
9629 // Fcvt usually has special NaN handling, but it respects default-NaN mode.
9630 __ Fcvt(s17, d0);
9631 }
9632
9633 if (test_2op) {
9634 __ Fadd(d18, d0, d1);
9635 __ Fsub(d19, d0, d1);
9636 __ Fmul(d20, d0, d1);
9637 __ Fdiv(d21, d0, d1);
9638 __ Fmax(d22, d0, d1);
9639 __ Fmin(d23, d0, d1);
9640 }
9641
9642 __ Fmadd(d24, d0, d1, d2);
9643 __ Fmsub(d25, d0, d1, d2);
9644 __ Fnmadd(d26, d0, d1, d2);
9645 __ Fnmsub(d27, d0, d1, d2);
9646
9647 // Restore FPCR.
9648 __ Msr(FPCR, x0);
9649
9650 END();
9651 RUN();
9652
9653 if (test_1op) {
9654 uint64_t n_raw = double_to_rawbits(n);
9655 ASSERT_EQUAL_FP64(n, d10);
9656 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw & ~kDSignMask), d11);
9657 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw ^ kDSignMask), d12);
9658 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
9659 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d14);
9660 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d15);
9661 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d16);
9662 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s17);
9663 }
9664
9665 if (test_2op) {
9666 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d18);
9667 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d19);
9668 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d20);
9669 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d21);
9670 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d22);
9671 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d23);
9672 }
9673
9674 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d24);
9675 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d25);
9676 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d26);
9677 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d27);
9678
9679 TEARDOWN();
9680}
9681
9682
9683TEST(default_nan_double) {
9684 double sn = rawbits_to_double(0x7ff5555511111111);
9685 double sm = rawbits_to_double(0x7ff5555522222222);
9686 double sa = rawbits_to_double(0x7ff55555aaaaaaaa);
9687 double qn = rawbits_to_double(0x7ffaaaaa11111111);
9688 double qm = rawbits_to_double(0x7ffaaaaa22222222);
9689 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa);
9690 VIXL_ASSERT(IsSignallingNaN(sn));
9691 VIXL_ASSERT(IsSignallingNaN(sm));
9692 VIXL_ASSERT(IsSignallingNaN(sa));
9693 VIXL_ASSERT(IsQuietNaN(qn));
9694 VIXL_ASSERT(IsQuietNaN(qm));
9695 VIXL_ASSERT(IsQuietNaN(qa));
9696
9697 // - Signalling NaNs
9698 DefaultNaNHelper(sn, 0.0, 0.0);
9699 DefaultNaNHelper(0.0, sm, 0.0);
9700 DefaultNaNHelper(0.0, 0.0, sa);
9701 DefaultNaNHelper(sn, sm, 0.0);
9702 DefaultNaNHelper(0.0, sm, sa);
9703 DefaultNaNHelper(sn, 0.0, sa);
9704 DefaultNaNHelper(sn, sm, sa);
9705 // - Quiet NaNs
9706 DefaultNaNHelper(qn, 0.0, 0.0);
9707 DefaultNaNHelper(0.0, qm, 0.0);
9708 DefaultNaNHelper(0.0, 0.0, qa);
9709 DefaultNaNHelper(qn, qm, 0.0);
9710 DefaultNaNHelper(0.0, qm, qa);
9711 DefaultNaNHelper(qn, 0.0, qa);
9712 DefaultNaNHelper(qn, qm, qa);
9713 // - Mixed NaNs
9714 DefaultNaNHelper(qn, sm, sa);
9715 DefaultNaNHelper(sn, qm, sa);
9716 DefaultNaNHelper(sn, sm, qa);
9717 DefaultNaNHelper(qn, qm, sa);
9718 DefaultNaNHelper(sn, qm, qa);
9719 DefaultNaNHelper(qn, sm, qa);
9720 DefaultNaNHelper(qn, qm, qa);
9721}
9722
9723
armvixl4a102ba2014-07-14 09:02:40 +01009724TEST(ldar_stlr) {
9725 // The middle value is read, modified, and written. The padding exists only to
9726 // check for over-write.
9727 uint8_t b[] = {0, 0x12, 0};
9728 uint16_t h[] = {0, 0x1234, 0};
9729 uint32_t w[] = {0, 0x12345678, 0};
9730 uint64_t x[] = {0, 0x123456789abcdef0, 0};
9731
9732 SETUP();
9733 START();
9734
9735 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
9736 __ Ldarb(w0, MemOperand(x10));
9737 __ Add(w0, w0, 1);
9738 __ Stlrb(w0, MemOperand(x10));
9739
9740 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
9741 __ Ldarh(w0, MemOperand(x10));
9742 __ Add(w0, w0, 1);
9743 __ Stlrh(w0, MemOperand(x10));
9744
9745 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
9746 __ Ldar(w0, MemOperand(x10));
9747 __ Add(w0, w0, 1);
9748 __ Stlr(w0, MemOperand(x10));
9749
9750 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
9751 __ Ldar(x0, MemOperand(x10));
9752 __ Add(x0, x0, 1);
9753 __ Stlr(x0, MemOperand(x10));
9754
9755 END();
9756 RUN();
9757
9758 ASSERT_EQUAL_32(0x13, b[1]);
9759 ASSERT_EQUAL_32(0x1235, h[1]);
9760 ASSERT_EQUAL_32(0x12345679, w[1]);
9761 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
9762
9763 // Check for over-write.
9764 ASSERT_EQUAL_32(0, b[0]);
9765 ASSERT_EQUAL_32(0, b[2]);
9766 ASSERT_EQUAL_32(0, h[0]);
9767 ASSERT_EQUAL_32(0, h[2]);
9768 ASSERT_EQUAL_32(0, w[0]);
9769 ASSERT_EQUAL_32(0, w[2]);
9770 ASSERT_EQUAL_32(0, x[0]);
9771 ASSERT_EQUAL_32(0, x[2]);
9772
9773 TEARDOWN();
9774}
9775
9776
9777TEST(ldxr_stxr) {
9778 // The middle value is read, modified, and written. The padding exists only to
9779 // check for over-write.
9780 uint8_t b[] = {0, 0x12, 0};
9781 uint16_t h[] = {0, 0x1234, 0};
9782 uint32_t w[] = {0, 0x12345678, 0};
9783 uint64_t x[] = {0, 0x123456789abcdef0, 0};
9784
9785 // As above, but get suitably-aligned values for ldxp and stxp.
9786 uint32_t wp_data[] = {0, 0, 0, 0, 0};
9787 uint32_t * wp = AlignUp(wp_data + 1, kWRegSizeInBytes * 2) - 1;
9788 wp[1] = 0x12345678; // wp[1] is 64-bit-aligned.
9789 wp[2] = 0x87654321;
9790 uint64_t xp_data[] = {0, 0, 0, 0, 0};
9791 uint64_t * xp = AlignUp(xp_data + 1, kXRegSizeInBytes * 2) - 1;
9792 xp[1] = 0x123456789abcdef0; // xp[1] is 128-bit-aligned.
9793 xp[2] = 0x0fedcba987654321;
9794
9795 SETUP();
9796 START();
9797
9798 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
9799 Label try_b;
9800 __ Bind(&try_b);
9801 __ Ldxrb(w0, MemOperand(x10));
9802 __ Add(w0, w0, 1);
9803 __ Stxrb(w5, w0, MemOperand(x10));
9804 __ Cbnz(w5, &try_b);
9805
9806 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
9807 Label try_h;
9808 __ Bind(&try_h);
9809 __ Ldxrh(w0, MemOperand(x10));
9810 __ Add(w0, w0, 1);
9811 __ Stxrh(w5, w0, MemOperand(x10));
9812 __ Cbnz(w5, &try_h);
9813
9814 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
9815 Label try_w;
9816 __ Bind(&try_w);
9817 __ Ldxr(w0, MemOperand(x10));
9818 __ Add(w0, w0, 1);
9819 __ Stxr(w5, w0, MemOperand(x10));
9820 __ Cbnz(w5, &try_w);
9821
9822 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
9823 Label try_x;
9824 __ Bind(&try_x);
9825 __ Ldxr(x0, MemOperand(x10));
9826 __ Add(x0, x0, 1);
9827 __ Stxr(w5, x0, MemOperand(x10));
9828 __ Cbnz(w5, &try_x);
9829
9830 __ Mov(x10, reinterpret_cast<uintptr_t>(&wp[1]));
9831 Label try_wp;
9832 __ Bind(&try_wp);
9833 __ Ldxp(w0, w1, MemOperand(x10));
9834 __ Add(w0, w0, 1);
9835 __ Add(w1, w1, 1);
9836 __ Stxp(w5, w0, w1, MemOperand(x10));
9837 __ Cbnz(w5, &try_wp);
9838
9839 __ Mov(x10, reinterpret_cast<uintptr_t>(&xp[1]));
9840 Label try_xp;
9841 __ Bind(&try_xp);
9842 __ Ldxp(x0, x1, MemOperand(x10));
9843 __ Add(x0, x0, 1);
9844 __ Add(x1, x1, 1);
9845 __ Stxp(w5, x0, x1, MemOperand(x10));
9846 __ Cbnz(w5, &try_xp);
9847
9848 END();
9849 RUN();
9850
9851 ASSERT_EQUAL_32(0x13, b[1]);
9852 ASSERT_EQUAL_32(0x1235, h[1]);
9853 ASSERT_EQUAL_32(0x12345679, w[1]);
9854 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
9855 ASSERT_EQUAL_32(0x12345679, wp[1]);
9856 ASSERT_EQUAL_32(0x87654322, wp[2]);
9857 ASSERT_EQUAL_64(0x123456789abcdef1, xp[1]);
9858 ASSERT_EQUAL_64(0x0fedcba987654322, xp[2]);
9859
9860 // Check for over-write.
9861 ASSERT_EQUAL_32(0, b[0]);
9862 ASSERT_EQUAL_32(0, b[2]);
9863 ASSERT_EQUAL_32(0, h[0]);
9864 ASSERT_EQUAL_32(0, h[2]);
9865 ASSERT_EQUAL_32(0, w[0]);
9866 ASSERT_EQUAL_32(0, w[2]);
9867 ASSERT_EQUAL_64(0, x[0]);
9868 ASSERT_EQUAL_64(0, x[2]);
9869 ASSERT_EQUAL_32(0, wp[0]);
9870 ASSERT_EQUAL_32(0, wp[3]);
9871 ASSERT_EQUAL_64(0, xp[0]);
9872 ASSERT_EQUAL_64(0, xp[3]);
9873
9874 TEARDOWN();
9875}
9876
9877
9878TEST(ldaxr_stlxr) {
9879 // The middle value is read, modified, and written. The padding exists only to
9880 // check for over-write.
9881 uint8_t b[] = {0, 0x12, 0};
9882 uint16_t h[] = {0, 0x1234, 0};
9883 uint32_t w[] = {0, 0x12345678, 0};
9884 uint64_t x[] = {0, 0x123456789abcdef0, 0};
9885
9886 // As above, but get suitably-aligned values for ldxp and stxp.
9887 uint32_t wp_data[] = {0, 0, 0, 0, 0};
9888 uint32_t * wp = AlignUp(wp_data + 1, kWRegSizeInBytes * 2) - 1;
9889 wp[1] = 0x12345678; // wp[1] is 64-bit-aligned.
9890 wp[2] = 0x87654321;
9891 uint64_t xp_data[] = {0, 0, 0, 0, 0};
9892 uint64_t * xp = AlignUp(xp_data + 1, kXRegSizeInBytes * 2) - 1;
9893 xp[1] = 0x123456789abcdef0; // xp[1] is 128-bit-aligned.
9894 xp[2] = 0x0fedcba987654321;
9895
9896 SETUP();
9897 START();
9898
9899 __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
9900 Label try_b;
9901 __ Bind(&try_b);
9902 __ Ldaxrb(w0, MemOperand(x10));
9903 __ Add(w0, w0, 1);
9904 __ Stlxrb(w5, w0, MemOperand(x10));
9905 __ Cbnz(w5, &try_b);
9906
9907 __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
9908 Label try_h;
9909 __ Bind(&try_h);
9910 __ Ldaxrh(w0, MemOperand(x10));
9911 __ Add(w0, w0, 1);
9912 __ Stlxrh(w5, w0, MemOperand(x10));
9913 __ Cbnz(w5, &try_h);
9914
9915 __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
9916 Label try_w;
9917 __ Bind(&try_w);
9918 __ Ldaxr(w0, MemOperand(x10));
9919 __ Add(w0, w0, 1);
9920 __ Stlxr(w5, w0, MemOperand(x10));
9921 __ Cbnz(w5, &try_w);
9922
9923 __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
9924 Label try_x;
9925 __ Bind(&try_x);
9926 __ Ldaxr(x0, MemOperand(x10));
9927 __ Add(x0, x0, 1);
9928 __ Stlxr(w5, x0, MemOperand(x10));
9929 __ Cbnz(w5, &try_x);
9930
9931 __ Mov(x10, reinterpret_cast<uintptr_t>(&wp[1]));
9932 Label try_wp;
9933 __ Bind(&try_wp);
9934 __ Ldaxp(w0, w1, MemOperand(x10));
9935 __ Add(w0, w0, 1);
9936 __ Add(w1, w1, 1);
9937 __ Stlxp(w5, w0, w1, MemOperand(x10));
9938 __ Cbnz(w5, &try_wp);
9939
9940 __ Mov(x10, reinterpret_cast<uintptr_t>(&xp[1]));
9941 Label try_xp;
9942 __ Bind(&try_xp);
9943 __ Ldaxp(x0, x1, MemOperand(x10));
9944 __ Add(x0, x0, 1);
9945 __ Add(x1, x1, 1);
9946 __ Stlxp(w5, x0, x1, MemOperand(x10));
9947 __ Cbnz(w5, &try_xp);
9948
9949 END();
9950 RUN();
9951
9952 ASSERT_EQUAL_32(0x13, b[1]);
9953 ASSERT_EQUAL_32(0x1235, h[1]);
9954 ASSERT_EQUAL_32(0x12345679, w[1]);
9955 ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
9956 ASSERT_EQUAL_32(0x12345679, wp[1]);
9957 ASSERT_EQUAL_32(0x87654322, wp[2]);
9958 ASSERT_EQUAL_64(0x123456789abcdef1, xp[1]);
9959 ASSERT_EQUAL_64(0x0fedcba987654322, xp[2]);
9960
9961 // Check for over-write.
9962 ASSERT_EQUAL_32(0, b[0]);
9963 ASSERT_EQUAL_32(0, b[2]);
9964 ASSERT_EQUAL_32(0, h[0]);
9965 ASSERT_EQUAL_32(0, h[2]);
9966 ASSERT_EQUAL_32(0, w[0]);
9967 ASSERT_EQUAL_32(0, w[2]);
9968 ASSERT_EQUAL_64(0, x[0]);
9969 ASSERT_EQUAL_64(0, x[2]);
9970 ASSERT_EQUAL_32(0, wp[0]);
9971 ASSERT_EQUAL_32(0, wp[3]);
9972 ASSERT_EQUAL_64(0, xp[0]);
9973 ASSERT_EQUAL_64(0, xp[3]);
9974
9975 TEARDOWN();
9976}
9977
9978
9979TEST(clrex) {
9980 // This data should never be written.
9981 uint64_t data[] = {0, 0, 0};
9982 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
9983
9984 SETUP();
9985 START();
9986
9987 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
9988 __ Mov(w6, 0);
9989
9990 __ Ldxrb(w0, MemOperand(x10));
9991 __ Clrex();
9992 __ Add(w0, w0, 1);
9993 __ Stxrb(w5, w0, MemOperand(x10));
9994 __ Add(w6, w6, w5);
9995
9996 __ Ldxrh(w0, MemOperand(x10));
9997 __ Clrex();
9998 __ Add(w0, w0, 1);
9999 __ Stxrh(w5, w0, MemOperand(x10));
10000 __ Add(w6, w6, w5);
10001
10002 __ Ldxr(w0, MemOperand(x10));
10003 __ Clrex();
10004 __ Add(w0, w0, 1);
10005 __ Stxr(w5, w0, MemOperand(x10));
10006 __ Add(w6, w6, w5);
10007
10008 __ Ldxr(x0, MemOperand(x10));
10009 __ Clrex();
10010 __ Add(x0, x0, 1);
10011 __ Stxr(w5, x0, MemOperand(x10));
10012 __ Add(w6, w6, w5);
10013
10014 __ Ldxp(w0, w1, MemOperand(x10));
10015 __ Clrex();
10016 __ Add(w0, w0, 1);
10017 __ Add(w1, w1, 1);
10018 __ Stxp(w5, w0, w1, MemOperand(x10));
10019 __ Add(w6, w6, w5);
10020
10021 __ Ldxp(x0, x1, MemOperand(x10));
10022 __ Clrex();
10023 __ Add(x0, x0, 1);
10024 __ Add(x1, x1, 1);
10025 __ Stxp(w5, x0, x1, MemOperand(x10));
10026 __ Add(w6, w6, w5);
10027
10028 // Acquire-release variants.
10029
10030 __ Ldaxrb(w0, MemOperand(x10));
10031 __ Clrex();
10032 __ Add(w0, w0, 1);
10033 __ Stlxrb(w5, w0, MemOperand(x10));
10034 __ Add(w6, w6, w5);
10035
10036 __ Ldaxrh(w0, MemOperand(x10));
10037 __ Clrex();
10038 __ Add(w0, w0, 1);
10039 __ Stlxrh(w5, w0, MemOperand(x10));
10040 __ Add(w6, w6, w5);
10041
10042 __ Ldaxr(w0, MemOperand(x10));
10043 __ Clrex();
10044 __ Add(w0, w0, 1);
10045 __ Stlxr(w5, w0, MemOperand(x10));
10046 __ Add(w6, w6, w5);
10047
10048 __ Ldaxr(x0, MemOperand(x10));
10049 __ Clrex();
10050 __ Add(x0, x0, 1);
10051 __ Stlxr(w5, x0, MemOperand(x10));
10052 __ Add(w6, w6, w5);
10053
10054 __ Ldaxp(w0, w1, MemOperand(x10));
10055 __ Clrex();
10056 __ Add(w0, w0, 1);
10057 __ Add(w1, w1, 1);
10058 __ Stlxp(w5, w0, w1, MemOperand(x10));
10059 __ Add(w6, w6, w5);
10060
10061 __ Ldaxp(x0, x1, MemOperand(x10));
10062 __ Clrex();
10063 __ Add(x0, x0, 1);
10064 __ Add(x1, x1, 1);
10065 __ Stlxp(w5, x0, x1, MemOperand(x10));
10066 __ Add(w6, w6, w5);
10067
10068 END();
10069 RUN();
10070
10071 // None of the 12 store-exclusives should have succeeded.
10072 ASSERT_EQUAL_32(12, w6);
10073
10074 ASSERT_EQUAL_64(0, data[0]);
10075 ASSERT_EQUAL_64(0, data[1]);
10076 ASSERT_EQUAL_64(0, data[2]);
10077}
10078
10079
10080#ifdef USE_SIMULATOR
10081// Check that the simulator occasionally makes store-exclusive fail.
10082TEST(ldxr_stxr_fail) {
10083 uint64_t data[] = {0, 0, 0};
10084 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
10085
10086 // Impose a hard limit on the number of attempts, so the test cannot hang.
10087 static const uint64_t kWatchdog = 10000;
10088 Label done;
10089
10090 SETUP();
10091 START();
10092
10093 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
10094 __ Mov(x11, kWatchdog);
10095
10096 // This loop is the opposite of what we normally do with ldxr and stxr; we
10097 // keep trying until we fail (or the watchdog counter runs out).
10098 Label try_b;
10099 __ Bind(&try_b);
10100 __ Ldxrb(w0, MemOperand(x10));
10101 __ Stxrb(w5, w0, MemOperand(x10));
10102 // Check the watchdog counter.
10103 __ Sub(x11, x11, 1);
10104 __ Cbz(x11, &done);
10105 // Check the exclusive-store result.
10106 __ Cbz(w5, &try_b);
10107
10108 Label try_h;
10109 __ Bind(&try_h);
10110 __ Ldxrh(w0, MemOperand(x10));
10111 __ Stxrh(w5, w0, MemOperand(x10));
10112 __ Sub(x11, x11, 1);
10113 __ Cbz(x11, &done);
10114 __ Cbz(w5, &try_h);
10115
10116 Label try_w;
10117 __ Bind(&try_w);
10118 __ Ldxr(w0, MemOperand(x10));
10119 __ Stxr(w5, w0, MemOperand(x10));
10120 __ Sub(x11, x11, 1);
10121 __ Cbz(x11, &done);
10122 __ Cbz(w5, &try_w);
10123
10124 Label try_x;
10125 __ Bind(&try_x);
10126 __ Ldxr(x0, MemOperand(x10));
10127 __ Stxr(w5, x0, MemOperand(x10));
10128 __ Sub(x11, x11, 1);
10129 __ Cbz(x11, &done);
10130 __ Cbz(w5, &try_x);
10131
10132 Label try_wp;
10133 __ Bind(&try_wp);
10134 __ Ldxp(w0, w1, MemOperand(x10));
10135 __ Stxp(w5, w0, w1, MemOperand(x10));
10136 __ Sub(x11, x11, 1);
10137 __ Cbz(x11, &done);
10138 __ Cbz(w5, &try_wp);
10139
10140 Label try_xp;
10141 __ Bind(&try_xp);
10142 __ Ldxp(x0, x1, MemOperand(x10));
10143 __ Stxp(w5, x0, x1, MemOperand(x10));
10144 __ Sub(x11, x11, 1);
10145 __ Cbz(x11, &done);
10146 __ Cbz(w5, &try_xp);
10147
10148 __ Bind(&done);
10149 // Trigger an error if x11 (watchdog) is zero.
10150 __ Cmp(x11, 0);
10151 __ Cset(x12, eq);
10152
10153 END();
10154 RUN();
10155
10156 // Check that the watchdog counter didn't run out.
10157 ASSERT_EQUAL_64(0, x12);
10158}
10159#endif
10160
10161
10162#ifdef USE_SIMULATOR
10163// Check that the simulator occasionally makes store-exclusive fail.
10164TEST(ldaxr_stlxr_fail) {
10165 uint64_t data[] = {0, 0, 0};
10166 uint64_t * data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
10167
10168 // Impose a hard limit on the number of attempts, so the test cannot hang.
10169 static const uint64_t kWatchdog = 10000;
10170 Label done;
10171
10172 SETUP();
10173 START();
10174
10175 __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
10176 __ Mov(x11, kWatchdog);
10177
10178 // This loop is the opposite of what we normally do with ldxr and stxr; we
10179 // keep trying until we fail (or the watchdog counter runs out).
10180 Label try_b;
10181 __ Bind(&try_b);
10182 __ Ldxrb(w0, MemOperand(x10));
10183 __ Stxrb(w5, w0, MemOperand(x10));
10184 // Check the watchdog counter.
10185 __ Sub(x11, x11, 1);
10186 __ Cbz(x11, &done);
10187 // Check the exclusive-store result.
10188 __ Cbz(w5, &try_b);
10189
10190 Label try_h;
10191 __ Bind(&try_h);
10192 __ Ldaxrh(w0, MemOperand(x10));
10193 __ Stlxrh(w5, w0, MemOperand(x10));
10194 __ Sub(x11, x11, 1);
10195 __ Cbz(x11, &done);
10196 __ Cbz(w5, &try_h);
10197
10198 Label try_w;
10199 __ Bind(&try_w);
10200 __ Ldaxr(w0, MemOperand(x10));
10201 __ Stlxr(w5, w0, MemOperand(x10));
10202 __ Sub(x11, x11, 1);
10203 __ Cbz(x11, &done);
10204 __ Cbz(w5, &try_w);
10205
10206 Label try_x;
10207 __ Bind(&try_x);
10208 __ Ldaxr(x0, MemOperand(x10));
10209 __ Stlxr(w5, x0, MemOperand(x10));
10210 __ Sub(x11, x11, 1);
10211 __ Cbz(x11, &done);
10212 __ Cbz(w5, &try_x);
10213
10214 Label try_wp;
10215 __ Bind(&try_wp);
10216 __ Ldaxp(w0, w1, MemOperand(x10));
10217 __ Stlxp(w5, w0, w1, MemOperand(x10));
10218 __ Sub(x11, x11, 1);
10219 __ Cbz(x11, &done);
10220 __ Cbz(w5, &try_wp);
10221
10222 Label try_xp;
10223 __ Bind(&try_xp);
10224 __ Ldaxp(x0, x1, MemOperand(x10));
10225 __ Stlxp(w5, x0, x1, MemOperand(x10));
10226 __ Sub(x11, x11, 1);
10227 __ Cbz(x11, &done);
10228 __ Cbz(w5, &try_xp);
10229
10230 __ Bind(&done);
10231 // Trigger an error if x11 (watchdog) is zero.
10232 __ Cmp(x11, 0);
10233 __ Cset(x12, eq);
10234
10235 END();
10236 RUN();
10237
10238 // Check that the watchdog counter didn't run out.
10239 ASSERT_EQUAL_64(0, x12);
10240}
10241#endif
10242
10243
10244TEST(load_store_tagged_immediate_offset) {
10245 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
10246 int tag_count = sizeof(tags) / sizeof(tags[0]);
10247
10248 const int kMaxDataLength = 128;
10249
10250 for (int i = 0; i < tag_count; i++) {
10251 unsigned char src[kMaxDataLength];
10252 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
10253 uint64_t src_tag = tags[i];
10254 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
10255
10256 for (int k = 0; k < kMaxDataLength; k++) {
10257 src[k] = k + 1;
10258 }
10259
10260 for (int j = 0; j < tag_count; j++) {
10261 unsigned char dst[kMaxDataLength];
10262 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
10263 uint64_t dst_tag = tags[j];
10264 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
10265
10266 memset(dst, 0, kMaxDataLength);
10267
10268 SETUP();
10269 START();
10270
10271 __ Mov(x0, src_tagged);
10272 __ Mov(x1, dst_tagged);
10273
10274 int offset = 0;
10275
10276 // Scaled-immediate offsets.
10277
10278 __ ldp(x2, x3, MemOperand(x0, offset));
10279 __ stp(x2, x3, MemOperand(x1, offset));
10280 offset += 2 * kXRegSizeInBytes;
10281
10282 __ ldpsw(x2, x3, MemOperand(x0, offset));
10283 __ stp(w2, w3, MemOperand(x1, offset));
10284 offset += 2 * kWRegSizeInBytes;
10285
10286 __ ldp(d0, d1, MemOperand(x0, offset));
10287 __ stp(d0, d1, MemOperand(x1, offset));
10288 offset += 2 * kDRegSizeInBytes;
10289
10290 __ ldp(w2, w3, MemOperand(x0, offset));
10291 __ stp(w2, w3, MemOperand(x1, offset));
10292 offset += 2 * kWRegSizeInBytes;
10293
10294 __ ldp(s0, s1, MemOperand(x0, offset));
10295 __ stp(s0, s1, MemOperand(x1, offset));
10296 offset += 2 * kSRegSizeInBytes;
10297
10298 __ ldr(x2, MemOperand(x0, offset), RequireScaledOffset);
10299 __ str(x2, MemOperand(x1, offset), RequireScaledOffset);
10300 offset += kXRegSizeInBytes;
10301
10302 __ ldr(d0, MemOperand(x0, offset), RequireScaledOffset);
10303 __ str(d0, MemOperand(x1, offset), RequireScaledOffset);
10304 offset += kDRegSizeInBytes;
10305
10306 __ ldr(w2, MemOperand(x0, offset), RequireScaledOffset);
10307 __ str(w2, MemOperand(x1, offset), RequireScaledOffset);
10308 offset += kWRegSizeInBytes;
10309
10310 __ ldr(s0, MemOperand(x0, offset), RequireScaledOffset);
10311 __ str(s0, MemOperand(x1, offset), RequireScaledOffset);
10312 offset += kSRegSizeInBytes;
10313
10314 __ ldrh(w2, MemOperand(x0, offset), RequireScaledOffset);
10315 __ strh(w2, MemOperand(x1, offset), RequireScaledOffset);
10316 offset += 2;
10317
10318 __ ldrsh(w2, MemOperand(x0, offset), RequireScaledOffset);
10319 __ strh(w2, MemOperand(x1, offset), RequireScaledOffset);
10320 offset += 2;
10321
10322 __ ldrb(w2, MemOperand(x0, offset), RequireScaledOffset);
10323 __ strb(w2, MemOperand(x1, offset), RequireScaledOffset);
10324 offset += 1;
10325
10326 __ ldrsb(w2, MemOperand(x0, offset), RequireScaledOffset);
10327 __ strb(w2, MemOperand(x1, offset), RequireScaledOffset);
10328 offset += 1;
10329
10330 // Unscaled-immediate offsets.
10331
10332 __ ldur(x2, MemOperand(x0, offset), RequireUnscaledOffset);
10333 __ stur(x2, MemOperand(x1, offset), RequireUnscaledOffset);
10334 offset += kXRegSizeInBytes;
10335
10336 __ ldur(d0, MemOperand(x0, offset), RequireUnscaledOffset);
10337 __ stur(d0, MemOperand(x1, offset), RequireUnscaledOffset);
10338 offset += kDRegSizeInBytes;
10339
10340 __ ldur(w2, MemOperand(x0, offset), RequireUnscaledOffset);
10341 __ stur(w2, MemOperand(x1, offset), RequireUnscaledOffset);
10342 offset += kWRegSizeInBytes;
10343
10344 __ ldur(s0, MemOperand(x0, offset), RequireUnscaledOffset);
10345 __ stur(s0, MemOperand(x1, offset), RequireUnscaledOffset);
10346 offset += kSRegSizeInBytes;
10347
10348 __ ldurh(w2, MemOperand(x0, offset), RequireUnscaledOffset);
10349 __ sturh(w2, MemOperand(x1, offset), RequireUnscaledOffset);
10350 offset += 2;
10351
10352 __ ldursh(w2, MemOperand(x0, offset), RequireUnscaledOffset);
10353 __ sturh(w2, MemOperand(x1, offset), RequireUnscaledOffset);
10354 offset += 2;
10355
10356 __ ldurb(w2, MemOperand(x0, offset), RequireUnscaledOffset);
10357 __ sturb(w2, MemOperand(x1, offset), RequireUnscaledOffset);
10358 offset += 1;
10359
10360 __ ldursb(w2, MemOperand(x0, offset), RequireUnscaledOffset);
10361 __ sturb(w2, MemOperand(x1, offset), RequireUnscaledOffset);
10362 offset += 1;
10363
10364 // Extract the tag (so we can test that it was preserved correctly).
10365 __ Ubfx(x0, x0, kAddressTagOffset, kAddressTagWidth);
10366 __ Ubfx(x1, x1, kAddressTagOffset, kAddressTagWidth);
10367
10368 VIXL_ASSERT(kMaxDataLength >= offset);
10369
10370 END();
10371 RUN();
10372
10373 ASSERT_EQUAL_64(src_tag, x0);
10374 ASSERT_EQUAL_64(dst_tag, x1);
10375
10376 for (int k = 0; k < offset; k++) {
10377 VIXL_CHECK(src[k] == dst[k]);
10378 }
10379
10380 TEARDOWN();
10381 }
10382 }
10383}
10384
10385
10386TEST(load_store_tagged_immediate_preindex) {
10387 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
10388 int tag_count = sizeof(tags) / sizeof(tags[0]);
10389
10390 const int kMaxDataLength = 128;
10391
10392 for (int i = 0; i < tag_count; i++) {
10393 unsigned char src[kMaxDataLength];
10394 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
10395 uint64_t src_tag = tags[i];
10396 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
10397
10398 for (int k = 0; k < kMaxDataLength; k++) {
10399 src[k] = k + 1;
10400 }
10401
10402 for (int j = 0; j < tag_count; j++) {
10403 unsigned char dst[kMaxDataLength];
10404 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
10405 uint64_t dst_tag = tags[j];
10406 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
10407
10408 for (int k = 0; k < kMaxDataLength; k++) {
10409 dst[k] = 0;
10410 }
10411
10412 SETUP();
10413 START();
10414
10415 // Each MemOperand must apply a pre-index equal to the size of the
10416 // previous access.
10417
10418 // Start with a non-zero preindex.
10419 int preindex = 63 * kXRegSizeInBytes;
10420
10421 __ Mov(x0, src_tagged - preindex);
10422 __ Mov(x1, dst_tagged - preindex);
10423
10424 __ ldp(x2, x3, MemOperand(x0, preindex, PreIndex));
10425 __ stp(x2, x3, MemOperand(x1, preindex, PreIndex));
10426 preindex = 2 * kXRegSizeInBytes;
10427 int data_length = preindex;
10428
10429 __ ldpsw(x2, x3, MemOperand(x0, preindex, PreIndex));
10430 __ stp(w2, w3, MemOperand(x1, preindex, PreIndex));
10431 preindex = 2 * kWRegSizeInBytes;
10432 data_length += preindex;
10433
10434 __ ldp(d0, d1, MemOperand(x0, preindex, PreIndex));
10435 __ stp(d0, d1, MemOperand(x1, preindex, PreIndex));
10436 preindex = 2 * kDRegSizeInBytes;
10437 data_length += preindex;
10438
10439 __ ldp(w2, w3, MemOperand(x0, preindex, PreIndex));
10440 __ stp(w2, w3, MemOperand(x1, preindex, PreIndex));
10441 preindex = 2 * kWRegSizeInBytes;
10442 data_length += preindex;
10443
10444 __ ldp(s0, s1, MemOperand(x0, preindex, PreIndex));
10445 __ stp(s0, s1, MemOperand(x1, preindex, PreIndex));
10446 preindex = 2 * kSRegSizeInBytes;
10447 data_length += preindex;
10448
10449 __ ldr(x2, MemOperand(x0, preindex, PreIndex));
10450 __ str(x2, MemOperand(x1, preindex, PreIndex));
10451 preindex = kXRegSizeInBytes;
10452 data_length += preindex;
10453
10454 __ ldr(d0, MemOperand(x0, preindex, PreIndex));
10455 __ str(d0, MemOperand(x1, preindex, PreIndex));
10456 preindex = kDRegSizeInBytes;
10457 data_length += preindex;
10458
10459 __ ldr(w2, MemOperand(x0, preindex, PreIndex));
10460 __ str(w2, MemOperand(x1, preindex, PreIndex));
10461 preindex = kWRegSizeInBytes;
10462 data_length += preindex;
10463
10464 __ ldr(s0, MemOperand(x0, preindex, PreIndex));
10465 __ str(s0, MemOperand(x1, preindex, PreIndex));
10466 preindex = kSRegSizeInBytes;
10467 data_length += preindex;
10468
10469 __ ldrh(w2, MemOperand(x0, preindex, PreIndex));
10470 __ strh(w2, MemOperand(x1, preindex, PreIndex));
10471 preindex = 2;
10472 data_length += preindex;
10473
10474 __ ldrsh(w2, MemOperand(x0, preindex, PreIndex));
10475 __ strh(w2, MemOperand(x1, preindex, PreIndex));
10476 preindex = 2;
10477 data_length += preindex;
10478
10479 __ ldrb(w2, MemOperand(x0, preindex, PreIndex));
10480 __ strb(w2, MemOperand(x1, preindex, PreIndex));
10481 preindex = 1;
10482 data_length += preindex;
10483
10484 __ ldrsb(w2, MemOperand(x0, preindex, PreIndex));
10485 __ strb(w2, MemOperand(x1, preindex, PreIndex));
10486 preindex = 1;
10487 data_length += preindex;
10488
10489 VIXL_ASSERT(kMaxDataLength >= data_length);
10490
10491 END();
10492 RUN();
10493
10494 // Check that the preindex was correctly applied in each operation, and
10495 // that the tag was preserved.
10496 ASSERT_EQUAL_64(src_tagged + data_length - preindex, x0);
10497 ASSERT_EQUAL_64(dst_tagged + data_length - preindex, x1);
10498
10499 for (int k = 0; k < data_length; k++) {
10500 VIXL_CHECK(src[k] == dst[k]);
10501 }
10502
10503 TEARDOWN();
10504 }
10505 }
10506}
10507
10508
10509TEST(load_store_tagged_immediate_postindex) {
10510 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
10511 int tag_count = sizeof(tags) / sizeof(tags[0]);
10512
10513 const int kMaxDataLength = 128;
10514
10515 for (int i = 0; i < tag_count; i++) {
10516 unsigned char src[kMaxDataLength];
10517 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
10518 uint64_t src_tag = tags[i];
10519 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
10520
10521 for (int k = 0; k < kMaxDataLength; k++) {
10522 src[k] = k + 1;
10523 }
10524
10525 for (int j = 0; j < tag_count; j++) {
10526 unsigned char dst[kMaxDataLength];
10527 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
10528 uint64_t dst_tag = tags[j];
10529 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
10530
10531 for (int k = 0; k < kMaxDataLength; k++) {
10532 dst[k] = 0;
10533 }
10534
10535 SETUP();
10536 START();
10537
10538 __ Mov(x0, src_tagged);
10539 __ Mov(x1, dst_tagged);
10540
10541 int postindex = 2 * kXRegSizeInBytes;
10542 __ ldp(x2, x3, MemOperand(x0, postindex, PostIndex));
10543 __ stp(x2, x3, MemOperand(x1, postindex, PostIndex));
10544 int data_length = postindex;
10545
10546 postindex = 2 * kWRegSizeInBytes;
10547 __ ldpsw(x2, x3, MemOperand(x0, postindex, PostIndex));
10548 __ stp(w2, w3, MemOperand(x1, postindex, PostIndex));
10549 data_length += postindex;
10550
10551 postindex = 2 * kDRegSizeInBytes;
10552 __ ldp(d0, d1, MemOperand(x0, postindex, PostIndex));
10553 __ stp(d0, d1, MemOperand(x1, postindex, PostIndex));
10554 data_length += postindex;
10555
10556 postindex = 2 * kWRegSizeInBytes;
10557 __ ldp(w2, w3, MemOperand(x0, postindex, PostIndex));
10558 __ stp(w2, w3, MemOperand(x1, postindex, PostIndex));
10559 data_length += postindex;
10560
10561 postindex = 2 * kSRegSizeInBytes;
10562 __ ldp(s0, s1, MemOperand(x0, postindex, PostIndex));
10563 __ stp(s0, s1, MemOperand(x1, postindex, PostIndex));
10564 data_length += postindex;
10565
10566 postindex = kXRegSizeInBytes;
10567 __ ldr(x2, MemOperand(x0, postindex, PostIndex));
10568 __ str(x2, MemOperand(x1, postindex, PostIndex));
10569 data_length += postindex;
10570
10571 postindex = kDRegSizeInBytes;
10572 __ ldr(d0, MemOperand(x0, postindex, PostIndex));
10573 __ str(d0, MemOperand(x1, postindex, PostIndex));
10574 data_length += postindex;
10575
10576 postindex = kWRegSizeInBytes;
10577 __ ldr(w2, MemOperand(x0, postindex, PostIndex));
10578 __ str(w2, MemOperand(x1, postindex, PostIndex));
10579 data_length += postindex;
10580
10581 postindex = kSRegSizeInBytes;
10582 __ ldr(s0, MemOperand(x0, postindex, PostIndex));
10583 __ str(s0, MemOperand(x1, postindex, PostIndex));
10584 data_length += postindex;
10585
10586 postindex = 2;
10587 __ ldrh(w2, MemOperand(x0, postindex, PostIndex));
10588 __ strh(w2, MemOperand(x1, postindex, PostIndex));
10589 data_length += postindex;
10590
10591 postindex = 2;
10592 __ ldrsh(w2, MemOperand(x0, postindex, PostIndex));
10593 __ strh(w2, MemOperand(x1, postindex, PostIndex));
10594 data_length += postindex;
10595
10596 postindex = 1;
10597 __ ldrb(w2, MemOperand(x0, postindex, PostIndex));
10598 __ strb(w2, MemOperand(x1, postindex, PostIndex));
10599 data_length += postindex;
10600
10601 postindex = 1;
10602 __ ldrsb(w2, MemOperand(x0, postindex, PostIndex));
10603 __ strb(w2, MemOperand(x1, postindex, PostIndex));
10604 data_length += postindex;
10605
10606 VIXL_ASSERT(kMaxDataLength >= data_length);
10607
10608 END();
10609 RUN();
10610
10611 // Check that the postindex was correctly applied in each operation, and
10612 // that the tag was preserved.
10613 ASSERT_EQUAL_64(src_tagged + data_length, x0);
10614 ASSERT_EQUAL_64(dst_tagged + data_length, x1);
10615
10616 for (int k = 0; k < data_length; k++) {
10617 VIXL_CHECK(src[k] == dst[k]);
10618 }
10619
10620 TEARDOWN();
10621 }
10622 }
10623}
10624
10625
10626TEST(load_store_tagged_register_offset) {
10627 uint64_t tags[] = { 0x00, 0x1, 0x55, 0xff };
10628 int tag_count = sizeof(tags) / sizeof(tags[0]);
10629
10630 const int kMaxDataLength = 128;
10631
10632 for (int i = 0; i < tag_count; i++) {
10633 unsigned char src[kMaxDataLength];
10634 uint64_t src_raw = reinterpret_cast<uint64_t>(src);
10635 uint64_t src_tag = tags[i];
10636 uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
10637
10638 for (int k = 0; k < kMaxDataLength; k++) {
10639 src[k] = k + 1;
10640 }
10641
10642 for (int j = 0; j < tag_count; j++) {
10643 unsigned char dst[kMaxDataLength];
10644 uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
10645 uint64_t dst_tag = tags[j];
10646 uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
10647
10648 // Also tag the offset register; the operation should still succeed.
10649 for (int o = 0; o < tag_count; o++) {
10650 uint64_t offset_base = CPU::SetPointerTag(UINT64_C(0), tags[o]);
10651 int data_length = 0;
10652
10653 for (int k = 0; k < kMaxDataLength; k++) {
10654 dst[k] = 0;
10655 }
10656
10657 SETUP();
10658 START();
10659
10660 __ Mov(x0, src_tagged);
10661 __ Mov(x1, dst_tagged);
10662
10663 __ Mov(x10, offset_base + data_length);
10664 __ ldr(x2, MemOperand(x0, x10));
10665 __ str(x2, MemOperand(x1, x10));
10666 data_length += kXRegSizeInBytes;
10667
10668 __ Mov(x10, offset_base + data_length);
10669 __ ldr(d0, MemOperand(x0, x10));
10670 __ str(d0, MemOperand(x1, x10));
10671 data_length += kDRegSizeInBytes;
10672
10673 __ Mov(x10, offset_base + data_length);
10674 __ ldr(w2, MemOperand(x0, x10));
10675 __ str(w2, MemOperand(x1, x10));
10676 data_length += kWRegSizeInBytes;
10677
10678 __ Mov(x10, offset_base + data_length);
10679 __ ldr(s0, MemOperand(x0, x10));
10680 __ str(s0, MemOperand(x1, x10));
10681 data_length += kSRegSizeInBytes;
10682
10683 __ Mov(x10, offset_base + data_length);
10684 __ ldrh(w2, MemOperand(x0, x10));
10685 __ strh(w2, MemOperand(x1, x10));
10686 data_length += 2;
10687
10688 __ Mov(x10, offset_base + data_length);
10689 __ ldrsh(w2, MemOperand(x0, x10));
10690 __ strh(w2, MemOperand(x1, x10));
10691 data_length += 2;
10692
10693 __ Mov(x10, offset_base + data_length);
10694 __ ldrb(w2, MemOperand(x0, x10));
10695 __ strb(w2, MemOperand(x1, x10));
10696 data_length += 1;
10697
10698 __ Mov(x10, offset_base + data_length);
10699 __ ldrsb(w2, MemOperand(x0, x10));
10700 __ strb(w2, MemOperand(x1, x10));
10701 data_length += 1;
10702
10703 VIXL_ASSERT(kMaxDataLength >= data_length);
10704
10705 END();
10706 RUN();
10707
10708 // Check that the postindex was correctly applied in each operation, and
10709 // that the tag was preserved.
10710 ASSERT_EQUAL_64(src_tagged, x0);
10711 ASSERT_EQUAL_64(dst_tagged, x1);
10712 ASSERT_EQUAL_64(offset_base + data_length - 1, x10);
10713
10714 for (int k = 0; k < data_length; k++) {
10715 VIXL_CHECK(src[k] == dst[k]);
10716 }
10717
10718 TEARDOWN();
10719 }
10720 }
10721 }
10722}
10723
10724
armvixlad96eda2013-06-14 11:42:37 +010010725} // namespace vixl