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

Side by Side Diff: src/mips/lithium-codegen-mips.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/mips/lithium-codegen-mips.h ('k') | src/mips64/lithium-codegen-mips64.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.7 1 // Copyright 2012 the V8 project authors. All rights reserved.7
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 int deoptimization_index = deoptimizations_.length(); 812 int deoptimization_index = deoptimizations_.length();
813 int pc_offset = masm()->pc_offset(); 813 int pc_offset = masm()->pc_offset();
814 environment->Register(deoptimization_index, 814 environment->Register(deoptimization_index,
815 translation.index(), 815 translation.index(),
816 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 816 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
817 deoptimizations_.Add(environment, zone()); 817 deoptimizations_.Add(environment, zone());
818 } 818 }
819 } 819 }
820 820
821 821
822 void LCodeGen::DeoptimizeIf(Condition condition, 822 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
823 LEnvironment* environment,
824 Deoptimizer::BailoutType bailout_type, 823 Deoptimizer::BailoutType bailout_type,
825 Register src1, 824 Register src1, const Operand& src2) {
826 const Operand& src2) { 825 LEnvironment* environment = instr->environment();
827 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 826 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
828 DCHECK(environment->HasBeenRegistered()); 827 DCHECK(environment->HasBeenRegistered());
829 int id = environment->deoptimization_index(); 828 int id = environment->deoptimization_index();
830 DCHECK(info()->IsOptimizing() || info()->IsStub()); 829 DCHECK(info()->IsOptimizing() || info()->IsStub());
831 Address entry = 830 Address entry =
832 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); 831 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
833 if (entry == NULL) { 832 if (entry == NULL) {
834 Abort(kBailoutWasNotPrepared); 833 Abort(kBailoutWasNotPrepared);
835 return; 834 return;
836 } 835 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 Deoptimizer::JumpTableEntry table_entry(entry, 878 Deoptimizer::JumpTableEntry table_entry(entry,
880 bailout_type, 879 bailout_type,
881 !frame_is_built_); 880 !frame_is_built_);
882 deopt_jump_table_.Add(table_entry, zone()); 881 deopt_jump_table_.Add(table_entry, zone());
883 } 882 }
884 __ Branch(&deopt_jump_table_.last().label, condition, src1, src2); 883 __ Branch(&deopt_jump_table_.last().label, condition, src1, src2);
885 } 884 }
886 } 885 }
887 886
888 887
889 void LCodeGen::DeoptimizeIf(Condition condition, 888 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
890 LEnvironment* environment, 889 Register src1, const Operand& src2) {
891 Register src1,
892 const Operand& src2) {
893 Deoptimizer::BailoutType bailout_type = info()->IsStub() 890 Deoptimizer::BailoutType bailout_type = info()->IsStub()
894 ? Deoptimizer::LAZY 891 ? Deoptimizer::LAZY
895 : Deoptimizer::EAGER; 892 : Deoptimizer::EAGER;
896 DeoptimizeIf(condition, environment, bailout_type, src1, src2); 893 DeoptimizeIf(condition, instr, bailout_type, src1, src2);
897 } 894 }
898 895
899 896
900 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 897 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
901 int length = deoptimizations_.length(); 898 int length = deoptimizations_.length();
902 if (length == 0) return; 899 if (length == 0) return;
903 Handle<DeoptimizationInputData> data = 900 Handle<DeoptimizationInputData> data =
904 DeoptimizationInputData::New(isolate(), length, TENURED); 901 DeoptimizationInputData::New(isolate(), length, TENURED);
905 902
906 Handle<ByteArray> translations = 903 Handle<ByteArray> translations =
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 HMod* hmod = instr->hydrogen(); 1113 HMod* hmod = instr->hydrogen();
1117 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1114 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
1118 Label dividend_is_not_negative, done; 1115 Label dividend_is_not_negative, done;
1119 1116
1120 if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) { 1117 if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) {
1121 __ Branch(&dividend_is_not_negative, ge, dividend, Operand(zero_reg)); 1118 __ Branch(&dividend_is_not_negative, ge, dividend, Operand(zero_reg));
1122 // Note: The code below even works when right contains kMinInt. 1119 // Note: The code below even works when right contains kMinInt.
1123 __ subu(dividend, zero_reg, dividend); 1120 __ subu(dividend, zero_reg, dividend);
1124 __ And(dividend, dividend, Operand(mask)); 1121 __ And(dividend, dividend, Operand(mask));
1125 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1122 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1126 DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg)); 1123 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1127 } 1124 }
1128 __ Branch(USE_DELAY_SLOT, &done); 1125 __ Branch(USE_DELAY_SLOT, &done);
1129 __ subu(dividend, zero_reg, dividend); 1126 __ subu(dividend, zero_reg, dividend);
1130 } 1127 }
1131 1128
1132 __ bind(&dividend_is_not_negative); 1129 __ bind(&dividend_is_not_negative);
1133 __ And(dividend, dividend, Operand(mask)); 1130 __ And(dividend, dividend, Operand(mask));
1134 __ bind(&done); 1131 __ bind(&done);
1135 } 1132 }
1136 1133
1137 1134
1138 void LCodeGen::DoModByConstI(LModByConstI* instr) { 1135 void LCodeGen::DoModByConstI(LModByConstI* instr) {
1139 Register dividend = ToRegister(instr->dividend()); 1136 Register dividend = ToRegister(instr->dividend());
1140 int32_t divisor = instr->divisor(); 1137 int32_t divisor = instr->divisor();
1141 Register result = ToRegister(instr->result()); 1138 Register result = ToRegister(instr->result());
1142 DCHECK(!dividend.is(result)); 1139 DCHECK(!dividend.is(result));
1143 1140
1144 if (divisor == 0) { 1141 if (divisor == 0) {
1145 DeoptimizeIf(al, instr->environment()); 1142 DeoptimizeIf(al, instr);
1146 return; 1143 return;
1147 } 1144 }
1148 1145
1149 __ TruncatingDiv(result, dividend, Abs(divisor)); 1146 __ TruncatingDiv(result, dividend, Abs(divisor));
1150 __ Mul(result, result, Operand(Abs(divisor))); 1147 __ Mul(result, result, Operand(Abs(divisor)));
1151 __ Subu(result, dividend, Operand(result)); 1148 __ Subu(result, dividend, Operand(result));
1152 1149
1153 // Check for negative zero. 1150 // Check for negative zero.
1154 HMod* hmod = instr->hydrogen(); 1151 HMod* hmod = instr->hydrogen();
1155 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1152 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1156 Label remainder_not_zero; 1153 Label remainder_not_zero;
1157 __ Branch(&remainder_not_zero, ne, result, Operand(zero_reg)); 1154 __ Branch(&remainder_not_zero, ne, result, Operand(zero_reg));
1158 DeoptimizeIf(lt, instr->environment(), dividend, Operand(zero_reg)); 1155 DeoptimizeIf(lt, instr, dividend, Operand(zero_reg));
1159 __ bind(&remainder_not_zero); 1156 __ bind(&remainder_not_zero);
1160 } 1157 }
1161 } 1158 }
1162 1159
1163 1160
1164 void LCodeGen::DoModI(LModI* instr) { 1161 void LCodeGen::DoModI(LModI* instr) {
1165 HMod* hmod = instr->hydrogen(); 1162 HMod* hmod = instr->hydrogen();
1166 const Register left_reg = ToRegister(instr->left()); 1163 const Register left_reg = ToRegister(instr->left());
1167 const Register right_reg = ToRegister(instr->right()); 1164 const Register right_reg = ToRegister(instr->right());
1168 const Register result_reg = ToRegister(instr->result()); 1165 const Register result_reg = ToRegister(instr->result());
1169 1166
1170 // div runs in the background while we check for special cases. 1167 // div runs in the background while we check for special cases.
1171 __ Mod(result_reg, left_reg, right_reg); 1168 __ Mod(result_reg, left_reg, right_reg);
1172 1169
1173 Label done; 1170 Label done;
1174 // Check for x % 0, we have to deopt in this case because we can't return a 1171 // Check for x % 0, we have to deopt in this case because we can't return a
1175 // NaN. 1172 // NaN.
1176 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { 1173 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
1177 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(zero_reg)); 1174 DeoptimizeIf(eq, instr, right_reg, Operand(zero_reg));
1178 } 1175 }
1179 1176
1180 // Check for kMinInt % -1, div will return kMinInt, which is not what we 1177 // Check for kMinInt % -1, div will return kMinInt, which is not what we
1181 // want. We have to deopt if we care about -0, because we can't return that. 1178 // want. We have to deopt if we care about -0, because we can't return that.
1182 if (hmod->CheckFlag(HValue::kCanOverflow)) { 1179 if (hmod->CheckFlag(HValue::kCanOverflow)) {
1183 Label no_overflow_possible; 1180 Label no_overflow_possible;
1184 __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt)); 1181 __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt));
1185 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1182 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1186 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1)); 1183 DeoptimizeIf(eq, instr, right_reg, Operand(-1));
1187 } else { 1184 } else {
1188 __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1)); 1185 __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1));
1189 __ Branch(USE_DELAY_SLOT, &done); 1186 __ Branch(USE_DELAY_SLOT, &done);
1190 __ mov(result_reg, zero_reg); 1187 __ mov(result_reg, zero_reg);
1191 } 1188 }
1192 __ bind(&no_overflow_possible); 1189 __ bind(&no_overflow_possible);
1193 } 1190 }
1194 1191
1195 // If we care about -0, test if the dividend is <0 and the result is 0. 1192 // If we care about -0, test if the dividend is <0 and the result is 0.
1196 __ Branch(&done, ge, left_reg, Operand(zero_reg)); 1193 __ Branch(&done, ge, left_reg, Operand(zero_reg));
1197 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1194 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1198 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg)); 1195 DeoptimizeIf(eq, instr, result_reg, Operand(zero_reg));
1199 } 1196 }
1200 __ bind(&done); 1197 __ bind(&done);
1201 } 1198 }
1202 1199
1203 1200
1204 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { 1201 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1205 Register dividend = ToRegister(instr->dividend()); 1202 Register dividend = ToRegister(instr->dividend());
1206 int32_t divisor = instr->divisor(); 1203 int32_t divisor = instr->divisor();
1207 Register result = ToRegister(instr->result()); 1204 Register result = ToRegister(instr->result());
1208 DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor))); 1205 DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor)));
1209 DCHECK(!result.is(dividend)); 1206 DCHECK(!result.is(dividend));
1210 1207
1211 // Check for (0 / -x) that will produce negative zero. 1208 // Check for (0 / -x) that will produce negative zero.
1212 HDiv* hdiv = instr->hydrogen(); 1209 HDiv* hdiv = instr->hydrogen();
1213 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1210 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1214 DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg)); 1211 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1215 } 1212 }
1216 // Check for (kMinInt / -1). 1213 // Check for (kMinInt / -1).
1217 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { 1214 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
1218 DeoptimizeIf(eq, instr->environment(), dividend, Operand(kMinInt)); 1215 DeoptimizeIf(eq, instr, dividend, Operand(kMinInt));
1219 } 1216 }
1220 // Deoptimize if remainder will not be 0. 1217 // Deoptimize if remainder will not be 0.
1221 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && 1218 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1222 divisor != 1 && divisor != -1) { 1219 divisor != 1 && divisor != -1) {
1223 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1220 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
1224 __ And(at, dividend, Operand(mask)); 1221 __ And(at, dividend, Operand(mask));
1225 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 1222 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
1226 } 1223 }
1227 1224
1228 if (divisor == -1) { // Nice shortcut, not needed for correctness. 1225 if (divisor == -1) { // Nice shortcut, not needed for correctness.
1229 __ Subu(result, zero_reg, dividend); 1226 __ Subu(result, zero_reg, dividend);
1230 return; 1227 return;
1231 } 1228 }
1232 uint16_t shift = WhichPowerOf2Abs(divisor); 1229 uint16_t shift = WhichPowerOf2Abs(divisor);
1233 if (shift == 0) { 1230 if (shift == 0) {
1234 __ Move(result, dividend); 1231 __ Move(result, dividend);
1235 } else if (shift == 1) { 1232 } else if (shift == 1) {
1236 __ srl(result, dividend, 31); 1233 __ srl(result, dividend, 31);
1237 __ Addu(result, dividend, Operand(result)); 1234 __ Addu(result, dividend, Operand(result));
1238 } else { 1235 } else {
1239 __ sra(result, dividend, 31); 1236 __ sra(result, dividend, 31);
1240 __ srl(result, result, 32 - shift); 1237 __ srl(result, result, 32 - shift);
1241 __ Addu(result, dividend, Operand(result)); 1238 __ Addu(result, dividend, Operand(result));
1242 } 1239 }
1243 if (shift > 0) __ sra(result, result, shift); 1240 if (shift > 0) __ sra(result, result, shift);
1244 if (divisor < 0) __ Subu(result, zero_reg, result); 1241 if (divisor < 0) __ Subu(result, zero_reg, result);
1245 } 1242 }
1246 1243
1247 1244
1248 void LCodeGen::DoDivByConstI(LDivByConstI* instr) { 1245 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
1249 Register dividend = ToRegister(instr->dividend()); 1246 Register dividend = ToRegister(instr->dividend());
1250 int32_t divisor = instr->divisor(); 1247 int32_t divisor = instr->divisor();
1251 Register result = ToRegister(instr->result()); 1248 Register result = ToRegister(instr->result());
1252 DCHECK(!dividend.is(result)); 1249 DCHECK(!dividend.is(result));
1253 1250
1254 if (divisor == 0) { 1251 if (divisor == 0) {
1255 DeoptimizeIf(al, instr->environment()); 1252 DeoptimizeIf(al, instr);
1256 return; 1253 return;
1257 } 1254 }
1258 1255
1259 // Check for (0 / -x) that will produce negative zero. 1256 // Check for (0 / -x) that will produce negative zero.
1260 HDiv* hdiv = instr->hydrogen(); 1257 HDiv* hdiv = instr->hydrogen();
1261 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1258 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1262 DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg)); 1259 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1263 } 1260 }
1264 1261
1265 __ TruncatingDiv(result, dividend, Abs(divisor)); 1262 __ TruncatingDiv(result, dividend, Abs(divisor));
1266 if (divisor < 0) __ Subu(result, zero_reg, result); 1263 if (divisor < 0) __ Subu(result, zero_reg, result);
1267 1264
1268 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { 1265 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1269 __ Mul(scratch0(), result, Operand(divisor)); 1266 __ Mul(scratch0(), result, Operand(divisor));
1270 __ Subu(scratch0(), scratch0(), dividend); 1267 __ Subu(scratch0(), scratch0(), dividend);
1271 DeoptimizeIf(ne, instr->environment(), scratch0(), Operand(zero_reg)); 1268 DeoptimizeIf(ne, instr, scratch0(), Operand(zero_reg));
1272 } 1269 }
1273 } 1270 }
1274 1271
1275 1272
1276 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. 1273 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
1277 void LCodeGen::DoDivI(LDivI* instr) { 1274 void LCodeGen::DoDivI(LDivI* instr) {
1278 HBinaryOperation* hdiv = instr->hydrogen(); 1275 HBinaryOperation* hdiv = instr->hydrogen();
1279 Register dividend = ToRegister(instr->dividend()); 1276 Register dividend = ToRegister(instr->dividend());
1280 Register divisor = ToRegister(instr->divisor()); 1277 Register divisor = ToRegister(instr->divisor());
1281 const Register result = ToRegister(instr->result()); 1278 const Register result = ToRegister(instr->result());
1282 Register remainder = ToRegister(instr->temp()); 1279 Register remainder = ToRegister(instr->temp());
1283 1280
1284 // On MIPS div is asynchronous - it will run in the background while we 1281 // On MIPS div is asynchronous - it will run in the background while we
1285 // check for special cases. 1282 // check for special cases.
1286 __ Div(remainder, result, dividend, divisor); 1283 __ Div(remainder, result, dividend, divisor);
1287 1284
1288 // Check for x / 0. 1285 // Check for x / 0.
1289 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1286 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
1290 DeoptimizeIf(eq, instr->environment(), divisor, Operand(zero_reg)); 1287 DeoptimizeIf(eq, instr, divisor, Operand(zero_reg));
1291 } 1288 }
1292 1289
1293 // Check for (0 / -x) that will produce negative zero. 1290 // Check for (0 / -x) that will produce negative zero.
1294 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1291 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1295 Label left_not_zero; 1292 Label left_not_zero;
1296 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg)); 1293 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
1297 DeoptimizeIf(lt, instr->environment(), divisor, Operand(zero_reg)); 1294 DeoptimizeIf(lt, instr, divisor, Operand(zero_reg));
1298 __ bind(&left_not_zero); 1295 __ bind(&left_not_zero);
1299 } 1296 }
1300 1297
1301 // Check for (kMinInt / -1). 1298 // Check for (kMinInt / -1).
1302 if (hdiv->CheckFlag(HValue::kCanOverflow) && 1299 if (hdiv->CheckFlag(HValue::kCanOverflow) &&
1303 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1300 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1304 Label left_not_min_int; 1301 Label left_not_min_int;
1305 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt)); 1302 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
1306 DeoptimizeIf(eq, instr->environment(), divisor, Operand(-1)); 1303 DeoptimizeIf(eq, instr, divisor, Operand(-1));
1307 __ bind(&left_not_min_int); 1304 __ bind(&left_not_min_int);
1308 } 1305 }
1309 1306
1310 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1307 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1311 DeoptimizeIf(ne, instr->environment(), remainder, Operand(zero_reg)); 1308 DeoptimizeIf(ne, instr, remainder, Operand(zero_reg));
1312 } 1309 }
1313 } 1310 }
1314 1311
1315 1312
1316 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { 1313 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
1317 DoubleRegister addend = ToDoubleRegister(instr->addend()); 1314 DoubleRegister addend = ToDoubleRegister(instr->addend());
1318 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); 1315 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier());
1319 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand()); 1316 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
1320 1317
1321 // This is computed in-place. 1318 // This is computed in-place.
(...skipping 25 matching lines...) Expand all
1347 } 1344 }
1348 1345
1349 // If the divisor is negative, we have to negate and handle edge cases. 1346 // If the divisor is negative, we have to negate and handle edge cases.
1350 1347
1351 // dividend can be the same register as result so save the value of it 1348 // dividend can be the same register as result so save the value of it
1352 // for checking overflow. 1349 // for checking overflow.
1353 __ Move(scratch, dividend); 1350 __ Move(scratch, dividend);
1354 1351
1355 __ Subu(result, zero_reg, dividend); 1352 __ Subu(result, zero_reg, dividend);
1356 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1353 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1357 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 1354 DeoptimizeIf(eq, instr, result, Operand(zero_reg));
1358 } 1355 }
1359 1356
1360 // Dividing by -1 is basically negation, unless we overflow. 1357 // Dividing by -1 is basically negation, unless we overflow.
1361 __ Xor(scratch, scratch, result); 1358 __ Xor(scratch, scratch, result);
1362 if (divisor == -1) { 1359 if (divisor == -1) {
1363 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 1360 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1364 DeoptimizeIf(ge, instr->environment(), scratch, Operand(zero_reg)); 1361 DeoptimizeIf(ge, instr, scratch, Operand(zero_reg));
1365 } 1362 }
1366 return; 1363 return;
1367 } 1364 }
1368 1365
1369 // If the negation could not overflow, simply shifting is OK. 1366 // If the negation could not overflow, simply shifting is OK.
1370 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 1367 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1371 __ sra(result, result, shift); 1368 __ sra(result, result, shift);
1372 return; 1369 return;
1373 } 1370 }
1374 1371
1375 Label no_overflow, done; 1372 Label no_overflow, done;
1376 __ Branch(&no_overflow, lt, scratch, Operand(zero_reg)); 1373 __ Branch(&no_overflow, lt, scratch, Operand(zero_reg));
1377 __ li(result, Operand(kMinInt / divisor)); 1374 __ li(result, Operand(kMinInt / divisor));
1378 __ Branch(&done); 1375 __ Branch(&done);
1379 __ bind(&no_overflow); 1376 __ bind(&no_overflow);
1380 __ sra(result, result, shift); 1377 __ sra(result, result, shift);
1381 __ bind(&done); 1378 __ bind(&done);
1382 } 1379 }
1383 1380
1384 1381
1385 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { 1382 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
1386 Register dividend = ToRegister(instr->dividend()); 1383 Register dividend = ToRegister(instr->dividend());
1387 int32_t divisor = instr->divisor(); 1384 int32_t divisor = instr->divisor();
1388 Register result = ToRegister(instr->result()); 1385 Register result = ToRegister(instr->result());
1389 DCHECK(!dividend.is(result)); 1386 DCHECK(!dividend.is(result));
1390 1387
1391 if (divisor == 0) { 1388 if (divisor == 0) {
1392 DeoptimizeIf(al, instr->environment()); 1389 DeoptimizeIf(al, instr);
1393 return; 1390 return;
1394 } 1391 }
1395 1392
1396 // Check for (0 / -x) that will produce negative zero. 1393 // Check for (0 / -x) that will produce negative zero.
1397 HMathFloorOfDiv* hdiv = instr->hydrogen(); 1394 HMathFloorOfDiv* hdiv = instr->hydrogen();
1398 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1395 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1399 DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg)); 1396 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1400 } 1397 }
1401 1398
1402 // Easy case: We need no dynamic check for the dividend and the flooring 1399 // Easy case: We need no dynamic check for the dividend and the flooring
1403 // division is the same as the truncating division. 1400 // division is the same as the truncating division.
1404 if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) || 1401 if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) ||
1405 (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) { 1402 (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) {
1406 __ TruncatingDiv(result, dividend, Abs(divisor)); 1403 __ TruncatingDiv(result, dividend, Abs(divisor));
1407 if (divisor < 0) __ Subu(result, zero_reg, result); 1404 if (divisor < 0) __ Subu(result, zero_reg, result);
1408 return; 1405 return;
1409 } 1406 }
(...skipping 23 matching lines...) Expand all
1433 Register dividend = ToRegister(instr->dividend()); 1430 Register dividend = ToRegister(instr->dividend());
1434 Register divisor = ToRegister(instr->divisor()); 1431 Register divisor = ToRegister(instr->divisor());
1435 const Register result = ToRegister(instr->result()); 1432 const Register result = ToRegister(instr->result());
1436 Register remainder = scratch0(); 1433 Register remainder = scratch0();
1437 // On MIPS div is asynchronous - it will run in the background while we 1434 // On MIPS div is asynchronous - it will run in the background while we
1438 // check for special cases. 1435 // check for special cases.
1439 __ Div(remainder, result, dividend, divisor); 1436 __ Div(remainder, result, dividend, divisor);
1440 1437
1441 // Check for x / 0. 1438 // Check for x / 0.
1442 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1439 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
1443 DeoptimizeIf(eq, instr->environment(), divisor, Operand(zero_reg)); 1440 DeoptimizeIf(eq, instr, divisor, Operand(zero_reg));
1444 } 1441 }
1445 1442
1446 // Check for (0 / -x) that will produce negative zero. 1443 // Check for (0 / -x) that will produce negative zero.
1447 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1444 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1448 Label left_not_zero; 1445 Label left_not_zero;
1449 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg)); 1446 __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
1450 DeoptimizeIf(lt, instr->environment(), divisor, Operand(zero_reg)); 1447 DeoptimizeIf(lt, instr, divisor, Operand(zero_reg));
1451 __ bind(&left_not_zero); 1448 __ bind(&left_not_zero);
1452 } 1449 }
1453 1450
1454 // Check for (kMinInt / -1). 1451 // Check for (kMinInt / -1).
1455 if (hdiv->CheckFlag(HValue::kCanOverflow) && 1452 if (hdiv->CheckFlag(HValue::kCanOverflow) &&
1456 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1453 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1457 Label left_not_min_int; 1454 Label left_not_min_int;
1458 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt)); 1455 __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
1459 DeoptimizeIf(eq, instr->environment(), divisor, Operand(-1)); 1456 DeoptimizeIf(eq, instr, divisor, Operand(-1));
1460 __ bind(&left_not_min_int); 1457 __ bind(&left_not_min_int);
1461 } 1458 }
1462 1459
1463 // We performed a truncating division. Correct the result if necessary. 1460 // We performed a truncating division. Correct the result if necessary.
1464 Label done; 1461 Label done;
1465 __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT); 1462 __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT);
1466 __ Xor(remainder, remainder, Operand(divisor)); 1463 __ Xor(remainder, remainder, Operand(divisor));
1467 __ Branch(&done, ge, remainder, Operand(zero_reg)); 1464 __ Branch(&done, ge, remainder, Operand(zero_reg));
1468 __ Subu(result, result, Operand(1)); 1465 __ Subu(result, result, Operand(1));
1469 __ bind(&done); 1466 __ bind(&done);
(...skipping 10 matching lines...) Expand all
1480 bool bailout_on_minus_zero = 1477 bool bailout_on_minus_zero =
1481 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1478 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1482 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1479 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1483 1480
1484 if (right_op->IsConstantOperand()) { 1481 if (right_op->IsConstantOperand()) {
1485 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); 1482 int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
1486 1483
1487 if (bailout_on_minus_zero && (constant < 0)) { 1484 if (bailout_on_minus_zero && (constant < 0)) {
1488 // The case of a null constant will be handled separately. 1485 // The case of a null constant will be handled separately.
1489 // If constant is negative and left is null, the result should be -0. 1486 // If constant is negative and left is null, the result should be -0.
1490 DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg)); 1487 DeoptimizeIf(eq, instr, left, Operand(zero_reg));
1491 } 1488 }
1492 1489
1493 switch (constant) { 1490 switch (constant) {
1494 case -1: 1491 case -1:
1495 if (overflow) { 1492 if (overflow) {
1496 __ SubuAndCheckForOverflow(result, zero_reg, left, scratch); 1493 __ SubuAndCheckForOverflow(result, zero_reg, left, scratch);
1497 DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg)); 1494 DeoptimizeIf(lt, instr, scratch, Operand(zero_reg));
1498 } else { 1495 } else {
1499 __ Subu(result, zero_reg, left); 1496 __ Subu(result, zero_reg, left);
1500 } 1497 }
1501 break; 1498 break;
1502 case 0: 1499 case 0:
1503 if (bailout_on_minus_zero) { 1500 if (bailout_on_minus_zero) {
1504 // If left is strictly negative and the constant is null, the 1501 // If left is strictly negative and the constant is null, the
1505 // result is -0. Deoptimize if required, otherwise return 0. 1502 // result is -0. Deoptimize if required, otherwise return 0.
1506 DeoptimizeIf(lt, instr->environment(), left, Operand(zero_reg)); 1503 DeoptimizeIf(lt, instr, left, Operand(zero_reg));
1507 } 1504 }
1508 __ mov(result, zero_reg); 1505 __ mov(result, zero_reg);
1509 break; 1506 break;
1510 case 1: 1507 case 1:
1511 // Nothing to do. 1508 // Nothing to do.
1512 __ Move(result, left); 1509 __ Move(result, left);
1513 break; 1510 break;
1514 default: 1511 default:
1515 // Multiplying by powers of two and powers of two plus or minus 1512 // Multiplying by powers of two and powers of two plus or minus
1516 // one can be done faster with shifted operands. 1513 // one can be done faster with shifted operands.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1548 1545
1549 if (overflow) { 1546 if (overflow) {
1550 // hi:lo = left * right. 1547 // hi:lo = left * right.
1551 if (instr->hydrogen()->representation().IsSmi()) { 1548 if (instr->hydrogen()->representation().IsSmi()) {
1552 __ SmiUntag(result, left); 1549 __ SmiUntag(result, left);
1553 __ Mul(scratch, result, result, right); 1550 __ Mul(scratch, result, result, right);
1554 } else { 1551 } else {
1555 __ Mul(scratch, result, left, right); 1552 __ Mul(scratch, result, left, right);
1556 } 1553 }
1557 __ sra(at, result, 31); 1554 __ sra(at, result, 31);
1558 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); 1555 DeoptimizeIf(ne, instr, scratch, Operand(at));
1559 } else { 1556 } else {
1560 if (instr->hydrogen()->representation().IsSmi()) { 1557 if (instr->hydrogen()->representation().IsSmi()) {
1561 __ SmiUntag(result, left); 1558 __ SmiUntag(result, left);
1562 __ Mul(result, result, right); 1559 __ Mul(result, result, right);
1563 } else { 1560 } else {
1564 __ Mul(result, left, right); 1561 __ Mul(result, left, right);
1565 } 1562 }
1566 } 1563 }
1567 1564
1568 if (bailout_on_minus_zero) { 1565 if (bailout_on_minus_zero) {
1569 Label done; 1566 Label done;
1570 __ Xor(at, left, right); 1567 __ Xor(at, left, right);
1571 __ Branch(&done, ge, at, Operand(zero_reg)); 1568 __ Branch(&done, ge, at, Operand(zero_reg));
1572 // Bail out if the result is minus zero. 1569 // Bail out if the result is minus zero.
1573 DeoptimizeIf(eq, 1570 DeoptimizeIf(eq, instr, result, Operand(zero_reg));
1574 instr->environment(),
1575 result,
1576 Operand(zero_reg));
1577 __ bind(&done); 1571 __ bind(&done);
1578 } 1572 }
1579 } 1573 }
1580 } 1574 }
1581 1575
1582 1576
1583 void LCodeGen::DoBitI(LBitI* instr) { 1577 void LCodeGen::DoBitI(LBitI* instr) {
1584 LOperand* left_op = instr->left(); 1578 LOperand* left_op = instr->left();
1585 LOperand* right_op = instr->right(); 1579 LOperand* right_op = instr->right();
1586 DCHECK(left_op->IsRegister()); 1580 DCHECK(left_op->IsRegister());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 switch (instr->op()) { 1624 switch (instr->op()) {
1631 case Token::ROR: 1625 case Token::ROR:
1632 __ Ror(result, left, Operand(ToRegister(right_op))); 1626 __ Ror(result, left, Operand(ToRegister(right_op)));
1633 break; 1627 break;
1634 case Token::SAR: 1628 case Token::SAR:
1635 __ srav(result, left, ToRegister(right_op)); 1629 __ srav(result, left, ToRegister(right_op));
1636 break; 1630 break;
1637 case Token::SHR: 1631 case Token::SHR:
1638 __ srlv(result, left, ToRegister(right_op)); 1632 __ srlv(result, left, ToRegister(right_op));
1639 if (instr->can_deopt()) { 1633 if (instr->can_deopt()) {
1640 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); 1634 DeoptimizeIf(lt, instr, result, Operand(zero_reg));
1641 } 1635 }
1642 break; 1636 break;
1643 case Token::SHL: 1637 case Token::SHL:
1644 __ sllv(result, left, ToRegister(right_op)); 1638 __ sllv(result, left, ToRegister(right_op));
1645 break; 1639 break;
1646 default: 1640 default:
1647 UNREACHABLE(); 1641 UNREACHABLE();
1648 break; 1642 break;
1649 } 1643 }
1650 } else { 1644 } else {
(...skipping 14 matching lines...) Expand all
1665 } else { 1659 } else {
1666 __ Move(result, left); 1660 __ Move(result, left);
1667 } 1661 }
1668 break; 1662 break;
1669 case Token::SHR: 1663 case Token::SHR:
1670 if (shift_count != 0) { 1664 if (shift_count != 0) {
1671 __ srl(result, left, shift_count); 1665 __ srl(result, left, shift_count);
1672 } else { 1666 } else {
1673 if (instr->can_deopt()) { 1667 if (instr->can_deopt()) {
1674 __ And(at, left, Operand(0x80000000)); 1668 __ And(at, left, Operand(0x80000000));
1675 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 1669 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
1676 } 1670 }
1677 __ Move(result, left); 1671 __ Move(result, left);
1678 } 1672 }
1679 break; 1673 break;
1680 case Token::SHL: 1674 case Token::SHL:
1681 if (shift_count != 0) { 1675 if (shift_count != 0) {
1682 if (instr->hydrogen_value()->representation().IsSmi() && 1676 if (instr->hydrogen_value()->representation().IsSmi() &&
1683 instr->can_deopt()) { 1677 instr->can_deopt()) {
1684 if (shift_count != 1) { 1678 if (shift_count != 1) {
1685 __ sll(result, left, shift_count - 1); 1679 __ sll(result, left, shift_count - 1);
1686 __ SmiTagCheckOverflow(result, result, scratch); 1680 __ SmiTagCheckOverflow(result, result, scratch);
1687 } else { 1681 } else {
1688 __ SmiTagCheckOverflow(result, left, scratch); 1682 __ SmiTagCheckOverflow(result, left, scratch);
1689 } 1683 }
1690 DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg)); 1684 DeoptimizeIf(lt, instr, scratch, Operand(zero_reg));
1691 } else { 1685 } else {
1692 __ sll(result, left, shift_count); 1686 __ sll(result, left, shift_count);
1693 } 1687 }
1694 } else { 1688 } else {
1695 __ Move(result, left); 1689 __ Move(result, left);
1696 } 1690 }
1697 break; 1691 break;
1698 default: 1692 default:
1699 UNREACHABLE(); 1693 UNREACHABLE();
1700 break; 1694 break;
(...skipping 27 matching lines...) Expand all
1728 overflow); // Reg at also used as scratch. 1722 overflow); // Reg at also used as scratch.
1729 } else { 1723 } else {
1730 DCHECK(right->IsRegister()); 1724 DCHECK(right->IsRegister());
1731 // Due to overflow check macros not supporting constant operands, 1725 // Due to overflow check macros not supporting constant operands,
1732 // handling the IsConstantOperand case was moved to prev if clause. 1726 // handling the IsConstantOperand case was moved to prev if clause.
1733 __ SubuAndCheckForOverflow(ToRegister(result), 1727 __ SubuAndCheckForOverflow(ToRegister(result),
1734 ToRegister(left), 1728 ToRegister(left),
1735 ToRegister(right), 1729 ToRegister(right),
1736 overflow); // Reg at also used as scratch. 1730 overflow); // Reg at also used as scratch.
1737 } 1731 }
1738 DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg)); 1732 DeoptimizeIf(lt, instr, overflow, Operand(zero_reg));
1739 } 1733 }
1740 } 1734 }
1741 1735
1742 1736
1743 void LCodeGen::DoConstantI(LConstantI* instr) { 1737 void LCodeGen::DoConstantI(LConstantI* instr) {
1744 __ li(ToRegister(instr->result()), Operand(instr->value())); 1738 __ li(ToRegister(instr->result()), Operand(instr->value()));
1745 } 1739 }
1746 1740
1747 1741
1748 void LCodeGen::DoConstantS(LConstantS* instr) { 1742 void LCodeGen::DoConstantS(LConstantS* instr) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 Register result = ToRegister(instr->result()); 1776 Register result = ToRegister(instr->result());
1783 Register scratch = ToRegister(instr->temp()); 1777 Register scratch = ToRegister(instr->temp());
1784 Smi* index = instr->index(); 1778 Smi* index = instr->index();
1785 Label runtime, done; 1779 Label runtime, done;
1786 DCHECK(object.is(a0)); 1780 DCHECK(object.is(a0));
1787 DCHECK(result.is(v0)); 1781 DCHECK(result.is(v0));
1788 DCHECK(!scratch.is(scratch0())); 1782 DCHECK(!scratch.is(scratch0()));
1789 DCHECK(!scratch.is(object)); 1783 DCHECK(!scratch.is(object));
1790 1784
1791 __ SmiTst(object, at); 1785 __ SmiTst(object, at);
1792 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 1786 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
1793 __ GetObjectType(object, scratch, scratch); 1787 __ GetObjectType(object, scratch, scratch);
1794 DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_DATE_TYPE)); 1788 DeoptimizeIf(ne, instr, scratch, Operand(JS_DATE_TYPE));
1795 1789
1796 if (index->value() == 0) { 1790 if (index->value() == 0) {
1797 __ lw(result, FieldMemOperand(object, JSDate::kValueOffset)); 1791 __ lw(result, FieldMemOperand(object, JSDate::kValueOffset));
1798 } else { 1792 } else {
1799 if (index->value() < JSDate::kFirstUncachedField) { 1793 if (index->value() < JSDate::kFirstUncachedField) {
1800 ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 1794 ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
1801 __ li(scratch, Operand(stamp)); 1795 __ li(scratch, Operand(stamp));
1802 __ lw(scratch, MemOperand(scratch)); 1796 __ lw(scratch, MemOperand(scratch));
1803 __ lw(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset)); 1797 __ lw(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset));
1804 __ Branch(&runtime, ne, scratch, Operand(scratch0())); 1798 __ Branch(&runtime, ne, scratch, Operand(scratch0()));
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 overflow); // Reg at also used as scratch. 1913 overflow); // Reg at also used as scratch.
1920 } else { 1914 } else {
1921 DCHECK(right->IsRegister()); 1915 DCHECK(right->IsRegister());
1922 // Due to overflow check macros not supporting constant operands, 1916 // Due to overflow check macros not supporting constant operands,
1923 // handling the IsConstantOperand case was moved to prev if clause. 1917 // handling the IsConstantOperand case was moved to prev if clause.
1924 __ AdduAndCheckForOverflow(ToRegister(result), 1918 __ AdduAndCheckForOverflow(ToRegister(result),
1925 ToRegister(left), 1919 ToRegister(left),
1926 ToRegister(right), 1920 ToRegister(right),
1927 overflow); // Reg at also used as scratch. 1921 overflow); // Reg at also used as scratch.
1928 } 1922 }
1929 DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg)); 1923 DeoptimizeIf(lt, instr, overflow, Operand(zero_reg));
1930 } 1924 }
1931 } 1925 }
1932 1926
1933 1927
1934 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1928 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1935 LOperand* left = instr->left(); 1929 LOperand* left = instr->left();
1936 LOperand* right = instr->right(); 1930 LOperand* right = instr->right();
1937 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1931 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1938 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; 1932 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
1939 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { 1933 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
2180 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); 2174 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2181 } 2175 }
2182 2176
2183 if (expected.Contains(ToBooleanStub::SMI)) { 2177 if (expected.Contains(ToBooleanStub::SMI)) {
2184 // Smis: 0 -> false, all other -> true. 2178 // Smis: 0 -> false, all other -> true.
2185 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg)); 2179 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg));
2186 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); 2180 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2187 } else if (expected.NeedsMap()) { 2181 } else if (expected.NeedsMap()) {
2188 // If we need a map later and have a Smi -> deopt. 2182 // If we need a map later and have a Smi -> deopt.
2189 __ SmiTst(reg, at); 2183 __ SmiTst(reg, at);
2190 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 2184 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
2191 } 2185 }
2192 2186
2193 const Register map = scratch0(); 2187 const Register map = scratch0();
2194 if (expected.NeedsMap()) { 2188 if (expected.NeedsMap()) {
2195 __ lw(map, FieldMemOperand(reg, HeapObject::kMapOffset)); 2189 __ lw(map, FieldMemOperand(reg, HeapObject::kMapOffset));
2196 if (expected.CanBeUndetectable()) { 2190 if (expected.CanBeUndetectable()) {
2197 // Undetectable -> false. 2191 // Undetectable -> false.
2198 __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset)); 2192 __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
2199 __ And(at, at, Operand(1 << Map::kIsUndetectable)); 2193 __ And(at, at, Operand(1 << Map::kIsUndetectable));
2200 __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg)); 2194 __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2236 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), 2230 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2237 ne, dbl_scratch, kDoubleRegZero); 2231 ne, dbl_scratch, kDoubleRegZero);
2238 // Falls through if dbl_scratch == 0. 2232 // Falls through if dbl_scratch == 0.
2239 __ Branch(instr->FalseLabel(chunk_)); 2233 __ Branch(instr->FalseLabel(chunk_));
2240 __ bind(&not_heap_number); 2234 __ bind(&not_heap_number);
2241 } 2235 }
2242 2236
2243 if (!expected.IsGeneric()) { 2237 if (!expected.IsGeneric()) {
2244 // We've seen something for the first time -> deopt. 2238 // We've seen something for the first time -> deopt.
2245 // This can only happen if we are not generic already. 2239 // This can only happen if we are not generic already.
2246 DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg)); 2240 DeoptimizeIf(al, instr, zero_reg, Operand(zero_reg));
2247 } 2241 }
2248 } 2242 }
2249 } 2243 }
2250 } 2244 }
2251 2245
2252 2246
2253 void LCodeGen::EmitGoto(int block) { 2247 void LCodeGen::EmitGoto(int block) {
2254 if (!IsNextEmittedBlock(block)) { 2248 if (!IsNextEmittedBlock(block)) {
2255 __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block))); 2249 __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
2256 } 2250 }
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after
2880 } 2874 }
2881 } 2875 }
2882 2876
2883 2877
2884 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 2878 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2885 Register result = ToRegister(instr->result()); 2879 Register result = ToRegister(instr->result());
2886 __ li(at, Operand(Handle<Object>(instr->hydrogen()->cell().handle()))); 2880 __ li(at, Operand(Handle<Object>(instr->hydrogen()->cell().handle())));
2887 __ lw(result, FieldMemOperand(at, Cell::kValueOffset)); 2881 __ lw(result, FieldMemOperand(at, Cell::kValueOffset));
2888 if (instr->hydrogen()->RequiresHoleCheck()) { 2882 if (instr->hydrogen()->RequiresHoleCheck()) {
2889 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2883 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2890 DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 2884 DeoptimizeIf(eq, instr, result, Operand(at));
2891 } 2885 }
2892 } 2886 }
2893 2887
2894 2888
2895 template <class T> 2889 template <class T>
2896 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { 2890 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
2897 DCHECK(FLAG_vector_ics); 2891 DCHECK(FLAG_vector_ics);
2898 Register vector = ToRegister(instr->temp_vector()); 2892 Register vector = ToRegister(instr->temp_vector());
2899 DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister())); 2893 DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister()));
2900 __ li(vector, instr->hydrogen()->feedback_vector()); 2894 __ li(vector, instr->hydrogen()->feedback_vector());
(...skipping 29 matching lines...) Expand all
2930 2924
2931 // If the cell we are storing to contains the hole it could have 2925 // If the cell we are storing to contains the hole it could have
2932 // been deleted from the property dictionary. In that case, we need 2926 // been deleted from the property dictionary. In that case, we need
2933 // to update the property details in the property dictionary to mark 2927 // to update the property details in the property dictionary to mark
2934 // it as no longer deleted. 2928 // it as no longer deleted.
2935 if (instr->hydrogen()->RequiresHoleCheck()) { 2929 if (instr->hydrogen()->RequiresHoleCheck()) {
2936 // We use a temp to check the payload. 2930 // We use a temp to check the payload.
2937 Register payload = ToRegister(instr->temp()); 2931 Register payload = ToRegister(instr->temp());
2938 __ lw(payload, FieldMemOperand(cell, Cell::kValueOffset)); 2932 __ lw(payload, FieldMemOperand(cell, Cell::kValueOffset));
2939 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2933 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2940 DeoptimizeIf(eq, instr->environment(), payload, Operand(at)); 2934 DeoptimizeIf(eq, instr, payload, Operand(at));
2941 } 2935 }
2942 2936
2943 // Store the value. 2937 // Store the value.
2944 __ sw(value, FieldMemOperand(cell, Cell::kValueOffset)); 2938 __ sw(value, FieldMemOperand(cell, Cell::kValueOffset));
2945 // Cells are always rescanned, so no write barrier here. 2939 // Cells are always rescanned, so no write barrier here.
2946 } 2940 }
2947 2941
2948 2942
2949 2943
2950 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 2944 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2951 Register context = ToRegister(instr->context()); 2945 Register context = ToRegister(instr->context());
2952 Register result = ToRegister(instr->result()); 2946 Register result = ToRegister(instr->result());
2953 2947
2954 __ lw(result, ContextOperand(context, instr->slot_index())); 2948 __ lw(result, ContextOperand(context, instr->slot_index()));
2955 if (instr->hydrogen()->RequiresHoleCheck()) { 2949 if (instr->hydrogen()->RequiresHoleCheck()) {
2956 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2950 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2957 2951
2958 if (instr->hydrogen()->DeoptimizesOnHole()) { 2952 if (instr->hydrogen()->DeoptimizesOnHole()) {
2959 DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 2953 DeoptimizeIf(eq, instr, result, Operand(at));
2960 } else { 2954 } else {
2961 Label is_not_hole; 2955 Label is_not_hole;
2962 __ Branch(&is_not_hole, ne, result, Operand(at)); 2956 __ Branch(&is_not_hole, ne, result, Operand(at));
2963 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); 2957 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
2964 __ bind(&is_not_hole); 2958 __ bind(&is_not_hole);
2965 } 2959 }
2966 } 2960 }
2967 } 2961 }
2968 2962
2969 2963
2970 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { 2964 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2971 Register context = ToRegister(instr->context()); 2965 Register context = ToRegister(instr->context());
2972 Register value = ToRegister(instr->value()); 2966 Register value = ToRegister(instr->value());
2973 Register scratch = scratch0(); 2967 Register scratch = scratch0();
2974 MemOperand target = ContextOperand(context, instr->slot_index()); 2968 MemOperand target = ContextOperand(context, instr->slot_index());
2975 2969
2976 Label skip_assignment; 2970 Label skip_assignment;
2977 2971
2978 if (instr->hydrogen()->RequiresHoleCheck()) { 2972 if (instr->hydrogen()->RequiresHoleCheck()) {
2979 __ lw(scratch, target); 2973 __ lw(scratch, target);
2980 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2974 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2981 2975
2982 if (instr->hydrogen()->DeoptimizesOnHole()) { 2976 if (instr->hydrogen()->DeoptimizesOnHole()) {
2983 DeoptimizeIf(eq, instr->environment(), scratch, Operand(at)); 2977 DeoptimizeIf(eq, instr, scratch, Operand(at));
2984 } else { 2978 } else {
2985 __ Branch(&skip_assignment, ne, scratch, Operand(at)); 2979 __ Branch(&skip_assignment, ne, scratch, Operand(at));
2986 } 2980 }
2987 } 2981 }
2988 2982
2989 __ sw(value, target); 2983 __ sw(value, target);
2990 if (instr->hydrogen()->NeedsWriteBarrier()) { 2984 if (instr->hydrogen()->NeedsWriteBarrier()) {
2991 SmiCheck check_needed = 2985 SmiCheck check_needed =
2992 instr->hydrogen()->value()->type().IsHeapObject() 2986 instr->hydrogen()->value()->type().IsHeapObject()
2993 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2987 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3052 Register scratch = scratch0(); 3046 Register scratch = scratch0();
3053 Register function = ToRegister(instr->function()); 3047 Register function = ToRegister(instr->function());
3054 Register result = ToRegister(instr->result()); 3048 Register result = ToRegister(instr->result());
3055 3049
3056 // Get the prototype or initial map from the function. 3050 // Get the prototype or initial map from the function.
3057 __ lw(result, 3051 __ lw(result,
3058 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 3052 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
3059 3053
3060 // Check that the function has a prototype or an initial map. 3054 // Check that the function has a prototype or an initial map.
3061 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 3055 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
3062 DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 3056 DeoptimizeIf(eq, instr, result, Operand(at));
3063 3057
3064 // If the function does not have an initial map, we're done. 3058 // If the function does not have an initial map, we're done.
3065 Label done; 3059 Label done;
3066 __ GetObjectType(result, scratch, scratch); 3060 __ GetObjectType(result, scratch, scratch);
3067 __ Branch(&done, ne, scratch, Operand(MAP_TYPE)); 3061 __ Branch(&done, ne, scratch, Operand(MAP_TYPE));
3068 3062
3069 // Get the prototype from the initial map. 3063 // Get the prototype from the initial map.
3070 __ lw(result, FieldMemOperand(result, Map::kPrototypeOffset)); 3064 __ lw(result, FieldMemOperand(result, Map::kPrototypeOffset));
3071 3065
3072 // All done. 3066 // All done.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
3188 __ lhu(result, mem_operand); 3182 __ lhu(result, mem_operand);
3189 break; 3183 break;
3190 case EXTERNAL_INT32_ELEMENTS: 3184 case EXTERNAL_INT32_ELEMENTS:
3191 case INT32_ELEMENTS: 3185 case INT32_ELEMENTS:
3192 __ lw(result, mem_operand); 3186 __ lw(result, mem_operand);
3193 break; 3187 break;
3194 case EXTERNAL_UINT32_ELEMENTS: 3188 case EXTERNAL_UINT32_ELEMENTS:
3195 case UINT32_ELEMENTS: 3189 case UINT32_ELEMENTS:
3196 __ lw(result, mem_operand); 3190 __ lw(result, mem_operand);
3197 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 3191 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3198 DeoptimizeIf(Ugreater_equal, instr->environment(), 3192 DeoptimizeIf(Ugreater_equal, instr, result, Operand(0x80000000));
3199 result, Operand(0x80000000));
3200 } 3193 }
3201 break; 3194 break;
3202 case FLOAT32_ELEMENTS: 3195 case FLOAT32_ELEMENTS:
3203 case FLOAT64_ELEMENTS: 3196 case FLOAT64_ELEMENTS:
3204 case EXTERNAL_FLOAT32_ELEMENTS: 3197 case EXTERNAL_FLOAT32_ELEMENTS:
3205 case EXTERNAL_FLOAT64_ELEMENTS: 3198 case EXTERNAL_FLOAT64_ELEMENTS:
3206 case FAST_DOUBLE_ELEMENTS: 3199 case FAST_DOUBLE_ELEMENTS:
3207 case FAST_ELEMENTS: 3200 case FAST_ELEMENTS:
3208 case FAST_SMI_ELEMENTS: 3201 case FAST_SMI_ELEMENTS:
3209 case FAST_HOLEY_DOUBLE_ELEMENTS: 3202 case FAST_HOLEY_DOUBLE_ELEMENTS:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3242 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) 3235 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
3243 ? (element_size_shift - kSmiTagSize) : element_size_shift; 3236 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3244 __ sll(at, key, shift_size); 3237 __ sll(at, key, shift_size);
3245 __ Addu(scratch, scratch, at); 3238 __ Addu(scratch, scratch, at);
3246 } 3239 }
3247 3240
3248 __ ldc1(result, MemOperand(scratch)); 3241 __ ldc1(result, MemOperand(scratch));
3249 3242
3250 if (instr->hydrogen()->RequiresHoleCheck()) { 3243 if (instr->hydrogen()->RequiresHoleCheck()) {
3251 __ lw(scratch, MemOperand(scratch, kHoleNanUpper32Offset)); 3244 __ lw(scratch, MemOperand(scratch, kHoleNanUpper32Offset));
3252 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); 3245 DeoptimizeIf(eq, instr, scratch, Operand(kHoleNanUpper32));
3253 } 3246 }
3254 } 3247 }
3255 3248
3256 3249
3257 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3250 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3258 Register elements = ToRegister(instr->elements()); 3251 Register elements = ToRegister(instr->elements());
3259 Register result = ToRegister(instr->result()); 3252 Register result = ToRegister(instr->result());
3260 Register scratch = scratch0(); 3253 Register scratch = scratch0();
3261 Register store_base = scratch; 3254 Register store_base = scratch;
3262 int offset = instr->base_offset(); 3255 int offset = instr->base_offset();
(...skipping 15 matching lines...) Expand all
3278 __ sll(scratch, key, kPointerSizeLog2); 3271 __ sll(scratch, key, kPointerSizeLog2);
3279 __ addu(scratch, elements, scratch); 3272 __ addu(scratch, elements, scratch);
3280 } 3273 }
3281 } 3274 }
3282 __ lw(result, MemOperand(store_base, offset)); 3275 __ lw(result, MemOperand(store_base, offset));
3283 3276
3284 // Check for the hole value. 3277 // Check for the hole value.
3285 if (instr->hydrogen()->RequiresHoleCheck()) { 3278 if (instr->hydrogen()->RequiresHoleCheck()) {
3286 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { 3279 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3287 __ SmiTst(result, scratch); 3280 __ SmiTst(result, scratch);
3288 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 3281 DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
3289 } else { 3282 } else {
3290 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 3283 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
3291 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); 3284 DeoptimizeIf(eq, instr, result, Operand(scratch));
3292 } 3285 }
3293 } 3286 }
3294 } 3287 }
3295 3288
3296 3289
3297 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { 3290 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3298 if (instr->is_typed_elements()) { 3291 if (instr->is_typed_elements()) {
3299 DoLoadKeyedExternalArray(instr); 3292 DoLoadKeyedExternalArray(instr);
3300 } else if (instr->hydrogen()->representation().IsDouble()) { 3293 } else if (instr->hydrogen()->representation().IsDouble()) {
3301 DoLoadKeyedFixedDoubleArray(instr); 3294 DoLoadKeyedFixedDoubleArray(instr);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
3427 } 3420 }
3428 3421
3429 // Normal function. Replace undefined or null with global receiver. 3422 // Normal function. Replace undefined or null with global receiver.
3430 __ LoadRoot(scratch, Heap::kNullValueRootIndex); 3423 __ LoadRoot(scratch, Heap::kNullValueRootIndex);
3431 __ Branch(&global_object, eq, receiver, Operand(scratch)); 3424 __ Branch(&global_object, eq, receiver, Operand(scratch));
3432 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 3425 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
3433 __ Branch(&global_object, eq, receiver, Operand(scratch)); 3426 __ Branch(&global_object, eq, receiver, Operand(scratch));
3434 3427
3435 // Deoptimize if the receiver is not a JS object. 3428 // Deoptimize if the receiver is not a JS object.
3436 __ SmiTst(receiver, scratch); 3429 __ SmiTst(receiver, scratch);
3437 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); 3430 DeoptimizeIf(eq, instr, scratch, Operand(zero_reg));
3438 3431
3439 __ GetObjectType(receiver, scratch, scratch); 3432 __ GetObjectType(receiver, scratch, scratch);
3440 DeoptimizeIf(lt, instr->environment(), 3433 DeoptimizeIf(lt, instr, scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
3441 scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
3442 3434
3443 __ Branch(&result_in_receiver); 3435 __ Branch(&result_in_receiver);
3444 __ bind(&global_object); 3436 __ bind(&global_object);
3445 __ lw(result, FieldMemOperand(function, JSFunction::kContextOffset)); 3437 __ lw(result, FieldMemOperand(function, JSFunction::kContextOffset));
3446 __ lw(result, 3438 __ lw(result,
3447 ContextOperand(result, Context::GLOBAL_OBJECT_INDEX)); 3439 ContextOperand(result, Context::GLOBAL_OBJECT_INDEX));
3448 __ lw(result, 3440 __ lw(result,
3449 FieldMemOperand(result, GlobalObject::kGlobalProxyOffset)); 3441 FieldMemOperand(result, GlobalObject::kGlobalProxyOffset));
3450 3442
3451 if (result.is(receiver)) { 3443 if (result.is(receiver)) {
(...skipping 14 matching lines...) Expand all
3466 Register length = ToRegister(instr->length()); 3458 Register length = ToRegister(instr->length());
3467 Register elements = ToRegister(instr->elements()); 3459 Register elements = ToRegister(instr->elements());
3468 Register scratch = scratch0(); 3460 Register scratch = scratch0();
3469 DCHECK(receiver.is(a0)); // Used for parameter count. 3461 DCHECK(receiver.is(a0)); // Used for parameter count.
3470 DCHECK(function.is(a1)); // Required by InvokeFunction. 3462 DCHECK(function.is(a1)); // Required by InvokeFunction.
3471 DCHECK(ToRegister(instr->result()).is(v0)); 3463 DCHECK(ToRegister(instr->result()).is(v0));
3472 3464
3473 // Copy the arguments to this function possibly from the 3465 // Copy the arguments to this function possibly from the
3474 // adaptor frame below it. 3466 // adaptor frame below it.
3475 const uint32_t kArgumentsLimit = 1 * KB; 3467 const uint32_t kArgumentsLimit = 1 * KB;
3476 DeoptimizeIf(hi, instr->environment(), length, Operand(kArgumentsLimit)); 3468 DeoptimizeIf(hi, instr, length, Operand(kArgumentsLimit));
3477 3469
3478 // Push the receiver and use the register to keep the original 3470 // Push the receiver and use the register to keep the original
3479 // number of arguments. 3471 // number of arguments.
3480 __ push(receiver); 3472 __ push(receiver);
3481 __ Move(receiver, length); 3473 __ Move(receiver, length);
3482 // The arguments are at a one pointer size offset from elements. 3474 // The arguments are at a one pointer size offset from elements.
3483 __ Addu(elements, elements, Operand(1 * kPointerSize)); 3475 __ Addu(elements, elements, Operand(1 * kPointerSize));
3484 3476
3485 // Loop through the arguments pushing them onto the execution 3477 // Loop through the arguments pushing them onto the execution
3486 // stack. 3478 // stack.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
3596 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3588 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3597 DCHECK(instr->context() != NULL); 3589 DCHECK(instr->context() != NULL);
3598 DCHECK(ToRegister(instr->context()).is(cp)); 3590 DCHECK(ToRegister(instr->context()).is(cp));
3599 Register input = ToRegister(instr->value()); 3591 Register input = ToRegister(instr->value());
3600 Register result = ToRegister(instr->result()); 3592 Register result = ToRegister(instr->result());
3601 Register scratch = scratch0(); 3593 Register scratch = scratch0();
3602 3594
3603 // Deoptimize if not a heap number. 3595 // Deoptimize if not a heap number.
3604 __ lw(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 3596 __ lw(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
3605 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 3597 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
3606 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); 3598 DeoptimizeIf(ne, instr, scratch, Operand(at));
3607 3599
3608 Label done; 3600 Label done;
3609 Register exponent = scratch0(); 3601 Register exponent = scratch0();
3610 scratch = no_reg; 3602 scratch = no_reg;
3611 __ lw(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 3603 __ lw(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
3612 // Check the sign of the argument. If the argument is positive, just 3604 // Check the sign of the argument. If the argument is positive, just
3613 // return it. 3605 // return it.
3614 __ Move(result, input); 3606 __ Move(result, input);
3615 __ And(at, exponent, Operand(HeapNumber::kSignMask)); 3607 __ And(at, exponent, Operand(HeapNumber::kSignMask));
3616 __ Branch(&done, eq, at, Operand(zero_reg)); 3608 __ Branch(&done, eq, at, Operand(zero_reg));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3663 3655
3664 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { 3656 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3665 Register input = ToRegister(instr->value()); 3657 Register input = ToRegister(instr->value());
3666 Register result = ToRegister(instr->result()); 3658 Register result = ToRegister(instr->result());
3667 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 3659 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
3668 Label done; 3660 Label done;
3669 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); 3661 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg));
3670 __ mov(result, input); 3662 __ mov(result, input);
3671 __ subu(result, zero_reg, input); 3663 __ subu(result, zero_reg, input);
3672 // Overflow if result is still negative, i.e. 0x80000000. 3664 // Overflow if result is still negative, i.e. 0x80000000.
3673 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); 3665 DeoptimizeIf(lt, instr, result, Operand(zero_reg));
3674 __ bind(&done); 3666 __ bind(&done);
3675 } 3667 }
3676 3668
3677 3669
3678 void LCodeGen::DoMathAbs(LMathAbs* instr) { 3670 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3679 // Class for deferred case. 3671 // Class for deferred case.
3680 class DeferredMathAbsTaggedHeapNumber FINAL : public LDeferredCode { 3672 class DeferredMathAbsTaggedHeapNumber FINAL : public LDeferredCode {
3681 public: 3673 public:
3682 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) 3674 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3683 : LDeferredCode(codegen), instr_(instr) { } 3675 : LDeferredCode(codegen), instr_(instr) { }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3717 Register except_flag = ToRegister(instr->temp()); 3709 Register except_flag = ToRegister(instr->temp());
3718 3710
3719 __ EmitFPUTruncate(kRoundToMinusInf, 3711 __ EmitFPUTruncate(kRoundToMinusInf,
3720 result, 3712 result,
3721 input, 3713 input,
3722 scratch1, 3714 scratch1,
3723 double_scratch0(), 3715 double_scratch0(),
3724 except_flag); 3716 except_flag);
3725 3717
3726 // Deopt if the operation did not succeed. 3718 // Deopt if the operation did not succeed.
3727 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 3719 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
3728 3720
3729 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3721 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3730 // Test for -0. 3722 // Test for -0.
3731 Label done; 3723 Label done;
3732 __ Branch(&done, ne, result, Operand(zero_reg)); 3724 __ Branch(&done, ne, result, Operand(zero_reg));
3733 __ Mfhc1(scratch1, input); 3725 __ Mfhc1(scratch1, input);
3734 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 3726 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
3735 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 3727 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
3736 __ bind(&done); 3728 __ bind(&done);
3737 } 3729 }
3738 } 3730 }
3739 3731
3740 3732
3741 void LCodeGen::DoMathRound(LMathRound* instr) { 3733 void LCodeGen::DoMathRound(LMathRound* instr) {
3742 DoubleRegister input = ToDoubleRegister(instr->value()); 3734 DoubleRegister input = ToDoubleRegister(instr->value());
3743 Register result = ToRegister(instr->result()); 3735 Register result = ToRegister(instr->result());
3744 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); 3736 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp());
3745 Register scratch = scratch0(); 3737 Register scratch = scratch0();
(...skipping 12 matching lines...) Expand all
3758 __ mov(result, zero_reg); 3750 __ mov(result, zero_reg);
3759 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3751 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3760 __ Branch(&check_sign_on_zero); 3752 __ Branch(&check_sign_on_zero);
3761 } else { 3753 } else {
3762 __ Branch(&done); 3754 __ Branch(&done);
3763 } 3755 }
3764 __ bind(&skip1); 3756 __ bind(&skip1);
3765 3757
3766 // The following conversion will not work with numbers 3758 // The following conversion will not work with numbers
3767 // outside of ]-2^32, 2^32[. 3759 // outside of ]-2^32, 2^32[.
3768 DeoptimizeIf(ge, instr->environment(), scratch, 3760 DeoptimizeIf(ge, instr, scratch, Operand(HeapNumber::kExponentBias + 32));
3769 Operand(HeapNumber::kExponentBias + 32));
3770 3761
3771 // Save the original sign for later comparison. 3762 // Save the original sign for later comparison.
3772 __ And(scratch, result, Operand(HeapNumber::kSignMask)); 3763 __ And(scratch, result, Operand(HeapNumber::kSignMask));
3773 3764
3774 __ Move(double_scratch0(), 0.5); 3765 __ Move(double_scratch0(), 0.5);
3775 __ add_d(double_scratch0(), input, double_scratch0()); 3766 __ add_d(double_scratch0(), input, double_scratch0());
3776 3767
3777 // Check sign of the result: if the sign changed, the input 3768 // Check sign of the result: if the sign changed, the input
3778 // value was in ]0.5, 0[ and the result should be -0. 3769 // value was in ]0.5, 0[ and the result should be -0.
3779 __ Mfhc1(result, double_scratch0()); 3770 __ Mfhc1(result, double_scratch0());
3780 __ Xor(result, result, Operand(scratch)); 3771 __ Xor(result, result, Operand(scratch));
3781 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3772 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3782 // ARM uses 'mi' here, which is 'lt' 3773 // ARM uses 'mi' here, which is 'lt'
3783 DeoptimizeIf(lt, instr->environment(), result, 3774 DeoptimizeIf(lt, instr, result, Operand(zero_reg));
3784 Operand(zero_reg));
3785 } else { 3775 } else {
3786 Label skip2; 3776 Label skip2;
3787 // ARM uses 'mi' here, which is 'lt' 3777 // ARM uses 'mi' here, which is 'lt'
3788 // Negating it results in 'ge' 3778 // Negating it results in 'ge'
3789 __ Branch(&skip2, ge, result, Operand(zero_reg)); 3779 __ Branch(&skip2, ge, result, Operand(zero_reg));
3790 __ mov(result, zero_reg); 3780 __ mov(result, zero_reg);
3791 __ Branch(&done); 3781 __ Branch(&done);
3792 __ bind(&skip2); 3782 __ bind(&skip2);
3793 } 3783 }
3794 3784
3795 Register except_flag = scratch; 3785 Register except_flag = scratch;
3796 __ EmitFPUTruncate(kRoundToMinusInf, 3786 __ EmitFPUTruncate(kRoundToMinusInf,
3797 result, 3787 result,
3798 double_scratch0(), 3788 double_scratch0(),
3799 at, 3789 at,
3800 double_scratch1, 3790 double_scratch1,
3801 except_flag); 3791 except_flag);
3802 3792
3803 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 3793 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
3804 3794
3805 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3795 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3806 // Test for -0. 3796 // Test for -0.
3807 __ Branch(&done, ne, result, Operand(zero_reg)); 3797 __ Branch(&done, ne, result, Operand(zero_reg));
3808 __ bind(&check_sign_on_zero); 3798 __ bind(&check_sign_on_zero);
3809 __ Mfhc1(scratch, input); 3799 __ Mfhc1(scratch, input);
3810 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); 3800 __ And(scratch, scratch, Operand(HeapNumber::kSignMask));
3811 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 3801 DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
3812 } 3802 }
3813 __ bind(&done); 3803 __ bind(&done);
3814 } 3804 }
3815 3805
3816 3806
3817 void LCodeGen::DoMathFround(LMathFround* instr) { 3807 void LCodeGen::DoMathFround(LMathFround* instr) {
3818 DoubleRegister input = ToDoubleRegister(instr->value()); 3808 DoubleRegister input = ToDoubleRegister(instr->value());
3819 DoubleRegister result = ToDoubleRegister(instr->result()); 3809 DoubleRegister result = ToDoubleRegister(instr->result());
3820 __ cvt_s_d(result.low(), input); 3810 __ cvt_s_d(result.low(), input);
3821 __ cvt_d_s(result, result.low()); 3811 __ cvt_d_s(result, result.low());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3867 3857
3868 if (exponent_type.IsSmi()) { 3858 if (exponent_type.IsSmi()) {
3869 MathPowStub stub(isolate(), MathPowStub::TAGGED); 3859 MathPowStub stub(isolate(), MathPowStub::TAGGED);
3870 __ CallStub(&stub); 3860 __ CallStub(&stub);
3871 } else if (exponent_type.IsTagged()) { 3861 } else if (exponent_type.IsTagged()) {
3872 Label no_deopt; 3862 Label no_deopt;
3873 __ JumpIfSmi(tagged_exponent, &no_deopt); 3863 __ JumpIfSmi(tagged_exponent, &no_deopt);
3874 DCHECK(!t3.is(tagged_exponent)); 3864 DCHECK(!t3.is(tagged_exponent));
3875 __ lw(t3, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset)); 3865 __ lw(t3, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset));
3876 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 3866 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
3877 DeoptimizeIf(ne, instr->environment(), t3, Operand(at)); 3867 DeoptimizeIf(ne, instr, t3, Operand(at));
3878 __ bind(&no_deopt); 3868 __ bind(&no_deopt);
3879 MathPowStub stub(isolate(), MathPowStub::TAGGED); 3869 MathPowStub stub(isolate(), MathPowStub::TAGGED);
3880 __ CallStub(&stub); 3870 __ CallStub(&stub);
3881 } else if (exponent_type.IsInteger32()) { 3871 } else if (exponent_type.IsInteger32()) {
3882 MathPowStub stub(isolate(), MathPowStub::INTEGER); 3872 MathPowStub stub(isolate(), MathPowStub::INTEGER);
3883 __ CallStub(&stub); 3873 __ CallStub(&stub);
3884 } else { 3874 } else {
3885 DCHECK(exponent_type.IsDouble()); 3875 DCHECK(exponent_type.IsDouble());
3886 MathPowStub stub(isolate(), MathPowStub::DOUBLE); 3876 MathPowStub stub(isolate(), MathPowStub::DOUBLE);
3887 __ CallStub(&stub); 3877 __ CallStub(&stub);
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
4210 } else { 4200 } else {
4211 reg = ToRegister(instr->index()); 4201 reg = ToRegister(instr->index());
4212 operand = ToOperand(instr->length()); 4202 operand = ToOperand(instr->length());
4213 } 4203 }
4214 if (FLAG_debug_code && instr->hydrogen()->skip_check()) { 4204 if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
4215 Label done; 4205 Label done;
4216 __ Branch(&done, NegateCondition(cc), reg, operand); 4206 __ Branch(&done, NegateCondition(cc), reg, operand);
4217 __ stop("eliminated bounds check failed"); 4207 __ stop("eliminated bounds check failed");
4218 __ bind(&done); 4208 __ bind(&done);
4219 } else { 4209 } else {
4220 DeoptimizeIf(cc, instr->environment(), reg, operand); 4210 DeoptimizeIf(cc, instr, reg, operand);
4221 } 4211 }
4222 } 4212 }
4223 4213
4224 4214
4225 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4215 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4226 Register external_pointer = ToRegister(instr->elements()); 4216 Register external_pointer = ToRegister(instr->elements());
4227 Register key = no_reg; 4217 Register key = no_reg;
4228 ElementsKind elements_kind = instr->elements_kind(); 4218 ElementsKind elements_kind = instr->elements_kind();
4229 bool key_is_constant = instr->key()->IsConstantOperand(); 4219 bool key_is_constant = instr->key()->IsConstantOperand();
4230 int constant_key = 0; 4220 int constant_key = 0;
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
4468 __ bind(&not_applicable); 4458 __ bind(&not_applicable);
4469 } 4459 }
4470 4460
4471 4461
4472 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 4462 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4473 Register object = ToRegister(instr->object()); 4463 Register object = ToRegister(instr->object());
4474 Register temp = ToRegister(instr->temp()); 4464 Register temp = ToRegister(instr->temp());
4475 Label no_memento_found; 4465 Label no_memento_found;
4476 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found, 4466 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found,
4477 ne, &no_memento_found); 4467 ne, &no_memento_found);
4478 DeoptimizeIf(al, instr->environment()); 4468 DeoptimizeIf(al, instr);
4479 __ bind(&no_memento_found); 4469 __ bind(&no_memento_found);
4480 } 4470 }
4481 4471
4482 4472
4483 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4473 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4484 DCHECK(ToRegister(instr->context()).is(cp)); 4474 DCHECK(ToRegister(instr->context()).is(cp));
4485 DCHECK(ToRegister(instr->left()).is(a1)); 4475 DCHECK(ToRegister(instr->left()).is(a1));
4486 DCHECK(ToRegister(instr->right()).is(a0)); 4476 DCHECK(ToRegister(instr->right()).is(a0));
4487 StringAddStub stub(isolate(), 4477 StringAddStub stub(isolate(),
4488 instr->hydrogen()->flags(), 4478 instr->hydrogen()->flags(),
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
4803 } 4793 }
4804 4794
4805 4795
4806 void LCodeGen::DoSmiTag(LSmiTag* instr) { 4796 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4807 HChange* hchange = instr->hydrogen(); 4797 HChange* hchange = instr->hydrogen();
4808 Register input = ToRegister(instr->value()); 4798 Register input = ToRegister(instr->value());
4809 Register output = ToRegister(instr->result()); 4799 Register output = ToRegister(instr->result());
4810 if (hchange->CheckFlag(HValue::kCanOverflow) && 4800 if (hchange->CheckFlag(HValue::kCanOverflow) &&
4811 hchange->value()->CheckFlag(HValue::kUint32)) { 4801 hchange->value()->CheckFlag(HValue::kUint32)) {
4812 __ And(at, input, Operand(0xc0000000)); 4802 __ And(at, input, Operand(0xc0000000));
4813 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 4803 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
4814 } 4804 }
4815 if (hchange->CheckFlag(HValue::kCanOverflow) && 4805 if (hchange->CheckFlag(HValue::kCanOverflow) &&
4816 !hchange->value()->CheckFlag(HValue::kUint32)) { 4806 !hchange->value()->CheckFlag(HValue::kUint32)) {
4817 __ SmiTagCheckOverflow(output, input, at); 4807 __ SmiTagCheckOverflow(output, input, at);
4818 DeoptimizeIf(lt, instr->environment(), at, Operand(zero_reg)); 4808 DeoptimizeIf(lt, instr, at, Operand(zero_reg));
4819 } else { 4809 } else {
4820 __ SmiTag(output, input); 4810 __ SmiTag(output, input);
4821 } 4811 }
4822 } 4812 }
4823 4813
4824 4814
4825 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4815 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4826 Register scratch = scratch0(); 4816 Register scratch = scratch0();
4827 Register input = ToRegister(instr->value()); 4817 Register input = ToRegister(instr->value());
4828 Register result = ToRegister(instr->result()); 4818 Register result = ToRegister(instr->result());
4829 if (instr->needs_check()) { 4819 if (instr->needs_check()) {
4830 STATIC_ASSERT(kHeapObjectTag == 1); 4820 STATIC_ASSERT(kHeapObjectTag == 1);
4831 // If the input is a HeapObject, value of scratch won't be zero. 4821 // If the input is a HeapObject, value of scratch won't be zero.
4832 __ And(scratch, input, Operand(kHeapObjectTag)); 4822 __ And(scratch, input, Operand(kHeapObjectTag));
4833 __ SmiUntag(result, input); 4823 __ SmiUntag(result, input);
4834 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 4824 DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
4835 } else { 4825 } else {
4836 __ SmiUntag(result, input); 4826 __ SmiUntag(result, input);
4837 } 4827 }
4838 } 4828 }
4839 4829
4840 4830
4841 void LCodeGen::EmitNumberUntagD(Register input_reg, 4831 void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
4842 DoubleRegister result_reg, 4832 DoubleRegister result_reg,
4843 bool can_convert_undefined_to_nan,
4844 bool deoptimize_on_minus_zero,
4845 LEnvironment* env,
4846 NumberUntagDMode mode) { 4833 NumberUntagDMode mode) {
4834 bool can_convert_undefined_to_nan =
4835 instr->hydrogen()->can_convert_undefined_to_nan();
4836 bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
4837
4847 Register scratch = scratch0(); 4838 Register scratch = scratch0();
4848 Label convert, load_smi, done; 4839 Label convert, load_smi, done;
4849 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 4840 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4850 // Smi check. 4841 // Smi check.
4851 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); 4842 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
4852 // Heap number map check. 4843 // Heap number map check.
4853 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4844 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4854 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 4845 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
4855 if (can_convert_undefined_to_nan) { 4846 if (can_convert_undefined_to_nan) {
4856 __ Branch(&convert, ne, scratch, Operand(at)); 4847 __ Branch(&convert, ne, scratch, Operand(at));
4857 } else { 4848 } else {
4858 DeoptimizeIf(ne, env, scratch, Operand(at)); 4849 DeoptimizeIf(ne, instr, scratch, Operand(at));
4859 } 4850 }
4860 // Load heap number. 4851 // Load heap number.
4861 __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 4852 __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset));
4862 if (deoptimize_on_minus_zero) { 4853 if (deoptimize_on_minus_zero) {
4863 __ mfc1(at, result_reg.low()); 4854 __ mfc1(at, result_reg.low());
4864 __ Branch(&done, ne, at, Operand(zero_reg)); 4855 __ Branch(&done, ne, at, Operand(zero_reg));
4865 __ Mfhc1(scratch, result_reg); 4856 __ Mfhc1(scratch, result_reg);
4866 DeoptimizeIf(eq, env, scratch, Operand(HeapNumber::kSignMask)); 4857 DeoptimizeIf(eq, instr, scratch, Operand(HeapNumber::kSignMask));
4867 } 4858 }
4868 __ Branch(&done); 4859 __ Branch(&done);
4869 if (can_convert_undefined_to_nan) { 4860 if (can_convert_undefined_to_nan) {
4870 __ bind(&convert); 4861 __ bind(&convert);
4871 // Convert undefined (and hole) to NaN. 4862 // Convert undefined (and hole) to NaN.
4872 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 4863 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
4873 DeoptimizeIf(ne, env, input_reg, Operand(at)); 4864 DeoptimizeIf(ne, instr, input_reg, Operand(at));
4874 __ LoadRoot(scratch, Heap::kNanValueRootIndex); 4865 __ LoadRoot(scratch, Heap::kNanValueRootIndex);
4875 __ ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset)); 4866 __ ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset));
4876 __ Branch(&done); 4867 __ Branch(&done);
4877 } 4868 }
4878 } else { 4869 } else {
4879 __ SmiUntag(scratch, input_reg); 4870 __ SmiUntag(scratch, input_reg);
4880 DCHECK(mode == NUMBER_CANDIDATE_IS_SMI); 4871 DCHECK(mode == NUMBER_CANDIDATE_IS_SMI);
4881 } 4872 }
4882 // Smi to double register conversion 4873 // Smi to double register conversion
4883 __ bind(&load_smi); 4874 __ bind(&load_smi);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4928 4919
4929 __ bind(&check_bools); 4920 __ bind(&check_bools);
4930 __ LoadRoot(at, Heap::kTrueValueRootIndex); 4921 __ LoadRoot(at, Heap::kTrueValueRootIndex);
4931 __ Branch(&check_false, ne, scratch2, Operand(at)); 4922 __ Branch(&check_false, ne, scratch2, Operand(at));
4932 __ Branch(USE_DELAY_SLOT, &done); 4923 __ Branch(USE_DELAY_SLOT, &done);
4933 __ li(input_reg, Operand(1)); // In delay slot. 4924 __ li(input_reg, Operand(1)); // In delay slot.
4934 4925
4935 __ bind(&check_false); 4926 __ bind(&check_false);
4936 __ LoadRoot(at, Heap::kFalseValueRootIndex); 4927 __ LoadRoot(at, Heap::kFalseValueRootIndex);
4937 __ RecordComment("Deferred TaggedToI: cannot truncate"); 4928 __ RecordComment("Deferred TaggedToI: cannot truncate");
4938 DeoptimizeIf(ne, instr->environment(), scratch2, Operand(at)); 4929 DeoptimizeIf(ne, instr, scratch2, Operand(at));
4939 __ Branch(USE_DELAY_SLOT, &done); 4930 __ Branch(USE_DELAY_SLOT, &done);
4940 __ mov(input_reg, zero_reg); // In delay slot. 4931 __ mov(input_reg, zero_reg); // In delay slot.
4941 } else { 4932 } else {
4942 __ RecordComment("Deferred TaggedToI: not a heap number"); 4933 __ RecordComment("Deferred TaggedToI: not a heap number");
4943 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(at)); 4934 DeoptimizeIf(ne, instr, scratch1, Operand(at));
4944 4935
4945 // Load the double value. 4936 // Load the double value.
4946 __ ldc1(double_scratch, 4937 __ ldc1(double_scratch,
4947 FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 4938 FieldMemOperand(input_reg, HeapNumber::kValueOffset));
4948 4939
4949 Register except_flag = scratch2; 4940 Register except_flag = scratch2;
4950 __ EmitFPUTruncate(kRoundToZero, 4941 __ EmitFPUTruncate(kRoundToZero,
4951 input_reg, 4942 input_reg,
4952 double_scratch, 4943 double_scratch,
4953 scratch1, 4944 scratch1,
4954 double_scratch2, 4945 double_scratch2,
4955 except_flag, 4946 except_flag,
4956 kCheckForInexactConversion); 4947 kCheckForInexactConversion);
4957 4948
4958 __ RecordComment("Deferred TaggedToI: lost precision or NaN"); 4949 __ RecordComment("Deferred TaggedToI: lost precision or NaN");
4959 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 4950 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
4960 4951
4961 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4952 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4962 __ Branch(&done, ne, input_reg, Operand(zero_reg)); 4953 __ Branch(&done, ne, input_reg, Operand(zero_reg));
4963 4954
4964 __ Mfhc1(scratch1, double_scratch); 4955 __ Mfhc1(scratch1, double_scratch);
4965 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 4956 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
4966 __ RecordComment("Deferred TaggedToI: minus zero"); 4957 __ RecordComment("Deferred TaggedToI: minus zero");
4967 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 4958 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
4968 } 4959 }
4969 } 4960 }
4970 __ bind(&done); 4961 __ bind(&done);
4971 } 4962 }
4972 4963
4973 4964
4974 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 4965 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4975 class DeferredTaggedToI FINAL : public LDeferredCode { 4966 class DeferredTaggedToI FINAL : public LDeferredCode {
4976 public: 4967 public:
4977 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4968 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
5011 LOperand* result = instr->result(); 5002 LOperand* result = instr->result();
5012 DCHECK(result->IsDoubleRegister()); 5003 DCHECK(result->IsDoubleRegister());
5013 5004
5014 Register input_reg = ToRegister(input); 5005 Register input_reg = ToRegister(input);
5015 DoubleRegister result_reg = ToDoubleRegister(result); 5006 DoubleRegister result_reg = ToDoubleRegister(result);
5016 5007
5017 HValue* value = instr->hydrogen()->value(); 5008 HValue* value = instr->hydrogen()->value();
5018 NumberUntagDMode mode = value->representation().IsSmi() 5009 NumberUntagDMode mode = value->representation().IsSmi()
5019 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED; 5010 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED;
5020 5011
5021 EmitNumberUntagD(input_reg, result_reg, 5012 EmitNumberUntagD(instr, input_reg, result_reg, mode);
5022 instr->hydrogen()->can_convert_undefined_to_nan(),
5023 instr->hydrogen()->deoptimize_on_minus_zero(),
5024 instr->environment(),
5025 mode);
5026 } 5013 }
5027 5014
5028 5015
5029 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 5016 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5030 Register result_reg = ToRegister(instr->result()); 5017 Register result_reg = ToRegister(instr->result());
5031 Register scratch1 = scratch0(); 5018 Register scratch1 = scratch0();
5032 DoubleRegister double_input = ToDoubleRegister(instr->value()); 5019 DoubleRegister double_input = ToDoubleRegister(instr->value());
5033 5020
5034 if (instr->truncating()) { 5021 if (instr->truncating()) {
5035 __ TruncateDoubleToI(result_reg, double_input); 5022 __ TruncateDoubleToI(result_reg, double_input);
5036 } else { 5023 } else {
5037 Register except_flag = LCodeGen::scratch1(); 5024 Register except_flag = LCodeGen::scratch1();
5038 5025
5039 __ EmitFPUTruncate(kRoundToMinusInf, 5026 __ EmitFPUTruncate(kRoundToMinusInf,
5040 result_reg, 5027 result_reg,
5041 double_input, 5028 double_input,
5042 scratch1, 5029 scratch1,
5043 double_scratch0(), 5030 double_scratch0(),
5044 except_flag, 5031 except_flag,
5045 kCheckForInexactConversion); 5032 kCheckForInexactConversion);
5046 5033
5047 // Deopt if the operation did not succeed (except_flag != 0). 5034 // Deopt if the operation did not succeed (except_flag != 0).
5048 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 5035 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
5049 5036
5050 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5037 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5051 Label done; 5038 Label done;
5052 __ Branch(&done, ne, result_reg, Operand(zero_reg)); 5039 __ Branch(&done, ne, result_reg, Operand(zero_reg));
5053 __ Mfhc1(scratch1, double_input); 5040 __ Mfhc1(scratch1, double_input);
5054 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 5041 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
5055 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 5042 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
5056 __ bind(&done); 5043 __ bind(&done);
5057 } 5044 }
5058 } 5045 }
5059 } 5046 }
5060 5047
5061 5048
5062 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5049 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5063 Register result_reg = ToRegister(instr->result()); 5050 Register result_reg = ToRegister(instr->result());
5064 Register scratch1 = LCodeGen::scratch0(); 5051 Register scratch1 = LCodeGen::scratch0();
5065 DoubleRegister double_input = ToDoubleRegister(instr->value()); 5052 DoubleRegister double_input = ToDoubleRegister(instr->value());
5066 5053
5067 if (instr->truncating()) { 5054 if (instr->truncating()) {
5068 __ TruncateDoubleToI(result_reg, double_input); 5055 __ TruncateDoubleToI(result_reg, double_input);
5069 } else { 5056 } else {
5070 Register except_flag = LCodeGen::scratch1(); 5057 Register except_flag = LCodeGen::scratch1();
5071 5058
5072 __ EmitFPUTruncate(kRoundToMinusInf, 5059 __ EmitFPUTruncate(kRoundToMinusInf,
5073 result_reg, 5060 result_reg,
5074 double_input, 5061 double_input,
5075 scratch1, 5062 scratch1,
5076 double_scratch0(), 5063 double_scratch0(),
5077 except_flag, 5064 except_flag,
5078 kCheckForInexactConversion); 5065 kCheckForInexactConversion);
5079 5066
5080 // Deopt if the operation did not succeed (except_flag != 0). 5067 // Deopt if the operation did not succeed (except_flag != 0).
5081 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 5068 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
5082 5069
5083 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5070 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5084 Label done; 5071 Label done;
5085 __ Branch(&done, ne, result_reg, Operand(zero_reg)); 5072 __ Branch(&done, ne, result_reg, Operand(zero_reg));
5086 __ Mfhc1(scratch1, double_input); 5073 __ Mfhc1(scratch1, double_input);
5087 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 5074 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
5088 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 5075 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
5089 __ bind(&done); 5076 __ bind(&done);
5090 } 5077 }
5091 } 5078 }
5092 __ SmiTagCheckOverflow(result_reg, result_reg, scratch1); 5079 __ SmiTagCheckOverflow(result_reg, result_reg, scratch1);
5093 DeoptimizeIf(lt, instr->environment(), scratch1, Operand(zero_reg)); 5080 DeoptimizeIf(lt, instr, scratch1, Operand(zero_reg));
5094 } 5081 }
5095 5082
5096 5083
5097 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 5084 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5098 LOperand* input = instr->value(); 5085 LOperand* input = instr->value();
5099 __ SmiTst(ToRegister(input), at); 5086 __ SmiTst(ToRegister(input), at);
5100 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 5087 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
5101 } 5088 }
5102 5089
5103 5090
5104 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 5091 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
5105 if (!instr->hydrogen()->value()->type().IsHeapObject()) { 5092 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
5106 LOperand* input = instr->value(); 5093 LOperand* input = instr->value();
5107 __ SmiTst(ToRegister(input), at); 5094 __ SmiTst(ToRegister(input), at);
5108 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 5095 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
5109 } 5096 }
5110 } 5097 }
5111 5098
5112 5099
5113 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 5100 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5114 Register input = ToRegister(instr->value()); 5101 Register input = ToRegister(instr->value());
5115 Register scratch = scratch0(); 5102 Register scratch = scratch0();
5116 5103
5117 __ GetObjectType(input, scratch, scratch); 5104 __ GetObjectType(input, scratch, scratch);
5118 5105
5119 if (instr->hydrogen()->is_interval_check()) { 5106 if (instr->hydrogen()->is_interval_check()) {
5120 InstanceType first; 5107 InstanceType first;
5121 InstanceType last; 5108 InstanceType last;
5122 instr->hydrogen()->GetCheckInterval(&first, &last); 5109 instr->hydrogen()->GetCheckInterval(&first, &last);
5123 5110
5124 // If there is only one type in the interval check for equality. 5111 // If there is only one type in the interval check for equality.
5125 if (first == last) { 5112 if (first == last) {
5126 DeoptimizeIf(ne, instr->environment(), scratch, Operand(first)); 5113 DeoptimizeIf(ne, instr, scratch, Operand(first));
5127 } else { 5114 } else {
5128 DeoptimizeIf(lo, instr->environment(), scratch, Operand(first)); 5115 DeoptimizeIf(lo, instr, scratch, Operand(first));
5129 // Omit check for the last type. 5116 // Omit check for the last type.
5130 if (last != LAST_TYPE) { 5117 if (last != LAST_TYPE) {
5131 DeoptimizeIf(hi, instr->environment(), scratch, Operand(last)); 5118 DeoptimizeIf(hi, instr, scratch, Operand(last));
5132 } 5119 }
5133 } 5120 }
5134 } else { 5121 } else {
5135 uint8_t mask; 5122 uint8_t mask;
5136 uint8_t tag; 5123 uint8_t tag;
5137 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); 5124 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
5138 5125
5139 if (base::bits::IsPowerOfTwo32(mask)) { 5126 if (base::bits::IsPowerOfTwo32(mask)) {
5140 DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); 5127 DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
5141 __ And(at, scratch, mask); 5128 __ And(at, scratch, mask);
5142 DeoptimizeIf(tag == 0 ? ne : eq, instr->environment(), 5129 DeoptimizeIf(tag == 0 ? ne : eq, instr, at, Operand(zero_reg));
5143 at, Operand(zero_reg));
5144 } else { 5130 } else {
5145 __ And(scratch, scratch, Operand(mask)); 5131 __ And(scratch, scratch, Operand(mask));
5146 DeoptimizeIf(ne, instr->environment(), scratch, Operand(tag)); 5132 DeoptimizeIf(ne, instr, scratch, Operand(tag));
5147 } 5133 }
5148 } 5134 }
5149 } 5135 }
5150 5136
5151 5137
5152 void LCodeGen::DoCheckValue(LCheckValue* instr) { 5138 void LCodeGen::DoCheckValue(LCheckValue* instr) {
5153 Register reg = ToRegister(instr->value()); 5139 Register reg = ToRegister(instr->value());
5154 Handle<HeapObject> object = instr->hydrogen()->object().handle(); 5140 Handle<HeapObject> object = instr->hydrogen()->object().handle();
5155 AllowDeferredHandleDereference smi_check; 5141 AllowDeferredHandleDereference smi_check;
5156 if (isolate()->heap()->InNewSpace(*object)) { 5142 if (isolate()->heap()->InNewSpace(*object)) {
5157 Register reg = ToRegister(instr->value()); 5143 Register reg = ToRegister(instr->value());
5158 Handle<Cell> cell = isolate()->factory()->NewCell(object); 5144 Handle<Cell> cell = isolate()->factory()->NewCell(object);
5159 __ li(at, Operand(Handle<Object>(cell))); 5145 __ li(at, Operand(Handle<Object>(cell)));
5160 __ lw(at, FieldMemOperand(at, Cell::kValueOffset)); 5146 __ lw(at, FieldMemOperand(at, Cell::kValueOffset));
5161 DeoptimizeIf(ne, instr->environment(), reg, 5147 DeoptimizeIf(ne, instr, reg, Operand(at));
5162 Operand(at));
5163 } else { 5148 } else {
5164 DeoptimizeIf(ne, instr->environment(), reg, 5149 DeoptimizeIf(ne, instr, reg, Operand(object));
5165 Operand(object));
5166 } 5150 }
5167 } 5151 }
5168 5152
5169 5153
5170 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5154 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5171 { 5155 {
5172 PushSafepointRegistersScope scope(this); 5156 PushSafepointRegistersScope scope(this);
5173 __ push(object); 5157 __ push(object);
5174 __ mov(cp, zero_reg); 5158 __ mov(cp, zero_reg);
5175 __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); 5159 __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance);
5176 RecordSafepointWithRegisters( 5160 RecordSafepointWithRegisters(
5177 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); 5161 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5178 __ StoreToSafepointRegisterSlot(v0, scratch0()); 5162 __ StoreToSafepointRegisterSlot(v0, scratch0());
5179 } 5163 }
5180 __ SmiTst(scratch0(), at); 5164 __ SmiTst(scratch0(), at);
5181 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 5165 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
5182 } 5166 }
5183 5167
5184 5168
5185 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 5169 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5186 class DeferredCheckMaps FINAL : public LDeferredCode { 5170 class DeferredCheckMaps FINAL : public LDeferredCode {
5187 public: 5171 public:
5188 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) 5172 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5189 : LDeferredCode(codegen), instr_(instr), object_(object) { 5173 : LDeferredCode(codegen), instr_(instr), object_(object) {
5190 SetExit(check_maps()); 5174 SetExit(check_maps());
5191 } 5175 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5224 Label success; 5208 Label success;
5225 for (int i = 0; i < maps->size() - 1; i++) { 5209 for (int i = 0; i < maps->size() - 1; i++) {
5226 Handle<Map> map = maps->at(i).handle(); 5210 Handle<Map> map = maps->at(i).handle();
5227 __ CompareMapAndBranch(map_reg, map, &success, eq, &success); 5211 __ CompareMapAndBranch(map_reg, map, &success, eq, &success);
5228 } 5212 }
5229 Handle<Map> map = maps->at(maps->size() - 1).handle(); 5213 Handle<Map> map = maps->at(maps->size() - 1).handle();
5230 // Do the CompareMap() directly within the Branch() and DeoptimizeIf(). 5214 // Do the CompareMap() directly within the Branch() and DeoptimizeIf().
5231 if (instr->hydrogen()->HasMigrationTarget()) { 5215 if (instr->hydrogen()->HasMigrationTarget()) {
5232 __ Branch(deferred->entry(), ne, map_reg, Operand(map)); 5216 __ Branch(deferred->entry(), ne, map_reg, Operand(map));
5233 } else { 5217 } else {
5234 DeoptimizeIf(ne, instr->environment(), map_reg, Operand(map)); 5218 DeoptimizeIf(ne, instr, map_reg, Operand(map));
5235 } 5219 }
5236 5220
5237 __ bind(&success); 5221 __ bind(&success);
5238 } 5222 }
5239 5223
5240 5224
5241 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5225 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5242 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); 5226 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
5243 Register result_reg = ToRegister(instr->result()); 5227 Register result_reg = ToRegister(instr->result());
5244 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); 5228 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
(...skipping 17 matching lines...) Expand all
5262 5246
5263 // Both smi and heap number cases are handled. 5247 // Both smi and heap number cases are handled.
5264 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); 5248 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi);
5265 5249
5266 // Check for heap number 5250 // Check for heap number
5267 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 5251 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
5268 __ Branch(&heap_number, eq, scratch, Operand(factory()->heap_number_map())); 5252 __ Branch(&heap_number, eq, scratch, Operand(factory()->heap_number_map()));
5269 5253
5270 // Check for undefined. Undefined is converted to zero for clamping 5254 // Check for undefined. Undefined is converted to zero for clamping
5271 // conversions. 5255 // conversions.
5272 DeoptimizeIf(ne, instr->environment(), input_reg, 5256 DeoptimizeIf(ne, instr, input_reg, Operand(factory()->undefined_value()));
5273 Operand(factory()->undefined_value()));
5274 __ mov(result_reg, zero_reg); 5257 __ mov(result_reg, zero_reg);
5275 __ jmp(&done); 5258 __ jmp(&done);
5276 5259
5277 // Heap number 5260 // Heap number
5278 __ bind(&heap_number); 5261 __ bind(&heap_number);
5279 __ ldc1(double_scratch0(), FieldMemOperand(input_reg, 5262 __ ldc1(double_scratch0(), FieldMemOperand(input_reg,
5280 HeapNumber::kValueOffset)); 5263 HeapNumber::kValueOffset));
5281 __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg); 5264 __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg);
5282 __ jmp(&done); 5265 __ jmp(&done);
5283 5266
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
5687 Deoptimizer::BailoutType type = instr->hydrogen()->type(); 5670 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5688 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 5671 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
5689 // needed return address), even though the implementation of LAZY and EAGER is 5672 // needed return address), even though the implementation of LAZY and EAGER is
5690 // now identical. When LAZY is eventually completely folded into EAGER, remove 5673 // now identical. When LAZY is eventually completely folded into EAGER, remove
5691 // the special case below. 5674 // the special case below.
5692 if (info()->IsStub() && type == Deoptimizer::EAGER) { 5675 if (info()->IsStub() && type == Deoptimizer::EAGER) {
5693 type = Deoptimizer::LAZY; 5676 type = Deoptimizer::LAZY;
5694 } 5677 }
5695 5678
5696 Comment(";;; deoptimize: %s", instr->hydrogen()->reason()); 5679 Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
5697 DeoptimizeIf(al, instr->environment(), type, zero_reg, Operand(zero_reg)); 5680 DeoptimizeIf(al, instr, type, zero_reg, Operand(zero_reg));
5698 } 5681 }
5699 5682
5700 5683
5701 void LCodeGen::DoDummy(LDummy* instr) { 5684 void LCodeGen::DoDummy(LDummy* instr) {
5702 // Nothing to see here, move on! 5685 // Nothing to see here, move on!
5703 } 5686 }
5704 5687
5705 5688
5706 void LCodeGen::DoDummyUse(LDummyUse* instr) { 5689 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5707 // Nothing to see here, move on! 5690 // Nothing to see here, move on!
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
5778 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 5761 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
5779 5762
5780 GenerateOsrPrologue(); 5763 GenerateOsrPrologue();
5781 } 5764 }
5782 5765
5783 5766
5784 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { 5767 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
5785 Register result = ToRegister(instr->result()); 5768 Register result = ToRegister(instr->result());
5786 Register object = ToRegister(instr->object()); 5769 Register object = ToRegister(instr->object());
5787 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 5770 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
5788 DeoptimizeIf(eq, instr->environment(), object, Operand(at)); 5771 DeoptimizeIf(eq, instr, object, Operand(at));
5789 5772
5790 Register null_value = t1; 5773 Register null_value = t1;
5791 __ LoadRoot(null_value, Heap::kNullValueRootIndex); 5774 __ LoadRoot(null_value, Heap::kNullValueRootIndex);
5792 DeoptimizeIf(eq, instr->environment(), object, Operand(null_value)); 5775 DeoptimizeIf(eq, instr, object, Operand(null_value));
5793 5776
5794 __ And(at, object, kSmiTagMask); 5777 __ And(at, object, kSmiTagMask);
5795 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 5778 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
5796 5779
5797 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 5780 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
5798 __ GetObjectType(object, a1, a1); 5781 __ GetObjectType(object, a1, a1);
5799 DeoptimizeIf(le, instr->environment(), a1, Operand(LAST_JS_PROXY_TYPE)); 5782 DeoptimizeIf(le, instr, a1, Operand(LAST_JS_PROXY_TYPE));
5800 5783
5801 Label use_cache, call_runtime; 5784 Label use_cache, call_runtime;
5802 DCHECK(object.is(a0)); 5785 DCHECK(object.is(a0));
5803 __ CheckEnumCache(null_value, &call_runtime); 5786 __ CheckEnumCache(null_value, &call_runtime);
5804 5787
5805 __ lw(result, FieldMemOperand(object, HeapObject::kMapOffset)); 5788 __ lw(result, FieldMemOperand(object, HeapObject::kMapOffset));
5806 __ Branch(&use_cache); 5789 __ Branch(&use_cache);
5807 5790
5808 // Get the set of properties to enumerate. 5791 // Get the set of properties to enumerate.
5809 __ bind(&call_runtime); 5792 __ bind(&call_runtime);
5810 __ push(object); 5793 __ push(object);
5811 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); 5794 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
5812 5795
5813 __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); 5796 __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
5814 DCHECK(result.is(v0)); 5797 DCHECK(result.is(v0));
5815 __ LoadRoot(at, Heap::kMetaMapRootIndex); 5798 __ LoadRoot(at, Heap::kMetaMapRootIndex);
5816 DeoptimizeIf(ne, instr->environment(), a1, Operand(at)); 5799 DeoptimizeIf(ne, instr, a1, Operand(at));
5817 __ bind(&use_cache); 5800 __ bind(&use_cache);
5818 } 5801 }
5819 5802
5820 5803
5821 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { 5804 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
5822 Register map = ToRegister(instr->map()); 5805 Register map = ToRegister(instr->map());
5823 Register result = ToRegister(instr->result()); 5806 Register result = ToRegister(instr->result());
5824 Label load_cache, done; 5807 Label load_cache, done;
5825 __ EnumLength(result, map); 5808 __ EnumLength(result, map);
5826 __ Branch(&load_cache, ne, result, Operand(Smi::FromInt(0))); 5809 __ Branch(&load_cache, ne, result, Operand(Smi::FromInt(0)));
5827 __ li(result, Operand(isolate()->factory()->empty_fixed_array())); 5810 __ li(result, Operand(isolate()->factory()->empty_fixed_array()));
5828 __ jmp(&done); 5811 __ jmp(&done);
5829 5812
5830 __ bind(&load_cache); 5813 __ bind(&load_cache);
5831 __ LoadInstanceDescriptors(map, result); 5814 __ LoadInstanceDescriptors(map, result);
5832 __ lw(result, 5815 __ lw(result,
5833 FieldMemOperand(result, DescriptorArray::kEnumCacheOffset)); 5816 FieldMemOperand(result, DescriptorArray::kEnumCacheOffset));
5834 __ lw(result, 5817 __ lw(result,
5835 FieldMemOperand(result, FixedArray::SizeFor(instr->idx()))); 5818 FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
5836 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 5819 DeoptimizeIf(eq, instr, result, Operand(zero_reg));
5837 5820
5838 __ bind(&done); 5821 __ bind(&done);
5839 } 5822 }
5840 5823
5841 5824
5842 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { 5825 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5843 Register object = ToRegister(instr->value()); 5826 Register object = ToRegister(instr->value());
5844 Register map = ToRegister(instr->map()); 5827 Register map = ToRegister(instr->map());
5845 __ lw(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset)); 5828 __ lw(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset));
5846 DeoptimizeIf(ne, instr->environment(), map, Operand(scratch0())); 5829 DeoptimizeIf(ne, instr, map, Operand(scratch0()));
5847 } 5830 }
5848 5831
5849 5832
5850 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 5833 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
5851 Register result, 5834 Register result,
5852 Register object, 5835 Register object,
5853 Register index) { 5836 Register index) {
5854 PushSafepointRegistersScope scope(this); 5837 PushSafepointRegistersScope scope(this);
5855 __ Push(object, index); 5838 __ Push(object, index);
5856 __ mov(cp, zero_reg); 5839 __ mov(cp, zero_reg);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
5932 __ li(at, scope_info); 5915 __ li(at, scope_info);
5933 __ Push(at, ToRegister(instr->function())); 5916 __ Push(at, ToRegister(instr->function()));
5934 CallRuntime(Runtime::kPushBlockContext, 2, instr); 5917 CallRuntime(Runtime::kPushBlockContext, 2, instr);
5935 RecordSafepoint(Safepoint::kNoLazyDeopt); 5918 RecordSafepoint(Safepoint::kNoLazyDeopt);
5936 } 5919 }
5937 5920
5938 5921
5939 #undef __ 5922 #undef __
5940 5923
5941 } } // namespace v8::internal 5924 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mips/lithium-codegen-mips.h ('k') | src/mips64/lithium-codegen-mips64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698