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

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

Issue 7246004: Revert "ARM: Improve register allocation and constraints." (Closed) Base URL: https://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
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.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 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());
877 876
878 int32_t divisor = 877 int32_t divisor =
879 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 878 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
880 879
881 if (divisor < 0) divisor = -divisor; 880 if (divisor < 0) divisor = -divisor;
882 881
883 Label positive_dividend, done; 882 Label positive_dividend, done;
884 __ cmp(dividend, Operand(0)); 883 __ cmp(dividend, Operand(0));
885 __ b(pl, &positive_dividend); 884 __ b(pl, &positive_dividend);
886 __ rsb(result, dividend, Operand(0)); 885 __ rsb(dividend, dividend, Operand(0));
887 __ and_(dividend, result, Operand(divisor - 1), SetCC); 886 __ and_(dividend, dividend, Operand(divisor - 1));
887 __ rsb(dividend, dividend, Operand(0), SetCC);
888 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 888 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
889 DeoptimizeIf(eq, instr->environment()); 889 __ b(ne, &done);
890 DeoptimizeIf(al, instr->environment());
891 } else {
892 __ b(&done);
890 } 893 }
891 __ rsb(result, dividend, Operand(0));
892 __ b(&done);
893 __ bind(&positive_dividend); 894 __ bind(&positive_dividend);
894 __ and_(result, dividend, Operand(divisor - 1)); 895 __ and_(dividend, dividend, Operand(divisor - 1));
895 __ bind(&done); 896 __ bind(&done);
896 return; 897 return;
897 } 898 }
898 899
899 // These registers hold untagged 32 bit values. 900 // These registers hold untagged 32 bit values.
900 Register left = ToRegister(instr->InputAt(0)); 901 Register left = ToRegister(instr->InputAt(0));
901 Register right = ToRegister(instr->InputAt(1)); 902 Register right = ToRegister(instr->InputAt(1));
902 Register result = ToRegister(instr->result()); 903 Register result = ToRegister(instr->result());
903 904
904 Register scratch = scratch0(); 905 Register scratch = scratch0();
905 Register scratch2 = ToRegister(instr->TempAt(0)); 906 Register scratch2 = ToRegister(instr->TempAt(0));
906 DwVfpRegister dividend = ToDoubleRegister(instr->TempAt(1)); 907 DwVfpRegister dividend = ToDoubleRegister(instr->TempAt(1));
907 DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2)); 908 DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2));
908 DwVfpRegister quotient = double_scratch0(); 909 DwVfpRegister quotient = double_scratch0();
909 910
911 ASSERT(result.is(left));
912
910 ASSERT(!dividend.is(divisor)); 913 ASSERT(!dividend.is(divisor));
911 ASSERT(!dividend.is(quotient)); 914 ASSERT(!dividend.is(quotient));
912 ASSERT(!divisor.is(quotient)); 915 ASSERT(!divisor.is(quotient));
913 ASSERT(!scratch.is(left)); 916 ASSERT(!scratch.is(left));
914 ASSERT(!scratch.is(right)); 917 ASSERT(!scratch.is(right));
915 ASSERT(!scratch.is(result)); 918 ASSERT(!scratch.is(result));
916 919
917 Label done, vfp_modulo, both_positive, right_negative; 920 Label done, vfp_modulo, both_positive, right_negative;
918 921
919 // Check for x % 0. 922 // Check for x % 0.
920 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 923 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
921 __ cmp(right, Operand(0)); 924 __ cmp(right, Operand(0));
922 DeoptimizeIf(eq, instr->environment()); 925 DeoptimizeIf(eq, instr->environment());
923 } 926 }
924 927
925 __ Move(result, left);
926
927 // (0 % x) must yield 0 (if x is finite, which is the case here). 928 // (0 % x) must yield 0 (if x is finite, which is the case here).
928 __ cmp(left, Operand(0)); 929 __ cmp(left, Operand(0));
929 __ b(eq, &done); 930 __ b(eq, &done);
930 // Preload right in a vfp register. 931 // Preload right in a vfp register.
931 __ vmov(divisor.low(), right); 932 __ vmov(divisor.low(), right);
932 __ b(lt, &vfp_modulo); 933 __ b(lt, &vfp_modulo);
933 934
934 __ cmp(left, Operand(right)); 935 __ cmp(left, Operand(right));
935 __ b(lt, &done); 936 __ b(lt, &done);
936 937
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 __ CallStub(&stub); 1113 __ CallStub(&stub);
1113 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), 1114 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
1114 0, 1115 0,
1115 Safepoint::kNoDeoptimizationIndex); 1116 Safepoint::kNoDeoptimizationIndex);
1116 // Overwrite the stored value of r0 with the result of the stub. 1117 // Overwrite the stored value of r0 with the result of the stub.
1117 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0); 1118 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0);
1118 } 1119 }
1119 1120
1120 1121
1121 void LCodeGen::DoMulI(LMulI* instr) { 1122 void LCodeGen::DoMulI(LMulI* instr) {
1123 ASSERT(instr->result()->Equals(instr->InputAt(0)));
1122 Register scratch = scratch0(); 1124 Register scratch = scratch0();
1123 Register result = ToRegister(instr->result()); 1125 Register result = ToRegister(instr->result());
1124 // Note that result may alias left.
1125 Register left = ToRegister(instr->InputAt(0)); 1126 Register left = ToRegister(instr->InputAt(0));
1126 LOperand* right_op = instr->InputAt(1); 1127 LOperand* right_op = instr->InputAt(1);
1127 1128
1128 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1129 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1129 bool bailout_on_minus_zero = 1130 bool bailout_on_minus_zero =
1130 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1131 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1131 1132
1132 if (right_op->IsConstantOperand() && !can_overflow) { 1133 if (right_op->IsConstantOperand() && !can_overflow) {
1133 // Use optimized code for specific constants. 1134 // Use optimized code for specific constants.
1134 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); 1135 int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
(...skipping 12 matching lines...) Expand all
1147 case 0: 1148 case 0:
1148 if (bailout_on_minus_zero) { 1149 if (bailout_on_minus_zero) {
1149 // If left is strictly negative and the constant is null, the 1150 // If left is strictly negative and the constant is null, the
1150 // result is -0. Deoptimize if required, otherwise return 0. 1151 // result is -0. Deoptimize if required, otherwise return 0.
1151 __ cmp(left, Operand(0)); 1152 __ cmp(left, Operand(0));
1152 DeoptimizeIf(mi, instr->environment()); 1153 DeoptimizeIf(mi, instr->environment());
1153 } 1154 }
1154 __ mov(result, Operand(0)); 1155 __ mov(result, Operand(0));
1155 break; 1156 break;
1156 case 1: 1157 case 1:
1157 __ Move(result, left); 1158 // Nothing to do.
1158 break; 1159 break;
1159 default: 1160 default:
1160 // Multiplying by powers of two and powers of two plus or minus 1161 // Multiplying by powers of two and powers of two plus or minus
1161 // one can be done faster with shifted operands. 1162 // one can be done faster with shifted operands.
1162 // For other constants we emit standard code. 1163 // For other constants we emit standard code.
1163 int32_t mask = constant >> 31; 1164 int32_t mask = constant >> 31;
1164 uint32_t constant_abs = (constant + mask) ^ mask; 1165 uint32_t constant_abs = (constant + mask) ^ mask;
1165 1166
1166 if (IsPowerOf2(constant_abs) || 1167 if (IsPowerOf2(constant_abs) ||
1167 IsPowerOf2(constant_abs - 1) || 1168 IsPowerOf2(constant_abs - 1) ||
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 __ b(ne, &done); 1210 __ b(ne, &done);
1210 __ cmp(ToRegister(instr->TempAt(0)), Operand(0)); 1211 __ cmp(ToRegister(instr->TempAt(0)), Operand(0));
1211 DeoptimizeIf(mi, instr->environment()); 1212 DeoptimizeIf(mi, instr->environment());
1212 __ bind(&done); 1213 __ bind(&done);
1213 } 1214 }
1214 } 1215 }
1215 } 1216 }
1216 1217
1217 1218
1218 void LCodeGen::DoBitI(LBitI* instr) { 1219 void LCodeGen::DoBitI(LBitI* instr) {
1219 LOperand* left_op = instr->InputAt(0); 1220 LOperand* left = instr->InputAt(0);
1220 LOperand* right_op = instr->InputAt(1); 1221 LOperand* right = instr->InputAt(1);
1221 ASSERT(left_op->IsRegister()); 1222 ASSERT(left->Equals(instr->result()));
1222 Register left = ToRegister(left_op); 1223 ASSERT(left->IsRegister());
1223 Register result = ToRegister(instr->result()); 1224 Register result = ToRegister(left);
1224 Operand right(no_reg); 1225 Operand right_operand(no_reg);
1225 1226
1226 if (right_op->IsStackSlot() || right_op->IsArgument()) { 1227 if (right->IsStackSlot() || right->IsArgument()) {
1227 right = Operand(EmitLoadRegister(right_op, ip)); 1228 Register right_reg = EmitLoadRegister(right, ip);
1229 right_operand = Operand(right_reg);
1228 } else { 1230 } else {
1229 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); 1231 ASSERT(right->IsRegister() || right->IsConstantOperand());
1230 right = ToOperand(right_op); 1232 right_operand = ToOperand(right);
1231 } 1233 }
1232 1234
1233 switch (instr->op()) { 1235 switch (instr->op()) {
1234 case Token::BIT_AND: 1236 case Token::BIT_AND:
1235 __ and_(result, left, right); 1237 __ and_(result, ToRegister(left), right_operand);
1236 break; 1238 break;
1237 case Token::BIT_OR: 1239 case Token::BIT_OR:
1238 __ orr(result, left, right); 1240 __ orr(result, ToRegister(left), right_operand);
1239 break; 1241 break;
1240 case Token::BIT_XOR: 1242 case Token::BIT_XOR:
1241 __ eor(result, left, right); 1243 __ eor(result, ToRegister(left), right_operand);
1242 break; 1244 break;
1243 default: 1245 default:
1244 UNREACHABLE(); 1246 UNREACHABLE();
1245 break; 1247 break;
1246 } 1248 }
1247 } 1249 }
1248 1250
1249 1251
1250 void LCodeGen::DoShiftI(LShiftI* instr) { 1252 void LCodeGen::DoShiftI(LShiftI* instr) {
1251 // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so
1252 // result may alias either of them.
1253 LOperand* right_op = instr->InputAt(1);
1254 Register left = ToRegister(instr->InputAt(0));
1255 Register result = ToRegister(instr->result());
1256 Register scratch = scratch0(); 1253 Register scratch = scratch0();
1257 if (right_op->IsRegister()) { 1254 LOperand* left = instr->InputAt(0);
1258 // Mask the right_op operand. 1255 LOperand* right = instr->InputAt(1);
1259 __ and_(scratch, ToRegister(right_op), Operand(0x1F)); 1256 ASSERT(left->Equals(instr->result()));
1257 ASSERT(left->IsRegister());
1258 Register result = ToRegister(left);
1259 if (right->IsRegister()) {
1260 // Mask the right operand.
1261 __ and_(scratch, ToRegister(right), Operand(0x1F));
1260 switch (instr->op()) { 1262 switch (instr->op()) {
1261 case Token::SAR: 1263 case Token::SAR:
1262 __ mov(result, Operand(left, ASR, scratch)); 1264 __ mov(result, Operand(result, ASR, scratch));
1263 break; 1265 break;
1264 case Token::SHR: 1266 case Token::SHR:
1265 if (instr->can_deopt()) { 1267 if (instr->can_deopt()) {
1266 __ mov(result, Operand(left, LSR, scratch), SetCC); 1268 __ mov(result, Operand(result, LSR, scratch), SetCC);
1267 DeoptimizeIf(mi, instr->environment()); 1269 DeoptimizeIf(mi, instr->environment());
1268 } else { 1270 } else {
1269 __ mov(result, Operand(left, LSR, scratch)); 1271 __ mov(result, Operand(result, LSR, scratch));
1270 } 1272 }
1271 break; 1273 break;
1272 case Token::SHL: 1274 case Token::SHL:
1273 __ mov(result, Operand(left, LSL, scratch)); 1275 __ mov(result, Operand(result, LSL, scratch));
1274 break; 1276 break;
1275 default: 1277 default:
1276 UNREACHABLE(); 1278 UNREACHABLE();
1277 break; 1279 break;
1278 } 1280 }
1279 } else { 1281 } else {
1280 // Mask the right_op operand. 1282 int value = ToInteger32(LConstantOperand::cast(right));
1281 int value = ToInteger32(LConstantOperand::cast(right_op));
1282 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); 1283 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
1283 switch (instr->op()) { 1284 switch (instr->op()) {
1284 case Token::SAR: 1285 case Token::SAR:
1285 if (shift_count != 0) { 1286 if (shift_count != 0) {
1286 __ mov(result, Operand(left, ASR, shift_count)); 1287 __ mov(result, Operand(result, ASR, shift_count));
1287 } else {
1288 __ Move(result, left);
1289 } 1288 }
1290 break; 1289 break;
1291 case Token::SHR: 1290 case Token::SHR:
1292 if (shift_count != 0) { 1291 if (shift_count == 0 && instr->can_deopt()) {
1293 __ mov(result, Operand(left, LSR, shift_count)); 1292 __ tst(result, Operand(0x80000000));
1293 DeoptimizeIf(ne, instr->environment());
1294 } else { 1294 } else {
1295 if (instr->can_deopt()) { 1295 __ mov(result, Operand(result, LSR, shift_count));
1296 __ tst(left, Operand(0x80000000));
1297 DeoptimizeIf(ne, instr->environment());
1298 }
1299 __ Move(result, left);
1300 } 1296 }
1301 break; 1297 break;
1302 case Token::SHL: 1298 case Token::SHL:
1303 if (shift_count != 0) { 1299 if (shift_count != 0) {
1304 __ mov(result, Operand(left, LSL, shift_count)); 1300 __ mov(result, Operand(result, LSL, shift_count));
1305 } else {
1306 __ Move(result, left);
1307 } 1301 }
1308 break; 1302 break;
1309 default: 1303 default:
1310 UNREACHABLE(); 1304 UNREACHABLE();
1311 break; 1305 break;
1312 } 1306 }
1313 } 1307 }
1314 } 1308 }
1315 1309
1316 1310
1317 void LCodeGen::DoSubI(LSubI* instr) { 1311 void LCodeGen::DoSubI(LSubI* instr) {
1318 LOperand* left = instr->InputAt(0); 1312 LOperand* left = instr->InputAt(0);
1319 LOperand* right = instr->InputAt(1); 1313 LOperand* right = instr->InputAt(1);
1320 LOperand* result = instr->result(); 1314 ASSERT(left->Equals(instr->result()));
1321 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1315 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1322 SBit set_cond = can_overflow ? SetCC : LeaveCC; 1316 SBit set_cond = can_overflow ? SetCC : LeaveCC;
1323 1317
1324 if (right->IsStackSlot() || right->IsArgument()) { 1318 if (right->IsStackSlot() || right->IsArgument()) {
1325 Register right_reg = EmitLoadRegister(right, ip); 1319 Register right_reg = EmitLoadRegister(right, ip);
1326 __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); 1320 __ sub(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond);
1327 } else { 1321 } else {
1328 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1322 ASSERT(right->IsRegister() || right->IsConstantOperand());
1329 __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); 1323 __ sub(ToRegister(left), ToRegister(left), ToOperand(right), set_cond);
1330 } 1324 }
1331 1325
1332 if (can_overflow) { 1326 if (can_overflow) {
1333 DeoptimizeIf(vs, instr->environment()); 1327 DeoptimizeIf(vs, instr->environment());
1334 } 1328 }
1335 } 1329 }
1336 1330
1337 1331
1338 void LCodeGen::DoConstantI(LConstantI* instr) { 1332 void LCodeGen::DoConstantI(LConstantI* instr) {
1339 ASSERT(instr->result()->IsRegister()); 1333 ASSERT(instr->result()->IsRegister());
1340 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1334 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1341 } 1335 }
1342 1336
1343 1337
1344 void LCodeGen::DoConstantD(LConstantD* instr) { 1338 void LCodeGen::DoConstantD(LConstantD* instr) {
1345 ASSERT(instr->result()->IsDoubleRegister()); 1339 ASSERT(instr->result()->IsDoubleRegister());
1346 DwVfpRegister result = ToDoubleRegister(instr->result()); 1340 DwVfpRegister result = ToDoubleRegister(instr->result());
1347 double v = instr->value(); 1341 double v = instr->value();
1348 __ Vmov(result, v); 1342 __ vmov(result, v);
1349 } 1343 }
1350 1344
1351 1345
1352 void LCodeGen::DoConstantT(LConstantT* instr) { 1346 void LCodeGen::DoConstantT(LConstantT* instr) {
1353 ASSERT(instr->result()->IsRegister()); 1347 ASSERT(instr->result()->IsRegister());
1354 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1348 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1355 } 1349 }
1356 1350
1357 1351
1358 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1352 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
(...skipping 28 matching lines...) Expand all
1387 __ ldr(result, FieldMemOperand(result, Map::kBitField2Offset)); 1381 __ ldr(result, FieldMemOperand(result, Map::kBitField2Offset));
1388 // Retrieve elements_kind from bit field 2. 1382 // Retrieve elements_kind from bit field 2.
1389 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); 1383 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount);
1390 } 1384 }
1391 1385
1392 1386
1393 void LCodeGen::DoValueOf(LValueOf* instr) { 1387 void LCodeGen::DoValueOf(LValueOf* instr) {
1394 Register input = ToRegister(instr->InputAt(0)); 1388 Register input = ToRegister(instr->InputAt(0));
1395 Register result = ToRegister(instr->result()); 1389 Register result = ToRegister(instr->result());
1396 Register map = ToRegister(instr->TempAt(0)); 1390 Register map = ToRegister(instr->TempAt(0));
1391 ASSERT(input.is(result));
1397 Label done; 1392 Label done;
1398 1393
1399 // If the object is a smi return the object. 1394 // If the object is a smi return the object.
1400 __ tst(input, Operand(kSmiTagMask)); 1395 __ JumpIfSmi(input, &done);
1401 __ Move(result, input, eq);
1402 __ b(eq, &done);
1403 1396
1404 // If the object is not a value type, return the object. 1397 // If the object is not a value type, return the object.
1405 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); 1398 __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
1406 __ Move(result, input, ne);
1407 __ b(ne, &done); 1399 __ b(ne, &done);
1408 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); 1400 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset));
1409 1401
1410 __ bind(&done); 1402 __ bind(&done);
1411 } 1403 }
1412 1404
1413 1405
1414 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1406 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1415 Register input = ToRegister(instr->InputAt(0)); 1407 LOperand* input = instr->InputAt(0);
1416 Register result = ToRegister(instr->result()); 1408 ASSERT(input->Equals(instr->result()));
1417 __ mvn(result, Operand(input)); 1409 __ mvn(ToRegister(input), Operand(ToRegister(input)));
1418 } 1410 }
1419 1411
1420 1412
1421 void LCodeGen::DoThrow(LThrow* instr) { 1413 void LCodeGen::DoThrow(LThrow* instr) {
1422 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); 1414 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
1423 __ push(input_reg); 1415 __ push(input_reg);
1424 CallRuntime(Runtime::kThrow, 1, instr); 1416 CallRuntime(Runtime::kThrow, 1, instr);
1425 1417
1426 if (FLAG_debug_code) { 1418 if (FLAG_debug_code) {
1427 __ stop("Unreachable code."); 1419 __ stop("Unreachable code.");
1428 } 1420 }
1429 } 1421 }
1430 1422
1431 1423
1432 void LCodeGen::DoAddI(LAddI* instr) { 1424 void LCodeGen::DoAddI(LAddI* instr) {
1433 LOperand* left = instr->InputAt(0); 1425 LOperand* left = instr->InputAt(0);
1434 LOperand* right = instr->InputAt(1); 1426 LOperand* right = instr->InputAt(1);
1435 LOperand* result = instr->result(); 1427 ASSERT(left->Equals(instr->result()));
1436 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1428 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1437 SBit set_cond = can_overflow ? SetCC : LeaveCC; 1429 SBit set_cond = can_overflow ? SetCC : LeaveCC;
1438 1430
1439 if (right->IsStackSlot() || right->IsArgument()) { 1431 if (right->IsStackSlot() || right->IsArgument()) {
1440 Register right_reg = EmitLoadRegister(right, ip); 1432 Register right_reg = EmitLoadRegister(right, ip);
1441 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); 1433 __ add(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond);
1442 } else { 1434 } else {
1443 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1435 ASSERT(right->IsRegister() || right->IsConstantOperand());
1444 __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); 1436 __ add(ToRegister(left), ToRegister(left), ToOperand(right), set_cond);
1445 } 1437 }
1446 1438
1447 if (can_overflow) { 1439 if (can_overflow) {
1448 DeoptimizeIf(vs, instr->environment()); 1440 DeoptimizeIf(vs, instr->environment());
1449 } 1441 }
1450 } 1442 }
1451 1443
1452 1444
1453 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1445 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1454 DoubleRegister left = ToDoubleRegister(instr->InputAt(0)); 1446 DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
1455 DoubleRegister right = ToDoubleRegister(instr->InputAt(1)); 1447 DoubleRegister right = ToDoubleRegister(instr->InputAt(1));
1456 DoubleRegister result = ToDoubleRegister(instr->result());
1457 switch (instr->op()) { 1448 switch (instr->op()) {
1458 case Token::ADD: 1449 case Token::ADD:
1459 __ vadd(result, left, right); 1450 __ vadd(left, left, right);
1460 break; 1451 break;
1461 case Token::SUB: 1452 case Token::SUB:
1462 __ vsub(result, left, right); 1453 __ vsub(left, left, right);
1463 break; 1454 break;
1464 case Token::MUL: 1455 case Token::MUL:
1465 __ vmul(result, left, right); 1456 __ vmul(left, left, right);
1466 break; 1457 break;
1467 case Token::DIV: 1458 case Token::DIV:
1468 __ vdiv(result, left, right); 1459 __ vdiv(left, left, right);
1469 break; 1460 break;
1470 case Token::MOD: { 1461 case Token::MOD: {
1471 // Save r0-r3 on the stack. 1462 // Save r0-r3 on the stack.
1472 __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); 1463 __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
1473 1464
1474 __ PrepareCallCFunction(0, 2, scratch0()); 1465 __ PrepareCallCFunction(0, 2, scratch0());
1475 __ SetCallCDoubleArguments(left, right); 1466 __ SetCallCDoubleArguments(left, right);
1476 __ CallCFunction( 1467 __ CallCFunction(
1477 ExternalReference::double_fp_operation(Token::MOD, isolate()), 1468 ExternalReference::double_fp_operation(Token::MOD, isolate()),
1478 0, 2); 1469 0, 2);
1479 // Move the result in the double result register. 1470 // Move the result in the double result register.
1480 __ GetCFunctionDoubleResult(result); 1471 __ GetCFunctionDoubleResult(ToDoubleRegister(instr->result()));
1481 1472
1482 // Restore r0-r3. 1473 // Restore r0-r3.
1483 __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); 1474 __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
1484 break; 1475 break;
1485 } 1476 }
1486 default: 1477 default:
1487 UNREACHABLE(); 1478 UNREACHABLE();
1488 break; 1479 break;
1489 } 1480 }
1490 } 1481 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1563 __ b(eq, true_label); 1554 __ b(eq, true_label);
1564 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 1555 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
1565 __ cmp(reg, ip); 1556 __ cmp(reg, ip);
1566 __ b(eq, false_label); 1557 __ b(eq, false_label);
1567 __ cmp(reg, Operand(0)); 1558 __ cmp(reg, Operand(0));
1568 __ b(eq, false_label); 1559 __ b(eq, false_label);
1569 __ JumpIfSmi(reg, true_label); 1560 __ JumpIfSmi(reg, true_label);
1570 1561
1571 // Test double values. Zero and NaN are false. 1562 // Test double values. Zero and NaN are false.
1572 Label call_stub; 1563 Label call_stub;
1573 DoubleRegister dbl_scratch = double_scratch0(); 1564 DoubleRegister dbl_scratch = d0;
1574 Register scratch = scratch0(); 1565 Register scratch = scratch0();
1575 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); 1566 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
1576 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 1567 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
1577 __ cmp(scratch, Operand(ip)); 1568 __ cmp(scratch, Operand(ip));
1578 __ b(ne, &call_stub); 1569 __ b(ne, &call_stub);
1579 __ sub(ip, reg, Operand(kHeapObjectTag)); 1570 __ sub(ip, reg, Operand(kHeapObjectTag));
1580 __ vldr(dbl_scratch, ip, HeapNumber::kValueOffset); 1571 __ vldr(dbl_scratch, ip, HeapNumber::kValueOffset);
1581 __ VFPCompareAndLoadFlags(dbl_scratch, 0.0, scratch); 1572 __ VFPCompareAndLoadFlags(dbl_scratch, 0.0, scratch);
1582 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); 1573 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
1583 __ b(ne, false_label); 1574 __ b(ne, false_label);
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after
2609 __ add(length, length, Operand(1)); 2600 __ add(length, length, Operand(1));
2610 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); 2601 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
2611 } 2602 }
2612 2603
2613 2604
2614 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2605 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2615 Register elements = ToRegister(instr->elements()); 2606 Register elements = ToRegister(instr->elements());
2616 Register key = EmitLoadRegister(instr->key(), scratch0()); 2607 Register key = EmitLoadRegister(instr->key(), scratch0());
2617 Register result = ToRegister(instr->result()); 2608 Register result = ToRegister(instr->result());
2618 Register scratch = scratch0(); 2609 Register scratch = scratch0();
2610 ASSERT(result.is(elements));
2619 2611
2620 // Load the result. 2612 // Load the result.
2621 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 2613 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
2622 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 2614 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize));
2623 2615
2624 // Check for the hole value. 2616 // Check for the hole value.
2625 if (instr->hydrogen()->RequiresHoleCheck()) { 2617 if (instr->hydrogen()->RequiresHoleCheck()) {
2626 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 2618 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
2627 __ cmp(result, scratch); 2619 __ cmp(result, scratch);
2628 DeoptimizeIf(eq, instr->environment()); 2620 DeoptimizeIf(eq, instr->environment());
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
2928 ASSERT(ToRegister(instr->result()).is(r0)); 2920 ASSERT(ToRegister(instr->result()).is(r0));
2929 __ mov(r1, Operand(instr->function())); 2921 __ mov(r1, Operand(instr->function()));
2930 CallKnownFunction(instr->function(), 2922 CallKnownFunction(instr->function(),
2931 instr->arity(), 2923 instr->arity(),
2932 instr, 2924 instr,
2933 CALL_AS_METHOD); 2925 CALL_AS_METHOD);
2934 } 2926 }
2935 2927
2936 2928
2937 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2929 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2930 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2938 Register input = ToRegister(instr->InputAt(0)); 2931 Register input = ToRegister(instr->InputAt(0));
2939 Register result = ToRegister(instr->result());
2940 Register scratch = scratch0(); 2932 Register scratch = scratch0();
2941 2933
2942 // Deoptimize if not a heap number. 2934 // Deoptimize if not a heap number.
2943 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 2935 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
2944 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 2936 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
2945 __ cmp(scratch, Operand(ip)); 2937 __ cmp(scratch, Operand(ip));
2946 DeoptimizeIf(ne, instr->environment()); 2938 DeoptimizeIf(ne, instr->environment());
2947 2939
2948 Label done; 2940 Label done;
2949 Register exponent = scratch0(); 2941 Register exponent = scratch0();
2950 scratch = no_reg; 2942 scratch = no_reg;
2951 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 2943 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2952 // Check the sign of the argument. If the argument is positive, just 2944 // Check the sign of the argument. If the argument is positive, just
2953 // return it. 2945 // return it. We do not need to patch the stack since |input| and
2946 // |result| are the same register and |input| would be restored
2947 // unchanged by popping safepoint registers.
2954 __ tst(exponent, Operand(HeapNumber::kSignMask)); 2948 __ tst(exponent, Operand(HeapNumber::kSignMask));
2955 // Move the input to the result if necessary.
2956 __ Move(result, input);
2957 __ b(eq, &done); 2949 __ b(eq, &done);
2958 2950
2959 // Input is negative. Reverse its sign. 2951 // Input is negative. Reverse its sign.
2960 // Preserve the value of all registers. 2952 // Preserve the value of all registers.
2961 { 2953 {
2962 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 2954 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2963 2955
2964 // Registers were saved at the safepoint, so we can use 2956 // Registers were saved at the safepoint, so we can use
2965 // many scratch registers. 2957 // many scratch registers.
2966 Register tmp1 = input.is(r1) ? r0 : r1; 2958 Register tmp1 = input.is(r1) ? r0 : r1;
(...skipping 19 matching lines...) Expand all
2986 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 2978 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2987 2979
2988 __ bind(&allocated); 2980 __ bind(&allocated);
2989 // exponent: floating point exponent value. 2981 // exponent: floating point exponent value.
2990 // tmp1: allocated heap number. 2982 // tmp1: allocated heap number.
2991 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask)); 2983 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask));
2992 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset)); 2984 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset));
2993 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); 2985 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
2994 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 2986 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
2995 2987
2996 __ StoreToSafepointRegisterSlot(tmp1, result); 2988 __ StoreToSafepointRegisterSlot(tmp1, input);
2997 } 2989 }
2998 2990
2999 __ bind(&done); 2991 __ bind(&done);
3000 } 2992 }
3001 2993
3002 2994
3003 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 2995 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
3004 Register input = ToRegister(instr->InputAt(0)); 2996 Register input = ToRegister(instr->InputAt(0));
3005 Register result = ToRegister(instr->result());
3006 __ cmp(input, Operand(0)); 2997 __ cmp(input, Operand(0));
3007 __ Move(result, input, pl);
3008 // We can make rsb conditional because the previous cmp instruction 2998 // We can make rsb conditional because the previous cmp instruction
3009 // will clear the V (overflow) flag and rsb won't set this flag 2999 // will clear the V (overflow) flag and rsb won't set this flag
3010 // if input is positive. 3000 // if input is positive.
3011 __ rsb(result, input, Operand(0), SetCC, mi); 3001 __ rsb(input, input, Operand(0), SetCC, mi);
3012 // Deoptimize on overflow. 3002 // Deoptimize on overflow.
3013 DeoptimizeIf(vs, instr->environment()); 3003 DeoptimizeIf(vs, instr->environment());
3014 } 3004 }
3015 3005
3016 3006
3017 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 3007 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
3018 // Class for deferred case. 3008 // Class for deferred case.
3019 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3009 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3020 public: 3010 public:
3021 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3011 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
3022 LUnaryMathOperation* instr) 3012 LUnaryMathOperation* instr)
3023 : LDeferredCode(codegen), instr_(instr) { } 3013 : LDeferredCode(codegen), instr_(instr) { }
3024 virtual void Generate() { 3014 virtual void Generate() {
3025 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3015 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3026 } 3016 }
3027 private: 3017 private:
3028 LUnaryMathOperation* instr_; 3018 LUnaryMathOperation* instr_;
3029 }; 3019 };
3030 3020
3021 ASSERT(instr->InputAt(0)->Equals(instr->result()));
3031 Representation r = instr->hydrogen()->value()->representation(); 3022 Representation r = instr->hydrogen()->value()->representation();
3032 if (r.IsDouble()) { 3023 if (r.IsDouble()) {
3033 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0)); 3024 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0));
3034 DwVfpRegister result = ToDoubleRegister(instr->result()); 3025 __ vabs(input, input);
3035 __ vabs(result, input);
3036 } else if (r.IsInteger32()) { 3026 } else if (r.IsInteger32()) {
3037 EmitIntegerMathAbs(instr); 3027 EmitIntegerMathAbs(instr);
3038 } else { 3028 } else {
3039 // Representation is tagged. 3029 // Representation is tagged.
3040 DeferredMathAbsTaggedHeapNumber* deferred = 3030 DeferredMathAbsTaggedHeapNumber* deferred =
3041 new DeferredMathAbsTaggedHeapNumber(this, instr); 3031 new DeferredMathAbsTaggedHeapNumber(this, instr);
3042 Register input = ToRegister(instr->InputAt(0)); 3032 Register input = ToRegister(instr->InputAt(0));
3043 // Smi check. 3033 // Smi check.
3044 __ JumpIfNotSmi(input, deferred->entry()); 3034 __ JumpIfNotSmi(input, deferred->entry());
3045 // If smi, handle it directly. 3035 // If smi, handle it directly.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3103 } 3093 }
3104 3094
3105 // The following conversion will not work with numbers 3095 // The following conversion will not work with numbers
3106 // outside of ]-2^32, 2^32[. 3096 // outside of ]-2^32, 2^32[.
3107 __ cmp(scratch2, Operand(HeapNumber::kExponentBias + 32)); 3097 __ cmp(scratch2, Operand(HeapNumber::kExponentBias + 32));
3108 DeoptimizeIf(ge, instr->environment()); 3098 DeoptimizeIf(ge, instr->environment());
3109 3099
3110 // Save the original sign for later comparison. 3100 // Save the original sign for later comparison.
3111 __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask)); 3101 __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask));
3112 3102
3113 __ Vmov(double_scratch0(), 0.5); 3103 __ vmov(double_scratch0(), 0.5);
3114 __ vadd(input, input, double_scratch0()); 3104 __ vadd(input, input, double_scratch0());
3115 3105
3116 // Check sign of the result: if the sign changed, the input 3106 // Check sign of the result: if the sign changed, the input
3117 // value was in ]0.5, 0[ and the result should be -0. 3107 // value was in ]0.5, 0[ and the result should be -0.
3118 __ vmov(scratch1, input.high()); 3108 __ vmov(scratch1, input.high());
3119 __ eor(scratch1, scratch1, Operand(scratch2), SetCC); 3109 __ eor(scratch1, scratch1, Operand(scratch2), SetCC);
3120 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3110 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3121 DeoptimizeIf(mi, instr->environment()); 3111 DeoptimizeIf(mi, instr->environment());
3122 } else { 3112 } else {
3123 __ mov(result, Operand(0), LeaveCC, mi); 3113 __ mov(result, Operand(0), LeaveCC, mi);
(...skipping 16 matching lines...) Expand all
3140 __ vmov(scratch1, input.high()); 3130 __ vmov(scratch1, input.high());
3141 __ tst(scratch1, Operand(HeapNumber::kSignMask)); 3131 __ tst(scratch1, Operand(HeapNumber::kSignMask));
3142 DeoptimizeIf(ne, instr->environment()); 3132 DeoptimizeIf(ne, instr->environment());
3143 } 3133 }
3144 __ bind(&done); 3134 __ bind(&done);
3145 } 3135 }
3146 3136
3147 3137
3148 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3138 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3149 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3139 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3150 DoubleRegister result = ToDoubleRegister(instr->result()); 3140 ASSERT(ToDoubleRegister(instr->result()).is(input));
3151 __ vsqrt(result, input); 3141 __ vsqrt(input, input);
3152 } 3142 }
3153 3143
3154 3144
3155 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3145 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
3156 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3146 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3157 DoubleRegister result = ToDoubleRegister(instr->result()); 3147 Register scratch = scratch0();
3148 SwVfpRegister single_scratch = double_scratch0().low();
3149 DoubleRegister double_scratch = double_scratch0();
3150 ASSERT(ToDoubleRegister(instr->result()).is(input));
3151
3158 // Add +0 to convert -0 to +0. 3152 // Add +0 to convert -0 to +0.
3159 __ vadd(result, input, kDoubleRegZero); 3153 __ mov(scratch, Operand(0));
3160 __ vsqrt(result, result); 3154 __ vmov(single_scratch, scratch);
3155 __ vcvt_f64_s32(double_scratch, single_scratch);
3156 __ vadd(input, input, double_scratch);
3157 __ vsqrt(input, input);
3161 } 3158 }
3162 3159
3163 3160
3164 void LCodeGen::DoPower(LPower* instr) { 3161 void LCodeGen::DoPower(LPower* instr) {
3165 LOperand* left = instr->InputAt(0); 3162 LOperand* left = instr->InputAt(0);
3166 LOperand* right = instr->InputAt(1); 3163 LOperand* right = instr->InputAt(1);
3167 Register scratch = scratch0(); 3164 Register scratch = scratch0();
3168 DoubleRegister result_reg = ToDoubleRegister(instr->result()); 3165 DoubleRegister result_reg = ToDoubleRegister(instr->result());
3169 Representation exponent_type = instr->hydrogen()->right()->representation(); 3166 Representation exponent_type = instr->hydrogen()->right()->representation();
3170 if (exponent_type.IsDouble()) { 3167 if (exponent_type.IsDouble()) {
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
3749 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); 3746 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr);
3750 __ SmiTag(reg, SetCC); 3747 __ SmiTag(reg, SetCC);
3751 __ b(vs, deferred->entry()); 3748 __ b(vs, deferred->entry());
3752 __ bind(deferred->exit()); 3749 __ bind(deferred->exit());
3753 } 3750 }
3754 3751
3755 3752
3756 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 3753 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
3757 Label slow; 3754 Label slow;
3758 Register reg = ToRegister(instr->InputAt(0)); 3755 Register reg = ToRegister(instr->InputAt(0));
3759 DoubleRegister dbl_scratch = double_scratch0(); 3756 DoubleRegister dbl_scratch = d0;
3760 SwVfpRegister flt_scratch = dbl_scratch.low(); 3757 SwVfpRegister flt_scratch = s0;
3761 3758
3762 // Preserve the value of all registers. 3759 // Preserve the value of all registers.
3763 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 3760 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
3764 3761
3765 // There was overflow, so bits 30 and 31 of the original integer 3762 // There was overflow, so bits 30 and 31 of the original integer
3766 // disagree. Try to allocate a heap number in new space and store 3763 // disagree. Try to allocate a heap number in new space and store
3767 // the value in there. If that fails, call the runtime system. 3764 // the value in there. If that fails, call the runtime system.
3768 Label done; 3765 Label done;
3769 __ SmiUntag(reg); 3766 __ SmiUntag(reg);
3770 __ eor(reg, reg, Operand(0x80000000)); 3767 __ eor(reg, reg, Operand(0x80000000));
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3859 __ SmiUntag(ToRegister(input)); 3856 __ SmiUntag(ToRegister(input));
3860 } 3857 }
3861 } 3858 }
3862 3859
3863 3860
3864 void LCodeGen::EmitNumberUntagD(Register input_reg, 3861 void LCodeGen::EmitNumberUntagD(Register input_reg,
3865 DoubleRegister result_reg, 3862 DoubleRegister result_reg,
3866 bool deoptimize_on_undefined, 3863 bool deoptimize_on_undefined,
3867 LEnvironment* env) { 3864 LEnvironment* env) {
3868 Register scratch = scratch0(); 3865 Register scratch = scratch0();
3869 SwVfpRegister flt_scratch = double_scratch0().low(); 3866 SwVfpRegister flt_scratch = s0;
3870 ASSERT(!result_reg.is(double_scratch0())); 3867 ASSERT(!result_reg.is(d0));
3871 3868
3872 Label load_smi, heap_number, done; 3869 Label load_smi, heap_number, done;
3873 3870
3874 // Smi check. 3871 // Smi check.
3875 __ JumpIfSmi(input_reg, &load_smi); 3872 __ JumpIfSmi(input_reg, &load_smi);
3876 3873
3877 // Heap number map check. 3874 // Heap number map check.
3878 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 3875 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
3879 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3876 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
3880 __ cmp(scratch, Operand(ip)); 3877 __ cmp(scratch, Operand(ip));
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after
4605 ASSERT(osr_pc_offset_ == -1); 4602 ASSERT(osr_pc_offset_ == -1);
4606 osr_pc_offset_ = masm()->pc_offset(); 4603 osr_pc_offset_ = masm()->pc_offset();
4607 } 4604 }
4608 4605
4609 4606
4610 4607
4611 4608
4612 #undef __ 4609 #undef __
4613 4610
4614 } } // namespace v8::internal 4611 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698