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

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

Issue 559143003: Thread the Lithium instruction down to DeoptimizeIf and friends. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mips64/lithium-codegen-mips64.h ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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/v8.h" 5 #include "src/v8.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/hydrogen-osr.h" 9 #include "src/hydrogen-osr.h"
10 #include "src/ic/ic.h" 10 #include "src/ic/ic.h"
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 int deoptimization_index = deoptimizations_.length(); 765 int deoptimization_index = deoptimizations_.length();
766 int pc_offset = masm()->pc_offset(); 766 int pc_offset = masm()->pc_offset();
767 environment->Register(deoptimization_index, 767 environment->Register(deoptimization_index,
768 translation.index(), 768 translation.index(),
769 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 769 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
770 deoptimizations_.Add(environment, zone()); 770 deoptimizations_.Add(environment, zone());
771 } 771 }
772 } 772 }
773 773
774 774
775 void LCodeGen::DeoptimizeIf(Condition condition, 775 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
776 LEnvironment* environment,
777 Deoptimizer::BailoutType bailout_type, 776 Deoptimizer::BailoutType bailout_type,
778 Register src1, 777 Register src1, const Operand& src2) {
779 const Operand& src2) { 778 LEnvironment* environment = instr->environment();
780 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 779 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
781 DCHECK(environment->HasBeenRegistered()); 780 DCHECK(environment->HasBeenRegistered());
782 int id = environment->deoptimization_index(); 781 int id = environment->deoptimization_index();
783 DCHECK(info()->IsOptimizing() || info()->IsStub()); 782 DCHECK(info()->IsOptimizing() || info()->IsStub());
784 Address entry = 783 Address entry =
785 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); 784 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
786 if (entry == NULL) { 785 if (entry == NULL) {
787 Abort(kBailoutWasNotPrepared); 786 Abort(kBailoutWasNotPrepared);
788 return; 787 return;
789 } 788 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 Deoptimizer::JumpTableEntry table_entry(entry, 831 Deoptimizer::JumpTableEntry table_entry(entry,
833 bailout_type, 832 bailout_type,
834 !frame_is_built_); 833 !frame_is_built_);
835 deopt_jump_table_.Add(table_entry, zone()); 834 deopt_jump_table_.Add(table_entry, zone());
836 } 835 }
837 __ Branch(&deopt_jump_table_.last().label, condition, src1, src2); 836 __ Branch(&deopt_jump_table_.last().label, condition, src1, src2);
838 } 837 }
839 } 838 }
840 839
841 840
842 void LCodeGen::DeoptimizeIf(Condition condition, 841 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
843 LEnvironment* environment, 842 Register src1, const Operand& src2) {
844 Register src1,
845 const Operand& src2) {
846 Deoptimizer::BailoutType bailout_type = info()->IsStub() 843 Deoptimizer::BailoutType bailout_type = info()->IsStub()
847 ? Deoptimizer::LAZY 844 ? Deoptimizer::LAZY
848 : Deoptimizer::EAGER; 845 : Deoptimizer::EAGER;
849 DeoptimizeIf(condition, environment, bailout_type, src1, src2); 846 DeoptimizeIf(condition, instr, bailout_type, src1, src2);
850 } 847 }
851 848
852 849
853 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 850 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
854 int length = deoptimizations_.length(); 851 int length = deoptimizations_.length();
855 if (length == 0) return; 852 if (length == 0) return;
856 Handle<DeoptimizationInputData> data = 853 Handle<DeoptimizationInputData> data =
857 DeoptimizationInputData::New(isolate(), length, TENURED); 854 DeoptimizationInputData::New(isolate(), length, TENURED);
858 855
859 Handle<ByteArray> translations = 856 Handle<ByteArray> translations =
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 HMod* hmod = instr->hydrogen(); 1066 HMod* hmod = instr->hydrogen();
1070 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1067 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
1071 Label dividend_is_not_negative, done; 1068 Label dividend_is_not_negative, done;
1072 1069
1073 if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) { 1070 if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) {
1074 __ Branch(&dividend_is_not_negative, ge, dividend, Operand(zero_reg)); 1071 __ Branch(&dividend_is_not_negative, ge, dividend, Operand(zero_reg));
1075 // Note: The code below even works when right contains kMinInt. 1072 // Note: The code below even works when right contains kMinInt.
1076 __ dsubu(dividend, zero_reg, dividend); 1073 __ dsubu(dividend, zero_reg, dividend);
1077 __ And(dividend, dividend, Operand(mask)); 1074 __ And(dividend, dividend, Operand(mask));
1078 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1075 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1079 DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg)); 1076 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1080 } 1077 }
1081 __ Branch(USE_DELAY_SLOT, &done); 1078 __ Branch(USE_DELAY_SLOT, &done);
1082 __ dsubu(dividend, zero_reg, dividend); 1079 __ dsubu(dividend, zero_reg, dividend);
1083 } 1080 }
1084 1081
1085 __ bind(&dividend_is_not_negative); 1082 __ bind(&dividend_is_not_negative);
1086 __ And(dividend, dividend, Operand(mask)); 1083 __ And(dividend, dividend, Operand(mask));
1087 __ bind(&done); 1084 __ bind(&done);
1088 } 1085 }
1089 1086
1090 1087
1091 void LCodeGen::DoModByConstI(LModByConstI* instr) { 1088 void LCodeGen::DoModByConstI(LModByConstI* instr) {
1092 Register dividend = ToRegister(instr->dividend()); 1089 Register dividend = ToRegister(instr->dividend());
1093 int32_t divisor = instr->divisor(); 1090 int32_t divisor = instr->divisor();
1094 Register result = ToRegister(instr->result()); 1091 Register result = ToRegister(instr->result());
1095 DCHECK(!dividend.is(result)); 1092 DCHECK(!dividend.is(result));
1096 1093
1097 if (divisor == 0) { 1094 if (divisor == 0) {
1098 DeoptimizeIf(al, instr->environment()); 1095 DeoptimizeIf(al, instr);
1099 return; 1096 return;
1100 } 1097 }
1101 1098
1102 __ TruncatingDiv(result, dividend, Abs(divisor)); 1099 __ TruncatingDiv(result, dividend, Abs(divisor));
1103 __ Dmul(result, result, Operand(Abs(divisor))); 1100 __ Dmul(result, result, Operand(Abs(divisor)));
1104 __ Dsubu(result, dividend, Operand(result)); 1101 __ Dsubu(result, dividend, Operand(result));
1105 1102
1106 // Check for negative zero. 1103 // Check for negative zero.
1107 HMod* hmod = instr->hydrogen(); 1104 HMod* hmod = instr->hydrogen();
1108 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1105 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1109 Label remainder_not_zero; 1106 Label remainder_not_zero;
1110 __ Branch(&remainder_not_zero, ne, result, Operand(zero_reg)); 1107 __ Branch(&remainder_not_zero, ne, result, Operand(zero_reg));
1111 DeoptimizeIf(lt, instr->environment(), dividend, Operand(zero_reg)); 1108 DeoptimizeIf(lt, instr, dividend, Operand(zero_reg));
1112 __ bind(&remainder_not_zero); 1109 __ bind(&remainder_not_zero);
1113 } 1110 }
1114 } 1111 }
1115 1112
1116 1113
1117 void LCodeGen::DoModI(LModI* instr) { 1114 void LCodeGen::DoModI(LModI* instr) {
1118 HMod* hmod = instr->hydrogen(); 1115 HMod* hmod = instr->hydrogen();
1119 const Register left_reg = ToRegister(instr->left()); 1116 const Register left_reg = ToRegister(instr->left());
1120 const Register right_reg = ToRegister(instr->right()); 1117 const Register right_reg = ToRegister(instr->right());
1121 const Register result_reg = ToRegister(instr->result()); 1118 const Register result_reg = ToRegister(instr->result());
1122 1119
1123 // div runs in the background while we check for special cases. 1120 // div runs in the background while we check for special cases.
1124 __ Dmod(result_reg, left_reg, right_reg); 1121 __ Dmod(result_reg, left_reg, right_reg);
1125 1122
1126 Label done; 1123 Label done;
1127 // Check for x % 0, we have to deopt in this case because we can't return a 1124 // Check for x % 0, we have to deopt in this case because we can't return a
1128 // NaN. 1125 // NaN.
1129 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { 1126 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
1130 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(zero_reg)); 1127 DeoptimizeIf(eq, instr, right_reg, Operand(zero_reg));
1131 } 1128 }
1132 1129
1133 // Check for kMinInt % -1, div will return kMinInt, which is not what we 1130 // Check for kMinInt % -1, div will return kMinInt, which is not what we
1134 // want. We have to deopt if we care about -0, because we can't return that. 1131 // want. We have to deopt if we care about -0, because we can't return that.
1135 if (hmod->CheckFlag(HValue::kCanOverflow)) { 1132 if (hmod->CheckFlag(HValue::kCanOverflow)) {
1136 Label no_overflow_possible; 1133 Label no_overflow_possible;
1137 __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt)); 1134 __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt));
1138 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1135 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1139 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1)); 1136 DeoptimizeIf(eq, instr, right_reg, Operand(-1));
1140 } else { 1137 } else {
1141 __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1)); 1138 __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1));
1142 __ Branch(USE_DELAY_SLOT, &done); 1139 __ Branch(USE_DELAY_SLOT, &done);
1143 __ mov(result_reg, zero_reg); 1140 __ mov(result_reg, zero_reg);
1144 } 1141 }
1145 __ bind(&no_overflow_possible); 1142 __ bind(&no_overflow_possible);
1146 } 1143 }
1147 1144
1148 // If we care about -0, test if the dividend is <0 and the result is 0. 1145 // If we care about -0, test if the dividend is <0 and the result is 0.
1149 __ Branch(&done, ge, left_reg, Operand(zero_reg)); 1146 __ Branch(&done, ge, left_reg, Operand(zero_reg));
1150 1147
1151 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1148 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1152 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg)); 1149 DeoptimizeIf(eq, instr, result_reg, Operand(zero_reg));
1153 } 1150 }
1154 __ bind(&done); 1151 __ bind(&done);
1155 } 1152 }
1156 1153
1157 1154
1158 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { 1155 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1159 Register dividend = ToRegister(instr->dividend()); 1156 Register dividend = ToRegister(instr->dividend());
1160 int32_t divisor = instr->divisor(); 1157 int32_t divisor = instr->divisor();
1161 Register result = ToRegister(instr->result()); 1158 Register result = ToRegister(instr->result());
1162 DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor))); 1159 DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor)));
1163 DCHECK(!result.is(dividend)); 1160 DCHECK(!result.is(dividend));
1164 1161
1165 // Check for (0 / -x) that will produce negative zero. 1162 // Check for (0 / -x) that will produce negative zero.
1166 HDiv* hdiv = instr->hydrogen(); 1163 HDiv* hdiv = instr->hydrogen();
1167 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1164 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1168 DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg)); 1165 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1169 } 1166 }
1170 // Check for (kMinInt / -1). 1167 // Check for (kMinInt / -1).
1171 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { 1168 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
1172 DeoptimizeIf(eq, instr->environment(), dividend, Operand(kMinInt)); 1169 DeoptimizeIf(eq, instr, dividend, Operand(kMinInt));
1173 } 1170 }
1174 // Deoptimize if remainder will not be 0. 1171 // Deoptimize if remainder will not be 0.
1175 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && 1172 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1176 divisor != 1 && divisor != -1) { 1173 divisor != 1 && divisor != -1) {
1177 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1174 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
1178 __ And(at, dividend, Operand(mask)); 1175 __ And(at, dividend, Operand(mask));
1179 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 1176 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
1180 } 1177 }
1181 1178
1182 if (divisor == -1) { // Nice shortcut, not needed for correctness. 1179 if (divisor == -1) { // Nice shortcut, not needed for correctness.
1183 __ Dsubu(result, zero_reg, dividend); 1180 __ Dsubu(result, zero_reg, dividend);
1184 return; 1181 return;
1185 } 1182 }
1186 uint16_t shift = WhichPowerOf2Abs(divisor); 1183 uint16_t shift = WhichPowerOf2Abs(divisor);
1187 if (shift == 0) { 1184 if (shift == 0) {
1188 __ Move(result, dividend); 1185 __ Move(result, dividend);
1189 } else if (shift == 1) { 1186 } else if (shift == 1) {
1190 __ dsrl32(result, dividend, 31); 1187 __ dsrl32(result, dividend, 31);
1191 __ Daddu(result, dividend, Operand(result)); 1188 __ Daddu(result, dividend, Operand(result));
1192 } else { 1189 } else {
1193 __ dsra32(result, dividend, 31); 1190 __ dsra32(result, dividend, 31);
1194 __ dsrl32(result, result, 32 - shift); 1191 __ dsrl32(result, result, 32 - shift);
1195 __ Daddu(result, dividend, Operand(result)); 1192 __ Daddu(result, dividend, Operand(result));
1196 } 1193 }
1197 if (shift > 0) __ dsra(result, result, shift); 1194 if (shift > 0) __ dsra(result, result, shift);
1198 if (divisor < 0) __ Dsubu(result, zero_reg, result); 1195 if (divisor < 0) __ Dsubu(result, zero_reg, result);
1199 } 1196 }
1200 1197
1201 1198
1202 void LCodeGen::DoDivByConstI(LDivByConstI* instr) { 1199 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
1203 Register dividend = ToRegister(instr->dividend()); 1200 Register dividend = ToRegister(instr->dividend());
1204 int32_t divisor = instr->divisor(); 1201 int32_t divisor = instr->divisor();
1205 Register result = ToRegister(instr->result()); 1202 Register result = ToRegister(instr->result());
1206 DCHECK(!dividend.is(result)); 1203 DCHECK(!dividend.is(result));
1207 1204
1208 if (divisor == 0) { 1205 if (divisor == 0) {
1209 DeoptimizeIf(al, instr->environment()); 1206 DeoptimizeIf(al, instr);
1210 return; 1207 return;
1211 } 1208 }
1212 1209
1213 // Check for (0 / -x) that will produce negative zero. 1210 // Check for (0 / -x) that will produce negative zero.
1214 HDiv* hdiv = instr->hydrogen(); 1211 HDiv* hdiv = instr->hydrogen();
1215 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1212 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1216 DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg)); 1213 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1217 } 1214 }
1218 1215
1219 __ TruncatingDiv(result, dividend, Abs(divisor)); 1216 __ TruncatingDiv(result, dividend, Abs(divisor));
1220 if (divisor < 0) __ Subu(result, zero_reg, result); 1217 if (divisor < 0) __ Subu(result, zero_reg, result);
1221 1218
1222 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { 1219 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1223 __ Dmul(scratch0(), result, Operand(divisor)); 1220 __ Dmul(scratch0(), result, Operand(divisor));
1224 __ Dsubu(scratch0(), scratch0(), dividend); 1221 __ Dsubu(scratch0(), scratch0(), dividend);
1225 DeoptimizeIf(ne, instr->environment(), scratch0(), Operand(zero_reg)); 1222 DeoptimizeIf(ne, instr, scratch0(), Operand(zero_reg));
1226 } 1223 }
1227 } 1224 }
1228 1225
1229 1226
1230 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. 1227 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
1231 void LCodeGen::DoDivI(LDivI* instr) { 1228 void LCodeGen::DoDivI(LDivI* instr) {
1232 HBinaryOperation* hdiv = instr->hydrogen(); 1229 HBinaryOperation* hdiv = instr->hydrogen();
1233 Register dividend = ToRegister(instr->dividend()); 1230 Register dividend = ToRegister(instr->dividend());
1234 Register divisor = ToRegister(instr->divisor()); 1231 Register divisor = ToRegister(instr->divisor());
1235 const Register result = ToRegister(instr->result()); 1232 const Register result = ToRegister(instr->result());
1236 1233
1237 // On MIPS div is asynchronous - it will run in the background while we 1234 // On MIPS div is asynchronous - it will run in the background while we
1238 // check for special cases. 1235 // check for special cases.
1239 __ Ddiv(result, dividend, divisor); 1236 __ Ddiv(result, dividend, divisor);
1240 1237
1241 // Check for x / 0. 1238 // Check for x / 0.
1242 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1239 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
1243 DeoptimizeIf(eq, instr->environment(), divisor, Operand(zero_reg)); 1240 DeoptimizeIf(eq, instr, divisor, Operand(zero_reg));
1244 } 1241 }
1245 1242
1246 // Check for (0 / -x) that will produce negative zero. 1243 // Check for (0 / -x) that will produce negative zero.
1247 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1244 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1248 Label left_not_zero; 1245 Label left_not_zero;
1249 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg)); 1246 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
1250 DeoptimizeIf(lt, instr->environment(), divisor, Operand(zero_reg)); 1247 DeoptimizeIf(lt, instr, divisor, Operand(zero_reg));
1251 __ bind(&left_not_zero); 1248 __ bind(&left_not_zero);
1252 } 1249 }
1253 1250
1254 // Check for (kMinInt / -1). 1251 // Check for (kMinInt / -1).
1255 if (hdiv->CheckFlag(HValue::kCanOverflow) && 1252 if (hdiv->CheckFlag(HValue::kCanOverflow) &&
1256 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1253 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1257 Label left_not_min_int; 1254 Label left_not_min_int;
1258 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt)); 1255 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
1259 DeoptimizeIf(eq, instr->environment(), divisor, Operand(-1)); 1256 DeoptimizeIf(eq, instr, divisor, Operand(-1));
1260 __ bind(&left_not_min_int); 1257 __ bind(&left_not_min_int);
1261 } 1258 }
1262 1259
1263 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1260 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1264 // Calculate remainder. 1261 // Calculate remainder.
1265 Register remainder = ToRegister(instr->temp()); 1262 Register remainder = ToRegister(instr->temp());
1266 if (kArchVariant != kMips64r6) { 1263 if (kArchVariant != kMips64r6) {
1267 __ mfhi(remainder); 1264 __ mfhi(remainder);
1268 } else { 1265 } else {
1269 __ dmod(remainder, dividend, divisor); 1266 __ dmod(remainder, dividend, divisor);
1270 } 1267 }
1271 DeoptimizeIf(ne, instr->environment(), remainder, Operand(zero_reg)); 1268 DeoptimizeIf(ne, instr, remainder, Operand(zero_reg));
1272 } 1269 }
1273 } 1270 }
1274 1271
1275 1272
1276 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { 1273 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
1277 DoubleRegister addend = ToDoubleRegister(instr->addend()); 1274 DoubleRegister addend = ToDoubleRegister(instr->addend());
1278 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); 1275 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier());
1279 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand()); 1276 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
1280 1277
1281 // This is computed in-place. 1278 // This is computed in-place.
(...skipping 24 matching lines...) Expand all
1306 return; 1303 return;
1307 } 1304 }
1308 1305
1309 // If the divisor is negative, we have to negate and handle edge cases. 1306 // If the divisor is negative, we have to negate and handle edge cases.
1310 // Dividend can be the same register as result so save the value of it 1307 // Dividend can be the same register as result so save the value of it
1311 // for checking overflow. 1308 // for checking overflow.
1312 __ Move(scratch, dividend); 1309 __ Move(scratch, dividend);
1313 1310
1314 __ Dsubu(result, zero_reg, dividend); 1311 __ Dsubu(result, zero_reg, dividend);
1315 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1312 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1316 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 1313 DeoptimizeIf(eq, instr, result, Operand(zero_reg));
1317 } 1314 }
1318 1315
1319 __ Xor(scratch, scratch, result); 1316 __ Xor(scratch, scratch, result);
1320 // Dividing by -1 is basically negation, unless we overflow. 1317 // Dividing by -1 is basically negation, unless we overflow.
1321 if (divisor == -1) { 1318 if (divisor == -1) {
1322 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 1319 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1323 DeoptimizeIf(gt, instr->environment(), result, Operand(kMaxInt)); 1320 DeoptimizeIf(gt, instr, result, Operand(kMaxInt));
1324 } 1321 }
1325 return; 1322 return;
1326 } 1323 }
1327 1324
1328 // If the negation could not overflow, simply shifting is OK. 1325 // If the negation could not overflow, simply shifting is OK.
1329 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 1326 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1330 __ dsra(result, result, shift); 1327 __ dsra(result, result, shift);
1331 return; 1328 return;
1332 } 1329 }
1333 1330
1334 Label no_overflow, done; 1331 Label no_overflow, done;
1335 __ Branch(&no_overflow, lt, scratch, Operand(zero_reg)); 1332 __ Branch(&no_overflow, lt, scratch, Operand(zero_reg));
1336 __ li(result, Operand(kMinInt / divisor), CONSTANT_SIZE); 1333 __ li(result, Operand(kMinInt / divisor), CONSTANT_SIZE);
1337 __ Branch(&done); 1334 __ Branch(&done);
1338 __ bind(&no_overflow); 1335 __ bind(&no_overflow);
1339 __ dsra(result, result, shift); 1336 __ dsra(result, result, shift);
1340 __ bind(&done); 1337 __ bind(&done);
1341 } 1338 }
1342 1339
1343 1340
1344 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { 1341 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
1345 Register dividend = ToRegister(instr->dividend()); 1342 Register dividend = ToRegister(instr->dividend());
1346 int32_t divisor = instr->divisor(); 1343 int32_t divisor = instr->divisor();
1347 Register result = ToRegister(instr->result()); 1344 Register result = ToRegister(instr->result());
1348 DCHECK(!dividend.is(result)); 1345 DCHECK(!dividend.is(result));
1349 1346
1350 if (divisor == 0) { 1347 if (divisor == 0) {
1351 DeoptimizeIf(al, instr->environment()); 1348 DeoptimizeIf(al, instr);
1352 return; 1349 return;
1353 } 1350 }
1354 1351
1355 // Check for (0 / -x) that will produce negative zero. 1352 // Check for (0 / -x) that will produce negative zero.
1356 HMathFloorOfDiv* hdiv = instr->hydrogen(); 1353 HMathFloorOfDiv* hdiv = instr->hydrogen();
1357 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1354 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1358 DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg)); 1355 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1359 } 1356 }
1360 1357
1361 // Easy case: We need no dynamic check for the dividend and the flooring 1358 // Easy case: We need no dynamic check for the dividend and the flooring
1362 // division is the same as the truncating division. 1359 // division is the same as the truncating division.
1363 if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) || 1360 if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) ||
1364 (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) { 1361 (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) {
1365 __ TruncatingDiv(result, dividend, Abs(divisor)); 1362 __ TruncatingDiv(result, dividend, Abs(divisor));
1366 if (divisor < 0) __ Dsubu(result, zero_reg, result); 1363 if (divisor < 0) __ Dsubu(result, zero_reg, result);
1367 return; 1364 return;
1368 } 1365 }
(...skipping 23 matching lines...) Expand all
1392 Register dividend = ToRegister(instr->dividend()); 1389 Register dividend = ToRegister(instr->dividend());
1393 Register divisor = ToRegister(instr->divisor()); 1390 Register divisor = ToRegister(instr->divisor());
1394 const Register result = ToRegister(instr->result()); 1391 const Register result = ToRegister(instr->result());
1395 1392
1396 // On MIPS div is asynchronous - it will run in the background while we 1393 // On MIPS div is asynchronous - it will run in the background while we
1397 // check for special cases. 1394 // check for special cases.
1398 __ Ddiv(result, dividend, divisor); 1395 __ Ddiv(result, dividend, divisor);
1399 1396
1400 // Check for x / 0. 1397 // Check for x / 0.
1401 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1398 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
1402 DeoptimizeIf(eq, instr->environment(), divisor, Operand(zero_reg)); 1399 DeoptimizeIf(eq, instr, divisor, Operand(zero_reg));
1403 } 1400 }
1404 1401
1405 // Check for (0 / -x) that will produce negative zero. 1402 // Check for (0 / -x) that will produce negative zero.
1406 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1403 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1407 Label left_not_zero; 1404 Label left_not_zero;
1408 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg)); 1405 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
1409 DeoptimizeIf(lt, instr->environment(), divisor, Operand(zero_reg)); 1406 DeoptimizeIf(lt, instr, divisor, Operand(zero_reg));
1410 __ bind(&left_not_zero); 1407 __ bind(&left_not_zero);
1411 } 1408 }
1412 1409
1413 // Check for (kMinInt / -1). 1410 // Check for (kMinInt / -1).
1414 if (hdiv->CheckFlag(HValue::kCanOverflow) && 1411 if (hdiv->CheckFlag(HValue::kCanOverflow) &&
1415 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1412 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1416 Label left_not_min_int; 1413 Label left_not_min_int;
1417 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt)); 1414 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
1418 DeoptimizeIf(eq, instr->environment(), divisor, Operand(-1)); 1415 DeoptimizeIf(eq, instr, divisor, Operand(-1));
1419 __ bind(&left_not_min_int); 1416 __ bind(&left_not_min_int);
1420 } 1417 }
1421 1418
1422 // We performed a truncating division. Correct the result if necessary. 1419 // We performed a truncating division. Correct the result if necessary.
1423 Label done; 1420 Label done;
1424 Register remainder = scratch0(); 1421 Register remainder = scratch0();
1425 if (kArchVariant != kMips64r6) { 1422 if (kArchVariant != kMips64r6) {
1426 __ mfhi(remainder); 1423 __ mfhi(remainder);
1427 } else { 1424 } else {
1428 __ dmod(remainder, dividend, divisor); 1425 __ dmod(remainder, dividend, divisor);
(...skipping 16 matching lines...) Expand all
1445 bool bailout_on_minus_zero = 1442 bool bailout_on_minus_zero =
1446 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1443 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1447 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1444 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1448 1445
1449 if (right_op->IsConstantOperand()) { 1446 if (right_op->IsConstantOperand()) {
1450 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); 1447 int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
1451 1448
1452 if (bailout_on_minus_zero && (constant < 0)) { 1449 if (bailout_on_minus_zero && (constant < 0)) {
1453 // The case of a null constant will be handled separately. 1450 // The case of a null constant will be handled separately.
1454 // If constant is negative and left is null, the result should be -0. 1451 // If constant is negative and left is null, the result should be -0.
1455 DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg)); 1452 DeoptimizeIf(eq, instr, left, Operand(zero_reg));
1456 } 1453 }
1457 1454
1458 switch (constant) { 1455 switch (constant) {
1459 case -1: 1456 case -1:
1460 if (overflow) { 1457 if (overflow) {
1461 __ SubuAndCheckForOverflow(result, zero_reg, left, scratch); 1458 __ SubuAndCheckForOverflow(result, zero_reg, left, scratch);
1462 DeoptimizeIf(gt, instr->environment(), scratch, Operand(kMaxInt)); 1459 DeoptimizeIf(gt, instr, scratch, Operand(kMaxInt));
1463 } else { 1460 } else {
1464 __ Dsubu(result, zero_reg, left); 1461 __ Dsubu(result, zero_reg, left);
1465 } 1462 }
1466 break; 1463 break;
1467 case 0: 1464 case 0:
1468 if (bailout_on_minus_zero) { 1465 if (bailout_on_minus_zero) {
1469 // If left is strictly negative and the constant is null, the 1466 // If left is strictly negative and the constant is null, the
1470 // result is -0. Deoptimize if required, otherwise return 0. 1467 // result is -0. Deoptimize if required, otherwise return 0.
1471 DeoptimizeIf(lt, instr->environment(), left, Operand(zero_reg)); 1468 DeoptimizeIf(lt, instr, left, Operand(zero_reg));
1472 } 1469 }
1473 __ mov(result, zero_reg); 1470 __ mov(result, zero_reg);
1474 break; 1471 break;
1475 case 1: 1472 case 1:
1476 // Nothing to do. 1473 // Nothing to do.
1477 __ Move(result, left); 1474 __ Move(result, left);
1478 break; 1475 break;
1479 default: 1476 default:
1480 // Multiplying by powers of two and powers of two plus or minus 1477 // Multiplying by powers of two and powers of two plus or minus
1481 // one can be done faster with shifted operands. 1478 // one can be done faster with shifted operands.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 if (instr->hydrogen()->representation().IsSmi()) { 1513 if (instr->hydrogen()->representation().IsSmi()) {
1517 __ Dmulh(result, left, right); 1514 __ Dmulh(result, left, right);
1518 } else { 1515 } else {
1519 __ Dmul(result, left, right); 1516 __ Dmul(result, left, right);
1520 } 1517 }
1521 __ dsra32(scratch, result, 0); 1518 __ dsra32(scratch, result, 0);
1522 __ sra(at, result, 31); 1519 __ sra(at, result, 31);
1523 if (instr->hydrogen()->representation().IsSmi()) { 1520 if (instr->hydrogen()->representation().IsSmi()) {
1524 __ SmiTag(result); 1521 __ SmiTag(result);
1525 } 1522 }
1526 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); 1523 DeoptimizeIf(ne, instr, scratch, Operand(at));
1527 } else { 1524 } else {
1528 if (instr->hydrogen()->representation().IsSmi()) { 1525 if (instr->hydrogen()->representation().IsSmi()) {
1529 __ SmiUntag(result, left); 1526 __ SmiUntag(result, left);
1530 __ Dmul(result, result, right); 1527 __ Dmul(result, result, right);
1531 } else { 1528 } else {
1532 __ Dmul(result, left, right); 1529 __ Dmul(result, left, right);
1533 } 1530 }
1534 } 1531 }
1535 1532
1536 if (bailout_on_minus_zero) { 1533 if (bailout_on_minus_zero) {
1537 Label done; 1534 Label done;
1538 __ Xor(at, left, right); 1535 __ Xor(at, left, right);
1539 __ Branch(&done, ge, at, Operand(zero_reg)); 1536 __ Branch(&done, ge, at, Operand(zero_reg));
1540 // Bail out if the result is minus zero. 1537 // Bail out if the result is minus zero.
1541 DeoptimizeIf(eq, 1538 DeoptimizeIf(eq, instr, result, Operand(zero_reg));
1542 instr->environment(),
1543 result,
1544 Operand(zero_reg));
1545 __ bind(&done); 1539 __ bind(&done);
1546 } 1540 }
1547 } 1541 }
1548 } 1542 }
1549 1543
1550 1544
1551 void LCodeGen::DoBitI(LBitI* instr) { 1545 void LCodeGen::DoBitI(LBitI* instr) {
1552 LOperand* left_op = instr->left(); 1546 LOperand* left_op = instr->left();
1553 LOperand* right_op = instr->right(); 1547 LOperand* right_op = instr->right();
1554 DCHECK(left_op->IsRegister()); 1548 DCHECK(left_op->IsRegister());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 case Token::ROR: 1592 case Token::ROR:
1599 __ Ror(result, left, Operand(ToRegister(right_op))); 1593 __ Ror(result, left, Operand(ToRegister(right_op)));
1600 break; 1594 break;
1601 case Token::SAR: 1595 case Token::SAR:
1602 __ srav(result, left, ToRegister(right_op)); 1596 __ srav(result, left, ToRegister(right_op));
1603 break; 1597 break;
1604 case Token::SHR: 1598 case Token::SHR:
1605 __ srlv(result, left, ToRegister(right_op)); 1599 __ srlv(result, left, ToRegister(right_op));
1606 if (instr->can_deopt()) { 1600 if (instr->can_deopt()) {
1607 // TODO(yy): (-1) >>> 0. anything else? 1601 // TODO(yy): (-1) >>> 0. anything else?
1608 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); 1602 DeoptimizeIf(lt, instr, result, Operand(zero_reg));
1609 DeoptimizeIf(gt, instr->environment(), result, Operand(kMaxInt)); 1603 DeoptimizeIf(gt, instr, result, Operand(kMaxInt));
1610 } 1604 }
1611 break; 1605 break;
1612 case Token::SHL: 1606 case Token::SHL:
1613 __ sllv(result, left, ToRegister(right_op)); 1607 __ sllv(result, left, ToRegister(right_op));
1614 break; 1608 break;
1615 default: 1609 default:
1616 UNREACHABLE(); 1610 UNREACHABLE();
1617 break; 1611 break;
1618 } 1612 }
1619 } else { 1613 } else {
(...skipping 14 matching lines...) Expand all
1634 } else { 1628 } else {
1635 __ Move(result, left); 1629 __ Move(result, left);
1636 } 1630 }
1637 break; 1631 break;
1638 case Token::SHR: 1632 case Token::SHR:
1639 if (shift_count != 0) { 1633 if (shift_count != 0) {
1640 __ srl(result, left, shift_count); 1634 __ srl(result, left, shift_count);
1641 } else { 1635 } else {
1642 if (instr->can_deopt()) { 1636 if (instr->can_deopt()) {
1643 __ And(at, left, Operand(0x80000000)); 1637 __ And(at, left, Operand(0x80000000));
1644 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 1638 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
1645 } 1639 }
1646 __ Move(result, left); 1640 __ Move(result, left);
1647 } 1641 }
1648 break; 1642 break;
1649 case Token::SHL: 1643 case Token::SHL:
1650 if (shift_count != 0) { 1644 if (shift_count != 0) {
1651 if (instr->hydrogen_value()->representation().IsSmi()) { 1645 if (instr->hydrogen_value()->representation().IsSmi()) {
1652 __ dsll(result, left, shift_count); 1646 __ dsll(result, left, shift_count);
1653 } else { 1647 } else {
1654 __ sll(result, left, shift_count); 1648 __ sll(result, left, shift_count);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 overflow); // Reg at also used as scratch. 1684 overflow); // Reg at also used as scratch.
1691 } else { 1685 } else {
1692 DCHECK(right->IsRegister()); 1686 DCHECK(right->IsRegister());
1693 // Due to overflow check macros not supporting constant operands, 1687 // Due to overflow check macros not supporting constant operands,
1694 // handling the IsConstantOperand case was moved to prev if clause. 1688 // handling the IsConstantOperand case was moved to prev if clause.
1695 __ SubuAndCheckForOverflow(ToRegister(result), 1689 __ SubuAndCheckForOverflow(ToRegister(result),
1696 ToRegister(left), 1690 ToRegister(left),
1697 ToRegister(right), 1691 ToRegister(right),
1698 overflow); // Reg at also used as scratch. 1692 overflow); // Reg at also used as scratch.
1699 } 1693 }
1700 DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg)); 1694 DeoptimizeIf(lt, instr, overflow, Operand(zero_reg));
1701 if (!instr->hydrogen()->representation().IsSmi()) { 1695 if (!instr->hydrogen()->representation().IsSmi()) {
1702 DeoptimizeIf(gt, instr->environment(), 1696 DeoptimizeIf(gt, instr, ToRegister(result), Operand(kMaxInt));
1703 ToRegister(result), Operand(kMaxInt)); 1697 DeoptimizeIf(lt, instr, ToRegister(result), Operand(kMinInt));
1704 DeoptimizeIf(lt, instr->environment(),
1705 ToRegister(result), Operand(kMinInt));
1706 } 1698 }
1707 } 1699 }
1708 } 1700 }
1709 1701
1710 1702
1711 void LCodeGen::DoConstantI(LConstantI* instr) { 1703 void LCodeGen::DoConstantI(LConstantI* instr) {
1712 __ li(ToRegister(instr->result()), Operand(instr->value())); 1704 __ li(ToRegister(instr->result()), Operand(instr->value()));
1713 } 1705 }
1714 1706
1715 1707
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 Register result = ToRegister(instr->result()); 1742 Register result = ToRegister(instr->result());
1751 Register scratch = ToRegister(instr->temp()); 1743 Register scratch = ToRegister(instr->temp());
1752 Smi* index = instr->index(); 1744 Smi* index = instr->index();
1753 Label runtime, done; 1745 Label runtime, done;
1754 DCHECK(object.is(a0)); 1746 DCHECK(object.is(a0));
1755 DCHECK(result.is(v0)); 1747 DCHECK(result.is(v0));
1756 DCHECK(!scratch.is(scratch0())); 1748 DCHECK(!scratch.is(scratch0()));
1757 DCHECK(!scratch.is(object)); 1749 DCHECK(!scratch.is(object));
1758 1750
1759 __ SmiTst(object, at); 1751 __ SmiTst(object, at);
1760 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 1752 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
1761 __ GetObjectType(object, scratch, scratch); 1753 __ GetObjectType(object, scratch, scratch);
1762 DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_DATE_TYPE)); 1754 DeoptimizeIf(ne, instr, scratch, Operand(JS_DATE_TYPE));
1763 1755
1764 if (index->value() == 0) { 1756 if (index->value() == 0) {
1765 __ ld(result, FieldMemOperand(object, JSDate::kValueOffset)); 1757 __ ld(result, FieldMemOperand(object, JSDate::kValueOffset));
1766 } else { 1758 } else {
1767 if (index->value() < JSDate::kFirstUncachedField) { 1759 if (index->value() < JSDate::kFirstUncachedField) {
1768 ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 1760 ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
1769 __ li(scratch, Operand(stamp)); 1761 __ li(scratch, Operand(stamp));
1770 __ ld(scratch, MemOperand(scratch)); 1762 __ ld(scratch, MemOperand(scratch));
1771 __ ld(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset)); 1763 __ ld(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset));
1772 __ Branch(&runtime, ne, scratch, Operand(scratch0())); 1764 __ Branch(&runtime, ne, scratch, Operand(scratch0()));
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1887 overflow); // Reg at also used as scratch. 1879 overflow); // Reg at also used as scratch.
1888 } else { 1880 } else {
1889 DCHECK(right->IsRegister()); 1881 DCHECK(right->IsRegister());
1890 // Due to overflow check macros not supporting constant operands, 1882 // Due to overflow check macros not supporting constant operands,
1891 // handling the IsConstantOperand case was moved to prev if clause. 1883 // handling the IsConstantOperand case was moved to prev if clause.
1892 __ AdduAndCheckForOverflow(ToRegister(result), 1884 __ AdduAndCheckForOverflow(ToRegister(result),
1893 ToRegister(left), 1885 ToRegister(left),
1894 ToRegister(right), 1886 ToRegister(right),
1895 overflow); // Reg at also used as scratch. 1887 overflow); // Reg at also used as scratch.
1896 } 1888 }
1897 DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg)); 1889 DeoptimizeIf(lt, instr, overflow, Operand(zero_reg));
1898 // if not smi, it must int32. 1890 // if not smi, it must int32.
1899 if (!instr->hydrogen()->representation().IsSmi()) { 1891 if (!instr->hydrogen()->representation().IsSmi()) {
1900 DeoptimizeIf(gt, instr->environment(), 1892 DeoptimizeIf(gt, instr, ToRegister(result), Operand(kMaxInt));
1901 ToRegister(result), Operand(kMaxInt)); 1893 DeoptimizeIf(lt, instr, ToRegister(result), Operand(kMinInt));
1902 DeoptimizeIf(lt, instr->environment(),
1903 ToRegister(result), Operand(kMinInt));
1904 } 1894 }
1905 } 1895 }
1906 } 1896 }
1907 1897
1908 1898
1909 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1899 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1910 LOperand* left = instr->left(); 1900 LOperand* left = instr->left();
1911 LOperand* right = instr->right(); 1901 LOperand* right = instr->right();
1912 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1902 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1913 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; 1903 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
2155 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); 2145 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2156 } 2146 }
2157 2147
2158 if (expected.Contains(ToBooleanStub::SMI)) { 2148 if (expected.Contains(ToBooleanStub::SMI)) {
2159 // Smis: 0 -> false, all other -> true. 2149 // Smis: 0 -> false, all other -> true.
2160 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg)); 2150 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg));
2161 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); 2151 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2162 } else if (expected.NeedsMap()) { 2152 } else if (expected.NeedsMap()) {
2163 // If we need a map later and have a Smi -> deopt. 2153 // If we need a map later and have a Smi -> deopt.
2164 __ SmiTst(reg, at); 2154 __ SmiTst(reg, at);
2165 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 2155 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
2166 } 2156 }
2167 2157
2168 const Register map = scratch0(); 2158 const Register map = scratch0();
2169 if (expected.NeedsMap()) { 2159 if (expected.NeedsMap()) {
2170 __ ld(map, FieldMemOperand(reg, HeapObject::kMapOffset)); 2160 __ ld(map, FieldMemOperand(reg, HeapObject::kMapOffset));
2171 if (expected.CanBeUndetectable()) { 2161 if (expected.CanBeUndetectable()) {
2172 // Undetectable -> false. 2162 // Undetectable -> false.
2173 __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset)); 2163 __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
2174 __ And(at, at, Operand(1 << Map::kIsUndetectable)); 2164 __ And(at, at, Operand(1 << Map::kIsUndetectable));
2175 __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg)); 2165 __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2211 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), 2201 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2212 ne, dbl_scratch, kDoubleRegZero); 2202 ne, dbl_scratch, kDoubleRegZero);
2213 // Falls through if dbl_scratch == 0. 2203 // Falls through if dbl_scratch == 0.
2214 __ Branch(instr->FalseLabel(chunk_)); 2204 __ Branch(instr->FalseLabel(chunk_));
2215 __ bind(&not_heap_number); 2205 __ bind(&not_heap_number);
2216 } 2206 }
2217 2207
2218 if (!expected.IsGeneric()) { 2208 if (!expected.IsGeneric()) {
2219 // We've seen something for the first time -> deopt. 2209 // We've seen something for the first time -> deopt.
2220 // This can only happen if we are not generic already. 2210 // This can only happen if we are not generic already.
2221 DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg)); 2211 DeoptimizeIf(al, instr, zero_reg, Operand(zero_reg));
2222 } 2212 }
2223 } 2213 }
2224 } 2214 }
2225 } 2215 }
2226 2216
2227 2217
2228 void LCodeGen::EmitGoto(int block) { 2218 void LCodeGen::EmitGoto(int block) {
2229 if (!IsNextEmittedBlock(block)) { 2219 if (!IsNextEmittedBlock(block)) {
2230 __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block))); 2220 __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
2231 } 2221 }
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
2857 } 2847 }
2858 } 2848 }
2859 2849
2860 2850
2861 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 2851 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2862 Register result = ToRegister(instr->result()); 2852 Register result = ToRegister(instr->result());
2863 __ li(at, Operand(Handle<Object>(instr->hydrogen()->cell().handle()))); 2853 __ li(at, Operand(Handle<Object>(instr->hydrogen()->cell().handle())));
2864 __ ld(result, FieldMemOperand(at, Cell::kValueOffset)); 2854 __ ld(result, FieldMemOperand(at, Cell::kValueOffset));
2865 if (instr->hydrogen()->RequiresHoleCheck()) { 2855 if (instr->hydrogen()->RequiresHoleCheck()) {
2866 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2856 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2867 DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 2857 DeoptimizeIf(eq, instr, result, Operand(at));
2868 } 2858 }
2869 } 2859 }
2870 2860
2871 2861
2872 template <class T> 2862 template <class T>
2873 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { 2863 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
2874 DCHECK(FLAG_vector_ics); 2864 DCHECK(FLAG_vector_ics);
2875 Register vector = ToRegister(instr->temp_vector()); 2865 Register vector = ToRegister(instr->temp_vector());
2876 DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister())); 2866 DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister()));
2877 __ li(vector, instr->hydrogen()->feedback_vector()); 2867 __ li(vector, instr->hydrogen()->feedback_vector());
(...skipping 29 matching lines...) Expand all
2907 2897
2908 // If the cell we are storing to contains the hole it could have 2898 // If the cell we are storing to contains the hole it could have
2909 // been deleted from the property dictionary. In that case, we need 2899 // been deleted from the property dictionary. In that case, we need
2910 // to update the property details in the property dictionary to mark 2900 // to update the property details in the property dictionary to mark
2911 // it as no longer deleted. 2901 // it as no longer deleted.
2912 if (instr->hydrogen()->RequiresHoleCheck()) { 2902 if (instr->hydrogen()->RequiresHoleCheck()) {
2913 // We use a temp to check the payload. 2903 // We use a temp to check the payload.
2914 Register payload = ToRegister(instr->temp()); 2904 Register payload = ToRegister(instr->temp());
2915 __ ld(payload, FieldMemOperand(cell, Cell::kValueOffset)); 2905 __ ld(payload, FieldMemOperand(cell, Cell::kValueOffset));
2916 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2906 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2917 DeoptimizeIf(eq, instr->environment(), payload, Operand(at)); 2907 DeoptimizeIf(eq, instr, payload, Operand(at));
2918 } 2908 }
2919 2909
2920 // Store the value. 2910 // Store the value.
2921 __ sd(value, FieldMemOperand(cell, Cell::kValueOffset)); 2911 __ sd(value, FieldMemOperand(cell, Cell::kValueOffset));
2922 // Cells are always rescanned, so no write barrier here. 2912 // Cells are always rescanned, so no write barrier here.
2923 } 2913 }
2924 2914
2925 2915
2926 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 2916 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2927 Register context = ToRegister(instr->context()); 2917 Register context = ToRegister(instr->context());
2928 Register result = ToRegister(instr->result()); 2918 Register result = ToRegister(instr->result());
2929 2919
2930 __ ld(result, ContextOperand(context, instr->slot_index())); 2920 __ ld(result, ContextOperand(context, instr->slot_index()));
2931 if (instr->hydrogen()->RequiresHoleCheck()) { 2921 if (instr->hydrogen()->RequiresHoleCheck()) {
2932 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2922 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2933 2923
2934 if (instr->hydrogen()->DeoptimizesOnHole()) { 2924 if (instr->hydrogen()->DeoptimizesOnHole()) {
2935 DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 2925 DeoptimizeIf(eq, instr, result, Operand(at));
2936 } else { 2926 } else {
2937 Label is_not_hole; 2927 Label is_not_hole;
2938 __ Branch(&is_not_hole, ne, result, Operand(at)); 2928 __ Branch(&is_not_hole, ne, result, Operand(at));
2939 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); 2929 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
2940 __ bind(&is_not_hole); 2930 __ bind(&is_not_hole);
2941 } 2931 }
2942 } 2932 }
2943 } 2933 }
2944 2934
2945 2935
2946 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { 2936 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2947 Register context = ToRegister(instr->context()); 2937 Register context = ToRegister(instr->context());
2948 Register value = ToRegister(instr->value()); 2938 Register value = ToRegister(instr->value());
2949 Register scratch = scratch0(); 2939 Register scratch = scratch0();
2950 MemOperand target = ContextOperand(context, instr->slot_index()); 2940 MemOperand target = ContextOperand(context, instr->slot_index());
2951 2941
2952 Label skip_assignment; 2942 Label skip_assignment;
2953 2943
2954 if (instr->hydrogen()->RequiresHoleCheck()) { 2944 if (instr->hydrogen()->RequiresHoleCheck()) {
2955 __ ld(scratch, target); 2945 __ ld(scratch, target);
2956 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2946 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2957 2947
2958 if (instr->hydrogen()->DeoptimizesOnHole()) { 2948 if (instr->hydrogen()->DeoptimizesOnHole()) {
2959 DeoptimizeIf(eq, instr->environment(), scratch, Operand(at)); 2949 DeoptimizeIf(eq, instr, scratch, Operand(at));
2960 } else { 2950 } else {
2961 __ Branch(&skip_assignment, ne, scratch, Operand(at)); 2951 __ Branch(&skip_assignment, ne, scratch, Operand(at));
2962 } 2952 }
2963 } 2953 }
2964 2954
2965 __ sd(value, target); 2955 __ sd(value, target);
2966 if (instr->hydrogen()->NeedsWriteBarrier()) { 2956 if (instr->hydrogen()->NeedsWriteBarrier()) {
2967 SmiCheck check_needed = 2957 SmiCheck check_needed =
2968 instr->hydrogen()->value()->type().IsHeapObject() 2958 instr->hydrogen()->value()->type().IsHeapObject()
2969 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2959 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
3043 Register scratch = scratch0(); 3033 Register scratch = scratch0();
3044 Register function = ToRegister(instr->function()); 3034 Register function = ToRegister(instr->function());
3045 Register result = ToRegister(instr->result()); 3035 Register result = ToRegister(instr->result());
3046 3036
3047 // Get the prototype or initial map from the function. 3037 // Get the prototype or initial map from the function.
3048 __ ld(result, 3038 __ ld(result,
3049 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 3039 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
3050 3040
3051 // Check that the function has a prototype or an initial map. 3041 // Check that the function has a prototype or an initial map.
3052 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 3042 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
3053 DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 3043 DeoptimizeIf(eq, instr, result, Operand(at));
3054 3044
3055 // If the function does not have an initial map, we're done. 3045 // If the function does not have an initial map, we're done.
3056 Label done; 3046 Label done;
3057 __ GetObjectType(result, scratch, scratch); 3047 __ GetObjectType(result, scratch, scratch);
3058 __ Branch(&done, ne, scratch, Operand(MAP_TYPE)); 3048 __ Branch(&done, ne, scratch, Operand(MAP_TYPE));
3059 3049
3060 // Get the prototype from the initial map. 3050 // Get the prototype from the initial map.
3061 __ ld(result, FieldMemOperand(result, Map::kPrototypeOffset)); 3051 __ ld(result, FieldMemOperand(result, Map::kPrototypeOffset));
3062 3052
3063 // All done. 3053 // All done.
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 __ lhu(result, mem_operand); 3179 __ lhu(result, mem_operand);
3190 break; 3180 break;
3191 case EXTERNAL_INT32_ELEMENTS: 3181 case EXTERNAL_INT32_ELEMENTS:
3192 case INT32_ELEMENTS: 3182 case INT32_ELEMENTS:
3193 __ lw(result, mem_operand); 3183 __ lw(result, mem_operand);
3194 break; 3184 break;
3195 case EXTERNAL_UINT32_ELEMENTS: 3185 case EXTERNAL_UINT32_ELEMENTS:
3196 case UINT32_ELEMENTS: 3186 case UINT32_ELEMENTS:
3197 __ lw(result, mem_operand); 3187 __ lw(result, mem_operand);
3198 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 3188 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3199 DeoptimizeIf(Ugreater_equal, instr->environment(), 3189 DeoptimizeIf(Ugreater_equal, instr, result, Operand(0x80000000));
3200 result, Operand(0x80000000));
3201 } 3190 }
3202 break; 3191 break;
3203 case FLOAT32_ELEMENTS: 3192 case FLOAT32_ELEMENTS:
3204 case FLOAT64_ELEMENTS: 3193 case FLOAT64_ELEMENTS:
3205 case EXTERNAL_FLOAT32_ELEMENTS: 3194 case EXTERNAL_FLOAT32_ELEMENTS:
3206 case EXTERNAL_FLOAT64_ELEMENTS: 3195 case EXTERNAL_FLOAT64_ELEMENTS:
3207 case FAST_DOUBLE_ELEMENTS: 3196 case FAST_DOUBLE_ELEMENTS:
3208 case FAST_ELEMENTS: 3197 case FAST_ELEMENTS:
3209 case FAST_SMI_ELEMENTS: 3198 case FAST_SMI_ELEMENTS:
3210 case FAST_HOLEY_DOUBLE_ELEMENTS: 3199 case FAST_HOLEY_DOUBLE_ELEMENTS:
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3250 } else { 3239 } else {
3251 __ dsra(at, key, -shift_size); 3240 __ dsra(at, key, -shift_size);
3252 } 3241 }
3253 __ Daddu(scratch, scratch, at); 3242 __ Daddu(scratch, scratch, at);
3254 } 3243 }
3255 3244
3256 __ ldc1(result, MemOperand(scratch)); 3245 __ ldc1(result, MemOperand(scratch));
3257 3246
3258 if (instr->hydrogen()->RequiresHoleCheck()) { 3247 if (instr->hydrogen()->RequiresHoleCheck()) {
3259 __ lw(scratch, MemOperand(scratch, sizeof(kHoleNanLower32))); 3248 __ lw(scratch, MemOperand(scratch, sizeof(kHoleNanLower32)));
3260 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); 3249 DeoptimizeIf(eq, instr, scratch, Operand(kHoleNanUpper32));
3261 } 3250 }
3262 } 3251 }
3263 3252
3264 3253
3265 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3254 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3266 HLoadKeyed* hinstr = instr->hydrogen(); 3255 HLoadKeyed* hinstr = instr->hydrogen();
3267 Register elements = ToRegister(instr->elements()); 3256 Register elements = ToRegister(instr->elements());
3268 Register result = ToRegister(instr->result()); 3257 Register result = ToRegister(instr->result());
3269 Register scratch = scratch0(); 3258 Register scratch = scratch0();
3270 Register store_base = scratch; 3259 Register store_base = scratch;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3304 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); 3293 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
3305 offset += kPointerSize / 2; 3294 offset += kPointerSize / 2;
3306 } 3295 }
3307 3296
3308 __ Load(result, MemOperand(store_base, offset), representation); 3297 __ Load(result, MemOperand(store_base, offset), representation);
3309 3298
3310 // Check for the hole value. 3299 // Check for the hole value.
3311 if (hinstr->RequiresHoleCheck()) { 3300 if (hinstr->RequiresHoleCheck()) {
3312 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { 3301 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3313 __ SmiTst(result, scratch); 3302 __ SmiTst(result, scratch);
3314 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 3303 DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
3315 } else { 3304 } else {
3316 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 3305 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
3317 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); 3306 DeoptimizeIf(eq, instr, result, Operand(scratch));
3318 } 3307 }
3319 } 3308 }
3320 } 3309 }
3321 3310
3322 3311
3323 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { 3312 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3324 if (instr->is_typed_elements()) { 3313 if (instr->is_typed_elements()) {
3325 DoLoadKeyedExternalArray(instr); 3314 DoLoadKeyedExternalArray(instr);
3326 } else if (instr->hydrogen()->representation().IsDouble()) { 3315 } else if (instr->hydrogen()->representation().IsDouble()) {
3327 DoLoadKeyedFixedDoubleArray(instr); 3316 DoLoadKeyedFixedDoubleArray(instr);
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
3463 } 3452 }
3464 3453
3465 // Normal function. Replace undefined or null with global receiver. 3454 // Normal function. Replace undefined or null with global receiver.
3466 __ LoadRoot(scratch, Heap::kNullValueRootIndex); 3455 __ LoadRoot(scratch, Heap::kNullValueRootIndex);
3467 __ Branch(&global_object, eq, receiver, Operand(scratch)); 3456 __ Branch(&global_object, eq, receiver, Operand(scratch));
3468 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 3457 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
3469 __ Branch(&global_object, eq, receiver, Operand(scratch)); 3458 __ Branch(&global_object, eq, receiver, Operand(scratch));
3470 3459
3471 // Deoptimize if the receiver is not a JS object. 3460 // Deoptimize if the receiver is not a JS object.
3472 __ SmiTst(receiver, scratch); 3461 __ SmiTst(receiver, scratch);
3473 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); 3462 DeoptimizeIf(eq, instr, scratch, Operand(zero_reg));
3474 3463
3475 __ GetObjectType(receiver, scratch, scratch); 3464 __ GetObjectType(receiver, scratch, scratch);
3476 DeoptimizeIf(lt, instr->environment(), 3465 DeoptimizeIf(lt, instr, scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
3477 scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
3478 __ Branch(&result_in_receiver); 3466 __ Branch(&result_in_receiver);
3479 3467
3480 __ bind(&global_object); 3468 __ bind(&global_object);
3481 __ ld(result, FieldMemOperand(function, JSFunction::kContextOffset)); 3469 __ ld(result, FieldMemOperand(function, JSFunction::kContextOffset));
3482 __ ld(result, 3470 __ ld(result,
3483 ContextOperand(result, Context::GLOBAL_OBJECT_INDEX)); 3471 ContextOperand(result, Context::GLOBAL_OBJECT_INDEX));
3484 __ ld(result, 3472 __ ld(result,
3485 FieldMemOperand(result, GlobalObject::kGlobalProxyOffset)); 3473 FieldMemOperand(result, GlobalObject::kGlobalProxyOffset));
3486 3474
3487 if (result.is(receiver)) { 3475 if (result.is(receiver)) {
(...skipping 14 matching lines...) Expand all
3502 Register length = ToRegister(instr->length()); 3490 Register length = ToRegister(instr->length());
3503 Register elements = ToRegister(instr->elements()); 3491 Register elements = ToRegister(instr->elements());
3504 Register scratch = scratch0(); 3492 Register scratch = scratch0();
3505 DCHECK(receiver.is(a0)); // Used for parameter count. 3493 DCHECK(receiver.is(a0)); // Used for parameter count.
3506 DCHECK(function.is(a1)); // Required by InvokeFunction. 3494 DCHECK(function.is(a1)); // Required by InvokeFunction.
3507 DCHECK(ToRegister(instr->result()).is(v0)); 3495 DCHECK(ToRegister(instr->result()).is(v0));
3508 3496
3509 // Copy the arguments to this function possibly from the 3497 // Copy the arguments to this function possibly from the
3510 // adaptor frame below it. 3498 // adaptor frame below it.
3511 const uint32_t kArgumentsLimit = 1 * KB; 3499 const uint32_t kArgumentsLimit = 1 * KB;
3512 DeoptimizeIf(hi, instr->environment(), length, Operand(kArgumentsLimit)); 3500 DeoptimizeIf(hi, instr, length, Operand(kArgumentsLimit));
3513 3501
3514 // Push the receiver and use the register to keep the original 3502 // Push the receiver and use the register to keep the original
3515 // number of arguments. 3503 // number of arguments.
3516 __ push(receiver); 3504 __ push(receiver);
3517 __ Move(receiver, length); 3505 __ Move(receiver, length);
3518 // The arguments are at a one pointer size offset from elements. 3506 // The arguments are at a one pointer size offset from elements.
3519 __ Daddu(elements, elements, Operand(1 * kPointerSize)); 3507 __ Daddu(elements, elements, Operand(1 * kPointerSize));
3520 3508
3521 // Loop through the arguments pushing them onto the execution 3509 // Loop through the arguments pushing them onto the execution
3522 // stack. 3510 // stack.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
3632 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3620 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3633 DCHECK(instr->context() != NULL); 3621 DCHECK(instr->context() != NULL);
3634 DCHECK(ToRegister(instr->context()).is(cp)); 3622 DCHECK(ToRegister(instr->context()).is(cp));
3635 Register input = ToRegister(instr->value()); 3623 Register input = ToRegister(instr->value());
3636 Register result = ToRegister(instr->result()); 3624 Register result = ToRegister(instr->result());
3637 Register scratch = scratch0(); 3625 Register scratch = scratch0();
3638 3626
3639 // Deoptimize if not a heap number. 3627 // Deoptimize if not a heap number.
3640 __ ld(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 3628 __ ld(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
3641 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 3629 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
3642 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); 3630 DeoptimizeIf(ne, instr, scratch, Operand(at));
3643 3631
3644 Label done; 3632 Label done;
3645 Register exponent = scratch0(); 3633 Register exponent = scratch0();
3646 scratch = no_reg; 3634 scratch = no_reg;
3647 __ lwu(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 3635 __ lwu(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
3648 // Check the sign of the argument. If the argument is positive, just 3636 // Check the sign of the argument. If the argument is positive, just
3649 // return it. 3637 // return it.
3650 __ Move(result, input); 3638 __ Move(result, input);
3651 __ And(at, exponent, Operand(HeapNumber::kSignMask)); 3639 __ And(at, exponent, Operand(HeapNumber::kSignMask));
3652 __ Branch(&done, eq, at, Operand(zero_reg)); 3640 __ Branch(&done, eq, at, Operand(zero_reg));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3699 3687
3700 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { 3688 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3701 Register input = ToRegister(instr->value()); 3689 Register input = ToRegister(instr->value());
3702 Register result = ToRegister(instr->result()); 3690 Register result = ToRegister(instr->result());
3703 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 3691 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
3704 Label done; 3692 Label done;
3705 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); 3693 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg));
3706 __ mov(result, input); 3694 __ mov(result, input);
3707 __ dsubu(result, zero_reg, input); 3695 __ dsubu(result, zero_reg, input);
3708 // Overflow if result is still negative, i.e. 0x80000000. 3696 // Overflow if result is still negative, i.e. 0x80000000.
3709 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); 3697 DeoptimizeIf(lt, instr, result, Operand(zero_reg));
3710 __ bind(&done); 3698 __ bind(&done);
3711 } 3699 }
3712 3700
3713 3701
3714 void LCodeGen::DoMathAbs(LMathAbs* instr) { 3702 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3715 // Class for deferred case. 3703 // Class for deferred case.
3716 class DeferredMathAbsTaggedHeapNumber FINAL : public LDeferredCode { 3704 class DeferredMathAbsTaggedHeapNumber FINAL : public LDeferredCode {
3717 public: 3705 public:
3718 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) 3706 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3719 : LDeferredCode(codegen), instr_(instr) { } 3707 : LDeferredCode(codegen), instr_(instr) { }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3753 Register except_flag = ToRegister(instr->temp()); 3741 Register except_flag = ToRegister(instr->temp());
3754 3742
3755 __ EmitFPUTruncate(kRoundToMinusInf, 3743 __ EmitFPUTruncate(kRoundToMinusInf,
3756 result, 3744 result,
3757 input, 3745 input,
3758 scratch1, 3746 scratch1,
3759 double_scratch0(), 3747 double_scratch0(),
3760 except_flag); 3748 except_flag);
3761 3749
3762 // Deopt if the operation did not succeed. 3750 // Deopt if the operation did not succeed.
3763 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 3751 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
3764 3752
3765 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3753 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3766 // Test for -0. 3754 // Test for -0.
3767 Label done; 3755 Label done;
3768 __ Branch(&done, ne, result, Operand(zero_reg)); 3756 __ Branch(&done, ne, result, Operand(zero_reg));
3769 __ mfhc1(scratch1, input); // Get exponent/sign bits. 3757 __ mfhc1(scratch1, input); // Get exponent/sign bits.
3770 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 3758 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
3771 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 3759 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
3772 __ bind(&done); 3760 __ bind(&done);
3773 } 3761 }
3774 } 3762 }
3775 3763
3776 3764
3777 void LCodeGen::DoMathRound(LMathRound* instr) { 3765 void LCodeGen::DoMathRound(LMathRound* instr) {
3778 DoubleRegister input = ToDoubleRegister(instr->value()); 3766 DoubleRegister input = ToDoubleRegister(instr->value());
3779 Register result = ToRegister(instr->result()); 3767 Register result = ToRegister(instr->result());
3780 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); 3768 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp());
3781 Register scratch = scratch0(); 3769 Register scratch = scratch0();
(...skipping 12 matching lines...) Expand all
3794 __ mov(result, zero_reg); 3782 __ mov(result, zero_reg);
3795 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3783 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3796 __ Branch(&check_sign_on_zero); 3784 __ Branch(&check_sign_on_zero);
3797 } else { 3785 } else {
3798 __ Branch(&done); 3786 __ Branch(&done);
3799 } 3787 }
3800 __ bind(&skip1); 3788 __ bind(&skip1);
3801 3789
3802 // The following conversion will not work with numbers 3790 // The following conversion will not work with numbers
3803 // outside of ]-2^32, 2^32[. 3791 // outside of ]-2^32, 2^32[.
3804 DeoptimizeIf(ge, instr->environment(), scratch, 3792 DeoptimizeIf(ge, instr, scratch, Operand(HeapNumber::kExponentBias + 32));
3805 Operand(HeapNumber::kExponentBias + 32));
3806 3793
3807 // Save the original sign for later comparison. 3794 // Save the original sign for later comparison.
3808 __ And(scratch, result, Operand(HeapNumber::kSignMask)); 3795 __ And(scratch, result, Operand(HeapNumber::kSignMask));
3809 3796
3810 __ Move(double_scratch0(), 0.5); 3797 __ Move(double_scratch0(), 0.5);
3811 __ add_d(double_scratch0(), input, double_scratch0()); 3798 __ add_d(double_scratch0(), input, double_scratch0());
3812 3799
3813 // Check sign of the result: if the sign changed, the input 3800 // Check sign of the result: if the sign changed, the input
3814 // value was in ]0.5, 0[ and the result should be -0. 3801 // value was in ]0.5, 0[ and the result should be -0.
3815 __ mfhc1(result, double_scratch0()); 3802 __ mfhc1(result, double_scratch0());
3816 // mfhc1 sign-extends, clear the upper bits. 3803 // mfhc1 sign-extends, clear the upper bits.
3817 __ dsll32(result, result, 0); 3804 __ dsll32(result, result, 0);
3818 __ dsrl32(result, result, 0); 3805 __ dsrl32(result, result, 0);
3819 __ Xor(result, result, Operand(scratch)); 3806 __ Xor(result, result, Operand(scratch));
3820 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3807 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3821 // ARM uses 'mi' here, which is 'lt' 3808 // ARM uses 'mi' here, which is 'lt'
3822 DeoptimizeIf(lt, instr->environment(), result, 3809 DeoptimizeIf(lt, instr, result, Operand(zero_reg));
3823 Operand(zero_reg));
3824 } else { 3810 } else {
3825 Label skip2; 3811 Label skip2;
3826 // ARM uses 'mi' here, which is 'lt' 3812 // ARM uses 'mi' here, which is 'lt'
3827 // Negating it results in 'ge' 3813 // Negating it results in 'ge'
3828 __ Branch(&skip2, ge, result, Operand(zero_reg)); 3814 __ Branch(&skip2, ge, result, Operand(zero_reg));
3829 __ mov(result, zero_reg); 3815 __ mov(result, zero_reg);
3830 __ Branch(&done); 3816 __ Branch(&done);
3831 __ bind(&skip2); 3817 __ bind(&skip2);
3832 } 3818 }
3833 3819
3834 Register except_flag = scratch; 3820 Register except_flag = scratch;
3835 __ EmitFPUTruncate(kRoundToMinusInf, 3821 __ EmitFPUTruncate(kRoundToMinusInf,
3836 result, 3822 result,
3837 double_scratch0(), 3823 double_scratch0(),
3838 at, 3824 at,
3839 double_scratch1, 3825 double_scratch1,
3840 except_flag); 3826 except_flag);
3841 3827
3842 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 3828 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
3843 3829
3844 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3830 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3845 // Test for -0. 3831 // Test for -0.
3846 __ Branch(&done, ne, result, Operand(zero_reg)); 3832 __ Branch(&done, ne, result, Operand(zero_reg));
3847 __ bind(&check_sign_on_zero); 3833 __ bind(&check_sign_on_zero);
3848 __ mfhc1(scratch, input); // Get exponent/sign bits. 3834 __ mfhc1(scratch, input); // Get exponent/sign bits.
3849 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); 3835 __ And(scratch, scratch, Operand(HeapNumber::kSignMask));
3850 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 3836 DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
3851 } 3837 }
3852 __ bind(&done); 3838 __ bind(&done);
3853 } 3839 }
3854 3840
3855 3841
3856 void LCodeGen::DoMathFround(LMathFround* instr) { 3842 void LCodeGen::DoMathFround(LMathFround* instr) {
3857 DoubleRegister input = ToDoubleRegister(instr->value()); 3843 DoubleRegister input = ToDoubleRegister(instr->value());
3858 DoubleRegister result = ToDoubleRegister(instr->result()); 3844 DoubleRegister result = ToDoubleRegister(instr->result());
3859 __ cvt_s_d(result, input); 3845 __ cvt_s_d(result, input);
3860 __ cvt_d_s(result, result); 3846 __ cvt_d_s(result, result);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3906 3892
3907 if (exponent_type.IsSmi()) { 3893 if (exponent_type.IsSmi()) {
3908 MathPowStub stub(isolate(), MathPowStub::TAGGED); 3894 MathPowStub stub(isolate(), MathPowStub::TAGGED);
3909 __ CallStub(&stub); 3895 __ CallStub(&stub);
3910 } else if (exponent_type.IsTagged()) { 3896 } else if (exponent_type.IsTagged()) {
3911 Label no_deopt; 3897 Label no_deopt;
3912 __ JumpIfSmi(tagged_exponent, &no_deopt); 3898 __ JumpIfSmi(tagged_exponent, &no_deopt);
3913 DCHECK(!a7.is(tagged_exponent)); 3899 DCHECK(!a7.is(tagged_exponent));
3914 __ lw(a7, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset)); 3900 __ lw(a7, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset));
3915 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 3901 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
3916 DeoptimizeIf(ne, instr->environment(), a7, Operand(at)); 3902 DeoptimizeIf(ne, instr, a7, Operand(at));
3917 __ bind(&no_deopt); 3903 __ bind(&no_deopt);
3918 MathPowStub stub(isolate(), MathPowStub::TAGGED); 3904 MathPowStub stub(isolate(), MathPowStub::TAGGED);
3919 __ CallStub(&stub); 3905 __ CallStub(&stub);
3920 } else if (exponent_type.IsInteger32()) { 3906 } else if (exponent_type.IsInteger32()) {
3921 MathPowStub stub(isolate(), MathPowStub::INTEGER); 3907 MathPowStub stub(isolate(), MathPowStub::INTEGER);
3922 __ CallStub(&stub); 3908 __ CallStub(&stub);
3923 } else { 3909 } else {
3924 DCHECK(exponent_type.IsDouble()); 3910 DCHECK(exponent_type.IsDouble());
3925 MathPowStub stub(isolate(), MathPowStub::DOUBLE); 3911 MathPowStub stub(isolate(), MathPowStub::DOUBLE);
3926 __ CallStub(&stub); 3912 __ CallStub(&stub);
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
4248 } else { 4234 } else {
4249 reg = ToRegister(instr->index()); 4235 reg = ToRegister(instr->index());
4250 operand = ToOperand(instr->length()); 4236 operand = ToOperand(instr->length());
4251 } 4237 }
4252 if (FLAG_debug_code && instr->hydrogen()->skip_check()) { 4238 if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
4253 Label done; 4239 Label done;
4254 __ Branch(&done, NegateCondition(cc), reg, operand); 4240 __ Branch(&done, NegateCondition(cc), reg, operand);
4255 __ stop("eliminated bounds check failed"); 4241 __ stop("eliminated bounds check failed");
4256 __ bind(&done); 4242 __ bind(&done);
4257 } else { 4243 } else {
4258 DeoptimizeIf(cc, instr->environment(), reg, operand); 4244 DeoptimizeIf(cc, instr, reg, operand);
4259 } 4245 }
4260 } 4246 }
4261 4247
4262 4248
4263 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4249 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4264 Register external_pointer = ToRegister(instr->elements()); 4250 Register external_pointer = ToRegister(instr->elements());
4265 Register key = no_reg; 4251 Register key = no_reg;
4266 ElementsKind elements_kind = instr->elements_kind(); 4252 ElementsKind elements_kind = instr->elements_kind();
4267 bool key_is_constant = instr->key()->IsConstantOperand(); 4253 bool key_is_constant = instr->key()->IsConstantOperand();
4268 int constant_key = 0; 4254 int constant_key = 0;
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
4539 __ bind(&not_applicable); 4525 __ bind(&not_applicable);
4540 } 4526 }
4541 4527
4542 4528
4543 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 4529 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4544 Register object = ToRegister(instr->object()); 4530 Register object = ToRegister(instr->object());
4545 Register temp = ToRegister(instr->temp()); 4531 Register temp = ToRegister(instr->temp());
4546 Label no_memento_found; 4532 Label no_memento_found;
4547 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found, 4533 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found,
4548 ne, &no_memento_found); 4534 ne, &no_memento_found);
4549 DeoptimizeIf(al, instr->environment()); 4535 DeoptimizeIf(al, instr);
4550 __ bind(&no_memento_found); 4536 __ bind(&no_memento_found);
4551 } 4537 }
4552 4538
4553 4539
4554 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4540 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4555 DCHECK(ToRegister(instr->context()).is(cp)); 4541 DCHECK(ToRegister(instr->context()).is(cp));
4556 DCHECK(ToRegister(instr->left()).is(a1)); 4542 DCHECK(ToRegister(instr->left()).is(a1));
4557 DCHECK(ToRegister(instr->right()).is(a0)); 4543 DCHECK(ToRegister(instr->right()).is(a0));
4558 StringAddStub stub(isolate(), 4544 StringAddStub stub(isolate(),
4559 instr->hydrogen()->flags(), 4545 instr->hydrogen()->flags(),
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
4842 } 4828 }
4843 4829
4844 4830
4845 void LCodeGen::DoSmiTag(LSmiTag* instr) { 4831 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4846 HChange* hchange = instr->hydrogen(); 4832 HChange* hchange = instr->hydrogen();
4847 Register input = ToRegister(instr->value()); 4833 Register input = ToRegister(instr->value());
4848 Register output = ToRegister(instr->result()); 4834 Register output = ToRegister(instr->result());
4849 if (hchange->CheckFlag(HValue::kCanOverflow) && 4835 if (hchange->CheckFlag(HValue::kCanOverflow) &&
4850 hchange->value()->CheckFlag(HValue::kUint32)) { 4836 hchange->value()->CheckFlag(HValue::kUint32)) {
4851 __ And(at, input, Operand(0x80000000)); 4837 __ And(at, input, Operand(0x80000000));
4852 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 4838 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
4853 } 4839 }
4854 if (hchange->CheckFlag(HValue::kCanOverflow) && 4840 if (hchange->CheckFlag(HValue::kCanOverflow) &&
4855 !hchange->value()->CheckFlag(HValue::kUint32)) { 4841 !hchange->value()->CheckFlag(HValue::kUint32)) {
4856 __ SmiTagCheckOverflow(output, input, at); 4842 __ SmiTagCheckOverflow(output, input, at);
4857 DeoptimizeIf(lt, instr->environment(), at, Operand(zero_reg)); 4843 DeoptimizeIf(lt, instr, at, Operand(zero_reg));
4858 } else { 4844 } else {
4859 __ SmiTag(output, input); 4845 __ SmiTag(output, input);
4860 } 4846 }
4861 } 4847 }
4862 4848
4863 4849
4864 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4850 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4865 Register scratch = scratch0(); 4851 Register scratch = scratch0();
4866 Register input = ToRegister(instr->value()); 4852 Register input = ToRegister(instr->value());
4867 Register result = ToRegister(instr->result()); 4853 Register result = ToRegister(instr->result());
4868 if (instr->needs_check()) { 4854 if (instr->needs_check()) {
4869 STATIC_ASSERT(kHeapObjectTag == 1); 4855 STATIC_ASSERT(kHeapObjectTag == 1);
4870 // If the input is a HeapObject, value of scratch won't be zero. 4856 // If the input is a HeapObject, value of scratch won't be zero.
4871 __ And(scratch, input, Operand(kHeapObjectTag)); 4857 __ And(scratch, input, Operand(kHeapObjectTag));
4872 __ SmiUntag(result, input); 4858 __ SmiUntag(result, input);
4873 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 4859 DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
4874 } else { 4860 } else {
4875 __ SmiUntag(result, input); 4861 __ SmiUntag(result, input);
4876 } 4862 }
4877 } 4863 }
4878 4864
4879 4865
4880 void LCodeGen::EmitNumberUntagD(Register input_reg, 4866 void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
4881 DoubleRegister result_reg, 4867 DoubleRegister result_reg,
4882 bool can_convert_undefined_to_nan,
4883 bool deoptimize_on_minus_zero,
4884 LEnvironment* env,
4885 NumberUntagDMode mode) { 4868 NumberUntagDMode mode) {
4869 bool can_convert_undefined_to_nan =
4870 instr->hydrogen()->can_convert_undefined_to_nan();
4871 bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
4872
4886 Register scratch = scratch0(); 4873 Register scratch = scratch0();
4887 Label convert, load_smi, done; 4874 Label convert, load_smi, done;
4888 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 4875 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4889 // Smi check. 4876 // Smi check.
4890 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); 4877 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
4891 // Heap number map check. 4878 // Heap number map check.
4892 __ ld(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4879 __ ld(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4893 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 4880 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
4894 if (can_convert_undefined_to_nan) { 4881 if (can_convert_undefined_to_nan) {
4895 __ Branch(&convert, ne, scratch, Operand(at)); 4882 __ Branch(&convert, ne, scratch, Operand(at));
4896 } else { 4883 } else {
4897 DeoptimizeIf(ne, env, scratch, Operand(at)); 4884 DeoptimizeIf(ne, instr, scratch, Operand(at));
4898 } 4885 }
4899 // Load heap number. 4886 // Load heap number.
4900 __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 4887 __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset));
4901 if (deoptimize_on_minus_zero) { 4888 if (deoptimize_on_minus_zero) {
4902 __ mfc1(at, result_reg); 4889 __ mfc1(at, result_reg);
4903 __ Branch(&done, ne, at, Operand(zero_reg)); 4890 __ Branch(&done, ne, at, Operand(zero_reg));
4904 __ mfhc1(scratch, result_reg); // Get exponent/sign bits. 4891 __ mfhc1(scratch, result_reg); // Get exponent/sign bits.
4905 DeoptimizeIf(eq, env, scratch, Operand(HeapNumber::kSignMask)); 4892 DeoptimizeIf(eq, instr, scratch, Operand(HeapNumber::kSignMask));
4906 } 4893 }
4907 __ Branch(&done); 4894 __ Branch(&done);
4908 if (can_convert_undefined_to_nan) { 4895 if (can_convert_undefined_to_nan) {
4909 __ bind(&convert); 4896 __ bind(&convert);
4910 // Convert undefined (and hole) to NaN. 4897 // Convert undefined (and hole) to NaN.
4911 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 4898 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
4912 DeoptimizeIf(ne, env, input_reg, Operand(at)); 4899 DeoptimizeIf(ne, instr, input_reg, Operand(at));
4913 __ LoadRoot(scratch, Heap::kNanValueRootIndex); 4900 __ LoadRoot(scratch, Heap::kNanValueRootIndex);
4914 __ ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset)); 4901 __ ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset));
4915 __ Branch(&done); 4902 __ Branch(&done);
4916 } 4903 }
4917 } else { 4904 } else {
4918 __ SmiUntag(scratch, input_reg); 4905 __ SmiUntag(scratch, input_reg);
4919 DCHECK(mode == NUMBER_CANDIDATE_IS_SMI); 4906 DCHECK(mode == NUMBER_CANDIDATE_IS_SMI);
4920 } 4907 }
4921 // Smi to double register conversion 4908 // Smi to double register conversion
4922 __ bind(&load_smi); 4909 __ bind(&load_smi);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4967 4954
4968 __ bind(&check_bools); 4955 __ bind(&check_bools);
4969 __ LoadRoot(at, Heap::kTrueValueRootIndex); 4956 __ LoadRoot(at, Heap::kTrueValueRootIndex);
4970 __ Branch(&check_false, ne, scratch2, Operand(at)); 4957 __ Branch(&check_false, ne, scratch2, Operand(at));
4971 __ Branch(USE_DELAY_SLOT, &done); 4958 __ Branch(USE_DELAY_SLOT, &done);
4972 __ li(input_reg, Operand(1)); // In delay slot. 4959 __ li(input_reg, Operand(1)); // In delay slot.
4973 4960
4974 __ bind(&check_false); 4961 __ bind(&check_false);
4975 __ LoadRoot(at, Heap::kFalseValueRootIndex); 4962 __ LoadRoot(at, Heap::kFalseValueRootIndex);
4976 __ RecordComment("Deferred TaggedToI: cannot truncate"); 4963 __ RecordComment("Deferred TaggedToI: cannot truncate");
4977 DeoptimizeIf(ne, instr->environment(), scratch2, Operand(at)); 4964 DeoptimizeIf(ne, instr, scratch2, Operand(at));
4978 __ Branch(USE_DELAY_SLOT, &done); 4965 __ Branch(USE_DELAY_SLOT, &done);
4979 __ mov(input_reg, zero_reg); // In delay slot. 4966 __ mov(input_reg, zero_reg); // In delay slot.
4980 } else { 4967 } else {
4981 __ RecordComment("Deferred TaggedToI: not a heap number"); 4968 __ RecordComment("Deferred TaggedToI: not a heap number");
4982 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(at)); 4969 DeoptimizeIf(ne, instr, scratch1, Operand(at));
4983 4970
4984 // Load the double value. 4971 // Load the double value.
4985 __ ldc1(double_scratch, 4972 __ ldc1(double_scratch,
4986 FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 4973 FieldMemOperand(input_reg, HeapNumber::kValueOffset));
4987 4974
4988 Register except_flag = scratch2; 4975 Register except_flag = scratch2;
4989 __ EmitFPUTruncate(kRoundToZero, 4976 __ EmitFPUTruncate(kRoundToZero,
4990 input_reg, 4977 input_reg,
4991 double_scratch, 4978 double_scratch,
4992 scratch1, 4979 scratch1,
4993 double_scratch2, 4980 double_scratch2,
4994 except_flag, 4981 except_flag,
4995 kCheckForInexactConversion); 4982 kCheckForInexactConversion);
4996 4983
4997 __ RecordComment("Deferred TaggedToI: lost precision or NaN"); 4984 __ RecordComment("Deferred TaggedToI: lost precision or NaN");
4998 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 4985 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
4999 4986
5000 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4987 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5001 __ Branch(&done, ne, input_reg, Operand(zero_reg)); 4988 __ Branch(&done, ne, input_reg, Operand(zero_reg));
5002 4989
5003 __ mfhc1(scratch1, double_scratch); // Get exponent/sign bits. 4990 __ mfhc1(scratch1, double_scratch); // Get exponent/sign bits.
5004 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 4991 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
5005 __ RecordComment("Deferred TaggedToI: minus zero"); 4992 __ RecordComment("Deferred TaggedToI: minus zero");
5006 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 4993 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
5007 } 4994 }
5008 } 4995 }
5009 __ bind(&done); 4996 __ bind(&done);
5010 } 4997 }
5011 4998
5012 4999
5013 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 5000 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
5014 class DeferredTaggedToI FINAL : public LDeferredCode { 5001 class DeferredTaggedToI FINAL : public LDeferredCode {
5015 public: 5002 public:
5016 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 5003 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
5050 LOperand* result = instr->result(); 5037 LOperand* result = instr->result();
5051 DCHECK(result->IsDoubleRegister()); 5038 DCHECK(result->IsDoubleRegister());
5052 5039
5053 Register input_reg = ToRegister(input); 5040 Register input_reg = ToRegister(input);
5054 DoubleRegister result_reg = ToDoubleRegister(result); 5041 DoubleRegister result_reg = ToDoubleRegister(result);
5055 5042
5056 HValue* value = instr->hydrogen()->value(); 5043 HValue* value = instr->hydrogen()->value();
5057 NumberUntagDMode mode = value->representation().IsSmi() 5044 NumberUntagDMode mode = value->representation().IsSmi()
5058 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED; 5045 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED;
5059 5046
5060 EmitNumberUntagD(input_reg, result_reg, 5047 EmitNumberUntagD(instr, input_reg, result_reg, mode);
5061 instr->hydrogen()->can_convert_undefined_to_nan(),
5062 instr->hydrogen()->deoptimize_on_minus_zero(),
5063 instr->environment(),
5064 mode);
5065 } 5048 }
5066 5049
5067 5050
5068 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 5051 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5069 Register result_reg = ToRegister(instr->result()); 5052 Register result_reg = ToRegister(instr->result());
5070 Register scratch1 = scratch0(); 5053 Register scratch1 = scratch0();
5071 DoubleRegister double_input = ToDoubleRegister(instr->value()); 5054 DoubleRegister double_input = ToDoubleRegister(instr->value());
5072 5055
5073 if (instr->truncating()) { 5056 if (instr->truncating()) {
5074 __ TruncateDoubleToI(result_reg, double_input); 5057 __ TruncateDoubleToI(result_reg, double_input);
5075 } else { 5058 } else {
5076 Register except_flag = LCodeGen::scratch1(); 5059 Register except_flag = LCodeGen::scratch1();
5077 5060
5078 __ EmitFPUTruncate(kRoundToMinusInf, 5061 __ EmitFPUTruncate(kRoundToMinusInf,
5079 result_reg, 5062 result_reg,
5080 double_input, 5063 double_input,
5081 scratch1, 5064 scratch1,
5082 double_scratch0(), 5065 double_scratch0(),
5083 except_flag, 5066 except_flag,
5084 kCheckForInexactConversion); 5067 kCheckForInexactConversion);
5085 5068
5086 // Deopt if the operation did not succeed (except_flag != 0). 5069 // Deopt if the operation did not succeed (except_flag != 0).
5087 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 5070 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
5088 5071
5089 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5072 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5090 Label done; 5073 Label done;
5091 __ Branch(&done, ne, result_reg, Operand(zero_reg)); 5074 __ Branch(&done, ne, result_reg, Operand(zero_reg));
5092 __ mfhc1(scratch1, double_input); // Get exponent/sign bits. 5075 __ mfhc1(scratch1, double_input); // Get exponent/sign bits.
5093 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 5076 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
5094 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 5077 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
5095 __ bind(&done); 5078 __ bind(&done);
5096 } 5079 }
5097 } 5080 }
5098 } 5081 }
5099 5082
5100 5083
5101 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5084 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5102 Register result_reg = ToRegister(instr->result()); 5085 Register result_reg = ToRegister(instr->result());
5103 Register scratch1 = LCodeGen::scratch0(); 5086 Register scratch1 = LCodeGen::scratch0();
5104 DoubleRegister double_input = ToDoubleRegister(instr->value()); 5087 DoubleRegister double_input = ToDoubleRegister(instr->value());
5105 5088
5106 if (instr->truncating()) { 5089 if (instr->truncating()) {
5107 __ TruncateDoubleToI(result_reg, double_input); 5090 __ TruncateDoubleToI(result_reg, double_input);
5108 } else { 5091 } else {
5109 Register except_flag = LCodeGen::scratch1(); 5092 Register except_flag = LCodeGen::scratch1();
5110 5093
5111 __ EmitFPUTruncate(kRoundToMinusInf, 5094 __ EmitFPUTruncate(kRoundToMinusInf,
5112 result_reg, 5095 result_reg,
5113 double_input, 5096 double_input,
5114 scratch1, 5097 scratch1,
5115 double_scratch0(), 5098 double_scratch0(),
5116 except_flag, 5099 except_flag,
5117 kCheckForInexactConversion); 5100 kCheckForInexactConversion);
5118 5101
5119 // Deopt if the operation did not succeed (except_flag != 0). 5102 // Deopt if the operation did not succeed (except_flag != 0).
5120 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 5103 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
5121 5104
5122 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5105 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5123 Label done; 5106 Label done;
5124 __ Branch(&done, ne, result_reg, Operand(zero_reg)); 5107 __ Branch(&done, ne, result_reg, Operand(zero_reg));
5125 __ mfhc1(scratch1, double_input); // Get exponent/sign bits. 5108 __ mfhc1(scratch1, double_input); // Get exponent/sign bits.
5126 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 5109 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
5127 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 5110 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
5128 __ bind(&done); 5111 __ bind(&done);
5129 } 5112 }
5130 } 5113 }
5131 __ SmiTag(result_reg, result_reg); 5114 __ SmiTag(result_reg, result_reg);
5132 } 5115 }
5133 5116
5134 5117
5135 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 5118 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5136 LOperand* input = instr->value(); 5119 LOperand* input = instr->value();
5137 __ SmiTst(ToRegister(input), at); 5120 __ SmiTst(ToRegister(input), at);
5138 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 5121 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
5139 } 5122 }
5140 5123
5141 5124
5142 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 5125 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
5143 if (!instr->hydrogen()->value()->type().IsHeapObject()) { 5126 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
5144 LOperand* input = instr->value(); 5127 LOperand* input = instr->value();
5145 __ SmiTst(ToRegister(input), at); 5128 __ SmiTst(ToRegister(input), at);
5146 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 5129 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
5147 } 5130 }
5148 } 5131 }
5149 5132
5150 5133
5151 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 5134 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5152 Register input = ToRegister(instr->value()); 5135 Register input = ToRegister(instr->value());
5153 Register scratch = scratch0(); 5136 Register scratch = scratch0();
5154 5137
5155 __ GetObjectType(input, scratch, scratch); 5138 __ GetObjectType(input, scratch, scratch);
5156 5139
5157 if (instr->hydrogen()->is_interval_check()) { 5140 if (instr->hydrogen()->is_interval_check()) {
5158 InstanceType first; 5141 InstanceType first;
5159 InstanceType last; 5142 InstanceType last;
5160 instr->hydrogen()->GetCheckInterval(&first, &last); 5143 instr->hydrogen()->GetCheckInterval(&first, &last);
5161 5144
5162 // If there is only one type in the interval check for equality. 5145 // If there is only one type in the interval check for equality.
5163 if (first == last) { 5146 if (first == last) {
5164 DeoptimizeIf(ne, instr->environment(), scratch, Operand(first)); 5147 DeoptimizeIf(ne, instr, scratch, Operand(first));
5165 } else { 5148 } else {
5166 DeoptimizeIf(lo, instr->environment(), scratch, Operand(first)); 5149 DeoptimizeIf(lo, instr, scratch, Operand(first));
5167 // Omit check for the last type. 5150 // Omit check for the last type.
5168 if (last != LAST_TYPE) { 5151 if (last != LAST_TYPE) {
5169 DeoptimizeIf(hi, instr->environment(), scratch, Operand(last)); 5152 DeoptimizeIf(hi, instr, scratch, Operand(last));
5170 } 5153 }
5171 } 5154 }
5172 } else { 5155 } else {
5173 uint8_t mask; 5156 uint8_t mask;
5174 uint8_t tag; 5157 uint8_t tag;
5175 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); 5158 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
5176 5159
5177 if (base::bits::IsPowerOfTwo32(mask)) { 5160 if (base::bits::IsPowerOfTwo32(mask)) {
5178 DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); 5161 DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
5179 __ And(at, scratch, mask); 5162 __ And(at, scratch, mask);
5180 DeoptimizeIf(tag == 0 ? ne : eq, instr->environment(), 5163 DeoptimizeIf(tag == 0 ? ne : eq, instr, at, Operand(zero_reg));
5181 at, Operand(zero_reg));
5182 } else { 5164 } else {
5183 __ And(scratch, scratch, Operand(mask)); 5165 __ And(scratch, scratch, Operand(mask));
5184 DeoptimizeIf(ne, instr->environment(), scratch, Operand(tag)); 5166 DeoptimizeIf(ne, instr, scratch, Operand(tag));
5185 } 5167 }
5186 } 5168 }
5187 } 5169 }
5188 5170
5189 5171
5190 void LCodeGen::DoCheckValue(LCheckValue* instr) { 5172 void LCodeGen::DoCheckValue(LCheckValue* instr) {
5191 Register reg = ToRegister(instr->value()); 5173 Register reg = ToRegister(instr->value());
5192 Handle<HeapObject> object = instr->hydrogen()->object().handle(); 5174 Handle<HeapObject> object = instr->hydrogen()->object().handle();
5193 AllowDeferredHandleDereference smi_check; 5175 AllowDeferredHandleDereference smi_check;
5194 if (isolate()->heap()->InNewSpace(*object)) { 5176 if (isolate()->heap()->InNewSpace(*object)) {
5195 Register reg = ToRegister(instr->value()); 5177 Register reg = ToRegister(instr->value());
5196 Handle<Cell> cell = isolate()->factory()->NewCell(object); 5178 Handle<Cell> cell = isolate()->factory()->NewCell(object);
5197 __ li(at, Operand(Handle<Object>(cell))); 5179 __ li(at, Operand(Handle<Object>(cell)));
5198 __ ld(at, FieldMemOperand(at, Cell::kValueOffset)); 5180 __ ld(at, FieldMemOperand(at, Cell::kValueOffset));
5199 DeoptimizeIf(ne, instr->environment(), reg, 5181 DeoptimizeIf(ne, instr, reg, Operand(at));
5200 Operand(at));
5201 } else { 5182 } else {
5202 DeoptimizeIf(ne, instr->environment(), reg, 5183 DeoptimizeIf(ne, instr, reg, Operand(object));
5203 Operand(object));
5204 } 5184 }
5205 } 5185 }
5206 5186
5207 5187
5208 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5188 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5209 { 5189 {
5210 PushSafepointRegistersScope scope(this); 5190 PushSafepointRegistersScope scope(this);
5211 __ push(object); 5191 __ push(object);
5212 __ mov(cp, zero_reg); 5192 __ mov(cp, zero_reg);
5213 __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); 5193 __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance);
5214 RecordSafepointWithRegisters( 5194 RecordSafepointWithRegisters(
5215 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); 5195 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5216 __ StoreToSafepointRegisterSlot(v0, scratch0()); 5196 __ StoreToSafepointRegisterSlot(v0, scratch0());
5217 } 5197 }
5218 __ SmiTst(scratch0(), at); 5198 __ SmiTst(scratch0(), at);
5219 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 5199 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
5220 } 5200 }
5221 5201
5222 5202
5223 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 5203 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5224 class DeferredCheckMaps FINAL : public LDeferredCode { 5204 class DeferredCheckMaps FINAL : public LDeferredCode {
5225 public: 5205 public:
5226 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) 5206 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5227 : LDeferredCode(codegen), instr_(instr), object_(object) { 5207 : LDeferredCode(codegen), instr_(instr), object_(object) {
5228 SetExit(check_maps()); 5208 SetExit(check_maps());
5229 } 5209 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5262 Label success; 5242 Label success;
5263 for (int i = 0; i < maps->size() - 1; i++) { 5243 for (int i = 0; i < maps->size() - 1; i++) {
5264 Handle<Map> map = maps->at(i).handle(); 5244 Handle<Map> map = maps->at(i).handle();
5265 __ CompareMapAndBranch(map_reg, map, &success, eq, &success); 5245 __ CompareMapAndBranch(map_reg, map, &success, eq, &success);
5266 } 5246 }
5267 Handle<Map> map = maps->at(maps->size() - 1).handle(); 5247 Handle<Map> map = maps->at(maps->size() - 1).handle();
5268 // Do the CompareMap() directly within the Branch() and DeoptimizeIf(). 5248 // Do the CompareMap() directly within the Branch() and DeoptimizeIf().
5269 if (instr->hydrogen()->HasMigrationTarget()) { 5249 if (instr->hydrogen()->HasMigrationTarget()) {
5270 __ Branch(deferred->entry(), ne, map_reg, Operand(map)); 5250 __ Branch(deferred->entry(), ne, map_reg, Operand(map));
5271 } else { 5251 } else {
5272 DeoptimizeIf(ne, instr->environment(), map_reg, Operand(map)); 5252 DeoptimizeIf(ne, instr, map_reg, Operand(map));
5273 } 5253 }
5274 5254
5275 __ bind(&success); 5255 __ bind(&success);
5276 } 5256 }
5277 5257
5278 5258
5279 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5259 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5280 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); 5260 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
5281 Register result_reg = ToRegister(instr->result()); 5261 Register result_reg = ToRegister(instr->result());
5282 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); 5262 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
(...skipping 17 matching lines...) Expand all
5300 5280
5301 // Both smi and heap number cases are handled. 5281 // Both smi and heap number cases are handled.
5302 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); 5282 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi);
5303 5283
5304 // Check for heap number 5284 // Check for heap number
5305 __ ld(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 5285 __ ld(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
5306 __ Branch(&heap_number, eq, scratch, Operand(factory()->heap_number_map())); 5286 __ Branch(&heap_number, eq, scratch, Operand(factory()->heap_number_map()));
5307 5287
5308 // Check for undefined. Undefined is converted to zero for clamping 5288 // Check for undefined. Undefined is converted to zero for clamping
5309 // conversions. 5289 // conversions.
5310 DeoptimizeIf(ne, instr->environment(), input_reg, 5290 DeoptimizeIf(ne, instr, input_reg, Operand(factory()->undefined_value()));
5311 Operand(factory()->undefined_value()));
5312 __ mov(result_reg, zero_reg); 5291 __ mov(result_reg, zero_reg);
5313 __ jmp(&done); 5292 __ jmp(&done);
5314 5293
5315 // Heap number 5294 // Heap number
5316 __ bind(&heap_number); 5295 __ bind(&heap_number);
5317 __ ldc1(double_scratch0(), FieldMemOperand(input_reg, 5296 __ ldc1(double_scratch0(), FieldMemOperand(input_reg,
5318 HeapNumber::kValueOffset)); 5297 HeapNumber::kValueOffset));
5319 __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg); 5298 __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg);
5320 __ jmp(&done); 5299 __ jmp(&done);
5321 5300
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
5727 Deoptimizer::BailoutType type = instr->hydrogen()->type(); 5706 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5728 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 5707 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
5729 // needed return address), even though the implementation of LAZY and EAGER is 5708 // needed return address), even though the implementation of LAZY and EAGER is
5730 // now identical. When LAZY is eventually completely folded into EAGER, remove 5709 // now identical. When LAZY is eventually completely folded into EAGER, remove
5731 // the special case below. 5710 // the special case below.
5732 if (info()->IsStub() && type == Deoptimizer::EAGER) { 5711 if (info()->IsStub() && type == Deoptimizer::EAGER) {
5733 type = Deoptimizer::LAZY; 5712 type = Deoptimizer::LAZY;
5734 } 5713 }
5735 5714
5736 Comment(";;; deoptimize: %s", instr->hydrogen()->reason()); 5715 Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
5737 DeoptimizeIf(al, instr->environment(), type, zero_reg, Operand(zero_reg)); 5716 DeoptimizeIf(al, instr, type, zero_reg, Operand(zero_reg));
5738 } 5717 }
5739 5718
5740 5719
5741 void LCodeGen::DoDummy(LDummy* instr) { 5720 void LCodeGen::DoDummy(LDummy* instr) {
5742 // Nothing to see here, move on! 5721 // Nothing to see here, move on!
5743 } 5722 }
5744 5723
5745 5724
5746 void LCodeGen::DoDummyUse(LDummyUse* instr) { 5725 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5747 // Nothing to see here, move on! 5726 // Nothing to see here, move on!
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
5818 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 5797 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
5819 5798
5820 GenerateOsrPrologue(); 5799 GenerateOsrPrologue();
5821 } 5800 }
5822 5801
5823 5802
5824 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { 5803 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
5825 Register result = ToRegister(instr->result()); 5804 Register result = ToRegister(instr->result());
5826 Register object = ToRegister(instr->object()); 5805 Register object = ToRegister(instr->object());
5827 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 5806 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
5828 DeoptimizeIf(eq, instr->environment(), object, Operand(at)); 5807 DeoptimizeIf(eq, instr, object, Operand(at));
5829 5808
5830 Register null_value = a5; 5809 Register null_value = a5;
5831 __ LoadRoot(null_value, Heap::kNullValueRootIndex); 5810 __ LoadRoot(null_value, Heap::kNullValueRootIndex);
5832 DeoptimizeIf(eq, instr->environment(), object, Operand(null_value)); 5811 DeoptimizeIf(eq, instr, object, Operand(null_value));
5833 5812
5834 __ And(at, object, kSmiTagMask); 5813 __ And(at, object, kSmiTagMask);
5835 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 5814 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
5836 5815
5837 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 5816 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
5838 __ GetObjectType(object, a1, a1); 5817 __ GetObjectType(object, a1, a1);
5839 DeoptimizeIf(le, instr->environment(), a1, Operand(LAST_JS_PROXY_TYPE)); 5818 DeoptimizeIf(le, instr, a1, Operand(LAST_JS_PROXY_TYPE));
5840 5819
5841 Label use_cache, call_runtime; 5820 Label use_cache, call_runtime;
5842 DCHECK(object.is(a0)); 5821 DCHECK(object.is(a0));
5843 __ CheckEnumCache(null_value, &call_runtime); 5822 __ CheckEnumCache(null_value, &call_runtime);
5844 5823
5845 __ ld(result, FieldMemOperand(object, HeapObject::kMapOffset)); 5824 __ ld(result, FieldMemOperand(object, HeapObject::kMapOffset));
5846 __ Branch(&use_cache); 5825 __ Branch(&use_cache);
5847 5826
5848 // Get the set of properties to enumerate. 5827 // Get the set of properties to enumerate.
5849 __ bind(&call_runtime); 5828 __ bind(&call_runtime);
5850 __ push(object); 5829 __ push(object);
5851 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); 5830 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
5852 5831
5853 __ ld(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); 5832 __ ld(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
5854 DCHECK(result.is(v0)); 5833 DCHECK(result.is(v0));
5855 __ LoadRoot(at, Heap::kMetaMapRootIndex); 5834 __ LoadRoot(at, Heap::kMetaMapRootIndex);
5856 DeoptimizeIf(ne, instr->environment(), a1, Operand(at)); 5835 DeoptimizeIf(ne, instr, a1, Operand(at));
5857 __ bind(&use_cache); 5836 __ bind(&use_cache);
5858 } 5837 }
5859 5838
5860 5839
5861 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { 5840 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
5862 Register map = ToRegister(instr->map()); 5841 Register map = ToRegister(instr->map());
5863 Register result = ToRegister(instr->result()); 5842 Register result = ToRegister(instr->result());
5864 Label load_cache, done; 5843 Label load_cache, done;
5865 __ EnumLength(result, map); 5844 __ EnumLength(result, map);
5866 __ Branch(&load_cache, ne, result, Operand(Smi::FromInt(0))); 5845 __ Branch(&load_cache, ne, result, Operand(Smi::FromInt(0)));
5867 __ li(result, Operand(isolate()->factory()->empty_fixed_array())); 5846 __ li(result, Operand(isolate()->factory()->empty_fixed_array()));
5868 __ jmp(&done); 5847 __ jmp(&done);
5869 5848
5870 __ bind(&load_cache); 5849 __ bind(&load_cache);
5871 __ LoadInstanceDescriptors(map, result); 5850 __ LoadInstanceDescriptors(map, result);
5872 __ ld(result, 5851 __ ld(result,
5873 FieldMemOperand(result, DescriptorArray::kEnumCacheOffset)); 5852 FieldMemOperand(result, DescriptorArray::kEnumCacheOffset));
5874 __ ld(result, 5853 __ ld(result,
5875 FieldMemOperand(result, FixedArray::SizeFor(instr->idx()))); 5854 FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
5876 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 5855 DeoptimizeIf(eq, instr, result, Operand(zero_reg));
5877 5856
5878 __ bind(&done); 5857 __ bind(&done);
5879 } 5858 }
5880 5859
5881 5860
5882 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { 5861 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5883 Register object = ToRegister(instr->value()); 5862 Register object = ToRegister(instr->value());
5884 Register map = ToRegister(instr->map()); 5863 Register map = ToRegister(instr->map());
5885 __ ld(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset)); 5864 __ ld(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset));
5886 DeoptimizeIf(ne, instr->environment(), map, Operand(scratch0())); 5865 DeoptimizeIf(ne, instr, map, Operand(scratch0()));
5887 } 5866 }
5888 5867
5889 5868
5890 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 5869 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
5891 Register result, 5870 Register result,
5892 Register object, 5871 Register object,
5893 Register index) { 5872 Register index) {
5894 PushSafepointRegistersScope scope(this); 5873 PushSafepointRegistersScope scope(this);
5895 __ Push(object, index); 5874 __ Push(object, index);
5896 __ mov(cp, zero_reg); 5875 __ mov(cp, zero_reg);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
5970 __ li(at, scope_info); 5949 __ li(at, scope_info);
5971 __ Push(at, ToRegister(instr->function())); 5950 __ Push(at, ToRegister(instr->function()));
5972 CallRuntime(Runtime::kPushBlockContext, 2, instr); 5951 CallRuntime(Runtime::kPushBlockContext, 2, instr);
5973 RecordSafepoint(Safepoint::kNoLazyDeopt); 5952 RecordSafepoint(Safepoint::kNoLazyDeopt);
5974 } 5953 }
5975 5954
5976 5955
5977 #undef __ 5956 #undef __
5978 5957
5979 } } // namespace v8::internal 5958 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mips64/lithium-codegen-mips64.h ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698