Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 6928060: Merge Label and NearLabel (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: address comments Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 538
539 if (FLAG_deopt_every_n_times != 0) { 539 if (FLAG_deopt_every_n_times != 0) {
540 Handle<SharedFunctionInfo> shared(info_->shared_info()); 540 Handle<SharedFunctionInfo> shared(info_->shared_info());
541 Label no_deopt; 541 Label no_deopt;
542 __ pushfd(); 542 __ pushfd();
543 __ push(eax); 543 __ push(eax);
544 __ push(ebx); 544 __ push(ebx);
545 __ mov(ebx, shared); 545 __ mov(ebx, shared);
546 __ mov(eax, FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset)); 546 __ mov(eax, FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset));
547 __ sub(Operand(eax), Immediate(Smi::FromInt(1))); 547 __ sub(Operand(eax), Immediate(Smi::FromInt(1)));
548 __ j(not_zero, &no_deopt); 548 __ j(not_zero, &no_deopt, Label::kNear);
549 if (FLAG_trap_on_deopt) __ int3(); 549 if (FLAG_trap_on_deopt) __ int3();
550 __ mov(eax, Immediate(Smi::FromInt(FLAG_deopt_every_n_times))); 550 __ mov(eax, Immediate(Smi::FromInt(FLAG_deopt_every_n_times)));
551 __ mov(FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset), eax); 551 __ mov(FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset), eax);
552 __ pop(ebx); 552 __ pop(ebx);
553 __ pop(eax); 553 __ pop(eax);
554 __ popfd(); 554 __ popfd();
555 __ jmp(entry, RelocInfo::RUNTIME_ENTRY); 555 __ jmp(entry, RelocInfo::RUNTIME_ENTRY);
556 556
557 __ bind(&no_deopt); 557 __ bind(&no_deopt);
558 __ mov(FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset), eax); 558 __ mov(FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset), eax);
559 __ pop(ebx); 559 __ pop(ebx);
560 __ pop(eax); 560 __ pop(eax);
561 __ popfd(); 561 __ popfd();
562 } 562 }
563 563
564 if (cc == no_condition) { 564 if (cc == no_condition) {
565 if (FLAG_trap_on_deopt) __ int3(); 565 if (FLAG_trap_on_deopt) __ int3();
566 __ jmp(entry, RelocInfo::RUNTIME_ENTRY); 566 __ jmp(entry, RelocInfo::RUNTIME_ENTRY);
567 } else { 567 } else {
568 if (FLAG_trap_on_deopt) { 568 if (FLAG_trap_on_deopt) {
569 NearLabel done; 569 Label done;
570 __ j(NegateCondition(cc), &done); 570 __ j(NegateCondition(cc), &done, Label::kNear);
571 __ int3(); 571 __ int3();
572 __ jmp(entry, RelocInfo::RUNTIME_ENTRY); 572 __ jmp(entry, RelocInfo::RUNTIME_ENTRY);
573 __ bind(&done); 573 __ bind(&done);
574 } else { 574 } else {
575 __ j(cc, entry, RelocInfo::RUNTIME_ENTRY, not_taken); 575 __ j(cc, entry, RelocInfo::RUNTIME_ENTRY, not_taken);
576 } 576 }
577 } 577 }
578 } 578 }
579 579
580 580
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 780
781 void LCodeGen::DoModI(LModI* instr) { 781 void LCodeGen::DoModI(LModI* instr) {
782 if (instr->hydrogen()->HasPowerOf2Divisor()) { 782 if (instr->hydrogen()->HasPowerOf2Divisor()) {
783 Register dividend = ToRegister(instr->InputAt(0)); 783 Register dividend = ToRegister(instr->InputAt(0));
784 784
785 int32_t divisor = 785 int32_t divisor =
786 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 786 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
787 787
788 if (divisor < 0) divisor = -divisor; 788 if (divisor < 0) divisor = -divisor;
789 789
790 NearLabel positive_dividend, done; 790 Label positive_dividend, done;
791 __ test(dividend, Operand(dividend)); 791 __ test(dividend, Operand(dividend));
792 __ j(not_sign, &positive_dividend); 792 __ j(not_sign, &positive_dividend, Label::kNear);
793 __ neg(dividend); 793 __ neg(dividend);
794 __ and_(dividend, divisor - 1); 794 __ and_(dividend, divisor - 1);
795 __ neg(dividend); 795 __ neg(dividend);
796 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 796 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
797 __ j(not_zero, &done); 797 __ j(not_zero, &done, Label::kNear);
798 DeoptimizeIf(no_condition, instr->environment()); 798 DeoptimizeIf(no_condition, instr->environment());
799 } 799 }
800 __ bind(&positive_dividend); 800 __ bind(&positive_dividend);
801 __ and_(dividend, divisor - 1); 801 __ and_(dividend, divisor - 1);
802 __ bind(&done); 802 __ bind(&done);
803 } else { 803 } else {
804 NearLabel done, remainder_eq_dividend, slow, do_subtraction, both_positive; 804 Label done, remainder_eq_dividend, slow, do_subtraction, both_positive;
805 Register left_reg = ToRegister(instr->InputAt(0)); 805 Register left_reg = ToRegister(instr->InputAt(0));
806 Register right_reg = ToRegister(instr->InputAt(1)); 806 Register right_reg = ToRegister(instr->InputAt(1));
807 Register result_reg = ToRegister(instr->result()); 807 Register result_reg = ToRegister(instr->result());
808 808
809 ASSERT(left_reg.is(eax)); 809 ASSERT(left_reg.is(eax));
810 ASSERT(result_reg.is(edx)); 810 ASSERT(result_reg.is(edx));
811 ASSERT(!right_reg.is(eax)); 811 ASSERT(!right_reg.is(eax));
812 ASSERT(!right_reg.is(edx)); 812 ASSERT(!right_reg.is(edx));
813 813
814 // Check for x % 0. 814 // Check for x % 0.
815 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 815 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
816 __ test(right_reg, Operand(right_reg)); 816 __ test(right_reg, Operand(right_reg));
817 DeoptimizeIf(zero, instr->environment()); 817 DeoptimizeIf(zero, instr->environment());
818 } 818 }
819 819
820 __ test(left_reg, Operand(left_reg)); 820 __ test(left_reg, Operand(left_reg));
821 __ j(zero, &remainder_eq_dividend); 821 __ j(zero, &remainder_eq_dividend, Label::kNear);
822 __ j(sign, &slow); 822 __ j(sign, &slow, Label::kNear);
823 823
824 __ test(right_reg, Operand(right_reg)); 824 __ test(right_reg, Operand(right_reg));
825 __ j(not_sign, &both_positive); 825 __ j(not_sign, &both_positive, Label::kNear);
826 // The sign of the divisor doesn't matter. 826 // The sign of the divisor doesn't matter.
827 __ neg(right_reg); 827 __ neg(right_reg);
828 828
829 __ bind(&both_positive); 829 __ bind(&both_positive);
830 // If the dividend is smaller than the nonnegative 830 // If the dividend is smaller than the nonnegative
831 // divisor, the dividend is the result. 831 // divisor, the dividend is the result.
832 __ cmp(left_reg, Operand(right_reg)); 832 __ cmp(left_reg, Operand(right_reg));
833 __ j(less, &remainder_eq_dividend); 833 __ j(less, &remainder_eq_dividend, Label::kNear);
834 834
835 // Check if the divisor is a PowerOfTwo integer. 835 // Check if the divisor is a PowerOfTwo integer.
836 Register scratch = ToRegister(instr->TempAt(0)); 836 Register scratch = ToRegister(instr->TempAt(0));
837 __ mov(scratch, right_reg); 837 __ mov(scratch, right_reg);
838 __ sub(Operand(scratch), Immediate(1)); 838 __ sub(Operand(scratch), Immediate(1));
839 __ test(scratch, Operand(right_reg)); 839 __ test(scratch, Operand(right_reg));
840 __ j(not_zero, &do_subtraction); 840 __ j(not_zero, &do_subtraction, Label::kNear);
841 __ and_(left_reg, Operand(scratch)); 841 __ and_(left_reg, Operand(scratch));
842 __ jmp(&remainder_eq_dividend); 842 __ jmp(&remainder_eq_dividend, Label::kNear);
843 843
844 __ bind(&do_subtraction); 844 __ bind(&do_subtraction);
845 const int kUnfolds = 3; 845 const int kUnfolds = 3;
846 // Try a few subtractions of the dividend. 846 // Try a few subtractions of the dividend.
847 __ mov(scratch, left_reg); 847 __ mov(scratch, left_reg);
848 for (int i = 0; i < kUnfolds; i++) { 848 for (int i = 0; i < kUnfolds; i++) {
849 // Reduce the dividend by the divisor. 849 // Reduce the dividend by the divisor.
850 __ sub(left_reg, Operand(right_reg)); 850 __ sub(left_reg, Operand(right_reg));
851 // Check if the dividend is less than the divisor. 851 // Check if the dividend is less than the divisor.
852 __ cmp(left_reg, Operand(right_reg)); 852 __ cmp(left_reg, Operand(right_reg));
853 __ j(less, &remainder_eq_dividend); 853 __ j(less, &remainder_eq_dividend, Label::kNear);
854 } 854 }
855 __ mov(left_reg, scratch); 855 __ mov(left_reg, scratch);
856 856
857 // Slow case, using idiv instruction. 857 // Slow case, using idiv instruction.
858 __ bind(&slow); 858 __ bind(&slow);
859 // Sign extend to edx. 859 // Sign extend to edx.
860 __ cdq(); 860 __ cdq();
861 861
862 // Check for (0 % -x) that will produce negative zero. 862 // Check for (0 % -x) that will produce negative zero.
863 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 863 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
864 NearLabel positive_left; 864 Label positive_left;
865 NearLabel done; 865 Label done;
866 __ test(left_reg, Operand(left_reg)); 866 __ test(left_reg, Operand(left_reg));
867 __ j(not_sign, &positive_left); 867 __ j(not_sign, &positive_left, Label::kNear);
868 __ idiv(right_reg); 868 __ idiv(right_reg);
869 869
870 // Test the remainder for 0, because then the result would be -0. 870 // Test the remainder for 0, because then the result would be -0.
871 __ test(result_reg, Operand(result_reg)); 871 __ test(result_reg, Operand(result_reg));
872 __ j(not_zero, &done); 872 __ j(not_zero, &done, Label::kNear);
873 873
874 DeoptimizeIf(no_condition, instr->environment()); 874 DeoptimizeIf(no_condition, instr->environment());
875 __ bind(&positive_left); 875 __ bind(&positive_left);
876 __ idiv(right_reg); 876 __ idiv(right_reg);
877 __ bind(&done); 877 __ bind(&done);
878 } else { 878 } else {
879 __ idiv(right_reg); 879 __ idiv(right_reg);
880 } 880 }
881 __ jmp(&done); 881 __ jmp(&done, Label::kNear);
882 882
883 __ bind(&remainder_eq_dividend); 883 __ bind(&remainder_eq_dividend);
884 __ mov(result_reg, left_reg); 884 __ mov(result_reg, left_reg);
885 885
886 __ bind(&done); 886 __ bind(&done);
887 } 887 }
888 } 888 }
889 889
890 890
891 void LCodeGen::DoDivI(LDivI* instr) { 891 void LCodeGen::DoDivI(LDivI* instr) {
892 LOperand* right = instr->InputAt(1); 892 LOperand* right = instr->InputAt(1);
893 ASSERT(ToRegister(instr->result()).is(eax)); 893 ASSERT(ToRegister(instr->result()).is(eax));
894 ASSERT(ToRegister(instr->InputAt(0)).is(eax)); 894 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
895 ASSERT(!ToRegister(instr->InputAt(1)).is(eax)); 895 ASSERT(!ToRegister(instr->InputAt(1)).is(eax));
896 ASSERT(!ToRegister(instr->InputAt(1)).is(edx)); 896 ASSERT(!ToRegister(instr->InputAt(1)).is(edx));
897 897
898 Register left_reg = eax; 898 Register left_reg = eax;
899 899
900 // Check for x / 0. 900 // Check for x / 0.
901 Register right_reg = ToRegister(right); 901 Register right_reg = ToRegister(right);
902 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 902 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
903 __ test(right_reg, ToOperand(right)); 903 __ test(right_reg, ToOperand(right));
904 DeoptimizeIf(zero, instr->environment()); 904 DeoptimizeIf(zero, instr->environment());
905 } 905 }
906 906
907 // Check for (0 / -x) that will produce negative zero. 907 // Check for (0 / -x) that will produce negative zero.
908 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 908 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
909 NearLabel left_not_zero; 909 Label left_not_zero;
910 __ test(left_reg, Operand(left_reg)); 910 __ test(left_reg, Operand(left_reg));
911 __ j(not_zero, &left_not_zero); 911 __ j(not_zero, &left_not_zero, Label::kNear);
912 __ test(right_reg, ToOperand(right)); 912 __ test(right_reg, ToOperand(right));
913 DeoptimizeIf(sign, instr->environment()); 913 DeoptimizeIf(sign, instr->environment());
914 __ bind(&left_not_zero); 914 __ bind(&left_not_zero);
915 } 915 }
916 916
917 // Check for (-kMinInt / -1). 917 // Check for (-kMinInt / -1).
918 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 918 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
919 NearLabel left_not_min_int; 919 Label left_not_min_int;
920 __ cmp(left_reg, kMinInt); 920 __ cmp(left_reg, kMinInt);
921 __ j(not_zero, &left_not_min_int); 921 __ j(not_zero, &left_not_min_int, Label::kNear);
922 __ cmp(right_reg, -1); 922 __ cmp(right_reg, -1);
923 DeoptimizeIf(zero, instr->environment()); 923 DeoptimizeIf(zero, instr->environment());
924 __ bind(&left_not_min_int); 924 __ bind(&left_not_min_int);
925 } 925 }
926 926
927 // Sign extend to edx. 927 // Sign extend to edx.
928 __ cdq(); 928 __ cdq();
929 __ idiv(right_reg); 929 __ idiv(right_reg);
930 930
931 // Deoptimize if remainder is not 0. 931 // Deoptimize if remainder is not 0.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 } else { 989 } else {
990 __ imul(left, ToOperand(right)); 990 __ imul(left, ToOperand(right));
991 } 991 }
992 992
993 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 993 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
994 DeoptimizeIf(overflow, instr->environment()); 994 DeoptimizeIf(overflow, instr->environment());
995 } 995 }
996 996
997 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 997 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
998 // Bail out if the result is supposed to be negative zero. 998 // Bail out if the result is supposed to be negative zero.
999 NearLabel done; 999 Label done;
1000 __ test(left, Operand(left)); 1000 __ test(left, Operand(left));
1001 __ j(not_zero, &done); 1001 __ j(not_zero, &done, Label::kNear);
1002 if (right->IsConstantOperand()) { 1002 if (right->IsConstantOperand()) {
1003 if (ToInteger32(LConstantOperand::cast(right)) <= 0) { 1003 if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
1004 DeoptimizeIf(no_condition, instr->environment()); 1004 DeoptimizeIf(no_condition, instr->environment());
1005 } 1005 }
1006 } else { 1006 } else {
1007 // Test the non-zero operand for negative sign. 1007 // Test the non-zero operand for negative sign.
1008 __ or_(ToRegister(instr->TempAt(0)), ToOperand(right)); 1008 __ or_(ToRegister(instr->TempAt(0)), ToOperand(right));
1009 DeoptimizeIf(sign, instr->environment()); 1009 DeoptimizeIf(sign, instr->environment());
1010 } 1010 }
1011 __ bind(&done); 1011 __ bind(&done);
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 Register array = ToRegister(instr->InputAt(0)); 1196 Register array = ToRegister(instr->InputAt(0));
1197 __ mov(result, FieldOperand(array, ExternalArray::kLengthOffset)); 1197 __ mov(result, FieldOperand(array, ExternalArray::kLengthOffset));
1198 } 1198 }
1199 1199
1200 1200
1201 void LCodeGen::DoValueOf(LValueOf* instr) { 1201 void LCodeGen::DoValueOf(LValueOf* instr) {
1202 Register input = ToRegister(instr->InputAt(0)); 1202 Register input = ToRegister(instr->InputAt(0));
1203 Register result = ToRegister(instr->result()); 1203 Register result = ToRegister(instr->result());
1204 Register map = ToRegister(instr->TempAt(0)); 1204 Register map = ToRegister(instr->TempAt(0));
1205 ASSERT(input.is(result)); 1205 ASSERT(input.is(result));
1206 NearLabel done; 1206 Label done;
1207 // If the object is a smi return the object. 1207 // If the object is a smi return the object.
1208 __ test(input, Immediate(kSmiTagMask)); 1208 __ test(input, Immediate(kSmiTagMask));
1209 __ j(zero, &done); 1209 __ j(zero, &done, Label::kNear);
1210 1210
1211 // If the object is not a value type, return the object. 1211 // If the object is not a value type, return the object.
1212 __ CmpObjectType(input, JS_VALUE_TYPE, map); 1212 __ CmpObjectType(input, JS_VALUE_TYPE, map);
1213 __ j(not_equal, &done); 1213 __ j(not_equal, &done, Label::kNear);
1214 __ mov(result, FieldOperand(input, JSValue::kValueOffset)); 1214 __ mov(result, FieldOperand(input, JSValue::kValueOffset));
1215 1215
1216 __ bind(&done); 1216 __ bind(&done);
1217 } 1217 }
1218 1218
1219 1219
1220 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1220 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1221 LOperand* input = instr->InputAt(0); 1221 LOperand* input = instr->InputAt(0);
1222 ASSERT(input->Equals(instr->result())); 1222 ASSERT(input->Equals(instr->result()));
1223 __ not_(ToRegister(input)); 1223 __ not_(ToRegister(input));
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 __ cmp(reg, factory()->true_value()); 1361 __ cmp(reg, factory()->true_value());
1362 __ j(equal, true_label); 1362 __ j(equal, true_label);
1363 __ cmp(reg, factory()->false_value()); 1363 __ cmp(reg, factory()->false_value());
1364 __ j(equal, false_label); 1364 __ j(equal, false_label);
1365 __ test(reg, Operand(reg)); 1365 __ test(reg, Operand(reg));
1366 __ j(equal, false_label); 1366 __ j(equal, false_label);
1367 __ test(reg, Immediate(kSmiTagMask)); 1367 __ test(reg, Immediate(kSmiTagMask));
1368 __ j(zero, true_label); 1368 __ j(zero, true_label);
1369 1369
1370 // Test for double values. Zero is false. 1370 // Test for double values. Zero is false.
1371 NearLabel call_stub; 1371 Label call_stub;
1372 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 1372 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
1373 factory()->heap_number_map()); 1373 factory()->heap_number_map());
1374 __ j(not_equal, &call_stub); 1374 __ j(not_equal, &call_stub, Label::kNear);
1375 __ fldz(); 1375 __ fldz();
1376 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); 1376 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
1377 __ FCmp(); 1377 __ FCmp();
1378 __ j(zero, false_label); 1378 __ j(zero, false_label);
1379 __ jmp(true_label); 1379 __ jmp(true_label);
1380 1380
1381 // The conversion stub doesn't cause garbage collections so it's 1381 // The conversion stub doesn't cause garbage collections so it's
1382 // safe to not record a safepoint after the call. 1382 // safe to not record a safepoint after the call.
1383 __ bind(&call_stub); 1383 __ bind(&call_stub);
1384 ToBooleanStub stub; 1384 ToBooleanStub stub;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 __ cmp(ToRegister(left), ToOperand(right)); 1470 __ cmp(ToRegister(left), ToOperand(right));
1471 } 1471 }
1472 } 1472 }
1473 1473
1474 1474
1475 void LCodeGen::DoCmpID(LCmpID* instr) { 1475 void LCodeGen::DoCmpID(LCmpID* instr) {
1476 LOperand* left = instr->InputAt(0); 1476 LOperand* left = instr->InputAt(0);
1477 LOperand* right = instr->InputAt(1); 1477 LOperand* right = instr->InputAt(1);
1478 LOperand* result = instr->result(); 1478 LOperand* result = instr->result();
1479 1479
1480 NearLabel unordered; 1480 Label unordered;
1481 if (instr->is_double()) { 1481 if (instr->is_double()) {
1482 // Don't base result on EFLAGS when a NaN is involved. Instead 1482 // Don't base result on EFLAGS when a NaN is involved. Instead
1483 // jump to the unordered case, which produces a false value. 1483 // jump to the unordered case, which produces a false value.
1484 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 1484 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
1485 __ j(parity_even, &unordered, not_taken); 1485 __ j(parity_even, &unordered, not_taken, Label::kNear);
1486 } else { 1486 } else {
1487 EmitCmpI(left, right); 1487 EmitCmpI(left, right);
1488 } 1488 }
1489 1489
1490 NearLabel done; 1490 Label done;
1491 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1491 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1492 __ mov(ToRegister(result), factory()->true_value()); 1492 __ mov(ToRegister(result), factory()->true_value());
1493 __ j(cc, &done); 1493 __ j(cc, &done, Label::kNear);
1494 1494
1495 __ bind(&unordered); 1495 __ bind(&unordered);
1496 __ mov(ToRegister(result), factory()->false_value()); 1496 __ mov(ToRegister(result), factory()->false_value());
1497 __ bind(&done); 1497 __ bind(&done);
1498 } 1498 }
1499 1499
1500 1500
1501 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1501 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
1502 LOperand* left = instr->InputAt(0); 1502 LOperand* left = instr->InputAt(0);
1503 LOperand* right = instr->InputAt(1); 1503 LOperand* right = instr->InputAt(1);
(...skipping 14 matching lines...) Expand all
1518 } 1518 }
1519 1519
1520 1520
1521 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { 1521 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
1522 Register left = ToRegister(instr->InputAt(0)); 1522 Register left = ToRegister(instr->InputAt(0));
1523 Register right = ToRegister(instr->InputAt(1)); 1523 Register right = ToRegister(instr->InputAt(1));
1524 Register result = ToRegister(instr->result()); 1524 Register result = ToRegister(instr->result());
1525 1525
1526 __ cmp(left, Operand(right)); 1526 __ cmp(left, Operand(right));
1527 __ mov(result, factory()->true_value()); 1527 __ mov(result, factory()->true_value());
1528 NearLabel done; 1528 Label done;
1529 __ j(equal, &done); 1529 __ j(equal, &done, Label::kNear);
1530 __ mov(result, factory()->false_value()); 1530 __ mov(result, factory()->false_value());
1531 __ bind(&done); 1531 __ bind(&done);
1532 } 1532 }
1533 1533
1534 1534
1535 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { 1535 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) {
1536 Register left = ToRegister(instr->InputAt(0)); 1536 Register left = ToRegister(instr->InputAt(0));
1537 Register right = ToRegister(instr->InputAt(1)); 1537 Register right = ToRegister(instr->InputAt(1));
1538 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1538 int false_block = chunk_->LookupDestination(instr->false_block_id());
1539 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1539 int true_block = chunk_->LookupDestination(instr->true_block_id());
1540 1540
1541 __ cmp(left, Operand(right)); 1541 __ cmp(left, Operand(right));
1542 EmitBranch(true_block, false_block, equal); 1542 EmitBranch(true_block, false_block, equal);
1543 } 1543 }
1544 1544
1545 1545
1546 void LCodeGen::DoIsNull(LIsNull* instr) { 1546 void LCodeGen::DoIsNull(LIsNull* instr) {
1547 Register reg = ToRegister(instr->InputAt(0)); 1547 Register reg = ToRegister(instr->InputAt(0));
1548 Register result = ToRegister(instr->result()); 1548 Register result = ToRegister(instr->result());
1549 1549
1550 // TODO(fsc): If the expression is known to be a smi, then it's 1550 // TODO(fsc): If the expression is known to be a smi, then it's
1551 // definitely not null. Materialize false. 1551 // definitely not null. Materialize false.
1552 1552
1553 __ cmp(reg, factory()->null_value()); 1553 __ cmp(reg, factory()->null_value());
1554 if (instr->is_strict()) { 1554 if (instr->is_strict()) {
1555 __ mov(result, factory()->true_value()); 1555 __ mov(result, factory()->true_value());
1556 NearLabel done; 1556 Label done;
1557 __ j(equal, &done); 1557 __ j(equal, &done, Label::kNear);
1558 __ mov(result, factory()->false_value()); 1558 __ mov(result, factory()->false_value());
1559 __ bind(&done); 1559 __ bind(&done);
1560 } else { 1560 } else {
1561 NearLabel true_value, false_value, done; 1561 Label true_value, false_value, done;
1562 __ j(equal, &true_value); 1562 __ j(equal, &true_value, Label::kNear);
1563 __ cmp(reg, factory()->undefined_value()); 1563 __ cmp(reg, factory()->undefined_value());
1564 __ j(equal, &true_value); 1564 __ j(equal, &true_value, Label::kNear);
1565 __ test(reg, Immediate(kSmiTagMask)); 1565 __ test(reg, Immediate(kSmiTagMask));
1566 __ j(zero, &false_value); 1566 __ j(zero, &false_value, Label::kNear);
1567 // Check for undetectable objects by looking in the bit field in 1567 // Check for undetectable objects by looking in the bit field in
1568 // the map. The object has already been smi checked. 1568 // the map. The object has already been smi checked.
1569 Register scratch = result; 1569 Register scratch = result;
1570 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); 1570 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1571 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); 1571 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
1572 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); 1572 __ test(scratch, Immediate(1 << Map::kIsUndetectable));
1573 __ j(not_zero, &true_value); 1573 __ j(not_zero, &true_value, Label::kNear);
1574 __ bind(&false_value); 1574 __ bind(&false_value);
1575 __ mov(result, factory()->false_value()); 1575 __ mov(result, factory()->false_value());
1576 __ jmp(&done); 1576 __ jmp(&done, Label::kNear);
1577 __ bind(&true_value); 1577 __ bind(&true_value);
1578 __ mov(result, factory()->true_value()); 1578 __ mov(result, factory()->true_value());
1579 __ bind(&done); 1579 __ bind(&done);
1580 } 1580 }
1581 } 1581 }
1582 1582
1583 1583
1584 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { 1584 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
1585 Register reg = ToRegister(instr->InputAt(0)); 1585 Register reg = ToRegister(instr->InputAt(0));
1586 1586
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 } 1677 }
1678 1678
1679 1679
1680 void LCodeGen::DoIsSmi(LIsSmi* instr) { 1680 void LCodeGen::DoIsSmi(LIsSmi* instr) {
1681 Operand input = ToOperand(instr->InputAt(0)); 1681 Operand input = ToOperand(instr->InputAt(0));
1682 Register result = ToRegister(instr->result()); 1682 Register result = ToRegister(instr->result());
1683 1683
1684 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1684 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1685 __ test(input, Immediate(kSmiTagMask)); 1685 __ test(input, Immediate(kSmiTagMask));
1686 __ mov(result, factory()->true_value()); 1686 __ mov(result, factory()->true_value());
1687 NearLabel done; 1687 Label done;
1688 __ j(zero, &done); 1688 __ j(zero, &done, Label::kNear);
1689 __ mov(result, factory()->false_value()); 1689 __ mov(result, factory()->false_value());
1690 __ bind(&done); 1690 __ bind(&done);
1691 } 1691 }
1692 1692
1693 1693
1694 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 1694 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
1695 Operand input = ToOperand(instr->InputAt(0)); 1695 Operand input = ToOperand(instr->InputAt(0));
1696 1696
1697 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1697 int true_block = chunk_->LookupDestination(instr->true_block_id());
1698 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1698 int false_block = chunk_->LookupDestination(instr->false_block_id());
(...skipping 22 matching lines...) Expand all
1721 return equal; 1721 return equal;
1722 } 1722 }
1723 1723
1724 1724
1725 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { 1725 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
1726 Register input = ToRegister(instr->InputAt(0)); 1726 Register input = ToRegister(instr->InputAt(0));
1727 Register result = ToRegister(instr->result()); 1727 Register result = ToRegister(instr->result());
1728 1728
1729 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1729 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1730 __ test(input, Immediate(kSmiTagMask)); 1730 __ test(input, Immediate(kSmiTagMask));
1731 NearLabel done, is_false; 1731 Label done, is_false;
1732 __ j(zero, &is_false); 1732 __ j(zero, &is_false, Label::kNear);
1733 __ CmpObjectType(input, TestType(instr->hydrogen()), result); 1733 __ CmpObjectType(input, TestType(instr->hydrogen()), result);
1734 __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false); 1734 __ j(NegateCondition(BranchCondition(instr->hydrogen())),
1735 &is_false, Label::kNear);
1735 __ mov(result, factory()->true_value()); 1736 __ mov(result, factory()->true_value());
1736 __ jmp(&done); 1737 __ jmp(&done, Label::kNear);
1737 __ bind(&is_false); 1738 __ bind(&is_false);
1738 __ mov(result, factory()->false_value()); 1739 __ mov(result, factory()->false_value());
1739 __ bind(&done); 1740 __ bind(&done);
1740 } 1741 }
1741 1742
1742 1743
1743 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 1744 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1744 Register input = ToRegister(instr->InputAt(0)); 1745 Register input = ToRegister(instr->InputAt(0));
1745 Register temp = ToRegister(instr->TempAt(0)); 1746 Register temp = ToRegister(instr->TempAt(0));
1746 1747
(...skipping 24 matching lines...) Expand all
1771 1772
1772 1773
1773 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { 1774 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
1774 Register input = ToRegister(instr->InputAt(0)); 1775 Register input = ToRegister(instr->InputAt(0));
1775 Register result = ToRegister(instr->result()); 1776 Register result = ToRegister(instr->result());
1776 1777
1777 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1778 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1778 __ mov(result, factory()->true_value()); 1779 __ mov(result, factory()->true_value());
1779 __ test(FieldOperand(input, String::kHashFieldOffset), 1780 __ test(FieldOperand(input, String::kHashFieldOffset),
1780 Immediate(String::kContainsCachedArrayIndexMask)); 1781 Immediate(String::kContainsCachedArrayIndexMask));
1781 NearLabel done; 1782 Label done;
1782 __ j(zero, &done); 1783 __ j(zero, &done, Label::kNear);
1783 __ mov(result, factory()->false_value()); 1784 __ mov(result, factory()->false_value());
1784 __ bind(&done); 1785 __ bind(&done);
1785 } 1786 }
1786 1787
1787 1788
1788 void LCodeGen::DoHasCachedArrayIndexAndBranch( 1789 void LCodeGen::DoHasCachedArrayIndexAndBranch(
1789 LHasCachedArrayIndexAndBranch* instr) { 1790 LHasCachedArrayIndexAndBranch* instr) {
1790 Register input = ToRegister(instr->InputAt(0)); 1791 Register input = ToRegister(instr->InputAt(0));
1791 1792
1792 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1793 int true_block = chunk_->LookupDestination(instr->true_block_id());
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1854 // End with the answer in the z flag. 1855 // End with the answer in the z flag.
1855 } 1856 }
1856 1857
1857 1858
1858 void LCodeGen::DoClassOfTest(LClassOfTest* instr) { 1859 void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
1859 Register input = ToRegister(instr->InputAt(0)); 1860 Register input = ToRegister(instr->InputAt(0));
1860 Register result = ToRegister(instr->result()); 1861 Register result = ToRegister(instr->result());
1861 ASSERT(input.is(result)); 1862 ASSERT(input.is(result));
1862 Register temp = ToRegister(instr->TempAt(0)); 1863 Register temp = ToRegister(instr->TempAt(0));
1863 Handle<String> class_name = instr->hydrogen()->class_name(); 1864 Handle<String> class_name = instr->hydrogen()->class_name();
1864 NearLabel done; 1865 Label done;
1865 Label is_true, is_false; 1866 Label is_true, is_false;
1866 1867
1867 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input); 1868 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input);
1868 1869
1869 __ j(not_equal, &is_false); 1870 __ j(not_equal, &is_false, Label::kNear);
1870 1871
1871 __ bind(&is_true); 1872 __ bind(&is_true);
1872 __ mov(result, factory()->true_value()); 1873 __ mov(result, factory()->true_value());
1873 __ jmp(&done); 1874 __ jmp(&done, Label::kNear);
1874 1875
1875 __ bind(&is_false); 1876 __ bind(&is_false);
1876 __ mov(result, factory()->false_value()); 1877 __ mov(result, factory()->false_value());
1877 __ bind(&done); 1878 __ bind(&done);
1878 } 1879 }
1879 1880
1880 1881
1881 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1882 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1882 Register input = ToRegister(instr->InputAt(0)); 1883 Register input = ToRegister(instr->InputAt(0));
1883 Register temp = ToRegister(instr->TempAt(0)); 1884 Register temp = ToRegister(instr->TempAt(0));
(...skipping 27 matching lines...) Expand all
1911 EmitBranch(true_block, false_block, equal); 1912 EmitBranch(true_block, false_block, equal);
1912 } 1913 }
1913 1914
1914 1915
1915 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 1916 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
1916 // Object and function are in fixed registers defined by the stub. 1917 // Object and function are in fixed registers defined by the stub.
1917 ASSERT(ToRegister(instr->context()).is(esi)); 1918 ASSERT(ToRegister(instr->context()).is(esi));
1918 InstanceofStub stub(InstanceofStub::kArgsInRegisters); 1919 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
1919 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 1920 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
1920 1921
1921 NearLabel true_value, done; 1922 Label true_value, done;
1922 __ test(eax, Operand(eax)); 1923 __ test(eax, Operand(eax));
1923 __ j(zero, &true_value); 1924 __ j(zero, &true_value, Label::kNear);
1924 __ mov(ToRegister(instr->result()), factory()->false_value()); 1925 __ mov(ToRegister(instr->result()), factory()->false_value());
1925 __ jmp(&done); 1926 __ jmp(&done, Label::kNear);
1926 __ bind(&true_value); 1927 __ bind(&true_value);
1927 __ mov(ToRegister(instr->result()), factory()->true_value()); 1928 __ mov(ToRegister(instr->result()), factory()->true_value());
1928 __ bind(&done); 1929 __ bind(&done);
1929 } 1930 }
1930 1931
1931 1932
1932 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { 1933 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) {
1933 ASSERT(ToRegister(instr->context()).is(esi)); 1934 ASSERT(ToRegister(instr->context()).is(esi));
1934 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1935 int true_block = chunk_->LookupDestination(instr->true_block_id());
1935 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1936 int false_block = chunk_->LookupDestination(instr->false_block_id());
(...skipping 29 matching lines...) Expand all
1965 Register object = ToRegister(instr->InputAt(0)); 1966 Register object = ToRegister(instr->InputAt(0));
1966 Register temp = ToRegister(instr->TempAt(0)); 1967 Register temp = ToRegister(instr->TempAt(0));
1967 1968
1968 // A Smi is not an instance of anything. 1969 // A Smi is not an instance of anything.
1969 __ test(object, Immediate(kSmiTagMask)); 1970 __ test(object, Immediate(kSmiTagMask));
1970 __ j(zero, &false_result, not_taken); 1971 __ j(zero, &false_result, not_taken);
1971 1972
1972 // This is the inlined call site instanceof cache. The two occurences of the 1973 // This is the inlined call site instanceof cache. The two occurences of the
1973 // hole value will be patched to the last map/result pair generated by the 1974 // hole value will be patched to the last map/result pair generated by the
1974 // instanceof stub. 1975 // instanceof stub.
1975 NearLabel cache_miss; 1976 Label cache_miss;
1976 Register map = ToRegister(instr->TempAt(0)); 1977 Register map = ToRegister(instr->TempAt(0));
1977 __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); 1978 __ mov(map, FieldOperand(object, HeapObject::kMapOffset));
1978 __ bind(deferred->map_check()); // Label for calculating code patching. 1979 __ bind(deferred->map_check()); // Label for calculating code patching.
1979 __ cmp(map, factory()->the_hole_value()); // Patched to cached map. 1980 __ cmp(map, factory()->the_hole_value()); // Patched to cached map.
1980 __ j(not_equal, &cache_miss, not_taken); 1981 __ j(not_equal, &cache_miss, not_taken, Label::kNear);
1981 __ mov(eax, factory()->the_hole_value()); // Patched to either true or false. 1982 __ mov(eax, factory()->the_hole_value()); // Patched to either true or false.
1982 __ jmp(&done); 1983 __ jmp(&done);
1983 1984
1984 // The inlined call site cache did not match. Check for null and string 1985 // The inlined call site cache did not match. Check for null and string
1985 // before calling the deferred code. 1986 // before calling the deferred code.
1986 __ bind(&cache_miss); 1987 __ bind(&cache_miss);
1987 // Null is not an instance of anything. 1988 // Null is not an instance of anything.
1988 __ cmp(object, factory()->null_value()); 1989 __ cmp(object, factory()->null_value());
1989 __ j(equal, &false_result); 1990 __ j(equal, &false_result);
1990 1991
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2062 void LCodeGen::DoCmpT(LCmpT* instr) { 2063 void LCodeGen::DoCmpT(LCmpT* instr) {
2063 Token::Value op = instr->op(); 2064 Token::Value op = instr->op();
2064 2065
2065 Handle<Code> ic = CompareIC::GetUninitialized(op); 2066 Handle<Code> ic = CompareIC::GetUninitialized(op);
2066 CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 2067 CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
2067 2068
2068 Condition condition = ComputeCompareCondition(op); 2069 Condition condition = ComputeCompareCondition(op);
2069 if (op == Token::GT || op == Token::LTE) { 2070 if (op == Token::GT || op == Token::LTE) {
2070 condition = ReverseCondition(condition); 2071 condition = ReverseCondition(condition);
2071 } 2072 }
2072 NearLabel true_value, done; 2073 Label true_value, done;
2073 __ test(eax, Operand(eax)); 2074 __ test(eax, Operand(eax));
2074 __ j(condition, &true_value); 2075 __ j(condition, &true_value, Label::kNear);
2075 __ mov(ToRegister(instr->result()), factory()->false_value()); 2076 __ mov(ToRegister(instr->result()), factory()->false_value());
2076 __ jmp(&done); 2077 __ jmp(&done, Label::kNear);
2077 __ bind(&true_value); 2078 __ bind(&true_value);
2078 __ mov(ToRegister(instr->result()), factory()->true_value()); 2079 __ mov(ToRegister(instr->result()), factory()->true_value());
2079 __ bind(&done); 2080 __ bind(&done);
2080 } 2081 }
2081 2082
2082 2083
2083 void LCodeGen::DoCmpTAndBranch(LCmpTAndBranch* instr) { 2084 void LCodeGen::DoCmpTAndBranch(LCmpTAndBranch* instr) {
2084 Token::Value op = instr->op(); 2085 Token::Value op = instr->op();
2085 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2086 int true_block = chunk_->LookupDestination(instr->true_block_id());
2086 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2087 int false_block = chunk_->LookupDestination(instr->false_block_id());
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 Register result = ToRegister(instr->result()); 2233 Register result = ToRegister(instr->result());
2233 2234
2234 int map_count = instr->hydrogen()->types()->length(); 2235 int map_count = instr->hydrogen()->types()->length();
2235 Handle<String> name = instr->hydrogen()->name(); 2236 Handle<String> name = instr->hydrogen()->name();
2236 if (map_count == 0) { 2237 if (map_count == 0) {
2237 ASSERT(instr->hydrogen()->need_generic()); 2238 ASSERT(instr->hydrogen()->need_generic());
2238 __ mov(ecx, name); 2239 __ mov(ecx, name);
2239 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2240 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2240 CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 2241 CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
2241 } else { 2242 } else {
2242 NearLabel done; 2243 Label done;
2243 for (int i = 0; i < map_count - 1; ++i) { 2244 for (int i = 0; i < map_count - 1; ++i) {
2244 Handle<Map> map = instr->hydrogen()->types()->at(i); 2245 Handle<Map> map = instr->hydrogen()->types()->at(i);
2245 NearLabel next; 2246 Label next;
2246 __ cmp(FieldOperand(object, HeapObject::kMapOffset), map); 2247 __ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
2247 __ j(not_equal, &next); 2248 __ j(not_equal, &next, Label::kNear);
2248 EmitLoadFieldOrConstantFunction(result, object, map, name); 2249 EmitLoadFieldOrConstantFunction(result, object, map, name);
2249 __ jmp(&done); 2250 __ jmp(&done, Label::kNear);
2250 __ bind(&next); 2251 __ bind(&next);
2251 } 2252 }
2252 Handle<Map> map = instr->hydrogen()->types()->last(); 2253 Handle<Map> map = instr->hydrogen()->types()->last();
2253 __ cmp(FieldOperand(object, HeapObject::kMapOffset), map); 2254 __ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
2254 if (instr->hydrogen()->need_generic()) { 2255 if (instr->hydrogen()->need_generic()) {
2255 NearLabel generic; 2256 Label generic;
2256 __ j(not_equal, &generic); 2257 __ j(not_equal, &generic, Label::kNear);
2257 EmitLoadFieldOrConstantFunction(result, object, map, name); 2258 EmitLoadFieldOrConstantFunction(result, object, map, name);
2258 __ jmp(&done); 2259 __ jmp(&done, Label::kNear);
2259 __ bind(&generic); 2260 __ bind(&generic);
2260 __ mov(ecx, name); 2261 __ mov(ecx, name);
2261 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2262 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2262 CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 2263 CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
2263 } else { 2264 } else {
2264 DeoptimizeIf(not_equal, instr->environment()); 2265 DeoptimizeIf(not_equal, instr->environment());
2265 EmitLoadFieldOrConstantFunction(result, object, map, name); 2266 EmitLoadFieldOrConstantFunction(result, object, map, name);
2266 } 2267 }
2267 __ bind(&done); 2268 __ bind(&done);
2268 } 2269 }
(...skipping 14 matching lines...) Expand all
2283 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 2284 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
2284 Register function = ToRegister(instr->function()); 2285 Register function = ToRegister(instr->function());
2285 Register temp = ToRegister(instr->TempAt(0)); 2286 Register temp = ToRegister(instr->TempAt(0));
2286 Register result = ToRegister(instr->result()); 2287 Register result = ToRegister(instr->result());
2287 2288
2288 // Check that the function really is a function. 2289 // Check that the function really is a function.
2289 __ CmpObjectType(function, JS_FUNCTION_TYPE, result); 2290 __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
2290 DeoptimizeIf(not_equal, instr->environment()); 2291 DeoptimizeIf(not_equal, instr->environment());
2291 2292
2292 // Check whether the function has an instance prototype. 2293 // Check whether the function has an instance prototype.
2293 NearLabel non_instance; 2294 Label non_instance;
2294 __ test_b(FieldOperand(result, Map::kBitFieldOffset), 2295 __ test_b(FieldOperand(result, Map::kBitFieldOffset),
2295 1 << Map::kHasNonInstancePrototype); 2296 1 << Map::kHasNonInstancePrototype);
2296 __ j(not_zero, &non_instance); 2297 __ j(not_zero, &non_instance, Label::kNear);
2297 2298
2298 // Get the prototype or initial map from the function. 2299 // Get the prototype or initial map from the function.
2299 __ mov(result, 2300 __ mov(result,
2300 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 2301 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
2301 2302
2302 // Check that the function has a prototype or an initial map. 2303 // Check that the function has a prototype or an initial map.
2303 __ cmp(Operand(result), Immediate(factory()->the_hole_value())); 2304 __ cmp(Operand(result), Immediate(factory()->the_hole_value()));
2304 DeoptimizeIf(equal, instr->environment()); 2305 DeoptimizeIf(equal, instr->environment());
2305 2306
2306 // If the function does not have an initial map, we're done. 2307 // If the function does not have an initial map, we're done.
2307 NearLabel done; 2308 Label done;
2308 __ CmpObjectType(result, MAP_TYPE, temp); 2309 __ CmpObjectType(result, MAP_TYPE, temp);
2309 __ j(not_equal, &done); 2310 __ j(not_equal, &done, Label::kNear);
2310 2311
2311 // Get the prototype from the initial map. 2312 // Get the prototype from the initial map.
2312 __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); 2313 __ mov(result, FieldOperand(result, Map::kPrototypeOffset));
2313 __ jmp(&done); 2314 __ jmp(&done, Label::kNear);
2314 2315
2315 // Non-instance prototype: Fetch prototype from constructor field 2316 // Non-instance prototype: Fetch prototype from constructor field
2316 // in the function's map. 2317 // in the function's map.
2317 __ bind(&non_instance); 2318 __ bind(&non_instance);
2318 __ mov(result, FieldOperand(result, Map::kConstructorOffset)); 2319 __ mov(result, FieldOperand(result, Map::kConstructorOffset));
2319 2320
2320 // All done. 2321 // All done.
2321 __ bind(&done); 2322 __ bind(&done);
2322 } 2323 }
2323 2324
2324 2325
2325 void LCodeGen::DoLoadElements(LLoadElements* instr) { 2326 void LCodeGen::DoLoadElements(LLoadElements* instr) {
2326 Register result = ToRegister(instr->result()); 2327 Register result = ToRegister(instr->result());
2327 Register input = ToRegister(instr->InputAt(0)); 2328 Register input = ToRegister(instr->InputAt(0));
2328 __ mov(result, FieldOperand(input, JSObject::kElementsOffset)); 2329 __ mov(result, FieldOperand(input, JSObject::kElementsOffset));
2329 if (FLAG_debug_code) { 2330 if (FLAG_debug_code) {
2330 NearLabel done; 2331 Label done;
2331 __ cmp(FieldOperand(result, HeapObject::kMapOffset), 2332 __ cmp(FieldOperand(result, HeapObject::kMapOffset),
2332 Immediate(factory()->fixed_array_map())); 2333 Immediate(factory()->fixed_array_map()));
2333 __ j(equal, &done); 2334 __ j(equal, &done, Label::kNear);
2334 __ cmp(FieldOperand(result, HeapObject::kMapOffset), 2335 __ cmp(FieldOperand(result, HeapObject::kMapOffset),
2335 Immediate(factory()->fixed_cow_array_map())); 2336 Immediate(factory()->fixed_cow_array_map()));
2336 __ j(equal, &done); 2337 __ j(equal, &done, Label::kNear);
2337 Register temp((result.is(eax)) ? ebx : eax); 2338 Register temp((result.is(eax)) ? ebx : eax);
2338 __ push(temp); 2339 __ push(temp);
2339 __ mov(temp, FieldOperand(result, HeapObject::kMapOffset)); 2340 __ mov(temp, FieldOperand(result, HeapObject::kMapOffset));
2340 __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); 2341 __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
2341 __ sub(Operand(temp), Immediate(FIRST_EXTERNAL_ARRAY_TYPE)); 2342 __ sub(Operand(temp), Immediate(FIRST_EXTERNAL_ARRAY_TYPE));
2342 __ cmp(Operand(temp), Immediate(kExternalArrayTypeCount)); 2343 __ cmp(Operand(temp), Immediate(kExternalArrayTypeCount));
2343 __ pop(temp); 2344 __ pop(temp);
2344 __ Check(below, "Check for fast elements or pixel array failed."); 2345 __ Check(below, "Check for fast elements or pixel array failed.");
2345 __ bind(&done); 2346 __ bind(&done);
2346 } 2347 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2444 2445
2445 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2446 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2446 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 2447 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
2447 } 2448 }
2448 2449
2449 2450
2450 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 2451 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
2451 Register result = ToRegister(instr->result()); 2452 Register result = ToRegister(instr->result());
2452 2453
2453 // Check for arguments adapter frame. 2454 // Check for arguments adapter frame.
2454 NearLabel done, adapted; 2455 Label done, adapted;
2455 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2456 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2456 __ mov(result, Operand(result, StandardFrameConstants::kContextOffset)); 2457 __ mov(result, Operand(result, StandardFrameConstants::kContextOffset));
2457 __ cmp(Operand(result), 2458 __ cmp(Operand(result),
2458 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 2459 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2459 __ j(equal, &adapted); 2460 __ j(equal, &adapted, Label::kNear);
2460 2461
2461 // No arguments adaptor frame. 2462 // No arguments adaptor frame.
2462 __ mov(result, Operand(ebp)); 2463 __ mov(result, Operand(ebp));
2463 __ jmp(&done); 2464 __ jmp(&done, Label::kNear);
2464 2465
2465 // Arguments adaptor frame present. 2466 // Arguments adaptor frame present.
2466 __ bind(&adapted); 2467 __ bind(&adapted);
2467 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2468 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2468 2469
2469 // Result is the frame pointer for the frame if not adapted and for the real 2470 // Result is the frame pointer for the frame if not adapted and for the real
2470 // frame below the adaptor frame if adapted. 2471 // frame below the adaptor frame if adapted.
2471 __ bind(&done); 2472 __ bind(&done);
2472 } 2473 }
2473 2474
2474 2475
2475 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 2476 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
2476 Operand elem = ToOperand(instr->InputAt(0)); 2477 Operand elem = ToOperand(instr->InputAt(0));
2477 Register result = ToRegister(instr->result()); 2478 Register result = ToRegister(instr->result());
2478 2479
2479 NearLabel done; 2480 Label done;
2480 2481
2481 // If no arguments adaptor frame the number of arguments is fixed. 2482 // If no arguments adaptor frame the number of arguments is fixed.
2482 __ cmp(ebp, elem); 2483 __ cmp(ebp, elem);
2483 __ mov(result, Immediate(scope()->num_parameters())); 2484 __ mov(result, Immediate(scope()->num_parameters()));
2484 __ j(equal, &done); 2485 __ j(equal, &done, Label::kNear);
2485 2486
2486 // Arguments adaptor frame present. Get argument length from there. 2487 // Arguments adaptor frame present. Get argument length from there.
2487 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2488 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2488 __ mov(result, Operand(result, 2489 __ mov(result, Operand(result,
2489 ArgumentsAdaptorFrameConstants::kLengthOffset)); 2490 ArgumentsAdaptorFrameConstants::kLengthOffset));
2490 __ SmiUntag(result); 2491 __ SmiUntag(result);
2491 2492
2492 // Argument length is in result register. 2493 // Argument length is in result register.
2493 __ bind(&done); 2494 __ bind(&done);
2494 } 2495 }
2495 2496
2496 2497
2497 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { 2498 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
2498 Register receiver = ToRegister(instr->receiver()); 2499 Register receiver = ToRegister(instr->receiver());
2499 Register function = ToRegister(instr->function()); 2500 Register function = ToRegister(instr->function());
2500 Register length = ToRegister(instr->length()); 2501 Register length = ToRegister(instr->length());
2501 Register elements = ToRegister(instr->elements()); 2502 Register elements = ToRegister(instr->elements());
2502 Register scratch = ToRegister(instr->TempAt(0)); 2503 Register scratch = ToRegister(instr->TempAt(0));
2503 ASSERT(receiver.is(eax)); // Used for parameter count. 2504 ASSERT(receiver.is(eax)); // Used for parameter count.
2504 ASSERT(function.is(edi)); // Required by InvokeFunction. 2505 ASSERT(function.is(edi)); // Required by InvokeFunction.
2505 ASSERT(ToRegister(instr->result()).is(eax)); 2506 ASSERT(ToRegister(instr->result()).is(eax));
2506 2507
2507 // If the receiver is null or undefined, we have to pass the global object 2508 // If the receiver is null or undefined, we have to pass the global object
2508 // as a receiver. 2509 // as a receiver.
2509 NearLabel global_object, receiver_ok; 2510 Label global_object, receiver_ok;
2510 __ cmp(receiver, factory()->null_value()); 2511 __ cmp(receiver, factory()->null_value());
2511 __ j(equal, &global_object); 2512 __ j(equal, &global_object, Label::kNear);
2512 __ cmp(receiver, factory()->undefined_value()); 2513 __ cmp(receiver, factory()->undefined_value());
2513 __ j(equal, &global_object); 2514 __ j(equal, &global_object, Label::kNear);
2514 2515
2515 // The receiver should be a JS object. 2516 // The receiver should be a JS object.
2516 __ test(receiver, Immediate(kSmiTagMask)); 2517 __ test(receiver, Immediate(kSmiTagMask));
2517 DeoptimizeIf(equal, instr->environment()); 2518 DeoptimizeIf(equal, instr->environment());
2518 __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, scratch); 2519 __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, scratch);
2519 DeoptimizeIf(below, instr->environment()); 2520 DeoptimizeIf(below, instr->environment());
2520 __ jmp(&receiver_ok); 2521 __ jmp(&receiver_ok, Label::kNear);
2521 2522
2522 __ bind(&global_object); 2523 __ bind(&global_object);
2523 // TODO(kmillikin): We have a hydrogen value for the global object. See 2524 // TODO(kmillikin): We have a hydrogen value for the global object. See
2524 // if it's better to use it than to explicitly fetch it from the context 2525 // if it's better to use it than to explicitly fetch it from the context
2525 // here. 2526 // here.
2526 __ mov(receiver, Operand(ebp, StandardFrameConstants::kContextOffset)); 2527 __ mov(receiver, Operand(ebp, StandardFrameConstants::kContextOffset));
2527 __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_INDEX)); 2528 __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_INDEX));
2528 __ bind(&receiver_ok); 2529 __ bind(&receiver_ok);
2529 2530
2530 // Copy the arguments to this function possibly from the 2531 // Copy the arguments to this function possibly from the
2531 // adaptor frame below it. 2532 // adaptor frame below it.
2532 const uint32_t kArgumentsLimit = 1 * KB; 2533 const uint32_t kArgumentsLimit = 1 * KB;
2533 __ cmp(length, kArgumentsLimit); 2534 __ cmp(length, kArgumentsLimit);
2534 DeoptimizeIf(above, instr->environment()); 2535 DeoptimizeIf(above, instr->environment());
2535 2536
2536 __ push(receiver); 2537 __ push(receiver);
2537 __ mov(receiver, length); 2538 __ mov(receiver, length);
2538 2539
2539 // Loop through the arguments pushing them onto the execution 2540 // Loop through the arguments pushing them onto the execution
2540 // stack. 2541 // stack.
2541 NearLabel invoke, loop; 2542 Label invoke, loop;
2542 // length is a small non-negative integer, due to the test above. 2543 // length is a small non-negative integer, due to the test above.
2543 __ test(length, Operand(length)); 2544 __ test(length, Operand(length));
2544 __ j(zero, &invoke); 2545 __ j(zero, &invoke, Label::kNear);
2545 __ bind(&loop); 2546 __ bind(&loop);
2546 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); 2547 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize));
2547 __ dec(length); 2548 __ dec(length);
2548 __ j(not_zero, &loop); 2549 __ j(not_zero, &loop);
2549 2550
2550 // Invoke the function. 2551 // Invoke the function.
2551 __ bind(&invoke); 2552 __ bind(&invoke);
2552 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 2553 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
2553 LPointerMap* pointers = instr->pointer_map(); 2554 LPointerMap* pointers = instr->pointer_map();
2554 LEnvironment* env = instr->deoptimization_environment(); 2555 LEnvironment* env = instr->deoptimization_environment();
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
2886 __ sub(Operand(esp), Immediate(kDoubleSize)); 2887 __ sub(Operand(esp), Immediate(kDoubleSize));
2887 __ fstp_d(Operand(esp, 0)); 2888 __ fstp_d(Operand(esp, 0));
2888 __ movdbl(result_reg, Operand(esp, 0)); 2889 __ movdbl(result_reg, Operand(esp, 0));
2889 __ add(Operand(esp), Immediate(kDoubleSize)); 2890 __ add(Operand(esp), Immediate(kDoubleSize));
2890 } 2891 }
2891 2892
2892 2893
2893 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { 2894 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
2894 ASSERT(instr->InputAt(0)->Equals(instr->result())); 2895 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2895 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2896 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2896 NearLabel positive, done, zero, negative; 2897 Label positive, done, zero;
2897 __ xorps(xmm0, xmm0); 2898 __ xorps(xmm0, xmm0);
2898 __ ucomisd(input_reg, xmm0); 2899 __ ucomisd(input_reg, xmm0);
2899 __ j(above, &positive); 2900 __ j(above, &positive, Label::kNear);
2900 __ j(equal, &zero); 2901 __ j(equal, &zero, Label::kNear);
2901 ExternalReference nan = ExternalReference::address_of_nan(); 2902 ExternalReference nan = ExternalReference::address_of_nan();
2902 __ movdbl(input_reg, Operand::StaticVariable(nan)); 2903 __ movdbl(input_reg, Operand::StaticVariable(nan));
2903 __ jmp(&done); 2904 __ jmp(&done, Label::kNear);
2904 __ bind(&zero); 2905 __ bind(&zero);
2905 __ push(Immediate(0xFFF00000)); 2906 __ push(Immediate(0xFFF00000));
2906 __ push(Immediate(0)); 2907 __ push(Immediate(0));
2907 __ movdbl(input_reg, Operand(esp, 0)); 2908 __ movdbl(input_reg, Operand(esp, 0));
2908 __ add(Operand(esp), Immediate(kDoubleSize)); 2909 __ add(Operand(esp), Immediate(kDoubleSize));
2909 __ jmp(&done); 2910 __ jmp(&done, Label::kNear);
2910 __ bind(&positive); 2911 __ bind(&positive);
2911 __ fldln2(); 2912 __ fldln2();
2912 __ sub(Operand(esp), Immediate(kDoubleSize)); 2913 __ sub(Operand(esp), Immediate(kDoubleSize));
2913 __ movdbl(Operand(esp, 0), input_reg); 2914 __ movdbl(Operand(esp, 0), input_reg);
2914 __ fld_d(Operand(esp, 0)); 2915 __ fld_d(Operand(esp, 0));
2915 __ fyl2x(); 2916 __ fyl2x();
2916 __ fstp_d(Operand(esp, 0)); 2917 __ fstp_d(Operand(esp, 0));
2917 __ movdbl(input_reg, Operand(esp, 0)); 2918 __ movdbl(input_reg, Operand(esp, 0));
2918 __ add(Operand(esp), Immediate(kDoubleSize)); 2919 __ add(Operand(esp), Immediate(kDoubleSize));
2919 __ bind(&done); 2920 __ bind(&done);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
3119 switch (array_type) { 3120 switch (array_type) {
3120 case kExternalPixelArray: { 3121 case kExternalPixelArray: {
3121 // Clamp the value to [0..255]. 3122 // Clamp the value to [0..255].
3122 Register temp = ToRegister(instr->TempAt(0)); 3123 Register temp = ToRegister(instr->TempAt(0));
3123 // The dec_b below requires that the clamped value is in a byte 3124 // The dec_b below requires that the clamped value is in a byte
3124 // register. eax is an arbitrary choice to satisfy this requirement, we 3125 // register. eax is an arbitrary choice to satisfy this requirement, we
3125 // hinted the register allocator to give us eax when building the 3126 // hinted the register allocator to give us eax when building the
3126 // instruction. 3127 // instruction.
3127 ASSERT(temp.is(eax)); 3128 ASSERT(temp.is(eax));
3128 __ mov(temp, ToRegister(instr->value())); 3129 __ mov(temp, ToRegister(instr->value()));
3129 NearLabel done; 3130 Label done;
3130 __ test(temp, Immediate(0xFFFFFF00)); 3131 __ test(temp, Immediate(0xFFFFFF00));
3131 __ j(zero, &done); 3132 __ j(zero, &done, Label::kNear);
3132 __ setcc(negative, temp); // 1 if negative, 0 if positive. 3133 __ setcc(negative, temp); // 1 if negative, 0 if positive.
3133 __ dec_b(temp); // 0 if negative, 255 if positive. 3134 __ dec_b(temp); // 0 if negative, 255 if positive.
3134 __ bind(&done); 3135 __ bind(&done);
3135 __ mov_b(Operand(external_pointer, key, times_1, 0), temp); 3136 __ mov_b(Operand(external_pointer, key, times_1, 0), temp);
3136 break; 3137 break;
3137 } 3138 }
3138 case kExternalByteArray: 3139 case kExternalByteArray:
3139 case kExternalUnsignedByteArray: 3140 case kExternalUnsignedByteArray:
3140 __ mov_b(Operand(external_pointer, key, times_1, 0), value); 3141 __ mov_b(Operand(external_pointer, key, times_1, 0), value);
3141 break; 3142 break;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3228 return; 3229 return;
3229 } 3230 }
3230 } else { 3231 } else {
3231 index = ToRegister(instr->index()); 3232 index = ToRegister(instr->index());
3232 } 3233 }
3233 Register result = ToRegister(instr->result()); 3234 Register result = ToRegister(instr->result());
3234 3235
3235 DeferredStringCharCodeAt* deferred = 3236 DeferredStringCharCodeAt* deferred =
3236 new DeferredStringCharCodeAt(this, instr); 3237 new DeferredStringCharCodeAt(this, instr);
3237 3238
3238 NearLabel flat_string, ascii_string, done; 3239 Label flat_string, ascii_string, done;
3239 3240
3240 // Fetch the instance type of the receiver into result register. 3241 // Fetch the instance type of the receiver into result register.
3241 __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); 3242 __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
3242 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); 3243 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
3243 3244
3244 // We need special handling for non-flat strings. 3245 // We need special handling for non-flat strings.
3245 STATIC_ASSERT(kSeqStringTag == 0); 3246 STATIC_ASSERT(kSeqStringTag == 0);
3246 __ test(result, Immediate(kStringRepresentationMask)); 3247 __ test(result, Immediate(kStringRepresentationMask));
3247 __ j(zero, &flat_string); 3248 __ j(zero, &flat_string, Label::kNear);
3248 3249
3249 // Handle non-flat strings. 3250 // Handle non-flat strings.
3250 __ test(result, Immediate(kIsConsStringMask)); 3251 __ test(result, Immediate(kIsConsStringMask));
3251 __ j(zero, deferred->entry()); 3252 __ j(zero, deferred->entry());
3252 3253
3253 // ConsString. 3254 // ConsString.
3254 // Check whether the right hand side is the empty string (i.e. if 3255 // Check whether the right hand side is the empty string (i.e. if
3255 // this is really a flat string in a cons string). If that is not 3256 // this is really a flat string in a cons string). If that is not
3256 // the case we would rather go to the runtime system now to flatten 3257 // the case we would rather go to the runtime system now to flatten
3257 // the string. 3258 // the string.
3258 __ cmp(FieldOperand(string, ConsString::kSecondOffset), 3259 __ cmp(FieldOperand(string, ConsString::kSecondOffset),
3259 Immediate(factory()->empty_string())); 3260 Immediate(factory()->empty_string()));
3260 __ j(not_equal, deferred->entry()); 3261 __ j(not_equal, deferred->entry());
3261 // Get the first of the two strings and load its instance type. 3262 // Get the first of the two strings and load its instance type.
3262 __ mov(string, FieldOperand(string, ConsString::kFirstOffset)); 3263 __ mov(string, FieldOperand(string, ConsString::kFirstOffset));
3263 __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); 3264 __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
3264 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); 3265 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
3265 // If the first cons component is also non-flat, then go to runtime. 3266 // If the first cons component is also non-flat, then go to runtime.
3266 STATIC_ASSERT(kSeqStringTag == 0); 3267 STATIC_ASSERT(kSeqStringTag == 0);
3267 __ test(result, Immediate(kStringRepresentationMask)); 3268 __ test(result, Immediate(kStringRepresentationMask));
3268 __ j(not_zero, deferred->entry()); 3269 __ j(not_zero, deferred->entry());
3269 3270
3270 // Check for ASCII or two-byte string. 3271 // Check for ASCII or two-byte string.
3271 __ bind(&flat_string); 3272 __ bind(&flat_string);
3272 STATIC_ASSERT(kAsciiStringTag != 0); 3273 STATIC_ASSERT(kAsciiStringTag != 0);
3273 __ test(result, Immediate(kStringEncodingMask)); 3274 __ test(result, Immediate(kStringEncodingMask));
3274 __ j(not_zero, &ascii_string); 3275 __ j(not_zero, &ascii_string, Label::kNear);
3275 3276
3276 // Two-byte string. 3277 // Two-byte string.
3277 // Load the two-byte character code into the result register. 3278 // Load the two-byte character code into the result register.
3278 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 3279 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
3279 if (instr->index()->IsConstantOperand()) { 3280 if (instr->index()->IsConstantOperand()) {
3280 __ movzx_w(result, 3281 __ movzx_w(result,
3281 FieldOperand(string, 3282 FieldOperand(string,
3282 SeqTwoByteString::kHeaderSize + 3283 SeqTwoByteString::kHeaderSize +
3283 (kUC16Size * const_index))); 3284 (kUC16Size * const_index)));
3284 } else { 3285 } else {
3285 __ movzx_w(result, FieldOperand(string, 3286 __ movzx_w(result, FieldOperand(string,
3286 index, 3287 index,
3287 times_2, 3288 times_2,
3288 SeqTwoByteString::kHeaderSize)); 3289 SeqTwoByteString::kHeaderSize));
3289 } 3290 }
3290 __ jmp(&done); 3291 __ jmp(&done, Label::kNear);
3291 3292
3292 // ASCII string. 3293 // ASCII string.
3293 // Load the byte into the result register. 3294 // Load the byte into the result register.
3294 __ bind(&ascii_string); 3295 __ bind(&ascii_string);
3295 if (instr->index()->IsConstantOperand()) { 3296 if (instr->index()->IsConstantOperand()) {
3296 __ movzx_b(result, FieldOperand(string, 3297 __ movzx_b(result, FieldOperand(string,
3297 SeqAsciiString::kHeaderSize + const_index)); 3298 SeqAsciiString::kHeaderSize + const_index));
3298 } else { 3299 } else {
3299 __ movzx_b(result, FieldOperand(string, 3300 __ movzx_b(result, FieldOperand(string,
3300 index, 3301 index,
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
3441 Label slow; 3442 Label slow;
3442 Register reg = ToRegister(instr->InputAt(0)); 3443 Register reg = ToRegister(instr->InputAt(0));
3443 Register tmp = reg.is(eax) ? ecx : eax; 3444 Register tmp = reg.is(eax) ? ecx : eax;
3444 3445
3445 // Preserve the value of all registers. 3446 // Preserve the value of all registers.
3446 PushSafepointRegistersScope scope(this); 3447 PushSafepointRegistersScope scope(this);
3447 3448
3448 // There was overflow, so bits 30 and 31 of the original integer 3449 // There was overflow, so bits 30 and 31 of the original integer
3449 // disagree. Try to allocate a heap number in new space and store 3450 // disagree. Try to allocate a heap number in new space and store
3450 // the value in there. If that fails, call the runtime system. 3451 // the value in there. If that fails, call the runtime system.
3451 NearLabel done; 3452 Label done;
3452 __ SmiUntag(reg); 3453 __ SmiUntag(reg);
3453 __ xor_(reg, 0x80000000); 3454 __ xor_(reg, 0x80000000);
3454 __ cvtsi2sd(xmm0, Operand(reg)); 3455 __ cvtsi2sd(xmm0, Operand(reg));
3455 if (FLAG_inline_new) { 3456 if (FLAG_inline_new) {
3456 __ AllocateHeapNumber(reg, tmp, no_reg, &slow); 3457 __ AllocateHeapNumber(reg, tmp, no_reg, &slow);
3457 __ jmp(&done); 3458 __ jmp(&done, Label::kNear);
3458 } 3459 }
3459 3460
3460 // Slow case: Call the runtime system to do the number allocation. 3461 // Slow case: Call the runtime system to do the number allocation.
3461 __ bind(&slow); 3462 __ bind(&slow);
3462 3463
3463 // TODO(3095996): Put a valid pointer value in the stack slot where the result 3464 // TODO(3095996): Put a valid pointer value in the stack slot where the result
3464 // register is stored, as this register is in the pointer map, but contains an 3465 // register is stored, as this register is in the pointer map, but contains an
3465 // integer value. 3466 // integer value.
3466 __ StoreToSafepointRegisterSlot(reg, Immediate(0)); 3467 __ StoreToSafepointRegisterSlot(reg, Immediate(0));
3467 3468
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3529 __ test(ToRegister(input), Immediate(kSmiTagMask)); 3530 __ test(ToRegister(input), Immediate(kSmiTagMask));
3530 DeoptimizeIf(not_zero, instr->environment()); 3531 DeoptimizeIf(not_zero, instr->environment());
3531 } 3532 }
3532 __ SmiUntag(ToRegister(input)); 3533 __ SmiUntag(ToRegister(input));
3533 } 3534 }
3534 3535
3535 3536
3536 void LCodeGen::EmitNumberUntagD(Register input_reg, 3537 void LCodeGen::EmitNumberUntagD(Register input_reg,
3537 XMMRegister result_reg, 3538 XMMRegister result_reg,
3538 LEnvironment* env) { 3539 LEnvironment* env) {
3539 NearLabel load_smi, heap_number, done; 3540 Label load_smi, heap_number, done;
3540 3541
3541 // Smi check. 3542 // Smi check.
3542 __ test(input_reg, Immediate(kSmiTagMask)); 3543 __ test(input_reg, Immediate(kSmiTagMask));
3543 __ j(zero, &load_smi, not_taken); 3544 __ j(zero, &load_smi, not_taken, Label::kNear);
3544 3545
3545 // Heap number map check. 3546 // Heap number map check.
3546 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 3547 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
3547 factory()->heap_number_map()); 3548 factory()->heap_number_map());
3548 __ j(equal, &heap_number); 3549 __ j(equal, &heap_number, Label::kNear);
3549 3550
3550 __ cmp(input_reg, factory()->undefined_value()); 3551 __ cmp(input_reg, factory()->undefined_value());
3551 DeoptimizeIf(not_equal, env); 3552 DeoptimizeIf(not_equal, env);
3552 3553
3553 // Convert undefined to NaN. 3554 // Convert undefined to NaN.
3554 ExternalReference nan = ExternalReference::address_of_nan(); 3555 ExternalReference nan = ExternalReference::address_of_nan();
3555 __ movdbl(result_reg, Operand::StaticVariable(nan)); 3556 __ movdbl(result_reg, Operand::StaticVariable(nan));
3556 __ jmp(&done); 3557 __ jmp(&done, Label::kNear);
3557 3558
3558 // Heap number to XMM conversion. 3559 // Heap number to XMM conversion.
3559 __ bind(&heap_number); 3560 __ bind(&heap_number);
3560 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3561 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
3561 __ jmp(&done); 3562 __ jmp(&done, Label::kNear);
3562 3563
3563 // Smi to XMM conversion 3564 // Smi to XMM conversion
3564 __ bind(&load_smi); 3565 __ bind(&load_smi);
3565 __ SmiUntag(input_reg); // Untag smi before converting to float. 3566 __ SmiUntag(input_reg); // Untag smi before converting to float.
3566 __ cvtsi2sd(result_reg, Operand(input_reg)); 3567 __ cvtsi2sd(result_reg, Operand(input_reg));
3567 __ SmiTag(input_reg); // Retag smi. 3568 __ SmiTag(input_reg); // Retag smi.
3568 __ bind(&done); 3569 __ bind(&done);
3569 } 3570 }
3570 3571
3571 3572
3572 class DeferredTaggedToI: public LDeferredCode { 3573 class DeferredTaggedToI: public LDeferredCode {
3573 public: 3574 public:
3574 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 3575 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
3575 : LDeferredCode(codegen), instr_(instr) { } 3576 : LDeferredCode(codegen), instr_(instr) { }
3576 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 3577 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
3577 private: 3578 private:
3578 LTaggedToI* instr_; 3579 LTaggedToI* instr_;
3579 }; 3580 };
3580 3581
3581 3582
3582 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 3583 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
3583 NearLabel done, heap_number; 3584 Label done, heap_number;
3584 Register input_reg = ToRegister(instr->InputAt(0)); 3585 Register input_reg = ToRegister(instr->InputAt(0));
3585 3586
3586 // Heap number map check. 3587 // Heap number map check.
3587 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 3588 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
3588 factory()->heap_number_map()); 3589 factory()->heap_number_map());
3589 3590
3590 if (instr->truncating()) { 3591 if (instr->truncating()) {
3591 __ j(equal, &heap_number); 3592 __ j(equal, &heap_number, Label::kNear);
3592 // Check for undefined. Undefined is converted to zero for truncating 3593 // Check for undefined. Undefined is converted to zero for truncating
3593 // conversions. 3594 // conversions.
3594 __ cmp(input_reg, factory()->undefined_value()); 3595 __ cmp(input_reg, factory()->undefined_value());
3595 DeoptimizeIf(not_equal, instr->environment()); 3596 DeoptimizeIf(not_equal, instr->environment());
3596 __ mov(input_reg, 0); 3597 __ mov(input_reg, 0);
3597 __ jmp(&done); 3598 __ jmp(&done, Label::kNear);
3598 3599
3599 __ bind(&heap_number); 3600 __ bind(&heap_number);
3600 if (CpuFeatures::IsSupported(SSE3)) { 3601 if (CpuFeatures::IsSupported(SSE3)) {
3601 CpuFeatures::Scope scope(SSE3); 3602 CpuFeatures::Scope scope(SSE3);
3602 NearLabel convert; 3603 Label convert;
3603 // Use more powerful conversion when sse3 is available. 3604 // Use more powerful conversion when sse3 is available.
3604 // Load x87 register with heap number. 3605 // Load x87 register with heap number.
3605 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 3606 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
3606 // Get exponent alone and check for too-big exponent. 3607 // Get exponent alone and check for too-big exponent.
3607 __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 3608 __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
3608 __ and_(input_reg, HeapNumber::kExponentMask); 3609 __ and_(input_reg, HeapNumber::kExponentMask);
3609 const uint32_t kTooBigExponent = 3610 const uint32_t kTooBigExponent =
3610 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; 3611 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
3611 __ cmp(Operand(input_reg), Immediate(kTooBigExponent)); 3612 __ cmp(Operand(input_reg), Immediate(kTooBigExponent));
3612 __ j(less, &convert); 3613 __ j(less, &convert, Label::kNear);
3613 // Pop FPU stack before deoptimizing. 3614 // Pop FPU stack before deoptimizing.
3614 __ ffree(0); 3615 __ ffree(0);
3615 __ fincstp(); 3616 __ fincstp();
3616 DeoptimizeIf(no_condition, instr->environment()); 3617 DeoptimizeIf(no_condition, instr->environment());
3617 3618
3618 // Reserve space for 64 bit answer. 3619 // Reserve space for 64 bit answer.
3619 __ bind(&convert); 3620 __ bind(&convert);
3620 __ sub(Operand(esp), Immediate(kDoubleSize)); 3621 __ sub(Operand(esp), Immediate(kDoubleSize));
3621 // Do conversion, which cannot fail because we checked the exponent. 3622 // Do conversion, which cannot fail because we checked the exponent.
3622 __ fisttp_d(Operand(esp, 0)); 3623 __ fisttp_d(Operand(esp, 0));
3623 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result. 3624 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result.
3624 __ add(Operand(esp), Immediate(kDoubleSize)); 3625 __ add(Operand(esp), Immediate(kDoubleSize));
3625 } else { 3626 } else {
3626 NearLabel deopt;
3627 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); 3627 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
3628 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3628 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
3629 __ cvttsd2si(input_reg, Operand(xmm0)); 3629 __ cvttsd2si(input_reg, Operand(xmm0));
3630 __ cmp(input_reg, 0x80000000u); 3630 __ cmp(input_reg, 0x80000000u);
3631 __ j(not_equal, &done); 3631 __ j(not_equal, &done);
3632 // Check if the input was 0x8000000 (kMinInt). 3632 // Check if the input was 0x8000000 (kMinInt).
3633 // If no, then we got an overflow and we deoptimize. 3633 // If no, then we got an overflow and we deoptimize.
3634 ExternalReference min_int = ExternalReference::address_of_min_int(); 3634 ExternalReference min_int = ExternalReference::address_of_min_int();
3635 __ movdbl(xmm_temp, Operand::StaticVariable(min_int)); 3635 __ movdbl(xmm_temp, Operand::StaticVariable(min_int));
3636 __ ucomisd(xmm_temp, xmm0); 3636 __ ucomisd(xmm_temp, xmm0);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3703 Register result_reg = ToRegister(result); 3703 Register result_reg = ToRegister(result);
3704 3704
3705 if (instr->truncating()) { 3705 if (instr->truncating()) {
3706 // Performs a truncating conversion of a floating point number as used by 3706 // Performs a truncating conversion of a floating point number as used by
3707 // the JS bitwise operations. 3707 // the JS bitwise operations.
3708 __ cvttsd2si(result_reg, Operand(input_reg)); 3708 __ cvttsd2si(result_reg, Operand(input_reg));
3709 __ cmp(result_reg, 0x80000000u); 3709 __ cmp(result_reg, 0x80000000u);
3710 if (CpuFeatures::IsSupported(SSE3)) { 3710 if (CpuFeatures::IsSupported(SSE3)) {
3711 // This will deoptimize if the exponent of the input in out of range. 3711 // This will deoptimize if the exponent of the input in out of range.
3712 CpuFeatures::Scope scope(SSE3); 3712 CpuFeatures::Scope scope(SSE3);
3713 NearLabel convert, done; 3713 Label convert, done;
3714 __ j(not_equal, &done); 3714 __ j(not_equal, &done, Label::kNear);
3715 __ sub(Operand(esp), Immediate(kDoubleSize)); 3715 __ sub(Operand(esp), Immediate(kDoubleSize));
3716 __ movdbl(Operand(esp, 0), input_reg); 3716 __ movdbl(Operand(esp, 0), input_reg);
3717 // Get exponent alone and check for too-big exponent. 3717 // Get exponent alone and check for too-big exponent.
3718 __ mov(result_reg, Operand(esp, sizeof(int32_t))); 3718 __ mov(result_reg, Operand(esp, sizeof(int32_t)));
3719 __ and_(result_reg, HeapNumber::kExponentMask); 3719 __ and_(result_reg, HeapNumber::kExponentMask);
3720 const uint32_t kTooBigExponent = 3720 const uint32_t kTooBigExponent =
3721 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; 3721 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
3722 __ cmp(Operand(result_reg), Immediate(kTooBigExponent)); 3722 __ cmp(Operand(result_reg), Immediate(kTooBigExponent));
3723 __ j(less, &convert); 3723 __ j(less, &convert, Label::kNear);
3724 __ add(Operand(esp), Immediate(kDoubleSize)); 3724 __ add(Operand(esp), Immediate(kDoubleSize));
3725 DeoptimizeIf(no_condition, instr->environment()); 3725 DeoptimizeIf(no_condition, instr->environment());
3726 __ bind(&convert); 3726 __ bind(&convert);
3727 // Do conversion, which cannot fail because we checked the exponent. 3727 // Do conversion, which cannot fail because we checked the exponent.
3728 __ fld_d(Operand(esp, 0)); 3728 __ fld_d(Operand(esp, 0));
3729 __ fisttp_d(Operand(esp, 0)); 3729 __ fisttp_d(Operand(esp, 0));
3730 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result. 3730 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result.
3731 __ add(Operand(esp), Immediate(kDoubleSize)); 3731 __ add(Operand(esp), Immediate(kDoubleSize));
3732 __ bind(&done); 3732 __ bind(&done);
3733 } else { 3733 } else {
3734 NearLabel done; 3734 Label done;
3735 Register temp_reg = ToRegister(instr->TempAt(0)); 3735 Register temp_reg = ToRegister(instr->TempAt(0));
3736 XMMRegister xmm_scratch = xmm0; 3736 XMMRegister xmm_scratch = xmm0;
3737 3737
3738 // If cvttsd2si succeeded, we're done. Otherwise, we attempt 3738 // If cvttsd2si succeeded, we're done. Otherwise, we attempt
3739 // manual conversion. 3739 // manual conversion.
3740 __ j(not_equal, &done); 3740 __ j(not_equal, &done, Label::kNear);
3741 3741
3742 // Get high 32 bits of the input in result_reg and temp_reg. 3742 // Get high 32 bits of the input in result_reg and temp_reg.
3743 __ pshufd(xmm_scratch, input_reg, 1); 3743 __ pshufd(xmm_scratch, input_reg, 1);
3744 __ movd(Operand(temp_reg), xmm_scratch); 3744 __ movd(Operand(temp_reg), xmm_scratch);
3745 __ mov(result_reg, temp_reg); 3745 __ mov(result_reg, temp_reg);
3746 3746
3747 // Prepare negation mask in temp_reg. 3747 // Prepare negation mask in temp_reg.
3748 __ sar(temp_reg, kBitsPerInt - 1); 3748 __ sar(temp_reg, kBitsPerInt - 1);
3749 3749
3750 // Extract the exponent from result_reg and subtract adjusted 3750 // Extract the exponent from result_reg and subtract adjusted
(...skipping 29 matching lines...) Expand all
3780 // Shift the input right and extract low 32 bits. 3780 // Shift the input right and extract low 32 bits.
3781 __ psrlq(input_reg, xmm_scratch); 3781 __ psrlq(input_reg, xmm_scratch);
3782 __ movd(Operand(result_reg), input_reg); 3782 __ movd(Operand(result_reg), input_reg);
3783 3783
3784 // Use the prepared mask in temp_reg to negate the result if necessary. 3784 // Use the prepared mask in temp_reg to negate the result if necessary.
3785 __ xor_(result_reg, Operand(temp_reg)); 3785 __ xor_(result_reg, Operand(temp_reg));
3786 __ sub(result_reg, Operand(temp_reg)); 3786 __ sub(result_reg, Operand(temp_reg));
3787 __ bind(&done); 3787 __ bind(&done);
3788 } 3788 }
3789 } else { 3789 } else {
3790 NearLabel done; 3790 Label done;
3791 __ cvttsd2si(result_reg, Operand(input_reg)); 3791 __ cvttsd2si(result_reg, Operand(input_reg));
3792 __ cvtsi2sd(xmm0, Operand(result_reg)); 3792 __ cvtsi2sd(xmm0, Operand(result_reg));
3793 __ ucomisd(xmm0, input_reg); 3793 __ ucomisd(xmm0, input_reg);
3794 DeoptimizeIf(not_equal, instr->environment()); 3794 DeoptimizeIf(not_equal, instr->environment());
3795 DeoptimizeIf(parity_even, instr->environment()); // NaN. 3795 DeoptimizeIf(parity_even, instr->environment()); // NaN.
3796 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3796 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3797 // The integer converted back is equal to the original. We 3797 // The integer converted back is equal to the original. We
3798 // only have to test if we got -0 as an input. 3798 // only have to test if we got -0 as an input.
3799 __ test(result_reg, Operand(result_reg)); 3799 __ test(result_reg, Operand(result_reg));
3800 __ j(not_zero, &done); 3800 __ j(not_zero, &done, Label::kNear);
3801 __ movmskpd(result_reg, input_reg); 3801 __ movmskpd(result_reg, input_reg);
3802 // Bit 0 contains the sign of the double in input_reg. 3802 // Bit 0 contains the sign of the double in input_reg.
3803 // If input was positive, we are ok and return 0, otherwise 3803 // If input was positive, we are ok and return 0, otherwise
3804 // deoptimize. 3804 // deoptimize.
3805 __ and_(result_reg, 1); 3805 __ and_(result_reg, 1);
3806 DeoptimizeIf(not_zero, instr->environment()); 3806 DeoptimizeIf(not_zero, instr->environment());
3807 } 3807 }
3808 __ bind(&done); 3808 __ bind(&done);
3809 } 3809 }
3810 } 3810 }
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
3967 3967
3968 3968
3969 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { 3969 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
3970 ASSERT(ToRegister(instr->InputAt(0)).is(eax)); 3970 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
3971 __ push(eax); 3971 __ push(eax);
3972 CallRuntime(Runtime::kToFastProperties, 1, instr, CONTEXT_ADJUSTED); 3972 CallRuntime(Runtime::kToFastProperties, 1, instr, CONTEXT_ADJUSTED);
3973 } 3973 }
3974 3974
3975 3975
3976 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 3976 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
3977 NearLabel materialized; 3977 Label materialized;
3978 // Registers will be used as follows: 3978 // Registers will be used as follows:
3979 // edi = JS function. 3979 // edi = JS function.
3980 // ecx = literals array. 3980 // ecx = literals array.
3981 // ebx = regexp literal. 3981 // ebx = regexp literal.
3982 // eax = regexp literal clone. 3982 // eax = regexp literal clone.
3983 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 3983 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
3984 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); 3984 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset));
3985 int literal_offset = FixedArray::kHeaderSize + 3985 int literal_offset = FixedArray::kHeaderSize +
3986 instr->hydrogen()->literal_index() * kPointerSize; 3986 instr->hydrogen()->literal_index() * kPointerSize;
3987 __ mov(ebx, FieldOperand(ecx, literal_offset)); 3987 __ mov(ebx, FieldOperand(ecx, literal_offset));
3988 __ cmp(ebx, factory()->undefined_value()); 3988 __ cmp(ebx, factory()->undefined_value());
3989 __ j(not_equal, &materialized); 3989 __ j(not_equal, &materialized, Label::kNear);
3990 3990
3991 // Create regexp literal using runtime function 3991 // Create regexp literal using runtime function
3992 // Result will be in eax. 3992 // Result will be in eax.
3993 __ push(ecx); 3993 __ push(ecx);
3994 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); 3994 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
3995 __ push(Immediate(instr->hydrogen()->pattern())); 3995 __ push(Immediate(instr->hydrogen()->pattern()));
3996 __ push(Immediate(instr->hydrogen()->flags())); 3996 __ push(Immediate(instr->hydrogen()->flags()));
3997 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr, RESTORE_CONTEXT); 3997 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr, RESTORE_CONTEXT);
3998 __ mov(ebx, eax); 3998 __ mov(ebx, eax);
3999 3999
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4055 } 4055 }
4056 CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT); 4056 CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT);
4057 } 4057 }
4058 4058
4059 4059
4060 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { 4060 void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
4061 Register input = ToRegister(instr->InputAt(0)); 4061 Register input = ToRegister(instr->InputAt(0));
4062 Register result = ToRegister(instr->result()); 4062 Register result = ToRegister(instr->result());
4063 Label true_label; 4063 Label true_label;
4064 Label false_label; 4064 Label false_label;
4065 NearLabel done; 4065 Label done;
4066 4066
4067 Condition final_branch_condition = EmitTypeofIs(&true_label, 4067 Condition final_branch_condition = EmitTypeofIs(&true_label,
4068 &false_label, 4068 &false_label,
4069 input, 4069 input,
4070 instr->type_literal()); 4070 instr->type_literal());
4071 __ j(final_branch_condition, &true_label); 4071 __ j(final_branch_condition, &true_label, Label::kNear);
4072 __ bind(&false_label); 4072 __ bind(&false_label);
4073 __ mov(result, factory()->false_value()); 4073 __ mov(result, factory()->false_value());
4074 __ jmp(&done); 4074 __ jmp(&done, Label::kNear);
4075 4075
4076 __ bind(&true_label); 4076 __ bind(&true_label);
4077 __ mov(result, factory()->true_value()); 4077 __ mov(result, factory()->true_value());
4078 4078
4079 __ bind(&done); 4079 __ bind(&done);
4080 } 4080 }
4081 4081
4082 4082
4083 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 4083 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
4084 Register input = ToRegister(instr->InputAt(0)); 4084 Register input = ToRegister(instr->InputAt(0));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
4158 __ jmp(false_label); 4158 __ jmp(false_label);
4159 // A dead branch instruction will be generated after this point. 4159 // A dead branch instruction will be generated after this point.
4160 } 4160 }
4161 4161
4162 return final_branch_condition; 4162 return final_branch_condition;
4163 } 4163 }
4164 4164
4165 4165
4166 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) { 4166 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
4167 Register result = ToRegister(instr->result()); 4167 Register result = ToRegister(instr->result());
4168 NearLabel true_label; 4168 Label true_label;
4169 NearLabel false_label; 4169 Label done;
4170 NearLabel done;
4171 4170
4172 EmitIsConstructCall(result); 4171 EmitIsConstructCall(result);
4173 __ j(equal, &true_label); 4172 __ j(equal, &true_label, Label::kNear);
4174 4173
4175 __ mov(result, factory()->false_value()); 4174 __ mov(result, factory()->false_value());
4176 __ jmp(&done); 4175 __ jmp(&done, Label::kNear);
4177 4176
4178 __ bind(&true_label); 4177 __ bind(&true_label);
4179 __ mov(result, factory()->true_value()); 4178 __ mov(result, factory()->true_value());
4180 4179
4181 __ bind(&done); 4180 __ bind(&done);
4182 } 4181 }
4183 4182
4184 4183
4185 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 4184 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
4186 Register temp = ToRegister(instr->TempAt(0)); 4185 Register temp = ToRegister(instr->TempAt(0));
4187 int true_block = chunk_->LookupDestination(instr->true_block_id()); 4186 int true_block = chunk_->LookupDestination(instr->true_block_id());
4188 int false_block = chunk_->LookupDestination(instr->false_block_id()); 4187 int false_block = chunk_->LookupDestination(instr->false_block_id());
4189 4188
4190 EmitIsConstructCall(temp); 4189 EmitIsConstructCall(temp);
4191 EmitBranch(true_block, false_block, equal); 4190 EmitBranch(true_block, false_block, equal);
4192 } 4191 }
4193 4192
4194 4193
4195 void LCodeGen::EmitIsConstructCall(Register temp) { 4194 void LCodeGen::EmitIsConstructCall(Register temp) {
4196 // Get the frame pointer for the calling frame. 4195 // Get the frame pointer for the calling frame.
4197 __ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 4196 __ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
4198 4197
4199 // Skip the arguments adaptor frame if it exists. 4198 // Skip the arguments adaptor frame if it exists.
4200 NearLabel check_frame_marker; 4199 Label check_frame_marker;
4201 __ cmp(Operand(temp, StandardFrameConstants::kContextOffset), 4200 __ cmp(Operand(temp, StandardFrameConstants::kContextOffset),
4202 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 4201 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
4203 __ j(not_equal, &check_frame_marker); 4202 __ j(not_equal, &check_frame_marker, Label::kNear);
4204 __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); 4203 __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset));
4205 4204
4206 // Check the marker in the calling frame. 4205 // Check the marker in the calling frame.
4207 __ bind(&check_frame_marker); 4206 __ bind(&check_frame_marker);
4208 __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), 4207 __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset),
4209 Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); 4208 Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
4210 } 4209 }
4211 4210
4212 4211
4213 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { 4212 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
(...skipping 28 matching lines...) Expand all
4242 pointers, 4241 pointers,
4243 env->deoptimization_index()); 4242 env->deoptimization_index());
4244 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4243 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4245 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 4244 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
4246 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator); 4245 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator);
4247 } 4246 }
4248 4247
4249 4248
4250 void LCodeGen::DoStackCheck(LStackCheck* instr) { 4249 void LCodeGen::DoStackCheck(LStackCheck* instr) {
4251 // Perform stack overflow check. 4250 // Perform stack overflow check.
4252 NearLabel done; 4251 Label done;
4253 ExternalReference stack_limit = 4252 ExternalReference stack_limit =
4254 ExternalReference::address_of_stack_limit(isolate()); 4253 ExternalReference::address_of_stack_limit(isolate());
4255 __ cmp(esp, Operand::StaticVariable(stack_limit)); 4254 __ cmp(esp, Operand::StaticVariable(stack_limit));
4256 __ j(above_equal, &done); 4255 __ j(above_equal, &done, Label::kNear);
4257 4256
4258 StackCheckStub stub; 4257 StackCheckStub stub;
4259 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 4258 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
4260 __ bind(&done); 4259 __ bind(&done);
4261 } 4260 }
4262 4261
4263 4262
4264 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { 4263 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
4265 // This is a pseudo-instruction that ensures that the environment here is 4264 // This is a pseudo-instruction that ensures that the environment here is
4266 // properly registered for deoptimization and records the assembler's PC 4265 // properly registered for deoptimization and records the assembler's PC
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4305 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4304 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4306 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4305 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4307 } 4306 }
4308 4307
4309 4308
4310 #undef __ 4309 #undef __
4311 4310
4312 } } // namespace v8::internal 4311 } } // namespace v8::internal
4313 4312
4314 #endif // V8_TARGET_ARCH_IA32 4313 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698