OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 #include "src/compilation-info.h" | 6 #include "src/compilation-info.h" |
7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/osr.h" | 10 #include "src/compiler/osr.h" |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 break; | 379 break; |
380 default: | 380 default: |
381 predicate = true; | 381 predicate = true; |
382 break; | 382 break; |
383 } | 383 } |
384 UNREACHABLE(); | 384 UNREACHABLE(); |
385 return kNoFPUCondition; | 385 return kNoFPUCondition; |
386 } | 386 } |
387 | 387 |
388 } // namespace | 388 } // namespace |
389 | 389 #define ASSEMBLE_BOUNDS_CHECK_REGISTER(offset, length, out_of_bounds) \ |
390 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ | |
391 do { \ | 390 do { \ |
392 auto result = i.Output##width##Register(); \ | 391 if (!length.is_reg() && base::bits::IsPowerOfTwo64(length.immediate())) { \ |
393 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ | 392 __ And(kScratchReg, offset, Operand(~(length.immediate() - 1))); \ |
394 if (instr->InputAt(0)->IsRegister()) { \ | 393 __ Branch(USE_DELAY_SLOT, out_of_bounds, ne, kScratchReg, \ |
395 auto offset = i.InputRegister(0); \ | 394 Operand(zero_reg)); \ |
396 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ | |
397 __ And(kScratchReg, offset, Operand(0xffffffff)); \ | |
398 __ Daddu(kScratchReg, i.InputRegister(2), kScratchReg); \ | |
399 __ asm_instr(result, MemOperand(kScratchReg, 0)); \ | |
400 } else { \ | 395 } else { \ |
401 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ | 396 __ Branch(USE_DELAY_SLOT, out_of_bounds, hs, offset, length); \ |
402 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \ | |
403 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ | |
404 } \ | 397 } \ |
405 __ bind(ool->exit()); \ | |
406 } while (0) | 398 } while (0) |
407 | 399 |
408 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ | 400 #define ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, length, out_of_bounds) \ |
409 do { \ | 401 do { \ |
410 auto result = i.OutputRegister(); \ | 402 if (!length.is_reg() && base::bits::IsPowerOfTwo64(length.immediate())) { \ |
411 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ | 403 __ Or(kScratchReg, zero_reg, Operand(offset)); \ |
412 if (instr->InputAt(0)->IsRegister()) { \ | 404 __ And(kScratchReg, kScratchReg, Operand(~(length.immediate() - 1))); \ |
413 auto offset = i.InputRegister(0); \ | 405 __ Branch(out_of_bounds, ne, kScratchReg, Operand(zero_reg)); \ |
414 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ | |
415 __ And(kScratchReg, offset, Operand(0xffffffff)); \ | |
416 __ Daddu(kScratchReg, i.InputRegister(2), kScratchReg); \ | |
417 __ asm_instr(result, MemOperand(kScratchReg, 0)); \ | |
418 } else { \ | 406 } else { \ |
419 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ | 407 __ Branch(out_of_bounds, ls, length.rm(), Operand(offset)); \ |
420 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \ | |
421 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ | |
422 } \ | 408 } \ |
423 __ bind(ool->exit()); \ | |
424 } while (0) | 409 } while (0) |
425 | 410 |
426 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \ | 411 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ |
427 do { \ | 412 do { \ |
428 Label done; \ | 413 auto result = i.Output##width##Register(); \ |
429 if (instr->InputAt(0)->IsRegister()) { \ | 414 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ |
430 auto offset = i.InputRegister(0); \ | 415 if (instr->InputAt(0)->IsRegister()) { \ |
431 auto value = i.InputOrZero##width##Register(2); \ | 416 auto offset = i.InputRegister(0); \ |
432 if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \ | 417 ASSEMBLE_BOUNDS_CHECK_REGISTER(offset, i.InputOperand(1), ool->entry()); \ |
433 __ Move(kDoubleRegZero, 0.0); \ | 418 __ And(kScratchReg, offset, Operand(0xffffffff)); \ |
434 } \ | 419 __ Daddu(kScratchReg, i.InputRegister(2), kScratchReg); \ |
435 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ | 420 __ asm_instr(result, MemOperand(kScratchReg, 0)); \ |
436 __ And(kScratchReg, offset, Operand(0xffffffff)); \ | 421 } else { \ |
437 __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \ | 422 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ |
438 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ | 423 ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), \ |
439 } else { \ | 424 ool->entry()); \ |
440 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ | 425 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ |
441 auto value = i.InputOrZero##width##Register(2); \ | 426 } \ |
442 if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \ | 427 __ bind(ool->exit()); \ |
443 __ Move(kDoubleRegZero, 0.0); \ | |
444 } \ | |
445 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | |
446 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | |
447 } \ | |
448 __ bind(&done); \ | |
449 } while (0) | 428 } while (0) |
450 | 429 |
451 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ | 430 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
452 do { \ | 431 do { \ |
453 Label done; \ | 432 auto result = i.OutputRegister(); \ |
454 if (instr->InputAt(0)->IsRegister()) { \ | 433 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ |
455 auto offset = i.InputRegister(0); \ | 434 if (instr->InputAt(0)->IsRegister()) { \ |
456 auto value = i.InputOrZeroRegister(2); \ | 435 auto offset = i.InputRegister(0); \ |
457 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ | 436 ASSEMBLE_BOUNDS_CHECK_REGISTER(offset, i.InputOperand(1), ool->entry()); \ |
458 __ And(kScratchReg, offset, Operand(0xffffffff)); \ | 437 __ And(kScratchReg, offset, Operand(0xffffffff)); \ |
459 __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \ | 438 __ Daddu(kScratchReg, i.InputRegister(2), kScratchReg); \ |
460 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ | 439 __ asm_instr(result, MemOperand(kScratchReg, 0)); \ |
461 } else { \ | 440 } else { \ |
462 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ | 441 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ |
463 auto value = i.InputOrZeroRegister(2); \ | 442 ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), \ |
464 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 443 ool->entry()); \ |
465 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 444 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ |
466 } \ | 445 } \ |
467 __ bind(&done); \ | 446 __ bind(ool->exit()); \ |
| 447 } while (0) |
| 448 |
| 449 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \ |
| 450 do { \ |
| 451 Label done; \ |
| 452 if (instr->InputAt(0)->IsRegister()) { \ |
| 453 auto offset = i.InputRegister(0); \ |
| 454 auto value = i.InputOrZero##width##Register(2); \ |
| 455 if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \ |
| 456 __ Move(kDoubleRegZero, 0.0); \ |
| 457 } \ |
| 458 ASSEMBLE_BOUNDS_CHECK_REGISTER(offset, i.InputOperand(1), &done); \ |
| 459 __ And(kScratchReg, offset, Operand(0xffffffff)); \ |
| 460 __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \ |
| 461 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ |
| 462 } else { \ |
| 463 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ |
| 464 auto value = i.InputOrZero##width##Register(2); \ |
| 465 if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \ |
| 466 __ Move(kDoubleRegZero, 0.0); \ |
| 467 } \ |
| 468 ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), &done); \ |
| 469 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
| 470 } \ |
| 471 __ bind(&done); \ |
| 472 } while (0) |
| 473 |
| 474 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
| 475 do { \ |
| 476 Label done; \ |
| 477 if (instr->InputAt(0)->IsRegister()) { \ |
| 478 auto offset = i.InputRegister(0); \ |
| 479 auto value = i.InputOrZeroRegister(2); \ |
| 480 ASSEMBLE_BOUNDS_CHECK_REGISTER(offset, i.InputOperand(1), &done); \ |
| 481 __ And(kScratchReg, offset, Operand(0xffffffff)); \ |
| 482 __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \ |
| 483 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ |
| 484 } else { \ |
| 485 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ |
| 486 auto value = i.InputOrZeroRegister(2); \ |
| 487 ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), &done); \ |
| 488 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
| 489 } \ |
| 490 __ bind(&done); \ |
468 } while (0) | 491 } while (0) |
469 | 492 |
470 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode) \ | 493 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode) \ |
471 if (kArchVariant == kMips64r6) { \ | 494 if (kArchVariant == kMips64r6) { \ |
472 __ cfc1(kScratchReg, FCSR); \ | 495 __ cfc1(kScratchReg, FCSR); \ |
473 __ li(at, Operand(mode_##mode)); \ | 496 __ li(at, Operand(mode_##mode)); \ |
474 __ ctc1(at, FCSR); \ | 497 __ ctc1(at, FCSR); \ |
475 __ rint_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 498 __ rint_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
476 __ ctc1(kScratchReg, FCSR); \ | 499 __ ctc1(kScratchReg, FCSR); \ |
477 } else { \ | 500 } else { \ |
(...skipping 2172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2650 padding_size -= v8::internal::Assembler::kInstrSize; | 2673 padding_size -= v8::internal::Assembler::kInstrSize; |
2651 } | 2674 } |
2652 } | 2675 } |
2653 } | 2676 } |
2654 | 2677 |
2655 #undef __ | 2678 #undef __ |
2656 | 2679 |
2657 } // namespace compiler | 2680 } // namespace compiler |
2658 } // namespace internal | 2681 } // namespace internal |
2659 } // namespace v8 | 2682 } // namespace v8 |
OLD | NEW |