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