OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 CpuFeatureScope avx_scope(masm(), AVX); \ | 367 CpuFeatureScope avx_scope(masm(), AVX); \ |
368 if (instr->InputAt(1)->IsDoubleRegister()) { \ | 368 if (instr->InputAt(1)->IsDoubleRegister()) { \ |
369 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ | 369 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ |
370 i.InputDoubleRegister(1)); \ | 370 i.InputDoubleRegister(1)); \ |
371 } else { \ | 371 } else { \ |
372 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ | 372 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ |
373 i.InputOperand(1)); \ | 373 i.InputOperand(1)); \ |
374 } \ | 374 } \ |
375 } while (0) | 375 } while (0) |
376 | 376 |
377 | |
378 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \ | 377 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \ |
379 do { \ | 378 do { \ |
380 auto result = i.OutputDoubleRegister(); \ | 379 auto result = i.OutputDoubleRegister(); \ |
381 auto buffer = i.InputRegister(0); \ | 380 auto buffer = i.InputRegister(0); \ |
382 auto index1 = i.InputRegister(1); \ | 381 auto index1 = i.InputRegister(1); \ |
383 auto index2 = i.InputInt32(2); \ | 382 auto index2 = i.InputUint32(2); \ |
384 OutOfLineCode* ool; \ | 383 OutOfLineCode* ool; \ |
385 if (instr->InputAt(3)->IsRegister()) { \ | 384 if (instr->InputAt(3)->IsRegister()) { \ |
386 auto length = i.InputRegister(3); \ | 385 auto length = i.InputRegister(3); \ |
387 DCHECK_EQ(0, index2); \ | 386 DCHECK_EQ(0, index2); \ |
388 __ cmpl(index1, length); \ | 387 __ cmpl(index1, length); \ |
389 ool = new (zone()) OutOfLineLoadNaN(this, result); \ | 388 ool = new (zone()) OutOfLineLoadNaN(this, result); \ |
390 } else { \ | 389 } else { \ |
391 auto length = i.InputInt32(3); \ | 390 auto length = i.InputUint32(3); \ |
392 DCHECK_LE(index2, length); \ | 391 DCHECK_LE(index2, length); \ |
393 __ cmpq(index1, Immediate(length - index2)); \ | 392 __ cmpl(index1, Immediate(length - index2)); \ |
394 class OutOfLineLoadFloat final : public OutOfLineCode { \ | 393 class OutOfLineLoadFloat final : public OutOfLineCode { \ |
395 public: \ | 394 public: \ |
396 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result, \ | 395 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result, \ |
397 Register buffer, Register index1, int32_t index2, \ | 396 Register buffer, Register index1, int32_t index2, \ |
398 int32_t length) \ | 397 int32_t length) \ |
399 : OutOfLineCode(gen), \ | 398 : OutOfLineCode(gen), \ |
400 result_(result), \ | 399 result_(result), \ |
401 buffer_(buffer), \ | 400 buffer_(buffer), \ |
402 index1_(index1), \ | 401 index1_(index1), \ |
403 index2_(index2), \ | 402 index2_(index2), \ |
(...skipping 16 matching lines...) Expand all Loading... |
420 int32_t const length_; \ | 419 int32_t const length_; \ |
421 }; \ | 420 }; \ |
422 ool = new (zone()) \ | 421 ool = new (zone()) \ |
423 OutOfLineLoadFloat(this, result, buffer, index1, index2, length); \ | 422 OutOfLineLoadFloat(this, result, buffer, index1, index2, length); \ |
424 } \ | 423 } \ |
425 __ j(above_equal, ool->entry()); \ | 424 __ j(above_equal, ool->entry()); \ |
426 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ | 425 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ |
427 __ bind(ool->exit()); \ | 426 __ bind(ool->exit()); \ |
428 } while (false) | 427 } while (false) |
429 | 428 |
430 | |
431 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ | 429 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
432 do { \ | 430 do { \ |
433 auto result = i.OutputRegister(); \ | 431 auto result = i.OutputRegister(); \ |
434 auto buffer = i.InputRegister(0); \ | 432 auto buffer = i.InputRegister(0); \ |
435 auto index1 = i.InputRegister(1); \ | 433 auto index1 = i.InputRegister(1); \ |
436 auto index2 = i.InputInt32(2); \ | 434 auto index2 = i.InputUint32(2); \ |
437 OutOfLineCode* ool; \ | 435 OutOfLineCode* ool; \ |
438 if (instr->InputAt(3)->IsRegister()) { \ | 436 if (instr->InputAt(3)->IsRegister()) { \ |
439 auto length = i.InputRegister(3); \ | 437 auto length = i.InputRegister(3); \ |
440 DCHECK_EQ(0, index2); \ | 438 DCHECK_EQ(0, index2); \ |
441 __ cmpl(index1, length); \ | 439 __ cmpl(index1, length); \ |
442 ool = new (zone()) OutOfLineLoadZero(this, result); \ | 440 ool = new (zone()) OutOfLineLoadZero(this, result); \ |
443 } else { \ | 441 } else { \ |
444 auto length = i.InputInt32(3); \ | 442 auto length = i.InputUint32(3); \ |
445 DCHECK_LE(index2, length); \ | 443 DCHECK_LE(index2, length); \ |
446 __ cmpq(index1, Immediate(length - index2)); \ | 444 __ cmpl(index1, Immediate(length - index2)); \ |
447 class OutOfLineLoadInteger final : public OutOfLineCode { \ | 445 class OutOfLineLoadInteger final : public OutOfLineCode { \ |
448 public: \ | 446 public: \ |
449 OutOfLineLoadInteger(CodeGenerator* gen, Register result, \ | 447 OutOfLineLoadInteger(CodeGenerator* gen, Register result, \ |
450 Register buffer, Register index1, int32_t index2, \ | 448 Register buffer, Register index1, int32_t index2, \ |
451 int32_t length) \ | 449 int32_t length) \ |
452 : OutOfLineCode(gen), \ | 450 : OutOfLineCode(gen), \ |
453 result_(result), \ | 451 result_(result), \ |
454 buffer_(buffer), \ | 452 buffer_(buffer), \ |
455 index1_(index1), \ | 453 index1_(index1), \ |
456 index2_(index2), \ | 454 index2_(index2), \ |
(...skipping 19 matching lines...) Expand all Loading... |
476 int32_t const length_; \ | 474 int32_t const length_; \ |
477 }; \ | 475 }; \ |
478 ool = new (zone()) \ | 476 ool = new (zone()) \ |
479 OutOfLineLoadInteger(this, result, buffer, index1, index2, length); \ | 477 OutOfLineLoadInteger(this, result, buffer, index1, index2, length); \ |
480 } \ | 478 } \ |
481 __ j(above_equal, ool->entry()); \ | 479 __ j(above_equal, ool->entry()); \ |
482 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ | 480 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ |
483 __ bind(ool->exit()); \ | 481 __ bind(ool->exit()); \ |
484 } while (false) | 482 } while (false) |
485 | 483 |
486 | |
487 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ | 484 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ |
488 do { \ | 485 do { \ |
489 auto buffer = i.InputRegister(0); \ | 486 auto buffer = i.InputRegister(0); \ |
490 auto index1 = i.InputRegister(1); \ | 487 auto index1 = i.InputRegister(1); \ |
491 auto index2 = i.InputInt32(2); \ | 488 auto index2 = i.InputUint32(2); \ |
492 auto value = i.InputDoubleRegister(4); \ | 489 auto value = i.InputDoubleRegister(4); \ |
493 if (instr->InputAt(3)->IsRegister()) { \ | 490 if (instr->InputAt(3)->IsRegister()) { \ |
494 auto length = i.InputRegister(3); \ | 491 auto length = i.InputRegister(3); \ |
495 DCHECK_EQ(0, index2); \ | 492 DCHECK_EQ(0, index2); \ |
496 Label done; \ | 493 Label done; \ |
497 __ cmpl(index1, length); \ | 494 __ cmpl(index1, length); \ |
498 __ j(above_equal, &done, Label::kNear); \ | 495 __ j(above_equal, &done, Label::kNear); \ |
499 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ | 496 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
500 __ bind(&done); \ | 497 __ bind(&done); \ |
501 } else { \ | 498 } else { \ |
502 auto length = i.InputInt32(3); \ | 499 auto length = i.InputUint32(3); \ |
503 DCHECK_LE(index2, length); \ | 500 DCHECK_LE(index2, length); \ |
504 __ cmpq(index1, Immediate(length - index2)); \ | 501 __ cmpl(index1, Immediate(length - index2)); \ |
505 class OutOfLineStoreFloat final : public OutOfLineCode { \ | 502 class OutOfLineStoreFloat final : public OutOfLineCode { \ |
506 public: \ | 503 public: \ |
507 OutOfLineStoreFloat(CodeGenerator* gen, Register buffer, \ | 504 OutOfLineStoreFloat(CodeGenerator* gen, Register buffer, \ |
508 Register index1, int32_t index2, int32_t length, \ | 505 Register index1, int32_t index2, int32_t length, \ |
509 XMMRegister value) \ | 506 XMMRegister value) \ |
510 : OutOfLineCode(gen), \ | 507 : OutOfLineCode(gen), \ |
511 buffer_(buffer), \ | 508 buffer_(buffer), \ |
512 index1_(index1), \ | 509 index1_(index1), \ |
513 index2_(index2), \ | 510 index2_(index2), \ |
514 length_(length), \ | 511 length_(length), \ |
(...skipping 15 matching lines...) Expand all Loading... |
530 XMMRegister const value_; \ | 527 XMMRegister const value_; \ |
531 }; \ | 528 }; \ |
532 auto ool = new (zone()) \ | 529 auto ool = new (zone()) \ |
533 OutOfLineStoreFloat(this, buffer, index1, index2, length, value); \ | 530 OutOfLineStoreFloat(this, buffer, index1, index2, length, value); \ |
534 __ j(above_equal, ool->entry()); \ | 531 __ j(above_equal, ool->entry()); \ |
535 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ | 532 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
536 __ bind(ool->exit()); \ | 533 __ bind(ool->exit()); \ |
537 } \ | 534 } \ |
538 } while (false) | 535 } while (false) |
539 | 536 |
540 | |
541 #define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value) \ | 537 #define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value) \ |
542 do { \ | 538 do { \ |
543 auto buffer = i.InputRegister(0); \ | 539 auto buffer = i.InputRegister(0); \ |
544 auto index1 = i.InputRegister(1); \ | 540 auto index1 = i.InputRegister(1); \ |
545 auto index2 = i.InputInt32(2); \ | 541 auto index2 = i.InputUint32(2); \ |
546 if (instr->InputAt(3)->IsRegister()) { \ | 542 if (instr->InputAt(3)->IsRegister()) { \ |
547 auto length = i.InputRegister(3); \ | 543 auto length = i.InputRegister(3); \ |
548 DCHECK_EQ(0, index2); \ | 544 DCHECK_EQ(0, index2); \ |
549 Label done; \ | 545 Label done; \ |
550 __ cmpl(index1, length); \ | 546 __ cmpl(index1, length); \ |
551 __ j(above_equal, &done, Label::kNear); \ | 547 __ j(above_equal, &done, Label::kNear); \ |
552 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ | 548 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
553 __ bind(&done); \ | 549 __ bind(&done); \ |
554 } else { \ | 550 } else { \ |
555 auto length = i.InputInt32(3); \ | 551 auto length = i.InputUint32(3); \ |
556 DCHECK_LE(index2, length); \ | 552 DCHECK_LE(index2, length); \ |
557 __ cmpq(index1, Immediate(length - index2)); \ | 553 __ cmpl(index1, Immediate(length - index2)); \ |
558 class OutOfLineStoreInteger final : public OutOfLineCode { \ | 554 class OutOfLineStoreInteger final : public OutOfLineCode { \ |
559 public: \ | 555 public: \ |
560 OutOfLineStoreInteger(CodeGenerator* gen, Register buffer, \ | 556 OutOfLineStoreInteger(CodeGenerator* gen, Register buffer, \ |
561 Register index1, int32_t index2, int32_t length, \ | 557 Register index1, int32_t index2, int32_t length, \ |
562 Value value) \ | 558 Value value) \ |
563 : OutOfLineCode(gen), \ | 559 : OutOfLineCode(gen), \ |
564 buffer_(buffer), \ | 560 buffer_(buffer), \ |
565 index1_(index1), \ | 561 index1_(index1), \ |
566 index2_(index2), \ | 562 index2_(index2), \ |
567 length_(length), \ | 563 length_(length), \ |
(...skipping 15 matching lines...) Expand all Loading... |
583 Value const value_; \ | 579 Value const value_; \ |
584 }; \ | 580 }; \ |
585 auto ool = new (zone()) \ | 581 auto ool = new (zone()) \ |
586 OutOfLineStoreInteger(this, buffer, index1, index2, length, value); \ | 582 OutOfLineStoreInteger(this, buffer, index1, index2, length, value); \ |
587 __ j(above_equal, ool->entry()); \ | 583 __ j(above_equal, ool->entry()); \ |
588 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ | 584 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
589 __ bind(ool->exit()); \ | 585 __ bind(ool->exit()); \ |
590 } \ | 586 } \ |
591 } while (false) | 587 } while (false) |
592 | 588 |
593 | |
594 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ | 589 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
595 do { \ | 590 do { \ |
596 if (instr->InputAt(4)->IsRegister()) { \ | 591 if (instr->InputAt(4)->IsRegister()) { \ |
597 Register value = i.InputRegister(4); \ | 592 Register value = i.InputRegister(4); \ |
598 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ | 593 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ |
599 } else { \ | 594 } else { \ |
600 Immediate value = i.InputImmediate(4); \ | 595 Immediate value = i.InputImmediate(4); \ |
601 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ | 596 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ |
602 } \ | 597 } \ |
603 } while (false) | 598 } while (false) |
(...skipping 1690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2294 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2289 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2295 __ Nop(padding_size); | 2290 __ Nop(padding_size); |
2296 } | 2291 } |
2297 } | 2292 } |
2298 | 2293 |
2299 #undef __ | 2294 #undef __ |
2300 | 2295 |
2301 } // namespace compiler | 2296 } // namespace compiler |
2302 } // namespace internal | 2297 } // namespace internal |
2303 } // namespace v8 | 2298 } // namespace v8 |
OLD | NEW |