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

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

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

Powered by Google App Engine
This is Rietveld 408576698