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

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

Issue 11028027: Revert trunk to bleeding_edge at r12484 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 return MemOperand(fp, -(index + 3) * kPointerSize + kPointerSize); 457 return MemOperand(fp, -(index + 3) * kPointerSize + kPointerSize);
458 } else { 458 } else {
459 // Incoming parameter. Skip the return address and the first word of 459 // Incoming parameter. Skip the return address and the first word of
460 // the double. 460 // the double.
461 return MemOperand(fp, -(index - 1) * kPointerSize + kPointerSize); 461 return MemOperand(fp, -(index - 1) * kPointerSize + kPointerSize);
462 } 462 }
463 } 463 }
464 464
465 465
466 void LCodeGen::WriteTranslation(LEnvironment* environment, 466 void LCodeGen::WriteTranslation(LEnvironment* environment,
467 Translation* translation, 467 Translation* translation) {
468 int* arguments_index,
469 int* arguments_count) {
470 if (environment == NULL) return; 468 if (environment == NULL) return;
471 469
472 // The translation includes one command per value in the environment. 470 // The translation includes one command per value in the environment.
473 int translation_size = environment->values()->length(); 471 int translation_size = environment->values()->length();
474 // The output frame height does not include the parameters. 472 // The output frame height does not include the parameters.
475 int height = translation_size - environment->parameter_count(); 473 int height = translation_size - environment->parameter_count();
476 474
477 // Function parameters are arguments to the outermost environment. The 475 WriteTranslation(environment->outer(), translation);
478 // arguments index points to the first element of a sequence of tagged
479 // values on the stack that represent the arguments. This needs to be
480 // kept in sync with the LArgumentsElements implementation.
481 *arguments_index = -environment->parameter_count();
482 *arguments_count = environment->parameter_count();
483
484 WriteTranslation(environment->outer(),
485 translation,
486 arguments_index,
487 arguments_count);
488 int closure_id = *info()->closure() != *environment->closure() 476 int closure_id = *info()->closure() != *environment->closure()
489 ? DefineDeoptimizationLiteral(environment->closure()) 477 ? DefineDeoptimizationLiteral(environment->closure())
490 : Translation::kSelfLiteralId; 478 : Translation::kSelfLiteralId;
491 479
492 switch (environment->frame_type()) { 480 switch (environment->frame_type()) {
493 case JS_FUNCTION: 481 case JS_FUNCTION:
494 translation->BeginJSFrame(environment->ast_id(), closure_id, height); 482 translation->BeginJSFrame(environment->ast_id(), closure_id, height);
495 break; 483 break;
496 case JS_CONSTRUCT: 484 case JS_CONSTRUCT:
497 translation->BeginConstructStubFrame(closure_id, translation_size); 485 translation->BeginConstructStubFrame(closure_id, translation_size);
498 break; 486 break;
499 case JS_GETTER: 487 case JS_GETTER:
500 ASSERT(translation_size == 1); 488 ASSERT(translation_size == 1);
501 ASSERT(height == 0); 489 ASSERT(height == 0);
502 translation->BeginGetterStubFrame(closure_id); 490 translation->BeginGetterStubFrame(closure_id);
503 break; 491 break;
504 case JS_SETTER: 492 case JS_SETTER:
505 ASSERT(translation_size == 2); 493 ASSERT(translation_size == 2);
506 ASSERT(height == 0); 494 ASSERT(height == 0);
507 translation->BeginSetterStubFrame(closure_id); 495 translation->BeginSetterStubFrame(closure_id);
508 break; 496 break;
509 case ARGUMENTS_ADAPTOR: 497 case ARGUMENTS_ADAPTOR:
510 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 498 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
511 break; 499 break;
512 } 500 }
513
514 // Inlined frames which push their arguments cause the index to be
515 // bumped and a new stack area to be used for materialization.
516 if (environment->entry() != NULL &&
517 environment->entry()->arguments_pushed()) {
518 *arguments_index = *arguments_index < 0
519 ? GetStackSlotCount()
520 : *arguments_index + *arguments_count;
521 *arguments_count = environment->entry()->arguments_count() + 1;
522 }
523
524 for (int i = 0; i < translation_size; ++i) { 501 for (int i = 0; i < translation_size; ++i) {
525 LOperand* value = environment->values()->at(i); 502 LOperand* value = environment->values()->at(i);
526 // spilled_registers_ and spilled_double_registers_ are either 503 // spilled_registers_ and spilled_double_registers_ are either
527 // both NULL or both set. 504 // both NULL or both set.
528 if (environment->spilled_registers() != NULL && value != NULL) { 505 if (environment->spilled_registers() != NULL && value != NULL) {
529 if (value->IsRegister() && 506 if (value->IsRegister() &&
530 environment->spilled_registers()[value->index()] != NULL) { 507 environment->spilled_registers()[value->index()] != NULL) {
531 translation->MarkDuplicate(); 508 translation->MarkDuplicate();
532 AddToTranslation(translation, 509 AddToTranslation(translation,
533 environment->spilled_registers()[value->index()], 510 environment->spilled_registers()[value->index()],
534 environment->HasTaggedValueAt(i), 511 environment->HasTaggedValueAt(i),
535 environment->HasUint32ValueAt(i), 512 environment->HasUint32ValueAt(i));
536 *arguments_index,
537 *arguments_count);
538 } else if ( 513 } else if (
539 value->IsDoubleRegister() && 514 value->IsDoubleRegister() &&
540 environment->spilled_double_registers()[value->index()] != NULL) { 515 environment->spilled_double_registers()[value->index()] != NULL) {
541 translation->MarkDuplicate(); 516 translation->MarkDuplicate();
542 AddToTranslation( 517 AddToTranslation(
543 translation, 518 translation,
544 environment->spilled_double_registers()[value->index()], 519 environment->spilled_double_registers()[value->index()],
545 false, 520 false,
546 false, 521 false);
547 *arguments_index,
548 *arguments_count);
549 } 522 }
550 } 523 }
551 524
552 AddToTranslation(translation, 525 AddToTranslation(translation,
553 value, 526 value,
554 environment->HasTaggedValueAt(i), 527 environment->HasTaggedValueAt(i),
555 environment->HasUint32ValueAt(i), 528 environment->HasUint32ValueAt(i));
556 *arguments_index,
557 *arguments_count);
558 } 529 }
559 } 530 }
560 531
561 532
562 void LCodeGen::AddToTranslation(Translation* translation, 533 void LCodeGen::AddToTranslation(Translation* translation,
563 LOperand* op, 534 LOperand* op,
564 bool is_tagged, 535 bool is_tagged,
565 bool is_uint32, 536 bool is_uint32) {
566 int arguments_index,
567 int arguments_count) {
568 if (op == NULL) { 537 if (op == NULL) {
569 // TODO(twuerthinger): Introduce marker operands to indicate that this value 538 // TODO(twuerthinger): Introduce marker operands to indicate that this value
570 // is not present and must be reconstructed from the deoptimizer. Currently 539 // is not present and must be reconstructed from the deoptimizer. Currently
571 // this is only used for the arguments object. 540 // this is only used for the arguments object.
572 translation->StoreArgumentsObject(arguments_index, arguments_count); 541 translation->StoreArgumentsObject();
573 } else if (op->IsStackSlot()) { 542 } else if (op->IsStackSlot()) {
574 if (is_tagged) { 543 if (is_tagged) {
575 translation->StoreStackSlot(op->index()); 544 translation->StoreStackSlot(op->index());
576 } else if (is_uint32) { 545 } else if (is_uint32) {
577 translation->StoreUint32StackSlot(op->index()); 546 translation->StoreUint32StackSlot(op->index());
578 } else { 547 } else {
579 translation->StoreInt32StackSlot(op->index()); 548 translation->StoreInt32StackSlot(op->index());
580 } 549 }
581 } else if (op->IsDoubleStackSlot()) { 550 } else if (op->IsDoubleStackSlot()) {
582 translation->StoreDoubleStackSlot(op->index()); 551 translation->StoreDoubleStackSlot(op->index());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 // 0 ..................................................... size-1 637 // 0 ..................................................... size-1
669 // [parameters] [locals] [expression stack including arguments] 638 // [parameters] [locals] [expression stack including arguments]
670 639
671 // Layout of the translation: 640 // Layout of the translation:
672 // 0 ........................................................ size - 1 + 4 641 // 0 ........................................................ size - 1 + 4
673 // [expression stack including arguments] [locals] [4 words] [parameters] 642 // [expression stack including arguments] [locals] [4 words] [parameters]
674 // |>------------ translation_size ------------<| 643 // |>------------ translation_size ------------<|
675 644
676 int frame_count = 0; 645 int frame_count = 0;
677 int jsframe_count = 0; 646 int jsframe_count = 0;
678 int args_index = 0;
679 int args_count = 0;
680 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 647 for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
681 ++frame_count; 648 ++frame_count;
682 if (e->frame_type() == JS_FUNCTION) { 649 if (e->frame_type() == JS_FUNCTION) {
683 ++jsframe_count; 650 ++jsframe_count;
684 } 651 }
685 } 652 }
686 Translation translation(&translations_, frame_count, jsframe_count, zone()); 653 Translation translation(&translations_, frame_count, jsframe_count,
687 WriteTranslation(environment, &translation, &args_index, &args_count); 654 zone());
655 WriteTranslation(environment, &translation);
688 int deoptimization_index = deoptimizations_.length(); 656 int deoptimization_index = deoptimizations_.length();
689 int pc_offset = masm()->pc_offset(); 657 int pc_offset = masm()->pc_offset();
690 environment->Register(deoptimization_index, 658 environment->Register(deoptimization_index,
691 translation.index(), 659 translation.index(),
692 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 660 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
693 deoptimizations_.Add(environment, zone()); 661 deoptimizations_.Add(environment, zone());
694 } 662 }
695 } 663 }
696 664
697 665
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 } 912 }
945 913
946 914
947 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 915 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
948 // Nothing to do. 916 // Nothing to do.
949 } 917 }
950 918
951 919
952 void LCodeGen::DoModI(LModI* instr) { 920 void LCodeGen::DoModI(LModI* instr) {
953 if (instr->hydrogen()->HasPowerOf2Divisor()) { 921 if (instr->hydrogen()->HasPowerOf2Divisor()) {
954 Register dividend = ToRegister(instr->left()); 922 Register dividend = ToRegister(instr->InputAt(0));
955 Register result = ToRegister(instr->result()); 923 Register result = ToRegister(instr->result());
956 924
957 int32_t divisor = 925 int32_t divisor =
958 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 926 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
959 927
960 if (divisor < 0) divisor = -divisor; 928 if (divisor < 0) divisor = -divisor;
961 929
962 Label positive_dividend, done; 930 Label positive_dividend, done;
963 __ cmp(dividend, Operand(0)); 931 __ cmp(dividend, Operand(0));
964 __ b(pl, &positive_dividend); 932 __ b(pl, &positive_dividend);
965 __ rsb(result, dividend, Operand(0)); 933 __ rsb(result, dividend, Operand(0));
966 __ and_(result, result, Operand(divisor - 1), SetCC); 934 __ and_(result, result, Operand(divisor - 1), SetCC);
967 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 935 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
968 DeoptimizeIf(eq, instr->environment()); 936 DeoptimizeIf(eq, instr->environment());
969 } 937 }
970 __ rsb(result, result, Operand(0)); 938 __ rsb(result, result, Operand(0));
971 __ b(&done); 939 __ b(&done);
972 __ bind(&positive_dividend); 940 __ bind(&positive_dividend);
973 __ and_(result, dividend, Operand(divisor - 1)); 941 __ and_(result, dividend, Operand(divisor - 1));
974 __ bind(&done); 942 __ bind(&done);
975 return; 943 return;
976 } 944 }
977 945
978 // These registers hold untagged 32 bit values. 946 // These registers hold untagged 32 bit values.
979 Register left = ToRegister(instr->left()); 947 Register left = ToRegister(instr->InputAt(0));
980 Register right = ToRegister(instr->right()); 948 Register right = ToRegister(instr->InputAt(1));
981 Register result = ToRegister(instr->result()); 949 Register result = ToRegister(instr->result());
982 950
983 Register scratch = scratch0(); 951 Register scratch = scratch0();
984 Register scratch2 = ToRegister(instr->temp()); 952 Register scratch2 = ToRegister(instr->TempAt(0));
985 DwVfpRegister dividend = ToDoubleRegister(instr->temp2()); 953 DwVfpRegister dividend = ToDoubleRegister(instr->TempAt(1));
986 DwVfpRegister divisor = ToDoubleRegister(instr->temp3()); 954 DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2));
987 DwVfpRegister quotient = double_scratch0(); 955 DwVfpRegister quotient = double_scratch0();
988 956
989 ASSERT(!dividend.is(divisor)); 957 ASSERT(!dividend.is(divisor));
990 ASSERT(!dividend.is(quotient)); 958 ASSERT(!dividend.is(quotient));
991 ASSERT(!divisor.is(quotient)); 959 ASSERT(!divisor.is(quotient));
992 ASSERT(!scratch.is(left)); 960 ASSERT(!scratch.is(left));
993 ASSERT(!scratch.is(right)); 961 ASSERT(!scratch.is(right));
994 ASSERT(!scratch.is(result)); 962 ASSERT(!scratch.is(result));
995 963
996 Label done, vfp_modulo, both_positive, right_negative; 964 Label done, vfp_modulo, both_positive, right_negative;
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 } 1147 }
1180 } 1148 }
1181 1149
1182 1150
1183 void LCodeGen::DoDivI(LDivI* instr) { 1151 void LCodeGen::DoDivI(LDivI* instr) {
1184 class DeferredDivI: public LDeferredCode { 1152 class DeferredDivI: public LDeferredCode {
1185 public: 1153 public:
1186 DeferredDivI(LCodeGen* codegen, LDivI* instr) 1154 DeferredDivI(LCodeGen* codegen, LDivI* instr)
1187 : LDeferredCode(codegen), instr_(instr) { } 1155 : LDeferredCode(codegen), instr_(instr) { }
1188 virtual void Generate() { 1156 virtual void Generate() {
1189 codegen()->DoDeferredBinaryOpStub(instr_->pointer_map(), 1157 codegen()->DoDeferredBinaryOpStub(instr_, Token::DIV);
1190 instr_->left(),
1191 instr_->right(),
1192 Token::DIV);
1193 } 1158 }
1194 virtual LInstruction* instr() { return instr_; } 1159 virtual LInstruction* instr() { return instr_; }
1195 private: 1160 private:
1196 LDivI* instr_; 1161 LDivI* instr_;
1197 }; 1162 };
1198 1163
1199 const Register left = ToRegister(instr->left()); 1164 const Register left = ToRegister(instr->InputAt(0));
1200 const Register right = ToRegister(instr->right()); 1165 const Register right = ToRegister(instr->InputAt(1));
1201 const Register scratch = scratch0(); 1166 const Register scratch = scratch0();
1202 const Register result = ToRegister(instr->result()); 1167 const Register result = ToRegister(instr->result());
1203 1168
1204 // Check for x / 0. 1169 // Check for x / 0.
1205 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1170 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1206 __ cmp(right, Operand(0)); 1171 __ cmp(right, Operand(0));
1207 DeoptimizeIf(eq, instr->environment()); 1172 DeoptimizeIf(eq, instr->environment());
1208 } 1173 }
1209 1174
1210 // Check for (0 / -x) that will produce negative zero. 1175 // Check for (0 / -x) that will produce negative zero.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 __ b(&done); 1224 __ b(&done);
1260 1225
1261 __ bind(&deoptimize); 1226 __ bind(&deoptimize);
1262 DeoptimizeIf(al, instr->environment()); 1227 DeoptimizeIf(al, instr->environment());
1263 __ bind(&done); 1228 __ bind(&done);
1264 } 1229 }
1265 1230
1266 1231
1267 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { 1232 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
1268 const Register result = ToRegister(instr->result()); 1233 const Register result = ToRegister(instr->result());
1269 const Register left = ToRegister(instr->left()); 1234 const Register left = ToRegister(instr->InputAt(0));
1270 const Register remainder = ToRegister(instr->temp()); 1235 const Register remainder = ToRegister(instr->TempAt(0));
1271 const Register scratch = scratch0(); 1236 const Register scratch = scratch0();
1272 1237
1273 // We only optimize this for division by constants, because the standard 1238 // We only optimize this for division by constants, because the standard
1274 // integer division routine is usually slower than transitionning to VFP. 1239 // integer division routine is usually slower than transitionning to VFP.
1275 // This could be optimized on processors with SDIV available. 1240 // This could be optimized on processors with SDIV available.
1276 ASSERT(instr->right()->IsConstantOperand()); 1241 ASSERT(instr->InputAt(1)->IsConstantOperand());
1277 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); 1242 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1)));
1278 if (divisor < 0) { 1243 if (divisor < 0) {
1279 __ cmp(left, Operand(0)); 1244 __ cmp(left, Operand(0));
1280 DeoptimizeIf(eq, instr->environment()); 1245 DeoptimizeIf(eq, instr->environment());
1281 } 1246 }
1282 EmitSignedIntegerDivisionByConstant(result, 1247 EmitSignedIntegerDivisionByConstant(result,
1283 left, 1248 left,
1284 divisor, 1249 divisor,
1285 remainder, 1250 remainder,
1286 scratch, 1251 scratch,
1287 instr->environment()); 1252 instr->environment());
1288 // We operated a truncating division. Correct the result if necessary. 1253 // We operated a truncating division. Correct the result if necessary.
1289 __ cmp(remainder, Operand(0)); 1254 __ cmp(remainder, Operand(0));
1290 __ teq(remainder, Operand(divisor), ne); 1255 __ teq(remainder, Operand(divisor), ne);
1291 __ sub(result, result, Operand(1), LeaveCC, mi); 1256 __ sub(result, result, Operand(1), LeaveCC, mi);
1292 } 1257 }
1293 1258
1294 1259
1295 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, 1260 template<int T>
1296 LOperand* left_argument, 1261 void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
1297 LOperand* right_argument,
1298 Token::Value op) { 1262 Token::Value op) {
1299 Register left = ToRegister(left_argument); 1263 Register left = ToRegister(instr->InputAt(0));
1300 Register right = ToRegister(right_argument); 1264 Register right = ToRegister(instr->InputAt(1));
1301 1265
1302 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles); 1266 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles);
1303 // Move left to r1 and right to r0 for the stub call. 1267 // Move left to r1 and right to r0 for the stub call.
1304 if (left.is(r1)) { 1268 if (left.is(r1)) {
1305 __ Move(r0, right); 1269 __ Move(r0, right);
1306 } else if (left.is(r0) && right.is(r1)) { 1270 } else if (left.is(r0) && right.is(r1)) {
1307 __ Swap(r0, r1, r2); 1271 __ Swap(r0, r1, r2);
1308 } else if (left.is(r0)) { 1272 } else if (left.is(r0)) {
1309 ASSERT(!right.is(r1)); 1273 ASSERT(!right.is(r1));
1310 __ mov(r1, r0); 1274 __ mov(r1, r0);
1311 __ mov(r0, right); 1275 __ mov(r0, right);
1312 } else { 1276 } else {
1313 ASSERT(!left.is(r0) && !right.is(r0)); 1277 ASSERT(!left.is(r0) && !right.is(r0));
1314 __ mov(r0, right); 1278 __ mov(r0, right);
1315 __ mov(r1, left); 1279 __ mov(r1, left);
1316 } 1280 }
1317 BinaryOpStub stub(op, OVERWRITE_LEFT); 1281 BinaryOpStub stub(op, OVERWRITE_LEFT);
1318 __ CallStub(&stub); 1282 __ CallStub(&stub);
1319 RecordSafepointWithRegistersAndDoubles(pointer_map, 1283 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
1320 0, 1284 0,
1321 Safepoint::kNoLazyDeopt); 1285 Safepoint::kNoLazyDeopt);
1322 // Overwrite the stored value of r0 with the result of the stub. 1286 // Overwrite the stored value of r0 with the result of the stub.
1323 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0); 1287 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0);
1324 } 1288 }
1325 1289
1326 1290
1327 void LCodeGen::DoMulI(LMulI* instr) { 1291 void LCodeGen::DoMulI(LMulI* instr) {
1328 Register scratch = scratch0(); 1292 Register scratch = scratch0();
1329 Register result = ToRegister(instr->result()); 1293 Register result = ToRegister(instr->result());
1330 // Note that result may alias left. 1294 // Note that result may alias left.
1331 Register left = ToRegister(instr->left()); 1295 Register left = ToRegister(instr->InputAt(0));
1332 LOperand* right_op = instr->right(); 1296 LOperand* right_op = instr->InputAt(1);
1333 1297
1334 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1298 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1335 bool bailout_on_minus_zero = 1299 bool bailout_on_minus_zero =
1336 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1300 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1337 1301
1338 if (right_op->IsConstantOperand() && !can_overflow) { 1302 if (right_op->IsConstantOperand() && !can_overflow) {
1339 // Use optimized code for specific constants. 1303 // Use optimized code for specific constants.
1340 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); 1304 int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
1341 1305
1342 if (bailout_on_minus_zero && (constant < 0)) { 1306 if (bailout_on_minus_zero && (constant < 0)) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 } else { 1353 } else {
1390 // Generate standard code. 1354 // Generate standard code.
1391 __ mov(ip, Operand(constant)); 1355 __ mov(ip, Operand(constant));
1392 __ mul(result, left, ip); 1356 __ mul(result, left, ip);
1393 } 1357 }
1394 } 1358 }
1395 1359
1396 } else { 1360 } else {
1397 Register right = EmitLoadRegister(right_op, scratch); 1361 Register right = EmitLoadRegister(right_op, scratch);
1398 if (bailout_on_minus_zero) { 1362 if (bailout_on_minus_zero) {
1399 __ orr(ToRegister(instr->temp()), left, right); 1363 __ orr(ToRegister(instr->TempAt(0)), left, right);
1400 } 1364 }
1401 1365
1402 if (can_overflow) { 1366 if (can_overflow) {
1403 // scratch:result = left * right. 1367 // scratch:result = left * right.
1404 __ smull(result, scratch, left, right); 1368 __ smull(result, scratch, left, right);
1405 __ cmp(scratch, Operand(result, ASR, 31)); 1369 __ cmp(scratch, Operand(result, ASR, 31));
1406 DeoptimizeIf(ne, instr->environment()); 1370 DeoptimizeIf(ne, instr->environment());
1407 } else { 1371 } else {
1408 __ mul(result, left, right); 1372 __ mul(result, left, right);
1409 } 1373 }
1410 1374
1411 if (bailout_on_minus_zero) { 1375 if (bailout_on_minus_zero) {
1412 // Bail out if the result is supposed to be negative zero. 1376 // Bail out if the result is supposed to be negative zero.
1413 Label done; 1377 Label done;
1414 __ cmp(result, Operand(0)); 1378 __ cmp(result, Operand(0));
1415 __ b(ne, &done); 1379 __ b(ne, &done);
1416 __ cmp(ToRegister(instr->temp()), Operand(0)); 1380 __ cmp(ToRegister(instr->TempAt(0)), Operand(0));
1417 DeoptimizeIf(mi, instr->environment()); 1381 DeoptimizeIf(mi, instr->environment());
1418 __ bind(&done); 1382 __ bind(&done);
1419 } 1383 }
1420 } 1384 }
1421 } 1385 }
1422 1386
1423 1387
1424 void LCodeGen::DoBitI(LBitI* instr) { 1388 void LCodeGen::DoBitI(LBitI* instr) {
1425 LOperand* left_op = instr->left(); 1389 LOperand* left_op = instr->InputAt(0);
1426 LOperand* right_op = instr->right(); 1390 LOperand* right_op = instr->InputAt(1);
1427 ASSERT(left_op->IsRegister()); 1391 ASSERT(left_op->IsRegister());
1428 Register left = ToRegister(left_op); 1392 Register left = ToRegister(left_op);
1429 Register result = ToRegister(instr->result()); 1393 Register result = ToRegister(instr->result());
1430 Operand right(no_reg); 1394 Operand right(no_reg);
1431 1395
1432 if (right_op->IsStackSlot() || right_op->IsArgument()) { 1396 if (right_op->IsStackSlot() || right_op->IsArgument()) {
1433 right = Operand(EmitLoadRegister(right_op, ip)); 1397 right = Operand(EmitLoadRegister(right_op, ip));
1434 } else { 1398 } else {
1435 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); 1399 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
1436 right = ToOperand(right_op); 1400 right = ToOperand(right_op);
(...skipping 12 matching lines...) Expand all
1449 default: 1413 default:
1450 UNREACHABLE(); 1414 UNREACHABLE();
1451 break; 1415 break;
1452 } 1416 }
1453 } 1417 }
1454 1418
1455 1419
1456 void LCodeGen::DoShiftI(LShiftI* instr) { 1420 void LCodeGen::DoShiftI(LShiftI* instr) {
1457 // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so 1421 // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so
1458 // result may alias either of them. 1422 // result may alias either of them.
1459 LOperand* right_op = instr->right(); 1423 LOperand* right_op = instr->InputAt(1);
1460 Register left = ToRegister(instr->left()); 1424 Register left = ToRegister(instr->InputAt(0));
1461 Register result = ToRegister(instr->result()); 1425 Register result = ToRegister(instr->result());
1462 Register scratch = scratch0(); 1426 Register scratch = scratch0();
1463 if (right_op->IsRegister()) { 1427 if (right_op->IsRegister()) {
1464 // Mask the right_op operand. 1428 // Mask the right_op operand.
1465 __ and_(scratch, ToRegister(right_op), Operand(0x1F)); 1429 __ and_(scratch, ToRegister(right_op), Operand(0x1F));
1466 switch (instr->op()) { 1430 switch (instr->op()) {
1467 case Token::SAR: 1431 case Token::SAR:
1468 __ mov(result, Operand(left, ASR, scratch)); 1432 __ mov(result, Operand(left, ASR, scratch));
1469 break; 1433 break;
1470 case Token::SHR: 1434 case Token::SHR:
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1514 break; 1478 break;
1515 default: 1479 default:
1516 UNREACHABLE(); 1480 UNREACHABLE();
1517 break; 1481 break;
1518 } 1482 }
1519 } 1483 }
1520 } 1484 }
1521 1485
1522 1486
1523 void LCodeGen::DoSubI(LSubI* instr) { 1487 void LCodeGen::DoSubI(LSubI* instr) {
1524 LOperand* left = instr->left(); 1488 LOperand* left = instr->InputAt(0);
1525 LOperand* right = instr->right(); 1489 LOperand* right = instr->InputAt(1);
1526 LOperand* result = instr->result(); 1490 LOperand* result = instr->result();
1527 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1491 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1528 SBit set_cond = can_overflow ? SetCC : LeaveCC; 1492 SBit set_cond = can_overflow ? SetCC : LeaveCC;
1529 1493
1530 if (right->IsStackSlot() || right->IsArgument()) { 1494 if (right->IsStackSlot() || right->IsArgument()) {
1531 Register right_reg = EmitLoadRegister(right, ip); 1495 Register right_reg = EmitLoadRegister(right, ip);
1532 __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); 1496 __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
1533 } else { 1497 } else {
1534 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1498 ASSERT(right->IsRegister() || right->IsConstantOperand());
1535 __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); 1499 __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
1536 } 1500 }
1537 1501
1538 if (can_overflow) { 1502 if (can_overflow) {
1539 DeoptimizeIf(vs, instr->environment()); 1503 DeoptimizeIf(vs, instr->environment());
1540 } 1504 }
1541 } 1505 }
1542 1506
1543 1507
1544 void LCodeGen::DoConstantI(LConstantI* instr) { 1508 void LCodeGen::DoConstantI(LConstantI* instr) {
1545 ASSERT(instr->result()->IsRegister()); 1509 ASSERT(instr->result()->IsRegister());
1546 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1510 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1547 } 1511 }
1548 1512
1549 1513
1550 void LCodeGen::DoConstantD(LConstantD* instr) { 1514 void LCodeGen::DoConstantD(LConstantD* instr) {
1551 ASSERT(instr->result()->IsDoubleRegister()); 1515 ASSERT(instr->result()->IsDoubleRegister());
1552 DwVfpRegister result = ToDoubleRegister(instr->result()); 1516 DwVfpRegister result = ToDoubleRegister(instr->result());
1553 double v = instr->value(); 1517 double v = instr->value();
1554 __ Vmov(result, v, scratch0()); 1518 __ Vmov(result, v);
1555 } 1519 }
1556 1520
1557 1521
1558 void LCodeGen::DoConstantT(LConstantT* instr) { 1522 void LCodeGen::DoConstantT(LConstantT* instr) {
1559 Handle<Object> value = instr->value(); 1523 Handle<Object> value = instr->value();
1560 if (value->IsSmi()) { 1524 if (value->IsSmi()) {
1561 __ mov(ToRegister(instr->result()), Operand(value)); 1525 __ mov(ToRegister(instr->result()), Operand(value));
1562 } else { 1526 } else {
1563 __ LoadHeapObject(ToRegister(instr->result()), 1527 __ LoadHeapObject(ToRegister(instr->result()),
1564 Handle<HeapObject>::cast(value)); 1528 Handle<HeapObject>::cast(value));
1565 } 1529 }
1566 } 1530 }
1567 1531
1568 1532
1569 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1533 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1570 Register result = ToRegister(instr->result()); 1534 Register result = ToRegister(instr->result());
1571 Register array = ToRegister(instr->value()); 1535 Register array = ToRegister(instr->InputAt(0));
1572 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset)); 1536 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset));
1573 } 1537 }
1574 1538
1575 1539
1576 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { 1540 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
1577 Register result = ToRegister(instr->result()); 1541 Register result = ToRegister(instr->result());
1578 Register array = ToRegister(instr->value()); 1542 Register array = ToRegister(instr->InputAt(0));
1579 __ ldr(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset)); 1543 __ ldr(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset));
1580 } 1544 }
1581 1545
1582 1546
1583 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1547 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1584 Register result = ToRegister(instr->result()); 1548 Register result = ToRegister(instr->result());
1585 Register map = ToRegister(instr->value()); 1549 Register map = ToRegister(instr->InputAt(0));
1586 __ EnumLength(result, map); 1550 __ EnumLength(result, map);
1587 } 1551 }
1588 1552
1589 1553
1590 void LCodeGen::DoElementsKind(LElementsKind* instr) { 1554 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1591 Register result = ToRegister(instr->result()); 1555 Register result = ToRegister(instr->result());
1592 Register input = ToRegister(instr->value()); 1556 Register input = ToRegister(instr->InputAt(0));
1593 1557
1594 // Load map into |result|. 1558 // Load map into |result|.
1595 __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset)); 1559 __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset));
1596 // Load the map's "bit field 2" into |result|. We only need the first byte, 1560 // Load the map's "bit field 2" into |result|. We only need the first byte,
1597 // but the following bit field extraction takes care of that anyway. 1561 // but the following bit field extraction takes care of that anyway.
1598 __ ldr(result, FieldMemOperand(result, Map::kBitField2Offset)); 1562 __ ldr(result, FieldMemOperand(result, Map::kBitField2Offset));
1599 // Retrieve elements_kind from bit field 2. 1563 // Retrieve elements_kind from bit field 2.
1600 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); 1564 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount);
1601 } 1565 }
1602 1566
1603 1567
1604 void LCodeGen::DoValueOf(LValueOf* instr) { 1568 void LCodeGen::DoValueOf(LValueOf* instr) {
1605 Register input = ToRegister(instr->value()); 1569 Register input = ToRegister(instr->InputAt(0));
1606 Register result = ToRegister(instr->result()); 1570 Register result = ToRegister(instr->result());
1607 Register map = ToRegister(instr->temp()); 1571 Register map = ToRegister(instr->TempAt(0));
1608 Label done; 1572 Label done;
1609 1573
1610 // If the object is a smi return the object. 1574 // If the object is a smi return the object.
1611 __ tst(input, Operand(kSmiTagMask)); 1575 __ tst(input, Operand(kSmiTagMask));
1612 __ Move(result, input, eq); 1576 __ Move(result, input, eq);
1613 __ b(eq, &done); 1577 __ b(eq, &done);
1614 1578
1615 // If the object is not a value type, return the object. 1579 // If the object is not a value type, return the object.
1616 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); 1580 __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
1617 __ Move(result, input, ne); 1581 __ Move(result, input, ne);
1618 __ b(ne, &done); 1582 __ b(ne, &done);
1619 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); 1583 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset));
1620 1584
1621 __ bind(&done); 1585 __ bind(&done);
1622 } 1586 }
1623 1587
1624 1588
1625 void LCodeGen::DoDateField(LDateField* instr) { 1589 void LCodeGen::DoDateField(LDateField* instr) {
1626 Register object = ToRegister(instr->date()); 1590 Register object = ToRegister(instr->InputAt(0));
1627 Register result = ToRegister(instr->result()); 1591 Register result = ToRegister(instr->result());
1628 Register scratch = ToRegister(instr->temp()); 1592 Register scratch = ToRegister(instr->TempAt(0));
1629 Smi* index = instr->index(); 1593 Smi* index = instr->index();
1630 Label runtime, done; 1594 Label runtime, done;
1631 ASSERT(object.is(result)); 1595 ASSERT(object.is(result));
1632 ASSERT(object.is(r0)); 1596 ASSERT(object.is(r0));
1633 ASSERT(!scratch.is(scratch0())); 1597 ASSERT(!scratch.is(scratch0()));
1634 ASSERT(!scratch.is(object)); 1598 ASSERT(!scratch.is(object));
1635 1599
1636 __ tst(object, Operand(kSmiTagMask)); 1600 __ tst(object, Operand(kSmiTagMask));
1637 DeoptimizeIf(eq, instr->environment()); 1601 DeoptimizeIf(eq, instr->environment());
1638 __ CompareObjectType(object, scratch, scratch, JS_DATE_TYPE); 1602 __ CompareObjectType(object, scratch, scratch, JS_DATE_TYPE);
(...skipping 16 matching lines...) Expand all
1655 __ bind(&runtime); 1619 __ bind(&runtime);
1656 __ PrepareCallCFunction(2, scratch); 1620 __ PrepareCallCFunction(2, scratch);
1657 __ mov(r1, Operand(index)); 1621 __ mov(r1, Operand(index));
1658 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 1622 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
1659 __ bind(&done); 1623 __ bind(&done);
1660 } 1624 }
1661 } 1625 }
1662 1626
1663 1627
1664 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1628 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1665 Register input = ToRegister(instr->value()); 1629 Register input = ToRegister(instr->InputAt(0));
1666 Register result = ToRegister(instr->result()); 1630 Register result = ToRegister(instr->result());
1667 __ mvn(result, Operand(input)); 1631 __ mvn(result, Operand(input));
1668 } 1632 }
1669 1633
1670 1634
1671 void LCodeGen::DoThrow(LThrow* instr) { 1635 void LCodeGen::DoThrow(LThrow* instr) {
1672 Register input_reg = EmitLoadRegister(instr->value(), ip); 1636 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
1673 __ push(input_reg); 1637 __ push(input_reg);
1674 CallRuntime(Runtime::kThrow, 1, instr); 1638 CallRuntime(Runtime::kThrow, 1, instr);
1675 1639
1676 if (FLAG_debug_code) { 1640 if (FLAG_debug_code) {
1677 __ stop("Unreachable code."); 1641 __ stop("Unreachable code.");
1678 } 1642 }
1679 } 1643 }
1680 1644
1681 1645
1682 void LCodeGen::DoAddI(LAddI* instr) { 1646 void LCodeGen::DoAddI(LAddI* instr) {
1683 LOperand* left = instr->left(); 1647 LOperand* left = instr->InputAt(0);
1684 LOperand* right = instr->right(); 1648 LOperand* right = instr->InputAt(1);
1685 LOperand* result = instr->result(); 1649 LOperand* result = instr->result();
1686 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1650 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1687 SBit set_cond = can_overflow ? SetCC : LeaveCC; 1651 SBit set_cond = can_overflow ? SetCC : LeaveCC;
1688 1652
1689 if (right->IsStackSlot() || right->IsArgument()) { 1653 if (right->IsStackSlot() || right->IsArgument()) {
1690 Register right_reg = EmitLoadRegister(right, ip); 1654 Register right_reg = EmitLoadRegister(right, ip);
1691 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); 1655 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
1692 } else { 1656 } else {
1693 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1657 ASSERT(right->IsRegister() || right->IsConstantOperand());
1694 __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); 1658 __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
1695 } 1659 }
1696 1660
1697 if (can_overflow) { 1661 if (can_overflow) {
1698 DeoptimizeIf(vs, instr->environment()); 1662 DeoptimizeIf(vs, instr->environment());
1699 } 1663 }
1700 } 1664 }
1701 1665
1702 1666
1703 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1667 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1704 LOperand* left = instr->left(); 1668 LOperand* left = instr->InputAt(0);
1705 LOperand* right = instr->right(); 1669 LOperand* right = instr->InputAt(1);
1706 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1670 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1707 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; 1671 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
1708 if (instr->hydrogen()->representation().IsInteger32()) { 1672 if (instr->hydrogen()->representation().IsInteger32()) {
1709 Register left_reg = ToRegister(left); 1673 Register left_reg = ToRegister(left);
1710 Operand right_op = (right->IsRegister() || right->IsConstantOperand()) 1674 Operand right_op = (right->IsRegister() || right->IsConstantOperand())
1711 ? ToOperand(right) 1675 ? ToOperand(right)
1712 : Operand(EmitLoadRegister(right, ip)); 1676 : Operand(EmitLoadRegister(right, ip));
1713 Register result_reg = ToRegister(instr->result()); 1677 Register result_reg = ToRegister(instr->result());
1714 __ cmp(left_reg, right_op); 1678 __ cmp(left_reg, right_op);
1715 if (!result_reg.is(left_reg)) { 1679 if (!result_reg.is(left_reg)) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 __ bind(&return_left); 1720 __ bind(&return_left);
1757 if (!left_reg.is(result_reg)) { 1721 if (!left_reg.is(result_reg)) {
1758 __ vmov(result_reg, left_reg); 1722 __ vmov(result_reg, left_reg);
1759 } 1723 }
1760 __ bind(&done); 1724 __ bind(&done);
1761 } 1725 }
1762 } 1726 }
1763 1727
1764 1728
1765 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1729 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1766 DoubleRegister left = ToDoubleRegister(instr->left()); 1730 DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
1767 DoubleRegister right = ToDoubleRegister(instr->right()); 1731 DoubleRegister right = ToDoubleRegister(instr->InputAt(1));
1768 DoubleRegister result = ToDoubleRegister(instr->result()); 1732 DoubleRegister result = ToDoubleRegister(instr->result());
1769 switch (instr->op()) { 1733 switch (instr->op()) {
1770 case Token::ADD: 1734 case Token::ADD:
1771 __ vadd(result, left, right); 1735 __ vadd(result, left, right);
1772 break; 1736 break;
1773 case Token::SUB: 1737 case Token::SUB:
1774 __ vsub(result, left, right); 1738 __ vsub(result, left, right);
1775 break; 1739 break;
1776 case Token::MUL: 1740 case Token::MUL:
1777 __ vmul(result, left, right); 1741 __ vmul(result, left, right);
(...skipping 18 matching lines...) Expand all
1796 break; 1760 break;
1797 } 1761 }
1798 default: 1762 default:
1799 UNREACHABLE(); 1763 UNREACHABLE();
1800 break; 1764 break;
1801 } 1765 }
1802 } 1766 }
1803 1767
1804 1768
1805 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1769 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1806 ASSERT(ToRegister(instr->left()).is(r1)); 1770 ASSERT(ToRegister(instr->InputAt(0)).is(r1));
1807 ASSERT(ToRegister(instr->right()).is(r0)); 1771 ASSERT(ToRegister(instr->InputAt(1)).is(r0));
1808 ASSERT(ToRegister(instr->result()).is(r0)); 1772 ASSERT(ToRegister(instr->result()).is(r0));
1809 1773
1810 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 1774 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
1811 // Block literal pool emission to ensure nop indicating no inlined smi code 1775 // Block literal pool emission to ensure nop indicating no inlined smi code
1812 // is in the correct position. 1776 // is in the correct position.
1813 Assembler::BlockConstPoolScope block_const_pool(masm()); 1777 Assembler::BlockConstPoolScope block_const_pool(masm());
1814 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1778 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1815 __ nop(); // Signals no inlined code. 1779 __ nop(); // Signals no inlined code.
1816 } 1780 }
1817 1781
(...skipping 24 matching lines...) Expand all
1842 } 1806 }
1843 } 1807 }
1844 1808
1845 1809
1846 void LCodeGen::DoBranch(LBranch* instr) { 1810 void LCodeGen::DoBranch(LBranch* instr) {
1847 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1811 int true_block = chunk_->LookupDestination(instr->true_block_id());
1848 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1812 int false_block = chunk_->LookupDestination(instr->false_block_id());
1849 1813
1850 Representation r = instr->hydrogen()->value()->representation(); 1814 Representation r = instr->hydrogen()->value()->representation();
1851 if (r.IsInteger32()) { 1815 if (r.IsInteger32()) {
1852 Register reg = ToRegister(instr->value()); 1816 Register reg = ToRegister(instr->InputAt(0));
1853 __ cmp(reg, Operand(0)); 1817 __ cmp(reg, Operand(0));
1854 EmitBranch(true_block, false_block, ne); 1818 EmitBranch(true_block, false_block, ne);
1855 } else if (r.IsDouble()) { 1819 } else if (r.IsDouble()) {
1856 DoubleRegister reg = ToDoubleRegister(instr->value()); 1820 DoubleRegister reg = ToDoubleRegister(instr->InputAt(0));
1857 Register scratch = scratch0(); 1821 Register scratch = scratch0();
1858 1822
1859 // Test the double value. Zero and NaN are false. 1823 // Test the double value. Zero and NaN are false.
1860 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); 1824 __ VFPCompareAndLoadFlags(reg, 0.0, scratch);
1861 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); 1825 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
1862 EmitBranch(true_block, false_block, eq); 1826 EmitBranch(true_block, false_block, eq);
1863 } else { 1827 } else {
1864 ASSERT(r.IsTagged()); 1828 ASSERT(r.IsTagged());
1865 Register reg = ToRegister(instr->value()); 1829 Register reg = ToRegister(instr->InputAt(0));
1866 HType type = instr->hydrogen()->value()->type(); 1830 HType type = instr->hydrogen()->value()->type();
1867 if (type.IsBoolean()) { 1831 if (type.IsBoolean()) {
1868 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 1832 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1869 EmitBranch(true_block, false_block, eq); 1833 EmitBranch(true_block, false_block, eq);
1870 } else if (type.IsSmi()) { 1834 } else if (type.IsSmi()) {
1871 __ cmp(reg, Operand(0)); 1835 __ cmp(reg, Operand(0));
1872 EmitBranch(true_block, false_block, ne); 1836 EmitBranch(true_block, false_block, ne);
1873 } else { 1837 } else {
1874 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1838 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1875 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1839 Label* false_label = chunk_->GetAssemblyLabel(false_block);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1994 case Token::IN: 1958 case Token::IN:
1995 case Token::INSTANCEOF: 1959 case Token::INSTANCEOF:
1996 default: 1960 default:
1997 UNREACHABLE(); 1961 UNREACHABLE();
1998 } 1962 }
1999 return cond; 1963 return cond;
2000 } 1964 }
2001 1965
2002 1966
2003 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1967 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
2004 LOperand* left = instr->left(); 1968 LOperand* left = instr->InputAt(0);
2005 LOperand* right = instr->right(); 1969 LOperand* right = instr->InputAt(1);
2006 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1970 int false_block = chunk_->LookupDestination(instr->false_block_id());
2007 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1971 int true_block = chunk_->LookupDestination(instr->true_block_id());
2008 Condition cond = TokenToCondition(instr->op(), false); 1972 Condition cond = TokenToCondition(instr->op(), false);
2009 1973
2010 if (left->IsConstantOperand() && right->IsConstantOperand()) { 1974 if (left->IsConstantOperand() && right->IsConstantOperand()) {
2011 // We can statically evaluate the comparison. 1975 // We can statically evaluate the comparison.
2012 double left_val = ToDouble(LConstantOperand::cast(left)); 1976 double left_val = ToDouble(LConstantOperand::cast(left));
2013 double right_val = ToDouble(LConstantOperand::cast(right)); 1977 double right_val = ToDouble(LConstantOperand::cast(right));
2014 int next_block = 1978 int next_block =
2015 EvalComparison(instr->op(), left_val, right_val) ? true_block 1979 EvalComparison(instr->op(), left_val, right_val) ? true_block
(...skipping 19 matching lines...) Expand all
2035 } else { 1999 } else {
2036 __ cmp(ToRegister(left), ToRegister(right)); 2000 __ cmp(ToRegister(left), ToRegister(right));
2037 } 2001 }
2038 } 2002 }
2039 EmitBranch(true_block, false_block, cond); 2003 EmitBranch(true_block, false_block, cond);
2040 } 2004 }
2041 } 2005 }
2042 2006
2043 2007
2044 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 2008 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2045 Register left = ToRegister(instr->left()); 2009 Register left = ToRegister(instr->InputAt(0));
2046 Register right = ToRegister(instr->right()); 2010 Register right = ToRegister(instr->InputAt(1));
2047 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2011 int false_block = chunk_->LookupDestination(instr->false_block_id());
2048 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2012 int true_block = chunk_->LookupDestination(instr->true_block_id());
2049 2013
2050 __ cmp(left, Operand(right)); 2014 __ cmp(left, Operand(right));
2051 EmitBranch(true_block, false_block, eq); 2015 EmitBranch(true_block, false_block, eq);
2052 } 2016 }
2053 2017
2054 2018
2055 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 2019 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
2056 Register left = ToRegister(instr->left()); 2020 Register left = ToRegister(instr->InputAt(0));
2057 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2021 int true_block = chunk_->LookupDestination(instr->true_block_id());
2058 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2022 int false_block = chunk_->LookupDestination(instr->false_block_id());
2059 2023
2060 __ cmp(left, Operand(instr->hydrogen()->right())); 2024 __ cmp(left, Operand(instr->hydrogen()->right()));
2061 EmitBranch(true_block, false_block, eq); 2025 EmitBranch(true_block, false_block, eq);
2062 } 2026 }
2063 2027
2064 2028
2065 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) { 2029 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
2066 Register scratch = scratch0(); 2030 Register scratch = scratch0();
2067 Register reg = ToRegister(instr->value()); 2031 Register reg = ToRegister(instr->InputAt(0));
2068 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2032 int false_block = chunk_->LookupDestination(instr->false_block_id());
2069 2033
2070 // If the expression is known to be untagged or a smi, then it's definitely 2034 // If the expression is known to be untagged or a smi, then it's definitely
2071 // not null, and it can't be a an undetectable object. 2035 // not null, and it can't be a an undetectable object.
2072 if (instr->hydrogen()->representation().IsSpecialization() || 2036 if (instr->hydrogen()->representation().IsSpecialization() ||
2073 instr->hydrogen()->type().IsSmi()) { 2037 instr->hydrogen()->type().IsSmi()) {
2074 EmitGoto(false_block); 2038 EmitGoto(false_block);
2075 return; 2039 return;
2076 } 2040 }
2077 2041
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2125 // Load instance type and check that it is in object type range. 2089 // Load instance type and check that it is in object type range.
2126 __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset)); 2090 __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset));
2127 __ cmp(temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2091 __ cmp(temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
2128 __ b(lt, is_not_object); 2092 __ b(lt, is_not_object);
2129 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2093 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
2130 return le; 2094 return le;
2131 } 2095 }
2132 2096
2133 2097
2134 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 2098 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2135 Register reg = ToRegister(instr->value()); 2099 Register reg = ToRegister(instr->InputAt(0));
2136 Register temp1 = ToRegister(instr->temp()); 2100 Register temp1 = ToRegister(instr->TempAt(0));
2137 2101
2138 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2102 int true_block = chunk_->LookupDestination(instr->true_block_id());
2139 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2103 int false_block = chunk_->LookupDestination(instr->false_block_id());
2140 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2104 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2141 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2105 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2142 2106
2143 Condition true_cond = 2107 Condition true_cond =
2144 EmitIsObject(reg, temp1, false_label, true_label); 2108 EmitIsObject(reg, temp1, false_label, true_label);
2145 2109
2146 EmitBranch(true_block, false_block, true_cond); 2110 EmitBranch(true_block, false_block, true_cond);
2147 } 2111 }
2148 2112
2149 2113
2150 Condition LCodeGen::EmitIsString(Register input, 2114 Condition LCodeGen::EmitIsString(Register input,
2151 Register temp1, 2115 Register temp1,
2152 Label* is_not_string) { 2116 Label* is_not_string) {
2153 __ JumpIfSmi(input, is_not_string); 2117 __ JumpIfSmi(input, is_not_string);
2154 __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE); 2118 __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE);
2155 2119
2156 return lt; 2120 return lt;
2157 } 2121 }
2158 2122
2159 2123
2160 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 2124 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2161 Register reg = ToRegister(instr->value()); 2125 Register reg = ToRegister(instr->InputAt(0));
2162 Register temp1 = ToRegister(instr->temp()); 2126 Register temp1 = ToRegister(instr->TempAt(0));
2163 2127
2164 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2128 int true_block = chunk_->LookupDestination(instr->true_block_id());
2165 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2129 int false_block = chunk_->LookupDestination(instr->false_block_id());
2166 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2130 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2167 2131
2168 Condition true_cond = 2132 Condition true_cond =
2169 EmitIsString(reg, temp1, false_label); 2133 EmitIsString(reg, temp1, false_label);
2170 2134
2171 EmitBranch(true_block, false_block, true_cond); 2135 EmitBranch(true_block, false_block, true_cond);
2172 } 2136 }
2173 2137
2174 2138
2175 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 2139 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2176 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2140 int true_block = chunk_->LookupDestination(instr->true_block_id());
2177 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2141 int false_block = chunk_->LookupDestination(instr->false_block_id());
2178 2142
2179 Register input_reg = EmitLoadRegister(instr->value(), ip); 2143 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
2180 __ tst(input_reg, Operand(kSmiTagMask)); 2144 __ tst(input_reg, Operand(kSmiTagMask));
2181 EmitBranch(true_block, false_block, eq); 2145 EmitBranch(true_block, false_block, eq);
2182 } 2146 }
2183 2147
2184 2148
2185 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 2149 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2186 Register input = ToRegister(instr->value()); 2150 Register input = ToRegister(instr->InputAt(0));
2187 Register temp = ToRegister(instr->temp()); 2151 Register temp = ToRegister(instr->TempAt(0));
2188 2152
2189 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2153 int true_block = chunk_->LookupDestination(instr->true_block_id());
2190 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2154 int false_block = chunk_->LookupDestination(instr->false_block_id());
2191 2155
2192 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 2156 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
2193 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); 2157 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset));
2194 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); 2158 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
2195 __ tst(temp, Operand(1 << Map::kIsUndetectable)); 2159 __ tst(temp, Operand(1 << Map::kIsUndetectable));
2196 EmitBranch(true_block, false_block, ne); 2160 EmitBranch(true_block, false_block, ne);
2197 } 2161 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2247 if (from == to) return eq; 2211 if (from == to) return eq;
2248 if (to == LAST_TYPE) return hs; 2212 if (to == LAST_TYPE) return hs;
2249 if (from == FIRST_TYPE) return ls; 2213 if (from == FIRST_TYPE) return ls;
2250 UNREACHABLE(); 2214 UNREACHABLE();
2251 return eq; 2215 return eq;
2252 } 2216 }
2253 2217
2254 2218
2255 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2219 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2256 Register scratch = scratch0(); 2220 Register scratch = scratch0();
2257 Register input = ToRegister(instr->value()); 2221 Register input = ToRegister(instr->InputAt(0));
2258 2222
2259 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2223 int true_block = chunk_->LookupDestination(instr->true_block_id());
2260 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2224 int false_block = chunk_->LookupDestination(instr->false_block_id());
2261 2225
2262 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2226 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2263 2227
2264 __ JumpIfSmi(input, false_label); 2228 __ JumpIfSmi(input, false_label);
2265 2229
2266 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); 2230 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen()));
2267 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 2231 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
2268 } 2232 }
2269 2233
2270 2234
2271 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2235 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2272 Register input = ToRegister(instr->value()); 2236 Register input = ToRegister(instr->InputAt(0));
2273 Register result = ToRegister(instr->result()); 2237 Register result = ToRegister(instr->result());
2274 2238
2275 __ AbortIfNotString(input); 2239 __ AbortIfNotString(input);
2276 2240
2277 __ ldr(result, FieldMemOperand(input, String::kHashFieldOffset)); 2241 __ ldr(result, FieldMemOperand(input, String::kHashFieldOffset));
2278 __ IndexFromHash(result, result); 2242 __ IndexFromHash(result, result);
2279 } 2243 }
2280 2244
2281 2245
2282 void LCodeGen::DoHasCachedArrayIndexAndBranch( 2246 void LCodeGen::DoHasCachedArrayIndexAndBranch(
2283 LHasCachedArrayIndexAndBranch* instr) { 2247 LHasCachedArrayIndexAndBranch* instr) {
2284 Register input = ToRegister(instr->value()); 2248 Register input = ToRegister(instr->InputAt(0));
2285 Register scratch = scratch0(); 2249 Register scratch = scratch0();
2286 2250
2287 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2251 int true_block = chunk_->LookupDestination(instr->true_block_id());
2288 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2252 int false_block = chunk_->LookupDestination(instr->false_block_id());
2289 2253
2290 __ ldr(scratch, 2254 __ ldr(scratch,
2291 FieldMemOperand(input, String::kHashFieldOffset)); 2255 FieldMemOperand(input, String::kHashFieldOffset));
2292 __ tst(scratch, Operand(String::kContainsCachedArrayIndexMask)); 2256 __ tst(scratch, Operand(String::kContainsCachedArrayIndexMask));
2293 EmitBranch(true_block, false_block, eq); 2257 EmitBranch(true_block, false_block, eq);
2294 } 2258 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2355 // booted. This routine isn't expected to work for random API-created 2319 // booted. This routine isn't expected to work for random API-created
2356 // classes and it doesn't have to because you can't access it with natives 2320 // classes and it doesn't have to because you can't access it with natives
2357 // syntax. Since both sides are symbols it is sufficient to use an identity 2321 // syntax. Since both sides are symbols it is sufficient to use an identity
2358 // comparison. 2322 // comparison.
2359 __ cmp(temp, Operand(class_name)); 2323 __ cmp(temp, Operand(class_name));
2360 // End with the answer in flags. 2324 // End with the answer in flags.
2361 } 2325 }
2362 2326
2363 2327
2364 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2328 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2365 Register input = ToRegister(instr->value()); 2329 Register input = ToRegister(instr->InputAt(0));
2366 Register temp = scratch0(); 2330 Register temp = scratch0();
2367 Register temp2 = ToRegister(instr->temp()); 2331 Register temp2 = ToRegister(instr->TempAt(0));
2368 Handle<String> class_name = instr->hydrogen()->class_name(); 2332 Handle<String> class_name = instr->hydrogen()->class_name();
2369 2333
2370 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2334 int true_block = chunk_->LookupDestination(instr->true_block_id());
2371 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2335 int false_block = chunk_->LookupDestination(instr->false_block_id());
2372 2336
2373 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2337 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2374 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2338 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2375 2339
2376 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 2340 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
2377 2341
2378 EmitBranch(true_block, false_block, eq); 2342 EmitBranch(true_block, false_block, eq);
2379 } 2343 }
2380 2344
2381 2345
2382 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2346 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2383 Register reg = ToRegister(instr->value()); 2347 Register reg = ToRegister(instr->InputAt(0));
2384 Register temp = ToRegister(instr->temp()); 2348 Register temp = ToRegister(instr->TempAt(0));
2385 int true_block = instr->true_block_id(); 2349 int true_block = instr->true_block_id();
2386 int false_block = instr->false_block_id(); 2350 int false_block = instr->false_block_id();
2387 2351
2388 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); 2352 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
2389 __ cmp(temp, Operand(instr->map())); 2353 __ cmp(temp, Operand(instr->map()));
2390 EmitBranch(true_block, false_block, eq); 2354 EmitBranch(true_block, false_block, eq);
2391 } 2355 }
2392 2356
2393 2357
2394 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2358 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2395 ASSERT(ToRegister(instr->left()).is(r0)); // Object is in r0. 2359 ASSERT(ToRegister(instr->InputAt(0)).is(r0)); // Object is in r0.
2396 ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1. 2360 ASSERT(ToRegister(instr->InputAt(1)).is(r1)); // Function is in r1.
2397 2361
2398 InstanceofStub stub(InstanceofStub::kArgsInRegisters); 2362 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
2399 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2363 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2400 2364
2401 __ cmp(r0, Operand(0)); 2365 __ cmp(r0, Operand(0));
2402 __ mov(r0, Operand(factory()->false_value()), LeaveCC, ne); 2366 __ mov(r0, Operand(factory()->false_value()), LeaveCC, ne);
2403 __ mov(r0, Operand(factory()->true_value()), LeaveCC, eq); 2367 __ mov(r0, Operand(factory()->true_value()), LeaveCC, eq);
2404 } 2368 }
2405 2369
2406 2370
(...skipping 10 matching lines...) Expand all
2417 Label* map_check() { return &map_check_; } 2381 Label* map_check() { return &map_check_; }
2418 private: 2382 private:
2419 LInstanceOfKnownGlobal* instr_; 2383 LInstanceOfKnownGlobal* instr_;
2420 Label map_check_; 2384 Label map_check_;
2421 }; 2385 };
2422 2386
2423 DeferredInstanceOfKnownGlobal* deferred; 2387 DeferredInstanceOfKnownGlobal* deferred;
2424 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 2388 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2425 2389
2426 Label done, false_result; 2390 Label done, false_result;
2427 Register object = ToRegister(instr->value()); 2391 Register object = ToRegister(instr->InputAt(0));
2428 Register temp = ToRegister(instr->temp()); 2392 Register temp = ToRegister(instr->TempAt(0));
2429 Register result = ToRegister(instr->result()); 2393 Register result = ToRegister(instr->result());
2430 2394
2431 ASSERT(object.is(r0)); 2395 ASSERT(object.is(r0));
2432 ASSERT(result.is(r0)); 2396 ASSERT(result.is(r0));
2433 2397
2434 // A Smi is not instance of anything. 2398 // A Smi is not instance of anything.
2435 __ JumpIfSmi(object, &false_result); 2399 __ JumpIfSmi(object, &false_result);
2436 2400
2437 // This is the inlined call site instanceof cache. The two occurences of the 2401 // This is the inlined call site instanceof cache. The two occurences of the
2438 // hole value will be patched to the last map/result pair generated by the 2402 // hole value will be patched to the last map/result pair generated by the
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2498 flags | InstanceofStub::kCallSiteInlineCheck); 2462 flags | InstanceofStub::kCallSiteInlineCheck);
2499 flags = static_cast<InstanceofStub::Flags>( 2463 flags = static_cast<InstanceofStub::Flags>(
2500 flags | InstanceofStub::kReturnTrueFalseObject); 2464 flags | InstanceofStub::kReturnTrueFalseObject);
2501 InstanceofStub stub(flags); 2465 InstanceofStub stub(flags);
2502 2466
2503 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 2467 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2504 2468
2505 // Get the temp register reserved by the instruction. This needs to be r4 as 2469 // Get the temp register reserved by the instruction. This needs to be r4 as
2506 // its slot of the pushing of safepoint registers is used to communicate the 2470 // its slot of the pushing of safepoint registers is used to communicate the
2507 // offset to the location of the map check. 2471 // offset to the location of the map check.
2508 Register temp = ToRegister(instr->temp()); 2472 Register temp = ToRegister(instr->TempAt(0));
2509 ASSERT(temp.is(r4)); 2473 ASSERT(temp.is(r4));
2510 __ LoadHeapObject(InstanceofStub::right(), instr->function()); 2474 __ LoadHeapObject(InstanceofStub::right(), instr->function());
2511 static const int kAdditionalDelta = 5; 2475 static const int kAdditionalDelta = 5;
2512 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; 2476 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
2513 Label before_push_delta; 2477 Label before_push_delta;
2514 __ bind(&before_push_delta); 2478 __ bind(&before_push_delta);
2515 __ BlockConstPoolFor(kAdditionalDelta); 2479 __ BlockConstPoolFor(kAdditionalDelta);
2516 __ mov(temp, Operand(delta * kPointerSize)); 2480 __ mov(temp, Operand(delta * kPointerSize));
2517 // The mov above can generate one or two instructions. The delta was computed 2481 // The mov above can generate one or two instructions. The delta was computed
2518 // for two instructions, so we need to pad here in case of one instruction. 2482 // for two instructions, so we need to pad here in case of one instruction.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2595 2559
2596 // Load the cell. 2560 // Load the cell.
2597 __ mov(cell, Operand(instr->hydrogen()->cell())); 2561 __ mov(cell, Operand(instr->hydrogen()->cell()));
2598 2562
2599 // If the cell we are storing to contains the hole it could have 2563 // If the cell we are storing to contains the hole it could have
2600 // been deleted from the property dictionary. In that case, we need 2564 // been deleted from the property dictionary. In that case, we need
2601 // to update the property details in the property dictionary to mark 2565 // to update the property details in the property dictionary to mark
2602 // it as no longer deleted. 2566 // it as no longer deleted.
2603 if (instr->hydrogen()->RequiresHoleCheck()) { 2567 if (instr->hydrogen()->RequiresHoleCheck()) {
2604 // We use a temp to check the payload (CompareRoot might clobber ip). 2568 // We use a temp to check the payload (CompareRoot might clobber ip).
2605 Register payload = ToRegister(instr->temp()); 2569 Register payload = ToRegister(instr->TempAt(0));
2606 __ ldr(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 2570 __ ldr(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
2607 __ CompareRoot(payload, Heap::kTheHoleValueRootIndex); 2571 __ CompareRoot(payload, Heap::kTheHoleValueRootIndex);
2608 DeoptimizeIf(eq, instr->environment()); 2572 DeoptimizeIf(eq, instr->environment());
2609 } 2573 }
2610 2574
2611 // Store the value. 2575 // Store the value.
2612 __ str(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 2576 __ str(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
2613 // Cells are always rescanned, so no write barrier here. 2577 // Cells are always rescanned, so no write barrier here.
2614 } 2578 }
2615 2579
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2674 kSaveFPRegs, 2638 kSaveFPRegs,
2675 EMIT_REMEMBERED_SET, 2639 EMIT_REMEMBERED_SET,
2676 check_needed); 2640 check_needed);
2677 } 2641 }
2678 2642
2679 __ bind(&skip_assignment); 2643 __ bind(&skip_assignment);
2680 } 2644 }
2681 2645
2682 2646
2683 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 2647 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2684 Register object = ToRegister(instr->object()); 2648 Register object = ToRegister(instr->InputAt(0));
2685 Register result = ToRegister(instr->result()); 2649 Register result = ToRegister(instr->result());
2686 if (instr->hydrogen()->is_in_object()) { 2650 if (instr->hydrogen()->is_in_object()) {
2687 __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset())); 2651 __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset()));
2688 } else { 2652 } else {
2689 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 2653 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
2690 __ ldr(result, FieldMemOperand(result, instr->hydrogen()->offset())); 2654 __ ldr(result, FieldMemOperand(result, instr->hydrogen()->offset()));
2691 } 2655 }
2692 } 2656 }
2693 2657
2694 2658
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2828 __ bind(&non_instance); 2792 __ bind(&non_instance);
2829 __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); 2793 __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset));
2830 2794
2831 // All done. 2795 // All done.
2832 __ bind(&done); 2796 __ bind(&done);
2833 } 2797 }
2834 2798
2835 2799
2836 void LCodeGen::DoLoadElements(LLoadElements* instr) { 2800 void LCodeGen::DoLoadElements(LLoadElements* instr) {
2837 Register result = ToRegister(instr->result()); 2801 Register result = ToRegister(instr->result());
2838 Register input = ToRegister(instr->object()); 2802 Register input = ToRegister(instr->InputAt(0));
2839 Register scratch = scratch0(); 2803 Register scratch = scratch0();
2840 2804
2841 __ ldr(result, FieldMemOperand(input, JSObject::kElementsOffset)); 2805 __ ldr(result, FieldMemOperand(input, JSObject::kElementsOffset));
2842 if (FLAG_debug_code) { 2806 if (FLAG_debug_code) {
2843 Label done, fail; 2807 Label done, fail;
2844 __ ldr(scratch, FieldMemOperand(result, HeapObject::kMapOffset)); 2808 __ ldr(scratch, FieldMemOperand(result, HeapObject::kMapOffset));
2845 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); 2809 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
2846 __ cmp(scratch, ip); 2810 __ cmp(scratch, ip);
2847 __ b(eq, &done); 2811 __ b(eq, &done);
2848 __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex); 2812 __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex);
(...skipping 14 matching lines...) Expand all
2863 __ bind(&fail); 2827 __ bind(&fail);
2864 __ Abort("Check for fast or external elements failed."); 2828 __ Abort("Check for fast or external elements failed.");
2865 __ bind(&done); 2829 __ bind(&done);
2866 } 2830 }
2867 } 2831 }
2868 2832
2869 2833
2870 void LCodeGen::DoLoadExternalArrayPointer( 2834 void LCodeGen::DoLoadExternalArrayPointer(
2871 LLoadExternalArrayPointer* instr) { 2835 LLoadExternalArrayPointer* instr) {
2872 Register to_reg = ToRegister(instr->result()); 2836 Register to_reg = ToRegister(instr->result());
2873 Register from_reg = ToRegister(instr->object()); 2837 Register from_reg = ToRegister(instr->InputAt(0));
2874 __ ldr(to_reg, FieldMemOperand(from_reg, 2838 __ ldr(to_reg, FieldMemOperand(from_reg,
2875 ExternalArray::kExternalPointerOffset)); 2839 ExternalArray::kExternalPointerOffset));
2876 } 2840 }
2877 2841
2878 2842
2879 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2843 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2880 Register arguments = ToRegister(instr->arguments()); 2844 Register arguments = ToRegister(instr->arguments());
2881 Register length = ToRegister(instr->length()); 2845 Register length = ToRegister(instr->length());
2882 Register index = ToRegister(instr->index()); 2846 Register index = ToRegister(instr->index());
2883 Register result = ToRegister(instr->result()); 2847 Register result = ToRegister(instr->result());
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
3120 3084
3121 // Result is the frame pointer for the frame if not adapted and for the real 3085 // Result is the frame pointer for the frame if not adapted and for the real
3122 // frame below the adaptor frame if adapted. 3086 // frame below the adaptor frame if adapted.
3123 __ mov(result, fp, LeaveCC, ne); 3087 __ mov(result, fp, LeaveCC, ne);
3124 __ mov(result, scratch, LeaveCC, eq); 3088 __ mov(result, scratch, LeaveCC, eq);
3125 } 3089 }
3126 } 3090 }
3127 3091
3128 3092
3129 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 3093 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3130 Register elem = ToRegister(instr->elements()); 3094 Register elem = ToRegister(instr->InputAt(0));
3131 Register result = ToRegister(instr->result()); 3095 Register result = ToRegister(instr->result());
3132 3096
3133 Label done; 3097 Label done;
3134 3098
3135 // If no arguments adaptor frame the number of arguments is fixed. 3099 // If no arguments adaptor frame the number of arguments is fixed.
3136 __ cmp(fp, elem); 3100 __ cmp(fp, elem);
3137 __ mov(result, Operand(scope()->num_parameters())); 3101 __ mov(result, Operand(scope()->num_parameters()));
3138 __ b(eq, &done); 3102 __ b(eq, &done);
3139 3103
3140 // Arguments adaptor frame present. Get argument length from there. 3104 // Arguments adaptor frame present. Get argument length from there.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3239 // The number of arguments is stored in receiver which is r0, as expected 3203 // The number of arguments is stored in receiver which is r0, as expected
3240 // by InvokeFunction. 3204 // by InvokeFunction.
3241 ParameterCount actual(receiver); 3205 ParameterCount actual(receiver);
3242 __ InvokeFunction(function, actual, CALL_FUNCTION, 3206 __ InvokeFunction(function, actual, CALL_FUNCTION,
3243 safepoint_generator, CALL_AS_METHOD); 3207 safepoint_generator, CALL_AS_METHOD);
3244 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3208 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3245 } 3209 }
3246 3210
3247 3211
3248 void LCodeGen::DoPushArgument(LPushArgument* instr) { 3212 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3249 LOperand* argument = instr->value(); 3213 LOperand* argument = instr->InputAt(0);
3250 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { 3214 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
3251 Abort("DoPushArgument not implemented for double type."); 3215 Abort("DoPushArgument not implemented for double type.");
3252 } else { 3216 } else {
3253 Register argument_reg = EmitLoadRegister(argument, ip); 3217 Register argument_reg = EmitLoadRegister(argument, ip);
3254 __ push(argument_reg); 3218 __ push(argument_reg);
3255 } 3219 }
3256 } 3220 }
3257 3221
3258 3222
3259 void LCodeGen::DoDrop(LDrop* instr) { 3223 void LCodeGen::DoDrop(LDrop* instr) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3291 } 3255 }
3292 3256
3293 3257
3294 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { 3258 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3295 Register result = ToRegister(instr->result()); 3259 Register result = ToRegister(instr->result());
3296 __ ldr(result, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); 3260 __ ldr(result, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
3297 } 3261 }
3298 3262
3299 3263
3300 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { 3264 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3301 Register global = ToRegister(instr->global_object()); 3265 Register global = ToRegister(instr->global());
3302 Register result = ToRegister(instr->result()); 3266 Register result = ToRegister(instr->result());
3303 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); 3267 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset));
3304 } 3268 }
3305 3269
3306 3270
3307 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 3271 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
3308 int arity, 3272 int arity,
3309 LInstruction* instr, 3273 LInstruction* instr,
3310 CallKind call_kind, 3274 CallKind call_kind,
3311 R1State r1_state) { 3275 R1State r1_state) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3351 ASSERT(ToRegister(instr->result()).is(r0)); 3315 ASSERT(ToRegister(instr->result()).is(r0));
3352 CallKnownFunction(instr->function(), 3316 CallKnownFunction(instr->function(),
3353 instr->arity(), 3317 instr->arity(),
3354 instr, 3318 instr,
3355 CALL_AS_METHOD, 3319 CALL_AS_METHOD,
3356 R1_UNINITIALIZED); 3320 R1_UNINITIALIZED);
3357 } 3321 }
3358 3322
3359 3323
3360 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 3324 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
3361 Register input = ToRegister(instr->value()); 3325 Register input = ToRegister(instr->InputAt(0));
3362 Register result = ToRegister(instr->result()); 3326 Register result = ToRegister(instr->result());
3363 Register scratch = scratch0(); 3327 Register scratch = scratch0();
3364 3328
3365 // Deoptimize if not a heap number. 3329 // Deoptimize if not a heap number.
3366 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 3330 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
3367 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3331 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
3368 __ cmp(scratch, Operand(ip)); 3332 __ cmp(scratch, Operand(ip));
3369 DeoptimizeIf(ne, instr->environment()); 3333 DeoptimizeIf(ne, instr->environment());
3370 3334
3371 Label done; 3335 Label done;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3417 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 3381 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
3418 3382
3419 __ StoreToSafepointRegisterSlot(tmp1, result); 3383 __ StoreToSafepointRegisterSlot(tmp1, result);
3420 } 3384 }
3421 3385
3422 __ bind(&done); 3386 __ bind(&done);
3423 } 3387 }
3424 3388
3425 3389
3426 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 3390 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
3427 Register input = ToRegister(instr->value()); 3391 Register input = ToRegister(instr->InputAt(0));
3428 Register result = ToRegister(instr->result()); 3392 Register result = ToRegister(instr->result());
3429 __ cmp(input, Operand(0)); 3393 __ cmp(input, Operand(0));
3430 __ Move(result, input, pl); 3394 __ Move(result, input, pl);
3431 // We can make rsb conditional because the previous cmp instruction 3395 // We can make rsb conditional because the previous cmp instruction
3432 // will clear the V (overflow) flag and rsb won't set this flag 3396 // will clear the V (overflow) flag and rsb won't set this flag
3433 // if input is positive. 3397 // if input is positive.
3434 __ rsb(result, input, Operand(0), SetCC, mi); 3398 __ rsb(result, input, Operand(0), SetCC, mi);
3435 // Deoptimize on overflow. 3399 // Deoptimize on overflow.
3436 DeoptimizeIf(vs, instr->environment()); 3400 DeoptimizeIf(vs, instr->environment());
3437 } 3401 }
3438 3402
3439 3403
3440 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 3404 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
3441 // Class for deferred case. 3405 // Class for deferred case.
3442 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3406 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3443 public: 3407 public:
3444 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3408 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
3445 LUnaryMathOperation* instr) 3409 LUnaryMathOperation* instr)
3446 : LDeferredCode(codegen), instr_(instr) { } 3410 : LDeferredCode(codegen), instr_(instr) { }
3447 virtual void Generate() { 3411 virtual void Generate() {
3448 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3412 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3449 } 3413 }
3450 virtual LInstruction* instr() { return instr_; } 3414 virtual LInstruction* instr() { return instr_; }
3451 private: 3415 private:
3452 LUnaryMathOperation* instr_; 3416 LUnaryMathOperation* instr_;
3453 }; 3417 };
3454 3418
3455 Representation r = instr->hydrogen()->value()->representation(); 3419 Representation r = instr->hydrogen()->value()->representation();
3456 if (r.IsDouble()) { 3420 if (r.IsDouble()) {
3457 DwVfpRegister input = ToDoubleRegister(instr->value()); 3421 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0));
3458 DwVfpRegister result = ToDoubleRegister(instr->result()); 3422 DwVfpRegister result = ToDoubleRegister(instr->result());
3459 __ vabs(result, input); 3423 __ vabs(result, input);
3460 } else if (r.IsInteger32()) { 3424 } else if (r.IsInteger32()) {
3461 EmitIntegerMathAbs(instr); 3425 EmitIntegerMathAbs(instr);
3462 } else { 3426 } else {
3463 // Representation is tagged. 3427 // Representation is tagged.
3464 DeferredMathAbsTaggedHeapNumber* deferred = 3428 DeferredMathAbsTaggedHeapNumber* deferred =
3465 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 3429 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3466 Register input = ToRegister(instr->value()); 3430 Register input = ToRegister(instr->InputAt(0));
3467 // Smi check. 3431 // Smi check.
3468 __ JumpIfNotSmi(input, deferred->entry()); 3432 __ JumpIfNotSmi(input, deferred->entry());
3469 // If smi, handle it directly. 3433 // If smi, handle it directly.
3470 EmitIntegerMathAbs(instr); 3434 EmitIntegerMathAbs(instr);
3471 __ bind(deferred->exit()); 3435 __ bind(deferred->exit());
3472 } 3436 }
3473 } 3437 }
3474 3438
3475 3439
3476 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 3440 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
3477 DoubleRegister input = ToDoubleRegister(instr->value()); 3441 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3478 Register result = ToRegister(instr->result()); 3442 Register result = ToRegister(instr->result());
3479 SwVfpRegister single_scratch = double_scratch0().low(); 3443 SwVfpRegister single_scratch = double_scratch0().low();
3480 Register scratch1 = scratch0(); 3444 Register scratch1 = scratch0();
3481 Register scratch2 = ToRegister(instr->temp()); 3445 Register scratch2 = ToRegister(instr->TempAt(0));
3482 3446
3483 __ EmitVFPTruncate(kRoundToMinusInf, 3447 __ EmitVFPTruncate(kRoundToMinusInf,
3484 single_scratch, 3448 single_scratch,
3485 input, 3449 input,
3486 scratch1, 3450 scratch1,
3487 scratch2); 3451 scratch2);
3488 DeoptimizeIf(ne, instr->environment()); 3452 DeoptimizeIf(ne, instr->environment());
3489 3453
3490 // Move the result back to general purpose register r0. 3454 // Move the result back to general purpose register r0.
3491 __ vmov(result, single_scratch); 3455 __ vmov(result, single_scratch);
3492 3456
3493 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3457 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3494 // Test for -0. 3458 // Test for -0.
3495 Label done; 3459 Label done;
3496 __ cmp(result, Operand(0)); 3460 __ cmp(result, Operand(0));
3497 __ b(ne, &done); 3461 __ b(ne, &done);
3498 __ vmov(scratch1, input.high()); 3462 __ vmov(scratch1, input.high());
3499 __ tst(scratch1, Operand(HeapNumber::kSignMask)); 3463 __ tst(scratch1, Operand(HeapNumber::kSignMask));
3500 DeoptimizeIf(ne, instr->environment()); 3464 DeoptimizeIf(ne, instr->environment());
3501 __ bind(&done); 3465 __ bind(&done);
3502 } 3466 }
3503 } 3467 }
3504 3468
3505 3469
3506 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 3470 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
3507 DoubleRegister input = ToDoubleRegister(instr->value()); 3471 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3508 Register result = ToRegister(instr->result()); 3472 Register result = ToRegister(instr->result());
3509 Register scratch = scratch0(); 3473 Register scratch = scratch0();
3510 Label done, check_sign_on_zero; 3474 Label done, check_sign_on_zero;
3511 3475
3512 // Extract exponent bits. 3476 // Extract exponent bits.
3513 __ vmov(result, input.high()); 3477 __ vmov(result, input.high());
3514 __ ubfx(scratch, 3478 __ ubfx(scratch,
3515 result, 3479 result,
3516 HeapNumber::kExponentShift, 3480 HeapNumber::kExponentShift,
3517 HeapNumber::kExponentBits); 3481 HeapNumber::kExponentBits);
3518 3482
3519 // If the number is in ]-0.5, +0.5[, the result is +/- 0. 3483 // If the number is in ]-0.5, +0.5[, the result is +/- 0.
3520 __ cmp(scratch, Operand(HeapNumber::kExponentBias - 2)); 3484 __ cmp(scratch, Operand(HeapNumber::kExponentBias - 2));
3521 __ mov(result, Operand(0), LeaveCC, le); 3485 __ mov(result, Operand(0), LeaveCC, le);
3522 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3486 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3523 __ b(le, &check_sign_on_zero); 3487 __ b(le, &check_sign_on_zero);
3524 } else { 3488 } else {
3525 __ b(le, &done); 3489 __ b(le, &done);
3526 } 3490 }
3527 3491
3528 // The following conversion will not work with numbers 3492 // The following conversion will not work with numbers
3529 // outside of ]-2^32, 2^32[. 3493 // outside of ]-2^32, 2^32[.
3530 __ cmp(scratch, Operand(HeapNumber::kExponentBias + 32)); 3494 __ cmp(scratch, Operand(HeapNumber::kExponentBias + 32));
3531 DeoptimizeIf(ge, instr->environment()); 3495 DeoptimizeIf(ge, instr->environment());
3532 3496
3533 __ Vmov(double_scratch0(), 0.5, scratch);
3534 __ vadd(double_scratch0(), input, double_scratch0());
3535
3536 // Save the original sign for later comparison. 3497 // Save the original sign for later comparison.
3537 __ and_(scratch, result, Operand(HeapNumber::kSignMask)); 3498 __ and_(scratch, result, Operand(HeapNumber::kSignMask));
3538 3499
3500 __ Vmov(double_scratch0(), 0.5);
3501 __ vadd(double_scratch0(), input, double_scratch0());
3502
3539 // Check sign of the result: if the sign changed, the input 3503 // Check sign of the result: if the sign changed, the input
3540 // value was in ]0.5, 0[ and the result should be -0. 3504 // value was in ]0.5, 0[ and the result should be -0.
3541 __ vmov(result, double_scratch0().high()); 3505 __ vmov(result, double_scratch0().high());
3542 __ eor(result, result, Operand(scratch), SetCC); 3506 __ eor(result, result, Operand(scratch), SetCC);
3543 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3507 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3544 DeoptimizeIf(mi, instr->environment()); 3508 DeoptimizeIf(mi, instr->environment());
3545 } else { 3509 } else {
3546 __ mov(result, Operand(0), LeaveCC, mi); 3510 __ mov(result, Operand(0), LeaveCC, mi);
3547 __ b(mi, &done); 3511 __ b(mi, &done);
3548 } 3512 }
(...skipping 13 matching lines...) Expand all
3562 __ bind(&check_sign_on_zero); 3526 __ bind(&check_sign_on_zero);
3563 __ vmov(scratch, input.high()); 3527 __ vmov(scratch, input.high());
3564 __ tst(scratch, Operand(HeapNumber::kSignMask)); 3528 __ tst(scratch, Operand(HeapNumber::kSignMask));
3565 DeoptimizeIf(ne, instr->environment()); 3529 DeoptimizeIf(ne, instr->environment());
3566 } 3530 }
3567 __ bind(&done); 3531 __ bind(&done);
3568 } 3532 }
3569 3533
3570 3534
3571 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3535 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3572 DoubleRegister input = ToDoubleRegister(instr->value()); 3536 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3573 DoubleRegister result = ToDoubleRegister(instr->result()); 3537 DoubleRegister result = ToDoubleRegister(instr->result());
3574 __ vsqrt(result, input); 3538 __ vsqrt(result, input);
3575 } 3539 }
3576 3540
3577 3541
3578 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3542 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
3579 DoubleRegister input = ToDoubleRegister(instr->value()); 3543 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3580 DoubleRegister result = ToDoubleRegister(instr->result()); 3544 DoubleRegister result = ToDoubleRegister(instr->result());
3581 DoubleRegister temp = ToDoubleRegister(instr->temp()); 3545 DoubleRegister temp = ToDoubleRegister(instr->TempAt(0));
3582 3546
3583 // Note that according to ECMA-262 15.8.2.13: 3547 // Note that according to ECMA-262 15.8.2.13:
3584 // Math.pow(-Infinity, 0.5) == Infinity 3548 // Math.pow(-Infinity, 0.5) == Infinity
3585 // Math.sqrt(-Infinity) == NaN 3549 // Math.sqrt(-Infinity) == NaN
3586 Label done; 3550 Label done;
3587 __ vmov(temp, -V8_INFINITY, scratch0()); 3551 __ vmov(temp, -V8_INFINITY);
3588 __ VFPCompareAndSetFlags(input, temp); 3552 __ VFPCompareAndSetFlags(input, temp);
3589 __ vneg(result, temp, eq); 3553 __ vneg(result, temp, eq);
3590 __ b(&done, eq); 3554 __ b(&done, eq);
3591 3555
3592 // Add +0 to convert -0 to +0. 3556 // Add +0 to convert -0 to +0.
3593 __ vadd(result, input, kDoubleRegZero); 3557 __ vadd(result, input, kDoubleRegZero);
3594 __ vsqrt(result, result); 3558 __ vsqrt(result, result);
3595 __ bind(&done); 3559 __ bind(&done);
3596 } 3560 }
3597 3561
3598 3562
3599 void LCodeGen::DoPower(LPower* instr) { 3563 void LCodeGen::DoPower(LPower* instr) {
3600 Representation exponent_type = instr->hydrogen()->right()->representation(); 3564 Representation exponent_type = instr->hydrogen()->right()->representation();
3601 // Having marked this as a call, we can use any registers. 3565 // Having marked this as a call, we can use any registers.
3602 // Just make sure that the input/output registers are the expected ones. 3566 // Just make sure that the input/output registers are the expected ones.
3603 ASSERT(!instr->right()->IsDoubleRegister() || 3567 ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
3604 ToDoubleRegister(instr->right()).is(d2)); 3568 ToDoubleRegister(instr->InputAt(1)).is(d2));
3605 ASSERT(!instr->right()->IsRegister() || 3569 ASSERT(!instr->InputAt(1)->IsRegister() ||
3606 ToRegister(instr->right()).is(r2)); 3570 ToRegister(instr->InputAt(1)).is(r2));
3607 ASSERT(ToDoubleRegister(instr->left()).is(d1)); 3571 ASSERT(ToDoubleRegister(instr->InputAt(0)).is(d1));
3608 ASSERT(ToDoubleRegister(instr->result()).is(d3)); 3572 ASSERT(ToDoubleRegister(instr->result()).is(d3));
3609 3573
3610 if (exponent_type.IsTagged()) { 3574 if (exponent_type.IsTagged()) {
3611 Label no_deopt; 3575 Label no_deopt;
3612 __ JumpIfSmi(r2, &no_deopt); 3576 __ JumpIfSmi(r2, &no_deopt);
3613 __ ldr(r7, FieldMemOperand(r2, HeapObject::kMapOffset)); 3577 __ ldr(r7, FieldMemOperand(r2, HeapObject::kMapOffset));
3614 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3578 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
3615 __ cmp(r7, Operand(ip)); 3579 __ cmp(r7, Operand(ip));
3616 DeoptimizeIf(ne, instr->environment()); 3580 DeoptimizeIf(ne, instr->environment());
3617 __ bind(&no_deopt); 3581 __ bind(&no_deopt);
(...skipping 19 matching lines...) Expand all
3637 virtual LInstruction* instr() { return instr_; } 3601 virtual LInstruction* instr() { return instr_; }
3638 private: 3602 private:
3639 LRandom* instr_; 3603 LRandom* instr_;
3640 }; 3604 };
3641 3605
3642 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 3606 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3643 3607
3644 // Having marked this instruction as a call we can use any 3608 // Having marked this instruction as a call we can use any
3645 // registers. 3609 // registers.
3646 ASSERT(ToDoubleRegister(instr->result()).is(d7)); 3610 ASSERT(ToDoubleRegister(instr->result()).is(d7));
3647 ASSERT(ToRegister(instr->global_object()).is(r0)); 3611 ASSERT(ToRegister(instr->InputAt(0)).is(r0));
3648 3612
3649 static const int kSeedSize = sizeof(uint32_t); 3613 static const int kSeedSize = sizeof(uint32_t);
3650 STATIC_ASSERT(kPointerSize == kSeedSize); 3614 STATIC_ASSERT(kPointerSize == kSeedSize);
3651 3615
3652 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset)); 3616 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset));
3653 static const int kRandomSeedOffset = 3617 static const int kRandomSeedOffset =
3654 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize; 3618 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
3655 __ ldr(r2, FieldMemOperand(r0, kRandomSeedOffset)); 3619 __ ldr(r2, FieldMemOperand(r0, kRandomSeedOffset));
3656 // r2: FixedArray of the native context's random seeds 3620 // r2: FixedArray of the native context's random seeds
3657 3621
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
3848 ASSERT(ToRegister(instr->result()).is(r0)); 3812 ASSERT(ToRegister(instr->result()).is(r0));
3849 CallKnownFunction(instr->target(), 3813 CallKnownFunction(instr->target(),
3850 instr->arity(), 3814 instr->arity(),
3851 instr, 3815 instr,
3852 CALL_AS_FUNCTION, 3816 CALL_AS_FUNCTION,
3853 R1_UNINITIALIZED); 3817 R1_UNINITIALIZED);
3854 } 3818 }
3855 3819
3856 3820
3857 void LCodeGen::DoCallNew(LCallNew* instr) { 3821 void LCodeGen::DoCallNew(LCallNew* instr) {
3858 ASSERT(ToRegister(instr->constructor()).is(r1)); 3822 ASSERT(ToRegister(instr->InputAt(0)).is(r1));
3859 ASSERT(ToRegister(instr->result()).is(r0)); 3823 ASSERT(ToRegister(instr->result()).is(r0));
3860 3824
3861 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 3825 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
3862 __ mov(r0, Operand(instr->arity())); 3826 __ mov(r0, Operand(instr->arity()));
3863 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 3827 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3864 } 3828 }
3865 3829
3866 3830
3867 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 3831 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3868 CallRuntime(instr->function(), instr->arity(), instr); 3832 CallRuntime(instr->function(), instr->arity(), instr);
3869 } 3833 }
3870 3834
3871 3835
3872 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 3836 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3873 Register object = ToRegister(instr->object()); 3837 Register object = ToRegister(instr->object());
3874 Register value = ToRegister(instr->value()); 3838 Register value = ToRegister(instr->value());
3875 Register scratch = scratch0(); 3839 Register scratch = scratch0();
3876 int offset = instr->offset(); 3840 int offset = instr->offset();
3877 3841
3878 ASSERT(!object.is(value)); 3842 ASSERT(!object.is(value));
3879 3843
3880 if (!instr->transition().is_null()) { 3844 if (!instr->transition().is_null()) {
3881 __ mov(scratch, Operand(instr->transition())); 3845 __ mov(scratch, Operand(instr->transition()));
3882 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); 3846 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
3883 if (instr->hydrogen()->NeedsWriteBarrierForMap()) { 3847 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
3884 Register temp = ToRegister(instr->temp()); 3848 Register temp = ToRegister(instr->TempAt(0));
3885 // Update the write barrier for the map field. 3849 // Update the write barrier for the map field.
3886 __ RecordWriteField(object, 3850 __ RecordWriteField(object,
3887 HeapObject::kMapOffset, 3851 HeapObject::kMapOffset,
3888 scratch, 3852 scratch,
3889 temp, 3853 temp,
3890 kLRHasBeenSaved, 3854 kLRHasBeenSaved,
3891 kSaveFPRegs, 3855 kSaveFPRegs,
3892 OMIT_REMEMBERED_SET, 3856 OMIT_REMEMBERED_SET,
3893 OMIT_SMI_CHECK); 3857 OMIT_SMI_CHECK);
3894 } 3858 }
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
4059 __ add(scratch, scratch, 4023 __ add(scratch, scratch,
4060 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 4024 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
4061 } 4025 }
4062 4026
4063 if (instr->NeedsCanonicalization()) { 4027 if (instr->NeedsCanonicalization()) {
4064 // Check for NaN. All NaNs must be canonicalized. 4028 // Check for NaN. All NaNs must be canonicalized.
4065 __ VFPCompareAndSetFlags(value, value); 4029 __ VFPCompareAndSetFlags(value, value);
4066 // Only load canonical NaN if the comparison above set the overflow. 4030 // Only load canonical NaN if the comparison above set the overflow.
4067 __ Vmov(value, 4031 __ Vmov(value,
4068 FixedDoubleArray::canonical_not_the_hole_nan_as_double(), 4032 FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
4069 no_reg, vs); 4033 vs);
4070 } 4034 }
4071 4035
4072 __ vstr(value, scratch, instr->additional_index() << element_size_shift); 4036 __ vstr(value, scratch, instr->additional_index() << element_size_shift);
4073 } 4037 }
4074 4038
4075 4039
4076 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 4040 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
4077 LStoreKeyedSpecializedArrayElement* instr) { 4041 LStoreKeyedSpecializedArrayElement* instr) {
4078 4042
4079 Register external_pointer = ToRegister(instr->external_pointer()); 4043 Register external_pointer = ToRegister(instr->external_pointer());
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
4152 4116
4153 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4117 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4154 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 4118 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
4155 : isolate()->builtins()->KeyedStoreIC_Initialize(); 4119 : isolate()->builtins()->KeyedStoreIC_Initialize();
4156 CallCode(ic, RelocInfo::CODE_TARGET, instr); 4120 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4157 } 4121 }
4158 4122
4159 4123
4160 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 4124 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4161 Register object_reg = ToRegister(instr->object()); 4125 Register object_reg = ToRegister(instr->object());
4162 Register new_map_reg = ToRegister(instr->new_map_temp()); 4126 Register new_map_reg = ToRegister(instr->new_map_reg());
4163 Register scratch = scratch0(); 4127 Register scratch = scratch0();
4164 4128
4165 Handle<Map> from_map = instr->original_map(); 4129 Handle<Map> from_map = instr->original_map();
4166 Handle<Map> to_map = instr->transitioned_map(); 4130 Handle<Map> to_map = instr->transitioned_map();
4167 ElementsKind from_kind = from_map->elements_kind(); 4131 ElementsKind from_kind = from_map->elements_kind();
4168 ElementsKind to_kind = to_map->elements_kind(); 4132 ElementsKind to_kind = to_map->elements_kind();
4169 4133
4170 Label not_applicable; 4134 Label not_applicable;
4171 __ ldr(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 4135 __ ldr(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset));
4172 __ cmp(scratch, Operand(from_map)); 4136 __ cmp(scratch, Operand(from_map));
4173 __ b(ne, &not_applicable); 4137 __ b(ne, &not_applicable);
4174 __ mov(new_map_reg, Operand(to_map)); 4138 __ mov(new_map_reg, Operand(to_map));
4175 4139
4176 if (IsSimpleMapChangeTransition(from_kind, to_kind)) { 4140 if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
4177 __ str(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 4141 __ str(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset));
4178 // Write barrier. 4142 // Write barrier.
4179 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 4143 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
4180 scratch, kLRHasBeenSaved, kDontSaveFPRegs); 4144 scratch, kLRHasBeenSaved, kDontSaveFPRegs);
4181 } else if (IsFastSmiElementsKind(from_kind) && 4145 } else if (IsFastSmiElementsKind(from_kind) &&
4182 IsFastDoubleElementsKind(to_kind)) { 4146 IsFastDoubleElementsKind(to_kind)) {
4183 Register fixed_object_reg = ToRegister(instr->temp()); 4147 Register fixed_object_reg = ToRegister(instr->temp_reg());
4184 ASSERT(fixed_object_reg.is(r2)); 4148 ASSERT(fixed_object_reg.is(r2));
4185 ASSERT(new_map_reg.is(r3)); 4149 ASSERT(new_map_reg.is(r3));
4186 __ mov(fixed_object_reg, object_reg); 4150 __ mov(fixed_object_reg, object_reg);
4187 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 4151 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
4188 RelocInfo::CODE_TARGET, instr); 4152 RelocInfo::CODE_TARGET, instr);
4189 } else if (IsFastDoubleElementsKind(from_kind) && 4153 } else if (IsFastDoubleElementsKind(from_kind) &&
4190 IsFastObjectElementsKind(to_kind)) { 4154 IsFastObjectElementsKind(to_kind)) {
4191 Register fixed_object_reg = ToRegister(instr->temp()); 4155 Register fixed_object_reg = ToRegister(instr->temp_reg());
4192 ASSERT(fixed_object_reg.is(r2)); 4156 ASSERT(fixed_object_reg.is(r2));
4193 ASSERT(new_map_reg.is(r3)); 4157 ASSERT(new_map_reg.is(r3));
4194 __ mov(fixed_object_reg, object_reg); 4158 __ mov(fixed_object_reg, object_reg);
4195 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 4159 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
4196 RelocInfo::CODE_TARGET, instr); 4160 RelocInfo::CODE_TARGET, instr);
4197 } else { 4161 } else {
4198 UNREACHABLE(); 4162 UNREACHABLE();
4199 } 4163 }
4200 __ bind(&not_applicable); 4164 __ bind(&not_applicable);
4201 } 4165 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
4306 4270
4307 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4271 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4308 __ SmiTag(char_code); 4272 __ SmiTag(char_code);
4309 __ push(char_code); 4273 __ push(char_code);
4310 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); 4274 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr);
4311 __ StoreToSafepointRegisterSlot(r0, result); 4275 __ StoreToSafepointRegisterSlot(r0, result);
4312 } 4276 }
4313 4277
4314 4278
4315 void LCodeGen::DoStringLength(LStringLength* instr) { 4279 void LCodeGen::DoStringLength(LStringLength* instr) {
4316 Register string = ToRegister(instr->string()); 4280 Register string = ToRegister(instr->InputAt(0));
4317 Register result = ToRegister(instr->result()); 4281 Register result = ToRegister(instr->result());
4318 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); 4282 __ ldr(result, FieldMemOperand(string, String::kLengthOffset));
4319 } 4283 }
4320 4284
4321 4285
4322 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4286 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4323 LOperand* input = instr->value(); 4287 LOperand* input = instr->InputAt(0);
4324 ASSERT(input->IsRegister() || input->IsStackSlot()); 4288 ASSERT(input->IsRegister() || input->IsStackSlot());
4325 LOperand* output = instr->result(); 4289 LOperand* output = instr->result();
4326 ASSERT(output->IsDoubleRegister()); 4290 ASSERT(output->IsDoubleRegister());
4327 SwVfpRegister single_scratch = double_scratch0().low(); 4291 SwVfpRegister single_scratch = double_scratch0().low();
4328 if (input->IsStackSlot()) { 4292 if (input->IsStackSlot()) {
4329 Register scratch = scratch0(); 4293 Register scratch = scratch0();
4330 __ ldr(scratch, ToMemOperand(input)); 4294 __ ldr(scratch, ToMemOperand(input));
4331 __ vmov(single_scratch, scratch); 4295 __ vmov(single_scratch, scratch);
4332 } else { 4296 } else {
4333 __ vmov(single_scratch, ToRegister(input)); 4297 __ vmov(single_scratch, ToRegister(input));
4334 } 4298 }
4335 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); 4299 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch);
4336 } 4300 }
4337 4301
4338 4302
4339 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4303 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4340 LOperand* input = instr->value(); 4304 LOperand* input = instr->InputAt(0);
4341 LOperand* output = instr->result(); 4305 LOperand* output = instr->result();
4342 4306
4343 SwVfpRegister flt_scratch = double_scratch0().low(); 4307 SwVfpRegister flt_scratch = double_scratch0().low();
4344 __ vmov(flt_scratch, ToRegister(input)); 4308 __ vmov(flt_scratch, ToRegister(input));
4345 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); 4309 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch);
4346 } 4310 }
4347 4311
4348 4312
4349 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4313 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4350 class DeferredNumberTagI: public LDeferredCode { 4314 class DeferredNumberTagI: public LDeferredCode {
4351 public: 4315 public:
4352 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4316 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4353 : LDeferredCode(codegen), instr_(instr) { } 4317 : LDeferredCode(codegen), instr_(instr) { }
4354 virtual void Generate() { 4318 virtual void Generate() {
4355 codegen()->DoDeferredNumberTagI(instr_, 4319 codegen()->DoDeferredNumberTagI(instr_,
4356 instr_->value(), 4320 instr_->InputAt(0),
4357 SIGNED_INT32); 4321 SIGNED_INT32);
4358 } 4322 }
4359 virtual LInstruction* instr() { return instr_; } 4323 virtual LInstruction* instr() { return instr_; }
4360 private: 4324 private:
4361 LNumberTagI* instr_; 4325 LNumberTagI* instr_;
4362 }; 4326 };
4363 4327
4364 Register src = ToRegister(instr->value()); 4328 Register src = ToRegister(instr->InputAt(0));
4365 Register dst = ToRegister(instr->result()); 4329 Register dst = ToRegister(instr->result());
4366 4330
4367 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4331 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4368 __ SmiTag(dst, src, SetCC); 4332 __ SmiTag(dst, src, SetCC);
4369 __ b(vs, deferred->entry()); 4333 __ b(vs, deferred->entry());
4370 __ bind(deferred->exit()); 4334 __ bind(deferred->exit());
4371 } 4335 }
4372 4336
4373 4337
4374 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4338 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4375 class DeferredNumberTagU: public LDeferredCode { 4339 class DeferredNumberTagU: public LDeferredCode {
4376 public: 4340 public:
4377 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 4341 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4378 : LDeferredCode(codegen), instr_(instr) { } 4342 : LDeferredCode(codegen), instr_(instr) { }
4379 virtual void Generate() { 4343 virtual void Generate() {
4380 codegen()->DoDeferredNumberTagI(instr_, 4344 codegen()->DoDeferredNumberTagI(instr_,
4381 instr_->value(), 4345 instr_->InputAt(0),
4382 UNSIGNED_INT32); 4346 UNSIGNED_INT32);
4383 } 4347 }
4384 virtual LInstruction* instr() { return instr_; } 4348 virtual LInstruction* instr() { return instr_; }
4385 private: 4349 private:
4386 LNumberTagU* instr_; 4350 LNumberTagU* instr_;
4387 }; 4351 };
4388 4352
4389 LOperand* input = instr->value(); 4353 LOperand* input = instr->InputAt(0);
4390 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4354 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4391 Register reg = ToRegister(input); 4355 Register reg = ToRegister(input);
4392 4356
4393 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4357 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4394 __ cmp(reg, Operand(Smi::kMaxValue)); 4358 __ cmp(reg, Operand(Smi::kMaxValue));
4395 __ b(hi, deferred->entry()); 4359 __ b(hi, deferred->entry());
4396 __ SmiTag(reg, reg); 4360 __ SmiTag(reg, reg);
4397 __ bind(deferred->exit()); 4361 __ bind(deferred->exit());
4398 } 4362 }
4399 4363
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
4457 class DeferredNumberTagD: public LDeferredCode { 4421 class DeferredNumberTagD: public LDeferredCode {
4458 public: 4422 public:
4459 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4423 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4460 : LDeferredCode(codegen), instr_(instr) { } 4424 : LDeferredCode(codegen), instr_(instr) { }
4461 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4425 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
4462 virtual LInstruction* instr() { return instr_; } 4426 virtual LInstruction* instr() { return instr_; }
4463 private: 4427 private:
4464 LNumberTagD* instr_; 4428 LNumberTagD* instr_;
4465 }; 4429 };
4466 4430
4467 DoubleRegister input_reg = ToDoubleRegister(instr->value()); 4431 DoubleRegister input_reg = ToDoubleRegister(instr->InputAt(0));
4468 Register scratch = scratch0(); 4432 Register scratch = scratch0();
4469 Register reg = ToRegister(instr->result()); 4433 Register reg = ToRegister(instr->result());
4470 Register temp1 = ToRegister(instr->temp()); 4434 Register temp1 = ToRegister(instr->TempAt(0));
4471 Register temp2 = ToRegister(instr->temp2()); 4435 Register temp2 = ToRegister(instr->TempAt(1));
4472 4436
4473 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4437 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4474 if (FLAG_inline_new) { 4438 if (FLAG_inline_new) {
4475 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 4439 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
4476 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry()); 4440 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry());
4477 } else { 4441 } else {
4478 __ jmp(deferred->entry()); 4442 __ jmp(deferred->entry());
4479 } 4443 }
4480 __ bind(deferred->exit()); 4444 __ bind(deferred->exit());
4481 __ sub(ip, reg, Operand(kHeapObjectTag)); 4445 __ sub(ip, reg, Operand(kHeapObjectTag));
4482 __ vstr(input_reg, ip, HeapNumber::kValueOffset); 4446 __ vstr(input_reg, ip, HeapNumber::kValueOffset);
4483 } 4447 }
4484 4448
4485 4449
4486 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4450 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4487 // TODO(3095996): Get rid of this. For now, we need to make the 4451 // TODO(3095996): Get rid of this. For now, we need to make the
4488 // result register contain a valid pointer because it is already 4452 // result register contain a valid pointer because it is already
4489 // contained in the register pointer map. 4453 // contained in the register pointer map.
4490 Register reg = ToRegister(instr->result()); 4454 Register reg = ToRegister(instr->result());
4491 __ mov(reg, Operand(0)); 4455 __ mov(reg, Operand(0));
4492 4456
4493 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4457 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4494 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 4458 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4495 __ StoreToSafepointRegisterSlot(r0, reg); 4459 __ StoreToSafepointRegisterSlot(r0, reg);
4496 } 4460 }
4497 4461
4498 4462
4499 void LCodeGen::DoSmiTag(LSmiTag* instr) { 4463 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4500 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 4464 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
4501 __ SmiTag(ToRegister(instr->result()), ToRegister(instr->value())); 4465 __ SmiTag(ToRegister(instr->result()), ToRegister(instr->InputAt(0)));
4502 } 4466 }
4503 4467
4504 4468
4505 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4469 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4506 Register input = ToRegister(instr->value()); 4470 Register input = ToRegister(instr->InputAt(0));
4507 Register result = ToRegister(instr->result()); 4471 Register result = ToRegister(instr->result());
4508 if (instr->needs_check()) { 4472 if (instr->needs_check()) {
4509 STATIC_ASSERT(kHeapObjectTag == 1); 4473 STATIC_ASSERT(kHeapObjectTag == 1);
4510 // If the input is a HeapObject, SmiUntag will set the carry flag. 4474 // If the input is a HeapObject, SmiUntag will set the carry flag.
4511 __ SmiUntag(result, input, SetCC); 4475 __ SmiUntag(result, input, SetCC);
4512 DeoptimizeIf(cs, instr->environment()); 4476 DeoptimizeIf(cs, instr->environment());
4513 } else { 4477 } else {
4514 __ SmiUntag(result, input); 4478 __ SmiUntag(result, input);
4515 } 4479 }
4516 } 4480 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4568 // Smi to double register conversion 4532 // Smi to double register conversion
4569 __ bind(&load_smi); 4533 __ bind(&load_smi);
4570 // scratch: untagged value of input_reg 4534 // scratch: untagged value of input_reg
4571 __ vmov(flt_scratch, scratch); 4535 __ vmov(flt_scratch, scratch);
4572 __ vcvt_f64_s32(result_reg, flt_scratch); 4536 __ vcvt_f64_s32(result_reg, flt_scratch);
4573 __ bind(&done); 4537 __ bind(&done);
4574 } 4538 }
4575 4539
4576 4540
4577 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 4541 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4578 Register input_reg = ToRegister(instr->value()); 4542 Register input_reg = ToRegister(instr->InputAt(0));
4579 Register scratch1 = scratch0(); 4543 Register scratch1 = scratch0();
4580 Register scratch2 = ToRegister(instr->temp()); 4544 Register scratch2 = ToRegister(instr->TempAt(0));
4581 DwVfpRegister double_scratch = double_scratch0(); 4545 DwVfpRegister double_scratch = double_scratch0();
4582 SwVfpRegister single_scratch = double_scratch.low(); 4546 SwVfpRegister single_scratch = double_scratch.low();
4583 4547
4584 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2)); 4548 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2));
4585 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1)); 4549 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1));
4586 4550
4587 Label done; 4551 Label done;
4588 4552
4589 // The input was optimistically untagged; revert it. 4553 // The input was optimistically untagged; revert it.
4590 // The carry flag is set when we reach this deferred code as we just executed 4554 // The carry flag is set when we reach this deferred code as we just executed
4591 // SmiUntag(heap_object, SetCC) 4555 // SmiUntag(heap_object, SetCC)
4592 STATIC_ASSERT(kHeapObjectTag == 1); 4556 STATIC_ASSERT(kHeapObjectTag == 1);
4593 __ adc(input_reg, input_reg, Operand(input_reg)); 4557 __ adc(input_reg, input_reg, Operand(input_reg));
4594 4558
4595 // Heap number map check. 4559 // Heap number map check.
4596 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4560 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4597 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 4561 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
4598 __ cmp(scratch1, Operand(ip)); 4562 __ cmp(scratch1, Operand(ip));
4599 4563
4600 if (instr->truncating()) { 4564 if (instr->truncating()) {
4601 Register scratch3 = ToRegister(instr->temp2()); 4565 Register scratch3 = ToRegister(instr->TempAt(1));
4602 DwVfpRegister double_scratch2 = ToDoubleRegister(instr->temp3()); 4566 DwVfpRegister double_scratch2 = ToDoubleRegister(instr->TempAt(2));
4603 ASSERT(!scratch3.is(input_reg) && 4567 ASSERT(!scratch3.is(input_reg) &&
4604 !scratch3.is(scratch1) && 4568 !scratch3.is(scratch1) &&
4605 !scratch3.is(scratch2)); 4569 !scratch3.is(scratch2));
4606 // Performs a truncating conversion of a floating point number as used by 4570 // Performs a truncating conversion of a floating point number as used by
4607 // the JS bitwise operations. 4571 // the JS bitwise operations.
4608 Label heap_number; 4572 Label heap_number;
4609 __ b(eq, &heap_number); 4573 __ b(eq, &heap_number);
4610 // Check for undefined. Undefined is converted to zero for truncating 4574 // Check for undefined. Undefined is converted to zero for truncating
4611 // conversions. 4575 // conversions.
4612 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 4576 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4659 class DeferredTaggedToI: public LDeferredCode { 4623 class DeferredTaggedToI: public LDeferredCode {
4660 public: 4624 public:
4661 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4625 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4662 : LDeferredCode(codegen), instr_(instr) { } 4626 : LDeferredCode(codegen), instr_(instr) { }
4663 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 4627 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
4664 virtual LInstruction* instr() { return instr_; } 4628 virtual LInstruction* instr() { return instr_; }
4665 private: 4629 private:
4666 LTaggedToI* instr_; 4630 LTaggedToI* instr_;
4667 }; 4631 };
4668 4632
4669 LOperand* input = instr->value(); 4633 LOperand* input = instr->InputAt(0);
4670 ASSERT(input->IsRegister()); 4634 ASSERT(input->IsRegister());
4671 ASSERT(input->Equals(instr->result())); 4635 ASSERT(input->Equals(instr->result()));
4672 4636
4673 Register input_reg = ToRegister(input); 4637 Register input_reg = ToRegister(input);
4674 4638
4675 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 4639 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4676 4640
4677 // Optimistically untag the input. 4641 // Optimistically untag the input.
4678 // If the input is a HeapObject, SmiUntag will set the carry flag. 4642 // If the input is a HeapObject, SmiUntag will set the carry flag.
4679 __ SmiUntag(input_reg, SetCC); 4643 __ SmiUntag(input_reg, SetCC);
4680 // Branch to deferred code if the input was tagged. 4644 // Branch to deferred code if the input was tagged.
4681 // The deferred code will take care of restoring the tag. 4645 // The deferred code will take care of restoring the tag.
4682 __ b(cs, deferred->entry()); 4646 __ b(cs, deferred->entry());
4683 __ bind(deferred->exit()); 4647 __ bind(deferred->exit());
4684 } 4648 }
4685 4649
4686 4650
4687 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4651 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4688 LOperand* input = instr->value(); 4652 LOperand* input = instr->InputAt(0);
4689 ASSERT(input->IsRegister()); 4653 ASSERT(input->IsRegister());
4690 LOperand* result = instr->result(); 4654 LOperand* result = instr->result();
4691 ASSERT(result->IsDoubleRegister()); 4655 ASSERT(result->IsDoubleRegister());
4692 4656
4693 Register input_reg = ToRegister(input); 4657 Register input_reg = ToRegister(input);
4694 DoubleRegister result_reg = ToDoubleRegister(result); 4658 DoubleRegister result_reg = ToDoubleRegister(result);
4695 4659
4696 EmitNumberUntagD(input_reg, result_reg, 4660 EmitNumberUntagD(input_reg, result_reg,
4697 instr->hydrogen()->deoptimize_on_undefined(), 4661 instr->hydrogen()->deoptimize_on_undefined(),
4698 instr->hydrogen()->deoptimize_on_minus_zero(), 4662 instr->hydrogen()->deoptimize_on_minus_zero(),
4699 instr->environment()); 4663 instr->environment());
4700 } 4664 }
4701 4665
4702 4666
4703 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4667 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4704 Register result_reg = ToRegister(instr->result()); 4668 Register result_reg = ToRegister(instr->result());
4705 Register scratch1 = scratch0(); 4669 Register scratch1 = scratch0();
4706 Register scratch2 = ToRegister(instr->temp()); 4670 Register scratch2 = ToRegister(instr->TempAt(0));
4707 DwVfpRegister double_input = ToDoubleRegister(instr->value()); 4671 DwVfpRegister double_input = ToDoubleRegister(instr->InputAt(0));
4708 SwVfpRegister single_scratch = double_scratch0().low(); 4672 SwVfpRegister single_scratch = double_scratch0().low();
4709 4673
4710 Label done; 4674 Label done;
4711 4675
4712 if (instr->truncating()) { 4676 if (instr->truncating()) {
4713 Register scratch3 = ToRegister(instr->temp2()); 4677 Register scratch3 = ToRegister(instr->TempAt(1));
4714 __ EmitECMATruncate(result_reg, 4678 __ EmitECMATruncate(result_reg,
4715 double_input, 4679 double_input,
4716 single_scratch, 4680 single_scratch,
4717 scratch1, 4681 scratch1,
4718 scratch2, 4682 scratch2,
4719 scratch3); 4683 scratch3);
4720 } else { 4684 } else {
4721 VFPRoundingMode rounding_mode = kRoundToMinusInf; 4685 VFPRoundingMode rounding_mode = kRoundToMinusInf;
4722 __ EmitVFPTruncate(rounding_mode, 4686 __ EmitVFPTruncate(rounding_mode,
4723 single_scratch, 4687 single_scratch,
4724 double_input, 4688 double_input,
4725 scratch1, 4689 scratch1,
4726 scratch2, 4690 scratch2,
4727 kCheckForInexactConversion); 4691 kCheckForInexactConversion);
4728 // Deoptimize if we had a vfp invalid exception, 4692 // Deoptimize if we had a vfp invalid exception,
4729 // including inexact operation. 4693 // including inexact operation.
4730 DeoptimizeIf(ne, instr->environment()); 4694 DeoptimizeIf(ne, instr->environment());
4731 // Retrieve the result. 4695 // Retrieve the result.
4732 __ vmov(result_reg, single_scratch); 4696 __ vmov(result_reg, single_scratch);
4733 } 4697 }
4734 __ bind(&done); 4698 __ bind(&done);
4735 } 4699 }
4736 4700
4737 4701
4738 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 4702 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4739 LOperand* input = instr->value(); 4703 LOperand* input = instr->InputAt(0);
4740 __ tst(ToRegister(input), Operand(kSmiTagMask)); 4704 __ tst(ToRegister(input), Operand(kSmiTagMask));
4741 DeoptimizeIf(ne, instr->environment()); 4705 DeoptimizeIf(ne, instr->environment());
4742 } 4706 }
4743 4707
4744 4708
4745 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 4709 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4746 LOperand* input = instr->value(); 4710 LOperand* input = instr->InputAt(0);
4747 __ tst(ToRegister(input), Operand(kSmiTagMask)); 4711 __ tst(ToRegister(input), Operand(kSmiTagMask));
4748 DeoptimizeIf(eq, instr->environment()); 4712 DeoptimizeIf(eq, instr->environment());
4749 } 4713 }
4750 4714
4751 4715
4752 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 4716 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4753 Register input = ToRegister(instr->value()); 4717 Register input = ToRegister(instr->InputAt(0));
4754 Register scratch = scratch0(); 4718 Register scratch = scratch0();
4755 4719
4756 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 4720 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
4757 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); 4721 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
4758 4722
4759 if (instr->hydrogen()->is_interval_check()) { 4723 if (instr->hydrogen()->is_interval_check()) {
4760 InstanceType first; 4724 InstanceType first;
4761 InstanceType last; 4725 InstanceType last;
4762 instr->hydrogen()->GetCheckInterval(&first, &last); 4726 instr->hydrogen()->GetCheckInterval(&first, &last);
4763 4727
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
4816 LEnvironment* env) { 4780 LEnvironment* env) {
4817 Label success; 4781 Label success;
4818 __ CompareMap(reg, scratch, map, &success, mode); 4782 __ CompareMap(reg, scratch, map, &success, mode);
4819 DeoptimizeIf(ne, env); 4783 DeoptimizeIf(ne, env);
4820 __ bind(&success); 4784 __ bind(&success);
4821 } 4785 }
4822 4786
4823 4787
4824 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 4788 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4825 Register scratch = scratch0(); 4789 Register scratch = scratch0();
4826 LOperand* input = instr->value(); 4790 LOperand* input = instr->InputAt(0);
4827 ASSERT(input->IsRegister()); 4791 ASSERT(input->IsRegister());
4828 Register reg = ToRegister(input); 4792 Register reg = ToRegister(input);
4829 4793
4830 Label success; 4794 Label success;
4831 SmallMapList* map_set = instr->hydrogen()->map_set(); 4795 SmallMapList* map_set = instr->hydrogen()->map_set();
4832 for (int i = 0; i < map_set->length() - 1; i++) { 4796 for (int i = 0; i < map_set->length() - 1; i++) {
4833 Handle<Map> map = map_set->at(i); 4797 Handle<Map> map = map_set->at(i);
4834 __ CompareMap(reg, scratch, map, &success, REQUIRE_EXACT_MAP); 4798 __ CompareMap(reg, scratch, map, &success, REQUIRE_EXACT_MAP);
4835 __ b(eq, &success); 4799 __ b(eq, &success);
4836 } 4800 }
4837 Handle<Map> map = map_set->last(); 4801 Handle<Map> map = map_set->last();
4838 DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment()); 4802 DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment());
4839 __ bind(&success); 4803 __ bind(&success);
4840 } 4804 }
4841 4805
4842 4806
4843 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 4807 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
4844 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); 4808 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
4845 Register result_reg = ToRegister(instr->result()); 4809 Register result_reg = ToRegister(instr->result());
4846 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); 4810 DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0));
4847 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); 4811 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg);
4848 } 4812 }
4849 4813
4850 4814
4851 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 4815 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
4852 Register unclamped_reg = ToRegister(instr->unclamped()); 4816 Register unclamped_reg = ToRegister(instr->unclamped());
4853 Register result_reg = ToRegister(instr->result()); 4817 Register result_reg = ToRegister(instr->result());
4854 __ ClampUint8(result_reg, unclamped_reg); 4818 __ ClampUint8(result_reg, unclamped_reg);
4855 } 4819 }
4856 4820
4857 4821
4858 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 4822 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
4859 Register scratch = scratch0(); 4823 Register scratch = scratch0();
4860 Register input_reg = ToRegister(instr->unclamped()); 4824 Register input_reg = ToRegister(instr->unclamped());
4861 Register result_reg = ToRegister(instr->result()); 4825 Register result_reg = ToRegister(instr->result());
4862 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); 4826 DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0));
4863 Label is_smi, done, heap_number; 4827 Label is_smi, done, heap_number;
4864 4828
4865 // Both smi and heap number cases are handled. 4829 // Both smi and heap number cases are handled.
4866 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi); 4830 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi);
4867 4831
4868 // Check for heap number 4832 // Check for heap number
4869 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4833 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4870 __ cmp(scratch, Operand(factory()->heap_number_map())); 4834 __ cmp(scratch, Operand(factory()->heap_number_map()));
4871 __ b(eq, &heap_number); 4835 __ b(eq, &heap_number);
4872 4836
(...skipping 13 matching lines...) Expand all
4886 4850
4887 // smi 4851 // smi
4888 __ bind(&is_smi); 4852 __ bind(&is_smi);
4889 __ ClampUint8(result_reg, result_reg); 4853 __ ClampUint8(result_reg, result_reg);
4890 4854
4891 __ bind(&done); 4855 __ bind(&done);
4892 } 4856 }
4893 4857
4894 4858
4895 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 4859 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
4896 Register temp1 = ToRegister(instr->temp()); 4860 Register temp1 = ToRegister(instr->TempAt(0));
4897 Register temp2 = ToRegister(instr->temp2()); 4861 Register temp2 = ToRegister(instr->TempAt(1));
4898 4862
4899 Handle<JSObject> holder = instr->holder(); 4863 Handle<JSObject> holder = instr->holder();
4900 Handle<JSObject> current_prototype = instr->prototype(); 4864 Handle<JSObject> current_prototype = instr->prototype();
4901 4865
4902 // Load prototype object. 4866 // Load prototype object.
4903 __ LoadHeapObject(temp1, current_prototype); 4867 __ LoadHeapObject(temp1, current_prototype);
4904 4868
4905 // Check prototype maps up to the holder. 4869 // Check prototype maps up to the holder.
4906 while (!current_prototype.is_identical_to(holder)) { 4870 while (!current_prototype.is_identical_to(holder)) {
4907 DoCheckMapCommon(temp1, temp2, 4871 DoCheckMapCommon(temp1, temp2,
(...skipping 21 matching lines...) Expand all
4929 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); } 4893 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
4930 virtual LInstruction* instr() { return instr_; } 4894 virtual LInstruction* instr() { return instr_; }
4931 private: 4895 private:
4932 LAllocateObject* instr_; 4896 LAllocateObject* instr_;
4933 }; 4897 };
4934 4898
4935 DeferredAllocateObject* deferred = 4899 DeferredAllocateObject* deferred =
4936 new(zone()) DeferredAllocateObject(this, instr); 4900 new(zone()) DeferredAllocateObject(this, instr);
4937 4901
4938 Register result = ToRegister(instr->result()); 4902 Register result = ToRegister(instr->result());
4939 Register scratch = ToRegister(instr->temp()); 4903 Register scratch = ToRegister(instr->TempAt(0));
4940 Register scratch2 = ToRegister(instr->temp2()); 4904 Register scratch2 = ToRegister(instr->TempAt(1));
4941 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); 4905 Handle<JSFunction> constructor = instr->hydrogen()->constructor();
4942 Handle<Map> initial_map(constructor->initial_map()); 4906 Handle<Map> initial_map(constructor->initial_map());
4943 int instance_size = initial_map->instance_size(); 4907 int instance_size = initial_map->instance_size();
4944 ASSERT(initial_map->pre_allocated_property_fields() + 4908 ASSERT(initial_map->pre_allocated_property_fields() +
4945 initial_map->unused_property_fields() - 4909 initial_map->unused_property_fields() -
4946 initial_map->inobject_properties() == 0); 4910 initial_map->inobject_properties() == 0);
4947 4911
4948 // Allocate memory for the object. The initial map might change when 4912 // Allocate memory for the object. The initial map might change when
4949 // the constructor's prototype changes, but instance size and property 4913 // the constructor's prototype changes, but instance size and property
4950 // counts remain unchanged (if slack tracking finished). 4914 // counts remain unchanged (if slack tracking finished).
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
5222 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 5186 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
5223 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); 5187 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr);
5224 } else { 5188 } else {
5225 FastCloneShallowObjectStub stub(properties_count); 5189 FastCloneShallowObjectStub stub(properties_count);
5226 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 5190 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
5227 } 5191 }
5228 } 5192 }
5229 5193
5230 5194
5231 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { 5195 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5232 ASSERT(ToRegister(instr->value()).is(r0)); 5196 ASSERT(ToRegister(instr->InputAt(0)).is(r0));
5233 __ push(r0); 5197 __ push(r0);
5234 CallRuntime(Runtime::kToFastProperties, 1, instr); 5198 CallRuntime(Runtime::kToFastProperties, 1, instr);
5235 } 5199 }
5236 5200
5237 5201
5238 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 5202 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5239 Label materialized; 5203 Label materialized;
5240 // Registers will be used as follows: 5204 // Registers will be used as follows:
5241 // r7 = literals array. 5205 // r7 = literals array.
5242 // r1 = regexp literal. 5206 // r1 = regexp literal.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
5303 __ mov(r1, Operand(pretenure 5267 __ mov(r1, Operand(pretenure
5304 ? factory()->true_value() 5268 ? factory()->true_value()
5305 : factory()->false_value())); 5269 : factory()->false_value()));
5306 __ Push(cp, r2, r1); 5270 __ Push(cp, r2, r1);
5307 CallRuntime(Runtime::kNewClosure, 3, instr); 5271 CallRuntime(Runtime::kNewClosure, 3, instr);
5308 } 5272 }
5309 } 5273 }
5310 5274
5311 5275
5312 void LCodeGen::DoTypeof(LTypeof* instr) { 5276 void LCodeGen::DoTypeof(LTypeof* instr) {
5313 Register input = ToRegister(instr->value()); 5277 Register input = ToRegister(instr->InputAt(0));
5314 __ push(input); 5278 __ push(input);
5315 CallRuntime(Runtime::kTypeof, 1, instr); 5279 CallRuntime(Runtime::kTypeof, 1, instr);
5316 } 5280 }
5317 5281
5318 5282
5319 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 5283 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5320 Register input = ToRegister(instr->value()); 5284 Register input = ToRegister(instr->InputAt(0));
5321 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5285 int true_block = chunk_->LookupDestination(instr->true_block_id());
5322 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5286 int false_block = chunk_->LookupDestination(instr->false_block_id());
5323 Label* true_label = chunk_->GetAssemblyLabel(true_block); 5287 Label* true_label = chunk_->GetAssemblyLabel(true_block);
5324 Label* false_label = chunk_->GetAssemblyLabel(false_block); 5288 Label* false_label = chunk_->GetAssemblyLabel(false_block);
5325 5289
5326 Condition final_branch_condition = EmitTypeofIs(true_label, 5290 Condition final_branch_condition = EmitTypeofIs(true_label,
5327 false_label, 5291 false_label,
5328 input, 5292 input,
5329 instr->type_literal()); 5293 instr->type_literal());
5330 if (final_branch_condition != kNoCondition) { 5294 if (final_branch_condition != kNoCondition) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
5400 5364
5401 } else { 5365 } else {
5402 __ b(false_label); 5366 __ b(false_label);
5403 } 5367 }
5404 5368
5405 return final_branch_condition; 5369 return final_branch_condition;
5406 } 5370 }
5407 5371
5408 5372
5409 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5373 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5410 Register temp1 = ToRegister(instr->temp()); 5374 Register temp1 = ToRegister(instr->TempAt(0));
5411 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5375 int true_block = chunk_->LookupDestination(instr->true_block_id());
5412 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5376 int false_block = chunk_->LookupDestination(instr->false_block_id());
5413 5377
5414 EmitIsConstructCall(temp1, scratch0()); 5378 EmitIsConstructCall(temp1, scratch0());
5415 EmitBranch(true_block, false_block, eq); 5379 EmitBranch(true_block, false_block, eq);
5416 } 5380 }
5417 5381
5418 5382
5419 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) { 5383 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
5420 ASSERT(!temp1.is(temp2)); 5384 ASSERT(!temp1.is(temp2));
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
5660 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 5624 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
5661 __ ldr(result, FieldMemOperand(scratch, 5625 __ ldr(result, FieldMemOperand(scratch,
5662 FixedArray::kHeaderSize - kPointerSize)); 5626 FixedArray::kHeaderSize - kPointerSize));
5663 __ bind(&done); 5627 __ bind(&done);
5664 } 5628 }
5665 5629
5666 5630
5667 #undef __ 5631 #undef __
5668 5632
5669 } } // namespace v8::internal 5633 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698