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

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