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/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/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 __ imul(i.OutputRegister(), i.InputOperand(0), i.InputInt32(1)); | 242 __ imul(i.OutputRegister(), i.InputOperand(0), i.InputInt32(1)); |
243 } else { | 243 } else { |
244 __ imul(i.OutputRegister(), i.InputOperand(1)); | 244 __ imul(i.OutputRegister(), i.InputOperand(1)); |
245 } | 245 } |
246 break; | 246 break; |
247 case kIA32Idiv: | 247 case kIA32Idiv: |
248 __ cdq(); | 248 __ cdq(); |
249 __ idiv(i.InputOperand(1)); | 249 __ idiv(i.InputOperand(1)); |
250 break; | 250 break; |
251 case kIA32Udiv: | 251 case kIA32Udiv: |
252 __ xor_(edx, edx); | 252 __ Move(edx, Immediate(0)); |
253 __ div(i.InputOperand(1)); | 253 __ div(i.InputOperand(1)); |
254 break; | 254 break; |
255 case kIA32Not: | 255 case kIA32Not: |
256 __ not_(i.OutputOperand()); | 256 __ not_(i.OutputOperand()); |
257 break; | 257 break; |
258 case kIA32Neg: | 258 case kIA32Neg: |
259 __ neg(i.OutputOperand()); | 259 __ neg(i.OutputOperand()); |
260 break; | 260 break; |
261 case kIA32Or: | 261 case kIA32Or: |
262 if (HasImmediateInput(instr, 1)) { | 262 if (HasImmediateInput(instr, 1)) { |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 | 545 |
546 // Materialize a full 32-bit 1 or 0 value. The result register is always the | 546 // Materialize a full 32-bit 1 or 0 value. The result register is always the |
547 // last output of the instruction. | 547 // last output of the instruction. |
548 Label check; | 548 Label check; |
549 DCHECK_NE(0, instr->OutputCount()); | 549 DCHECK_NE(0, instr->OutputCount()); |
550 Register reg = i.OutputRegister(instr->OutputCount() - 1); | 550 Register reg = i.OutputRegister(instr->OutputCount() - 1); |
551 Condition cc = no_condition; | 551 Condition cc = no_condition; |
552 switch (condition) { | 552 switch (condition) { |
553 case kUnorderedEqual: | 553 case kUnorderedEqual: |
554 __ j(parity_odd, &check, Label::kNear); | 554 __ j(parity_odd, &check, Label::kNear); |
555 __ mov(reg, Immediate(0)); | 555 __ Move(reg, Immediate(0)); |
556 __ jmp(&done, Label::kNear); | 556 __ jmp(&done, Label::kNear); |
557 // Fall through. | 557 // Fall through. |
558 case kEqual: | 558 case kEqual: |
559 cc = equal; | 559 cc = equal; |
560 break; | 560 break; |
561 case kUnorderedNotEqual: | 561 case kUnorderedNotEqual: |
562 __ j(parity_odd, &check, Label::kNear); | 562 __ j(parity_odd, &check, Label::kNear); |
563 __ mov(reg, Immediate(1)); | 563 __ mov(reg, Immediate(1)); |
564 __ jmp(&done, Label::kNear); | 564 __ jmp(&done, Label::kNear); |
565 // Fall through. | 565 // Fall through. |
566 case kNotEqual: | 566 case kNotEqual: |
567 cc = not_equal; | 567 cc = not_equal; |
568 break; | 568 break; |
569 case kSignedLessThan: | 569 case kSignedLessThan: |
570 cc = less; | 570 cc = less; |
571 break; | 571 break; |
572 case kSignedGreaterThanOrEqual: | 572 case kSignedGreaterThanOrEqual: |
573 cc = greater_equal; | 573 cc = greater_equal; |
574 break; | 574 break; |
575 case kSignedLessThanOrEqual: | 575 case kSignedLessThanOrEqual: |
576 cc = less_equal; | 576 cc = less_equal; |
577 break; | 577 break; |
578 case kSignedGreaterThan: | 578 case kSignedGreaterThan: |
579 cc = greater; | 579 cc = greater; |
580 break; | 580 break; |
581 case kUnorderedLessThan: | 581 case kUnorderedLessThan: |
582 __ j(parity_odd, &check, Label::kNear); | 582 __ j(parity_odd, &check, Label::kNear); |
583 __ mov(reg, Immediate(0)); | 583 __ Move(reg, Immediate(0)); |
584 __ jmp(&done, Label::kNear); | 584 __ jmp(&done, Label::kNear); |
585 // Fall through. | 585 // Fall through. |
586 case kUnsignedLessThan: | 586 case kUnsignedLessThan: |
587 cc = below; | 587 cc = below; |
588 break; | 588 break; |
589 case kUnorderedGreaterThanOrEqual: | 589 case kUnorderedGreaterThanOrEqual: |
590 __ j(parity_odd, &check, Label::kNear); | 590 __ j(parity_odd, &check, Label::kNear); |
591 __ mov(reg, Immediate(1)); | 591 __ mov(reg, Immediate(1)); |
592 __ jmp(&done, Label::kNear); | 592 __ jmp(&done, Label::kNear); |
593 // Fall through. | 593 // Fall through. |
594 case kUnsignedGreaterThanOrEqual: | 594 case kUnsignedGreaterThanOrEqual: |
595 cc = above_equal; | 595 cc = above_equal; |
596 break; | 596 break; |
597 case kUnorderedLessThanOrEqual: | 597 case kUnorderedLessThanOrEqual: |
598 __ j(parity_odd, &check, Label::kNear); | 598 __ j(parity_odd, &check, Label::kNear); |
599 __ mov(reg, Immediate(0)); | 599 __ Move(reg, Immediate(0)); |
600 __ jmp(&done, Label::kNear); | 600 __ jmp(&done, Label::kNear); |
601 // Fall through. | 601 // Fall through. |
602 case kUnsignedLessThanOrEqual: | 602 case kUnsignedLessThanOrEqual: |
603 cc = below_equal; | 603 cc = below_equal; |
604 break; | 604 break; |
605 case kUnorderedGreaterThan: | 605 case kUnorderedGreaterThan: |
606 __ j(parity_odd, &check, Label::kNear); | 606 __ j(parity_odd, &check, Label::kNear); |
607 __ mov(reg, Immediate(1)); | 607 __ mov(reg, Immediate(1)); |
608 __ jmp(&done, Label::kNear); | 608 __ jmp(&done, Label::kNear); |
609 // Fall through. | 609 // Fall through. |
610 case kUnsignedGreaterThan: | 610 case kUnsignedGreaterThan: |
611 cc = above; | 611 cc = above; |
612 break; | 612 break; |
613 case kOverflow: | 613 case kOverflow: |
614 cc = overflow; | 614 cc = overflow; |
615 break; | 615 break; |
616 case kNotOverflow: | 616 case kNotOverflow: |
617 cc = no_overflow; | 617 cc = no_overflow; |
618 break; | 618 break; |
619 } | 619 } |
620 __ bind(&check); | 620 __ bind(&check); |
621 if (reg.is_byte_register()) { | 621 if (reg.is_byte_register()) { |
622 // setcc for byte registers (al, bl, cl, dl). | 622 // setcc for byte registers (al, bl, cl, dl). |
623 __ setcc(cc, reg); | 623 __ setcc(cc, reg); |
624 __ movzx_b(reg, reg); | 624 __ movzx_b(reg, reg); |
625 } else { | 625 } else { |
626 // Emit a branch to set a register to either 1 or 0. | 626 // Emit a branch to set a register to either 1 or 0. |
627 Label set; | 627 Label set; |
628 __ j(cc, &set, Label::kNear); | 628 __ j(cc, &set, Label::kNear); |
629 __ mov(reg, Immediate(0)); | 629 __ Move(reg, Immediate(0)); |
630 __ jmp(&done, Label::kNear); | 630 __ jmp(&done, Label::kNear); |
631 __ bind(&set); | 631 __ bind(&set); |
632 __ mov(reg, Immediate(1)); | 632 __ mov(reg, Immediate(1)); |
633 } | 633 } |
634 __ bind(&done); | 634 __ bind(&done); |
635 } | 635 } |
636 | 636 |
637 | 637 |
638 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 638 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { |
639 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 639 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 AllowDeferredHandleDereference embedding_raw_address; | 892 AllowDeferredHandleDereference embedding_raw_address; |
893 if (isolate()->heap()->InNewSpace(*src)) { | 893 if (isolate()->heap()->InNewSpace(*src)) { |
894 __ PushHeapObject(src); | 894 __ PushHeapObject(src); |
895 __ pop(dst); | 895 __ pop(dst); |
896 } else { | 896 } else { |
897 __ mov(dst, src); | 897 __ mov(dst, src); |
898 } | 898 } |
899 } | 899 } |
900 } else if (destination->IsRegister()) { | 900 } else if (destination->IsRegister()) { |
901 Register dst = g.ToRegister(destination); | 901 Register dst = g.ToRegister(destination); |
902 __ mov(dst, g.ToImmediate(source)); | 902 __ Move(dst, g.ToImmediate(source)); |
903 } else if (destination->IsStackSlot()) { | 903 } else if (destination->IsStackSlot()) { |
904 Operand dst = g.ToOperand(destination); | 904 Operand dst = g.ToOperand(destination); |
905 __ mov(dst, g.ToImmediate(source)); | 905 __ Move(dst, g.ToImmediate(source)); |
906 } else if (src_constant.type() == Constant::kFloat32) { | 906 } else if (src_constant.type() == Constant::kFloat32) { |
907 // TODO(turbofan): Can we do better here? | 907 // TODO(turbofan): Can we do better here? |
908 uint32_t src = bit_cast<uint32_t>(src_constant.ToFloat32()); | 908 uint32_t src = bit_cast<uint32_t>(src_constant.ToFloat32()); |
909 if (destination->IsDoubleRegister()) { | 909 if (destination->IsDoubleRegister()) { |
910 XMMRegister dst = g.ToDoubleRegister(destination); | 910 XMMRegister dst = g.ToDoubleRegister(destination); |
911 __ Move(dst, src); | 911 __ Move(dst, src); |
912 } else { | 912 } else { |
913 DCHECK(destination->IsDoubleStackSlot()); | 913 DCHECK(destination->IsDoubleStackSlot()); |
914 Operand dst = g.ToOperand(destination); | 914 Operand dst = g.ToOperand(destination); |
915 __ mov(dst, Immediate(src)); | 915 __ Move(dst, Immediate(src)); |
916 } | 916 } |
917 } else { | 917 } else { |
918 DCHECK_EQ(Constant::kFloat64, src_constant.type()); | 918 DCHECK_EQ(Constant::kFloat64, src_constant.type()); |
919 uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64()); | 919 uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64()); |
920 uint32_t lower = static_cast<uint32_t>(src); | 920 uint32_t lower = static_cast<uint32_t>(src); |
921 uint32_t upper = static_cast<uint32_t>(src >> 32); | 921 uint32_t upper = static_cast<uint32_t>(src >> 32); |
922 if (destination->IsDoubleRegister()) { | 922 if (destination->IsDoubleRegister()) { |
923 XMMRegister dst = g.ToDoubleRegister(destination); | 923 XMMRegister dst = g.ToDoubleRegister(destination); |
924 __ Move(dst, src); | 924 __ Move(dst, src); |
925 } else { | 925 } else { |
926 DCHECK(destination->IsDoubleStackSlot()); | 926 DCHECK(destination->IsDoubleStackSlot()); |
927 Operand dst0 = g.ToOperand(destination); | 927 Operand dst0 = g.ToOperand(destination); |
928 Operand dst1 = g.HighOperand(destination); | 928 Operand dst1 = g.HighOperand(destination); |
929 __ mov(dst0, Immediate(lower)); | 929 __ Move(dst0, Immediate(lower)); |
930 __ mov(dst1, Immediate(upper)); | 930 __ Move(dst1, Immediate(upper)); |
931 } | 931 } |
932 } | 932 } |
933 } else if (source->IsDoubleRegister()) { | 933 } else if (source->IsDoubleRegister()) { |
934 XMMRegister src = g.ToDoubleRegister(source); | 934 XMMRegister src = g.ToDoubleRegister(source); |
935 if (destination->IsDoubleRegister()) { | 935 if (destination->IsDoubleRegister()) { |
936 XMMRegister dst = g.ToDoubleRegister(destination); | 936 XMMRegister dst = g.ToDoubleRegister(destination); |
937 __ movaps(dst, src); | 937 __ movaps(dst, src); |
938 } else { | 938 } else { |
939 DCHECK(destination->IsDoubleStackSlot()); | 939 DCHECK(destination->IsDoubleStackSlot()); |
940 Operand dst = g.ToOperand(destination); | 940 Operand dst = g.ToOperand(destination); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 } | 1029 } |
1030 } | 1030 } |
1031 MarkLazyDeoptSite(); | 1031 MarkLazyDeoptSite(); |
1032 } | 1032 } |
1033 | 1033 |
1034 #undef __ | 1034 #undef __ |
1035 | 1035 |
1036 } // namespace compiler | 1036 } // namespace compiler |
1037 } // namespace internal | 1037 } // namespace internal |
1038 } // namespace v8 | 1038 } // namespace v8 |
OLD | NEW |