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