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

Side by Side Diff: src/crankshaft/mips64/lithium-codegen-mips64.cc

Issue 2161543002: [turbofan] Add support for eager/soft deoptimization reasons. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Do the ports properly Created 4 years, 5 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/crankshaft/mips64/lithium-codegen-mips64.h" 5 #include "src/crankshaft/mips64/lithium-codegen-mips64.h"
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/crankshaft/hydrogen-osr.h" 9 #include "src/crankshaft/hydrogen-osr.h"
10 #include "src/crankshaft/mips64/lithium-gap-resolver-mips64.h" 10 #include "src/crankshaft/mips64/lithium-gap-resolver-mips64.h"
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 WriteTranslation(environment, &translation); 725 WriteTranslation(environment, &translation);
726 int deoptimization_index = deoptimizations_.length(); 726 int deoptimization_index = deoptimizations_.length();
727 int pc_offset = masm()->pc_offset(); 727 int pc_offset = masm()->pc_offset();
728 environment->Register(deoptimization_index, 728 environment->Register(deoptimization_index,
729 translation.index(), 729 translation.index(),
730 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 730 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
731 deoptimizations_.Add(environment, zone()); 731 deoptimizations_.Add(environment, zone());
732 } 732 }
733 } 733 }
734 734
735
736 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, 735 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
737 Deoptimizer::DeoptReason deopt_reason, 736 DeoptimizeReason deopt_reason,
738 Deoptimizer::BailoutType bailout_type, 737 Deoptimizer::BailoutType bailout_type,
739 Register src1, const Operand& src2) { 738 Register src1, const Operand& src2) {
740 LEnvironment* environment = instr->environment(); 739 LEnvironment* environment = instr->environment();
741 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 740 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
742 DCHECK(environment->HasBeenRegistered()); 741 DCHECK(environment->HasBeenRegistered());
743 int id = environment->deoptimization_index(); 742 int id = environment->deoptimization_index();
744 Address entry = 743 Address entry =
745 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); 744 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
746 if (entry == NULL) { 745 if (entry == NULL) {
747 Abort(kBailoutWasNotPrepared); 746 Abort(kBailoutWasNotPrepared);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 // jump entry if this is the case. 792 // jump entry if this is the case.
794 if (FLAG_trace_deopt || isolate()->is_profiling() || 793 if (FLAG_trace_deopt || isolate()->is_profiling() ||
795 jump_table_.is_empty() || 794 jump_table_.is_empty() ||
796 !table_entry->IsEquivalentTo(*jump_table_.last())) { 795 !table_entry->IsEquivalentTo(*jump_table_.last())) {
797 jump_table_.Add(table_entry, zone()); 796 jump_table_.Add(table_entry, zone());
798 } 797 }
799 __ Branch(&jump_table_.last()->label, condition, src1, src2); 798 __ Branch(&jump_table_.last()->label, condition, src1, src2);
800 } 799 }
801 } 800 }
802 801
803
804 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, 802 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
805 Deoptimizer::DeoptReason deopt_reason, 803 DeoptimizeReason deopt_reason, Register src1,
806 Register src1, const Operand& src2) { 804 const Operand& src2) {
807 Deoptimizer::BailoutType bailout_type = info()->IsStub() 805 Deoptimizer::BailoutType bailout_type = info()->IsStub()
808 ? Deoptimizer::LAZY 806 ? Deoptimizer::LAZY
809 : Deoptimizer::EAGER; 807 : Deoptimizer::EAGER;
810 DeoptimizeIf(condition, instr, deopt_reason, bailout_type, src1, src2); 808 DeoptimizeIf(condition, instr, deopt_reason, bailout_type, src1, src2);
811 } 809 }
812 810
813 811
814 void LCodeGen::RecordSafepointWithLazyDeopt( 812 void LCodeGen::RecordSafepointWithLazyDeopt(
815 LInstruction* instr, SafepointMode safepoint_mode) { 813 LInstruction* instr, SafepointMode safepoint_mode) {
816 if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { 814 if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 HMod* hmod = instr->hydrogen(); 926 HMod* hmod = instr->hydrogen();
929 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 927 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
930 Label dividend_is_not_negative, done; 928 Label dividend_is_not_negative, done;
931 929
932 if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) { 930 if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) {
933 __ Branch(&dividend_is_not_negative, ge, dividend, Operand(zero_reg)); 931 __ Branch(&dividend_is_not_negative, ge, dividend, Operand(zero_reg));
934 // Note: The code below even works when right contains kMinInt. 932 // Note: The code below even works when right contains kMinInt.
935 __ dsubu(dividend, zero_reg, dividend); 933 __ dsubu(dividend, zero_reg, dividend);
936 __ And(dividend, dividend, Operand(mask)); 934 __ And(dividend, dividend, Operand(mask));
937 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 935 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
938 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, dividend, 936 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, dividend,
939 Operand(zero_reg)); 937 Operand(zero_reg));
940 } 938 }
941 __ Branch(USE_DELAY_SLOT, &done); 939 __ Branch(USE_DELAY_SLOT, &done);
942 __ dsubu(dividend, zero_reg, dividend); 940 __ dsubu(dividend, zero_reg, dividend);
943 } 941 }
944 942
945 __ bind(&dividend_is_not_negative); 943 __ bind(&dividend_is_not_negative);
946 __ And(dividend, dividend, Operand(mask)); 944 __ And(dividend, dividend, Operand(mask));
947 __ bind(&done); 945 __ bind(&done);
948 } 946 }
949 947
950 948
951 void LCodeGen::DoModByConstI(LModByConstI* instr) { 949 void LCodeGen::DoModByConstI(LModByConstI* instr) {
952 Register dividend = ToRegister(instr->dividend()); 950 Register dividend = ToRegister(instr->dividend());
953 int32_t divisor = instr->divisor(); 951 int32_t divisor = instr->divisor();
954 Register result = ToRegister(instr->result()); 952 Register result = ToRegister(instr->result());
955 DCHECK(!dividend.is(result)); 953 DCHECK(!dividend.is(result));
956 954
957 if (divisor == 0) { 955 if (divisor == 0) {
958 DeoptimizeIf(al, instr, Deoptimizer::kDivisionByZero); 956 DeoptimizeIf(al, instr, DeoptimizeReason::kDivisionByZero);
959 return; 957 return;
960 } 958 }
961 959
962 __ TruncatingDiv(result, dividend, Abs(divisor)); 960 __ TruncatingDiv(result, dividend, Abs(divisor));
963 __ Dmul(result, result, Operand(Abs(divisor))); 961 __ Dmul(result, result, Operand(Abs(divisor)));
964 __ Dsubu(result, dividend, Operand(result)); 962 __ Dsubu(result, dividend, Operand(result));
965 963
966 // Check for negative zero. 964 // Check for negative zero.
967 HMod* hmod = instr->hydrogen(); 965 HMod* hmod = instr->hydrogen();
968 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 966 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
969 Label remainder_not_zero; 967 Label remainder_not_zero;
970 __ Branch(&remainder_not_zero, ne, result, Operand(zero_reg)); 968 __ Branch(&remainder_not_zero, ne, result, Operand(zero_reg));
971 DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero, dividend, 969 DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero, dividend,
972 Operand(zero_reg)); 970 Operand(zero_reg));
973 __ bind(&remainder_not_zero); 971 __ bind(&remainder_not_zero);
974 } 972 }
975 } 973 }
976 974
977 975
978 void LCodeGen::DoModI(LModI* instr) { 976 void LCodeGen::DoModI(LModI* instr) {
979 HMod* hmod = instr->hydrogen(); 977 HMod* hmod = instr->hydrogen();
980 const Register left_reg = ToRegister(instr->left()); 978 const Register left_reg = ToRegister(instr->left());
981 const Register right_reg = ToRegister(instr->right()); 979 const Register right_reg = ToRegister(instr->right());
982 const Register result_reg = ToRegister(instr->result()); 980 const Register result_reg = ToRegister(instr->result());
983 981
984 // div runs in the background while we check for special cases. 982 // div runs in the background while we check for special cases.
985 __ Dmod(result_reg, left_reg, right_reg); 983 __ Dmod(result_reg, left_reg, right_reg);
986 984
987 Label done; 985 Label done;
988 // Check for x % 0, we have to deopt in this case because we can't return a 986 // Check for x % 0, we have to deopt in this case because we can't return a
989 // NaN. 987 // NaN.
990 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { 988 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
991 DeoptimizeIf(eq, instr, Deoptimizer::kDivisionByZero, right_reg, 989 DeoptimizeIf(eq, instr, DeoptimizeReason::kDivisionByZero, right_reg,
992 Operand(zero_reg)); 990 Operand(zero_reg));
993 } 991 }
994 992
995 // Check for kMinInt % -1, div will return kMinInt, which is not what we 993 // Check for kMinInt % -1, div will return kMinInt, which is not what we
996 // want. We have to deopt if we care about -0, because we can't return that. 994 // want. We have to deopt if we care about -0, because we can't return that.
997 if (hmod->CheckFlag(HValue::kCanOverflow)) { 995 if (hmod->CheckFlag(HValue::kCanOverflow)) {
998 Label no_overflow_possible; 996 Label no_overflow_possible;
999 __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt)); 997 __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt));
1000 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 998 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1001 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, right_reg, Operand(-1)); 999 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, right_reg,
1000 Operand(-1));
1002 } else { 1001 } else {
1003 __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1)); 1002 __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1));
1004 __ Branch(USE_DELAY_SLOT, &done); 1003 __ Branch(USE_DELAY_SLOT, &done);
1005 __ mov(result_reg, zero_reg); 1004 __ mov(result_reg, zero_reg);
1006 } 1005 }
1007 __ bind(&no_overflow_possible); 1006 __ bind(&no_overflow_possible);
1008 } 1007 }
1009 1008
1010 // If we care about -0, test if the dividend is <0 and the result is 0. 1009 // If we care about -0, test if the dividend is <0 and the result is 0.
1011 __ Branch(&done, ge, left_reg, Operand(zero_reg)); 1010 __ Branch(&done, ge, left_reg, Operand(zero_reg));
1012 1011
1013 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1012 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1014 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, result_reg, 1013 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, result_reg,
1015 Operand(zero_reg)); 1014 Operand(zero_reg));
1016 } 1015 }
1017 __ bind(&done); 1016 __ bind(&done);
1018 } 1017 }
1019 1018
1020 1019
1021 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { 1020 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1022 Register dividend = ToRegister(instr->dividend()); 1021 Register dividend = ToRegister(instr->dividend());
1023 int32_t divisor = instr->divisor(); 1022 int32_t divisor = instr->divisor();
1024 Register result = ToRegister(instr->result()); 1023 Register result = ToRegister(instr->result());
1025 DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor))); 1024 DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor)));
1026 DCHECK(!result.is(dividend)); 1025 DCHECK(!result.is(dividend));
1027 1026
1028 // Check for (0 / -x) that will produce negative zero. 1027 // Check for (0 / -x) that will produce negative zero.
1029 HDiv* hdiv = instr->hydrogen(); 1028 HDiv* hdiv = instr->hydrogen();
1030 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1029 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1031 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, dividend, 1030 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, dividend,
1032 Operand(zero_reg)); 1031 Operand(zero_reg));
1033 } 1032 }
1034 // Check for (kMinInt / -1). 1033 // Check for (kMinInt / -1).
1035 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { 1034 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
1036 DeoptimizeIf(eq, instr, Deoptimizer::kOverflow, dividend, Operand(kMinInt)); 1035 DeoptimizeIf(eq, instr, DeoptimizeReason::kOverflow, dividend,
1036 Operand(kMinInt));
1037 } 1037 }
1038 // Deoptimize if remainder will not be 0. 1038 // Deoptimize if remainder will not be 0.
1039 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && 1039 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1040 divisor != 1 && divisor != -1) { 1040 divisor != 1 && divisor != -1) {
1041 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1041 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
1042 __ And(at, dividend, Operand(mask)); 1042 __ And(at, dividend, Operand(mask));
1043 DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecision, at, Operand(zero_reg)); 1043 DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecision, at,
1044 Operand(zero_reg));
1044 } 1045 }
1045 1046
1046 if (divisor == -1) { // Nice shortcut, not needed for correctness. 1047 if (divisor == -1) { // Nice shortcut, not needed for correctness.
1047 __ Dsubu(result, zero_reg, dividend); 1048 __ Dsubu(result, zero_reg, dividend);
1048 return; 1049 return;
1049 } 1050 }
1050 uint16_t shift = WhichPowerOf2Abs(divisor); 1051 uint16_t shift = WhichPowerOf2Abs(divisor);
1051 if (shift == 0) { 1052 if (shift == 0) {
1052 __ Move(result, dividend); 1053 __ Move(result, dividend);
1053 } else if (shift == 1) { 1054 } else if (shift == 1) {
1054 __ dsrl32(result, dividend, 31); 1055 __ dsrl32(result, dividend, 31);
1055 __ Daddu(result, dividend, Operand(result)); 1056 __ Daddu(result, dividend, Operand(result));
1056 } else { 1057 } else {
1057 __ dsra32(result, dividend, 31); 1058 __ dsra32(result, dividend, 31);
1058 __ dsrl32(result, result, 32 - shift); 1059 __ dsrl32(result, result, 32 - shift);
1059 __ Daddu(result, dividend, Operand(result)); 1060 __ Daddu(result, dividend, Operand(result));
1060 } 1061 }
1061 if (shift > 0) __ dsra(result, result, shift); 1062 if (shift > 0) __ dsra(result, result, shift);
1062 if (divisor < 0) __ Dsubu(result, zero_reg, result); 1063 if (divisor < 0) __ Dsubu(result, zero_reg, result);
1063 } 1064 }
1064 1065
1065 1066
1066 void LCodeGen::DoDivByConstI(LDivByConstI* instr) { 1067 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
1067 Register dividend = ToRegister(instr->dividend()); 1068 Register dividend = ToRegister(instr->dividend());
1068 int32_t divisor = instr->divisor(); 1069 int32_t divisor = instr->divisor();
1069 Register result = ToRegister(instr->result()); 1070 Register result = ToRegister(instr->result());
1070 DCHECK(!dividend.is(result)); 1071 DCHECK(!dividend.is(result));
1071 1072
1072 if (divisor == 0) { 1073 if (divisor == 0) {
1073 DeoptimizeIf(al, instr, Deoptimizer::kDivisionByZero); 1074 DeoptimizeIf(al, instr, DeoptimizeReason::kDivisionByZero);
1074 return; 1075 return;
1075 } 1076 }
1076 1077
1077 // Check for (0 / -x) that will produce negative zero. 1078 // Check for (0 / -x) that will produce negative zero.
1078 HDiv* hdiv = instr->hydrogen(); 1079 HDiv* hdiv = instr->hydrogen();
1079 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1080 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1080 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, dividend, 1081 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, dividend,
1081 Operand(zero_reg)); 1082 Operand(zero_reg));
1082 } 1083 }
1083 1084
1084 __ TruncatingDiv(result, dividend, Abs(divisor)); 1085 __ TruncatingDiv(result, dividend, Abs(divisor));
1085 if (divisor < 0) __ Subu(result, zero_reg, result); 1086 if (divisor < 0) __ Subu(result, zero_reg, result);
1086 1087
1087 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { 1088 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1088 __ Dmul(scratch0(), result, Operand(divisor)); 1089 __ Dmul(scratch0(), result, Operand(divisor));
1089 __ Dsubu(scratch0(), scratch0(), dividend); 1090 __ Dsubu(scratch0(), scratch0(), dividend);
1090 DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecision, scratch0(), 1091 DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecision, scratch0(),
1091 Operand(zero_reg)); 1092 Operand(zero_reg));
1092 } 1093 }
1093 } 1094 }
1094 1095
1095 1096
1096 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. 1097 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
1097 void LCodeGen::DoDivI(LDivI* instr) { 1098 void LCodeGen::DoDivI(LDivI* instr) {
1098 HBinaryOperation* hdiv = instr->hydrogen(); 1099 HBinaryOperation* hdiv = instr->hydrogen();
1099 Register dividend = ToRegister(instr->dividend()); 1100 Register dividend = ToRegister(instr->dividend());
1100 Register divisor = ToRegister(instr->divisor()); 1101 Register divisor = ToRegister(instr->divisor());
1101 const Register result = ToRegister(instr->result()); 1102 const Register result = ToRegister(instr->result());
1102 1103
1103 // On MIPS div is asynchronous - it will run in the background while we 1104 // On MIPS div is asynchronous - it will run in the background while we
1104 // check for special cases. 1105 // check for special cases.
1105 __ Div(result, dividend, divisor); 1106 __ Div(result, dividend, divisor);
1106 1107
1107 // Check for x / 0. 1108 // Check for x / 0.
1108 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1109 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
1109 DeoptimizeIf(eq, instr, Deoptimizer::kDivisionByZero, divisor, 1110 DeoptimizeIf(eq, instr, DeoptimizeReason::kDivisionByZero, divisor,
1110 Operand(zero_reg)); 1111 Operand(zero_reg));
1111 } 1112 }
1112 1113
1113 // Check for (0 / -x) that will produce negative zero. 1114 // Check for (0 / -x) that will produce negative zero.
1114 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1115 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1115 Label left_not_zero; 1116 Label left_not_zero;
1116 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg)); 1117 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
1117 DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero, divisor, 1118 DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero, divisor,
1118 Operand(zero_reg)); 1119 Operand(zero_reg));
1119 __ bind(&left_not_zero); 1120 __ bind(&left_not_zero);
1120 } 1121 }
1121 1122
1122 // Check for (kMinInt / -1). 1123 // Check for (kMinInt / -1).
1123 if (hdiv->CheckFlag(HValue::kCanOverflow) && 1124 if (hdiv->CheckFlag(HValue::kCanOverflow) &&
1124 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1125 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1125 Label left_not_min_int; 1126 Label left_not_min_int;
1126 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt)); 1127 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
1127 DeoptimizeIf(eq, instr, Deoptimizer::kOverflow, divisor, Operand(-1)); 1128 DeoptimizeIf(eq, instr, DeoptimizeReason::kOverflow, divisor, Operand(-1));
1128 __ bind(&left_not_min_int); 1129 __ bind(&left_not_min_int);
1129 } 1130 }
1130 1131
1131 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1132 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1132 // Calculate remainder. 1133 // Calculate remainder.
1133 Register remainder = ToRegister(instr->temp()); 1134 Register remainder = ToRegister(instr->temp());
1134 if (kArchVariant != kMips64r6) { 1135 if (kArchVariant != kMips64r6) {
1135 __ mfhi(remainder); 1136 __ mfhi(remainder);
1136 } else { 1137 } else {
1137 __ dmod(remainder, dividend, divisor); 1138 __ dmod(remainder, dividend, divisor);
1138 } 1139 }
1139 DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecision, remainder, 1140 DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecision, remainder,
1140 Operand(zero_reg)); 1141 Operand(zero_reg));
1141 } 1142 }
1142 } 1143 }
1143 1144
1144 1145
1145 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { 1146 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
1146 DoubleRegister addend = ToDoubleRegister(instr->addend()); 1147 DoubleRegister addend = ToDoubleRegister(instr->addend());
1147 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); 1148 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier());
1148 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand()); 1149 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
1149 1150
(...skipping 25 matching lines...) Expand all
1175 return; 1176 return;
1176 } 1177 }
1177 1178
1178 // If the divisor is negative, we have to negate and handle edge cases. 1179 // If the divisor is negative, we have to negate and handle edge cases.
1179 // Dividend can be the same register as result so save the value of it 1180 // Dividend can be the same register as result so save the value of it
1180 // for checking overflow. 1181 // for checking overflow.
1181 __ Move(scratch, dividend); 1182 __ Move(scratch, dividend);
1182 1183
1183 __ Dsubu(result, zero_reg, dividend); 1184 __ Dsubu(result, zero_reg, dividend);
1184 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1185 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1185 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, result, Operand(zero_reg)); 1186 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, result,
1187 Operand(zero_reg));
1186 } 1188 }
1187 1189
1188 __ Xor(scratch, scratch, result); 1190 __ Xor(scratch, scratch, result);
1189 // Dividing by -1 is basically negation, unless we overflow. 1191 // Dividing by -1 is basically negation, unless we overflow.
1190 if (divisor == -1) { 1192 if (divisor == -1) {
1191 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 1193 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1192 DeoptimizeIf(gt, instr, Deoptimizer::kOverflow, result, Operand(kMaxInt)); 1194 DeoptimizeIf(gt, instr, DeoptimizeReason::kOverflow, result,
1195 Operand(kMaxInt));
1193 } 1196 }
1194 return; 1197 return;
1195 } 1198 }
1196 1199
1197 // If the negation could not overflow, simply shifting is OK. 1200 // If the negation could not overflow, simply shifting is OK.
1198 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 1201 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1199 __ dsra(result, result, shift); 1202 __ dsra(result, result, shift);
1200 return; 1203 return;
1201 } 1204 }
1202 1205
1203 Label no_overflow, done; 1206 Label no_overflow, done;
1204 __ Branch(&no_overflow, lt, scratch, Operand(zero_reg)); 1207 __ Branch(&no_overflow, lt, scratch, Operand(zero_reg));
1205 __ li(result, Operand(kMinInt / divisor), CONSTANT_SIZE); 1208 __ li(result, Operand(kMinInt / divisor), CONSTANT_SIZE);
1206 __ Branch(&done); 1209 __ Branch(&done);
1207 __ bind(&no_overflow); 1210 __ bind(&no_overflow);
1208 __ dsra(result, result, shift); 1211 __ dsra(result, result, shift);
1209 __ bind(&done); 1212 __ bind(&done);
1210 } 1213 }
1211 1214
1212 1215
1213 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { 1216 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
1214 Register dividend = ToRegister(instr->dividend()); 1217 Register dividend = ToRegister(instr->dividend());
1215 int32_t divisor = instr->divisor(); 1218 int32_t divisor = instr->divisor();
1216 Register result = ToRegister(instr->result()); 1219 Register result = ToRegister(instr->result());
1217 DCHECK(!dividend.is(result)); 1220 DCHECK(!dividend.is(result));
1218 1221
1219 if (divisor == 0) { 1222 if (divisor == 0) {
1220 DeoptimizeIf(al, instr, Deoptimizer::kDivisionByZero); 1223 DeoptimizeIf(al, instr, DeoptimizeReason::kDivisionByZero);
1221 return; 1224 return;
1222 } 1225 }
1223 1226
1224 // Check for (0 / -x) that will produce negative zero. 1227 // Check for (0 / -x) that will produce negative zero.
1225 HMathFloorOfDiv* hdiv = instr->hydrogen(); 1228 HMathFloorOfDiv* hdiv = instr->hydrogen();
1226 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1229 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1227 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, dividend, 1230 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, dividend,
1228 Operand(zero_reg)); 1231 Operand(zero_reg));
1229 } 1232 }
1230 1233
1231 // Easy case: We need no dynamic check for the dividend and the flooring 1234 // Easy case: We need no dynamic check for the dividend and the flooring
1232 // division is the same as the truncating division. 1235 // division is the same as the truncating division.
1233 if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) || 1236 if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) ||
1234 (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) { 1237 (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) {
1235 __ TruncatingDiv(result, dividend, Abs(divisor)); 1238 __ TruncatingDiv(result, dividend, Abs(divisor));
1236 if (divisor < 0) __ Dsubu(result, zero_reg, result); 1239 if (divisor < 0) __ Dsubu(result, zero_reg, result);
1237 return; 1240 return;
(...skipping 24 matching lines...) Expand all
1262 Register dividend = ToRegister(instr->dividend()); 1265 Register dividend = ToRegister(instr->dividend());
1263 Register divisor = ToRegister(instr->divisor()); 1266 Register divisor = ToRegister(instr->divisor());
1264 const Register result = ToRegister(instr->result()); 1267 const Register result = ToRegister(instr->result());
1265 1268
1266 // On MIPS div is asynchronous - it will run in the background while we 1269 // On MIPS div is asynchronous - it will run in the background while we
1267 // check for special cases. 1270 // check for special cases.
1268 __ Ddiv(result, dividend, divisor); 1271 __ Ddiv(result, dividend, divisor);
1269 1272
1270 // Check for x / 0. 1273 // Check for x / 0.
1271 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1274 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
1272 DeoptimizeIf(eq, instr, Deoptimizer::kDivisionByZero, divisor, 1275 DeoptimizeIf(eq, instr, DeoptimizeReason::kDivisionByZero, divisor,
1273 Operand(zero_reg)); 1276 Operand(zero_reg));
1274 } 1277 }
1275 1278
1276 // Check for (0 / -x) that will produce negative zero. 1279 // Check for (0 / -x) that will produce negative zero.
1277 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1280 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1278 Label left_not_zero; 1281 Label left_not_zero;
1279 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg)); 1282 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
1280 DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero, divisor, 1283 DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero, divisor,
1281 Operand(zero_reg)); 1284 Operand(zero_reg));
1282 __ bind(&left_not_zero); 1285 __ bind(&left_not_zero);
1283 } 1286 }
1284 1287
1285 // Check for (kMinInt / -1). 1288 // Check for (kMinInt / -1).
1286 if (hdiv->CheckFlag(HValue::kCanOverflow) && 1289 if (hdiv->CheckFlag(HValue::kCanOverflow) &&
1287 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1290 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1288 Label left_not_min_int; 1291 Label left_not_min_int;
1289 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt)); 1292 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
1290 DeoptimizeIf(eq, instr, Deoptimizer::kOverflow, divisor, Operand(-1)); 1293 DeoptimizeIf(eq, instr, DeoptimizeReason::kOverflow, divisor, Operand(-1));
1291 __ bind(&left_not_min_int); 1294 __ bind(&left_not_min_int);
1292 } 1295 }
1293 1296
1294 // We performed a truncating division. Correct the result if necessary. 1297 // We performed a truncating division. Correct the result if necessary.
1295 Label done; 1298 Label done;
1296 Register remainder = scratch0(); 1299 Register remainder = scratch0();
1297 if (kArchVariant != kMips64r6) { 1300 if (kArchVariant != kMips64r6) {
1298 __ mfhi(remainder); 1301 __ mfhi(remainder);
1299 } else { 1302 } else {
1300 __ dmod(remainder, dividend, divisor); 1303 __ dmod(remainder, dividend, divisor);
(...skipping 16 matching lines...) Expand all
1317 bool bailout_on_minus_zero = 1320 bool bailout_on_minus_zero =
1318 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1321 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1319 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1322 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1320 1323
1321 if (right_op->IsConstantOperand()) { 1324 if (right_op->IsConstantOperand()) {
1322 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); 1325 int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
1323 1326
1324 if (bailout_on_minus_zero && (constant < 0)) { 1327 if (bailout_on_minus_zero && (constant < 0)) {
1325 // The case of a null constant will be handled separately. 1328 // The case of a null constant will be handled separately.
1326 // If constant is negative and left is null, the result should be -0. 1329 // If constant is negative and left is null, the result should be -0.
1327 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, left, Operand(zero_reg)); 1330 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, left,
1331 Operand(zero_reg));
1328 } 1332 }
1329 1333
1330 switch (constant) { 1334 switch (constant) {
1331 case -1: 1335 case -1:
1332 if (overflow) { 1336 if (overflow) {
1333 Label no_overflow; 1337 Label no_overflow;
1334 __ DsubBranchNoOvf(result, zero_reg, Operand(left), &no_overflow); 1338 __ DsubBranchNoOvf(result, zero_reg, Operand(left), &no_overflow);
1335 DeoptimizeIf(al, instr); 1339 DeoptimizeIf(al, instr);
1336 __ bind(&no_overflow); 1340 __ bind(&no_overflow);
1337 } else { 1341 } else {
1338 __ Dsubu(result, zero_reg, left); 1342 __ Dsubu(result, zero_reg, left);
1339 } 1343 }
1340 break; 1344 break;
1341 case 0: 1345 case 0:
1342 if (bailout_on_minus_zero) { 1346 if (bailout_on_minus_zero) {
1343 // If left is strictly negative and the constant is null, the 1347 // If left is strictly negative and the constant is null, the
1344 // result is -0. Deoptimize if required, otherwise return 0. 1348 // result is -0. Deoptimize if required, otherwise return 0.
1345 DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero, left, 1349 DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero, left,
1346 Operand(zero_reg)); 1350 Operand(zero_reg));
1347 } 1351 }
1348 __ mov(result, zero_reg); 1352 __ mov(result, zero_reg);
1349 break; 1353 break;
1350 case 1: 1354 case 1:
1351 // Nothing to do. 1355 // Nothing to do.
1352 __ Move(result, left); 1356 __ Move(result, left);
1353 break; 1357 break;
1354 default: 1358 default:
1355 // Multiplying by powers of two and powers of two plus or minus 1359 // Multiplying by powers of two and powers of two plus or minus
(...skipping 27 matching lines...) Expand all
1383 } else { 1387 } else {
1384 DCHECK(right_op->IsRegister()); 1388 DCHECK(right_op->IsRegister());
1385 Register right = ToRegister(right_op); 1389 Register right = ToRegister(right_op);
1386 1390
1387 if (overflow) { 1391 if (overflow) {
1388 // hi:lo = left * right. 1392 // hi:lo = left * right.
1389 __ Dmulh(result, left, right); 1393 __ Dmulh(result, left, right);
1390 __ dsra32(scratch, result, 0); 1394 __ dsra32(scratch, result, 0);
1391 __ sra(at, result, 31); 1395 __ sra(at, result, 31);
1392 __ SmiTag(result); 1396 __ SmiTag(result);
1393 DeoptimizeIf(ne, instr, Deoptimizer::kOverflow, scratch, Operand(at)); 1397 DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow, scratch,
1398 Operand(at));
1394 } else { 1399 } else {
1395 __ SmiUntag(result, left); 1400 __ SmiUntag(result, left);
1396 __ dmul(result, result, right); 1401 __ dmul(result, result, right);
1397 } 1402 }
1398 1403
1399 if (bailout_on_minus_zero) { 1404 if (bailout_on_minus_zero) {
1400 Label done; 1405 Label done;
1401 __ Xor(at, left, right); 1406 __ Xor(at, left, right);
1402 __ Branch(&done, ge, at, Operand(zero_reg)); 1407 __ Branch(&done, ge, at, Operand(zero_reg));
1403 // Bail out if the result is minus zero. 1408 // Bail out if the result is minus zero.
1404 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, result, 1409 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, result,
1405 Operand(zero_reg)); 1410 Operand(zero_reg));
1406 __ bind(&done); 1411 __ bind(&done);
1407 } 1412 }
1408 } 1413 }
1409 } 1414 }
1410 1415
1411 1416
1412 void LCodeGen::DoMulI(LMulI* instr) { 1417 void LCodeGen::DoMulI(LMulI* instr) {
1413 Register scratch = scratch0(); 1418 Register scratch = scratch0();
1414 Register result = ToRegister(instr->result()); 1419 Register result = ToRegister(instr->result());
1415 // Note that result may alias left. 1420 // Note that result may alias left.
1416 Register left = ToRegister(instr->left()); 1421 Register left = ToRegister(instr->left());
1417 LOperand* right_op = instr->right(); 1422 LOperand* right_op = instr->right();
1418 1423
1419 bool bailout_on_minus_zero = 1424 bool bailout_on_minus_zero =
1420 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1425 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1421 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1426 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1422 1427
1423 if (right_op->IsConstantOperand()) { 1428 if (right_op->IsConstantOperand()) {
1424 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); 1429 int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
1425 1430
1426 if (bailout_on_minus_zero && (constant < 0)) { 1431 if (bailout_on_minus_zero && (constant < 0)) {
1427 // The case of a null constant will be handled separately. 1432 // The case of a null constant will be handled separately.
1428 // If constant is negative and left is null, the result should be -0. 1433 // If constant is negative and left is null, the result should be -0.
1429 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, left, Operand(zero_reg)); 1434 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, left,
1435 Operand(zero_reg));
1430 } 1436 }
1431 1437
1432 switch (constant) { 1438 switch (constant) {
1433 case -1: 1439 case -1:
1434 if (overflow) { 1440 if (overflow) {
1435 Label no_overflow; 1441 Label no_overflow;
1436 __ SubBranchNoOvf(result, zero_reg, Operand(left), &no_overflow); 1442 __ SubBranchNoOvf(result, zero_reg, Operand(left), &no_overflow);
1437 DeoptimizeIf(al, instr); 1443 DeoptimizeIf(al, instr);
1438 __ bind(&no_overflow); 1444 __ bind(&no_overflow);
1439 } else { 1445 } else {
1440 __ Subu(result, zero_reg, left); 1446 __ Subu(result, zero_reg, left);
1441 } 1447 }
1442 break; 1448 break;
1443 case 0: 1449 case 0:
1444 if (bailout_on_minus_zero) { 1450 if (bailout_on_minus_zero) {
1445 // If left is strictly negative and the constant is null, the 1451 // If left is strictly negative and the constant is null, the
1446 // result is -0. Deoptimize if required, otherwise return 0. 1452 // result is -0. Deoptimize if required, otherwise return 0.
1447 DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero, left, 1453 DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero, left,
1448 Operand(zero_reg)); 1454 Operand(zero_reg));
1449 } 1455 }
1450 __ mov(result, zero_reg); 1456 __ mov(result, zero_reg);
1451 break; 1457 break;
1452 case 1: 1458 case 1:
1453 // Nothing to do. 1459 // Nothing to do.
1454 __ Move(result, left); 1460 __ Move(result, left);
1455 break; 1461 break;
1456 default: 1462 default:
1457 // Multiplying by powers of two and powers of two plus or minus 1463 // Multiplying by powers of two and powers of two plus or minus
(...skipping 28 matching lines...) Expand all
1486 } else { 1492 } else {
1487 DCHECK(right_op->IsRegister()); 1493 DCHECK(right_op->IsRegister());
1488 Register right = ToRegister(right_op); 1494 Register right = ToRegister(right_op);
1489 1495
1490 if (overflow) { 1496 if (overflow) {
1491 // hi:lo = left * right. 1497 // hi:lo = left * right.
1492 __ Dmul(result, left, right); 1498 __ Dmul(result, left, right);
1493 __ dsra32(scratch, result, 0); 1499 __ dsra32(scratch, result, 0);
1494 __ sra(at, result, 31); 1500 __ sra(at, result, 31);
1495 1501
1496 DeoptimizeIf(ne, instr, Deoptimizer::kOverflow, scratch, Operand(at)); 1502 DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow, scratch,
1503 Operand(at));
1497 } else { 1504 } else {
1498 __ mul(result, left, right); 1505 __ mul(result, left, right);
1499 } 1506 }
1500 1507
1501 if (bailout_on_minus_zero) { 1508 if (bailout_on_minus_zero) {
1502 Label done; 1509 Label done;
1503 __ Xor(at, left, right); 1510 __ Xor(at, left, right);
1504 __ Branch(&done, ge, at, Operand(zero_reg)); 1511 __ Branch(&done, ge, at, Operand(zero_reg));
1505 // Bail out if the result is minus zero. 1512 // Bail out if the result is minus zero.
1506 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, result, 1513 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, result,
1507 Operand(zero_reg)); 1514 Operand(zero_reg));
1508 __ bind(&done); 1515 __ bind(&done);
1509 } 1516 }
1510 } 1517 }
1511 } 1518 }
1512 1519
1513 1520
1514 void LCodeGen::DoBitI(LBitI* instr) { 1521 void LCodeGen::DoBitI(LBitI* instr) {
1515 LOperand* left_op = instr->left(); 1522 LOperand* left_op = instr->left();
1516 LOperand* right_op = instr->right(); 1523 LOperand* right_op = instr->right();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1561 case Token::ROR: 1568 case Token::ROR:
1562 __ Ror(result, left, Operand(ToRegister(right_op))); 1569 __ Ror(result, left, Operand(ToRegister(right_op)));
1563 break; 1570 break;
1564 case Token::SAR: 1571 case Token::SAR:
1565 __ srav(result, left, ToRegister(right_op)); 1572 __ srav(result, left, ToRegister(right_op));
1566 break; 1573 break;
1567 case Token::SHR: 1574 case Token::SHR:
1568 __ srlv(result, left, ToRegister(right_op)); 1575 __ srlv(result, left, ToRegister(right_op));
1569 if (instr->can_deopt()) { 1576 if (instr->can_deopt()) {
1570 // TODO(yy): (-1) >>> 0. anything else? 1577 // TODO(yy): (-1) >>> 0. anything else?
1571 DeoptimizeIf(lt, instr, Deoptimizer::kNegativeValue, result, 1578 DeoptimizeIf(lt, instr, DeoptimizeReason::kNegativeValue, result,
1572 Operand(zero_reg)); 1579 Operand(zero_reg));
1573 DeoptimizeIf(gt, instr, Deoptimizer::kNegativeValue, result, 1580 DeoptimizeIf(gt, instr, DeoptimizeReason::kNegativeValue, result,
1574 Operand(kMaxInt)); 1581 Operand(kMaxInt));
1575 } 1582 }
1576 break; 1583 break;
1577 case Token::SHL: 1584 case Token::SHL:
1578 __ sllv(result, left, ToRegister(right_op)); 1585 __ sllv(result, left, ToRegister(right_op));
1579 break; 1586 break;
1580 default: 1587 default:
1581 UNREACHABLE(); 1588 UNREACHABLE();
1582 break; 1589 break;
1583 } 1590 }
1584 } else { 1591 } else {
(...skipping 14 matching lines...) Expand all
1599 } else { 1606 } else {
1600 __ Move(result, left); 1607 __ Move(result, left);
1601 } 1608 }
1602 break; 1609 break;
1603 case Token::SHR: 1610 case Token::SHR:
1604 if (shift_count != 0) { 1611 if (shift_count != 0) {
1605 __ srl(result, left, shift_count); 1612 __ srl(result, left, shift_count);
1606 } else { 1613 } else {
1607 if (instr->can_deopt()) { 1614 if (instr->can_deopt()) {
1608 __ And(at, left, Operand(0x80000000)); 1615 __ And(at, left, Operand(0x80000000));
1609 DeoptimizeIf(ne, instr, Deoptimizer::kNegativeValue, at, 1616 DeoptimizeIf(ne, instr, DeoptimizeReason::kNegativeValue, at,
1610 Operand(zero_reg)); 1617 Operand(zero_reg));
1611 } 1618 }
1612 __ Move(result, left); 1619 __ Move(result, left);
1613 } 1620 }
1614 break; 1621 break;
1615 case Token::SHL: 1622 case Token::SHL:
1616 if (shift_count != 0) { 1623 if (shift_count != 0) {
1617 if (instr->hydrogen_value()->representation().IsSmi()) { 1624 if (instr->hydrogen_value()->representation().IsSmi()) {
1618 __ dsll(result, left, shift_count); 1625 __ dsll(result, left, shift_count);
1619 } else { 1626 } else {
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
2071 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); 2078 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2072 } 2079 }
2073 2080
2074 if (expected.Contains(ToBooleanICStub::SMI)) { 2081 if (expected.Contains(ToBooleanICStub::SMI)) {
2075 // Smis: 0 -> false, all other -> true. 2082 // Smis: 0 -> false, all other -> true.
2076 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg)); 2083 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg));
2077 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); 2084 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2078 } else if (expected.NeedsMap()) { 2085 } else if (expected.NeedsMap()) {
2079 // If we need a map later and have a Smi -> deopt. 2086 // If we need a map later and have a Smi -> deopt.
2080 __ SmiTst(reg, at); 2087 __ SmiTst(reg, at);
2081 DeoptimizeIf(eq, instr, Deoptimizer::kSmi, at, Operand(zero_reg)); 2088 DeoptimizeIf(eq, instr, DeoptimizeReason::kSmi, at, Operand(zero_reg));
2082 } 2089 }
2083 2090
2084 const Register map = scratch0(); 2091 const Register map = scratch0();
2085 if (expected.NeedsMap()) { 2092 if (expected.NeedsMap()) {
2086 __ ld(map, FieldMemOperand(reg, HeapObject::kMapOffset)); 2093 __ ld(map, FieldMemOperand(reg, HeapObject::kMapOffset));
2087 if (expected.CanBeUndetectable()) { 2094 if (expected.CanBeUndetectable()) {
2088 // Undetectable -> false. 2095 // Undetectable -> false.
2089 __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset)); 2096 __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
2090 __ And(at, at, Operand(1 << Map::kIsUndetectable)); 2097 __ And(at, at, Operand(1 << Map::kIsUndetectable));
2091 __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg)); 2098 __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2135 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), 2142 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2136 ne, dbl_scratch, kDoubleRegZero); 2143 ne, dbl_scratch, kDoubleRegZero);
2137 // Falls through if dbl_scratch == 0. 2144 // Falls through if dbl_scratch == 0.
2138 __ Branch(instr->FalseLabel(chunk_)); 2145 __ Branch(instr->FalseLabel(chunk_));
2139 __ bind(&not_heap_number); 2146 __ bind(&not_heap_number);
2140 } 2147 }
2141 2148
2142 if (!expected.IsGeneric()) { 2149 if (!expected.IsGeneric()) {
2143 // We've seen something for the first time -> deopt. 2150 // We've seen something for the first time -> deopt.
2144 // This can only happen if we are not generic already. 2151 // This can only happen if we are not generic already.
2145 DeoptimizeIf(al, instr, Deoptimizer::kUnexpectedObject, zero_reg, 2152 DeoptimizeIf(al, instr, DeoptimizeReason::kUnexpectedObject, zero_reg,
2146 Operand(zero_reg)); 2153 Operand(zero_reg));
2147 } 2154 }
2148 } 2155 }
2149 } 2156 }
2150 } 2157 }
2151 2158
2152 2159
2153 void LCodeGen::EmitGoto(int block) { 2160 void LCodeGen::EmitGoto(int block) {
2154 if (!IsNextEmittedBlock(block)) { 2161 if (!IsNextEmittedBlock(block)) {
2155 __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block))); 2162 __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
2516 // Loop through the {object}s prototype chain looking for the {prototype}. 2523 // Loop through the {object}s prototype chain looking for the {prototype}.
2517 __ ld(object_map, FieldMemOperand(object, HeapObject::kMapOffset)); 2524 __ ld(object_map, FieldMemOperand(object, HeapObject::kMapOffset));
2518 Label loop; 2525 Label loop;
2519 __ bind(&loop); 2526 __ bind(&loop);
2520 2527
2521 // Deoptimize if the object needs to be access checked. 2528 // Deoptimize if the object needs to be access checked.
2522 __ lbu(object_instance_type, 2529 __ lbu(object_instance_type,
2523 FieldMemOperand(object_map, Map::kBitFieldOffset)); 2530 FieldMemOperand(object_map, Map::kBitFieldOffset));
2524 __ And(object_instance_type, object_instance_type, 2531 __ And(object_instance_type, object_instance_type,
2525 Operand(1 << Map::kIsAccessCheckNeeded)); 2532 Operand(1 << Map::kIsAccessCheckNeeded));
2526 DeoptimizeIf(ne, instr, Deoptimizer::kAccessCheck, object_instance_type, 2533 DeoptimizeIf(ne, instr, DeoptimizeReason::kAccessCheck, object_instance_type,
2527 Operand(zero_reg)); 2534 Operand(zero_reg));
2528 __ lbu(object_instance_type, 2535 __ lbu(object_instance_type,
2529 FieldMemOperand(object_map, Map::kInstanceTypeOffset)); 2536 FieldMemOperand(object_map, Map::kInstanceTypeOffset));
2530 DeoptimizeIf(eq, instr, Deoptimizer::kProxy, object_instance_type, 2537 DeoptimizeIf(eq, instr, DeoptimizeReason::kProxy, object_instance_type,
2531 Operand(JS_PROXY_TYPE)); 2538 Operand(JS_PROXY_TYPE));
2532 2539
2533 __ ld(object_prototype, FieldMemOperand(object_map, Map::kPrototypeOffset)); 2540 __ ld(object_prototype, FieldMemOperand(object_map, Map::kPrototypeOffset));
2534 __ LoadRoot(at, Heap::kNullValueRootIndex); 2541 __ LoadRoot(at, Heap::kNullValueRootIndex);
2535 EmitFalseBranch(instr, eq, object_prototype, Operand(at)); 2542 EmitFalseBranch(instr, eq, object_prototype, Operand(at));
2536 EmitTrueBranch(instr, eq, object_prototype, Operand(prototype)); 2543 EmitTrueBranch(instr, eq, object_prototype, Operand(prototype));
2537 __ Branch(&loop, USE_DELAY_SLOT); 2544 __ Branch(&loop, USE_DELAY_SLOT);
2538 __ ld(object_map, FieldMemOperand(object_prototype, 2545 __ ld(object_map, FieldMemOperand(object_prototype,
2539 HeapObject::kMapOffset)); // In delay slot. 2546 HeapObject::kMapOffset)); // In delay slot.
2540 } 2547 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2642 2649
2643 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 2650 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2644 Register context = ToRegister(instr->context()); 2651 Register context = ToRegister(instr->context());
2645 Register result = ToRegister(instr->result()); 2652 Register result = ToRegister(instr->result());
2646 2653
2647 __ ld(result, ContextMemOperand(context, instr->slot_index())); 2654 __ ld(result, ContextMemOperand(context, instr->slot_index()));
2648 if (instr->hydrogen()->RequiresHoleCheck()) { 2655 if (instr->hydrogen()->RequiresHoleCheck()) {
2649 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2656 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2650 2657
2651 if (instr->hydrogen()->DeoptimizesOnHole()) { 2658 if (instr->hydrogen()->DeoptimizesOnHole()) {
2652 DeoptimizeIf(eq, instr, Deoptimizer::kHole, result, Operand(at)); 2659 DeoptimizeIf(eq, instr, DeoptimizeReason::kHole, result, Operand(at));
2653 } else { 2660 } else {
2654 Label is_not_hole; 2661 Label is_not_hole;
2655 __ Branch(&is_not_hole, ne, result, Operand(at)); 2662 __ Branch(&is_not_hole, ne, result, Operand(at));
2656 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); 2663 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
2657 __ bind(&is_not_hole); 2664 __ bind(&is_not_hole);
2658 } 2665 }
2659 } 2666 }
2660 } 2667 }
2661 2668
2662 2669
2663 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { 2670 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2664 Register context = ToRegister(instr->context()); 2671 Register context = ToRegister(instr->context());
2665 Register value = ToRegister(instr->value()); 2672 Register value = ToRegister(instr->value());
2666 Register scratch = scratch0(); 2673 Register scratch = scratch0();
2667 MemOperand target = ContextMemOperand(context, instr->slot_index()); 2674 MemOperand target = ContextMemOperand(context, instr->slot_index());
2668 2675
2669 Label skip_assignment; 2676 Label skip_assignment;
2670 2677
2671 if (instr->hydrogen()->RequiresHoleCheck()) { 2678 if (instr->hydrogen()->RequiresHoleCheck()) {
2672 __ ld(scratch, target); 2679 __ ld(scratch, target);
2673 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2680 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2674 2681
2675 if (instr->hydrogen()->DeoptimizesOnHole()) { 2682 if (instr->hydrogen()->DeoptimizesOnHole()) {
2676 DeoptimizeIf(eq, instr, Deoptimizer::kHole, scratch, Operand(at)); 2683 DeoptimizeIf(eq, instr, DeoptimizeReason::kHole, scratch, Operand(at));
2677 } else { 2684 } else {
2678 __ Branch(&skip_assignment, ne, scratch, Operand(at)); 2685 __ Branch(&skip_assignment, ne, scratch, Operand(at));
2679 } 2686 }
2680 } 2687 }
2681 2688
2682 __ sd(value, target); 2689 __ sd(value, target);
2683 if (instr->hydrogen()->NeedsWriteBarrier()) { 2690 if (instr->hydrogen()->NeedsWriteBarrier()) {
2684 SmiCheck check_needed = 2691 SmiCheck check_needed =
2685 instr->hydrogen()->value()->type().IsHeapObject() 2692 instr->hydrogen()->value()->type().IsHeapObject()
2686 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2693 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2758 Register scratch = scratch0(); 2765 Register scratch = scratch0();
2759 Register function = ToRegister(instr->function()); 2766 Register function = ToRegister(instr->function());
2760 Register result = ToRegister(instr->result()); 2767 Register result = ToRegister(instr->result());
2761 2768
2762 // Get the prototype or initial map from the function. 2769 // Get the prototype or initial map from the function.
2763 __ ld(result, 2770 __ ld(result,
2764 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 2771 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
2765 2772
2766 // Check that the function has a prototype or an initial map. 2773 // Check that the function has a prototype or an initial map.
2767 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2774 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2768 DeoptimizeIf(eq, instr, Deoptimizer::kHole, result, Operand(at)); 2775 DeoptimizeIf(eq, instr, DeoptimizeReason::kHole, result, Operand(at));
2769 2776
2770 // If the function does not have an initial map, we're done. 2777 // If the function does not have an initial map, we're done.
2771 Label done; 2778 Label done;
2772 __ GetObjectType(result, scratch, scratch); 2779 __ GetObjectType(result, scratch, scratch);
2773 __ Branch(&done, ne, scratch, Operand(MAP_TYPE)); 2780 __ Branch(&done, ne, scratch, Operand(MAP_TYPE));
2774 2781
2775 // Get the prototype from the initial map. 2782 // Get the prototype from the initial map.
2776 __ ld(result, FieldMemOperand(result, Map::kPrototypeOffset)); 2783 __ ld(result, FieldMemOperand(result, Map::kPrototypeOffset));
2777 2784
2778 // All done. 2785 // All done.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2888 break; 2895 break;
2889 case UINT16_ELEMENTS: 2896 case UINT16_ELEMENTS:
2890 __ lhu(result, mem_operand); 2897 __ lhu(result, mem_operand);
2891 break; 2898 break;
2892 case INT32_ELEMENTS: 2899 case INT32_ELEMENTS:
2893 __ lw(result, mem_operand); 2900 __ lw(result, mem_operand);
2894 break; 2901 break;
2895 case UINT32_ELEMENTS: 2902 case UINT32_ELEMENTS:
2896 __ lw(result, mem_operand); 2903 __ lw(result, mem_operand);
2897 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 2904 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
2898 DeoptimizeIf(Ugreater_equal, instr, Deoptimizer::kNegativeValue, 2905 DeoptimizeIf(Ugreater_equal, instr, DeoptimizeReason::kNegativeValue,
2899 result, Operand(0x80000000)); 2906 result, Operand(0x80000000));
2900 } 2907 }
2901 break; 2908 break;
2902 case FLOAT32_ELEMENTS: 2909 case FLOAT32_ELEMENTS:
2903 case FLOAT64_ELEMENTS: 2910 case FLOAT64_ELEMENTS:
2904 case FAST_DOUBLE_ELEMENTS: 2911 case FAST_DOUBLE_ELEMENTS:
2905 case FAST_ELEMENTS: 2912 case FAST_ELEMENTS:
2906 case FAST_SMI_ELEMENTS: 2913 case FAST_SMI_ELEMENTS:
2907 case FAST_HOLEY_DOUBLE_ELEMENTS: 2914 case FAST_HOLEY_DOUBLE_ELEMENTS:
2908 case FAST_HOLEY_ELEMENTS: 2915 case FAST_HOLEY_ELEMENTS:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2951 } else { 2958 } else {
2952 __ dsra(at, key, -shift_size); 2959 __ dsra(at, key, -shift_size);
2953 } 2960 }
2954 __ Daddu(scratch, scratch, at); 2961 __ Daddu(scratch, scratch, at);
2955 } 2962 }
2956 2963
2957 __ ldc1(result, MemOperand(scratch)); 2964 __ ldc1(result, MemOperand(scratch));
2958 2965
2959 if (instr->hydrogen()->RequiresHoleCheck()) { 2966 if (instr->hydrogen()->RequiresHoleCheck()) {
2960 __ FmoveHigh(scratch, result); 2967 __ FmoveHigh(scratch, result);
2961 DeoptimizeIf(eq, instr, Deoptimizer::kHole, scratch, 2968 DeoptimizeIf(eq, instr, DeoptimizeReason::kHole, scratch,
2962 Operand(static_cast<int32_t>(kHoleNanUpper32))); 2969 Operand(static_cast<int32_t>(kHoleNanUpper32)));
2963 } 2970 }
2964 } 2971 }
2965 2972
2966 2973
2967 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 2974 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
2968 HLoadKeyed* hinstr = instr->hydrogen(); 2975 HLoadKeyed* hinstr = instr->hydrogen();
2969 Register elements = ToRegister(instr->elements()); 2976 Register elements = ToRegister(instr->elements());
2970 Register result = ToRegister(instr->result()); 2977 Register result = ToRegister(instr->result());
2971 Register scratch = scratch0(); 2978 Register scratch = scratch0();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3005 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); 3012 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
3006 offset = SmiWordOffset(offset); 3013 offset = SmiWordOffset(offset);
3007 } 3014 }
3008 3015
3009 __ Load(result, MemOperand(store_base, offset), representation); 3016 __ Load(result, MemOperand(store_base, offset), representation);
3010 3017
3011 // Check for the hole value. 3018 // Check for the hole value.
3012 if (hinstr->RequiresHoleCheck()) { 3019 if (hinstr->RequiresHoleCheck()) {
3013 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { 3020 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3014 __ SmiTst(result, scratch); 3021 __ SmiTst(result, scratch);
3015 DeoptimizeIf(ne, instr, Deoptimizer::kNotASmi, scratch, 3022 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotASmi, scratch,
3016 Operand(zero_reg)); 3023 Operand(zero_reg));
3017 } else { 3024 } else {
3018 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 3025 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
3019 DeoptimizeIf(eq, instr, Deoptimizer::kHole, result, Operand(scratch)); 3026 DeoptimizeIf(eq, instr, DeoptimizeReason::kHole, result,
3027 Operand(scratch));
3020 } 3028 }
3021 } else if (instr->hydrogen()->hole_mode() == CONVERT_HOLE_TO_UNDEFINED) { 3029 } else if (instr->hydrogen()->hole_mode() == CONVERT_HOLE_TO_UNDEFINED) {
3022 DCHECK(instr->hydrogen()->elements_kind() == FAST_HOLEY_ELEMENTS); 3030 DCHECK(instr->hydrogen()->elements_kind() == FAST_HOLEY_ELEMENTS);
3023 Label done; 3031 Label done;
3024 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 3032 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
3025 __ Branch(&done, ne, result, Operand(scratch)); 3033 __ Branch(&done, ne, result, Operand(scratch));
3026 if (info()->IsStub()) { 3034 if (info()->IsStub()) {
3027 // A stub can safely convert the hole to undefined only if the array 3035 // A stub can safely convert the hole to undefined only if the array
3028 // protector cell contains (Smi) Isolate::kArrayProtectorValid. Otherwise 3036 // protector cell contains (Smi) Isolate::kArrayProtectorValid. Otherwise
3029 // it needs to bail out. 3037 // it needs to bail out.
3030 __ LoadRoot(result, Heap::kArrayProtectorRootIndex); 3038 __ LoadRoot(result, Heap::kArrayProtectorRootIndex);
3031 // The comparison only needs LS bits of value, which is a smi. 3039 // The comparison only needs LS bits of value, which is a smi.
3032 __ ld(result, FieldMemOperand(result, Cell::kValueOffset)); 3040 __ ld(result, FieldMemOperand(result, Cell::kValueOffset));
3033 DeoptimizeIf(ne, instr, Deoptimizer::kHole, result, 3041 DeoptimizeIf(ne, instr, DeoptimizeReason::kHole, result,
3034 Operand(Smi::FromInt(Isolate::kArrayProtectorValid))); 3042 Operand(Smi::FromInt(Isolate::kArrayProtectorValid)));
3035 } 3043 }
3036 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); 3044 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
3037 __ bind(&done); 3045 __ bind(&done);
3038 } 3046 }
3039 } 3047 }
3040 3048
3041 3049
3042 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { 3050 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3043 if (instr->is_fixed_typed_array()) { 3051 if (instr->is_fixed_typed_array()) {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
3183 } 3191 }
3184 3192
3185 // Normal function. Replace undefined or null with global receiver. 3193 // Normal function. Replace undefined or null with global receiver.
3186 __ LoadRoot(scratch, Heap::kNullValueRootIndex); 3194 __ LoadRoot(scratch, Heap::kNullValueRootIndex);
3187 __ Branch(&global_object, eq, receiver, Operand(scratch)); 3195 __ Branch(&global_object, eq, receiver, Operand(scratch));
3188 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 3196 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
3189 __ Branch(&global_object, eq, receiver, Operand(scratch)); 3197 __ Branch(&global_object, eq, receiver, Operand(scratch));
3190 3198
3191 // Deoptimize if the receiver is not a JS object. 3199 // Deoptimize if the receiver is not a JS object.
3192 __ SmiTst(receiver, scratch); 3200 __ SmiTst(receiver, scratch);
3193 DeoptimizeIf(eq, instr, Deoptimizer::kSmi, scratch, Operand(zero_reg)); 3201 DeoptimizeIf(eq, instr, DeoptimizeReason::kSmi, scratch, Operand(zero_reg));
3194 3202
3195 __ GetObjectType(receiver, scratch, scratch); 3203 __ GetObjectType(receiver, scratch, scratch);
3196 DeoptimizeIf(lt, instr, Deoptimizer::kNotAJavaScriptObject, scratch, 3204 DeoptimizeIf(lt, instr, DeoptimizeReason::kNotAJavaScriptObject, scratch,
3197 Operand(FIRST_JS_RECEIVER_TYPE)); 3205 Operand(FIRST_JS_RECEIVER_TYPE));
3198 __ Branch(&result_in_receiver); 3206 __ Branch(&result_in_receiver);
3199 3207
3200 __ bind(&global_object); 3208 __ bind(&global_object);
3201 __ ld(result, FieldMemOperand(function, JSFunction::kContextOffset)); 3209 __ ld(result, FieldMemOperand(function, JSFunction::kContextOffset));
3202 __ ld(result, ContextMemOperand(result, Context::NATIVE_CONTEXT_INDEX)); 3210 __ ld(result, ContextMemOperand(result, Context::NATIVE_CONTEXT_INDEX));
3203 __ ld(result, ContextMemOperand(result, Context::GLOBAL_PROXY_INDEX)); 3211 __ ld(result, ContextMemOperand(result, Context::GLOBAL_PROXY_INDEX));
3204 3212
3205 if (result.is(receiver)) { 3213 if (result.is(receiver)) {
3206 __ bind(&result_in_receiver); 3214 __ bind(&result_in_receiver);
(...skipping 13 matching lines...) Expand all
3220 Register length = ToRegister(instr->length()); 3228 Register length = ToRegister(instr->length());
3221 Register elements = ToRegister(instr->elements()); 3229 Register elements = ToRegister(instr->elements());
3222 Register scratch = scratch0(); 3230 Register scratch = scratch0();
3223 DCHECK(receiver.is(a0)); // Used for parameter count. 3231 DCHECK(receiver.is(a0)); // Used for parameter count.
3224 DCHECK(function.is(a1)); // Required by InvokeFunction. 3232 DCHECK(function.is(a1)); // Required by InvokeFunction.
3225 DCHECK(ToRegister(instr->result()).is(v0)); 3233 DCHECK(ToRegister(instr->result()).is(v0));
3226 3234
3227 // Copy the arguments to this function possibly from the 3235 // Copy the arguments to this function possibly from the
3228 // adaptor frame below it. 3236 // adaptor frame below it.
3229 const uint32_t kArgumentsLimit = 1 * KB; 3237 const uint32_t kArgumentsLimit = 1 * KB;
3230 DeoptimizeIf(hi, instr, Deoptimizer::kTooManyArguments, length, 3238 DeoptimizeIf(hi, instr, DeoptimizeReason::kTooManyArguments, length,
3231 Operand(kArgumentsLimit)); 3239 Operand(kArgumentsLimit));
3232 3240
3233 // Push the receiver and use the register to keep the original 3241 // Push the receiver and use the register to keep the original
3234 // number of arguments. 3242 // number of arguments.
3235 __ push(receiver); 3243 __ push(receiver);
3236 __ Move(receiver, length); 3244 __ Move(receiver, length);
3237 // The arguments are at a one pointer size offset from elements. 3245 // The arguments are at a one pointer size offset from elements.
3238 __ Daddu(elements, elements, Operand(1 * kPointerSize)); 3246 __ Daddu(elements, elements, Operand(1 * kPointerSize));
3239 3247
3240 // Loop through the arguments pushing them onto the execution 3248 // Loop through the arguments pushing them onto the execution
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
3373 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3381 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3374 DCHECK(instr->context() != NULL); 3382 DCHECK(instr->context() != NULL);
3375 DCHECK(ToRegister(instr->context()).is(cp)); 3383 DCHECK(ToRegister(instr->context()).is(cp));
3376 Register input = ToRegister(instr->value()); 3384 Register input = ToRegister(instr->value());
3377 Register result = ToRegister(instr->result()); 3385 Register result = ToRegister(instr->result());
3378 Register scratch = scratch0(); 3386 Register scratch = scratch0();
3379 3387
3380 // Deoptimize if not a heap number. 3388 // Deoptimize if not a heap number.
3381 __ ld(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 3389 __ ld(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
3382 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 3390 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
3383 DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumber, scratch, Operand(at)); 3391 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber, scratch,
3392 Operand(at));
3384 3393
3385 Label done; 3394 Label done;
3386 Register exponent = scratch0(); 3395 Register exponent = scratch0();
3387 scratch = no_reg; 3396 scratch = no_reg;
3388 __ lwu(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 3397 __ lwu(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
3389 // Check the sign of the argument. If the argument is positive, just 3398 // Check the sign of the argument. If the argument is positive, just
3390 // return it. 3399 // return it.
3391 __ Move(result, input); 3400 __ Move(result, input);
3392 __ And(at, exponent, Operand(HeapNumber::kSignMask)); 3401 __ And(at, exponent, Operand(HeapNumber::kSignMask));
3393 __ Branch(&done, eq, at, Operand(zero_reg)); 3402 __ Branch(&done, eq, at, Operand(zero_reg));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3440 3449
3441 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { 3450 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3442 Register input = ToRegister(instr->value()); 3451 Register input = ToRegister(instr->value());
3443 Register result = ToRegister(instr->result()); 3452 Register result = ToRegister(instr->result());
3444 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 3453 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
3445 Label done; 3454 Label done;
3446 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); 3455 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg));
3447 __ mov(result, input); 3456 __ mov(result, input);
3448 __ subu(result, zero_reg, input); 3457 __ subu(result, zero_reg, input);
3449 // Overflow if result is still negative, i.e. 0x80000000. 3458 // Overflow if result is still negative, i.e. 0x80000000.
3450 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, result, Operand(zero_reg)); 3459 DeoptimizeIf(lt, instr, DeoptimizeReason::kOverflow, result,
3460 Operand(zero_reg));
3451 __ bind(&done); 3461 __ bind(&done);
3452 } 3462 }
3453 3463
3454 3464
3455 void LCodeGen::EmitSmiMathAbs(LMathAbs* instr) { 3465 void LCodeGen::EmitSmiMathAbs(LMathAbs* instr) {
3456 Register input = ToRegister(instr->value()); 3466 Register input = ToRegister(instr->value());
3457 Register result = ToRegister(instr->result()); 3467 Register result = ToRegister(instr->result());
3458 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 3468 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
3459 Label done; 3469 Label done;
3460 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); 3470 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg));
3461 __ mov(result, input); 3471 __ mov(result, input);
3462 __ dsubu(result, zero_reg, input); 3472 __ dsubu(result, zero_reg, input);
3463 // Overflow if result is still negative, i.e. 0x80000000 00000000. 3473 // Overflow if result is still negative, i.e. 0x80000000 00000000.
3464 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, result, Operand(zero_reg)); 3474 DeoptimizeIf(lt, instr, DeoptimizeReason::kOverflow, result,
3475 Operand(zero_reg));
3465 __ bind(&done); 3476 __ bind(&done);
3466 } 3477 }
3467 3478
3468 3479
3469 void LCodeGen::DoMathAbs(LMathAbs* instr) { 3480 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3470 // Class for deferred case. 3481 // Class for deferred case.
3471 class DeferredMathAbsTaggedHeapNumber final : public LDeferredCode { 3482 class DeferredMathAbsTaggedHeapNumber final : public LDeferredCode {
3472 public: 3483 public:
3473 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) 3484 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3474 : LDeferredCode(codegen), instr_(instr) { } 3485 : LDeferredCode(codegen), instr_(instr) { }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3511 Register except_flag = ToRegister(instr->temp()); 3522 Register except_flag = ToRegister(instr->temp());
3512 3523
3513 __ EmitFPUTruncate(kRoundToMinusInf, 3524 __ EmitFPUTruncate(kRoundToMinusInf,
3514 result, 3525 result,
3515 input, 3526 input,
3516 scratch1, 3527 scratch1,
3517 double_scratch0(), 3528 double_scratch0(),
3518 except_flag); 3529 except_flag);
3519 3530
3520 // Deopt if the operation did not succeed. 3531 // Deopt if the operation did not succeed.
3521 DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecisionOrNaN, except_flag, 3532 DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecisionOrNaN, except_flag,
3522 Operand(zero_reg)); 3533 Operand(zero_reg));
3523 3534
3524 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3535 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3525 // Test for -0. 3536 // Test for -0.
3526 Label done; 3537 Label done;
3527 __ Branch(&done, ne, result, Operand(zero_reg)); 3538 __ Branch(&done, ne, result, Operand(zero_reg));
3528 __ mfhc1(scratch1, input); // Get exponent/sign bits. 3539 __ mfhc1(scratch1, input); // Get exponent/sign bits.
3529 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 3540 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
3530 DeoptimizeIf(ne, instr, Deoptimizer::kMinusZero, scratch1, 3541 DeoptimizeIf(ne, instr, DeoptimizeReason::kMinusZero, scratch1,
3531 Operand(zero_reg)); 3542 Operand(zero_reg));
3532 __ bind(&done); 3543 __ bind(&done);
3533 } 3544 }
3534 } 3545 }
3535 3546
3536 3547
3537 void LCodeGen::DoMathRound(LMathRound* instr) { 3548 void LCodeGen::DoMathRound(LMathRound* instr) {
3538 DoubleRegister input = ToDoubleRegister(instr->value()); 3549 DoubleRegister input = ToDoubleRegister(instr->value());
3539 Register result = ToRegister(instr->result()); 3550 Register result = ToRegister(instr->result());
3540 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); 3551 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp());
(...skipping 13 matching lines...) Expand all
3554 __ mov(result, zero_reg); 3565 __ mov(result, zero_reg);
3555 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3566 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3556 __ Branch(&check_sign_on_zero); 3567 __ Branch(&check_sign_on_zero);
3557 } else { 3568 } else {
3558 __ Branch(&done); 3569 __ Branch(&done);
3559 } 3570 }
3560 __ bind(&skip1); 3571 __ bind(&skip1);
3561 3572
3562 // The following conversion will not work with numbers 3573 // The following conversion will not work with numbers
3563 // outside of ]-2^32, 2^32[. 3574 // outside of ]-2^32, 2^32[.
3564 DeoptimizeIf(ge, instr, Deoptimizer::kOverflow, scratch, 3575 DeoptimizeIf(ge, instr, DeoptimizeReason::kOverflow, scratch,
3565 Operand(HeapNumber::kExponentBias + 32)); 3576 Operand(HeapNumber::kExponentBias + 32));
3566 3577
3567 // Save the original sign for later comparison. 3578 // Save the original sign for later comparison.
3568 __ And(scratch, result, Operand(HeapNumber::kSignMask)); 3579 __ And(scratch, result, Operand(HeapNumber::kSignMask));
3569 3580
3570 __ Move(double_scratch0(), 0.5); 3581 __ Move(double_scratch0(), 0.5);
3571 __ add_d(double_scratch0(), input, double_scratch0()); 3582 __ add_d(double_scratch0(), input, double_scratch0());
3572 3583
3573 // Check sign of the result: if the sign changed, the input 3584 // Check sign of the result: if the sign changed, the input
3574 // value was in ]0.5, 0[ and the result should be -0. 3585 // value was in ]0.5, 0[ and the result should be -0.
3575 __ mfhc1(result, double_scratch0()); 3586 __ mfhc1(result, double_scratch0());
3576 // mfhc1 sign-extends, clear the upper bits. 3587 // mfhc1 sign-extends, clear the upper bits.
3577 __ dsll32(result, result, 0); 3588 __ dsll32(result, result, 0);
3578 __ dsrl32(result, result, 0); 3589 __ dsrl32(result, result, 0);
3579 __ Xor(result, result, Operand(scratch)); 3590 __ Xor(result, result, Operand(scratch));
3580 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3591 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3581 // ARM uses 'mi' here, which is 'lt' 3592 // ARM uses 'mi' here, which is 'lt'
3582 DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero, result, Operand(zero_reg)); 3593 DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero, result,
3594 Operand(zero_reg));
3583 } else { 3595 } else {
3584 Label skip2; 3596 Label skip2;
3585 // ARM uses 'mi' here, which is 'lt' 3597 // ARM uses 'mi' here, which is 'lt'
3586 // Negating it results in 'ge' 3598 // Negating it results in 'ge'
3587 __ Branch(&skip2, ge, result, Operand(zero_reg)); 3599 __ Branch(&skip2, ge, result, Operand(zero_reg));
3588 __ mov(result, zero_reg); 3600 __ mov(result, zero_reg);
3589 __ Branch(&done); 3601 __ Branch(&done);
3590 __ bind(&skip2); 3602 __ bind(&skip2);
3591 } 3603 }
3592 3604
3593 Register except_flag = scratch; 3605 Register except_flag = scratch;
3594 __ EmitFPUTruncate(kRoundToMinusInf, 3606 __ EmitFPUTruncate(kRoundToMinusInf,
3595 result, 3607 result,
3596 double_scratch0(), 3608 double_scratch0(),
3597 at, 3609 at,
3598 double_scratch1, 3610 double_scratch1,
3599 except_flag); 3611 except_flag);
3600 3612
3601 DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecisionOrNaN, except_flag, 3613 DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecisionOrNaN, except_flag,
3602 Operand(zero_reg)); 3614 Operand(zero_reg));
3603 3615
3604 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3616 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3605 // Test for -0. 3617 // Test for -0.
3606 __ Branch(&done, ne, result, Operand(zero_reg)); 3618 __ Branch(&done, ne, result, Operand(zero_reg));
3607 __ bind(&check_sign_on_zero); 3619 __ bind(&check_sign_on_zero);
3608 __ mfhc1(scratch, input); // Get exponent/sign bits. 3620 __ mfhc1(scratch, input); // Get exponent/sign bits.
3609 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); 3621 __ And(scratch, scratch, Operand(HeapNumber::kSignMask));
3610 DeoptimizeIf(ne, instr, Deoptimizer::kMinusZero, scratch, 3622 DeoptimizeIf(ne, instr, DeoptimizeReason::kMinusZero, scratch,
3611 Operand(zero_reg)); 3623 Operand(zero_reg));
3612 } 3624 }
3613 __ bind(&done); 3625 __ bind(&done);
3614 } 3626 }
3615 3627
3616 3628
3617 void LCodeGen::DoMathFround(LMathFround* instr) { 3629 void LCodeGen::DoMathFround(LMathFround* instr) {
3618 DoubleRegister input = ToDoubleRegister(instr->value()); 3630 DoubleRegister input = ToDoubleRegister(instr->value());
3619 DoubleRegister result = ToDoubleRegister(instr->result()); 3631 DoubleRegister result = ToDoubleRegister(instr->result());
3620 __ cvt_s_d(result, input); 3632 __ cvt_s_d(result, input);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3667 3679
3668 if (exponent_type.IsSmi()) { 3680 if (exponent_type.IsSmi()) {
3669 MathPowStub stub(isolate(), MathPowStub::TAGGED); 3681 MathPowStub stub(isolate(), MathPowStub::TAGGED);
3670 __ CallStub(&stub); 3682 __ CallStub(&stub);
3671 } else if (exponent_type.IsTagged()) { 3683 } else if (exponent_type.IsTagged()) {
3672 Label no_deopt; 3684 Label no_deopt;
3673 __ JumpIfSmi(tagged_exponent, &no_deopt); 3685 __ JumpIfSmi(tagged_exponent, &no_deopt);
3674 DCHECK(!a7.is(tagged_exponent)); 3686 DCHECK(!a7.is(tagged_exponent));
3675 __ lw(a7, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset)); 3687 __ lw(a7, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset));
3676 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 3688 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
3677 DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumber, a7, Operand(at)); 3689 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber, a7, Operand(at));
3678 __ bind(&no_deopt); 3690 __ bind(&no_deopt);
3679 MathPowStub stub(isolate(), MathPowStub::TAGGED); 3691 MathPowStub stub(isolate(), MathPowStub::TAGGED);
3680 __ CallStub(&stub); 3692 __ CallStub(&stub);
3681 } else if (exponent_type.IsInteger32()) { 3693 } else if (exponent_type.IsInteger32()) {
3682 MathPowStub stub(isolate(), MathPowStub::INTEGER); 3694 MathPowStub stub(isolate(), MathPowStub::INTEGER);
3683 __ CallStub(&stub); 3695 __ CallStub(&stub);
3684 } else { 3696 } else {
3685 DCHECK(exponent_type.IsDouble()); 3697 DCHECK(exponent_type.IsDouble());
3686 MathPowStub stub(isolate(), MathPowStub::DOUBLE); 3698 MathPowStub stub(isolate(), MathPowStub::DOUBLE);
3687 __ CallStub(&stub); 3699 __ CallStub(&stub);
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
4027 } else { 4039 } else {
4028 reg = ToRegister(instr->index()); 4040 reg = ToRegister(instr->index());
4029 operand = ToOperand(instr->length()); 4041 operand = ToOperand(instr->length());
4030 } 4042 }
4031 if (FLAG_debug_code && instr->hydrogen()->skip_check()) { 4043 if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
4032 Label done; 4044 Label done;
4033 __ Branch(&done, NegateCondition(cc), reg, operand); 4045 __ Branch(&done, NegateCondition(cc), reg, operand);
4034 __ stop("eliminated bounds check failed"); 4046 __ stop("eliminated bounds check failed");
4035 __ bind(&done); 4047 __ bind(&done);
4036 } else { 4048 } else {
4037 DeoptimizeIf(cc, instr, Deoptimizer::kOutOfBounds, reg, operand); 4049 DeoptimizeIf(cc, instr, DeoptimizeReason::kOutOfBounds, reg, operand);
4038 } 4050 }
4039 } 4051 }
4040 4052
4041 4053
4042 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4054 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4043 Register external_pointer = ToRegister(instr->elements()); 4055 Register external_pointer = ToRegister(instr->elements());
4044 Register key = no_reg; 4056 Register key = no_reg;
4045 ElementsKind elements_kind = instr->elements_kind(); 4057 ElementsKind elements_kind = instr->elements_kind();
4046 bool key_is_constant = instr->key()->IsConstantOperand(); 4058 bool key_is_constant = instr->key()->IsConstantOperand();
4047 int constant_key = 0; 4059 int constant_key = 0;
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
4355 instr->hydrogen()->kind()); 4367 instr->hydrogen()->kind());
4356 __ mov(a0, result); 4368 __ mov(a0, result);
4357 __ CallStub(&stub); 4369 __ CallStub(&stub);
4358 RecordSafepointWithLazyDeopt( 4370 RecordSafepointWithLazyDeopt(
4359 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 4371 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
4360 __ StoreToSafepointRegisterSlot(result, result); 4372 __ StoreToSafepointRegisterSlot(result, result);
4361 } 4373 }
4362 4374
4363 // Deopt on smi, which means the elements array changed to dictionary mode. 4375 // Deopt on smi, which means the elements array changed to dictionary mode.
4364 __ SmiTst(result, at); 4376 __ SmiTst(result, at);
4365 DeoptimizeIf(eq, instr, Deoptimizer::kSmi, at, Operand(zero_reg)); 4377 DeoptimizeIf(eq, instr, DeoptimizeReason::kSmi, at, Operand(zero_reg));
4366 } 4378 }
4367 4379
4368 4380
4369 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 4381 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4370 Register object_reg = ToRegister(instr->object()); 4382 Register object_reg = ToRegister(instr->object());
4371 Register scratch = scratch0(); 4383 Register scratch = scratch0();
4372 4384
4373 Handle<Map> from_map = instr->original_map(); 4385 Handle<Map> from_map = instr->original_map();
4374 Handle<Map> to_map = instr->transitioned_map(); 4386 Handle<Map> to_map = instr->transitioned_map();
4375 ElementsKind from_kind = instr->from_kind(); 4387 ElementsKind from_kind = instr->from_kind();
(...skipping 25 matching lines...) Expand all
4401 } 4413 }
4402 __ bind(&not_applicable); 4414 __ bind(&not_applicable);
4403 } 4415 }
4404 4416
4405 4417
4406 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 4418 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4407 Register object = ToRegister(instr->object()); 4419 Register object = ToRegister(instr->object());
4408 Register temp = ToRegister(instr->temp()); 4420 Register temp = ToRegister(instr->temp());
4409 Label no_memento_found; 4421 Label no_memento_found;
4410 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); 4422 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
4411 DeoptimizeIf(al, instr, Deoptimizer::kMementoFound); 4423 DeoptimizeIf(al, instr, DeoptimizeReason::kMementoFound);
4412 __ bind(&no_memento_found); 4424 __ bind(&no_memento_found);
4413 } 4425 }
4414 4426
4415 4427
4416 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4428 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4417 DCHECK(ToRegister(instr->context()).is(cp)); 4429 DCHECK(ToRegister(instr->context()).is(cp));
4418 DCHECK(ToRegister(instr->left()).is(a1)); 4430 DCHECK(ToRegister(instr->left()).is(a1));
4419 DCHECK(ToRegister(instr->right()).is(a0)); 4431 DCHECK(ToRegister(instr->right()).is(a0));
4420 StringAddStub stub(isolate(), 4432 StringAddStub stub(isolate(),
4421 instr->hydrogen()->flags(), 4433 instr->hydrogen()->flags(),
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
4695 } 4707 }
4696 4708
4697 4709
4698 void LCodeGen::DoSmiTag(LSmiTag* instr) { 4710 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4699 HChange* hchange = instr->hydrogen(); 4711 HChange* hchange = instr->hydrogen();
4700 Register input = ToRegister(instr->value()); 4712 Register input = ToRegister(instr->value());
4701 Register output = ToRegister(instr->result()); 4713 Register output = ToRegister(instr->result());
4702 if (hchange->CheckFlag(HValue::kCanOverflow) && 4714 if (hchange->CheckFlag(HValue::kCanOverflow) &&
4703 hchange->value()->CheckFlag(HValue::kUint32)) { 4715 hchange->value()->CheckFlag(HValue::kUint32)) {
4704 __ And(at, input, Operand(0x80000000)); 4716 __ And(at, input, Operand(0x80000000));
4705 DeoptimizeIf(ne, instr, Deoptimizer::kOverflow, at, Operand(zero_reg)); 4717 DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow, at, Operand(zero_reg));
4706 } 4718 }
4707 if (hchange->CheckFlag(HValue::kCanOverflow) && 4719 if (hchange->CheckFlag(HValue::kCanOverflow) &&
4708 !hchange->value()->CheckFlag(HValue::kUint32)) { 4720 !hchange->value()->CheckFlag(HValue::kUint32)) {
4709 __ SmiTagCheckOverflow(output, input, at); 4721 __ SmiTagCheckOverflow(output, input, at);
4710 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, at, Operand(zero_reg)); 4722 DeoptimizeIf(lt, instr, DeoptimizeReason::kOverflow, at, Operand(zero_reg));
4711 } else { 4723 } else {
4712 __ SmiTag(output, input); 4724 __ SmiTag(output, input);
4713 } 4725 }
4714 } 4726 }
4715 4727
4716 4728
4717 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4729 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4718 Register scratch = scratch0(); 4730 Register scratch = scratch0();
4719 Register input = ToRegister(instr->value()); 4731 Register input = ToRegister(instr->value());
4720 Register result = ToRegister(instr->result()); 4732 Register result = ToRegister(instr->result());
4721 if (instr->needs_check()) { 4733 if (instr->needs_check()) {
4722 STATIC_ASSERT(kHeapObjectTag == 1); 4734 STATIC_ASSERT(kHeapObjectTag == 1);
4723 // If the input is a HeapObject, value of scratch won't be zero. 4735 // If the input is a HeapObject, value of scratch won't be zero.
4724 __ And(scratch, input, Operand(kHeapObjectTag)); 4736 __ And(scratch, input, Operand(kHeapObjectTag));
4725 __ SmiUntag(result, input); 4737 __ SmiUntag(result, input);
4726 DeoptimizeIf(ne, instr, Deoptimizer::kNotASmi, scratch, Operand(zero_reg)); 4738 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotASmi, scratch,
4739 Operand(zero_reg));
4727 } else { 4740 } else {
4728 __ SmiUntag(result, input); 4741 __ SmiUntag(result, input);
4729 } 4742 }
4730 } 4743 }
4731 4744
4732 4745
4733 void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, 4746 void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
4734 DoubleRegister result_reg, 4747 DoubleRegister result_reg,
4735 NumberUntagDMode mode) { 4748 NumberUntagDMode mode) {
4736 bool can_convert_undefined_to_nan = 4749 bool can_convert_undefined_to_nan =
4737 instr->hydrogen()->can_convert_undefined_to_nan(); 4750 instr->hydrogen()->can_convert_undefined_to_nan();
4738 bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero(); 4751 bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
4739 4752
4740 Register scratch = scratch0(); 4753 Register scratch = scratch0();
4741 Label convert, load_smi, done; 4754 Label convert, load_smi, done;
4742 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 4755 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4743 // Smi check. 4756 // Smi check.
4744 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); 4757 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
4745 // Heap number map check. 4758 // Heap number map check.
4746 __ ld(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4759 __ ld(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4747 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 4760 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
4748 if (can_convert_undefined_to_nan) { 4761 if (can_convert_undefined_to_nan) {
4749 __ Branch(&convert, ne, scratch, Operand(at)); 4762 __ Branch(&convert, ne, scratch, Operand(at));
4750 } else { 4763 } else {
4751 DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumber, scratch, 4764 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber, scratch,
4752 Operand(at)); 4765 Operand(at));
4753 } 4766 }
4754 // Load heap number. 4767 // Load heap number.
4755 __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 4768 __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset));
4756 if (deoptimize_on_minus_zero) { 4769 if (deoptimize_on_minus_zero) {
4757 __ mfc1(at, result_reg); 4770 __ mfc1(at, result_reg);
4758 __ Branch(&done, ne, at, Operand(zero_reg)); 4771 __ Branch(&done, ne, at, Operand(zero_reg));
4759 __ mfhc1(scratch, result_reg); // Get exponent/sign bits. 4772 __ mfhc1(scratch, result_reg); // Get exponent/sign bits.
4760 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, scratch, 4773 DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, scratch,
4761 Operand(HeapNumber::kSignMask)); 4774 Operand(HeapNumber::kSignMask));
4762 } 4775 }
4763 __ Branch(&done); 4776 __ Branch(&done);
4764 if (can_convert_undefined_to_nan) { 4777 if (can_convert_undefined_to_nan) {
4765 __ bind(&convert); 4778 __ bind(&convert);
4766 // Convert undefined (and hole) to NaN. 4779 // Convert undefined (and hole) to NaN.
4767 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 4780 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
4768 DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumberUndefined, input_reg, 4781 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumberUndefined,
4769 Operand(at)); 4782 input_reg, Operand(at));
4770 __ LoadRoot(scratch, Heap::kNanValueRootIndex); 4783 __ LoadRoot(scratch, Heap::kNanValueRootIndex);
4771 __ ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset)); 4784 __ ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset));
4772 __ Branch(&done); 4785 __ Branch(&done);
4773 } 4786 }
4774 } else { 4787 } else {
4775 __ SmiUntag(scratch, input_reg); 4788 __ SmiUntag(scratch, input_reg);
4776 DCHECK(mode == NUMBER_CANDIDATE_IS_SMI); 4789 DCHECK(mode == NUMBER_CANDIDATE_IS_SMI);
4777 } 4790 }
4778 // Smi to double register conversion 4791 // Smi to double register conversion
4779 __ bind(&load_smi); 4792 __ bind(&load_smi);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
4823 __ mov(input_reg, zero_reg); // In delay slot. 4836 __ mov(input_reg, zero_reg); // In delay slot.
4824 4837
4825 __ bind(&check_bools); 4838 __ bind(&check_bools);
4826 __ LoadRoot(at, Heap::kTrueValueRootIndex); 4839 __ LoadRoot(at, Heap::kTrueValueRootIndex);
4827 __ Branch(&check_false, ne, scratch2, Operand(at)); 4840 __ Branch(&check_false, ne, scratch2, Operand(at));
4828 __ Branch(USE_DELAY_SLOT, &done); 4841 __ Branch(USE_DELAY_SLOT, &done);
4829 __ li(input_reg, Operand(1)); // In delay slot. 4842 __ li(input_reg, Operand(1)); // In delay slot.
4830 4843
4831 __ bind(&check_false); 4844 __ bind(&check_false);
4832 __ LoadRoot(at, Heap::kFalseValueRootIndex); 4845 __ LoadRoot(at, Heap::kFalseValueRootIndex);
4833 DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumberUndefinedBoolean, 4846 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumberUndefinedBoolean,
4834 scratch2, Operand(at)); 4847 scratch2, Operand(at));
4835 __ Branch(USE_DELAY_SLOT, &done); 4848 __ Branch(USE_DELAY_SLOT, &done);
4836 __ mov(input_reg, zero_reg); // In delay slot. 4849 __ mov(input_reg, zero_reg); // In delay slot.
4837 } else { 4850 } else {
4838 DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumber, scratch1, 4851 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber, scratch1,
4839 Operand(at)); 4852 Operand(at));
4840 4853
4841 // Load the double value. 4854 // Load the double value.
4842 __ ldc1(double_scratch, 4855 __ ldc1(double_scratch,
4843 FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 4856 FieldMemOperand(input_reg, HeapNumber::kValueOffset));
4844 4857
4845 Register except_flag = scratch2; 4858 Register except_flag = scratch2;
4846 __ EmitFPUTruncate(kRoundToZero, 4859 __ EmitFPUTruncate(kRoundToZero,
4847 input_reg, 4860 input_reg,
4848 double_scratch, 4861 double_scratch,
4849 scratch1, 4862 scratch1,
4850 double_scratch2, 4863 double_scratch2,
4851 except_flag, 4864 except_flag,
4852 kCheckForInexactConversion); 4865 kCheckForInexactConversion);
4853 4866
4854 DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecisionOrNaN, except_flag, 4867 DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecisionOrNaN, except_flag,
4855 Operand(zero_reg)); 4868 Operand(zero_reg));
4856 4869
4857 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4870 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4858 __ Branch(&done, ne, input_reg, Operand(zero_reg)); 4871 __ Branch(&done, ne, input_reg, Operand(zero_reg));
4859 4872
4860 __ mfhc1(scratch1, double_scratch); // Get exponent/sign bits. 4873 __ mfhc1(scratch1, double_scratch); // Get exponent/sign bits.
4861 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 4874 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
4862 DeoptimizeIf(ne, instr, Deoptimizer::kMinusZero, scratch1, 4875 DeoptimizeIf(ne, instr, DeoptimizeReason::kMinusZero, scratch1,
4863 Operand(zero_reg)); 4876 Operand(zero_reg));
4864 } 4877 }
4865 } 4878 }
4866 __ bind(&done); 4879 __ bind(&done);
4867 } 4880 }
4868 4881
4869 4882
4870 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 4883 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4871 class DeferredTaggedToI final : public LDeferredCode { 4884 class DeferredTaggedToI final : public LDeferredCode {
4872 public: 4885 public:
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4929 4942
4930 __ EmitFPUTruncate(kRoundToMinusInf, 4943 __ EmitFPUTruncate(kRoundToMinusInf,
4931 result_reg, 4944 result_reg,
4932 double_input, 4945 double_input,
4933 scratch1, 4946 scratch1,
4934 double_scratch0(), 4947 double_scratch0(),
4935 except_flag, 4948 except_flag,
4936 kCheckForInexactConversion); 4949 kCheckForInexactConversion);
4937 4950
4938 // Deopt if the operation did not succeed (except_flag != 0). 4951 // Deopt if the operation did not succeed (except_flag != 0).
4939 DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecisionOrNaN, except_flag, 4952 DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecisionOrNaN, except_flag,
4940 Operand(zero_reg)); 4953 Operand(zero_reg));
4941 4954
4942 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4955 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4943 Label done; 4956 Label done;
4944 __ Branch(&done, ne, result_reg, Operand(zero_reg)); 4957 __ Branch(&done, ne, result_reg, Operand(zero_reg));
4945 __ mfhc1(scratch1, double_input); // Get exponent/sign bits. 4958 __ mfhc1(scratch1, double_input); // Get exponent/sign bits.
4946 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 4959 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
4947 DeoptimizeIf(ne, instr, Deoptimizer::kMinusZero, scratch1, 4960 DeoptimizeIf(ne, instr, DeoptimizeReason::kMinusZero, scratch1,
4948 Operand(zero_reg)); 4961 Operand(zero_reg));
4949 __ bind(&done); 4962 __ bind(&done);
4950 } 4963 }
4951 } 4964 }
4952 } 4965 }
4953 4966
4954 4967
4955 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 4968 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
4956 Register result_reg = ToRegister(instr->result()); 4969 Register result_reg = ToRegister(instr->result());
4957 Register scratch1 = LCodeGen::scratch0(); 4970 Register scratch1 = LCodeGen::scratch0();
4958 DoubleRegister double_input = ToDoubleRegister(instr->value()); 4971 DoubleRegister double_input = ToDoubleRegister(instr->value());
4959 4972
4960 if (instr->truncating()) { 4973 if (instr->truncating()) {
4961 __ TruncateDoubleToI(result_reg, double_input); 4974 __ TruncateDoubleToI(result_reg, double_input);
4962 } else { 4975 } else {
4963 Register except_flag = LCodeGen::scratch1(); 4976 Register except_flag = LCodeGen::scratch1();
4964 4977
4965 __ EmitFPUTruncate(kRoundToMinusInf, 4978 __ EmitFPUTruncate(kRoundToMinusInf,
4966 result_reg, 4979 result_reg,
4967 double_input, 4980 double_input,
4968 scratch1, 4981 scratch1,
4969 double_scratch0(), 4982 double_scratch0(),
4970 except_flag, 4983 except_flag,
4971 kCheckForInexactConversion); 4984 kCheckForInexactConversion);
4972 4985
4973 // Deopt if the operation did not succeed (except_flag != 0). 4986 // Deopt if the operation did not succeed (except_flag != 0).
4974 DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecisionOrNaN, except_flag, 4987 DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecisionOrNaN, except_flag,
4975 Operand(zero_reg)); 4988 Operand(zero_reg));
4976 4989
4977 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4990 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4978 Label done; 4991 Label done;
4979 __ Branch(&done, ne, result_reg, Operand(zero_reg)); 4992 __ Branch(&done, ne, result_reg, Operand(zero_reg));
4980 __ mfhc1(scratch1, double_input); // Get exponent/sign bits. 4993 __ mfhc1(scratch1, double_input); // Get exponent/sign bits.
4981 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 4994 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
4982 DeoptimizeIf(ne, instr, Deoptimizer::kMinusZero, scratch1, 4995 DeoptimizeIf(ne, instr, DeoptimizeReason::kMinusZero, scratch1,
4983 Operand(zero_reg)); 4996 Operand(zero_reg));
4984 __ bind(&done); 4997 __ bind(&done);
4985 } 4998 }
4986 } 4999 }
4987 __ SmiTag(result_reg, result_reg); 5000 __ SmiTag(result_reg, result_reg);
4988 } 5001 }
4989 5002
4990 5003
4991 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 5004 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4992 LOperand* input = instr->value(); 5005 LOperand* input = instr->value();
4993 __ SmiTst(ToRegister(input), at); 5006 __ SmiTst(ToRegister(input), at);
4994 DeoptimizeIf(ne, instr, Deoptimizer::kNotASmi, at, Operand(zero_reg)); 5007 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotASmi, at, Operand(zero_reg));
4995 } 5008 }
4996 5009
4997 5010
4998 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 5011 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4999 if (!instr->hydrogen()->value()->type().IsHeapObject()) { 5012 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
5000 LOperand* input = instr->value(); 5013 LOperand* input = instr->value();
5001 __ SmiTst(ToRegister(input), at); 5014 __ SmiTst(ToRegister(input), at);
5002 DeoptimizeIf(eq, instr, Deoptimizer::kSmi, at, Operand(zero_reg)); 5015 DeoptimizeIf(eq, instr, DeoptimizeReason::kSmi, at, Operand(zero_reg));
5003 } 5016 }
5004 } 5017 }
5005 5018
5006 5019
5007 void LCodeGen::DoCheckArrayBufferNotNeutered( 5020 void LCodeGen::DoCheckArrayBufferNotNeutered(
5008 LCheckArrayBufferNotNeutered* instr) { 5021 LCheckArrayBufferNotNeutered* instr) {
5009 Register view = ToRegister(instr->view()); 5022 Register view = ToRegister(instr->view());
5010 Register scratch = scratch0(); 5023 Register scratch = scratch0();
5011 5024
5012 __ ld(scratch, FieldMemOperand(view, JSArrayBufferView::kBufferOffset)); 5025 __ ld(scratch, FieldMemOperand(view, JSArrayBufferView::kBufferOffset));
5013 __ lw(scratch, FieldMemOperand(scratch, JSArrayBuffer::kBitFieldOffset)); 5026 __ lw(scratch, FieldMemOperand(scratch, JSArrayBuffer::kBitFieldOffset));
5014 __ And(at, scratch, 1 << JSArrayBuffer::WasNeutered::kShift); 5027 __ And(at, scratch, 1 << JSArrayBuffer::WasNeutered::kShift);
5015 DeoptimizeIf(ne, instr, Deoptimizer::kOutOfBounds, at, Operand(zero_reg)); 5028 DeoptimizeIf(ne, instr, DeoptimizeReason::kOutOfBounds, at,
5029 Operand(zero_reg));
5016 } 5030 }
5017 5031
5018 5032
5019 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 5033 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5020 Register input = ToRegister(instr->value()); 5034 Register input = ToRegister(instr->value());
5021 Register scratch = scratch0(); 5035 Register scratch = scratch0();
5022 5036
5023 __ GetObjectType(input, scratch, scratch); 5037 __ GetObjectType(input, scratch, scratch);
5024 5038
5025 if (instr->hydrogen()->is_interval_check()) { 5039 if (instr->hydrogen()->is_interval_check()) {
5026 InstanceType first; 5040 InstanceType first;
5027 InstanceType last; 5041 InstanceType last;
5028 instr->hydrogen()->GetCheckInterval(&first, &last); 5042 instr->hydrogen()->GetCheckInterval(&first, &last);
5029 5043
5030 // If there is only one type in the interval check for equality. 5044 // If there is only one type in the interval check for equality.
5031 if (first == last) { 5045 if (first == last) {
5032 DeoptimizeIf(ne, instr, Deoptimizer::kWrongInstanceType, scratch, 5046 DeoptimizeIf(ne, instr, DeoptimizeReason::kWrongInstanceType, scratch,
5033 Operand(first)); 5047 Operand(first));
5034 } else { 5048 } else {
5035 DeoptimizeIf(lo, instr, Deoptimizer::kWrongInstanceType, scratch, 5049 DeoptimizeIf(lo, instr, DeoptimizeReason::kWrongInstanceType, scratch,
5036 Operand(first)); 5050 Operand(first));
5037 // Omit check for the last type. 5051 // Omit check for the last type.
5038 if (last != LAST_TYPE) { 5052 if (last != LAST_TYPE) {
5039 DeoptimizeIf(hi, instr, Deoptimizer::kWrongInstanceType, scratch, 5053 DeoptimizeIf(hi, instr, DeoptimizeReason::kWrongInstanceType, scratch,
5040 Operand(last)); 5054 Operand(last));
5041 } 5055 }
5042 } 5056 }
5043 } else { 5057 } else {
5044 uint8_t mask; 5058 uint8_t mask;
5045 uint8_t tag; 5059 uint8_t tag;
5046 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); 5060 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
5047 5061
5048 if (base::bits::IsPowerOfTwo32(mask)) { 5062 if (base::bits::IsPowerOfTwo32(mask)) {
5049 DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); 5063 DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
5050 __ And(at, scratch, mask); 5064 __ And(at, scratch, mask);
5051 DeoptimizeIf(tag == 0 ? ne : eq, instr, Deoptimizer::kWrongInstanceType, 5065 DeoptimizeIf(tag == 0 ? ne : eq, instr,
5052 at, Operand(zero_reg)); 5066 DeoptimizeReason::kWrongInstanceType, at, Operand(zero_reg));
5053 } else { 5067 } else {
5054 __ And(scratch, scratch, Operand(mask)); 5068 __ And(scratch, scratch, Operand(mask));
5055 DeoptimizeIf(ne, instr, Deoptimizer::kWrongInstanceType, scratch, 5069 DeoptimizeIf(ne, instr, DeoptimizeReason::kWrongInstanceType, scratch,
5056 Operand(tag)); 5070 Operand(tag));
5057 } 5071 }
5058 } 5072 }
5059 } 5073 }
5060 5074
5061 5075
5062 void LCodeGen::DoCheckValue(LCheckValue* instr) { 5076 void LCodeGen::DoCheckValue(LCheckValue* instr) {
5063 Register reg = ToRegister(instr->value()); 5077 Register reg = ToRegister(instr->value());
5064 Handle<HeapObject> object = instr->hydrogen()->object().handle(); 5078 Handle<HeapObject> object = instr->hydrogen()->object().handle();
5065 AllowDeferredHandleDereference smi_check; 5079 AllowDeferredHandleDereference smi_check;
5066 if (isolate()->heap()->InNewSpace(*object)) { 5080 if (isolate()->heap()->InNewSpace(*object)) {
5067 Register reg = ToRegister(instr->value()); 5081 Register reg = ToRegister(instr->value());
5068 Handle<Cell> cell = isolate()->factory()->NewCell(object); 5082 Handle<Cell> cell = isolate()->factory()->NewCell(object);
5069 __ li(at, Operand(cell)); 5083 __ li(at, Operand(cell));
5070 __ ld(at, FieldMemOperand(at, Cell::kValueOffset)); 5084 __ ld(at, FieldMemOperand(at, Cell::kValueOffset));
5071 DeoptimizeIf(ne, instr, Deoptimizer::kValueMismatch, reg, Operand(at)); 5085 DeoptimizeIf(ne, instr, DeoptimizeReason::kValueMismatch, reg, Operand(at));
5072 } else { 5086 } else {
5073 DeoptimizeIf(ne, instr, Deoptimizer::kValueMismatch, reg, Operand(object)); 5087 DeoptimizeIf(ne, instr, DeoptimizeReason::kValueMismatch, reg,
5088 Operand(object));
5074 } 5089 }
5075 } 5090 }
5076 5091
5077 5092
5078 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5093 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5079 { 5094 {
5080 PushSafepointRegistersScope scope(this); 5095 PushSafepointRegistersScope scope(this);
5081 __ push(object); 5096 __ push(object);
5082 __ mov(cp, zero_reg); 5097 __ mov(cp, zero_reg);
5083 __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); 5098 __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance);
5084 RecordSafepointWithRegisters( 5099 RecordSafepointWithRegisters(
5085 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); 5100 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5086 __ StoreToSafepointRegisterSlot(v0, scratch0()); 5101 __ StoreToSafepointRegisterSlot(v0, scratch0());
5087 } 5102 }
5088 __ SmiTst(scratch0(), at); 5103 __ SmiTst(scratch0(), at);
5089 DeoptimizeIf(eq, instr, Deoptimizer::kInstanceMigrationFailed, at, 5104 DeoptimizeIf(eq, instr, DeoptimizeReason::kInstanceMigrationFailed, at,
5090 Operand(zero_reg)); 5105 Operand(zero_reg));
5091 } 5106 }
5092 5107
5093 5108
5094 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 5109 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5095 class DeferredCheckMaps final : public LDeferredCode { 5110 class DeferredCheckMaps final : public LDeferredCode {
5096 public: 5111 public:
5097 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) 5112 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5098 : LDeferredCode(codegen), instr_(instr), object_(object) { 5113 : LDeferredCode(codegen), instr_(instr), object_(object) {
5099 SetExit(check_maps()); 5114 SetExit(check_maps());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
5134 Label success; 5149 Label success;
5135 for (int i = 0; i < maps->size() - 1; i++) { 5150 for (int i = 0; i < maps->size() - 1; i++) {
5136 Handle<Map> map = maps->at(i).handle(); 5151 Handle<Map> map = maps->at(i).handle();
5137 __ CompareMapAndBranch(map_reg, map, &success, eq, &success); 5152 __ CompareMapAndBranch(map_reg, map, &success, eq, &success);
5138 } 5153 }
5139 Handle<Map> map = maps->at(maps->size() - 1).handle(); 5154 Handle<Map> map = maps->at(maps->size() - 1).handle();
5140 // Do the CompareMap() directly within the Branch() and DeoptimizeIf(). 5155 // Do the CompareMap() directly within the Branch() and DeoptimizeIf().
5141 if (instr->hydrogen()->HasMigrationTarget()) { 5156 if (instr->hydrogen()->HasMigrationTarget()) {
5142 __ Branch(deferred->entry(), ne, map_reg, Operand(map)); 5157 __ Branch(deferred->entry(), ne, map_reg, Operand(map));
5143 } else { 5158 } else {
5144 DeoptimizeIf(ne, instr, Deoptimizer::kWrongMap, map_reg, Operand(map)); 5159 DeoptimizeIf(ne, instr, DeoptimizeReason::kWrongMap, map_reg, Operand(map));
5145 } 5160 }
5146 5161
5147 __ bind(&success); 5162 __ bind(&success);
5148 } 5163 }
5149 5164
5150 5165
5151 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5166 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5152 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); 5167 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
5153 Register result_reg = ToRegister(instr->result()); 5168 Register result_reg = ToRegister(instr->result());
5154 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); 5169 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
(...skipping 17 matching lines...) Expand all
5172 5187
5173 // Both smi and heap number cases are handled. 5188 // Both smi and heap number cases are handled.
5174 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); 5189 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi);
5175 5190
5176 // Check for heap number 5191 // Check for heap number
5177 __ ld(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 5192 __ ld(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
5178 __ Branch(&heap_number, eq, scratch, Operand(factory()->heap_number_map())); 5193 __ Branch(&heap_number, eq, scratch, Operand(factory()->heap_number_map()));
5179 5194
5180 // Check for undefined. Undefined is converted to zero for clamping 5195 // Check for undefined. Undefined is converted to zero for clamping
5181 // conversions. 5196 // conversions.
5182 DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumberUndefined, input_reg, 5197 DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumberUndefined, input_reg,
5183 Operand(factory()->undefined_value())); 5198 Operand(factory()->undefined_value()));
5184 __ mov(result_reg, zero_reg); 5199 __ mov(result_reg, zero_reg);
5185 __ jmp(&done); 5200 __ jmp(&done);
5186 5201
5187 // Heap number 5202 // Heap number
5188 __ bind(&heap_number); 5203 __ bind(&heap_number);
5189 __ ldc1(double_scratch0(), FieldMemOperand(input_reg, 5204 __ ldc1(double_scratch0(), FieldMemOperand(input_reg,
5190 HeapNumber::kValueOffset)); 5205 HeapNumber::kValueOffset));
5191 __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg); 5206 __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg);
5192 __ jmp(&done); 5207 __ jmp(&done);
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
5641 __ Branch(&load_cache, ne, result, Operand(Smi::FromInt(0))); 5656 __ Branch(&load_cache, ne, result, Operand(Smi::FromInt(0)));
5642 __ li(result, Operand(isolate()->factory()->empty_fixed_array())); 5657 __ li(result, Operand(isolate()->factory()->empty_fixed_array()));
5643 __ jmp(&done); 5658 __ jmp(&done);
5644 5659
5645 __ bind(&load_cache); 5660 __ bind(&load_cache);
5646 __ LoadInstanceDescriptors(map, result); 5661 __ LoadInstanceDescriptors(map, result);
5647 __ ld(result, 5662 __ ld(result,
5648 FieldMemOperand(result, DescriptorArray::kEnumCacheOffset)); 5663 FieldMemOperand(result, DescriptorArray::kEnumCacheOffset));
5649 __ ld(result, 5664 __ ld(result,
5650 FieldMemOperand(result, FixedArray::SizeFor(instr->idx()))); 5665 FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
5651 DeoptimizeIf(eq, instr, Deoptimizer::kNoCache, result, Operand(zero_reg)); 5666 DeoptimizeIf(eq, instr, DeoptimizeReason::kNoCache, result,
5667 Operand(zero_reg));
5652 5668
5653 __ bind(&done); 5669 __ bind(&done);
5654 } 5670 }
5655 5671
5656 5672
5657 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { 5673 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5658 Register object = ToRegister(instr->value()); 5674 Register object = ToRegister(instr->value());
5659 Register map = ToRegister(instr->map()); 5675 Register map = ToRegister(instr->map());
5660 __ ld(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset)); 5676 __ ld(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset));
5661 DeoptimizeIf(ne, instr, Deoptimizer::kWrongMap, map, Operand(scratch0())); 5677 DeoptimizeIf(ne, instr, DeoptimizeReason::kWrongMap, map,
5678 Operand(scratch0()));
5662 } 5679 }
5663 5680
5664 5681
5665 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 5682 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
5666 Register result, 5683 Register result,
5667 Register object, 5684 Register object,
5668 Register index) { 5685 Register index) {
5669 PushSafepointRegistersScope scope(this); 5686 PushSafepointRegistersScope scope(this);
5670 __ Push(object, index); 5687 __ Push(object, index);
5671 __ mov(cp, zero_reg); 5688 __ mov(cp, zero_reg);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
5731 __ ld(result, FieldMemOperand(scratch, 5748 __ ld(result, FieldMemOperand(scratch,
5732 FixedArray::kHeaderSize - kPointerSize)); 5749 FixedArray::kHeaderSize - kPointerSize));
5733 __ bind(deferred->exit()); 5750 __ bind(deferred->exit());
5734 __ bind(&done); 5751 __ bind(&done);
5735 } 5752 }
5736 5753
5737 #undef __ 5754 #undef __
5738 5755
5739 } // namespace internal 5756 } // namespace internal
5740 } // namespace v8 5757 } // namespace v8
OLDNEW
« no previous file with comments | « src/crankshaft/mips64/lithium-codegen-mips64.h ('k') | src/crankshaft/ppc/lithium-codegen-ppc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698