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

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

Issue 7148018: ARM: Improve register allocation and constraints.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 6 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 866
867 867
868 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 868 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
869 // Nothing to do. 869 // Nothing to do.
870 } 870 }
871 871
872 872
873 void LCodeGen::DoModI(LModI* instr) { 873 void LCodeGen::DoModI(LModI* instr) {
874 if (instr->hydrogen()->HasPowerOf2Divisor()) { 874 if (instr->hydrogen()->HasPowerOf2Divisor()) {
875 Register dividend = ToRegister(instr->InputAt(0)); 875 Register dividend = ToRegister(instr->InputAt(0));
876 Register result = ToRegister(instr->result());
876 877
877 int32_t divisor = 878 int32_t divisor =
878 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 879 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
879 880
880 if (divisor < 0) divisor = -divisor; 881 if (divisor < 0) divisor = -divisor;
881 882
882 Label positive_dividend, done; 883 Label positive_dividend, done;
883 __ cmp(dividend, Operand(0)); 884 __ cmp(dividend, Operand(0));
884 __ b(pl, &positive_dividend); 885 __ b(pl, &positive_dividend);
885 __ rsb(dividend, dividend, Operand(0)); 886 __ rsb(result, dividend, Operand(0));
886 __ and_(dividend, dividend, Operand(divisor - 1)); 887 __ and_(dividend, result, Operand(divisor - 1), SetCC);
887 __ rsb(dividend, dividend, Operand(0), SetCC);
888 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 888 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
889 __ b(ne, &done); 889 DeoptimizeIf(eq, instr->environment());
890 DeoptimizeIf(al, instr->environment());
891 } 890 }
891 __ rsb(result, dividend, Operand(0));
892 __ b(&done);
892 __ bind(&positive_dividend); 893 __ bind(&positive_dividend);
893 __ and_(dividend, dividend, Operand(divisor - 1)); 894 __ and_(result, dividend, Operand(divisor - 1));
894 __ bind(&done); 895 __ bind(&done);
895 return; 896 return;
896 } 897 }
897 898
898 // These registers hold untagged 32 bit values. 899 // These registers hold untagged 32 bit values.
899 Register left = ToRegister(instr->InputAt(0)); 900 Register left = ToRegister(instr->InputAt(0));
900 Register right = ToRegister(instr->InputAt(1)); 901 Register right = ToRegister(instr->InputAt(1));
901 Register result = ToRegister(instr->result()); 902 Register result = ToRegister(instr->result());
902 903
903 Register scratch = scratch0(); 904 Register scratch = scratch0();
904 Register scratch2 = ToRegister(instr->TempAt(0)); 905 Register scratch2 = ToRegister(instr->TempAt(0));
905 DwVfpRegister dividend = ToDoubleRegister(instr->TempAt(1)); 906 DwVfpRegister dividend = ToDoubleRegister(instr->TempAt(1));
906 DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2)); 907 DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2));
907 DwVfpRegister quotient = double_scratch0(); 908 DwVfpRegister quotient = double_scratch0();
908 909
909 ASSERT(result.is(left));
910
911 ASSERT(!dividend.is(divisor)); 910 ASSERT(!dividend.is(divisor));
912 ASSERT(!dividend.is(quotient)); 911 ASSERT(!dividend.is(quotient));
913 ASSERT(!divisor.is(quotient)); 912 ASSERT(!divisor.is(quotient));
914 ASSERT(!scratch.is(left)); 913 ASSERT(!scratch.is(left));
915 ASSERT(!scratch.is(right)); 914 ASSERT(!scratch.is(right));
916 ASSERT(!scratch.is(result)); 915 ASSERT(!scratch.is(result));
917 916
918 Label done, vfp_modulo, both_positive, right_negative; 917 Label done, vfp_modulo, both_positive, right_negative;
919 918
920 // Check for x % 0. 919 // Check for x % 0.
921 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 920 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
922 __ cmp(right, Operand(0)); 921 __ cmp(right, Operand(0));
923 DeoptimizeIf(eq, instr->environment()); 922 DeoptimizeIf(eq, instr->environment());
924 } 923 }
925 924
925 __ Move(result, left);
926
926 // (0 % x) must yield 0 (if x is finite, which is the case here). 927 // (0 % x) must yield 0 (if x is finite, which is the case here).
927 __ cmp(left, Operand(0)); 928 __ cmp(left, Operand(0));
928 __ b(eq, &done); 929 __ b(eq, &done);
929 // Preload right in a vfp register. 930 // Preload right in a vfp register.
930 __ vmov(divisor.low(), right); 931 __ vmov(divisor.low(), right);
931 __ b(lt, &vfp_modulo); 932 __ b(lt, &vfp_modulo);
932 933
933 __ cmp(left, Operand(right)); 934 __ cmp(left, Operand(right));
934 __ b(lt, &done); 935 __ b(lt, &done);
935 936
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 __ CallStub(&stub); 1112 __ CallStub(&stub);
1112 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), 1113 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
1113 0, 1114 0,
1114 Safepoint::kNoDeoptimizationIndex); 1115 Safepoint::kNoDeoptimizationIndex);
1115 // Overwrite the stored value of r0 with the result of the stub. 1116 // Overwrite the stored value of r0 with the result of the stub.
1116 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0); 1117 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0);
1117 } 1118 }
1118 1119
1119 1120
1120 void LCodeGen::DoMulI(LMulI* instr) { 1121 void LCodeGen::DoMulI(LMulI* instr) {
1121 ASSERT(instr->result()->Equals(instr->InputAt(0)));
1122 Register scratch = scratch0(); 1122 Register scratch = scratch0();
Søren Thygesen Gjesse 2011/06/16 09:38:07 Maybe add a comment that result might alias left (
Alexandre 2011/06/16 12:58:48 Done.
1123 Register result = ToRegister(instr->result()); 1123 Register result = ToRegister(instr->result());
1124 Register left = ToRegister(instr->InputAt(0)); 1124 Register left = ToRegister(instr->InputAt(0));
1125 LOperand* right_op = instr->InputAt(1); 1125 LOperand* right_op = instr->InputAt(1);
1126 1126
1127 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1127 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1128 bool bailout_on_minus_zero = 1128 bool bailout_on_minus_zero =
1129 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1129 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1130 1130
1131 if (right_op->IsConstantOperand() && !can_overflow) { 1131 if (right_op->IsConstantOperand() && !can_overflow) {
1132 // Use optimized code for specific constants. 1132 // Use optimized code for specific constants.
(...skipping 13 matching lines...) Expand all
1146 case 0: 1146 case 0:
1147 if (bailout_on_minus_zero) { 1147 if (bailout_on_minus_zero) {
1148 // If left is strictly negative and the constant is null, the 1148 // If left is strictly negative and the constant is null, the
1149 // result is -0. Deoptimize if required, otherwise return 0. 1149 // result is -0. Deoptimize if required, otherwise return 0.
1150 __ cmp(left, Operand(0)); 1150 __ cmp(left, Operand(0));
1151 DeoptimizeIf(mi, instr->environment()); 1151 DeoptimizeIf(mi, instr->environment());
1152 } 1152 }
1153 __ mov(result, Operand(0)); 1153 __ mov(result, Operand(0));
1154 break; 1154 break;
1155 case 1: 1155 case 1:
1156 // Nothing to do. 1156 __ Move(result, left);
1157 break; 1157 break;
1158 default: 1158 default:
1159 // Multiplying by powers of two and powers of two plus or minus 1159 // Multiplying by powers of two and powers of two plus or minus
1160 // one can be done faster with shifted operands. 1160 // one can be done faster with shifted operands.
1161 // For other constants we emit standard code. 1161 // For other constants we emit standard code.
1162 int32_t mask = constant >> 31; 1162 int32_t mask = constant >> 31;
1163 uint32_t constant_abs = (constant + mask) ^ mask; 1163 uint32_t constant_abs = (constant + mask) ^ mask;
1164 1164
1165 if (IsPowerOf2(constant_abs) || 1165 if (IsPowerOf2(constant_abs) ||
1166 IsPowerOf2(constant_abs - 1) || 1166 IsPowerOf2(constant_abs - 1) ||
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 __ b(ne, &done); 1208 __ b(ne, &done);
1209 __ cmp(ToRegister(instr->TempAt(0)), Operand(0)); 1209 __ cmp(ToRegister(instr->TempAt(0)), Operand(0));
1210 DeoptimizeIf(mi, instr->environment()); 1210 DeoptimizeIf(mi, instr->environment());
1211 __ bind(&done); 1211 __ bind(&done);
1212 } 1212 }
1213 } 1213 }
1214 } 1214 }
1215 1215
1216 1216
1217 void LCodeGen::DoBitI(LBitI* instr) { 1217 void LCodeGen::DoBitI(LBitI* instr) {
1218 LOperand* left = instr->InputAt(0); 1218 LOperand* left_op = instr->InputAt(0);
1219 LOperand* right = instr->InputAt(1); 1219 LOperand* right_op = instr->InputAt(1);
1220 ASSERT(left->Equals(instr->result())); 1220 ASSERT(left_op->IsRegister());
1221 ASSERT(left->IsRegister()); 1221 Register left = ToRegister(left_op);
1222 Register result = ToRegister(left); 1222 Register result = ToRegister(instr->result());
1223 Operand right_operand(no_reg); 1223 Operand right(no_reg);
1224 1224
1225 if (right->IsStackSlot() || right->IsArgument()) { 1225 if (right_op->IsStackSlot() || right_op->IsArgument()) {
1226 Register right_reg = EmitLoadRegister(right, ip); 1226 right = Operand(EmitLoadRegister(right_op, ip));
1227 right_operand = Operand(right_reg);
1228 } else { 1227 } else {
1229 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1228 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
1230 right_operand = ToOperand(right); 1229 right = ToOperand(right_op);
1231 } 1230 }
1232 1231
1233 switch (instr->op()) { 1232 switch (instr->op()) {
1234 case Token::BIT_AND: 1233 case Token::BIT_AND:
1235 __ and_(result, ToRegister(left), right_operand); 1234 __ and_(result, left, right);
1236 break; 1235 break;
1237 case Token::BIT_OR: 1236 case Token::BIT_OR:
1238 __ orr(result, ToRegister(left), right_operand); 1237 __ orr(result, left, right);
1239 break; 1238 break;
1240 case Token::BIT_XOR: 1239 case Token::BIT_XOR:
1241 __ eor(result, ToRegister(left), right_operand); 1240 __ eor(result, left, right);
1242 break; 1241 break;
1243 default: 1242 default:
1244 UNREACHABLE(); 1243 UNREACHABLE();
1245 break; 1244 break;
1246 } 1245 }
1247 } 1246 }
1248 1247
1249 1248
1250 void LCodeGen::DoShiftI(LShiftI* instr) { 1249 void LCodeGen::DoShiftI(LShiftI* instr) {
Søren Thygesen Gjesse 2011/06/16 09:38:07 Please add a comment that both left and right are
Alexandre 2011/06/16 12:58:48 Done.
1250 LOperand* right_op = instr->InputAt(1);
1251 Register left = ToRegister(instr->InputAt(0));
1252 Register result = ToRegister(instr->result());
1251 Register scratch = scratch0(); 1253 Register scratch = scratch0();
1252 LOperand* left = instr->InputAt(0); 1254 if (right_op->IsRegister()) {
1253 LOperand* right = instr->InputAt(1); 1255 // Mask the right_op operand.
1254 ASSERT(left->Equals(instr->result())); 1256 __ and_(scratch, ToRegister(right_op), Operand(0x1F));
1255 ASSERT(left->IsRegister());
1256 Register result = ToRegister(left);
1257 if (right->IsRegister()) {
1258 // Mask the right operand.
1259 __ and_(scratch, ToRegister(right), Operand(0x1F));
1260 switch (instr->op()) { 1257 switch (instr->op()) {
1261 case Token::SAR: 1258 case Token::SAR:
1262 __ mov(result, Operand(result, ASR, scratch)); 1259 __ mov(result, Operand(left, ASR, scratch));
1263 break; 1260 break;
1264 case Token::SHR: 1261 case Token::SHR:
1265 if (instr->can_deopt()) { 1262 if (instr->can_deopt()) {
1266 __ mov(result, Operand(result, LSR, scratch), SetCC); 1263 __ mov(result, Operand(left, LSR, scratch), SetCC);
1267 DeoptimizeIf(mi, instr->environment()); 1264 DeoptimizeIf(mi, instr->environment());
1268 } else { 1265 } else {
1269 __ mov(result, Operand(result, LSR, scratch)); 1266 __ mov(result, Operand(left, LSR, scratch));
1270 } 1267 }
1271 break; 1268 break;
1272 case Token::SHL: 1269 case Token::SHL:
1273 __ mov(result, Operand(result, LSL, scratch)); 1270 __ mov(result, Operand(left, LSL, scratch));
1274 break; 1271 break;
1275 default: 1272 default:
1276 UNREACHABLE(); 1273 UNREACHABLE();
1277 break; 1274 break;
1278 } 1275 }
1279 } else { 1276 } else {
1280 int value = ToInteger32(LConstantOperand::cast(right)); 1277 // Mask the right_op operand.
1278 int value = ToInteger32(LConstantOperand::cast(right_op));
1281 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); 1279 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
1282 switch (instr->op()) { 1280 switch (instr->op()) {
1283 case Token::SAR: 1281 case Token::SAR:
1284 if (shift_count != 0) { 1282 if (shift_count != 0) {
1285 __ mov(result, Operand(result, ASR, shift_count)); 1283 __ mov(result, Operand(left, ASR, shift_count));
1286 } 1284 }
1287 break; 1285 break;
1288 case Token::SHR: 1286 case Token::SHR:
1289 if (shift_count == 0 && instr->can_deopt()) { 1287 if (shift_count == 0 && instr->can_deopt()) {
1290 __ tst(result, Operand(0x80000000)); 1288 __ tst(left, Operand(0x80000000));
1291 DeoptimizeIf(ne, instr->environment()); 1289 DeoptimizeIf(ne, instr->environment());
1292 } else { 1290 } else {
1293 __ mov(result, Operand(result, LSR, shift_count)); 1291 __ mov(result, Operand(left, LSR, shift_count));
1294 } 1292 }
1295 break; 1293 break;
1296 case Token::SHL: 1294 case Token::SHL:
1297 if (shift_count != 0) { 1295 if (shift_count != 0) {
1298 __ mov(result, Operand(result, LSL, shift_count)); 1296 __ mov(result, Operand(left, LSL, shift_count));
1299 } 1297 }
1300 break; 1298 break;
1301 default: 1299 default:
1302 UNREACHABLE(); 1300 UNREACHABLE();
1303 break; 1301 break;
1304 } 1302 }
1303 if (shift_count == 0) __ Move(result, left);
Søren Thygesen Gjesse 2011/06/16 09:38:07 I think this will be easier to read if you mode th
Alexandre 2011/06/16 12:58:48 The code for SHR was not optimal when ((shift_coun
1305 } 1304 }
1306 } 1305 }
1307 1306
1308 1307
1309 void LCodeGen::DoSubI(LSubI* instr) { 1308 void LCodeGen::DoSubI(LSubI* instr) {
1310 LOperand* left = instr->InputAt(0); 1309 LOperand* left = instr->InputAt(0);
1311 LOperand* right = instr->InputAt(1); 1310 LOperand* right = instr->InputAt(1);
1312 ASSERT(left->Equals(instr->result())); 1311 LOperand* result = instr->result();
1313 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1312 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1314 SBit set_cond = can_overflow ? SetCC : LeaveCC; 1313 SBit set_cond = can_overflow ? SetCC : LeaveCC;
1315 1314
1316 if (right->IsStackSlot() || right->IsArgument()) { 1315 if (right->IsStackSlot() || right->IsArgument()) {
1317 Register right_reg = EmitLoadRegister(right, ip); 1316 Register right_reg = EmitLoadRegister(right, ip);
1318 __ sub(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond); 1317 __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
1319 } else { 1318 } else {
1320 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1319 ASSERT(right->IsRegister() || right->IsConstantOperand());
1321 __ sub(ToRegister(left), ToRegister(left), ToOperand(right), set_cond); 1320 __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
1322 } 1321 }
1323 1322
1324 if (can_overflow) { 1323 if (can_overflow) {
1325 DeoptimizeIf(vs, instr->environment()); 1324 DeoptimizeIf(vs, instr->environment());
1326 } 1325 }
1327 } 1326 }
1328 1327
1329 1328
1330 void LCodeGen::DoConstantI(LConstantI* instr) { 1329 void LCodeGen::DoConstantI(LConstantI* instr) {
1331 ASSERT(instr->result()->IsRegister()); 1330 ASSERT(instr->result()->IsRegister());
1332 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1331 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1333 } 1332 }
1334 1333
1335 1334
1336 void LCodeGen::DoConstantD(LConstantD* instr) { 1335 void LCodeGen::DoConstantD(LConstantD* instr) {
1337 ASSERT(instr->result()->IsDoubleRegister()); 1336 ASSERT(instr->result()->IsDoubleRegister());
1338 DwVfpRegister result = ToDoubleRegister(instr->result()); 1337 DwVfpRegister result = ToDoubleRegister(instr->result());
1339 double v = instr->value(); 1338 double v = instr->value();
1340 __ vmov(result, v); 1339 __ Vmov(result, v);
1341 } 1340 }
1342 1341
1343 1342
1344 void LCodeGen::DoConstantT(LConstantT* instr) { 1343 void LCodeGen::DoConstantT(LConstantT* instr) {
1345 ASSERT(instr->result()->IsRegister()); 1344 ASSERT(instr->result()->IsRegister());
1346 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1345 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1347 } 1346 }
1348 1347
1349 1348
1350 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1349 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
(...skipping 14 matching lines...) Expand all
1365 Register result = ToRegister(instr->result()); 1364 Register result = ToRegister(instr->result());
1366 Register array = ToRegister(instr->InputAt(0)); 1365 Register array = ToRegister(instr->InputAt(0));
1367 __ ldr(result, FieldMemOperand(array, FixedArray::kLengthOffset)); 1366 __ ldr(result, FieldMemOperand(array, FixedArray::kLengthOffset));
1368 } 1367 }
1369 1368
1370 1369
1371 void LCodeGen::DoValueOf(LValueOf* instr) { 1370 void LCodeGen::DoValueOf(LValueOf* instr) {
1372 Register input = ToRegister(instr->InputAt(0)); 1371 Register input = ToRegister(instr->InputAt(0));
1373 Register result = ToRegister(instr->result()); 1372 Register result = ToRegister(instr->result());
1374 Register map = ToRegister(instr->TempAt(0)); 1373 Register map = ToRegister(instr->TempAt(0));
1375 ASSERT(input.is(result));
1376 Label done; 1374 Label done;
1377 1375
1378 // If the object is a smi return the object. 1376 // If the object is a smi return the object.
1379 __ tst(input, Operand(kSmiTagMask)); 1377 __ tst(input, Operand(kSmiTagMask));
1378 __ Move(result, input);
1380 __ b(eq, &done); 1379 __ b(eq, &done);
1381 1380
1382 // If the object is not a value type, return the object. 1381 // If the object is not a value type, return the object.
1383 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); 1382 __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
1384 __ b(ne, &done); 1383 __ b(ne, &done);
1385 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); 1384 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset));
1386 1385
1387 __ bind(&done); 1386 __ bind(&done);
1388 } 1387 }
1389 1388
1390 1389
1391 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1390 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1392 LOperand* input = instr->InputAt(0); 1391 Register input = ToRegister(instr->InputAt(0));
1393 ASSERT(input->Equals(instr->result())); 1392 Register result = ToRegister(instr->result());
1394 __ mvn(ToRegister(input), Operand(ToRegister(input))); 1393 __ mvn(input, Operand(input));
1395 } 1394 }
1396 1395
1397 1396
1398 void LCodeGen::DoThrow(LThrow* instr) { 1397 void LCodeGen::DoThrow(LThrow* instr) {
1399 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); 1398 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
1400 __ push(input_reg); 1399 __ push(input_reg);
1401 CallRuntime(Runtime::kThrow, 1, instr); 1400 CallRuntime(Runtime::kThrow, 1, instr);
1402 1401
1403 if (FLAG_debug_code) { 1402 if (FLAG_debug_code) {
1404 __ stop("Unreachable code."); 1403 __ stop("Unreachable code.");
1405 } 1404 }
1406 } 1405 }
1407 1406
1408 1407
1409 void LCodeGen::DoAddI(LAddI* instr) { 1408 void LCodeGen::DoAddI(LAddI* instr) {
1410 LOperand* left = instr->InputAt(0); 1409 LOperand* left = instr->InputAt(0);
1411 LOperand* right = instr->InputAt(1); 1410 LOperand* right = instr->InputAt(1);
1412 ASSERT(left->Equals(instr->result())); 1411 LOperand* result = instr->result();
1413 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1412 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1414 SBit set_cond = can_overflow ? SetCC : LeaveCC; 1413 SBit set_cond = can_overflow ? SetCC : LeaveCC;
1415 1414
1416 if (right->IsStackSlot() || right->IsArgument()) { 1415 if (right->IsStackSlot() || right->IsArgument()) {
1417 Register right_reg = EmitLoadRegister(right, ip); 1416 Register right_reg = EmitLoadRegister(right, ip);
1418 __ add(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond); 1417 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
1419 } else { 1418 } else {
1420 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1419 ASSERT(right->IsRegister() || right->IsConstantOperand());
1421 __ add(ToRegister(left), ToRegister(left), ToOperand(right), set_cond); 1420 __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
1422 } 1421 }
1423 1422
1424 if (can_overflow) { 1423 if (can_overflow) {
1425 DeoptimizeIf(vs, instr->environment()); 1424 DeoptimizeIf(vs, instr->environment());
1426 } 1425 }
1427 } 1426 }
1428 1427
1429 1428
1430 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1429 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1431 DoubleRegister left = ToDoubleRegister(instr->InputAt(0)); 1430 DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
1432 DoubleRegister right = ToDoubleRegister(instr->InputAt(1)); 1431 DoubleRegister right = ToDoubleRegister(instr->InputAt(1));
1432 DoubleRegister result = ToDoubleRegister(instr->result());
1433 switch (instr->op()) { 1433 switch (instr->op()) {
1434 case Token::ADD: 1434 case Token::ADD:
1435 __ vadd(left, left, right); 1435 __ vadd(result, left, right);
1436 break; 1436 break;
1437 case Token::SUB: 1437 case Token::SUB:
1438 __ vsub(left, left, right); 1438 __ vsub(result, left, right);
1439 break; 1439 break;
1440 case Token::MUL: 1440 case Token::MUL:
1441 __ vmul(left, left, right); 1441 __ vmul(result, left, right);
1442 break; 1442 break;
1443 case Token::DIV: 1443 case Token::DIV:
1444 __ vdiv(left, left, right); 1444 __ vdiv(result, left, right);
1445 break; 1445 break;
1446 case Token::MOD: { 1446 case Token::MOD: {
1447 // Save r0-r3 on the stack. 1447 // Save r0-r3 on the stack.
1448 __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); 1448 __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
1449 1449
1450 __ PrepareCallCFunction(0, 2, scratch0()); 1450 __ PrepareCallCFunction(0, 2, scratch0());
1451 __ SetCallCDoubleArguments(left, right); 1451 __ SetCallCDoubleArguments(left, right);
1452 __ CallCFunction( 1452 __ CallCFunction(
1453 ExternalReference::double_fp_operation(Token::MOD, isolate()), 1453 ExternalReference::double_fp_operation(Token::MOD, isolate()),
1454 0, 2); 1454 0, 2);
1455 // Move the result in the double result register. 1455 // Move the result in the double result register.
1456 __ GetCFunctionDoubleResult(ToDoubleRegister(instr->result())); 1456 __ GetCFunctionDoubleResult(result);
1457 1457
1458 // Restore r0-r3. 1458 // Restore r0-r3.
1459 __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); 1459 __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
1460 break; 1460 break;
1461 } 1461 }
1462 default: 1462 default:
1463 UNREACHABLE(); 1463 UNREACHABLE();
1464 break; 1464 break;
1465 } 1465 }
1466 } 1466 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1540 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 1540 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
1541 __ cmp(reg, ip); 1541 __ cmp(reg, ip);
1542 __ b(eq, false_label); 1542 __ b(eq, false_label);
1543 __ cmp(reg, Operand(0)); 1543 __ cmp(reg, Operand(0));
1544 __ b(eq, false_label); 1544 __ b(eq, false_label);
1545 __ tst(reg, Operand(kSmiTagMask)); 1545 __ tst(reg, Operand(kSmiTagMask));
1546 __ b(eq, true_label); 1546 __ b(eq, true_label);
1547 1547
1548 // Test double values. Zero and NaN are false. 1548 // Test double values. Zero and NaN are false.
1549 Label call_stub; 1549 Label call_stub;
1550 DoubleRegister dbl_scratch = d0; 1550 DoubleRegister dbl_scratch = double_scratch0();
1551 Register scratch = scratch0(); 1551 Register scratch = scratch0();
1552 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); 1552 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
1553 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 1553 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
1554 __ cmp(scratch, Operand(ip)); 1554 __ cmp(scratch, Operand(ip));
1555 __ b(ne, &call_stub); 1555 __ b(ne, &call_stub);
1556 __ sub(ip, reg, Operand(kHeapObjectTag)); 1556 __ sub(ip, reg, Operand(kHeapObjectTag));
1557 __ vldr(dbl_scratch, ip, HeapNumber::kValueOffset); 1557 __ vldr(dbl_scratch, ip, HeapNumber::kValueOffset);
1558 __ VFPCompareAndLoadFlags(dbl_scratch, 0.0, scratch); 1558 __ VFPCompareAndLoadFlags(dbl_scratch, 0.0, scratch);
1559 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); 1559 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
1560 __ b(ne, false_label); 1560 __ b(ne, false_label);
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after
2585 __ add(length, length, Operand(1)); 2585 __ add(length, length, Operand(1));
2586 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); 2586 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
2587 } 2587 }
2588 2588
2589 2589
2590 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2590 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2591 Register elements = ToRegister(instr->elements()); 2591 Register elements = ToRegister(instr->elements());
2592 Register key = EmitLoadRegister(instr->key(), scratch0()); 2592 Register key = EmitLoadRegister(instr->key(), scratch0());
2593 Register result = ToRegister(instr->result()); 2593 Register result = ToRegister(instr->result());
2594 Register scratch = scratch0(); 2594 Register scratch = scratch0();
2595 ASSERT(result.is(elements));
2596 2595
2597 // Load the result. 2596 // Load the result.
2598 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 2597 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
2599 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 2598 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize));
2600 2599
2601 // Check for the hole value. 2600 // Check for the hole value.
2602 if (instr->hydrogen()->RequiresHoleCheck()) { 2601 if (instr->hydrogen()->RequiresHoleCheck()) {
2603 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 2602 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
2604 __ cmp(result, scratch); 2603 __ cmp(result, scratch);
2605 DeoptimizeIf(eq, instr->environment()); 2604 DeoptimizeIf(eq, instr->environment());
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
2904 ASSERT(ToRegister(instr->result()).is(r0)); 2903 ASSERT(ToRegister(instr->result()).is(r0));
2905 __ mov(r1, Operand(instr->function())); 2904 __ mov(r1, Operand(instr->function()));
2906 CallKnownFunction(instr->function(), 2905 CallKnownFunction(instr->function(),
2907 instr->arity(), 2906 instr->arity(),
2908 instr, 2907 instr,
2909 CALL_AS_METHOD); 2908 CALL_AS_METHOD);
2910 } 2909 }
2911 2910
2912 2911
2913 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2912 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2914 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2915 Register input = ToRegister(instr->InputAt(0)); 2913 Register input = ToRegister(instr->InputAt(0));
2914 Register result = ToRegister(instr->result());
2916 Register scratch = scratch0(); 2915 Register scratch = scratch0();
2917 2916
2918 // Deoptimize if not a heap number. 2917 // Deoptimize if not a heap number.
2919 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 2918 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
2920 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 2919 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
2921 __ cmp(scratch, Operand(ip)); 2920 __ cmp(scratch, Operand(ip));
2922 DeoptimizeIf(ne, instr->environment()); 2921 DeoptimizeIf(ne, instr->environment());
2923 2922
2924 Label done; 2923 Label done;
2925 Register exponent = scratch0(); 2924 Register exponent = scratch0();
2926 scratch = no_reg; 2925 scratch = no_reg;
2927 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 2926 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2928 // Check the sign of the argument. If the argument is positive, just 2927 // Check the sign of the argument. If the argument is positive, just
2929 // return it. We do not need to patch the stack since |input| and 2928 // return it.
2930 // |result| are the same register and |input| would be restored
2931 // unchanged by popping safepoint registers.
2932 __ tst(exponent, Operand(HeapNumber::kSignMask)); 2929 __ tst(exponent, Operand(HeapNumber::kSignMask));
2930 // Move the input to the result if necessary.
2931 __ Move(result, input);
2933 __ b(eq, &done); 2932 __ b(eq, &done);
2934 2933
2935 // Input is negative. Reverse its sign. 2934 // Input is negative. Reverse its sign.
2936 // Preserve the value of all registers. 2935 // Preserve the value of all registers.
2937 { 2936 {
2938 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 2937 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2939 2938
2940 // Registers were saved at the safepoint, so we can use 2939 // Registers were saved at the safepoint, so we can use
2941 // many scratch registers. 2940 // many scratch registers.
2942 Register tmp1 = input.is(r1) ? r0 : r1; 2941 Register tmp1 = input.is(r1) ? r0 : r1;
(...skipping 19 matching lines...) Expand all
2962 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 2961 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2963 2962
2964 __ bind(&allocated); 2963 __ bind(&allocated);
2965 // exponent: floating point exponent value. 2964 // exponent: floating point exponent value.
2966 // tmp1: allocated heap number. 2965 // tmp1: allocated heap number.
2967 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask)); 2966 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask));
2968 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset)); 2967 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset));
2969 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); 2968 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
2970 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 2969 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
2971 2970
2972 __ StoreToSafepointRegisterSlot(tmp1, input); 2971 __ StoreToSafepointRegisterSlot(tmp1, result);
2973 } 2972 }
2974 2973
2975 __ bind(&done); 2974 __ bind(&done);
2976 } 2975 }
2977 2976
2978 2977
2979 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 2978 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
2980 Register input = ToRegister(instr->InputAt(0)); 2979 Register input = ToRegister(instr->InputAt(0));
2980 Register result = ToRegister(instr->result());
2981 __ cmp(input, Operand(0)); 2981 __ cmp(input, Operand(0));
2982 __ Move(result, input);
2982 // We can make rsb conditional because the previous cmp instruction 2983 // We can make rsb conditional because the previous cmp instruction
2983 // will clear the V (overflow) flag and rsb won't set this flag 2984 // will clear the V (overflow) flag and rsb won't set this flag
2984 // if input is positive. 2985 // if input is positive.
2985 __ rsb(input, input, Operand(0), SetCC, mi); 2986 __ rsb(result, input, Operand(0), SetCC, mi);
2986 // Deoptimize on overflow. 2987 // Deoptimize on overflow.
2987 DeoptimizeIf(vs, instr->environment()); 2988 DeoptimizeIf(vs, instr->environment());
2988 } 2989 }
2989 2990
2990 2991
2991 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 2992 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
2992 // Class for deferred case. 2993 // Class for deferred case.
2993 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 2994 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
2994 public: 2995 public:
2995 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 2996 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
2996 LUnaryMathOperation* instr) 2997 LUnaryMathOperation* instr)
2997 : LDeferredCode(codegen), instr_(instr) { } 2998 : LDeferredCode(codegen), instr_(instr) { }
2998 virtual void Generate() { 2999 virtual void Generate() {
2999 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3000 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3000 } 3001 }
3001 private: 3002 private:
3002 LUnaryMathOperation* instr_; 3003 LUnaryMathOperation* instr_;
3003 }; 3004 };
3004 3005
3005 ASSERT(instr->InputAt(0)->Equals(instr->result()));
3006 Representation r = instr->hydrogen()->value()->representation(); 3006 Representation r = instr->hydrogen()->value()->representation();
3007 if (r.IsDouble()) { 3007 if (r.IsDouble()) {
3008 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0)); 3008 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0));
3009 __ vabs(input, input); 3009 DwVfpRegister result = ToDoubleRegister(instr->result());
3010 __ vabs(result, input);
3010 } else if (r.IsInteger32()) { 3011 } else if (r.IsInteger32()) {
3011 EmitIntegerMathAbs(instr); 3012 EmitIntegerMathAbs(instr);
3012 } else { 3013 } else {
3013 // Representation is tagged. 3014 // Representation is tagged.
3014 DeferredMathAbsTaggedHeapNumber* deferred = 3015 DeferredMathAbsTaggedHeapNumber* deferred =
3015 new DeferredMathAbsTaggedHeapNumber(this, instr); 3016 new DeferredMathAbsTaggedHeapNumber(this, instr);
3016 Register input = ToRegister(instr->InputAt(0)); 3017 Register input = ToRegister(instr->InputAt(0));
3017 // Smi check. 3018 // Smi check.
3018 __ JumpIfNotSmi(input, deferred->entry()); 3019 __ JumpIfNotSmi(input, deferred->entry());
3019 // If smi, handle it directly. 3020 // If smi, handle it directly.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3077 } 3078 }
3078 3079
3079 // The following conversion will not work with numbers 3080 // The following conversion will not work with numbers
3080 // outside of ]-2^32, 2^32[. 3081 // outside of ]-2^32, 2^32[.
3081 __ cmp(scratch2, Operand(HeapNumber::kExponentBias + 32)); 3082 __ cmp(scratch2, Operand(HeapNumber::kExponentBias + 32));
3082 DeoptimizeIf(ge, instr->environment()); 3083 DeoptimizeIf(ge, instr->environment());
3083 3084
3084 // Save the original sign for later comparison. 3085 // Save the original sign for later comparison.
3085 __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask)); 3086 __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask));
3086 3087
3087 __ vmov(double_scratch0(), 0.5); 3088 __ Vmov(double_scratch0(), 0.5);
3088 __ vadd(input, input, double_scratch0()); 3089 __ vadd(input, input, double_scratch0());
3089 3090
3090 // Check sign of the result: if the sign changed, the input 3091 // Check sign of the result: if the sign changed, the input
3091 // value was in ]0.5, 0[ and the result should be -0. 3092 // value was in ]0.5, 0[ and the result should be -0.
3092 __ vmov(scratch1, input.high()); 3093 __ vmov(scratch1, input.high());
3093 __ eor(scratch1, scratch1, Operand(scratch2), SetCC); 3094 __ eor(scratch1, scratch1, Operand(scratch2), SetCC);
3094 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3095 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3095 DeoptimizeIf(mi, instr->environment()); 3096 DeoptimizeIf(mi, instr->environment());
3096 } else { 3097 } else {
3097 __ mov(result, Operand(0), LeaveCC, mi); 3098 __ mov(result, Operand(0), LeaveCC, mi);
(...skipping 16 matching lines...) Expand all
3114 __ vmov(scratch1, input.high()); 3115 __ vmov(scratch1, input.high());
3115 __ tst(scratch1, Operand(HeapNumber::kSignMask)); 3116 __ tst(scratch1, Operand(HeapNumber::kSignMask));
3116 DeoptimizeIf(ne, instr->environment()); 3117 DeoptimizeIf(ne, instr->environment());
3117 } 3118 }
3118 __ bind(&done); 3119 __ bind(&done);
3119 } 3120 }
3120 3121
3121 3122
3122 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3123 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3123 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3124 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3124 ASSERT(ToDoubleRegister(instr->result()).is(input)); 3125 DoubleRegister result = ToDoubleRegister(instr->result());
3125 __ vsqrt(input, input); 3126 __ vsqrt(result, input);
3126 } 3127 }
3127 3128
3128 3129
3129 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3130 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
3130 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3131 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3131 Register scratch = scratch0(); 3132 DoubleRegister result = ToDoubleRegister(instr->result());
3132 SwVfpRegister single_scratch = double_scratch0().low();
3133 DoubleRegister double_scratch = double_scratch0();
3134 ASSERT(ToDoubleRegister(instr->result()).is(input));
3135
3136 // Add +0 to convert -0 to +0. 3133 // Add +0 to convert -0 to +0.
3137 __ mov(scratch, Operand(0)); 3134 __ vadd(input, input, kDoubleRegZero);
3138 __ vmov(single_scratch, scratch); 3135 __ vsqrt(result, input);
3139 __ vcvt_f64_s32(double_scratch, single_scratch);
3140 __ vadd(input, input, double_scratch);
3141 __ vsqrt(input, input);
3142 } 3136 }
3143 3137
3144 3138
3145 void LCodeGen::DoPower(LPower* instr) { 3139 void LCodeGen::DoPower(LPower* instr) {
3146 LOperand* left = instr->InputAt(0); 3140 LOperand* left = instr->InputAt(0);
3147 LOperand* right = instr->InputAt(1); 3141 LOperand* right = instr->InputAt(1);
3148 Register scratch = scratch0(); 3142 Register scratch = scratch0();
3149 DoubleRegister result_reg = ToDoubleRegister(instr->result()); 3143 DoubleRegister result_reg = ToDoubleRegister(instr->result());
3150 Representation exponent_type = instr->hydrogen()->right()->representation(); 3144 Representation exponent_type = instr->hydrogen()->right()->representation();
3151 if (exponent_type.IsDouble()) { 3145 if (exponent_type.IsDouble()) {
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
3729 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); 3723 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr);
3730 __ SmiTag(reg, SetCC); 3724 __ SmiTag(reg, SetCC);
3731 __ b(vs, deferred->entry()); 3725 __ b(vs, deferred->entry());
3732 __ bind(deferred->exit()); 3726 __ bind(deferred->exit());
3733 } 3727 }
3734 3728
3735 3729
3736 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 3730 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
3737 Label slow; 3731 Label slow;
3738 Register reg = ToRegister(instr->InputAt(0)); 3732 Register reg = ToRegister(instr->InputAt(0));
3739 DoubleRegister dbl_scratch = d0; 3733 DoubleRegister dbl_scratch = double_scratch0();
3740 SwVfpRegister flt_scratch = s0; 3734 SwVfpRegister flt_scratch = dbl_scratch.low();
3741 3735
3742 // Preserve the value of all registers. 3736 // Preserve the value of all registers.
3743 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 3737 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
3744 3738
3745 // There was overflow, so bits 30 and 31 of the original integer 3739 // There was overflow, so bits 30 and 31 of the original integer
3746 // disagree. Try to allocate a heap number in new space and store 3740 // disagree. Try to allocate a heap number in new space and store
3747 // the value in there. If that fails, call the runtime system. 3741 // the value in there. If that fails, call the runtime system.
3748 Label done; 3742 Label done;
3749 __ SmiUntag(reg); 3743 __ SmiUntag(reg);
3750 __ eor(reg, reg, Operand(0x80000000)); 3744 __ eor(reg, reg, Operand(0x80000000));
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3839 __ SmiUntag(ToRegister(input)); 3833 __ SmiUntag(ToRegister(input));
3840 } 3834 }
3841 } 3835 }
3842 3836
3843 3837
3844 void LCodeGen::EmitNumberUntagD(Register input_reg, 3838 void LCodeGen::EmitNumberUntagD(Register input_reg,
3845 DoubleRegister result_reg, 3839 DoubleRegister result_reg,
3846 bool deoptimize_on_undefined, 3840 bool deoptimize_on_undefined,
3847 LEnvironment* env) { 3841 LEnvironment* env) {
3848 Register scratch = scratch0(); 3842 Register scratch = scratch0();
3849 SwVfpRegister flt_scratch = s0; 3843 SwVfpRegister flt_scratch = double_scratch0().low();
3850 ASSERT(!result_reg.is(d0)); 3844 ASSERT(!result_reg.is(double_scratch0()));
3851 3845
3852 Label load_smi, heap_number, done; 3846 Label load_smi, heap_number, done;
3853 3847
3854 // Smi check. 3848 // Smi check.
3855 __ tst(input_reg, Operand(kSmiTagMask)); 3849 __ tst(input_reg, Operand(kSmiTagMask));
3856 __ b(eq, &load_smi); 3850 __ b(eq, &load_smi);
3857 3851
3858 // Heap number map check. 3852 // Heap number map check.
3859 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 3853 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
3860 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3854 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
4586 ASSERT(osr_pc_offset_ == -1); 4580 ASSERT(osr_pc_offset_ == -1);
4587 osr_pc_offset_ = masm()->pc_offset(); 4581 osr_pc_offset_ = masm()->pc_offset();
4588 } 4582 }
4589 4583
4590 4584
4591 4585
4592 4586
4593 #undef __ 4587 #undef __
4594 4588
4595 } } // namespace v8::internal 4589 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698