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

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

Issue 7276034: ARM: Improve register allocation and constraints (try 2).... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 5 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_(result, 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, result, 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 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
2572 __ add(length, length, Operand(1)); 2581 __ add(length, length, Operand(1));
2573 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); 2582 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
2574 } 2583 }
2575 2584
2576 2585
2577 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2586 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2578 Register elements = ToRegister(instr->elements()); 2587 Register elements = ToRegister(instr->elements());
2579 Register key = EmitLoadRegister(instr->key(), scratch0()); 2588 Register key = EmitLoadRegister(instr->key(), scratch0());
2580 Register result = ToRegister(instr->result()); 2589 Register result = ToRegister(instr->result());
2581 Register scratch = scratch0(); 2590 Register scratch = scratch0();
2582 ASSERT(result.is(elements));
2583 2591
2584 // Load the result. 2592 // Load the result.
2585 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 2593 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
2586 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 2594 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize));
2587 2595
2588 // Check for the hole value. 2596 // Check for the hole value.
2589 if (instr->hydrogen()->RequiresHoleCheck()) { 2597 if (instr->hydrogen()->RequiresHoleCheck()) {
2590 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 2598 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
2591 __ cmp(result, scratch); 2599 __ cmp(result, scratch);
2592 DeoptimizeIf(eq, instr->environment()); 2600 DeoptimizeIf(eq, instr->environment());
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
2892 ASSERT(ToRegister(instr->result()).is(r0)); 2900 ASSERT(ToRegister(instr->result()).is(r0));
2893 __ mov(r1, Operand(instr->function())); 2901 __ mov(r1, Operand(instr->function()));
2894 CallKnownFunction(instr->function(), 2902 CallKnownFunction(instr->function(),
2895 instr->arity(), 2903 instr->arity(),
2896 instr, 2904 instr,
2897 CALL_AS_METHOD); 2905 CALL_AS_METHOD);
2898 } 2906 }
2899 2907
2900 2908
2901 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2909 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2902 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2903 Register input = ToRegister(instr->InputAt(0)); 2910 Register input = ToRegister(instr->InputAt(0));
2911 Register result = ToRegister(instr->result());
2904 Register scratch = scratch0(); 2912 Register scratch = scratch0();
2905 2913
2906 // Deoptimize if not a heap number. 2914 // Deoptimize if not a heap number.
2907 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 2915 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
2908 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 2916 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
2909 __ cmp(scratch, Operand(ip)); 2917 __ cmp(scratch, Operand(ip));
2910 DeoptimizeIf(ne, instr->environment()); 2918 DeoptimizeIf(ne, instr->environment());
2911 2919
2912 Label done; 2920 Label done;
2913 Register exponent = scratch0(); 2921 Register exponent = scratch0();
2914 scratch = no_reg; 2922 scratch = no_reg;
2915 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 2923 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2916 // Check the sign of the argument. If the argument is positive, just 2924 // Check the sign of the argument. If the argument is positive, just
2917 // return it. We do not need to patch the stack since |input| and 2925 // return it.
2918 // |result| are the same register and |input| would be restored
2919 // unchanged by popping safepoint registers.
2920 __ tst(exponent, Operand(HeapNumber::kSignMask)); 2926 __ tst(exponent, Operand(HeapNumber::kSignMask));
2927 // Move the input to the result if necessary.
2928 __ Move(result, input);
2921 __ b(eq, &done); 2929 __ b(eq, &done);
2922 2930
2923 // Input is negative. Reverse its sign. 2931 // Input is negative. Reverse its sign.
2924 // Preserve the value of all registers. 2932 // Preserve the value of all registers.
2925 { 2933 {
2926 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 2934 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2927 2935
2928 // Registers were saved at the safepoint, so we can use 2936 // Registers were saved at the safepoint, so we can use
2929 // many scratch registers. 2937 // many scratch registers.
2930 Register tmp1 = input.is(r1) ? r0 : r1; 2938 Register tmp1 = input.is(r1) ? r0 : r1;
(...skipping 19 matching lines...) Expand all
2950 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 2958 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2951 2959
2952 __ bind(&allocated); 2960 __ bind(&allocated);
2953 // exponent: floating point exponent value. 2961 // exponent: floating point exponent value.
2954 // tmp1: allocated heap number. 2962 // tmp1: allocated heap number.
2955 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask)); 2963 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask));
2956 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset)); 2964 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset));
2957 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); 2965 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
2958 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 2966 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
2959 2967
2960 __ StoreToSafepointRegisterSlot(tmp1, input); 2968 __ StoreToSafepointRegisterSlot(tmp1, result);
2961 } 2969 }
2962 2970
2963 __ bind(&done); 2971 __ bind(&done);
2964 } 2972 }
2965 2973
2966 2974
2967 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 2975 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
2968 Register input = ToRegister(instr->InputAt(0)); 2976 Register input = ToRegister(instr->InputAt(0));
2977 Register result = ToRegister(instr->result());
2969 __ cmp(input, Operand(0)); 2978 __ cmp(input, Operand(0));
2979 __ Move(result, input, pl);
2970 // We can make rsb conditional because the previous cmp instruction 2980 // We can make rsb conditional because the previous cmp instruction
2971 // will clear the V (overflow) flag and rsb won't set this flag 2981 // will clear the V (overflow) flag and rsb won't set this flag
2972 // if input is positive. 2982 // if input is positive.
2973 __ rsb(input, input, Operand(0), SetCC, mi); 2983 __ rsb(result, input, Operand(0), SetCC, mi);
2974 // Deoptimize on overflow. 2984 // Deoptimize on overflow.
2975 DeoptimizeIf(vs, instr->environment()); 2985 DeoptimizeIf(vs, instr->environment());
2976 } 2986 }
2977 2987
2978 2988
2979 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 2989 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
2980 // Class for deferred case. 2990 // Class for deferred case.
2981 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 2991 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
2982 public: 2992 public:
2983 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 2993 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
2984 LUnaryMathOperation* instr) 2994 LUnaryMathOperation* instr)
2985 : LDeferredCode(codegen), instr_(instr) { } 2995 : LDeferredCode(codegen), instr_(instr) { }
2986 virtual void Generate() { 2996 virtual void Generate() {
2987 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 2997 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
2988 } 2998 }
2989 private: 2999 private:
2990 LUnaryMathOperation* instr_; 3000 LUnaryMathOperation* instr_;
2991 }; 3001 };
2992 3002
2993 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2994 Representation r = instr->hydrogen()->value()->representation(); 3003 Representation r = instr->hydrogen()->value()->representation();
2995 if (r.IsDouble()) { 3004 if (r.IsDouble()) {
2996 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0)); 3005 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0));
2997 __ vabs(input, input); 3006 DwVfpRegister result = ToDoubleRegister(instr->result());
3007 __ vabs(result, input);
2998 } else if (r.IsInteger32()) { 3008 } else if (r.IsInteger32()) {
2999 EmitIntegerMathAbs(instr); 3009 EmitIntegerMathAbs(instr);
3000 } else { 3010 } else {
3001 // Representation is tagged. 3011 // Representation is tagged.
3002 DeferredMathAbsTaggedHeapNumber* deferred = 3012 DeferredMathAbsTaggedHeapNumber* deferred =
3003 new DeferredMathAbsTaggedHeapNumber(this, instr); 3013 new DeferredMathAbsTaggedHeapNumber(this, instr);
3004 Register input = ToRegister(instr->InputAt(0)); 3014 Register input = ToRegister(instr->InputAt(0));
3005 // Smi check. 3015 // Smi check.
3006 __ JumpIfNotSmi(input, deferred->entry()); 3016 __ JumpIfNotSmi(input, deferred->entry());
3007 // If smi, handle it directly. 3017 // If smi, handle it directly.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3065 } 3075 }
3066 3076
3067 // The following conversion will not work with numbers 3077 // The following conversion will not work with numbers
3068 // outside of ]-2^32, 2^32[. 3078 // outside of ]-2^32, 2^32[.
3069 __ cmp(scratch2, Operand(HeapNumber::kExponentBias + 32)); 3079 __ cmp(scratch2, Operand(HeapNumber::kExponentBias + 32));
3070 DeoptimizeIf(ge, instr->environment()); 3080 DeoptimizeIf(ge, instr->environment());
3071 3081
3072 // Save the original sign for later comparison. 3082 // Save the original sign for later comparison.
3073 __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask)); 3083 __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask));
3074 3084
3075 __ vmov(double_scratch0(), 0.5); 3085 __ Vmov(double_scratch0(), 0.5);
3076 __ vadd(input, input, double_scratch0()); 3086 __ vadd(input, input, double_scratch0());
3077 3087
3078 // Check sign of the result: if the sign changed, the input 3088 // Check sign of the result: if the sign changed, the input
3079 // value was in ]0.5, 0[ and the result should be -0. 3089 // value was in ]0.5, 0[ and the result should be -0.
3080 __ vmov(scratch1, input.high()); 3090 __ vmov(scratch1, input.high());
3081 __ eor(scratch1, scratch1, Operand(scratch2), SetCC); 3091 __ eor(scratch1, scratch1, Operand(scratch2), SetCC);
3082 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3092 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3083 DeoptimizeIf(mi, instr->environment()); 3093 DeoptimizeIf(mi, instr->environment());
3084 } else { 3094 } else {
3085 __ mov(result, Operand(0), LeaveCC, mi); 3095 __ mov(result, Operand(0), LeaveCC, mi);
(...skipping 16 matching lines...) Expand all
3102 __ vmov(scratch1, input.high()); 3112 __ vmov(scratch1, input.high());
3103 __ tst(scratch1, Operand(HeapNumber::kSignMask)); 3113 __ tst(scratch1, Operand(HeapNumber::kSignMask));
3104 DeoptimizeIf(ne, instr->environment()); 3114 DeoptimizeIf(ne, instr->environment());
3105 } 3115 }
3106 __ bind(&done); 3116 __ bind(&done);
3107 } 3117 }
3108 3118
3109 3119
3110 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3120 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3111 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3121 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3112 ASSERT(ToDoubleRegister(instr->result()).is(input)); 3122 DoubleRegister result = ToDoubleRegister(instr->result());
3113 __ vsqrt(input, input); 3123 __ vsqrt(result, input);
3114 } 3124 }
3115 3125
3116 3126
3117 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3127 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
3118 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3128 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3119 Register scratch = scratch0(); 3129 DoubleRegister result = ToDoubleRegister(instr->result());
3120 SwVfpRegister single_scratch = double_scratch0().low();
3121 DoubleRegister double_scratch = double_scratch0();
3122 ASSERT(ToDoubleRegister(instr->result()).is(input));
3123
3124 // Add +0 to convert -0 to +0. 3130 // Add +0 to convert -0 to +0.
3125 __ mov(scratch, Operand(0)); 3131 __ vadd(result, input, kDoubleRegZero);
3126 __ vmov(single_scratch, scratch); 3132 __ vsqrt(result, result);
3127 __ vcvt_f64_s32(double_scratch, single_scratch);
3128 __ vadd(input, input, double_scratch);
3129 __ vsqrt(input, input);
3130 } 3133 }
3131 3134
3132 3135
3133 void LCodeGen::DoPower(LPower* instr) { 3136 void LCodeGen::DoPower(LPower* instr) {
3134 LOperand* left = instr->InputAt(0); 3137 LOperand* left = instr->InputAt(0);
3135 LOperand* right = instr->InputAt(1); 3138 LOperand* right = instr->InputAt(1);
3136 Register scratch = scratch0(); 3139 Register scratch = scratch0();
3137 DoubleRegister result_reg = ToDoubleRegister(instr->result()); 3140 DoubleRegister result_reg = ToDoubleRegister(instr->result());
3138 Representation exponent_type = instr->hydrogen()->right()->representation(); 3141 Representation exponent_type = instr->hydrogen()->right()->representation();
3139 if (exponent_type.IsDouble()) { 3142 if (exponent_type.IsDouble()) {
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
3718 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); 3721 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr);
3719 __ SmiTag(reg, SetCC); 3722 __ SmiTag(reg, SetCC);
3720 __ b(vs, deferred->entry()); 3723 __ b(vs, deferred->entry());
3721 __ bind(deferred->exit()); 3724 __ bind(deferred->exit());
3722 } 3725 }
3723 3726
3724 3727
3725 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 3728 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
3726 Label slow; 3729 Label slow;
3727 Register reg = ToRegister(instr->InputAt(0)); 3730 Register reg = ToRegister(instr->InputAt(0));
3728 DoubleRegister dbl_scratch = d0; 3731 DoubleRegister dbl_scratch = double_scratch0();
3729 SwVfpRegister flt_scratch = s0; 3732 SwVfpRegister flt_scratch = dbl_scratch.low();
3730 3733
3731 // Preserve the value of all registers. 3734 // Preserve the value of all registers.
3732 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 3735 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
3733 3736
3734 // There was overflow, so bits 30 and 31 of the original integer 3737 // There was overflow, so bits 30 and 31 of the original integer
3735 // disagree. Try to allocate a heap number in new space and store 3738 // disagree. Try to allocate a heap number in new space and store
3736 // the value in there. If that fails, call the runtime system. 3739 // the value in there. If that fails, call the runtime system.
3737 Label done; 3740 Label done;
3738 __ SmiUntag(reg); 3741 __ SmiUntag(reg);
3739 __ eor(reg, reg, Operand(0x80000000)); 3742 __ eor(reg, reg, Operand(0x80000000));
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3828 __ SmiUntag(ToRegister(input)); 3831 __ SmiUntag(ToRegister(input));
3829 } 3832 }
3830 } 3833 }
3831 3834
3832 3835
3833 void LCodeGen::EmitNumberUntagD(Register input_reg, 3836 void LCodeGen::EmitNumberUntagD(Register input_reg,
3834 DoubleRegister result_reg, 3837 DoubleRegister result_reg,
3835 bool deoptimize_on_undefined, 3838 bool deoptimize_on_undefined,
3836 LEnvironment* env) { 3839 LEnvironment* env) {
3837 Register scratch = scratch0(); 3840 Register scratch = scratch0();
3838 SwVfpRegister flt_scratch = s0; 3841 SwVfpRegister flt_scratch = double_scratch0().low();
3839 ASSERT(!result_reg.is(d0)); 3842 ASSERT(!result_reg.is(double_scratch0()));
3840 3843
3841 Label load_smi, heap_number, done; 3844 Label load_smi, heap_number, done;
3842 3845
3843 // Smi check. 3846 // Smi check.
3844 __ JumpIfSmi(input_reg, &load_smi); 3847 __ JumpIfSmi(input_reg, &load_smi);
3845 3848
3846 // Heap number map check. 3849 // Heap number map check.
3847 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 3850 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
3848 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3851 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
3849 __ cmp(scratch, Operand(ip)); 3852 __ cmp(scratch, Operand(ip));
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
4601 ASSERT(osr_pc_offset_ == -1); 4604 ASSERT(osr_pc_offset_ == -1);
4602 osr_pc_offset_ = masm()->pc_offset(); 4605 osr_pc_offset_ = masm()->pc_offset();
4603 } 4606 }
4604 4607
4605 4608
4606 4609
4607 4610
4608 #undef __ 4611 #undef __
4609 4612
4610 } } // namespace v8::internal 4613 } } // 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