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

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

Issue 11035053: Rollback trunk to bleeding_edge revision 12525 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 8 years, 2 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 } 944 }
945 945
946 946
947 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 947 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
948 // Nothing to do. 948 // Nothing to do.
949 } 949 }
950 950
951 951
952 void LCodeGen::DoModI(LModI* instr) { 952 void LCodeGen::DoModI(LModI* instr) {
953 if (instr->hydrogen()->HasPowerOf2Divisor()) { 953 if (instr->hydrogen()->HasPowerOf2Divisor()) {
954 Register dividend = ToRegister(instr->left()); 954 Register dividend = ToRegister(instr->InputAt(0));
955 Register result = ToRegister(instr->result()); 955 Register result = ToRegister(instr->result());
956 956
957 int32_t divisor = 957 int32_t divisor =
958 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 958 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
959 959
960 if (divisor < 0) divisor = -divisor; 960 if (divisor < 0) divisor = -divisor;
961 961
962 Label positive_dividend, done; 962 Label positive_dividend, done;
963 __ cmp(dividend, Operand(0)); 963 __ cmp(dividend, Operand(0));
964 __ b(pl, &positive_dividend); 964 __ b(pl, &positive_dividend);
965 __ rsb(result, dividend, Operand(0)); 965 __ rsb(result, dividend, Operand(0));
966 __ and_(result, result, Operand(divisor - 1), SetCC); 966 __ and_(result, result, Operand(divisor - 1), SetCC);
967 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 967 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
968 DeoptimizeIf(eq, instr->environment()); 968 DeoptimizeIf(eq, instr->environment());
969 } 969 }
970 __ rsb(result, result, Operand(0)); 970 __ rsb(result, result, Operand(0));
971 __ b(&done); 971 __ b(&done);
972 __ bind(&positive_dividend); 972 __ bind(&positive_dividend);
973 __ and_(result, dividend, Operand(divisor - 1)); 973 __ and_(result, dividend, Operand(divisor - 1));
974 __ bind(&done); 974 __ bind(&done);
975 return; 975 return;
976 } 976 }
977 977
978 // These registers hold untagged 32 bit values. 978 // These registers hold untagged 32 bit values.
979 Register left = ToRegister(instr->left()); 979 Register left = ToRegister(instr->InputAt(0));
980 Register right = ToRegister(instr->right()); 980 Register right = ToRegister(instr->InputAt(1));
981 Register result = ToRegister(instr->result()); 981 Register result = ToRegister(instr->result());
982 982
983 Register scratch = scratch0(); 983 Register scratch = scratch0();
984 Register scratch2 = ToRegister(instr->temp()); 984 Register scratch2 = ToRegister(instr->TempAt(0));
985 DwVfpRegister dividend = ToDoubleRegister(instr->temp2()); 985 DwVfpRegister dividend = ToDoubleRegister(instr->TempAt(1));
986 DwVfpRegister divisor = ToDoubleRegister(instr->temp3()); 986 DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2));
987 DwVfpRegister quotient = double_scratch0(); 987 DwVfpRegister quotient = double_scratch0();
988 988
989 ASSERT(!dividend.is(divisor)); 989 ASSERT(!dividend.is(divisor));
990 ASSERT(!dividend.is(quotient)); 990 ASSERT(!dividend.is(quotient));
991 ASSERT(!divisor.is(quotient)); 991 ASSERT(!divisor.is(quotient));
992 ASSERT(!scratch.is(left)); 992 ASSERT(!scratch.is(left));
993 ASSERT(!scratch.is(right)); 993 ASSERT(!scratch.is(right));
994 ASSERT(!scratch.is(result)); 994 ASSERT(!scratch.is(result));
995 995
996 Label done, vfp_modulo, both_positive, right_negative; 996 Label done, vfp_modulo, both_positive, right_negative;
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 } 1179 }
1180 } 1180 }
1181 1181
1182 1182
1183 void LCodeGen::DoDivI(LDivI* instr) { 1183 void LCodeGen::DoDivI(LDivI* instr) {
1184 class DeferredDivI: public LDeferredCode { 1184 class DeferredDivI: public LDeferredCode {
1185 public: 1185 public:
1186 DeferredDivI(LCodeGen* codegen, LDivI* instr) 1186 DeferredDivI(LCodeGen* codegen, LDivI* instr)
1187 : LDeferredCode(codegen), instr_(instr) { } 1187 : LDeferredCode(codegen), instr_(instr) { }
1188 virtual void Generate() { 1188 virtual void Generate() {
1189 codegen()->DoDeferredBinaryOpStub(instr_->pointer_map(), 1189 codegen()->DoDeferredBinaryOpStub(instr_, Token::DIV);
1190 instr_->left(),
1191 instr_->right(),
1192 Token::DIV);
1193 } 1190 }
1194 virtual LInstruction* instr() { return instr_; } 1191 virtual LInstruction* instr() { return instr_; }
1195 private: 1192 private:
1196 LDivI* instr_; 1193 LDivI* instr_;
1197 }; 1194 };
1198 1195
1199 const Register left = ToRegister(instr->left()); 1196 const Register left = ToRegister(instr->InputAt(0));
1200 const Register right = ToRegister(instr->right()); 1197 const Register right = ToRegister(instr->InputAt(1));
1201 const Register scratch = scratch0(); 1198 const Register scratch = scratch0();
1202 const Register result = ToRegister(instr->result()); 1199 const Register result = ToRegister(instr->result());
1203 1200
1204 // Check for x / 0. 1201 // Check for x / 0.
1205 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1202 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1206 __ cmp(right, Operand(0)); 1203 __ cmp(right, Operand(0));
1207 DeoptimizeIf(eq, instr->environment()); 1204 DeoptimizeIf(eq, instr->environment());
1208 } 1205 }
1209 1206
1210 // Check for (0 / -x) that will produce negative zero. 1207 // Check for (0 / -x) that will produce negative zero.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 __ b(&done); 1256 __ b(&done);
1260 1257
1261 __ bind(&deoptimize); 1258 __ bind(&deoptimize);
1262 DeoptimizeIf(al, instr->environment()); 1259 DeoptimizeIf(al, instr->environment());
1263 __ bind(&done); 1260 __ bind(&done);
1264 } 1261 }
1265 1262
1266 1263
1267 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { 1264 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
1268 const Register result = ToRegister(instr->result()); 1265 const Register result = ToRegister(instr->result());
1269 const Register left = ToRegister(instr->left()); 1266 const Register left = ToRegister(instr->InputAt(0));
1270 const Register remainder = ToRegister(instr->temp()); 1267 const Register remainder = ToRegister(instr->TempAt(0));
1271 const Register scratch = scratch0(); 1268 const Register scratch = scratch0();
1272 1269
1273 // We only optimize this for division by constants, because the standard 1270 // We only optimize this for division by constants, because the standard
1274 // integer division routine is usually slower than transitionning to VFP. 1271 // integer division routine is usually slower than transitionning to VFP.
1275 // This could be optimized on processors with SDIV available. 1272 // This could be optimized on processors with SDIV available.
1276 ASSERT(instr->right()->IsConstantOperand()); 1273 ASSERT(instr->InputAt(1)->IsConstantOperand());
1277 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); 1274 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1)));
1278 if (divisor < 0) { 1275 if (divisor < 0) {
1279 __ cmp(left, Operand(0)); 1276 __ cmp(left, Operand(0));
1280 DeoptimizeIf(eq, instr->environment()); 1277 DeoptimizeIf(eq, instr->environment());
1281 } 1278 }
1282 EmitSignedIntegerDivisionByConstant(result, 1279 EmitSignedIntegerDivisionByConstant(result,
1283 left, 1280 left,
1284 divisor, 1281 divisor,
1285 remainder, 1282 remainder,
1286 scratch, 1283 scratch,
1287 instr->environment()); 1284 instr->environment());
1288 // We operated a truncating division. Correct the result if necessary. 1285 // We operated a truncating division. Correct the result if necessary.
1289 __ cmp(remainder, Operand(0)); 1286 __ cmp(remainder, Operand(0));
1290 __ teq(remainder, Operand(divisor), ne); 1287 __ teq(remainder, Operand(divisor), ne);
1291 __ sub(result, result, Operand(1), LeaveCC, mi); 1288 __ sub(result, result, Operand(1), LeaveCC, mi);
1292 } 1289 }
1293 1290
1294 1291
1295 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, 1292 template<int T>
1296 LOperand* left_argument, 1293 void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
1297 LOperand* right_argument,
1298 Token::Value op) { 1294 Token::Value op) {
1299 Register left = ToRegister(left_argument); 1295 Register left = ToRegister(instr->InputAt(0));
1300 Register right = ToRegister(right_argument); 1296 Register right = ToRegister(instr->InputAt(1));
1301 1297
1302 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles); 1298 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles);
1303 // Move left to r1 and right to r0 for the stub call. 1299 // Move left to r1 and right to r0 for the stub call.
1304 if (left.is(r1)) { 1300 if (left.is(r1)) {
1305 __ Move(r0, right); 1301 __ Move(r0, right);
1306 } else if (left.is(r0) && right.is(r1)) { 1302 } else if (left.is(r0) && right.is(r1)) {
1307 __ Swap(r0, r1, r2); 1303 __ Swap(r0, r1, r2);
1308 } else if (left.is(r0)) { 1304 } else if (left.is(r0)) {
1309 ASSERT(!right.is(r1)); 1305 ASSERT(!right.is(r1));
1310 __ mov(r1, r0); 1306 __ mov(r1, r0);
1311 __ mov(r0, right); 1307 __ mov(r0, right);
1312 } else { 1308 } else {
1313 ASSERT(!left.is(r0) && !right.is(r0)); 1309 ASSERT(!left.is(r0) && !right.is(r0));
1314 __ mov(r0, right); 1310 __ mov(r0, right);
1315 __ mov(r1, left); 1311 __ mov(r1, left);
1316 } 1312 }
1317 BinaryOpStub stub(op, OVERWRITE_LEFT); 1313 BinaryOpStub stub(op, OVERWRITE_LEFT);
1318 __ CallStub(&stub); 1314 __ CallStub(&stub);
1319 RecordSafepointWithRegistersAndDoubles(pointer_map, 1315 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
1320 0, 1316 0,
1321 Safepoint::kNoLazyDeopt); 1317 Safepoint::kNoLazyDeopt);
1322 // Overwrite the stored value of r0 with the result of the stub. 1318 // Overwrite the stored value of r0 with the result of the stub.
1323 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0); 1319 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0);
1324 } 1320 }
1325 1321
1326 1322
1327 void LCodeGen::DoMulI(LMulI* instr) { 1323 void LCodeGen::DoMulI(LMulI* instr) {
1328 Register scratch = scratch0(); 1324 Register scratch = scratch0();
1329 Register result = ToRegister(instr->result()); 1325 Register result = ToRegister(instr->result());
1330 // Note that result may alias left. 1326 // Note that result may alias left.
1331 Register left = ToRegister(instr->left()); 1327 Register left = ToRegister(instr->InputAt(0));
1332 LOperand* right_op = instr->right(); 1328 LOperand* right_op = instr->InputAt(1);
1333 1329
1334 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1330 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1335 bool bailout_on_minus_zero = 1331 bool bailout_on_minus_zero =
1336 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1332 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1337 1333
1338 if (right_op->IsConstantOperand() && !can_overflow) { 1334 if (right_op->IsConstantOperand() && !can_overflow) {
1339 // Use optimized code for specific constants. 1335 // Use optimized code for specific constants.
1340 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); 1336 int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
1341 1337
1342 if (bailout_on_minus_zero && (constant < 0)) { 1338 if (bailout_on_minus_zero && (constant < 0)) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 } else { 1385 } else {
1390 // Generate standard code. 1386 // Generate standard code.
1391 __ mov(ip, Operand(constant)); 1387 __ mov(ip, Operand(constant));
1392 __ mul(result, left, ip); 1388 __ mul(result, left, ip);
1393 } 1389 }
1394 } 1390 }
1395 1391
1396 } else { 1392 } else {
1397 Register right = EmitLoadRegister(right_op, scratch); 1393 Register right = EmitLoadRegister(right_op, scratch);
1398 if (bailout_on_minus_zero) { 1394 if (bailout_on_minus_zero) {
1399 __ orr(ToRegister(instr->temp()), left, right); 1395 __ orr(ToRegister(instr->TempAt(0)), left, right);
1400 } 1396 }
1401 1397
1402 if (can_overflow) { 1398 if (can_overflow) {
1403 // scratch:result = left * right. 1399 // scratch:result = left * right.
1404 __ smull(result, scratch, left, right); 1400 __ smull(result, scratch, left, right);
1405 __ cmp(scratch, Operand(result, ASR, 31)); 1401 __ cmp(scratch, Operand(result, ASR, 31));
1406 DeoptimizeIf(ne, instr->environment()); 1402 DeoptimizeIf(ne, instr->environment());
1407 } else { 1403 } else {
1408 __ mul(result, left, right); 1404 __ mul(result, left, right);
1409 } 1405 }
1410 1406
1411 if (bailout_on_minus_zero) { 1407 if (bailout_on_minus_zero) {
1412 // Bail out if the result is supposed to be negative zero. 1408 // Bail out if the result is supposed to be negative zero.
1413 Label done; 1409 Label done;
1414 __ cmp(result, Operand(0)); 1410 __ cmp(result, Operand(0));
1415 __ b(ne, &done); 1411 __ b(ne, &done);
1416 __ cmp(ToRegister(instr->temp()), Operand(0)); 1412 __ cmp(ToRegister(instr->TempAt(0)), Operand(0));
1417 DeoptimizeIf(mi, instr->environment()); 1413 DeoptimizeIf(mi, instr->environment());
1418 __ bind(&done); 1414 __ bind(&done);
1419 } 1415 }
1420 } 1416 }
1421 } 1417 }
1422 1418
1423 1419
1424 void LCodeGen::DoBitI(LBitI* instr) { 1420 void LCodeGen::DoBitI(LBitI* instr) {
1425 LOperand* left_op = instr->left(); 1421 LOperand* left_op = instr->InputAt(0);
1426 LOperand* right_op = instr->right(); 1422 LOperand* right_op = instr->InputAt(1);
1427 ASSERT(left_op->IsRegister()); 1423 ASSERT(left_op->IsRegister());
1428 Register left = ToRegister(left_op); 1424 Register left = ToRegister(left_op);
1429 Register result = ToRegister(instr->result()); 1425 Register result = ToRegister(instr->result());
1430 Operand right(no_reg); 1426 Operand right(no_reg);
1431 1427
1432 if (right_op->IsStackSlot() || right_op->IsArgument()) { 1428 if (right_op->IsStackSlot() || right_op->IsArgument()) {
1433 right = Operand(EmitLoadRegister(right_op, ip)); 1429 right = Operand(EmitLoadRegister(right_op, ip));
1434 } else { 1430 } else {
1435 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); 1431 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
1436 right = ToOperand(right_op); 1432 right = ToOperand(right_op);
(...skipping 12 matching lines...) Expand all
1449 default: 1445 default:
1450 UNREACHABLE(); 1446 UNREACHABLE();
1451 break; 1447 break;
1452 } 1448 }
1453 } 1449 }
1454 1450
1455 1451
1456 void LCodeGen::DoShiftI(LShiftI* instr) { 1452 void LCodeGen::DoShiftI(LShiftI* instr) {
1457 // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so 1453 // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so
1458 // result may alias either of them. 1454 // result may alias either of them.
1459 LOperand* right_op = instr->right(); 1455 LOperand* right_op = instr->InputAt(1);
1460 Register left = ToRegister(instr->left()); 1456 Register left = ToRegister(instr->InputAt(0));
1461 Register result = ToRegister(instr->result()); 1457 Register result = ToRegister(instr->result());
1462 Register scratch = scratch0(); 1458 Register scratch = scratch0();
1463 if (right_op->IsRegister()) { 1459 if (right_op->IsRegister()) {
1464 // Mask the right_op operand. 1460 // Mask the right_op operand.
1465 __ and_(scratch, ToRegister(right_op), Operand(0x1F)); 1461 __ and_(scratch, ToRegister(right_op), Operand(0x1F));
1466 switch (instr->op()) { 1462 switch (instr->op()) {
1467 case Token::SAR: 1463 case Token::SAR:
1468 __ mov(result, Operand(left, ASR, scratch)); 1464 __ mov(result, Operand(left, ASR, scratch));
1469 break; 1465 break;
1470 case Token::SHR: 1466 case Token::SHR:
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1514 break; 1510 break;
1515 default: 1511 default:
1516 UNREACHABLE(); 1512 UNREACHABLE();
1517 break; 1513 break;
1518 } 1514 }
1519 } 1515 }
1520 } 1516 }
1521 1517
1522 1518
1523 void LCodeGen::DoSubI(LSubI* instr) { 1519 void LCodeGen::DoSubI(LSubI* instr) {
1524 LOperand* left = instr->left(); 1520 LOperand* left = instr->InputAt(0);
1525 LOperand* right = instr->right(); 1521 LOperand* right = instr->InputAt(1);
1526 LOperand* result = instr->result(); 1522 LOperand* result = instr->result();
1527 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1523 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1528 SBit set_cond = can_overflow ? SetCC : LeaveCC; 1524 SBit set_cond = can_overflow ? SetCC : LeaveCC;
1529 1525
1530 if (right->IsStackSlot() || right->IsArgument()) { 1526 if (right->IsStackSlot() || right->IsArgument()) {
1531 Register right_reg = EmitLoadRegister(right, ip); 1527 Register right_reg = EmitLoadRegister(right, ip);
1532 __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); 1528 __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
1533 } else { 1529 } else {
1534 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1530 ASSERT(right->IsRegister() || right->IsConstantOperand());
1535 __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); 1531 __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
1536 } 1532 }
1537 1533
1538 if (can_overflow) { 1534 if (can_overflow) {
1539 DeoptimizeIf(vs, instr->environment()); 1535 DeoptimizeIf(vs, instr->environment());
1540 } 1536 }
1541 } 1537 }
1542 1538
1543 1539
1544 void LCodeGen::DoConstantI(LConstantI* instr) { 1540 void LCodeGen::DoConstantI(LConstantI* instr) {
1545 ASSERT(instr->result()->IsRegister()); 1541 ASSERT(instr->result()->IsRegister());
1546 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1542 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1547 } 1543 }
1548 1544
1549 1545
1550 void LCodeGen::DoConstantD(LConstantD* instr) { 1546 void LCodeGen::DoConstantD(LConstantD* instr) {
1551 ASSERT(instr->result()->IsDoubleRegister()); 1547 ASSERT(instr->result()->IsDoubleRegister());
1552 DwVfpRegister result = ToDoubleRegister(instr->result()); 1548 DwVfpRegister result = ToDoubleRegister(instr->result());
1553 double v = instr->value(); 1549 double v = instr->value();
1554 __ Vmov(result, v, scratch0()); 1550 __ Vmov(result, v);
1555 } 1551 }
1556 1552
1557 1553
1558 void LCodeGen::DoConstantT(LConstantT* instr) { 1554 void LCodeGen::DoConstantT(LConstantT* instr) {
1559 Handle<Object> value = instr->value(); 1555 Handle<Object> value = instr->value();
1560 if (value->IsSmi()) { 1556 if (value->IsSmi()) {
1561 __ mov(ToRegister(instr->result()), Operand(value)); 1557 __ mov(ToRegister(instr->result()), Operand(value));
1562 } else { 1558 } else {
1563 __ LoadHeapObject(ToRegister(instr->result()), 1559 __ LoadHeapObject(ToRegister(instr->result()),
1564 Handle<HeapObject>::cast(value)); 1560 Handle<HeapObject>::cast(value));
1565 } 1561 }
1566 } 1562 }
1567 1563
1568 1564
1569 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1565 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1570 Register result = ToRegister(instr->result()); 1566 Register result = ToRegister(instr->result());
1571 Register array = ToRegister(instr->value()); 1567 Register array = ToRegister(instr->InputAt(0));
1572 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset)); 1568 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset));
1573 } 1569 }
1574 1570
1575 1571
1576 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { 1572 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
1577 Register result = ToRegister(instr->result()); 1573 Register result = ToRegister(instr->result());
1578 Register array = ToRegister(instr->value()); 1574 Register array = ToRegister(instr->InputAt(0));
1579 __ ldr(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset)); 1575 __ ldr(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset));
1580 } 1576 }
1581 1577
1582 1578
1583 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1579 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1584 Register result = ToRegister(instr->result()); 1580 Register result = ToRegister(instr->result());
1585 Register map = ToRegister(instr->value()); 1581 Register map = ToRegister(instr->InputAt(0));
1586 __ EnumLength(result, map); 1582 __ EnumLength(result, map);
1587 } 1583 }
1588 1584
1589 1585
1590 void LCodeGen::DoElementsKind(LElementsKind* instr) { 1586 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1591 Register result = ToRegister(instr->result()); 1587 Register result = ToRegister(instr->result());
1592 Register input = ToRegister(instr->value()); 1588 Register input = ToRegister(instr->InputAt(0));
1593 1589
1594 // Load map into |result|. 1590 // Load map into |result|.
1595 __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset)); 1591 __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset));
1596 // Load the map's "bit field 2" into |result|. We only need the first byte, 1592 // Load the map's "bit field 2" into |result|. We only need the first byte,
1597 // but the following bit field extraction takes care of that anyway. 1593 // but the following bit field extraction takes care of that anyway.
1598 __ ldr(result, FieldMemOperand(result, Map::kBitField2Offset)); 1594 __ ldr(result, FieldMemOperand(result, Map::kBitField2Offset));
1599 // Retrieve elements_kind from bit field 2. 1595 // Retrieve elements_kind from bit field 2.
1600 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); 1596 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount);
1601 } 1597 }
1602 1598
1603 1599
1604 void LCodeGen::DoValueOf(LValueOf* instr) { 1600 void LCodeGen::DoValueOf(LValueOf* instr) {
1605 Register input = ToRegister(instr->value()); 1601 Register input = ToRegister(instr->InputAt(0));
1606 Register result = ToRegister(instr->result()); 1602 Register result = ToRegister(instr->result());
1607 Register map = ToRegister(instr->temp()); 1603 Register map = ToRegister(instr->TempAt(0));
1608 Label done; 1604 Label done;
1609 1605
1610 // If the object is a smi return the object. 1606 // If the object is a smi return the object.
1611 __ tst(input, Operand(kSmiTagMask)); 1607 __ tst(input, Operand(kSmiTagMask));
1612 __ Move(result, input, eq); 1608 __ Move(result, input, eq);
1613 __ b(eq, &done); 1609 __ b(eq, &done);
1614 1610
1615 // If the object is not a value type, return the object. 1611 // If the object is not a value type, return the object.
1616 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); 1612 __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
1617 __ Move(result, input, ne); 1613 __ Move(result, input, ne);
1618 __ b(ne, &done); 1614 __ b(ne, &done);
1619 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); 1615 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset));
1620 1616
1621 __ bind(&done); 1617 __ bind(&done);
1622 } 1618 }
1623 1619
1624 1620
1625 void LCodeGen::DoDateField(LDateField* instr) { 1621 void LCodeGen::DoDateField(LDateField* instr) {
1626 Register object = ToRegister(instr->date()); 1622 Register object = ToRegister(instr->InputAt(0));
1627 Register result = ToRegister(instr->result()); 1623 Register result = ToRegister(instr->result());
1628 Register scratch = ToRegister(instr->temp()); 1624 Register scratch = ToRegister(instr->TempAt(0));
1629 Smi* index = instr->index(); 1625 Smi* index = instr->index();
1630 Label runtime, done; 1626 Label runtime, done;
1631 ASSERT(object.is(result)); 1627 ASSERT(object.is(result));
1632 ASSERT(object.is(r0)); 1628 ASSERT(object.is(r0));
1633 ASSERT(!scratch.is(scratch0())); 1629 ASSERT(!scratch.is(scratch0()));
1634 ASSERT(!scratch.is(object)); 1630 ASSERT(!scratch.is(object));
1635 1631
1636 __ tst(object, Operand(kSmiTagMask)); 1632 __ tst(object, Operand(kSmiTagMask));
1637 DeoptimizeIf(eq, instr->environment()); 1633 DeoptimizeIf(eq, instr->environment());
1638 __ CompareObjectType(object, scratch, scratch, JS_DATE_TYPE); 1634 __ CompareObjectType(object, scratch, scratch, JS_DATE_TYPE);
(...skipping 16 matching lines...) Expand all
1655 __ bind(&runtime); 1651 __ bind(&runtime);
1656 __ PrepareCallCFunction(2, scratch); 1652 __ PrepareCallCFunction(2, scratch);
1657 __ mov(r1, Operand(index)); 1653 __ mov(r1, Operand(index));
1658 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 1654 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
1659 __ bind(&done); 1655 __ bind(&done);
1660 } 1656 }
1661 } 1657 }
1662 1658
1663 1659
1664 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1660 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1665 Register input = ToRegister(instr->value()); 1661 Register input = ToRegister(instr->InputAt(0));
1666 Register result = ToRegister(instr->result()); 1662 Register result = ToRegister(instr->result());
1667 __ mvn(result, Operand(input)); 1663 __ mvn(result, Operand(input));
1668 } 1664 }
1669 1665
1670 1666
1671 void LCodeGen::DoThrow(LThrow* instr) { 1667 void LCodeGen::DoThrow(LThrow* instr) {
1672 Register input_reg = EmitLoadRegister(instr->value(), ip); 1668 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
1673 __ push(input_reg); 1669 __ push(input_reg);
1674 CallRuntime(Runtime::kThrow, 1, instr); 1670 CallRuntime(Runtime::kThrow, 1, instr);
1675 1671
1676 if (FLAG_debug_code) { 1672 if (FLAG_debug_code) {
1677 __ stop("Unreachable code."); 1673 __ stop("Unreachable code.");
1678 } 1674 }
1679 } 1675 }
1680 1676
1681 1677
1682 void LCodeGen::DoAddI(LAddI* instr) { 1678 void LCodeGen::DoAddI(LAddI* instr) {
1683 LOperand* left = instr->left(); 1679 LOperand* left = instr->InputAt(0);
1684 LOperand* right = instr->right(); 1680 LOperand* right = instr->InputAt(1);
1685 LOperand* result = instr->result(); 1681 LOperand* result = instr->result();
1686 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1682 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1687 SBit set_cond = can_overflow ? SetCC : LeaveCC; 1683 SBit set_cond = can_overflow ? SetCC : LeaveCC;
1688 1684
1689 if (right->IsStackSlot() || right->IsArgument()) { 1685 if (right->IsStackSlot() || right->IsArgument()) {
1690 Register right_reg = EmitLoadRegister(right, ip); 1686 Register right_reg = EmitLoadRegister(right, ip);
1691 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); 1687 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
1692 } else { 1688 } else {
1693 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1689 ASSERT(right->IsRegister() || right->IsConstantOperand());
1694 __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); 1690 __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
1695 } 1691 }
1696 1692
1697 if (can_overflow) { 1693 if (can_overflow) {
1698 DeoptimizeIf(vs, instr->environment()); 1694 DeoptimizeIf(vs, instr->environment());
1699 } 1695 }
1700 } 1696 }
1701 1697
1702 1698
1703 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1699 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1704 LOperand* left = instr->left(); 1700 LOperand* left = instr->InputAt(0);
1705 LOperand* right = instr->right(); 1701 LOperand* right = instr->InputAt(1);
1706 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1702 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1707 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; 1703 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
1708 if (instr->hydrogen()->representation().IsInteger32()) { 1704 if (instr->hydrogen()->representation().IsInteger32()) {
1709 Register left_reg = ToRegister(left); 1705 Register left_reg = ToRegister(left);
1710 Operand right_op = (right->IsRegister() || right->IsConstantOperand()) 1706 Operand right_op = (right->IsRegister() || right->IsConstantOperand())
1711 ? ToOperand(right) 1707 ? ToOperand(right)
1712 : Operand(EmitLoadRegister(right, ip)); 1708 : Operand(EmitLoadRegister(right, ip));
1713 Register result_reg = ToRegister(instr->result()); 1709 Register result_reg = ToRegister(instr->result());
1714 __ cmp(left_reg, right_op); 1710 __ cmp(left_reg, right_op);
1715 if (!result_reg.is(left_reg)) { 1711 if (!result_reg.is(left_reg)) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 __ bind(&return_left); 1752 __ bind(&return_left);
1757 if (!left_reg.is(result_reg)) { 1753 if (!left_reg.is(result_reg)) {
1758 __ vmov(result_reg, left_reg); 1754 __ vmov(result_reg, left_reg);
1759 } 1755 }
1760 __ bind(&done); 1756 __ bind(&done);
1761 } 1757 }
1762 } 1758 }
1763 1759
1764 1760
1765 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1761 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1766 DoubleRegister left = ToDoubleRegister(instr->left()); 1762 DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
1767 DoubleRegister right = ToDoubleRegister(instr->right()); 1763 DoubleRegister right = ToDoubleRegister(instr->InputAt(1));
1768 DoubleRegister result = ToDoubleRegister(instr->result()); 1764 DoubleRegister result = ToDoubleRegister(instr->result());
1769 switch (instr->op()) { 1765 switch (instr->op()) {
1770 case Token::ADD: 1766 case Token::ADD:
1771 __ vadd(result, left, right); 1767 __ vadd(result, left, right);
1772 break; 1768 break;
1773 case Token::SUB: 1769 case Token::SUB:
1774 __ vsub(result, left, right); 1770 __ vsub(result, left, right);
1775 break; 1771 break;
1776 case Token::MUL: 1772 case Token::MUL:
1777 __ vmul(result, left, right); 1773 __ vmul(result, left, right);
(...skipping 18 matching lines...) Expand all
1796 break; 1792 break;
1797 } 1793 }
1798 default: 1794 default:
1799 UNREACHABLE(); 1795 UNREACHABLE();
1800 break; 1796 break;
1801 } 1797 }
1802 } 1798 }
1803 1799
1804 1800
1805 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1801 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1806 ASSERT(ToRegister(instr->left()).is(r1)); 1802 ASSERT(ToRegister(instr->InputAt(0)).is(r1));
1807 ASSERT(ToRegister(instr->right()).is(r0)); 1803 ASSERT(ToRegister(instr->InputAt(1)).is(r0));
1808 ASSERT(ToRegister(instr->result()).is(r0)); 1804 ASSERT(ToRegister(instr->result()).is(r0));
1809 1805
1810 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 1806 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
1811 // Block literal pool emission to ensure nop indicating no inlined smi code 1807 // Block literal pool emission to ensure nop indicating no inlined smi code
1812 // is in the correct position. 1808 // is in the correct position.
1813 Assembler::BlockConstPoolScope block_const_pool(masm()); 1809 Assembler::BlockConstPoolScope block_const_pool(masm());
1814 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1810 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1815 __ nop(); // Signals no inlined code. 1811 __ nop(); // Signals no inlined code.
1816 } 1812 }
1817 1813
(...skipping 24 matching lines...) Expand all
1842 } 1838 }
1843 } 1839 }
1844 1840
1845 1841
1846 void LCodeGen::DoBranch(LBranch* instr) { 1842 void LCodeGen::DoBranch(LBranch* instr) {
1847 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1843 int true_block = chunk_->LookupDestination(instr->true_block_id());
1848 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1844 int false_block = chunk_->LookupDestination(instr->false_block_id());
1849 1845
1850 Representation r = instr->hydrogen()->value()->representation(); 1846 Representation r = instr->hydrogen()->value()->representation();
1851 if (r.IsInteger32()) { 1847 if (r.IsInteger32()) {
1852 Register reg = ToRegister(instr->value()); 1848 Register reg = ToRegister(instr->InputAt(0));
1853 __ cmp(reg, Operand(0)); 1849 __ cmp(reg, Operand(0));
1854 EmitBranch(true_block, false_block, ne); 1850 EmitBranch(true_block, false_block, ne);
1855 } else if (r.IsDouble()) { 1851 } else if (r.IsDouble()) {
1856 DoubleRegister reg = ToDoubleRegister(instr->value()); 1852 DoubleRegister reg = ToDoubleRegister(instr->InputAt(0));
1857 Register scratch = scratch0(); 1853 Register scratch = scratch0();
1858 1854
1859 // Test the double value. Zero and NaN are false. 1855 // Test the double value. Zero and NaN are false.
1860 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); 1856 __ VFPCompareAndLoadFlags(reg, 0.0, scratch);
1861 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); 1857 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
1862 EmitBranch(true_block, false_block, eq); 1858 EmitBranch(true_block, false_block, eq);
1863 } else { 1859 } else {
1864 ASSERT(r.IsTagged()); 1860 ASSERT(r.IsTagged());
1865 Register reg = ToRegister(instr->value()); 1861 Register reg = ToRegister(instr->InputAt(0));
1866 HType type = instr->hydrogen()->value()->type(); 1862 HType type = instr->hydrogen()->value()->type();
1867 if (type.IsBoolean()) { 1863 if (type.IsBoolean()) {
1868 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 1864 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1869 EmitBranch(true_block, false_block, eq); 1865 EmitBranch(true_block, false_block, eq);
1870 } else if (type.IsSmi()) { 1866 } else if (type.IsSmi()) {
1871 __ cmp(reg, Operand(0)); 1867 __ cmp(reg, Operand(0));
1872 EmitBranch(true_block, false_block, ne); 1868 EmitBranch(true_block, false_block, ne);
1873 } else { 1869 } else {
1874 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1870 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1875 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1871 Label* false_label = chunk_->GetAssemblyLabel(false_block);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1994 case Token::IN: 1990 case Token::IN:
1995 case Token::INSTANCEOF: 1991 case Token::INSTANCEOF:
1996 default: 1992 default:
1997 UNREACHABLE(); 1993 UNREACHABLE();
1998 } 1994 }
1999 return cond; 1995 return cond;
2000 } 1996 }
2001 1997
2002 1998
2003 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1999 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
2004 LOperand* left = instr->left(); 2000 LOperand* left = instr->InputAt(0);
2005 LOperand* right = instr->right(); 2001 LOperand* right = instr->InputAt(1);
2006 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2002 int false_block = chunk_->LookupDestination(instr->false_block_id());
2007 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2003 int true_block = chunk_->LookupDestination(instr->true_block_id());
2008 Condition cond = TokenToCondition(instr->op(), false); 2004 Condition cond = TokenToCondition(instr->op(), false);
2009 2005
2010 if (left->IsConstantOperand() && right->IsConstantOperand()) { 2006 if (left->IsConstantOperand() && right->IsConstantOperand()) {
2011 // We can statically evaluate the comparison. 2007 // We can statically evaluate the comparison.
2012 double left_val = ToDouble(LConstantOperand::cast(left)); 2008 double left_val = ToDouble(LConstantOperand::cast(left));
2013 double right_val = ToDouble(LConstantOperand::cast(right)); 2009 double right_val = ToDouble(LConstantOperand::cast(right));
2014 int next_block = 2010 int next_block =
2015 EvalComparison(instr->op(), left_val, right_val) ? true_block 2011 EvalComparison(instr->op(), left_val, right_val) ? true_block
(...skipping 19 matching lines...) Expand all
2035 } else { 2031 } else {
2036 __ cmp(ToRegister(left), ToRegister(right)); 2032 __ cmp(ToRegister(left), ToRegister(right));
2037 } 2033 }
2038 } 2034 }
2039 EmitBranch(true_block, false_block, cond); 2035 EmitBranch(true_block, false_block, cond);
2040 } 2036 }
2041 } 2037 }
2042 2038
2043 2039
2044 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 2040 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2045 Register left = ToRegister(instr->left()); 2041 Register left = ToRegister(instr->InputAt(0));
2046 Register right = ToRegister(instr->right()); 2042 Register right = ToRegister(instr->InputAt(1));
2047 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2043 int false_block = chunk_->LookupDestination(instr->false_block_id());
2048 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2044 int true_block = chunk_->LookupDestination(instr->true_block_id());
2049 2045
2050 __ cmp(left, Operand(right)); 2046 __ cmp(left, Operand(right));
2051 EmitBranch(true_block, false_block, eq); 2047 EmitBranch(true_block, false_block, eq);
2052 } 2048 }
2053 2049
2054 2050
2055 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 2051 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
2056 Register left = ToRegister(instr->left()); 2052 Register left = ToRegister(instr->InputAt(0));
2057 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2053 int true_block = chunk_->LookupDestination(instr->true_block_id());
2058 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2054 int false_block = chunk_->LookupDestination(instr->false_block_id());
2059 2055
2060 __ cmp(left, Operand(instr->hydrogen()->right())); 2056 __ cmp(left, Operand(instr->hydrogen()->right()));
2061 EmitBranch(true_block, false_block, eq); 2057 EmitBranch(true_block, false_block, eq);
2062 } 2058 }
2063 2059
2064 2060
2065 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) { 2061 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
2066 Register scratch = scratch0(); 2062 Register scratch = scratch0();
2067 Register reg = ToRegister(instr->value()); 2063 Register reg = ToRegister(instr->InputAt(0));
2068 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2064 int false_block = chunk_->LookupDestination(instr->false_block_id());
2069 2065
2070 // If the expression is known to be untagged or a smi, then it's definitely 2066 // If the expression is known to be untagged or a smi, then it's definitely
2071 // not null, and it can't be a an undetectable object. 2067 // not null, and it can't be a an undetectable object.
2072 if (instr->hydrogen()->representation().IsSpecialization() || 2068 if (instr->hydrogen()->representation().IsSpecialization() ||
2073 instr->hydrogen()->type().IsSmi()) { 2069 instr->hydrogen()->type().IsSmi()) {
2074 EmitGoto(false_block); 2070 EmitGoto(false_block);
2075 return; 2071 return;
2076 } 2072 }
2077 2073
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2125 // Load instance type and check that it is in object type range. 2121 // Load instance type and check that it is in object type range.
2126 __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset)); 2122 __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset));
2127 __ cmp(temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2123 __ cmp(temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
2128 __ b(lt, is_not_object); 2124 __ b(lt, is_not_object);
2129 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2125 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
2130 return le; 2126 return le;
2131 } 2127 }
2132 2128
2133 2129
2134 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 2130 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2135 Register reg = ToRegister(instr->value()); 2131 Register reg = ToRegister(instr->InputAt(0));
2136 Register temp1 = ToRegister(instr->temp()); 2132 Register temp1 = ToRegister(instr->TempAt(0));
2137 2133
2138 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2134 int true_block = chunk_->LookupDestination(instr->true_block_id());
2139 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2135 int false_block = chunk_->LookupDestination(instr->false_block_id());
2140 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2136 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2141 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2137 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2142 2138
2143 Condition true_cond = 2139 Condition true_cond =
2144 EmitIsObject(reg, temp1, false_label, true_label); 2140 EmitIsObject(reg, temp1, false_label, true_label);
2145 2141
2146 EmitBranch(true_block, false_block, true_cond); 2142 EmitBranch(true_block, false_block, true_cond);
2147 } 2143 }
2148 2144
2149 2145
2150 Condition LCodeGen::EmitIsString(Register input, 2146 Condition LCodeGen::EmitIsString(Register input,
2151 Register temp1, 2147 Register temp1,
2152 Label* is_not_string) { 2148 Label* is_not_string) {
2153 __ JumpIfSmi(input, is_not_string); 2149 __ JumpIfSmi(input, is_not_string);
2154 __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE); 2150 __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE);
2155 2151
2156 return lt; 2152 return lt;
2157 } 2153 }
2158 2154
2159 2155
2160 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 2156 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2161 Register reg = ToRegister(instr->value()); 2157 Register reg = ToRegister(instr->InputAt(0));
2162 Register temp1 = ToRegister(instr->temp()); 2158 Register temp1 = ToRegister(instr->TempAt(0));
2163 2159
2164 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2160 int true_block = chunk_->LookupDestination(instr->true_block_id());
2165 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2161 int false_block = chunk_->LookupDestination(instr->false_block_id());
2166 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2162 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2167 2163
2168 Condition true_cond = 2164 Condition true_cond =
2169 EmitIsString(reg, temp1, false_label); 2165 EmitIsString(reg, temp1, false_label);
2170 2166
2171 EmitBranch(true_block, false_block, true_cond); 2167 EmitBranch(true_block, false_block, true_cond);
2172 } 2168 }
2173 2169
2174 2170
2175 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 2171 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2176 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2172 int true_block = chunk_->LookupDestination(instr->true_block_id());
2177 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2173 int false_block = chunk_->LookupDestination(instr->false_block_id());
2178 2174
2179 Register input_reg = EmitLoadRegister(instr->value(), ip); 2175 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
2180 __ tst(input_reg, Operand(kSmiTagMask)); 2176 __ tst(input_reg, Operand(kSmiTagMask));
2181 EmitBranch(true_block, false_block, eq); 2177 EmitBranch(true_block, false_block, eq);
2182 } 2178 }
2183 2179
2184 2180
2185 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 2181 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2186 Register input = ToRegister(instr->value()); 2182 Register input = ToRegister(instr->InputAt(0));
2187 Register temp = ToRegister(instr->temp()); 2183 Register temp = ToRegister(instr->TempAt(0));
2188 2184
2189 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2185 int true_block = chunk_->LookupDestination(instr->true_block_id());
2190 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2186 int false_block = chunk_->LookupDestination(instr->false_block_id());
2191 2187
2192 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 2188 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
2193 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); 2189 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset));
2194 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); 2190 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
2195 __ tst(temp, Operand(1 << Map::kIsUndetectable)); 2191 __ tst(temp, Operand(1 << Map::kIsUndetectable));
2196 EmitBranch(true_block, false_block, ne); 2192 EmitBranch(true_block, false_block, ne);
2197 } 2193 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2247 if (from == to) return eq; 2243 if (from == to) return eq;
2248 if (to == LAST_TYPE) return hs; 2244 if (to == LAST_TYPE) return hs;
2249 if (from == FIRST_TYPE) return ls; 2245 if (from == FIRST_TYPE) return ls;
2250 UNREACHABLE(); 2246 UNREACHABLE();
2251 return eq; 2247 return eq;
2252 } 2248 }
2253 2249
2254 2250
2255 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2251 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2256 Register scratch = scratch0(); 2252 Register scratch = scratch0();
2257 Register input = ToRegister(instr->value()); 2253 Register input = ToRegister(instr->InputAt(0));
2258 2254
2259 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2255 int true_block = chunk_->LookupDestination(instr->true_block_id());
2260 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2256 int false_block = chunk_->LookupDestination(instr->false_block_id());
2261 2257
2262 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2258 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2263 2259
2264 __ JumpIfSmi(input, false_label); 2260 __ JumpIfSmi(input, false_label);
2265 2261
2266 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); 2262 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen()));
2267 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 2263 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
2268 } 2264 }
2269 2265
2270 2266
2271 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2267 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2272 Register input = ToRegister(instr->value()); 2268 Register input = ToRegister(instr->InputAt(0));
2273 Register result = ToRegister(instr->result()); 2269 Register result = ToRegister(instr->result());
2274 2270
2275 __ AbortIfNotString(input); 2271 __ AbortIfNotString(input);
2276 2272
2277 __ ldr(result, FieldMemOperand(input, String::kHashFieldOffset)); 2273 __ ldr(result, FieldMemOperand(input, String::kHashFieldOffset));
2278 __ IndexFromHash(result, result); 2274 __ IndexFromHash(result, result);
2279 } 2275 }
2280 2276
2281 2277
2282 void LCodeGen::DoHasCachedArrayIndexAndBranch( 2278 void LCodeGen::DoHasCachedArrayIndexAndBranch(
2283 LHasCachedArrayIndexAndBranch* instr) { 2279 LHasCachedArrayIndexAndBranch* instr) {
2284 Register input = ToRegister(instr->value()); 2280 Register input = ToRegister(instr->InputAt(0));
2285 Register scratch = scratch0(); 2281 Register scratch = scratch0();
2286 2282
2287 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2283 int true_block = chunk_->LookupDestination(instr->true_block_id());
2288 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2284 int false_block = chunk_->LookupDestination(instr->false_block_id());
2289 2285
2290 __ ldr(scratch, 2286 __ ldr(scratch,
2291 FieldMemOperand(input, String::kHashFieldOffset)); 2287 FieldMemOperand(input, String::kHashFieldOffset));
2292 __ tst(scratch, Operand(String::kContainsCachedArrayIndexMask)); 2288 __ tst(scratch, Operand(String::kContainsCachedArrayIndexMask));
2293 EmitBranch(true_block, false_block, eq); 2289 EmitBranch(true_block, false_block, eq);
2294 } 2290 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2355 // booted. This routine isn't expected to work for random API-created 2351 // booted. This routine isn't expected to work for random API-created
2356 // classes and it doesn't have to because you can't access it with natives 2352 // classes and it doesn't have to because you can't access it with natives
2357 // syntax. Since both sides are symbols it is sufficient to use an identity 2353 // syntax. Since both sides are symbols it is sufficient to use an identity
2358 // comparison. 2354 // comparison.
2359 __ cmp(temp, Operand(class_name)); 2355 __ cmp(temp, Operand(class_name));
2360 // End with the answer in flags. 2356 // End with the answer in flags.
2361 } 2357 }
2362 2358
2363 2359
2364 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2360 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2365 Register input = ToRegister(instr->value()); 2361 Register input = ToRegister(instr->InputAt(0));
2366 Register temp = scratch0(); 2362 Register temp = scratch0();
2367 Register temp2 = ToRegister(instr->temp()); 2363 Register temp2 = ToRegister(instr->TempAt(0));
2368 Handle<String> class_name = instr->hydrogen()->class_name(); 2364 Handle<String> class_name = instr->hydrogen()->class_name();
2369 2365
2370 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2366 int true_block = chunk_->LookupDestination(instr->true_block_id());
2371 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2367 int false_block = chunk_->LookupDestination(instr->false_block_id());
2372 2368
2373 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2369 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2374 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2370 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2375 2371
2376 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 2372 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
2377 2373
2378 EmitBranch(true_block, false_block, eq); 2374 EmitBranch(true_block, false_block, eq);
2379 } 2375 }
2380 2376
2381 2377
2382 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2378 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2383 Register reg = ToRegister(instr->value()); 2379 Register reg = ToRegister(instr->InputAt(0));
2384 Register temp = ToRegister(instr->temp()); 2380 Register temp = ToRegister(instr->TempAt(0));
2385 int true_block = instr->true_block_id(); 2381 int true_block = instr->true_block_id();
2386 int false_block = instr->false_block_id(); 2382 int false_block = instr->false_block_id();
2387 2383
2388 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); 2384 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
2389 __ cmp(temp, Operand(instr->map())); 2385 __ cmp(temp, Operand(instr->map()));
2390 EmitBranch(true_block, false_block, eq); 2386 EmitBranch(true_block, false_block, eq);
2391 } 2387 }
2392 2388
2393 2389
2394 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2390 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2395 ASSERT(ToRegister(instr->left()).is(r0)); // Object is in r0. 2391 ASSERT(ToRegister(instr->InputAt(0)).is(r0)); // Object is in r0.
2396 ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1. 2392 ASSERT(ToRegister(instr->InputAt(1)).is(r1)); // Function is in r1.
2397 2393
2398 InstanceofStub stub(InstanceofStub::kArgsInRegisters); 2394 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
2399 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2395 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2400 2396
2401 __ cmp(r0, Operand(0)); 2397 __ cmp(r0, Operand(0));
2402 __ mov(r0, Operand(factory()->false_value()), LeaveCC, ne); 2398 __ mov(r0, Operand(factory()->false_value()), LeaveCC, ne);
2403 __ mov(r0, Operand(factory()->true_value()), LeaveCC, eq); 2399 __ mov(r0, Operand(factory()->true_value()), LeaveCC, eq);
2404 } 2400 }
2405 2401
2406 2402
(...skipping 10 matching lines...) Expand all
2417 Label* map_check() { return &map_check_; } 2413 Label* map_check() { return &map_check_; }
2418 private: 2414 private:
2419 LInstanceOfKnownGlobal* instr_; 2415 LInstanceOfKnownGlobal* instr_;
2420 Label map_check_; 2416 Label map_check_;
2421 }; 2417 };
2422 2418
2423 DeferredInstanceOfKnownGlobal* deferred; 2419 DeferredInstanceOfKnownGlobal* deferred;
2424 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 2420 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2425 2421
2426 Label done, false_result; 2422 Label done, false_result;
2427 Register object = ToRegister(instr->value()); 2423 Register object = ToRegister(instr->InputAt(0));
2428 Register temp = ToRegister(instr->temp()); 2424 Register temp = ToRegister(instr->TempAt(0));
2429 Register result = ToRegister(instr->result()); 2425 Register result = ToRegister(instr->result());
2430 2426
2431 ASSERT(object.is(r0)); 2427 ASSERT(object.is(r0));
2432 ASSERT(result.is(r0)); 2428 ASSERT(result.is(r0));
2433 2429
2434 // A Smi is not instance of anything. 2430 // A Smi is not instance of anything.
2435 __ JumpIfSmi(object, &false_result); 2431 __ JumpIfSmi(object, &false_result);
2436 2432
2437 // This is the inlined call site instanceof cache. The two occurences of the 2433 // This is the inlined call site instanceof cache. The two occurences of the
2438 // hole value will be patched to the last map/result pair generated by the 2434 // hole value will be patched to the last map/result pair generated by the
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2498 flags | InstanceofStub::kCallSiteInlineCheck); 2494 flags | InstanceofStub::kCallSiteInlineCheck);
2499 flags = static_cast<InstanceofStub::Flags>( 2495 flags = static_cast<InstanceofStub::Flags>(
2500 flags | InstanceofStub::kReturnTrueFalseObject); 2496 flags | InstanceofStub::kReturnTrueFalseObject);
2501 InstanceofStub stub(flags); 2497 InstanceofStub stub(flags);
2502 2498
2503 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 2499 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2504 2500
2505 // Get the temp register reserved by the instruction. This needs to be r4 as 2501 // Get the temp register reserved by the instruction. This needs to be r4 as
2506 // its slot of the pushing of safepoint registers is used to communicate the 2502 // its slot of the pushing of safepoint registers is used to communicate the
2507 // offset to the location of the map check. 2503 // offset to the location of the map check.
2508 Register temp = ToRegister(instr->temp()); 2504 Register temp = ToRegister(instr->TempAt(0));
2509 ASSERT(temp.is(r4)); 2505 ASSERT(temp.is(r4));
2510 __ LoadHeapObject(InstanceofStub::right(), instr->function()); 2506 __ LoadHeapObject(InstanceofStub::right(), instr->function());
2511 static const int kAdditionalDelta = 5; 2507 static const int kAdditionalDelta = 5;
2512 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; 2508 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
2513 Label before_push_delta; 2509 Label before_push_delta;
2514 __ bind(&before_push_delta); 2510 __ bind(&before_push_delta);
2515 __ BlockConstPoolFor(kAdditionalDelta); 2511 __ BlockConstPoolFor(kAdditionalDelta);
2516 __ mov(temp, Operand(delta * kPointerSize)); 2512 __ mov(temp, Operand(delta * kPointerSize));
2517 // The mov above can generate one or two instructions. The delta was computed 2513 // The mov above can generate one or two instructions. The delta was computed
2518 // for two instructions, so we need to pad here in case of one instruction. 2514 // for two instructions, so we need to pad here in case of one instruction.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2595 2591
2596 // Load the cell. 2592 // Load the cell.
2597 __ mov(cell, Operand(instr->hydrogen()->cell())); 2593 __ mov(cell, Operand(instr->hydrogen()->cell()));
2598 2594
2599 // If the cell we are storing to contains the hole it could have 2595 // If the cell we are storing to contains the hole it could have
2600 // been deleted from the property dictionary. In that case, we need 2596 // been deleted from the property dictionary. In that case, we need
2601 // to update the property details in the property dictionary to mark 2597 // to update the property details in the property dictionary to mark
2602 // it as no longer deleted. 2598 // it as no longer deleted.
2603 if (instr->hydrogen()->RequiresHoleCheck()) { 2599 if (instr->hydrogen()->RequiresHoleCheck()) {
2604 // We use a temp to check the payload (CompareRoot might clobber ip). 2600 // We use a temp to check the payload (CompareRoot might clobber ip).
2605 Register payload = ToRegister(instr->temp()); 2601 Register payload = ToRegister(instr->TempAt(0));
2606 __ ldr(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 2602 __ ldr(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
2607 __ CompareRoot(payload, Heap::kTheHoleValueRootIndex); 2603 __ CompareRoot(payload, Heap::kTheHoleValueRootIndex);
2608 DeoptimizeIf(eq, instr->environment()); 2604 DeoptimizeIf(eq, instr->environment());
2609 } 2605 }
2610 2606
2611 // Store the value. 2607 // Store the value.
2612 __ str(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 2608 __ str(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
2613 // Cells are always rescanned, so no write barrier here. 2609 // Cells are always rescanned, so no write barrier here.
2614 } 2610 }
2615 2611
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2674 kSaveFPRegs, 2670 kSaveFPRegs,
2675 EMIT_REMEMBERED_SET, 2671 EMIT_REMEMBERED_SET,
2676 check_needed); 2672 check_needed);
2677 } 2673 }
2678 2674
2679 __ bind(&skip_assignment); 2675 __ bind(&skip_assignment);
2680 } 2676 }
2681 2677
2682 2678
2683 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 2679 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2684 Register object = ToRegister(instr->object()); 2680 Register object = ToRegister(instr->InputAt(0));
2685 Register result = ToRegister(instr->result()); 2681 Register result = ToRegister(instr->result());
2686 if (instr->hydrogen()->is_in_object()) { 2682 if (instr->hydrogen()->is_in_object()) {
2687 __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset())); 2683 __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset()));
2688 } else { 2684 } else {
2689 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 2685 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
2690 __ ldr(result, FieldMemOperand(result, instr->hydrogen()->offset())); 2686 __ ldr(result, FieldMemOperand(result, instr->hydrogen()->offset()));
2691 } 2687 }
2692 } 2688 }
2693 2689
2694 2690
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2828 __ bind(&non_instance); 2824 __ bind(&non_instance);
2829 __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); 2825 __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset));
2830 2826
2831 // All done. 2827 // All done.
2832 __ bind(&done); 2828 __ bind(&done);
2833 } 2829 }
2834 2830
2835 2831
2836 void LCodeGen::DoLoadElements(LLoadElements* instr) { 2832 void LCodeGen::DoLoadElements(LLoadElements* instr) {
2837 Register result = ToRegister(instr->result()); 2833 Register result = ToRegister(instr->result());
2838 Register input = ToRegister(instr->object()); 2834 Register input = ToRegister(instr->InputAt(0));
2839 Register scratch = scratch0(); 2835 Register scratch = scratch0();
2840 2836
2841 __ ldr(result, FieldMemOperand(input, JSObject::kElementsOffset)); 2837 __ ldr(result, FieldMemOperand(input, JSObject::kElementsOffset));
2842 if (FLAG_debug_code) { 2838 if (FLAG_debug_code) {
2843 Label done, fail; 2839 Label done, fail;
2844 __ ldr(scratch, FieldMemOperand(result, HeapObject::kMapOffset)); 2840 __ ldr(scratch, FieldMemOperand(result, HeapObject::kMapOffset));
2845 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); 2841 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
2846 __ cmp(scratch, ip); 2842 __ cmp(scratch, ip);
2847 __ b(eq, &done); 2843 __ b(eq, &done);
2848 __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex); 2844 __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex);
(...skipping 14 matching lines...) Expand all
2863 __ bind(&fail); 2859 __ bind(&fail);
2864 __ Abort("Check for fast or external elements failed."); 2860 __ Abort("Check for fast or external elements failed.");
2865 __ bind(&done); 2861 __ bind(&done);
2866 } 2862 }
2867 } 2863 }
2868 2864
2869 2865
2870 void LCodeGen::DoLoadExternalArrayPointer( 2866 void LCodeGen::DoLoadExternalArrayPointer(
2871 LLoadExternalArrayPointer* instr) { 2867 LLoadExternalArrayPointer* instr) {
2872 Register to_reg = ToRegister(instr->result()); 2868 Register to_reg = ToRegister(instr->result());
2873 Register from_reg = ToRegister(instr->object()); 2869 Register from_reg = ToRegister(instr->InputAt(0));
2874 __ ldr(to_reg, FieldMemOperand(from_reg, 2870 __ ldr(to_reg, FieldMemOperand(from_reg,
2875 ExternalArray::kExternalPointerOffset)); 2871 ExternalArray::kExternalPointerOffset));
2876 } 2872 }
2877 2873
2878 2874
2879 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2875 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2880 Register arguments = ToRegister(instr->arguments()); 2876 Register arguments = ToRegister(instr->arguments());
2881 Register length = ToRegister(instr->length()); 2877 Register length = ToRegister(instr->length());
2882 Register index = ToRegister(instr->index()); 2878 Register index = ToRegister(instr->index());
2883 Register result = ToRegister(instr->result()); 2879 Register result = ToRegister(instr->result());
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
3120 3116
3121 // Result is the frame pointer for the frame if not adapted and for the real 3117 // Result is the frame pointer for the frame if not adapted and for the real
3122 // frame below the adaptor frame if adapted. 3118 // frame below the adaptor frame if adapted.
3123 __ mov(result, fp, LeaveCC, ne); 3119 __ mov(result, fp, LeaveCC, ne);
3124 __ mov(result, scratch, LeaveCC, eq); 3120 __ mov(result, scratch, LeaveCC, eq);
3125 } 3121 }
3126 } 3122 }
3127 3123
3128 3124
3129 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 3125 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3130 Register elem = ToRegister(instr->elements()); 3126 Register elem = ToRegister(instr->InputAt(0));
3131 Register result = ToRegister(instr->result()); 3127 Register result = ToRegister(instr->result());
3132 3128
3133 Label done; 3129 Label done;
3134 3130
3135 // If no arguments adaptor frame the number of arguments is fixed. 3131 // If no arguments adaptor frame the number of arguments is fixed.
3136 __ cmp(fp, elem); 3132 __ cmp(fp, elem);
3137 __ mov(result, Operand(scope()->num_parameters())); 3133 __ mov(result, Operand(scope()->num_parameters()));
3138 __ b(eq, &done); 3134 __ b(eq, &done);
3139 3135
3140 // Arguments adaptor frame present. Get argument length from there. 3136 // Arguments adaptor frame present. Get argument length from there.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3239 // The number of arguments is stored in receiver which is r0, as expected 3235 // The number of arguments is stored in receiver which is r0, as expected
3240 // by InvokeFunction. 3236 // by InvokeFunction.
3241 ParameterCount actual(receiver); 3237 ParameterCount actual(receiver);
3242 __ InvokeFunction(function, actual, CALL_FUNCTION, 3238 __ InvokeFunction(function, actual, CALL_FUNCTION,
3243 safepoint_generator, CALL_AS_METHOD); 3239 safepoint_generator, CALL_AS_METHOD);
3244 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3240 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3245 } 3241 }
3246 3242
3247 3243
3248 void LCodeGen::DoPushArgument(LPushArgument* instr) { 3244 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3249 LOperand* argument = instr->value(); 3245 LOperand* argument = instr->InputAt(0);
3250 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { 3246 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
3251 Abort("DoPushArgument not implemented for double type."); 3247 Abort("DoPushArgument not implemented for double type.");
3252 } else { 3248 } else {
3253 Register argument_reg = EmitLoadRegister(argument, ip); 3249 Register argument_reg = EmitLoadRegister(argument, ip);
3254 __ push(argument_reg); 3250 __ push(argument_reg);
3255 } 3251 }
3256 } 3252 }
3257 3253
3258 3254
3259 void LCodeGen::DoDrop(LDrop* instr) { 3255 void LCodeGen::DoDrop(LDrop* instr) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3291 } 3287 }
3292 3288
3293 3289
3294 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { 3290 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3295 Register result = ToRegister(instr->result()); 3291 Register result = ToRegister(instr->result());
3296 __ ldr(result, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); 3292 __ ldr(result, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
3297 } 3293 }
3298 3294
3299 3295
3300 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { 3296 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3301 Register global = ToRegister(instr->global_object()); 3297 Register global = ToRegister(instr->global());
3302 Register result = ToRegister(instr->result()); 3298 Register result = ToRegister(instr->result());
3303 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); 3299 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset));
3304 } 3300 }
3305 3301
3306 3302
3307 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 3303 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
3308 int arity, 3304 int arity,
3309 LInstruction* instr, 3305 LInstruction* instr,
3310 CallKind call_kind, 3306 CallKind call_kind,
3311 R1State r1_state) { 3307 R1State r1_state) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3351 ASSERT(ToRegister(instr->result()).is(r0)); 3347 ASSERT(ToRegister(instr->result()).is(r0));
3352 CallKnownFunction(instr->function(), 3348 CallKnownFunction(instr->function(),
3353 instr->arity(), 3349 instr->arity(),
3354 instr, 3350 instr,
3355 CALL_AS_METHOD, 3351 CALL_AS_METHOD,
3356 R1_UNINITIALIZED); 3352 R1_UNINITIALIZED);
3357 } 3353 }
3358 3354
3359 3355
3360 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 3356 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
3361 Register input = ToRegister(instr->value()); 3357 Register input = ToRegister(instr->InputAt(0));
3362 Register result = ToRegister(instr->result()); 3358 Register result = ToRegister(instr->result());
3363 Register scratch = scratch0(); 3359 Register scratch = scratch0();
3364 3360
3365 // Deoptimize if not a heap number. 3361 // Deoptimize if not a heap number.
3366 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 3362 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
3367 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3363 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
3368 __ cmp(scratch, Operand(ip)); 3364 __ cmp(scratch, Operand(ip));
3369 DeoptimizeIf(ne, instr->environment()); 3365 DeoptimizeIf(ne, instr->environment());
3370 3366
3371 Label done; 3367 Label done;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3417 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 3413 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
3418 3414
3419 __ StoreToSafepointRegisterSlot(tmp1, result); 3415 __ StoreToSafepointRegisterSlot(tmp1, result);
3420 } 3416 }
3421 3417
3422 __ bind(&done); 3418 __ bind(&done);
3423 } 3419 }
3424 3420
3425 3421
3426 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 3422 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
3427 Register input = ToRegister(instr->value()); 3423 Register input = ToRegister(instr->InputAt(0));
3428 Register result = ToRegister(instr->result()); 3424 Register result = ToRegister(instr->result());
3429 __ cmp(input, Operand(0)); 3425 __ cmp(input, Operand(0));
3430 __ Move(result, input, pl); 3426 __ Move(result, input, pl);
3431 // We can make rsb conditional because the previous cmp instruction 3427 // We can make rsb conditional because the previous cmp instruction
3432 // will clear the V (overflow) flag and rsb won't set this flag 3428 // will clear the V (overflow) flag and rsb won't set this flag
3433 // if input is positive. 3429 // if input is positive.
3434 __ rsb(result, input, Operand(0), SetCC, mi); 3430 __ rsb(result, input, Operand(0), SetCC, mi);
3435 // Deoptimize on overflow. 3431 // Deoptimize on overflow.
3436 DeoptimizeIf(vs, instr->environment()); 3432 DeoptimizeIf(vs, instr->environment());
3437 } 3433 }
3438 3434
3439 3435
3440 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 3436 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
3441 // Class for deferred case. 3437 // Class for deferred case.
3442 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3438 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3443 public: 3439 public:
3444 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3440 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
3445 LUnaryMathOperation* instr) 3441 LUnaryMathOperation* instr)
3446 : LDeferredCode(codegen), instr_(instr) { } 3442 : LDeferredCode(codegen), instr_(instr) { }
3447 virtual void Generate() { 3443 virtual void Generate() {
3448 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3444 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3449 } 3445 }
3450 virtual LInstruction* instr() { return instr_; } 3446 virtual LInstruction* instr() { return instr_; }
3451 private: 3447 private:
3452 LUnaryMathOperation* instr_; 3448 LUnaryMathOperation* instr_;
3453 }; 3449 };
3454 3450
3455 Representation r = instr->hydrogen()->value()->representation(); 3451 Representation r = instr->hydrogen()->value()->representation();
3456 if (r.IsDouble()) { 3452 if (r.IsDouble()) {
3457 DwVfpRegister input = ToDoubleRegister(instr->value()); 3453 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0));
3458 DwVfpRegister result = ToDoubleRegister(instr->result()); 3454 DwVfpRegister result = ToDoubleRegister(instr->result());
3459 __ vabs(result, input); 3455 __ vabs(result, input);
3460 } else if (r.IsInteger32()) { 3456 } else if (r.IsInteger32()) {
3461 EmitIntegerMathAbs(instr); 3457 EmitIntegerMathAbs(instr);
3462 } else { 3458 } else {
3463 // Representation is tagged. 3459 // Representation is tagged.
3464 DeferredMathAbsTaggedHeapNumber* deferred = 3460 DeferredMathAbsTaggedHeapNumber* deferred =
3465 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 3461 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3466 Register input = ToRegister(instr->value()); 3462 Register input = ToRegister(instr->InputAt(0));
3467 // Smi check. 3463 // Smi check.
3468 __ JumpIfNotSmi(input, deferred->entry()); 3464 __ JumpIfNotSmi(input, deferred->entry());
3469 // If smi, handle it directly. 3465 // If smi, handle it directly.
3470 EmitIntegerMathAbs(instr); 3466 EmitIntegerMathAbs(instr);
3471 __ bind(deferred->exit()); 3467 __ bind(deferred->exit());
3472 } 3468 }
3473 } 3469 }
3474 3470
3475 3471
3476 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 3472 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
3477 DoubleRegister input = ToDoubleRegister(instr->value()); 3473 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3478 Register result = ToRegister(instr->result()); 3474 Register result = ToRegister(instr->result());
3479 SwVfpRegister single_scratch = double_scratch0().low(); 3475 SwVfpRegister single_scratch = double_scratch0().low();
3480 Register scratch1 = scratch0(); 3476 Register scratch1 = scratch0();
3481 Register scratch2 = ToRegister(instr->temp()); 3477 Register scratch2 = ToRegister(instr->TempAt(0));
3482 3478
3483 __ EmitVFPTruncate(kRoundToMinusInf, 3479 __ EmitVFPTruncate(kRoundToMinusInf,
3484 single_scratch, 3480 single_scratch,
3485 input, 3481 input,
3486 scratch1, 3482 scratch1,
3487 scratch2); 3483 scratch2);
3488 DeoptimizeIf(ne, instr->environment()); 3484 DeoptimizeIf(ne, instr->environment());
3489 3485
3490 // Move the result back to general purpose register r0. 3486 // Move the result back to general purpose register r0.
3491 __ vmov(result, single_scratch); 3487 __ vmov(result, single_scratch);
3492 3488
3493 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3489 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3494 // Test for -0. 3490 // Test for -0.
3495 Label done; 3491 Label done;
3496 __ cmp(result, Operand(0)); 3492 __ cmp(result, Operand(0));
3497 __ b(ne, &done); 3493 __ b(ne, &done);
3498 __ vmov(scratch1, input.high()); 3494 __ vmov(scratch1, input.high());
3499 __ tst(scratch1, Operand(HeapNumber::kSignMask)); 3495 __ tst(scratch1, Operand(HeapNumber::kSignMask));
3500 DeoptimizeIf(ne, instr->environment()); 3496 DeoptimizeIf(ne, instr->environment());
3501 __ bind(&done); 3497 __ bind(&done);
3502 } 3498 }
3503 } 3499 }
3504 3500
3505 3501
3506 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 3502 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
3507 DoubleRegister input = ToDoubleRegister(instr->value()); 3503 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3508 Register result = ToRegister(instr->result()); 3504 Register result = ToRegister(instr->result());
3509 Register scratch = scratch0(); 3505 Register scratch = scratch0();
3510 Label done, check_sign_on_zero; 3506 Label done, check_sign_on_zero;
3511 3507
3512 // Extract exponent bits. 3508 // Extract exponent bits.
3513 __ vmov(result, input.high()); 3509 __ vmov(result, input.high());
3514 __ ubfx(scratch, 3510 __ ubfx(scratch,
3515 result, 3511 result,
3516 HeapNumber::kExponentShift, 3512 HeapNumber::kExponentShift,
3517 HeapNumber::kExponentBits); 3513 HeapNumber::kExponentBits);
3518 3514
3519 // If the number is in ]-0.5, +0.5[, the result is +/- 0. 3515 // If the number is in ]-0.5, +0.5[, the result is +/- 0.
3520 __ cmp(scratch, Operand(HeapNumber::kExponentBias - 2)); 3516 __ cmp(scratch, Operand(HeapNumber::kExponentBias - 2));
3521 __ mov(result, Operand(0), LeaveCC, le); 3517 __ mov(result, Operand(0), LeaveCC, le);
3522 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3518 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3523 __ b(le, &check_sign_on_zero); 3519 __ b(le, &check_sign_on_zero);
3524 } else { 3520 } else {
3525 __ b(le, &done); 3521 __ b(le, &done);
3526 } 3522 }
3527 3523
3528 // The following conversion will not work with numbers 3524 // The following conversion will not work with numbers
3529 // outside of ]-2^32, 2^32[. 3525 // outside of ]-2^32, 2^32[.
3530 __ cmp(scratch, Operand(HeapNumber::kExponentBias + 32)); 3526 __ cmp(scratch, Operand(HeapNumber::kExponentBias + 32));
3531 DeoptimizeIf(ge, instr->environment()); 3527 DeoptimizeIf(ge, instr->environment());
3532 3528
3533 __ Vmov(double_scratch0(), 0.5, scratch);
3534 __ vadd(double_scratch0(), input, double_scratch0());
3535
3536 // Save the original sign for later comparison. 3529 // Save the original sign for later comparison.
3537 __ and_(scratch, result, Operand(HeapNumber::kSignMask)); 3530 __ and_(scratch, result, Operand(HeapNumber::kSignMask));
3538 3531
3532 __ Vmov(double_scratch0(), 0.5);
3533 __ vadd(double_scratch0(), input, double_scratch0());
3534
3539 // Check sign of the result: if the sign changed, the input 3535 // Check sign of the result: if the sign changed, the input
3540 // value was in ]0.5, 0[ and the result should be -0. 3536 // value was in ]0.5, 0[ and the result should be -0.
3541 __ vmov(result, double_scratch0().high()); 3537 __ vmov(result, double_scratch0().high());
3542 __ eor(result, result, Operand(scratch), SetCC); 3538 __ eor(result, result, Operand(scratch), SetCC);
3543 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3539 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3544 DeoptimizeIf(mi, instr->environment()); 3540 DeoptimizeIf(mi, instr->environment());
3545 } else { 3541 } else {
3546 __ mov(result, Operand(0), LeaveCC, mi); 3542 __ mov(result, Operand(0), LeaveCC, mi);
3547 __ b(mi, &done); 3543 __ b(mi, &done);
3548 } 3544 }
(...skipping 13 matching lines...) Expand all
3562 __ bind(&check_sign_on_zero); 3558 __ bind(&check_sign_on_zero);
3563 __ vmov(scratch, input.high()); 3559 __ vmov(scratch, input.high());
3564 __ tst(scratch, Operand(HeapNumber::kSignMask)); 3560 __ tst(scratch, Operand(HeapNumber::kSignMask));
3565 DeoptimizeIf(ne, instr->environment()); 3561 DeoptimizeIf(ne, instr->environment());
3566 } 3562 }
3567 __ bind(&done); 3563 __ bind(&done);
3568 } 3564 }
3569 3565
3570 3566
3571 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3567 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3572 DoubleRegister input = ToDoubleRegister(instr->value()); 3568 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3573 DoubleRegister result = ToDoubleRegister(instr->result()); 3569 DoubleRegister result = ToDoubleRegister(instr->result());
3574 __ vsqrt(result, input); 3570 __ vsqrt(result, input);
3575 } 3571 }
3576 3572
3577 3573
3578 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3574 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
3579 DoubleRegister input = ToDoubleRegister(instr->value()); 3575 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3580 DoubleRegister result = ToDoubleRegister(instr->result()); 3576 DoubleRegister result = ToDoubleRegister(instr->result());
3581 DoubleRegister temp = ToDoubleRegister(instr->temp()); 3577 DoubleRegister temp = ToDoubleRegister(instr->TempAt(0));
3582 3578
3583 // Note that according to ECMA-262 15.8.2.13: 3579 // Note that according to ECMA-262 15.8.2.13:
3584 // Math.pow(-Infinity, 0.5) == Infinity 3580 // Math.pow(-Infinity, 0.5) == Infinity
3585 // Math.sqrt(-Infinity) == NaN 3581 // Math.sqrt(-Infinity) == NaN
3586 Label done; 3582 Label done;
3587 __ vmov(temp, -V8_INFINITY, scratch0()); 3583 __ vmov(temp, -V8_INFINITY);
3588 __ VFPCompareAndSetFlags(input, temp); 3584 __ VFPCompareAndSetFlags(input, temp);
3589 __ vneg(result, temp, eq); 3585 __ vneg(result, temp, eq);
3590 __ b(&done, eq); 3586 __ b(&done, eq);
3591 3587
3592 // Add +0 to convert -0 to +0. 3588 // Add +0 to convert -0 to +0.
3593 __ vadd(result, input, kDoubleRegZero); 3589 __ vadd(result, input, kDoubleRegZero);
3594 __ vsqrt(result, result); 3590 __ vsqrt(result, result);
3595 __ bind(&done); 3591 __ bind(&done);
3596 } 3592 }
3597 3593
3598 3594
3599 void LCodeGen::DoPower(LPower* instr) { 3595 void LCodeGen::DoPower(LPower* instr) {
3600 Representation exponent_type = instr->hydrogen()->right()->representation(); 3596 Representation exponent_type = instr->hydrogen()->right()->representation();
3601 // Having marked this as a call, we can use any registers. 3597 // Having marked this as a call, we can use any registers.
3602 // Just make sure that the input/output registers are the expected ones. 3598 // Just make sure that the input/output registers are the expected ones.
3603 ASSERT(!instr->right()->IsDoubleRegister() || 3599 ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
3604 ToDoubleRegister(instr->right()).is(d2)); 3600 ToDoubleRegister(instr->InputAt(1)).is(d2));
3605 ASSERT(!instr->right()->IsRegister() || 3601 ASSERT(!instr->InputAt(1)->IsRegister() ||
3606 ToRegister(instr->right()).is(r2)); 3602 ToRegister(instr->InputAt(1)).is(r2));
3607 ASSERT(ToDoubleRegister(instr->left()).is(d1)); 3603 ASSERT(ToDoubleRegister(instr->InputAt(0)).is(d1));
3608 ASSERT(ToDoubleRegister(instr->result()).is(d3)); 3604 ASSERT(ToDoubleRegister(instr->result()).is(d3));
3609 3605
3610 if (exponent_type.IsTagged()) { 3606 if (exponent_type.IsTagged()) {
3611 Label no_deopt; 3607 Label no_deopt;
3612 __ JumpIfSmi(r2, &no_deopt); 3608 __ JumpIfSmi(r2, &no_deopt);
3613 __ ldr(r7, FieldMemOperand(r2, HeapObject::kMapOffset)); 3609 __ ldr(r7, FieldMemOperand(r2, HeapObject::kMapOffset));
3614 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3610 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
3615 __ cmp(r7, Operand(ip)); 3611 __ cmp(r7, Operand(ip));
3616 DeoptimizeIf(ne, instr->environment()); 3612 DeoptimizeIf(ne, instr->environment());
3617 __ bind(&no_deopt); 3613 __ bind(&no_deopt);
(...skipping 19 matching lines...) Expand all
3637 virtual LInstruction* instr() { return instr_; } 3633 virtual LInstruction* instr() { return instr_; }
3638 private: 3634 private:
3639 LRandom* instr_; 3635 LRandom* instr_;
3640 }; 3636 };
3641 3637
3642 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 3638 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3643 3639
3644 // Having marked this instruction as a call we can use any 3640 // Having marked this instruction as a call we can use any
3645 // registers. 3641 // registers.
3646 ASSERT(ToDoubleRegister(instr->result()).is(d7)); 3642 ASSERT(ToDoubleRegister(instr->result()).is(d7));
3647 ASSERT(ToRegister(instr->global_object()).is(r0)); 3643 ASSERT(ToRegister(instr->InputAt(0)).is(r0));
3648 3644
3649 static const int kSeedSize = sizeof(uint32_t); 3645 static const int kSeedSize = sizeof(uint32_t);
3650 STATIC_ASSERT(kPointerSize == kSeedSize); 3646 STATIC_ASSERT(kPointerSize == kSeedSize);
3651 3647
3652 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset)); 3648 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset));
3653 static const int kRandomSeedOffset = 3649 static const int kRandomSeedOffset =
3654 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize; 3650 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
3655 __ ldr(r2, FieldMemOperand(r0, kRandomSeedOffset)); 3651 __ ldr(r2, FieldMemOperand(r0, kRandomSeedOffset));
3656 // r2: FixedArray of the native context's random seeds 3652 // r2: FixedArray of the native context's random seeds
3657 3653
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
3848 ASSERT(ToRegister(instr->result()).is(r0)); 3844 ASSERT(ToRegister(instr->result()).is(r0));
3849 CallKnownFunction(instr->target(), 3845 CallKnownFunction(instr->target(),
3850 instr->arity(), 3846 instr->arity(),
3851 instr, 3847 instr,
3852 CALL_AS_FUNCTION, 3848 CALL_AS_FUNCTION,
3853 R1_UNINITIALIZED); 3849 R1_UNINITIALIZED);
3854 } 3850 }
3855 3851
3856 3852
3857 void LCodeGen::DoCallNew(LCallNew* instr) { 3853 void LCodeGen::DoCallNew(LCallNew* instr) {
3858 ASSERT(ToRegister(instr->constructor()).is(r1)); 3854 ASSERT(ToRegister(instr->InputAt(0)).is(r1));
3859 ASSERT(ToRegister(instr->result()).is(r0)); 3855 ASSERT(ToRegister(instr->result()).is(r0));
3860 3856
3861 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 3857 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
3862 __ mov(r0, Operand(instr->arity())); 3858 __ mov(r0, Operand(instr->arity()));
3863 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 3859 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3864 } 3860 }
3865 3861
3866 3862
3867 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 3863 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3868 CallRuntime(instr->function(), instr->arity(), instr); 3864 CallRuntime(instr->function(), instr->arity(), instr);
3869 } 3865 }
3870 3866
3871 3867
3872 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 3868 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3873 Register object = ToRegister(instr->object()); 3869 Register object = ToRegister(instr->object());
3874 Register value = ToRegister(instr->value()); 3870 Register value = ToRegister(instr->value());
3875 Register scratch = scratch0(); 3871 Register scratch = scratch0();
3876 int offset = instr->offset(); 3872 int offset = instr->offset();
3877 3873
3878 ASSERT(!object.is(value)); 3874 ASSERT(!object.is(value));
3879 3875
3880 if (!instr->transition().is_null()) { 3876 if (!instr->transition().is_null()) {
3881 __ mov(scratch, Operand(instr->transition())); 3877 __ mov(scratch, Operand(instr->transition()));
3882 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); 3878 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
3883 if (instr->hydrogen()->NeedsWriteBarrierForMap()) { 3879 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
3884 Register temp = ToRegister(instr->temp()); 3880 Register temp = ToRegister(instr->TempAt(0));
3885 // Update the write barrier for the map field. 3881 // Update the write barrier for the map field.
3886 __ RecordWriteField(object, 3882 __ RecordWriteField(object,
3887 HeapObject::kMapOffset, 3883 HeapObject::kMapOffset,
3888 scratch, 3884 scratch,
3889 temp, 3885 temp,
3890 kLRHasBeenSaved, 3886 kLRHasBeenSaved,
3891 kSaveFPRegs, 3887 kSaveFPRegs,
3892 OMIT_REMEMBERED_SET, 3888 OMIT_REMEMBERED_SET,
3893 OMIT_SMI_CHECK); 3889 OMIT_SMI_CHECK);
3894 } 3890 }
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
4059 __ add(scratch, scratch, 4055 __ add(scratch, scratch,
4060 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 4056 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
4061 } 4057 }
4062 4058
4063 if (instr->NeedsCanonicalization()) { 4059 if (instr->NeedsCanonicalization()) {
4064 // Check for NaN. All NaNs must be canonicalized. 4060 // Check for NaN. All NaNs must be canonicalized.
4065 __ VFPCompareAndSetFlags(value, value); 4061 __ VFPCompareAndSetFlags(value, value);
4066 // Only load canonical NaN if the comparison above set the overflow. 4062 // Only load canonical NaN if the comparison above set the overflow.
4067 __ Vmov(value, 4063 __ Vmov(value,
4068 FixedDoubleArray::canonical_not_the_hole_nan_as_double(), 4064 FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
4069 no_reg, vs); 4065 vs);
4070 } 4066 }
4071 4067
4072 __ vstr(value, scratch, instr->additional_index() << element_size_shift); 4068 __ vstr(value, scratch, instr->additional_index() << element_size_shift);
4073 } 4069 }
4074 4070
4075 4071
4076 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 4072 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
4077 LStoreKeyedSpecializedArrayElement* instr) { 4073 LStoreKeyedSpecializedArrayElement* instr) {
4078 4074
4079 Register external_pointer = ToRegister(instr->external_pointer()); 4075 Register external_pointer = ToRegister(instr->external_pointer());
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
4152 4148
4153 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4149 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4154 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 4150 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
4155 : isolate()->builtins()->KeyedStoreIC_Initialize(); 4151 : isolate()->builtins()->KeyedStoreIC_Initialize();
4156 CallCode(ic, RelocInfo::CODE_TARGET, instr); 4152 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4157 } 4153 }
4158 4154
4159 4155
4160 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 4156 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4161 Register object_reg = ToRegister(instr->object()); 4157 Register object_reg = ToRegister(instr->object());
4162 Register new_map_reg = ToRegister(instr->new_map_temp()); 4158 Register new_map_reg = ToRegister(instr->new_map_reg());
4163 Register scratch = scratch0(); 4159 Register scratch = scratch0();
4164 4160
4165 Handle<Map> from_map = instr->original_map(); 4161 Handle<Map> from_map = instr->original_map();
4166 Handle<Map> to_map = instr->transitioned_map(); 4162 Handle<Map> to_map = instr->transitioned_map();
4167 ElementsKind from_kind = from_map->elements_kind(); 4163 ElementsKind from_kind = from_map->elements_kind();
4168 ElementsKind to_kind = to_map->elements_kind(); 4164 ElementsKind to_kind = to_map->elements_kind();
4169 4165
4170 Label not_applicable; 4166 Label not_applicable;
4171 __ ldr(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 4167 __ ldr(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset));
4172 __ cmp(scratch, Operand(from_map)); 4168 __ cmp(scratch, Operand(from_map));
4173 __ b(ne, &not_applicable); 4169 __ b(ne, &not_applicable);
4174 __ mov(new_map_reg, Operand(to_map)); 4170 __ mov(new_map_reg, Operand(to_map));
4175 4171
4176 if (IsSimpleMapChangeTransition(from_kind, to_kind)) { 4172 if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
4177 __ str(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 4173 __ str(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset));
4178 // Write barrier. 4174 // Write barrier.
4179 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 4175 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
4180 scratch, kLRHasBeenSaved, kDontSaveFPRegs); 4176 scratch, kLRHasBeenSaved, kDontSaveFPRegs);
4181 } else if (IsFastSmiElementsKind(from_kind) && 4177 } else if (IsFastSmiElementsKind(from_kind) &&
4182 IsFastDoubleElementsKind(to_kind)) { 4178 IsFastDoubleElementsKind(to_kind)) {
4183 Register fixed_object_reg = ToRegister(instr->temp()); 4179 Register fixed_object_reg = ToRegister(instr->temp_reg());
4184 ASSERT(fixed_object_reg.is(r2)); 4180 ASSERT(fixed_object_reg.is(r2));
4185 ASSERT(new_map_reg.is(r3)); 4181 ASSERT(new_map_reg.is(r3));
4186 __ mov(fixed_object_reg, object_reg); 4182 __ mov(fixed_object_reg, object_reg);
4187 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 4183 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
4188 RelocInfo::CODE_TARGET, instr); 4184 RelocInfo::CODE_TARGET, instr);
4189 } else if (IsFastDoubleElementsKind(from_kind) && 4185 } else if (IsFastDoubleElementsKind(from_kind) &&
4190 IsFastObjectElementsKind(to_kind)) { 4186 IsFastObjectElementsKind(to_kind)) {
4191 Register fixed_object_reg = ToRegister(instr->temp()); 4187 Register fixed_object_reg = ToRegister(instr->temp_reg());
4192 ASSERT(fixed_object_reg.is(r2)); 4188 ASSERT(fixed_object_reg.is(r2));
4193 ASSERT(new_map_reg.is(r3)); 4189 ASSERT(new_map_reg.is(r3));
4194 __ mov(fixed_object_reg, object_reg); 4190 __ mov(fixed_object_reg, object_reg);
4195 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 4191 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
4196 RelocInfo::CODE_TARGET, instr); 4192 RelocInfo::CODE_TARGET, instr);
4197 } else { 4193 } else {
4198 UNREACHABLE(); 4194 UNREACHABLE();
4199 } 4195 }
4200 __ bind(&not_applicable); 4196 __ bind(&not_applicable);
4201 } 4197 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
4306 4302
4307 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4303 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4308 __ SmiTag(char_code); 4304 __ SmiTag(char_code);
4309 __ push(char_code); 4305 __ push(char_code);
4310 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); 4306 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr);
4311 __ StoreToSafepointRegisterSlot(r0, result); 4307 __ StoreToSafepointRegisterSlot(r0, result);
4312 } 4308 }
4313 4309
4314 4310
4315 void LCodeGen::DoStringLength(LStringLength* instr) { 4311 void LCodeGen::DoStringLength(LStringLength* instr) {
4316 Register string = ToRegister(instr->string()); 4312 Register string = ToRegister(instr->InputAt(0));
4317 Register result = ToRegister(instr->result()); 4313 Register result = ToRegister(instr->result());
4318 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); 4314 __ ldr(result, FieldMemOperand(string, String::kLengthOffset));
4319 } 4315 }
4320 4316
4321 4317
4322 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4318 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4323 LOperand* input = instr->value(); 4319 LOperand* input = instr->InputAt(0);
4324 ASSERT(input->IsRegister() || input->IsStackSlot()); 4320 ASSERT(input->IsRegister() || input->IsStackSlot());
4325 LOperand* output = instr->result(); 4321 LOperand* output = instr->result();
4326 ASSERT(output->IsDoubleRegister()); 4322 ASSERT(output->IsDoubleRegister());
4327 SwVfpRegister single_scratch = double_scratch0().low(); 4323 SwVfpRegister single_scratch = double_scratch0().low();
4328 if (input->IsStackSlot()) { 4324 if (input->IsStackSlot()) {
4329 Register scratch = scratch0(); 4325 Register scratch = scratch0();
4330 __ ldr(scratch, ToMemOperand(input)); 4326 __ ldr(scratch, ToMemOperand(input));
4331 __ vmov(single_scratch, scratch); 4327 __ vmov(single_scratch, scratch);
4332 } else { 4328 } else {
4333 __ vmov(single_scratch, ToRegister(input)); 4329 __ vmov(single_scratch, ToRegister(input));
4334 } 4330 }
4335 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); 4331 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch);
4336 } 4332 }
4337 4333
4338 4334
4339 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4335 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4340 LOperand* input = instr->value(); 4336 LOperand* input = instr->InputAt(0);
4341 LOperand* output = instr->result(); 4337 LOperand* output = instr->result();
4342 4338
4343 SwVfpRegister flt_scratch = double_scratch0().low(); 4339 SwVfpRegister flt_scratch = double_scratch0().low();
4344 __ vmov(flt_scratch, ToRegister(input)); 4340 __ vmov(flt_scratch, ToRegister(input));
4345 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); 4341 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch);
4346 } 4342 }
4347 4343
4348 4344
4349 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4345 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4350 class DeferredNumberTagI: public LDeferredCode { 4346 class DeferredNumberTagI: public LDeferredCode {
4351 public: 4347 public:
4352 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4348 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4353 : LDeferredCode(codegen), instr_(instr) { } 4349 : LDeferredCode(codegen), instr_(instr) { }
4354 virtual void Generate() { 4350 virtual void Generate() {
4355 codegen()->DoDeferredNumberTagI(instr_, 4351 codegen()->DoDeferredNumberTagI(instr_,
4356 instr_->value(), 4352 instr_->InputAt(0),
4357 SIGNED_INT32); 4353 SIGNED_INT32);
4358 } 4354 }
4359 virtual LInstruction* instr() { return instr_; } 4355 virtual LInstruction* instr() { return instr_; }
4360 private: 4356 private:
4361 LNumberTagI* instr_; 4357 LNumberTagI* instr_;
4362 }; 4358 };
4363 4359
4364 Register src = ToRegister(instr->value()); 4360 Register src = ToRegister(instr->InputAt(0));
4365 Register dst = ToRegister(instr->result()); 4361 Register dst = ToRegister(instr->result());
4366 4362
4367 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4363 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4368 __ SmiTag(dst, src, SetCC); 4364 __ SmiTag(dst, src, SetCC);
4369 __ b(vs, deferred->entry()); 4365 __ b(vs, deferred->entry());
4370 __ bind(deferred->exit()); 4366 __ bind(deferred->exit());
4371 } 4367 }
4372 4368
4373 4369
4374 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4370 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4375 class DeferredNumberTagU: public LDeferredCode { 4371 class DeferredNumberTagU: public LDeferredCode {
4376 public: 4372 public:
4377 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 4373 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4378 : LDeferredCode(codegen), instr_(instr) { } 4374 : LDeferredCode(codegen), instr_(instr) { }
4379 virtual void Generate() { 4375 virtual void Generate() {
4380 codegen()->DoDeferredNumberTagI(instr_, 4376 codegen()->DoDeferredNumberTagI(instr_,
4381 instr_->value(), 4377 instr_->InputAt(0),
4382 UNSIGNED_INT32); 4378 UNSIGNED_INT32);
4383 } 4379 }
4384 virtual LInstruction* instr() { return instr_; } 4380 virtual LInstruction* instr() { return instr_; }
4385 private: 4381 private:
4386 LNumberTagU* instr_; 4382 LNumberTagU* instr_;
4387 }; 4383 };
4388 4384
4389 LOperand* input = instr->value(); 4385 LOperand* input = instr->InputAt(0);
4390 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4386 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4391 Register reg = ToRegister(input); 4387 Register reg = ToRegister(input);
4392 4388
4393 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4389 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4394 __ cmp(reg, Operand(Smi::kMaxValue)); 4390 __ cmp(reg, Operand(Smi::kMaxValue));
4395 __ b(hi, deferred->entry()); 4391 __ b(hi, deferred->entry());
4396 __ SmiTag(reg, reg); 4392 __ SmiTag(reg, reg);
4397 __ bind(deferred->exit()); 4393 __ bind(deferred->exit());
4398 } 4394 }
4399 4395
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
4457 class DeferredNumberTagD: public LDeferredCode { 4453 class DeferredNumberTagD: public LDeferredCode {
4458 public: 4454 public:
4459 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4455 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4460 : LDeferredCode(codegen), instr_(instr) { } 4456 : LDeferredCode(codegen), instr_(instr) { }
4461 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4457 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
4462 virtual LInstruction* instr() { return instr_; } 4458 virtual LInstruction* instr() { return instr_; }
4463 private: 4459 private:
4464 LNumberTagD* instr_; 4460 LNumberTagD* instr_;
4465 }; 4461 };
4466 4462
4467 DoubleRegister input_reg = ToDoubleRegister(instr->value()); 4463 DoubleRegister input_reg = ToDoubleRegister(instr->InputAt(0));
4468 Register scratch = scratch0(); 4464 Register scratch = scratch0();
4469 Register reg = ToRegister(instr->result()); 4465 Register reg = ToRegister(instr->result());
4470 Register temp1 = ToRegister(instr->temp()); 4466 Register temp1 = ToRegister(instr->TempAt(0));
4471 Register temp2 = ToRegister(instr->temp2()); 4467 Register temp2 = ToRegister(instr->TempAt(1));
4472 4468
4473 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4469 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4474 if (FLAG_inline_new) { 4470 if (FLAG_inline_new) {
4475 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 4471 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
4476 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry()); 4472 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry());
4477 } else { 4473 } else {
4478 __ jmp(deferred->entry()); 4474 __ jmp(deferred->entry());
4479 } 4475 }
4480 __ bind(deferred->exit()); 4476 __ bind(deferred->exit());
4481 __ sub(ip, reg, Operand(kHeapObjectTag)); 4477 __ sub(ip, reg, Operand(kHeapObjectTag));
4482 __ vstr(input_reg, ip, HeapNumber::kValueOffset); 4478 __ vstr(input_reg, ip, HeapNumber::kValueOffset);
4483 } 4479 }
4484 4480
4485 4481
4486 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4482 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4487 // TODO(3095996): Get rid of this. For now, we need to make the 4483 // TODO(3095996): Get rid of this. For now, we need to make the
4488 // result register contain a valid pointer because it is already 4484 // result register contain a valid pointer because it is already
4489 // contained in the register pointer map. 4485 // contained in the register pointer map.
4490 Register reg = ToRegister(instr->result()); 4486 Register reg = ToRegister(instr->result());
4491 __ mov(reg, Operand(0)); 4487 __ mov(reg, Operand(0));
4492 4488
4493 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4489 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4494 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 4490 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4495 __ StoreToSafepointRegisterSlot(r0, reg); 4491 __ StoreToSafepointRegisterSlot(r0, reg);
4496 } 4492 }
4497 4493
4498 4494
4499 void LCodeGen::DoSmiTag(LSmiTag* instr) { 4495 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4500 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 4496 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
4501 __ SmiTag(ToRegister(instr->result()), ToRegister(instr->value())); 4497 __ SmiTag(ToRegister(instr->result()), ToRegister(instr->InputAt(0)));
4502 } 4498 }
4503 4499
4504 4500
4505 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4501 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4506 Register input = ToRegister(instr->value()); 4502 Register input = ToRegister(instr->InputAt(0));
4507 Register result = ToRegister(instr->result()); 4503 Register result = ToRegister(instr->result());
4508 if (instr->needs_check()) { 4504 if (instr->needs_check()) {
4509 STATIC_ASSERT(kHeapObjectTag == 1); 4505 STATIC_ASSERT(kHeapObjectTag == 1);
4510 // If the input is a HeapObject, SmiUntag will set the carry flag. 4506 // If the input is a HeapObject, SmiUntag will set the carry flag.
4511 __ SmiUntag(result, input, SetCC); 4507 __ SmiUntag(result, input, SetCC);
4512 DeoptimizeIf(cs, instr->environment()); 4508 DeoptimizeIf(cs, instr->environment());
4513 } else { 4509 } else {
4514 __ SmiUntag(result, input); 4510 __ SmiUntag(result, input);
4515 } 4511 }
4516 } 4512 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4568 // Smi to double register conversion 4564 // Smi to double register conversion
4569 __ bind(&load_smi); 4565 __ bind(&load_smi);
4570 // scratch: untagged value of input_reg 4566 // scratch: untagged value of input_reg
4571 __ vmov(flt_scratch, scratch); 4567 __ vmov(flt_scratch, scratch);
4572 __ vcvt_f64_s32(result_reg, flt_scratch); 4568 __ vcvt_f64_s32(result_reg, flt_scratch);
4573 __ bind(&done); 4569 __ bind(&done);
4574 } 4570 }
4575 4571
4576 4572
4577 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 4573 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4578 Register input_reg = ToRegister(instr->value()); 4574 Register input_reg = ToRegister(instr->InputAt(0));
4579 Register scratch1 = scratch0(); 4575 Register scratch1 = scratch0();
4580 Register scratch2 = ToRegister(instr->temp()); 4576 Register scratch2 = ToRegister(instr->TempAt(0));
4581 DwVfpRegister double_scratch = double_scratch0(); 4577 DwVfpRegister double_scratch = double_scratch0();
4582 SwVfpRegister single_scratch = double_scratch.low(); 4578 SwVfpRegister single_scratch = double_scratch.low();
4583 4579
4584 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2)); 4580 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2));
4585 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1)); 4581 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1));
4586 4582
4587 Label done; 4583 Label done;
4588 4584
4589 // The input was optimistically untagged; revert it. 4585 // The input was optimistically untagged; revert it.
4590 // The carry flag is set when we reach this deferred code as we just executed 4586 // The carry flag is set when we reach this deferred code as we just executed
4591 // SmiUntag(heap_object, SetCC) 4587 // SmiUntag(heap_object, SetCC)
4592 STATIC_ASSERT(kHeapObjectTag == 1); 4588 STATIC_ASSERT(kHeapObjectTag == 1);
4593 __ adc(input_reg, input_reg, Operand(input_reg)); 4589 __ adc(input_reg, input_reg, Operand(input_reg));
4594 4590
4595 // Heap number map check. 4591 // Heap number map check.
4596 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4592 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4597 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 4593 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
4598 __ cmp(scratch1, Operand(ip)); 4594 __ cmp(scratch1, Operand(ip));
4599 4595
4600 if (instr->truncating()) { 4596 if (instr->truncating()) {
4601 Register scratch3 = ToRegister(instr->temp2()); 4597 Register scratch3 = ToRegister(instr->TempAt(1));
4602 DwVfpRegister double_scratch2 = ToDoubleRegister(instr->temp3()); 4598 DwVfpRegister double_scratch2 = ToDoubleRegister(instr->TempAt(2));
4603 ASSERT(!scratch3.is(input_reg) && 4599 ASSERT(!scratch3.is(input_reg) &&
4604 !scratch3.is(scratch1) && 4600 !scratch3.is(scratch1) &&
4605 !scratch3.is(scratch2)); 4601 !scratch3.is(scratch2));
4606 // Performs a truncating conversion of a floating point number as used by 4602 // Performs a truncating conversion of a floating point number as used by
4607 // the JS bitwise operations. 4603 // the JS bitwise operations.
4608 Label heap_number; 4604 Label heap_number;
4609 __ b(eq, &heap_number); 4605 __ b(eq, &heap_number);
4610 // Check for undefined. Undefined is converted to zero for truncating 4606 // Check for undefined. Undefined is converted to zero for truncating
4611 // conversions. 4607 // conversions.
4612 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 4608 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4659 class DeferredTaggedToI: public LDeferredCode { 4655 class DeferredTaggedToI: public LDeferredCode {
4660 public: 4656 public:
4661 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4657 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4662 : LDeferredCode(codegen), instr_(instr) { } 4658 : LDeferredCode(codegen), instr_(instr) { }
4663 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 4659 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
4664 virtual LInstruction* instr() { return instr_; } 4660 virtual LInstruction* instr() { return instr_; }
4665 private: 4661 private:
4666 LTaggedToI* instr_; 4662 LTaggedToI* instr_;
4667 }; 4663 };
4668 4664
4669 LOperand* input = instr->value(); 4665 LOperand* input = instr->InputAt(0);
4670 ASSERT(input->IsRegister()); 4666 ASSERT(input->IsRegister());
4671 ASSERT(input->Equals(instr->result())); 4667 ASSERT(input->Equals(instr->result()));
4672 4668
4673 Register input_reg = ToRegister(input); 4669 Register input_reg = ToRegister(input);
4674 4670
4675 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 4671 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4676 4672
4677 // Optimistically untag the input. 4673 // Optimistically untag the input.
4678 // If the input is a HeapObject, SmiUntag will set the carry flag. 4674 // If the input is a HeapObject, SmiUntag will set the carry flag.
4679 __ SmiUntag(input_reg, SetCC); 4675 __ SmiUntag(input_reg, SetCC);
4680 // Branch to deferred code if the input was tagged. 4676 // Branch to deferred code if the input was tagged.
4681 // The deferred code will take care of restoring the tag. 4677 // The deferred code will take care of restoring the tag.
4682 __ b(cs, deferred->entry()); 4678 __ b(cs, deferred->entry());
4683 __ bind(deferred->exit()); 4679 __ bind(deferred->exit());
4684 } 4680 }
4685 4681
4686 4682
4687 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4683 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4688 LOperand* input = instr->value(); 4684 LOperand* input = instr->InputAt(0);
4689 ASSERT(input->IsRegister()); 4685 ASSERT(input->IsRegister());
4690 LOperand* result = instr->result(); 4686 LOperand* result = instr->result();
4691 ASSERT(result->IsDoubleRegister()); 4687 ASSERT(result->IsDoubleRegister());
4692 4688
4693 Register input_reg = ToRegister(input); 4689 Register input_reg = ToRegister(input);
4694 DoubleRegister result_reg = ToDoubleRegister(result); 4690 DoubleRegister result_reg = ToDoubleRegister(result);
4695 4691
4696 EmitNumberUntagD(input_reg, result_reg, 4692 EmitNumberUntagD(input_reg, result_reg,
4697 instr->hydrogen()->deoptimize_on_undefined(), 4693 instr->hydrogen()->deoptimize_on_undefined(),
4698 instr->hydrogen()->deoptimize_on_minus_zero(), 4694 instr->hydrogen()->deoptimize_on_minus_zero(),
4699 instr->environment()); 4695 instr->environment());
4700 } 4696 }
4701 4697
4702 4698
4703 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4699 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4704 Register result_reg = ToRegister(instr->result()); 4700 Register result_reg = ToRegister(instr->result());
4705 Register scratch1 = scratch0(); 4701 Register scratch1 = scratch0();
4706 Register scratch2 = ToRegister(instr->temp()); 4702 Register scratch2 = ToRegister(instr->TempAt(0));
4707 DwVfpRegister double_input = ToDoubleRegister(instr->value()); 4703 DwVfpRegister double_input = ToDoubleRegister(instr->InputAt(0));
4708 SwVfpRegister single_scratch = double_scratch0().low(); 4704 SwVfpRegister single_scratch = double_scratch0().low();
4709 4705
4710 Label done; 4706 Label done;
4711 4707
4712 if (instr->truncating()) { 4708 if (instr->truncating()) {
4713 Register scratch3 = ToRegister(instr->temp2()); 4709 Register scratch3 = ToRegister(instr->TempAt(1));
4714 __ EmitECMATruncate(result_reg, 4710 __ EmitECMATruncate(result_reg,
4715 double_input, 4711 double_input,
4716 single_scratch, 4712 single_scratch,
4717 scratch1, 4713 scratch1,
4718 scratch2, 4714 scratch2,
4719 scratch3); 4715 scratch3);
4720 } else { 4716 } else {
4721 VFPRoundingMode rounding_mode = kRoundToMinusInf; 4717 VFPRoundingMode rounding_mode = kRoundToMinusInf;
4722 __ EmitVFPTruncate(rounding_mode, 4718 __ EmitVFPTruncate(rounding_mode,
4723 single_scratch, 4719 single_scratch,
4724 double_input, 4720 double_input,
4725 scratch1, 4721 scratch1,
4726 scratch2, 4722 scratch2,
4727 kCheckForInexactConversion); 4723 kCheckForInexactConversion);
4728 // Deoptimize if we had a vfp invalid exception, 4724 // Deoptimize if we had a vfp invalid exception,
4729 // including inexact operation. 4725 // including inexact operation.
4730 DeoptimizeIf(ne, instr->environment()); 4726 DeoptimizeIf(ne, instr->environment());
4731 // Retrieve the result. 4727 // Retrieve the result.
4732 __ vmov(result_reg, single_scratch); 4728 __ vmov(result_reg, single_scratch);
4733 } 4729 }
4734 __ bind(&done); 4730 __ bind(&done);
4735 } 4731 }
4736 4732
4737 4733
4738 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 4734 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4739 LOperand* input = instr->value(); 4735 LOperand* input = instr->InputAt(0);
4740 __ tst(ToRegister(input), Operand(kSmiTagMask)); 4736 __ tst(ToRegister(input), Operand(kSmiTagMask));
4741 DeoptimizeIf(ne, instr->environment()); 4737 DeoptimizeIf(ne, instr->environment());
4742 } 4738 }
4743 4739
4744 4740
4745 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 4741 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4746 LOperand* input = instr->value(); 4742 LOperand* input = instr->InputAt(0);
4747 __ tst(ToRegister(input), Operand(kSmiTagMask)); 4743 __ tst(ToRegister(input), Operand(kSmiTagMask));
4748 DeoptimizeIf(eq, instr->environment()); 4744 DeoptimizeIf(eq, instr->environment());
4749 } 4745 }
4750 4746
4751 4747
4752 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 4748 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4753 Register input = ToRegister(instr->value()); 4749 Register input = ToRegister(instr->InputAt(0));
4754 Register scratch = scratch0(); 4750 Register scratch = scratch0();
4755 4751
4756 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 4752 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
4757 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); 4753 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
4758 4754
4759 if (instr->hydrogen()->is_interval_check()) { 4755 if (instr->hydrogen()->is_interval_check()) {
4760 InstanceType first; 4756 InstanceType first;
4761 InstanceType last; 4757 InstanceType last;
4762 instr->hydrogen()->GetCheckInterval(&first, &last); 4758 instr->hydrogen()->GetCheckInterval(&first, &last);
4763 4759
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
4816 LEnvironment* env) { 4812 LEnvironment* env) {
4817 Label success; 4813 Label success;
4818 __ CompareMap(reg, scratch, map, &success, mode); 4814 __ CompareMap(reg, scratch, map, &success, mode);
4819 DeoptimizeIf(ne, env); 4815 DeoptimizeIf(ne, env);
4820 __ bind(&success); 4816 __ bind(&success);
4821 } 4817 }
4822 4818
4823 4819
4824 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 4820 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4825 Register scratch = scratch0(); 4821 Register scratch = scratch0();
4826 LOperand* input = instr->value(); 4822 LOperand* input = instr->InputAt(0);
4827 ASSERT(input->IsRegister()); 4823 ASSERT(input->IsRegister());
4828 Register reg = ToRegister(input); 4824 Register reg = ToRegister(input);
4829 4825
4830 Label success; 4826 Label success;
4831 SmallMapList* map_set = instr->hydrogen()->map_set(); 4827 SmallMapList* map_set = instr->hydrogen()->map_set();
4832 for (int i = 0; i < map_set->length() - 1; i++) { 4828 for (int i = 0; i < map_set->length() - 1; i++) {
4833 Handle<Map> map = map_set->at(i); 4829 Handle<Map> map = map_set->at(i);
4834 __ CompareMap(reg, scratch, map, &success, REQUIRE_EXACT_MAP); 4830 __ CompareMap(reg, scratch, map, &success, REQUIRE_EXACT_MAP);
4835 __ b(eq, &success); 4831 __ b(eq, &success);
4836 } 4832 }
4837 Handle<Map> map = map_set->last(); 4833 Handle<Map> map = map_set->last();
4838 DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment()); 4834 DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment());
4839 __ bind(&success); 4835 __ bind(&success);
4840 } 4836 }
4841 4837
4842 4838
4843 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 4839 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
4844 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); 4840 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
4845 Register result_reg = ToRegister(instr->result()); 4841 Register result_reg = ToRegister(instr->result());
4846 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); 4842 DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0));
4847 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); 4843 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg);
4848 } 4844 }
4849 4845
4850 4846
4851 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 4847 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
4852 Register unclamped_reg = ToRegister(instr->unclamped()); 4848 Register unclamped_reg = ToRegister(instr->unclamped());
4853 Register result_reg = ToRegister(instr->result()); 4849 Register result_reg = ToRegister(instr->result());
4854 __ ClampUint8(result_reg, unclamped_reg); 4850 __ ClampUint8(result_reg, unclamped_reg);
4855 } 4851 }
4856 4852
4857 4853
4858 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 4854 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
4859 Register scratch = scratch0(); 4855 Register scratch = scratch0();
4860 Register input_reg = ToRegister(instr->unclamped()); 4856 Register input_reg = ToRegister(instr->unclamped());
4861 Register result_reg = ToRegister(instr->result()); 4857 Register result_reg = ToRegister(instr->result());
4862 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); 4858 DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0));
4863 Label is_smi, done, heap_number; 4859 Label is_smi, done, heap_number;
4864 4860
4865 // Both smi and heap number cases are handled. 4861 // Both smi and heap number cases are handled.
4866 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi); 4862 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi);
4867 4863
4868 // Check for heap number 4864 // Check for heap number
4869 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4865 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4870 __ cmp(scratch, Operand(factory()->heap_number_map())); 4866 __ cmp(scratch, Operand(factory()->heap_number_map()));
4871 __ b(eq, &heap_number); 4867 __ b(eq, &heap_number);
4872 4868
(...skipping 13 matching lines...) Expand all
4886 4882
4887 // smi 4883 // smi
4888 __ bind(&is_smi); 4884 __ bind(&is_smi);
4889 __ ClampUint8(result_reg, result_reg); 4885 __ ClampUint8(result_reg, result_reg);
4890 4886
4891 __ bind(&done); 4887 __ bind(&done);
4892 } 4888 }
4893 4889
4894 4890
4895 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 4891 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
4896 Register temp1 = ToRegister(instr->temp()); 4892 Register temp1 = ToRegister(instr->TempAt(0));
4897 Register temp2 = ToRegister(instr->temp2()); 4893 Register temp2 = ToRegister(instr->TempAt(1));
4898 4894
4899 Handle<JSObject> holder = instr->holder(); 4895 Handle<JSObject> holder = instr->holder();
4900 Handle<JSObject> current_prototype = instr->prototype(); 4896 Handle<JSObject> current_prototype = instr->prototype();
4901 4897
4902 // Load prototype object. 4898 // Load prototype object.
4903 __ LoadHeapObject(temp1, current_prototype); 4899 __ LoadHeapObject(temp1, current_prototype);
4904 4900
4905 // Check prototype maps up to the holder. 4901 // Check prototype maps up to the holder.
4906 while (!current_prototype.is_identical_to(holder)) { 4902 while (!current_prototype.is_identical_to(holder)) {
4907 DoCheckMapCommon(temp1, temp2, 4903 DoCheckMapCommon(temp1, temp2,
(...skipping 21 matching lines...) Expand all
4929 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); } 4925 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
4930 virtual LInstruction* instr() { return instr_; } 4926 virtual LInstruction* instr() { return instr_; }
4931 private: 4927 private:
4932 LAllocateObject* instr_; 4928 LAllocateObject* instr_;
4933 }; 4929 };
4934 4930
4935 DeferredAllocateObject* deferred = 4931 DeferredAllocateObject* deferred =
4936 new(zone()) DeferredAllocateObject(this, instr); 4932 new(zone()) DeferredAllocateObject(this, instr);
4937 4933
4938 Register result = ToRegister(instr->result()); 4934 Register result = ToRegister(instr->result());
4939 Register scratch = ToRegister(instr->temp()); 4935 Register scratch = ToRegister(instr->TempAt(0));
4940 Register scratch2 = ToRegister(instr->temp2()); 4936 Register scratch2 = ToRegister(instr->TempAt(1));
4941 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); 4937 Handle<JSFunction> constructor = instr->hydrogen()->constructor();
4942 Handle<Map> initial_map(constructor->initial_map()); 4938 Handle<Map> initial_map(constructor->initial_map());
4943 int instance_size = initial_map->instance_size(); 4939 int instance_size = initial_map->instance_size();
4944 ASSERT(initial_map->pre_allocated_property_fields() + 4940 ASSERT(initial_map->pre_allocated_property_fields() +
4945 initial_map->unused_property_fields() - 4941 initial_map->unused_property_fields() -
4946 initial_map->inobject_properties() == 0); 4942 initial_map->inobject_properties() == 0);
4947 4943
4948 // Allocate memory for the object. The initial map might change when 4944 // Allocate memory for the object. The initial map might change when
4949 // the constructor's prototype changes, but instance size and property 4945 // the constructor's prototype changes, but instance size and property
4950 // counts remain unchanged (if slack tracking finished). 4946 // counts remain unchanged (if slack tracking finished).
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
5222 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 5218 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
5223 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); 5219 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr);
5224 } else { 5220 } else {
5225 FastCloneShallowObjectStub stub(properties_count); 5221 FastCloneShallowObjectStub stub(properties_count);
5226 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 5222 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
5227 } 5223 }
5228 } 5224 }
5229 5225
5230 5226
5231 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { 5227 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5232 ASSERT(ToRegister(instr->value()).is(r0)); 5228 ASSERT(ToRegister(instr->InputAt(0)).is(r0));
5233 __ push(r0); 5229 __ push(r0);
5234 CallRuntime(Runtime::kToFastProperties, 1, instr); 5230 CallRuntime(Runtime::kToFastProperties, 1, instr);
5235 } 5231 }
5236 5232
5237 5233
5238 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 5234 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5239 Label materialized; 5235 Label materialized;
5240 // Registers will be used as follows: 5236 // Registers will be used as follows:
5241 // r7 = literals array. 5237 // r7 = literals array.
5242 // r1 = regexp literal. 5238 // r1 = regexp literal.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
5303 __ mov(r1, Operand(pretenure 5299 __ mov(r1, Operand(pretenure
5304 ? factory()->true_value() 5300 ? factory()->true_value()
5305 : factory()->false_value())); 5301 : factory()->false_value()));
5306 __ Push(cp, r2, r1); 5302 __ Push(cp, r2, r1);
5307 CallRuntime(Runtime::kNewClosure, 3, instr); 5303 CallRuntime(Runtime::kNewClosure, 3, instr);
5308 } 5304 }
5309 } 5305 }
5310 5306
5311 5307
5312 void LCodeGen::DoTypeof(LTypeof* instr) { 5308 void LCodeGen::DoTypeof(LTypeof* instr) {
5313 Register input = ToRegister(instr->value()); 5309 Register input = ToRegister(instr->InputAt(0));
5314 __ push(input); 5310 __ push(input);
5315 CallRuntime(Runtime::kTypeof, 1, instr); 5311 CallRuntime(Runtime::kTypeof, 1, instr);
5316 } 5312 }
5317 5313
5318 5314
5319 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 5315 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5320 Register input = ToRegister(instr->value()); 5316 Register input = ToRegister(instr->InputAt(0));
5321 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5317 int true_block = chunk_->LookupDestination(instr->true_block_id());
5322 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5318 int false_block = chunk_->LookupDestination(instr->false_block_id());
5323 Label* true_label = chunk_->GetAssemblyLabel(true_block); 5319 Label* true_label = chunk_->GetAssemblyLabel(true_block);
5324 Label* false_label = chunk_->GetAssemblyLabel(false_block); 5320 Label* false_label = chunk_->GetAssemblyLabel(false_block);
5325 5321
5326 Condition final_branch_condition = EmitTypeofIs(true_label, 5322 Condition final_branch_condition = EmitTypeofIs(true_label,
5327 false_label, 5323 false_label,
5328 input, 5324 input,
5329 instr->type_literal()); 5325 instr->type_literal());
5330 if (final_branch_condition != kNoCondition) { 5326 if (final_branch_condition != kNoCondition) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
5400 5396
5401 } else { 5397 } else {
5402 __ b(false_label); 5398 __ b(false_label);
5403 } 5399 }
5404 5400
5405 return final_branch_condition; 5401 return final_branch_condition;
5406 } 5402 }
5407 5403
5408 5404
5409 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5405 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5410 Register temp1 = ToRegister(instr->temp()); 5406 Register temp1 = ToRegister(instr->TempAt(0));
5411 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5407 int true_block = chunk_->LookupDestination(instr->true_block_id());
5412 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5408 int false_block = chunk_->LookupDestination(instr->false_block_id());
5413 5409
5414 EmitIsConstructCall(temp1, scratch0()); 5410 EmitIsConstructCall(temp1, scratch0());
5415 EmitBranch(true_block, false_block, eq); 5411 EmitBranch(true_block, false_block, eq);
5416 } 5412 }
5417 5413
5418 5414
5419 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) { 5415 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
5420 ASSERT(!temp1.is(temp2)); 5416 ASSERT(!temp1.is(temp2));
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
5660 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 5656 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
5661 __ ldr(result, FieldMemOperand(scratch, 5657 __ ldr(result, FieldMemOperand(scratch,
5662 FixedArray::kHeaderSize - kPointerSize)); 5658 FixedArray::kHeaderSize - kPointerSize));
5663 __ bind(&done); 5659 __ bind(&done);
5664 } 5660 }
5665 5661
5666 5662
5667 #undef __ 5663 #undef __
5668 5664
5669 } } // namespace v8::internal 5665 } } // 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