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

Side by Side Diff: src/ia32/lithium-codegen-ia32.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/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.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 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 397
398 Operand LCodeGen::HighOperand(LOperand* op) { 398 Operand LCodeGen::HighOperand(LOperand* op) {
399 ASSERT(op->IsDoubleStackSlot()); 399 ASSERT(op->IsDoubleStackSlot());
400 int index = op->index(); 400 int index = op->index();
401 int offset = (index >= 0) ? index + 3 : index - 1; 401 int offset = (index >= 0) ? index + 3 : index - 1;
402 return Operand(ebp, -offset * kPointerSize); 402 return Operand(ebp, -offset * kPointerSize);
403 } 403 }
404 404
405 405
406 void LCodeGen::WriteTranslation(LEnvironment* environment, 406 void LCodeGen::WriteTranslation(LEnvironment* environment,
407 Translation* translation, 407 Translation* translation) {
408 int* arguments_index,
409 int* arguments_count) {
410 if (environment == NULL) return; 408 if (environment == NULL) return;
411 409
412 // The translation includes one command per value in the environment. 410 // The translation includes one command per value in the environment.
413 int translation_size = environment->values()->length(); 411 int translation_size = environment->values()->length();
414 // The output frame height does not include the parameters. 412 // The output frame height does not include the parameters.
415 int height = translation_size - environment->parameter_count(); 413 int height = translation_size - environment->parameter_count();
416 414
417 // Function parameters are arguments to the outermost environment. The 415 WriteTranslation(environment->outer(), translation);
418 // arguments index points to the first element of a sequence of tagged
419 // values on the stack that represent the arguments. This needs to be
420 // kept in sync with the LArgumentsElements implementation.
421 *arguments_index = -environment->parameter_count();
422 *arguments_count = environment->parameter_count();
423
424 WriteTranslation(environment->outer(),
425 translation,
426 arguments_index,
427 arguments_count);
428 int closure_id = *info()->closure() != *environment->closure() 416 int closure_id = *info()->closure() != *environment->closure()
429 ? DefineDeoptimizationLiteral(environment->closure()) 417 ? DefineDeoptimizationLiteral(environment->closure())
430 : Translation::kSelfLiteralId; 418 : Translation::kSelfLiteralId;
431 switch (environment->frame_type()) { 419 switch (environment->frame_type()) {
432 case JS_FUNCTION: 420 case JS_FUNCTION:
433 translation->BeginJSFrame(environment->ast_id(), closure_id, height); 421 translation->BeginJSFrame(environment->ast_id(), closure_id, height);
434 break; 422 break;
435 case JS_CONSTRUCT: 423 case JS_CONSTRUCT:
436 translation->BeginConstructStubFrame(closure_id, translation_size); 424 translation->BeginConstructStubFrame(closure_id, translation_size);
437 break; 425 break;
438 case JS_GETTER: 426 case JS_GETTER:
439 ASSERT(translation_size == 1); 427 ASSERT(translation_size == 1);
440 ASSERT(height == 0); 428 ASSERT(height == 0);
441 translation->BeginGetterStubFrame(closure_id); 429 translation->BeginGetterStubFrame(closure_id);
442 break; 430 break;
443 case JS_SETTER: 431 case JS_SETTER:
444 ASSERT(translation_size == 2); 432 ASSERT(translation_size == 2);
445 ASSERT(height == 0); 433 ASSERT(height == 0);
446 translation->BeginSetterStubFrame(closure_id); 434 translation->BeginSetterStubFrame(closure_id);
447 break; 435 break;
448 case ARGUMENTS_ADAPTOR: 436 case ARGUMENTS_ADAPTOR:
449 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 437 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
450 break; 438 break;
451 } 439 }
452
453 // Inlined frames which push their arguments cause the index to be
454 // bumped and another stack area to be used for materialization.
455 if (environment->entry() != NULL &&
456 environment->entry()->arguments_pushed()) {
457 *arguments_index = *arguments_index < 0
458 ? GetStackSlotCount()
459 : *arguments_index + *arguments_count;
460 *arguments_count = environment->entry()->arguments_count() + 1;
461 }
462
463 for (int i = 0; i < translation_size; ++i) { 440 for (int i = 0; i < translation_size; ++i) {
464 LOperand* value = environment->values()->at(i); 441 LOperand* value = environment->values()->at(i);
465 // spilled_registers_ and spilled_double_registers_ are either 442 // spilled_registers_ and spilled_double_registers_ are either
466 // both NULL or both set. 443 // both NULL or both set.
467 if (environment->spilled_registers() != NULL && value != NULL) { 444 if (environment->spilled_registers() != NULL && value != NULL) {
468 if (value->IsRegister() && 445 if (value->IsRegister() &&
469 environment->spilled_registers()[value->index()] != NULL) { 446 environment->spilled_registers()[value->index()] != NULL) {
470 translation->MarkDuplicate(); 447 translation->MarkDuplicate();
471 AddToTranslation(translation, 448 AddToTranslation(translation,
472 environment->spilled_registers()[value->index()], 449 environment->spilled_registers()[value->index()],
473 environment->HasTaggedValueAt(i), 450 environment->HasTaggedValueAt(i),
474 environment->HasUint32ValueAt(i), 451 environment->HasUint32ValueAt(i));
475 *arguments_index,
476 *arguments_count);
477 } else if ( 452 } else if (
478 value->IsDoubleRegister() && 453 value->IsDoubleRegister() &&
479 environment->spilled_double_registers()[value->index()] != NULL) { 454 environment->spilled_double_registers()[value->index()] != NULL) {
480 translation->MarkDuplicate(); 455 translation->MarkDuplicate();
481 AddToTranslation( 456 AddToTranslation(
482 translation, 457 translation,
483 environment->spilled_double_registers()[value->index()], 458 environment->spilled_double_registers()[value->index()],
484 false, 459 false,
485 false, 460 false);
486 *arguments_index,
487 *arguments_count);
488 } 461 }
489 } 462 }
490 463
491 AddToTranslation(translation, 464 AddToTranslation(translation,
492 value, 465 value,
493 environment->HasTaggedValueAt(i), 466 environment->HasTaggedValueAt(i),
494 environment->HasUint32ValueAt(i), 467 environment->HasUint32ValueAt(i));
495 *arguments_index,
496 *arguments_count);
497 } 468 }
498 } 469 }
499 470
500 471
501 void LCodeGen::AddToTranslation(Translation* translation, 472 void LCodeGen::AddToTranslation(Translation* translation,
502 LOperand* op, 473 LOperand* op,
503 bool is_tagged, 474 bool is_tagged,
504 bool is_uint32, 475 bool is_uint32) {
505 int arguments_index,
506 int arguments_count) {
507 if (op == NULL) { 476 if (op == NULL) {
508 // TODO(twuerthinger): Introduce marker operands to indicate that this value 477 // TODO(twuerthinger): Introduce marker operands to indicate that this value
509 // is not present and must be reconstructed from the deoptimizer. Currently 478 // is not present and must be reconstructed from the deoptimizer. Currently
510 // this is only used for the arguments object. 479 // this is only used for the arguments object.
511 translation->StoreArgumentsObject(arguments_index, arguments_count); 480 translation->StoreArgumentsObject();
512 } else if (op->IsStackSlot()) { 481 } else if (op->IsStackSlot()) {
513 if (is_tagged) { 482 if (is_tagged) {
514 translation->StoreStackSlot(op->index()); 483 translation->StoreStackSlot(op->index());
515 } else if (is_uint32) { 484 } else if (is_uint32) {
516 translation->StoreUint32StackSlot(op->index()); 485 translation->StoreUint32StackSlot(op->index());
517 } else { 486 } else {
518 translation->StoreInt32StackSlot(op->index()); 487 translation->StoreInt32StackSlot(op->index());
519 } 488 }
520 } else if (op->IsDoubleStackSlot()) { 489 } else if (op->IsDoubleStackSlot()) {
521 translation->StoreDoubleStackSlot(op->index()); 490 translation->StoreDoubleStackSlot(op->index());
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 // 0 ..................................................... size-1 589 // 0 ..................................................... size-1
621 // [parameters] [locals] [expression stack including arguments] 590 // [parameters] [locals] [expression stack including arguments]
622 591
623 // Layout of the translation: 592 // Layout of the translation:
624 // 0 ........................................................ size - 1 + 4 593 // 0 ........................................................ size - 1 + 4
625 // [expression stack including arguments] [locals] [4 words] [parameters] 594 // [expression stack including arguments] [locals] [4 words] [parameters]
626 // |>------------ translation_size ------------<| 595 // |>------------ translation_size ------------<|
627 596
628 int frame_count = 0; 597 int frame_count = 0;
629 int jsframe_count = 0; 598 int jsframe_count = 0;
630 int args_index = 0;
631 int args_count = 0;
632 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 599 for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
633 ++frame_count; 600 ++frame_count;
634 if (e->frame_type() == JS_FUNCTION) { 601 if (e->frame_type() == JS_FUNCTION) {
635 ++jsframe_count; 602 ++jsframe_count;
636 } 603 }
637 } 604 }
638 Translation translation(&translations_, frame_count, jsframe_count, zone()); 605 Translation translation(&translations_, frame_count, jsframe_count,
639 WriteTranslation(environment, &translation, &args_index, &args_count); 606 zone());
607 WriteTranslation(environment, &translation);
640 int deoptimization_index = deoptimizations_.length(); 608 int deoptimization_index = deoptimizations_.length();
641 int pc_offset = masm()->pc_offset(); 609 int pc_offset = masm()->pc_offset();
642 environment->Register(deoptimization_index, 610 environment->Register(deoptimization_index,
643 translation.index(), 611 translation.index(),
644 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 612 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
645 deoptimizations_.Add(environment, zone()); 613 deoptimizations_.Add(environment, zone());
646 } 614 }
647 } 615 }
648 616
649 617
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 } 870 }
903 871
904 872
905 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 873 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
906 // Nothing to do. 874 // Nothing to do.
907 } 875 }
908 876
909 877
910 void LCodeGen::DoModI(LModI* instr) { 878 void LCodeGen::DoModI(LModI* instr) {
911 if (instr->hydrogen()->HasPowerOf2Divisor()) { 879 if (instr->hydrogen()->HasPowerOf2Divisor()) {
912 Register dividend = ToRegister(instr->left()); 880 Register dividend = ToRegister(instr->InputAt(0));
913 881
914 int32_t divisor = 882 int32_t divisor =
915 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 883 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
916 884
917 if (divisor < 0) divisor = -divisor; 885 if (divisor < 0) divisor = -divisor;
918 886
919 Label positive_dividend, done; 887 Label positive_dividend, done;
920 __ test(dividend, Operand(dividend)); 888 __ test(dividend, Operand(dividend));
921 __ j(not_sign, &positive_dividend, Label::kNear); 889 __ j(not_sign, &positive_dividend, Label::kNear);
922 __ neg(dividend); 890 __ neg(dividend);
923 __ and_(dividend, divisor - 1); 891 __ and_(dividend, divisor - 1);
924 __ neg(dividend); 892 __ neg(dividend);
925 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 893 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
926 __ j(not_zero, &done, Label::kNear); 894 __ j(not_zero, &done, Label::kNear);
927 DeoptimizeIf(no_condition, instr->environment()); 895 DeoptimizeIf(no_condition, instr->environment());
928 } else { 896 } else {
929 __ jmp(&done, Label::kNear); 897 __ jmp(&done, Label::kNear);
930 } 898 }
931 __ bind(&positive_dividend); 899 __ bind(&positive_dividend);
932 __ and_(dividend, divisor - 1); 900 __ and_(dividend, divisor - 1);
933 __ bind(&done); 901 __ bind(&done);
934 } else { 902 } else {
935 Label done, remainder_eq_dividend, slow, do_subtraction, both_positive; 903 Label done, remainder_eq_dividend, slow, do_subtraction, both_positive;
936 Register left_reg = ToRegister(instr->left()); 904 Register left_reg = ToRegister(instr->InputAt(0));
937 Register right_reg = ToRegister(instr->right()); 905 Register right_reg = ToRegister(instr->InputAt(1));
938 Register result_reg = ToRegister(instr->result()); 906 Register result_reg = ToRegister(instr->result());
939 907
940 ASSERT(left_reg.is(eax)); 908 ASSERT(left_reg.is(eax));
941 ASSERT(result_reg.is(edx)); 909 ASSERT(result_reg.is(edx));
942 ASSERT(!right_reg.is(eax)); 910 ASSERT(!right_reg.is(eax));
943 ASSERT(!right_reg.is(edx)); 911 ASSERT(!right_reg.is(edx));
944 912
945 // Check for x % 0. 913 // Check for x % 0.
946 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 914 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
947 __ test(right_reg, Operand(right_reg)); 915 __ test(right_reg, Operand(right_reg));
948 DeoptimizeIf(zero, instr->environment()); 916 DeoptimizeIf(zero, instr->environment());
949 } 917 }
950 918
951 __ test(left_reg, Operand(left_reg)); 919 __ test(left_reg, Operand(left_reg));
952 __ j(zero, &remainder_eq_dividend, Label::kNear); 920 __ j(zero, &remainder_eq_dividend, Label::kNear);
953 __ j(sign, &slow, Label::kNear); 921 __ j(sign, &slow, Label::kNear);
954 922
955 __ test(right_reg, Operand(right_reg)); 923 __ test(right_reg, Operand(right_reg));
956 __ j(not_sign, &both_positive, Label::kNear); 924 __ j(not_sign, &both_positive, Label::kNear);
957 // The sign of the divisor doesn't matter. 925 // The sign of the divisor doesn't matter.
958 __ neg(right_reg); 926 __ neg(right_reg);
959 927
960 __ bind(&both_positive); 928 __ bind(&both_positive);
961 // If the dividend is smaller than the nonnegative 929 // If the dividend is smaller than the nonnegative
962 // divisor, the dividend is the result. 930 // divisor, the dividend is the result.
963 __ cmp(left_reg, Operand(right_reg)); 931 __ cmp(left_reg, Operand(right_reg));
964 __ j(less, &remainder_eq_dividend, Label::kNear); 932 __ j(less, &remainder_eq_dividend, Label::kNear);
965 933
966 // Check if the divisor is a PowerOfTwo integer. 934 // Check if the divisor is a PowerOfTwo integer.
967 Register scratch = ToRegister(instr->temp()); 935 Register scratch = ToRegister(instr->TempAt(0));
968 __ mov(scratch, right_reg); 936 __ mov(scratch, right_reg);
969 __ sub(Operand(scratch), Immediate(1)); 937 __ sub(Operand(scratch), Immediate(1));
970 __ test(scratch, Operand(right_reg)); 938 __ test(scratch, Operand(right_reg));
971 __ j(not_zero, &do_subtraction, Label::kNear); 939 __ j(not_zero, &do_subtraction, Label::kNear);
972 __ and_(left_reg, Operand(scratch)); 940 __ and_(left_reg, Operand(scratch));
973 __ jmp(&remainder_eq_dividend, Label::kNear); 941 __ jmp(&remainder_eq_dividend, Label::kNear);
974 942
975 __ bind(&do_subtraction); 943 __ bind(&do_subtraction);
976 const int kUnfolds = 3; 944 const int kUnfolds = 3;
977 // Try a few subtractions of the dividend. 945 // Try a few subtractions of the dividend.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 981
1014 __ bind(&remainder_eq_dividend); 982 __ bind(&remainder_eq_dividend);
1015 __ mov(result_reg, left_reg); 983 __ mov(result_reg, left_reg);
1016 984
1017 __ bind(&done); 985 __ bind(&done);
1018 } 986 }
1019 } 987 }
1020 988
1021 989
1022 void LCodeGen::DoDivI(LDivI* instr) { 990 void LCodeGen::DoDivI(LDivI* instr) {
1023 LOperand* right = instr->right(); 991 LOperand* right = instr->InputAt(1);
1024 ASSERT(ToRegister(instr->result()).is(eax)); 992 ASSERT(ToRegister(instr->result()).is(eax));
1025 ASSERT(ToRegister(instr->left()).is(eax)); 993 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
1026 ASSERT(!ToRegister(instr->right()).is(eax)); 994 ASSERT(!ToRegister(instr->InputAt(1)).is(eax));
1027 ASSERT(!ToRegister(instr->right()).is(edx)); 995 ASSERT(!ToRegister(instr->InputAt(1)).is(edx));
1028 996
1029 Register left_reg = eax; 997 Register left_reg = eax;
1030 998
1031 // Check for x / 0. 999 // Check for x / 0.
1032 Register right_reg = ToRegister(right); 1000 Register right_reg = ToRegister(right);
1033 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1001 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1034 __ test(right_reg, ToOperand(right)); 1002 __ test(right_reg, ToOperand(right));
1035 DeoptimizeIf(zero, instr->environment()); 1003 DeoptimizeIf(zero, instr->environment());
1036 } 1004 }
1037 1005
(...skipping 21 matching lines...) Expand all
1059 __ cdq(); 1027 __ cdq();
1060 __ idiv(right_reg); 1028 __ idiv(right_reg);
1061 1029
1062 // Deoptimize if remainder is not 0. 1030 // Deoptimize if remainder is not 0.
1063 __ test(edx, Operand(edx)); 1031 __ test(edx, Operand(edx));
1064 DeoptimizeIf(not_zero, instr->environment()); 1032 DeoptimizeIf(not_zero, instr->environment());
1065 } 1033 }
1066 1034
1067 1035
1068 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { 1036 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
1069 ASSERT(instr->right()->IsConstantOperand()); 1037 ASSERT(instr->InputAt(1)->IsConstantOperand());
1070 1038
1071 Register dividend = ToRegister(instr->left()); 1039 Register dividend = ToRegister(instr->InputAt(0));
1072 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); 1040 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1)));
1073 Register result = ToRegister(instr->result()); 1041 Register result = ToRegister(instr->result());
1074 1042
1075 switch (divisor) { 1043 switch (divisor) {
1076 case 0: 1044 case 0:
1077 DeoptimizeIf(no_condition, instr->environment()); 1045 DeoptimizeIf(no_condition, instr->environment());
1078 return; 1046 return;
1079 1047
1080 case 1: 1048 case 1:
1081 __ Move(result, dividend); 1049 __ Move(result, dividend);
1082 return; 1050 return;
(...skipping 25 matching lines...) Expand all
1108 __ shl(dividend, 32 - power); 1076 __ shl(dividend, 32 - power);
1109 __ sar(result, power); 1077 __ sar(result, power);
1110 __ not_(dividend); 1078 __ not_(dividend);
1111 // Clear result.sign if dividend.sign is set. 1079 // Clear result.sign if dividend.sign is set.
1112 __ and_(result, dividend); 1080 __ and_(result, dividend);
1113 } else { 1081 } else {
1114 __ Move(result, dividend); 1082 __ Move(result, dividend);
1115 __ sar(result, power); 1083 __ sar(result, power);
1116 } 1084 }
1117 } else { 1085 } else {
1118 ASSERT(ToRegister(instr->left()).is(eax)); 1086 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
1119 ASSERT(ToRegister(instr->result()).is(edx)); 1087 ASSERT(ToRegister(instr->result()).is(edx));
1120 Register scratch = ToRegister(instr->temp()); 1088 Register scratch = ToRegister(instr->TempAt(0));
1121 1089
1122 // Find b which: 2^b < divisor_abs < 2^(b+1). 1090 // Find b which: 2^b < divisor_abs < 2^(b+1).
1123 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs); 1091 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
1124 unsigned shift = 32 + b; // Precision +1bit (effectively). 1092 unsigned shift = 32 + b; // Precision +1bit (effectively).
1125 double multiplier_f = 1093 double multiplier_f =
1126 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs; 1094 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs;
1127 int64_t multiplier; 1095 int64_t multiplier;
1128 if (multiplier_f - floor(multiplier_f) < 0.5) { 1096 if (multiplier_f - floor(multiplier_f) < 0.5) {
1129 multiplier = static_cast<int64_t>(floor(multiplier_f)); 1097 multiplier = static_cast<int64_t>(floor(multiplier_f));
1130 } else { 1098 } else {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 __ cmp(reg_lo, 0xC0000000); 1130 __ cmp(reg_lo, 0xC0000000);
1163 __ setcc(above_equal, reg_byte_scratch); 1131 __ setcc(above_equal, reg_byte_scratch);
1164 __ add(edx, reg_byte_scratch); 1132 __ add(edx, reg_byte_scratch);
1165 } 1133 }
1166 __ sar(edx, shift - 32); 1134 __ sar(edx, shift - 32);
1167 } 1135 }
1168 } 1136 }
1169 1137
1170 1138
1171 void LCodeGen::DoMulI(LMulI* instr) { 1139 void LCodeGen::DoMulI(LMulI* instr) {
1172 Register left = ToRegister(instr->left()); 1140 Register left = ToRegister(instr->InputAt(0));
1173 LOperand* right = instr->right(); 1141 LOperand* right = instr->InputAt(1);
1174 1142
1175 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1143 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1176 __ mov(ToRegister(instr->temp()), left); 1144 __ mov(ToRegister(instr->TempAt(0)), left);
1177 } 1145 }
1178 1146
1179 if (right->IsConstantOperand()) { 1147 if (right->IsConstantOperand()) {
1180 // Try strength reductions on the multiplication. 1148 // Try strength reductions on the multiplication.
1181 // All replacement instructions are at most as long as the imul 1149 // All replacement instructions are at most as long as the imul
1182 // and have better latency. 1150 // and have better latency.
1183 int constant = ToInteger32(LConstantOperand::cast(right)); 1151 int constant = ToInteger32(LConstantOperand::cast(right));
1184 if (constant == -1) { 1152 if (constant == -1) {
1185 __ neg(left); 1153 __ neg(left);
1186 } else if (constant == 0) { 1154 } else if (constant == 0) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1195 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1228 DeoptimizeIf(overflow, instr->environment()); 1196 DeoptimizeIf(overflow, instr->environment());
1229 } 1197 }
1230 1198
1231 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1199 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1232 // Bail out if the result is supposed to be negative zero. 1200 // Bail out if the result is supposed to be negative zero.
1233 Label done; 1201 Label done;
1234 __ test(left, Operand(left)); 1202 __ test(left, Operand(left));
1235 __ j(not_zero, &done, Label::kNear); 1203 __ j(not_zero, &done, Label::kNear);
1236 if (right->IsConstantOperand()) { 1204 if (right->IsConstantOperand()) {
1237 if (ToInteger32(LConstantOperand::cast(right)) < 0) { 1205 if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
1238 DeoptimizeIf(no_condition, instr->environment()); 1206 DeoptimizeIf(no_condition, instr->environment());
1239 } else if (ToInteger32(LConstantOperand::cast(right)) == 0) {
1240 __ cmp(ToRegister(instr->temp()), Immediate(0));
1241 DeoptimizeIf(less, instr->environment());
1242 } 1207 }
1243 } else { 1208 } else {
1244 // Test the non-zero operand for negative sign. 1209 // Test the non-zero operand for negative sign.
1245 __ or_(ToRegister(instr->temp()), ToOperand(right)); 1210 __ or_(ToRegister(instr->TempAt(0)), ToOperand(right));
1246 DeoptimizeIf(sign, instr->environment()); 1211 DeoptimizeIf(sign, instr->environment());
1247 } 1212 }
1248 __ bind(&done); 1213 __ bind(&done);
1249 } 1214 }
1250 } 1215 }
1251 1216
1252 1217
1253 void LCodeGen::DoBitI(LBitI* instr) { 1218 void LCodeGen::DoBitI(LBitI* instr) {
1254 LOperand* left = instr->left(); 1219 LOperand* left = instr->InputAt(0);
1255 LOperand* right = instr->right(); 1220 LOperand* right = instr->InputAt(1);
1256 ASSERT(left->Equals(instr->result())); 1221 ASSERT(left->Equals(instr->result()));
1257 ASSERT(left->IsRegister()); 1222 ASSERT(left->IsRegister());
1258 1223
1259 if (right->IsConstantOperand()) { 1224 if (right->IsConstantOperand()) {
1260 int right_operand = ToInteger32(LConstantOperand::cast(right)); 1225 int right_operand = ToInteger32(LConstantOperand::cast(right));
1261 switch (instr->op()) { 1226 switch (instr->op()) {
1262 case Token::BIT_AND: 1227 case Token::BIT_AND:
1263 __ and_(ToRegister(left), right_operand); 1228 __ and_(ToRegister(left), right_operand);
1264 break; 1229 break;
1265 case Token::BIT_OR: 1230 case Token::BIT_OR:
(...skipping 19 matching lines...) Expand all
1285 break; 1250 break;
1286 default: 1251 default:
1287 UNREACHABLE(); 1252 UNREACHABLE();
1288 break; 1253 break;
1289 } 1254 }
1290 } 1255 }
1291 } 1256 }
1292 1257
1293 1258
1294 void LCodeGen::DoShiftI(LShiftI* instr) { 1259 void LCodeGen::DoShiftI(LShiftI* instr) {
1295 LOperand* left = instr->left(); 1260 LOperand* left = instr->InputAt(0);
1296 LOperand* right = instr->right(); 1261 LOperand* right = instr->InputAt(1);
1297 ASSERT(left->Equals(instr->result())); 1262 ASSERT(left->Equals(instr->result()));
1298 ASSERT(left->IsRegister()); 1263 ASSERT(left->IsRegister());
1299 if (right->IsRegister()) { 1264 if (right->IsRegister()) {
1300 ASSERT(ToRegister(right).is(ecx)); 1265 ASSERT(ToRegister(right).is(ecx));
1301 1266
1302 switch (instr->op()) { 1267 switch (instr->op()) {
1303 case Token::SAR: 1268 case Token::SAR:
1304 __ sar_cl(ToRegister(left)); 1269 __ sar_cl(ToRegister(left));
1305 break; 1270 break;
1306 case Token::SHR: 1271 case Token::SHR:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 break; 1306 break;
1342 default: 1307 default:
1343 UNREACHABLE(); 1308 UNREACHABLE();
1344 break; 1309 break;
1345 } 1310 }
1346 } 1311 }
1347 } 1312 }
1348 1313
1349 1314
1350 void LCodeGen::DoSubI(LSubI* instr) { 1315 void LCodeGen::DoSubI(LSubI* instr) {
1351 LOperand* left = instr->left(); 1316 LOperand* left = instr->InputAt(0);
1352 LOperand* right = instr->right(); 1317 LOperand* right = instr->InputAt(1);
1353 ASSERT(left->Equals(instr->result())); 1318 ASSERT(left->Equals(instr->result()));
1354 1319
1355 if (right->IsConstantOperand()) { 1320 if (right->IsConstantOperand()) {
1356 __ sub(ToOperand(left), ToInteger32Immediate(right)); 1321 __ sub(ToOperand(left), ToInteger32Immediate(right));
1357 } else { 1322 } else {
1358 __ sub(ToRegister(left), ToOperand(right)); 1323 __ sub(ToRegister(left), ToOperand(right));
1359 } 1324 }
1360 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1325 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1361 DeoptimizeIf(overflow, instr->environment()); 1326 DeoptimizeIf(overflow, instr->environment());
1362 } 1327 }
1363 } 1328 }
1364 1329
1365 1330
1366 void LCodeGen::DoConstantI(LConstantI* instr) { 1331 void LCodeGen::DoConstantI(LConstantI* instr) {
1367 ASSERT(instr->result()->IsRegister()); 1332 ASSERT(instr->result()->IsRegister());
1368 __ Set(ToRegister(instr->result()), Immediate(instr->value())); 1333 __ Set(ToRegister(instr->result()), Immediate(instr->value()));
1369 } 1334 }
1370 1335
1371 1336
1372 void LCodeGen::DoConstantD(LConstantD* instr) { 1337 void LCodeGen::DoConstantD(LConstantD* instr) {
1373 ASSERT(instr->result()->IsDoubleRegister()); 1338 ASSERT(instr->result()->IsDoubleRegister());
1374 XMMRegister res = ToDoubleRegister(instr->result()); 1339 XMMRegister res = ToDoubleRegister(instr->result());
1375 double v = instr->value(); 1340 double v = instr->value();
1376 // Use xor to produce +0.0 in a fast and compact way, but avoid to 1341 // Use xor to produce +0.0 in a fast and compact way, but avoid to
1377 // do so if the constant is -0.0. 1342 // do so if the constant is -0.0.
1378 if (BitCast<uint64_t, double>(v) == 0) { 1343 if (BitCast<uint64_t, double>(v) == 0) {
1379 __ xorps(res, res); 1344 __ xorps(res, res);
1380 } else { 1345 } else {
1381 Register temp = ToRegister(instr->temp()); 1346 Register temp = ToRegister(instr->TempAt(0));
1382 uint64_t int_val = BitCast<uint64_t, double>(v); 1347 uint64_t int_val = BitCast<uint64_t, double>(v);
1383 int32_t lower = static_cast<int32_t>(int_val); 1348 int32_t lower = static_cast<int32_t>(int_val);
1384 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); 1349 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
1385 if (CpuFeatures::IsSupported(SSE4_1)) { 1350 if (CpuFeatures::IsSupported(SSE4_1)) {
1386 CpuFeatures::Scope scope(SSE4_1); 1351 CpuFeatures::Scope scope(SSE4_1);
1387 if (lower != 0) { 1352 if (lower != 0) {
1388 __ Set(temp, Immediate(lower)); 1353 __ Set(temp, Immediate(lower));
1389 __ movd(res, Operand(temp)); 1354 __ movd(res, Operand(temp));
1390 __ Set(temp, Immediate(upper)); 1355 __ Set(temp, Immediate(upper));
1391 __ pinsrd(res, Operand(temp), 1); 1356 __ pinsrd(res, Operand(temp), 1);
(...skipping 22 matching lines...) Expand all
1414 if (handle->IsHeapObject()) { 1379 if (handle->IsHeapObject()) {
1415 __ LoadHeapObject(reg, Handle<HeapObject>::cast(handle)); 1380 __ LoadHeapObject(reg, Handle<HeapObject>::cast(handle));
1416 } else { 1381 } else {
1417 __ Set(reg, Immediate(handle)); 1382 __ Set(reg, Immediate(handle));
1418 } 1383 }
1419 } 1384 }
1420 1385
1421 1386
1422 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1387 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1423 Register result = ToRegister(instr->result()); 1388 Register result = ToRegister(instr->result());
1424 Register array = ToRegister(instr->value()); 1389 Register array = ToRegister(instr->InputAt(0));
1425 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); 1390 __ mov(result, FieldOperand(array, JSArray::kLengthOffset));
1426 } 1391 }
1427 1392
1428 1393
1429 void LCodeGen::DoFixedArrayBaseLength( 1394 void LCodeGen::DoFixedArrayBaseLength(
1430 LFixedArrayBaseLength* instr) { 1395 LFixedArrayBaseLength* instr) {
1431 Register result = ToRegister(instr->result()); 1396 Register result = ToRegister(instr->result());
1432 Register array = ToRegister(instr->value()); 1397 Register array = ToRegister(instr->InputAt(0));
1433 __ mov(result, FieldOperand(array, FixedArrayBase::kLengthOffset)); 1398 __ mov(result, FieldOperand(array, FixedArrayBase::kLengthOffset));
1434 } 1399 }
1435 1400
1436 1401
1437 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1402 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1438 Register result = ToRegister(instr->result()); 1403 Register result = ToRegister(instr->result());
1439 Register map = ToRegister(instr->value()); 1404 Register map = ToRegister(instr->InputAt(0));
1440 __ EnumLength(result, map); 1405 __ EnumLength(result, map);
1441 } 1406 }
1442 1407
1443 1408
1444 void LCodeGen::DoElementsKind(LElementsKind* instr) { 1409 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1445 Register result = ToRegister(instr->result()); 1410 Register result = ToRegister(instr->result());
1446 Register input = ToRegister(instr->value()); 1411 Register input = ToRegister(instr->InputAt(0));
1447 1412
1448 // Load map into |result|. 1413 // Load map into |result|.
1449 __ mov(result, FieldOperand(input, HeapObject::kMapOffset)); 1414 __ mov(result, FieldOperand(input, HeapObject::kMapOffset));
1450 // Load the map's "bit field 2" into |result|. We only need the first byte, 1415 // Load the map's "bit field 2" into |result|. We only need the first byte,
1451 // but the following masking takes care of that anyway. 1416 // but the following masking takes care of that anyway.
1452 __ mov(result, FieldOperand(result, Map::kBitField2Offset)); 1417 __ mov(result, FieldOperand(result, Map::kBitField2Offset));
1453 // Retrieve elements_kind from bit field 2. 1418 // Retrieve elements_kind from bit field 2.
1454 __ and_(result, Map::kElementsKindMask); 1419 __ and_(result, Map::kElementsKindMask);
1455 __ shr(result, Map::kElementsKindShift); 1420 __ shr(result, Map::kElementsKindShift);
1456 } 1421 }
1457 1422
1458 1423
1459 void LCodeGen::DoValueOf(LValueOf* instr) { 1424 void LCodeGen::DoValueOf(LValueOf* instr) {
1460 Register input = ToRegister(instr->value()); 1425 Register input = ToRegister(instr->InputAt(0));
1461 Register result = ToRegister(instr->result()); 1426 Register result = ToRegister(instr->result());
1462 Register map = ToRegister(instr->temp()); 1427 Register map = ToRegister(instr->TempAt(0));
1463 ASSERT(input.is(result)); 1428 ASSERT(input.is(result));
1464 1429
1465 Label done; 1430 Label done;
1466 // If the object is a smi return the object. 1431 // If the object is a smi return the object.
1467 __ JumpIfSmi(input, &done, Label::kNear); 1432 __ JumpIfSmi(input, &done, Label::kNear);
1468 1433
1469 // If the object is not a value type, return the object. 1434 // If the object is not a value type, return the object.
1470 __ CmpObjectType(input, JS_VALUE_TYPE, map); 1435 __ CmpObjectType(input, JS_VALUE_TYPE, map);
1471 __ j(not_equal, &done, Label::kNear); 1436 __ j(not_equal, &done, Label::kNear);
1472 __ mov(result, FieldOperand(input, JSValue::kValueOffset)); 1437 __ mov(result, FieldOperand(input, JSValue::kValueOffset));
1473 1438
1474 __ bind(&done); 1439 __ bind(&done);
1475 } 1440 }
1476 1441
1477 1442
1478 void LCodeGen::DoDateField(LDateField* instr) { 1443 void LCodeGen::DoDateField(LDateField* instr) {
1479 Register object = ToRegister(instr->date()); 1444 Register object = ToRegister(instr->InputAt(0));
1480 Register result = ToRegister(instr->result()); 1445 Register result = ToRegister(instr->result());
1481 Register scratch = ToRegister(instr->temp()); 1446 Register scratch = ToRegister(instr->TempAt(0));
1482 Smi* index = instr->index(); 1447 Smi* index = instr->index();
1483 Label runtime, done; 1448 Label runtime, done;
1484 ASSERT(object.is(result)); 1449 ASSERT(object.is(result));
1485 ASSERT(object.is(eax)); 1450 ASSERT(object.is(eax));
1486 1451
1487 __ test(object, Immediate(kSmiTagMask)); 1452 __ test(object, Immediate(kSmiTagMask));
1488 DeoptimizeIf(zero, instr->environment()); 1453 DeoptimizeIf(zero, instr->environment());
1489 __ CmpObjectType(object, JS_DATE_TYPE, scratch); 1454 __ CmpObjectType(object, JS_DATE_TYPE, scratch);
1490 DeoptimizeIf(not_equal, instr->environment()); 1455 DeoptimizeIf(not_equal, instr->environment());
1491 1456
(...skipping 13 matching lines...) Expand all
1505 __ PrepareCallCFunction(2, scratch); 1470 __ PrepareCallCFunction(2, scratch);
1506 __ mov(Operand(esp, 0), object); 1471 __ mov(Operand(esp, 0), object);
1507 __ mov(Operand(esp, 1 * kPointerSize), Immediate(index)); 1472 __ mov(Operand(esp, 1 * kPointerSize), Immediate(index));
1508 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 1473 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
1509 __ bind(&done); 1474 __ bind(&done);
1510 } 1475 }
1511 } 1476 }
1512 1477
1513 1478
1514 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1479 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1515 LOperand* input = instr->value(); 1480 LOperand* input = instr->InputAt(0);
1516 ASSERT(input->Equals(instr->result())); 1481 ASSERT(input->Equals(instr->result()));
1517 __ not_(ToRegister(input)); 1482 __ not_(ToRegister(input));
1518 } 1483 }
1519 1484
1520 1485
1521 void LCodeGen::DoThrow(LThrow* instr) { 1486 void LCodeGen::DoThrow(LThrow* instr) {
1522 __ push(ToOperand(instr->value())); 1487 __ push(ToOperand(instr->value()));
1523 ASSERT(ToRegister(instr->context()).is(esi)); 1488 ASSERT(ToRegister(instr->context()).is(esi));
1524 CallRuntime(Runtime::kThrow, 1, instr); 1489 CallRuntime(Runtime::kThrow, 1, instr);
1525 1490
1526 if (FLAG_debug_code) { 1491 if (FLAG_debug_code) {
1527 Comment("Unreachable code."); 1492 Comment("Unreachable code.");
1528 __ int3(); 1493 __ int3();
1529 } 1494 }
1530 } 1495 }
1531 1496
1532 1497
1533 void LCodeGen::DoAddI(LAddI* instr) { 1498 void LCodeGen::DoAddI(LAddI* instr) {
1534 LOperand* left = instr->left(); 1499 LOperand* left = instr->InputAt(0);
1535 LOperand* right = instr->right(); 1500 LOperand* right = instr->InputAt(1);
1536 ASSERT(left->Equals(instr->result())); 1501 ASSERT(left->Equals(instr->result()));
1537 1502
1538 if (right->IsConstantOperand()) { 1503 if (right->IsConstantOperand()) {
1539 __ add(ToOperand(left), ToInteger32Immediate(right)); 1504 __ add(ToOperand(left), ToInteger32Immediate(right));
1540 } else { 1505 } else {
1541 __ add(ToRegister(left), ToOperand(right)); 1506 __ add(ToRegister(left), ToOperand(right));
1542 } 1507 }
1543 1508
1544 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1509 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1545 DeoptimizeIf(overflow, instr->environment()); 1510 DeoptimizeIf(overflow, instr->environment());
1546 } 1511 }
1547 } 1512 }
1548 1513
1549 1514
1550 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1515 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1551 LOperand* left = instr->left(); 1516 LOperand* left = instr->InputAt(0);
1552 LOperand* right = instr->right(); 1517 LOperand* right = instr->InputAt(1);
1553 ASSERT(left->Equals(instr->result())); 1518 ASSERT(left->Equals(instr->result()));
1554 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1519 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1555 if (instr->hydrogen()->representation().IsInteger32()) { 1520 if (instr->hydrogen()->representation().IsInteger32()) {
1556 Label return_left; 1521 Label return_left;
1557 Condition condition = (operation == HMathMinMax::kMathMin) 1522 Condition condition = (operation == HMathMinMax::kMathMin)
1558 ? less_equal 1523 ? less_equal
1559 : greater_equal; 1524 : greater_equal;
1560 if (right->IsConstantOperand()) { 1525 if (right->IsConstantOperand()) {
1561 Operand left_op = ToOperand(left); 1526 Operand left_op = ToOperand(left);
1562 Immediate right_imm = ToInteger32Immediate(right); 1527 Immediate right_imm = ToInteger32Immediate(right);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 __ j(parity_even, &return_left, Label::kNear); // left == NaN. 1567 __ j(parity_even, &return_left, Label::kNear); // left == NaN.
1603 __ bind(&return_right); 1568 __ bind(&return_right);
1604 __ movsd(left_reg, right_reg); 1569 __ movsd(left_reg, right_reg);
1605 1570
1606 __ bind(&return_left); 1571 __ bind(&return_left);
1607 } 1572 }
1608 } 1573 }
1609 1574
1610 1575
1611 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1576 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1612 XMMRegister left = ToDoubleRegister(instr->left()); 1577 XMMRegister left = ToDoubleRegister(instr->InputAt(0));
1613 XMMRegister right = ToDoubleRegister(instr->right()); 1578 XMMRegister right = ToDoubleRegister(instr->InputAt(1));
1614 XMMRegister result = ToDoubleRegister(instr->result()); 1579 XMMRegister result = ToDoubleRegister(instr->result());
1615 // Modulo uses a fixed result register. 1580 // Modulo uses a fixed result register.
1616 ASSERT(instr->op() == Token::MOD || left.is(result)); 1581 ASSERT(instr->op() == Token::MOD || left.is(result));
1617 switch (instr->op()) { 1582 switch (instr->op()) {
1618 case Token::ADD: 1583 case Token::ADD:
1619 __ addsd(left, right); 1584 __ addsd(left, right);
1620 break; 1585 break;
1621 case Token::SUB: 1586 case Token::SUB:
1622 __ subsd(left, right); 1587 __ subsd(left, right);
1623 break; 1588 break;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 } 1654 }
1690 } 1655 }
1691 1656
1692 1657
1693 void LCodeGen::DoBranch(LBranch* instr) { 1658 void LCodeGen::DoBranch(LBranch* instr) {
1694 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1659 int true_block = chunk_->LookupDestination(instr->true_block_id());
1695 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1660 int false_block = chunk_->LookupDestination(instr->false_block_id());
1696 1661
1697 Representation r = instr->hydrogen()->value()->representation(); 1662 Representation r = instr->hydrogen()->value()->representation();
1698 if (r.IsInteger32()) { 1663 if (r.IsInteger32()) {
1699 Register reg = ToRegister(instr->value()); 1664 Register reg = ToRegister(instr->InputAt(0));
1700 __ test(reg, Operand(reg)); 1665 __ test(reg, Operand(reg));
1701 EmitBranch(true_block, false_block, not_zero); 1666 EmitBranch(true_block, false_block, not_zero);
1702 } else if (r.IsDouble()) { 1667 } else if (r.IsDouble()) {
1703 XMMRegister reg = ToDoubleRegister(instr->value()); 1668 XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
1704 __ xorps(xmm0, xmm0); 1669 __ xorps(xmm0, xmm0);
1705 __ ucomisd(reg, xmm0); 1670 __ ucomisd(reg, xmm0);
1706 EmitBranch(true_block, false_block, not_equal); 1671 EmitBranch(true_block, false_block, not_equal);
1707 } else { 1672 } else {
1708 ASSERT(r.IsTagged()); 1673 ASSERT(r.IsTagged());
1709 Register reg = ToRegister(instr->value()); 1674 Register reg = ToRegister(instr->InputAt(0));
1710 HType type = instr->hydrogen()->value()->type(); 1675 HType type = instr->hydrogen()->value()->type();
1711 if (type.IsBoolean()) { 1676 if (type.IsBoolean()) {
1712 __ cmp(reg, factory()->true_value()); 1677 __ cmp(reg, factory()->true_value());
1713 EmitBranch(true_block, false_block, equal); 1678 EmitBranch(true_block, false_block, equal);
1714 } else if (type.IsSmi()) { 1679 } else if (type.IsSmi()) {
1715 __ test(reg, Operand(reg)); 1680 __ test(reg, Operand(reg));
1716 EmitBranch(true_block, false_block, not_equal); 1681 EmitBranch(true_block, false_block, not_equal);
1717 } else { 1682 } else {
1718 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1683 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1719 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1684 Label* false_label = chunk_->GetAssemblyLabel(false_block);
(...skipping 27 matching lines...) Expand all
1747 __ j(equal, false_label); 1712 __ j(equal, false_label);
1748 __ JumpIfSmi(reg, true_label); 1713 __ JumpIfSmi(reg, true_label);
1749 } else if (expected.NeedsMap()) { 1714 } else if (expected.NeedsMap()) {
1750 // If we need a map later and have a Smi -> deopt. 1715 // If we need a map later and have a Smi -> deopt.
1751 __ test(reg, Immediate(kSmiTagMask)); 1716 __ test(reg, Immediate(kSmiTagMask));
1752 DeoptimizeIf(zero, instr->environment()); 1717 DeoptimizeIf(zero, instr->environment());
1753 } 1718 }
1754 1719
1755 Register map = no_reg; // Keep the compiler happy. 1720 Register map = no_reg; // Keep the compiler happy.
1756 if (expected.NeedsMap()) { 1721 if (expected.NeedsMap()) {
1757 map = ToRegister(instr->temp()); 1722 map = ToRegister(instr->TempAt(0));
1758 ASSERT(!map.is(reg)); 1723 ASSERT(!map.is(reg));
1759 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset)); 1724 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset));
1760 1725
1761 if (expected.CanBeUndetectable()) { 1726 if (expected.CanBeUndetectable()) {
1762 // Undetectable -> false. 1727 // Undetectable -> false.
1763 __ test_b(FieldOperand(map, Map::kBitFieldOffset), 1728 __ test_b(FieldOperand(map, Map::kBitFieldOffset),
1764 1 << Map::kIsUndetectable); 1729 1 << Map::kIsUndetectable);
1765 __ j(not_zero, false_label); 1730 __ j(not_zero, false_label);
1766 } 1731 }
1767 } 1732 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 case Token::IN: 1805 case Token::IN:
1841 case Token::INSTANCEOF: 1806 case Token::INSTANCEOF:
1842 default: 1807 default:
1843 UNREACHABLE(); 1808 UNREACHABLE();
1844 } 1809 }
1845 return cond; 1810 return cond;
1846 } 1811 }
1847 1812
1848 1813
1849 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1814 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
1850 LOperand* left = instr->left(); 1815 LOperand* left = instr->InputAt(0);
1851 LOperand* right = instr->right(); 1816 LOperand* right = instr->InputAt(1);
1852 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1817 int false_block = chunk_->LookupDestination(instr->false_block_id());
1853 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1818 int true_block = chunk_->LookupDestination(instr->true_block_id());
1854 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1819 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1855 1820
1856 if (left->IsConstantOperand() && right->IsConstantOperand()) { 1821 if (left->IsConstantOperand() && right->IsConstantOperand()) {
1857 // We can statically evaluate the comparison. 1822 // We can statically evaluate the comparison.
1858 double left_val = ToDouble(LConstantOperand::cast(left)); 1823 double left_val = ToDouble(LConstantOperand::cast(left));
1859 double right_val = ToDouble(LConstantOperand::cast(right)); 1824 double right_val = ToDouble(LConstantOperand::cast(right));
1860 int next_block = 1825 int next_block =
1861 EvalComparison(instr->op(), left_val, right_val) ? true_block 1826 EvalComparison(instr->op(), left_val, right_val) ? true_block
(...skipping 15 matching lines...) Expand all
1877 } else { 1842 } else {
1878 __ cmp(ToRegister(left), ToOperand(right)); 1843 __ cmp(ToRegister(left), ToOperand(right));
1879 } 1844 }
1880 } 1845 }
1881 EmitBranch(true_block, false_block, cc); 1846 EmitBranch(true_block, false_block, cc);
1882 } 1847 }
1883 } 1848 }
1884 1849
1885 1850
1886 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 1851 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
1887 Register left = ToRegister(instr->left()); 1852 Register left = ToRegister(instr->InputAt(0));
1888 Operand right = ToOperand(instr->right()); 1853 Operand right = ToOperand(instr->InputAt(1));
1889 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1854 int false_block = chunk_->LookupDestination(instr->false_block_id());
1890 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1855 int true_block = chunk_->LookupDestination(instr->true_block_id());
1891 1856
1892 __ cmp(left, Operand(right)); 1857 __ cmp(left, Operand(right));
1893 EmitBranch(true_block, false_block, equal); 1858 EmitBranch(true_block, false_block, equal);
1894 } 1859 }
1895 1860
1896 1861
1897 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 1862 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
1898 Register left = ToRegister(instr->left()); 1863 Register left = ToRegister(instr->InputAt(0));
1899 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1864 int true_block = chunk_->LookupDestination(instr->true_block_id());
1900 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1865 int false_block = chunk_->LookupDestination(instr->false_block_id());
1901 1866
1902 __ cmp(left, instr->hydrogen()->right()); 1867 __ cmp(left, instr->hydrogen()->right());
1903 EmitBranch(true_block, false_block, equal); 1868 EmitBranch(true_block, false_block, equal);
1904 } 1869 }
1905 1870
1906 1871
1907 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) { 1872 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
1908 Register reg = ToRegister(instr->value()); 1873 Register reg = ToRegister(instr->InputAt(0));
1909 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1874 int false_block = chunk_->LookupDestination(instr->false_block_id());
1910 1875
1911 // If the expression is known to be untagged or a smi, then it's definitely 1876 // If the expression is known to be untagged or a smi, then it's definitely
1912 // not null, and it can't be a an undetectable object. 1877 // not null, and it can't be a an undetectable object.
1913 if (instr->hydrogen()->representation().IsSpecialization() || 1878 if (instr->hydrogen()->representation().IsSpecialization() ||
1914 instr->hydrogen()->type().IsSmi()) { 1879 instr->hydrogen()->type().IsSmi()) {
1915 EmitGoto(false_block); 1880 EmitGoto(false_block);
1916 return; 1881 return;
1917 } 1882 }
1918 1883
1919 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1884 int true_block = chunk_->LookupDestination(instr->true_block_id());
1920 Handle<Object> nil_value = instr->nil() == kNullValue ? 1885 Handle<Object> nil_value = instr->nil() == kNullValue ?
1921 factory()->null_value() : 1886 factory()->null_value() :
1922 factory()->undefined_value(); 1887 factory()->undefined_value();
1923 __ cmp(reg, nil_value); 1888 __ cmp(reg, nil_value);
1924 if (instr->kind() == kStrictEquality) { 1889 if (instr->kind() == kStrictEquality) {
1925 EmitBranch(true_block, false_block, equal); 1890 EmitBranch(true_block, false_block, equal);
1926 } else { 1891 } else {
1927 Handle<Object> other_nil_value = instr->nil() == kNullValue ? 1892 Handle<Object> other_nil_value = instr->nil() == kNullValue ?
1928 factory()->undefined_value() : 1893 factory()->undefined_value() :
1929 factory()->null_value(); 1894 factory()->null_value();
1930 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1895 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1931 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1896 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1932 __ j(equal, true_label); 1897 __ j(equal, true_label);
1933 __ cmp(reg, other_nil_value); 1898 __ cmp(reg, other_nil_value);
1934 __ j(equal, true_label); 1899 __ j(equal, true_label);
1935 __ JumpIfSmi(reg, false_label); 1900 __ JumpIfSmi(reg, false_label);
1936 // Check for undetectable objects by looking in the bit field in 1901 // Check for undetectable objects by looking in the bit field in
1937 // the map. The object has already been smi checked. 1902 // the map. The object has already been smi checked.
1938 Register scratch = ToRegister(instr->temp()); 1903 Register scratch = ToRegister(instr->TempAt(0));
1939 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); 1904 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1940 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); 1905 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
1941 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); 1906 __ test(scratch, Immediate(1 << Map::kIsUndetectable));
1942 EmitBranch(true_block, false_block, not_zero); 1907 EmitBranch(true_block, false_block, not_zero);
1943 } 1908 }
1944 } 1909 }
1945 1910
1946 1911
1947 Condition LCodeGen::EmitIsObject(Register input, 1912 Condition LCodeGen::EmitIsObject(Register input,
1948 Register temp1, 1913 Register temp1,
(...skipping 12 matching lines...) Expand all
1961 1926
1962 __ movzx_b(temp1, FieldOperand(temp1, Map::kInstanceTypeOffset)); 1927 __ movzx_b(temp1, FieldOperand(temp1, Map::kInstanceTypeOffset));
1963 __ cmp(temp1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 1928 __ cmp(temp1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
1964 __ j(below, is_not_object); 1929 __ j(below, is_not_object);
1965 __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 1930 __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
1966 return below_equal; 1931 return below_equal;
1967 } 1932 }
1968 1933
1969 1934
1970 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1935 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1971 Register reg = ToRegister(instr->value()); 1936 Register reg = ToRegister(instr->InputAt(0));
1972 Register temp = ToRegister(instr->temp()); 1937 Register temp = ToRegister(instr->TempAt(0));
1973 1938
1974 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1939 int true_block = chunk_->LookupDestination(instr->true_block_id());
1975 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1940 int false_block = chunk_->LookupDestination(instr->false_block_id());
1976 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1941 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1977 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1942 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1978 1943
1979 Condition true_cond = EmitIsObject(reg, temp, false_label, true_label); 1944 Condition true_cond = EmitIsObject(reg, temp, false_label, true_label);
1980 1945
1981 EmitBranch(true_block, false_block, true_cond); 1946 EmitBranch(true_block, false_block, true_cond);
1982 } 1947 }
1983 1948
1984 1949
1985 Condition LCodeGen::EmitIsString(Register input, 1950 Condition LCodeGen::EmitIsString(Register input,
1986 Register temp1, 1951 Register temp1,
1987 Label* is_not_string) { 1952 Label* is_not_string) {
1988 __ JumpIfSmi(input, is_not_string); 1953 __ JumpIfSmi(input, is_not_string);
1989 1954
1990 Condition cond = masm_->IsObjectStringType(input, temp1, temp1); 1955 Condition cond = masm_->IsObjectStringType(input, temp1, temp1);
1991 1956
1992 return cond; 1957 return cond;
1993 } 1958 }
1994 1959
1995 1960
1996 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 1961 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
1997 Register reg = ToRegister(instr->value()); 1962 Register reg = ToRegister(instr->InputAt(0));
1998 Register temp = ToRegister(instr->temp()); 1963 Register temp = ToRegister(instr->TempAt(0));
1999 1964
2000 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1965 int true_block = chunk_->LookupDestination(instr->true_block_id());
2001 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1966 int false_block = chunk_->LookupDestination(instr->false_block_id());
2002 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1967 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2003 1968
2004 Condition true_cond = EmitIsString(reg, temp, false_label); 1969 Condition true_cond = EmitIsString(reg, temp, false_label);
2005 1970
2006 EmitBranch(true_block, false_block, true_cond); 1971 EmitBranch(true_block, false_block, true_cond);
2007 } 1972 }
2008 1973
2009 1974
2010 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 1975 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2011 Operand input = ToOperand(instr->value()); 1976 Operand input = ToOperand(instr->InputAt(0));
2012 1977
2013 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1978 int true_block = chunk_->LookupDestination(instr->true_block_id());
2014 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1979 int false_block = chunk_->LookupDestination(instr->false_block_id());
2015 1980
2016 __ test(input, Immediate(kSmiTagMask)); 1981 __ test(input, Immediate(kSmiTagMask));
2017 EmitBranch(true_block, false_block, zero); 1982 EmitBranch(true_block, false_block, zero);
2018 } 1983 }
2019 1984
2020 1985
2021 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 1986 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2022 Register input = ToRegister(instr->value()); 1987 Register input = ToRegister(instr->InputAt(0));
2023 Register temp = ToRegister(instr->temp()); 1988 Register temp = ToRegister(instr->TempAt(0));
2024 1989
2025 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1990 int true_block = chunk_->LookupDestination(instr->true_block_id());
2026 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1991 int false_block = chunk_->LookupDestination(instr->false_block_id());
2027 1992
2028 STATIC_ASSERT(kSmiTag == 0); 1993 STATIC_ASSERT(kSmiTag == 0);
2029 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 1994 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
2030 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 1995 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
2031 __ test_b(FieldOperand(temp, Map::kBitFieldOffset), 1996 __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
2032 1 << Map::kIsUndetectable); 1997 1 << Map::kIsUndetectable);
2033 EmitBranch(true_block, false_block, not_zero); 1998 EmitBranch(true_block, false_block, not_zero);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2083 InstanceType to = instr->to(); 2048 InstanceType to = instr->to();
2084 if (from == to) return equal; 2049 if (from == to) return equal;
2085 if (to == LAST_TYPE) return above_equal; 2050 if (to == LAST_TYPE) return above_equal;
2086 if (from == FIRST_TYPE) return below_equal; 2051 if (from == FIRST_TYPE) return below_equal;
2087 UNREACHABLE(); 2052 UNREACHABLE();
2088 return equal; 2053 return equal;
2089 } 2054 }
2090 2055
2091 2056
2092 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2057 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2093 Register input = ToRegister(instr->value()); 2058 Register input = ToRegister(instr->InputAt(0));
2094 Register temp = ToRegister(instr->temp()); 2059 Register temp = ToRegister(instr->TempAt(0));
2095 2060
2096 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2061 int true_block = chunk_->LookupDestination(instr->true_block_id());
2097 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2062 int false_block = chunk_->LookupDestination(instr->false_block_id());
2098 2063
2099 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2064 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2100 2065
2101 __ JumpIfSmi(input, false_label); 2066 __ JumpIfSmi(input, false_label);
2102 2067
2103 __ CmpObjectType(input, TestType(instr->hydrogen()), temp); 2068 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
2104 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 2069 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
2105 } 2070 }
2106 2071
2107 2072
2108 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2073 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2109 Register input = ToRegister(instr->value()); 2074 Register input = ToRegister(instr->InputAt(0));
2110 Register result = ToRegister(instr->result()); 2075 Register result = ToRegister(instr->result());
2111 2076
2112 __ AbortIfNotString(input); 2077 __ AbortIfNotString(input);
2113 2078
2114 __ mov(result, FieldOperand(input, String::kHashFieldOffset)); 2079 __ mov(result, FieldOperand(input, String::kHashFieldOffset));
2115 __ IndexFromHash(result, result); 2080 __ IndexFromHash(result, result);
2116 } 2081 }
2117 2082
2118 2083
2119 void LCodeGen::DoHasCachedArrayIndexAndBranch( 2084 void LCodeGen::DoHasCachedArrayIndexAndBranch(
2120 LHasCachedArrayIndexAndBranch* instr) { 2085 LHasCachedArrayIndexAndBranch* instr) {
2121 Register input = ToRegister(instr->value()); 2086 Register input = ToRegister(instr->InputAt(0));
2122 2087
2123 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2088 int true_block = chunk_->LookupDestination(instr->true_block_id());
2124 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2089 int false_block = chunk_->LookupDestination(instr->false_block_id());
2125 2090
2126 __ test(FieldOperand(input, String::kHashFieldOffset), 2091 __ test(FieldOperand(input, String::kHashFieldOffset),
2127 Immediate(String::kContainsCachedArrayIndexMask)); 2092 Immediate(String::kContainsCachedArrayIndexMask));
2128 EmitBranch(true_block, false_block, equal); 2093 EmitBranch(true_block, false_block, equal);
2129 } 2094 }
2130 2095
2131 2096
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2188 // booted. This routine isn't expected to work for random API-created 2153 // booted. This routine isn't expected to work for random API-created
2189 // classes and it doesn't have to because you can't access it with natives 2154 // classes and it doesn't have to because you can't access it with natives
2190 // syntax. Since both sides are symbols it is sufficient to use an identity 2155 // syntax. Since both sides are symbols it is sufficient to use an identity
2191 // comparison. 2156 // comparison.
2192 __ cmp(temp, class_name); 2157 __ cmp(temp, class_name);
2193 // End with the answer in the z flag. 2158 // End with the answer in the z flag.
2194 } 2159 }
2195 2160
2196 2161
2197 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2162 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2198 Register input = ToRegister(instr->value()); 2163 Register input = ToRegister(instr->InputAt(0));
2199 Register temp = ToRegister(instr->temp()); 2164 Register temp = ToRegister(instr->TempAt(0));
2200 Register temp2 = ToRegister(instr->temp2()); 2165 Register temp2 = ToRegister(instr->TempAt(1));
2201 2166
2202 Handle<String> class_name = instr->hydrogen()->class_name(); 2167 Handle<String> class_name = instr->hydrogen()->class_name();
2203 2168
2204 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2169 int true_block = chunk_->LookupDestination(instr->true_block_id());
2205 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2170 int false_block = chunk_->LookupDestination(instr->false_block_id());
2206 2171
2207 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2172 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2208 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2173 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2209 2174
2210 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 2175 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
2211 2176
2212 EmitBranch(true_block, false_block, equal); 2177 EmitBranch(true_block, false_block, equal);
2213 } 2178 }
2214 2179
2215 2180
2216 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2181 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2217 Register reg = ToRegister(instr->value()); 2182 Register reg = ToRegister(instr->InputAt(0));
2218 int true_block = instr->true_block_id(); 2183 int true_block = instr->true_block_id();
2219 int false_block = instr->false_block_id(); 2184 int false_block = instr->false_block_id();
2220 2185
2221 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 2186 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2222 EmitBranch(true_block, false_block, equal); 2187 EmitBranch(true_block, false_block, equal);
2223 } 2188 }
2224 2189
2225 2190
2226 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2191 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2227 // Object and function are in fixed registers defined by the stub. 2192 // Object and function are in fixed registers defined by the stub.
(...skipping 25 matching lines...) Expand all
2253 Label* map_check() { return &map_check_; } 2218 Label* map_check() { return &map_check_; }
2254 private: 2219 private:
2255 LInstanceOfKnownGlobal* instr_; 2220 LInstanceOfKnownGlobal* instr_;
2256 Label map_check_; 2221 Label map_check_;
2257 }; 2222 };
2258 2223
2259 DeferredInstanceOfKnownGlobal* deferred; 2224 DeferredInstanceOfKnownGlobal* deferred;
2260 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 2225 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2261 2226
2262 Label done, false_result; 2227 Label done, false_result;
2263 Register object = ToRegister(instr->value()); 2228 Register object = ToRegister(instr->InputAt(1));
2264 Register temp = ToRegister(instr->temp()); 2229 Register temp = ToRegister(instr->TempAt(0));
2265 2230
2266 // A Smi is not an instance of anything. 2231 // A Smi is not an instance of anything.
2267 __ JumpIfSmi(object, &false_result); 2232 __ JumpIfSmi(object, &false_result);
2268 2233
2269 // This is the inlined call site instanceof cache. The two occurences of the 2234 // This is the inlined call site instanceof cache. The two occurences of the
2270 // hole value will be patched to the last map/result pair generated by the 2235 // hole value will be patched to the last map/result pair generated by the
2271 // instanceof stub. 2236 // instanceof stub.
2272 Label cache_miss; 2237 Label cache_miss;
2273 Register map = ToRegister(instr->temp()); 2238 Register map = ToRegister(instr->TempAt(0));
2274 __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); 2239 __ mov(map, FieldOperand(object, HeapObject::kMapOffset));
2275 __ bind(deferred->map_check()); // Label for calculating code patching. 2240 __ bind(deferred->map_check()); // Label for calculating code patching.
2276 Handle<JSGlobalPropertyCell> cache_cell = 2241 Handle<JSGlobalPropertyCell> cache_cell =
2277 factory()->NewJSGlobalPropertyCell(factory()->the_hole_value()); 2242 factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
2278 __ cmp(map, Operand::Cell(cache_cell)); // Patched to cached map. 2243 __ cmp(map, Operand::Cell(cache_cell)); // Patched to cached map.
2279 __ j(not_equal, &cache_miss, Label::kNear); 2244 __ j(not_equal, &cache_miss, Label::kNear);
2280 __ mov(eax, factory()->the_hole_value()); // Patched to either true or false. 2245 __ mov(eax, factory()->the_hole_value()); // Patched to either true or false.
2281 __ jmp(&done); 2246 __ jmp(&done);
2282 2247
2283 // The inlined call site cache did not match. Check for null and string 2248 // The inlined call site cache did not match. Check for null and string
(...skipping 30 matching lines...) Expand all
2314 flags = static_cast<InstanceofStub::Flags>( 2279 flags = static_cast<InstanceofStub::Flags>(
2315 flags | InstanceofStub::kCallSiteInlineCheck); 2280 flags | InstanceofStub::kCallSiteInlineCheck);
2316 flags = static_cast<InstanceofStub::Flags>( 2281 flags = static_cast<InstanceofStub::Flags>(
2317 flags | InstanceofStub::kReturnTrueFalseObject); 2282 flags | InstanceofStub::kReturnTrueFalseObject);
2318 InstanceofStub stub(flags); 2283 InstanceofStub stub(flags);
2319 2284
2320 // Get the temp register reserved by the instruction. This needs to be a 2285 // Get the temp register reserved by the instruction. This needs to be a
2321 // register which is pushed last by PushSafepointRegisters as top of the 2286 // register which is pushed last by PushSafepointRegisters as top of the
2322 // stack is used to pass the offset to the location of the map check to 2287 // stack is used to pass the offset to the location of the map check to
2323 // the stub. 2288 // the stub.
2324 Register temp = ToRegister(instr->temp()); 2289 Register temp = ToRegister(instr->TempAt(0));
2325 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); 2290 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0);
2326 __ LoadHeapObject(InstanceofStub::right(), instr->function()); 2291 __ LoadHeapObject(InstanceofStub::right(), instr->function());
2327 static const int kAdditionalDelta = 13; 2292 static const int kAdditionalDelta = 13;
2328 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 2293 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
2329 __ mov(temp, Immediate(delta)); 2294 __ mov(temp, Immediate(delta));
2330 __ StoreToSafepointRegisterSlot(temp, temp); 2295 __ StoreToSafepointRegisterSlot(temp, temp);
2331 CallCodeGeneric(stub.GetCode(), 2296 CallCodeGeneric(stub.GetCode(),
2332 RelocInfo::CODE_TARGET, 2297 RelocInfo::CODE_TARGET,
2333 instr, 2298 instr,
2334 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 2299 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
2481 } else { 2446 } else {
2482 __ j(not_equal, &skip_assignment, Label::kNear); 2447 __ j(not_equal, &skip_assignment, Label::kNear);
2483 } 2448 }
2484 } 2449 }
2485 2450
2486 __ mov(target, value); 2451 __ mov(target, value);
2487 if (instr->hydrogen()->NeedsWriteBarrier()) { 2452 if (instr->hydrogen()->NeedsWriteBarrier()) {
2488 HType type = instr->hydrogen()->value()->type(); 2453 HType type = instr->hydrogen()->value()->type();
2489 SmiCheck check_needed = 2454 SmiCheck check_needed =
2490 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2455 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2491 Register temp = ToRegister(instr->temp()); 2456 Register temp = ToRegister(instr->TempAt(0));
2492 int offset = Context::SlotOffset(instr->slot_index()); 2457 int offset = Context::SlotOffset(instr->slot_index());
2493 __ RecordWriteContextSlot(context, 2458 __ RecordWriteContextSlot(context,
2494 offset, 2459 offset,
2495 value, 2460 value,
2496 temp, 2461 temp,
2497 kSaveFPRegs, 2462 kSaveFPRegs,
2498 EMIT_REMEMBERED_SET, 2463 EMIT_REMEMBERED_SET,
2499 check_needed); 2464 check_needed);
2500 } 2465 }
2501 2466
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2646 ASSERT(ToRegister(instr->result()).is(eax)); 2611 ASSERT(ToRegister(instr->result()).is(eax));
2647 2612
2648 __ mov(ecx, instr->name()); 2613 __ mov(ecx, instr->name());
2649 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2614 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2650 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2615 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2651 } 2616 }
2652 2617
2653 2618
2654 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 2619 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
2655 Register function = ToRegister(instr->function()); 2620 Register function = ToRegister(instr->function());
2656 Register temp = ToRegister(instr->temp()); 2621 Register temp = ToRegister(instr->TempAt(0));
2657 Register result = ToRegister(instr->result()); 2622 Register result = ToRegister(instr->result());
2658 2623
2659 // Check that the function really is a function. 2624 // Check that the function really is a function.
2660 __ CmpObjectType(function, JS_FUNCTION_TYPE, result); 2625 __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
2661 DeoptimizeIf(not_equal, instr->environment()); 2626 DeoptimizeIf(not_equal, instr->environment());
2662 2627
2663 // Check whether the function has an instance prototype. 2628 // Check whether the function has an instance prototype.
2664 Label non_instance; 2629 Label non_instance;
2665 __ test_b(FieldOperand(result, Map::kBitFieldOffset), 2630 __ test_b(FieldOperand(result, Map::kBitFieldOffset),
2666 1 << Map::kHasNonInstancePrototype); 2631 1 << Map::kHasNonInstancePrototype);
(...skipping 21 matching lines...) Expand all
2688 __ bind(&non_instance); 2653 __ bind(&non_instance);
2689 __ mov(result, FieldOperand(result, Map::kConstructorOffset)); 2654 __ mov(result, FieldOperand(result, Map::kConstructorOffset));
2690 2655
2691 // All done. 2656 // All done.
2692 __ bind(&done); 2657 __ bind(&done);
2693 } 2658 }
2694 2659
2695 2660
2696 void LCodeGen::DoLoadElements(LLoadElements* instr) { 2661 void LCodeGen::DoLoadElements(LLoadElements* instr) {
2697 Register result = ToRegister(instr->result()); 2662 Register result = ToRegister(instr->result());
2698 Register input = ToRegister(instr->object()); 2663 Register input = ToRegister(instr->InputAt(0));
2699 __ mov(result, FieldOperand(input, JSObject::kElementsOffset)); 2664 __ mov(result, FieldOperand(input, JSObject::kElementsOffset));
2700 if (FLAG_debug_code) { 2665 if (FLAG_debug_code) {
2701 Label done, ok, fail; 2666 Label done, ok, fail;
2702 __ cmp(FieldOperand(result, HeapObject::kMapOffset), 2667 __ cmp(FieldOperand(result, HeapObject::kMapOffset),
2703 Immediate(factory()->fixed_array_map())); 2668 Immediate(factory()->fixed_array_map()));
2704 __ j(equal, &done, Label::kNear); 2669 __ j(equal, &done, Label::kNear);
2705 __ cmp(FieldOperand(result, HeapObject::kMapOffset), 2670 __ cmp(FieldOperand(result, HeapObject::kMapOffset),
2706 Immediate(factory()->fixed_cow_array_map())); 2671 Immediate(factory()->fixed_cow_array_map()));
2707 __ j(equal, &done, Label::kNear); 2672 __ j(equal, &done, Label::kNear);
2708 Register temp((result.is(eax)) ? ebx : eax); 2673 Register temp((result.is(eax)) ? ebx : eax);
(...skipping 15 matching lines...) Expand all
2724 __ bind(&ok); 2689 __ bind(&ok);
2725 __ pop(temp); 2690 __ pop(temp);
2726 __ bind(&done); 2691 __ bind(&done);
2727 } 2692 }
2728 } 2693 }
2729 2694
2730 2695
2731 void LCodeGen::DoLoadExternalArrayPointer( 2696 void LCodeGen::DoLoadExternalArrayPointer(
2732 LLoadExternalArrayPointer* instr) { 2697 LLoadExternalArrayPointer* instr) {
2733 Register result = ToRegister(instr->result()); 2698 Register result = ToRegister(instr->result());
2734 Register input = ToRegister(instr->object()); 2699 Register input = ToRegister(instr->InputAt(0));
2735 __ mov(result, FieldOperand(input, 2700 __ mov(result, FieldOperand(input,
2736 ExternalArray::kExternalPointerOffset)); 2701 ExternalArray::kExternalPointerOffset));
2737 } 2702 }
2738 2703
2739 2704
2740 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2705 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2741 Register arguments = ToRegister(instr->arguments()); 2706 Register arguments = ToRegister(instr->arguments());
2742 Register length = ToRegister(instr->length()); 2707 Register length = ToRegister(instr->length());
2743 Operand index = ToOperand(instr->index()); 2708 Operand index = ToOperand(instr->index());
2744 Register result = ToRegister(instr->result()); 2709 Register result = ToRegister(instr->result());
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
2937 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2902 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2938 2903
2939 // Result is the frame pointer for the frame if not adapted and for the real 2904 // Result is the frame pointer for the frame if not adapted and for the real
2940 // frame below the adaptor frame if adapted. 2905 // frame below the adaptor frame if adapted.
2941 __ bind(&done); 2906 __ bind(&done);
2942 } 2907 }
2943 } 2908 }
2944 2909
2945 2910
2946 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 2911 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
2947 Operand elem = ToOperand(instr->elements()); 2912 Operand elem = ToOperand(instr->InputAt(0));
2948 Register result = ToRegister(instr->result()); 2913 Register result = ToRegister(instr->result());
2949 2914
2950 Label done; 2915 Label done;
2951 2916
2952 // If no arguments adaptor frame the number of arguments is fixed. 2917 // If no arguments adaptor frame the number of arguments is fixed.
2953 __ cmp(ebp, elem); 2918 __ cmp(ebp, elem);
2954 __ mov(result, Immediate(scope()->num_parameters())); 2919 __ mov(result, Immediate(scope()->num_parameters()));
2955 __ j(equal, &done, Label::kNear); 2920 __ j(equal, &done, Label::kNear);
2956 2921
2957 // Arguments adaptor frame present. Get argument length from there. 2922 // Arguments adaptor frame present. Get argument length from there.
2958 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2923 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2959 __ mov(result, Operand(result, 2924 __ mov(result, Operand(result,
2960 ArgumentsAdaptorFrameConstants::kLengthOffset)); 2925 ArgumentsAdaptorFrameConstants::kLengthOffset));
2961 __ SmiUntag(result); 2926 __ SmiUntag(result);
2962 2927
2963 // Argument length is in result register. 2928 // Argument length is in result register.
2964 __ bind(&done); 2929 __ bind(&done);
2965 } 2930 }
2966 2931
2967 2932
2968 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 2933 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
2969 Register receiver = ToRegister(instr->receiver()); 2934 Register receiver = ToRegister(instr->receiver());
2970 Register function = ToRegister(instr->function()); 2935 Register function = ToRegister(instr->function());
2971 Register scratch = ToRegister(instr->temp()); 2936 Register scratch = ToRegister(instr->TempAt(0));
2972 2937
2973 // If the receiver is null or undefined, we have to pass the global 2938 // If the receiver is null or undefined, we have to pass the global
2974 // object as a receiver to normal functions. Values have to be 2939 // object as a receiver to normal functions. Values have to be
2975 // passed unchanged to builtins and strict-mode functions. 2940 // passed unchanged to builtins and strict-mode functions.
2976 Label global_object, receiver_ok; 2941 Label global_object, receiver_ok;
2977 2942
2978 // Do not transform the receiver to object for strict mode 2943 // Do not transform the receiver to object for strict mode
2979 // functions. 2944 // functions.
2980 __ mov(scratch, 2945 __ mov(scratch,
2981 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 2946 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
2982 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset), 2947 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset),
2983 1 << SharedFunctionInfo::kStrictModeBitWithinByte); 2948 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
2984 __ j(not_equal, &receiver_ok); // A near jump is not sufficient here! 2949 __ j(not_equal, &receiver_ok, Label::kNear);
2985 2950
2986 // Do not transform the receiver to object for builtins. 2951 // Do not transform the receiver to object for builtins.
2987 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset), 2952 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset),
2988 1 << SharedFunctionInfo::kNativeBitWithinByte); 2953 1 << SharedFunctionInfo::kNativeBitWithinByte);
2989 __ j(not_equal, &receiver_ok); 2954 __ j(not_equal, &receiver_ok, Label::kNear);
2990 2955
2991 // Normal function. Replace undefined or null with global receiver. 2956 // Normal function. Replace undefined or null with global receiver.
2992 __ cmp(receiver, factory()->null_value()); 2957 __ cmp(receiver, factory()->null_value());
2993 __ j(equal, &global_object, Label::kNear); 2958 __ j(equal, &global_object, Label::kNear);
2994 __ cmp(receiver, factory()->undefined_value()); 2959 __ cmp(receiver, factory()->undefined_value());
2995 __ j(equal, &global_object, Label::kNear); 2960 __ j(equal, &global_object, Label::kNear);
2996 2961
2997 // The receiver should be a JS object. 2962 // The receiver should be a JS object.
2998 __ test(receiver, Immediate(kSmiTagMask)); 2963 __ test(receiver, Immediate(kSmiTagMask));
2999 DeoptimizeIf(equal, instr->environment()); 2964 DeoptimizeIf(equal, instr->environment());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3049 RecordPosition(pointers->position()); 3014 RecordPosition(pointers->position());
3050 SafepointGenerator safepoint_generator( 3015 SafepointGenerator safepoint_generator(
3051 this, pointers, Safepoint::kLazyDeopt); 3016 this, pointers, Safepoint::kLazyDeopt);
3052 ParameterCount actual(eax); 3017 ParameterCount actual(eax);
3053 __ InvokeFunction(function, actual, CALL_FUNCTION, 3018 __ InvokeFunction(function, actual, CALL_FUNCTION,
3054 safepoint_generator, CALL_AS_METHOD); 3019 safepoint_generator, CALL_AS_METHOD);
3055 } 3020 }
3056 3021
3057 3022
3058 void LCodeGen::DoPushArgument(LPushArgument* instr) { 3023 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3059 LOperand* argument = instr->value(); 3024 LOperand* argument = instr->InputAt(0);
3060 EmitPushTaggedOperand(argument); 3025 EmitPushTaggedOperand(argument);
3061 } 3026 }
3062 3027
3063 3028
3064 void LCodeGen::DoDrop(LDrop* instr) { 3029 void LCodeGen::DoDrop(LDrop* instr) {
3065 __ Drop(instr->count()); 3030 __ Drop(instr->count());
3066 } 3031 }
3067 3032
3068 3033
3069 void LCodeGen::DoThisFunction(LThisFunction* instr) { 3034 void LCodeGen::DoThisFunction(LThisFunction* instr) {
(...skipping 10 matching lines...) Expand all
3080 3045
3081 void LCodeGen::DoOuterContext(LOuterContext* instr) { 3046 void LCodeGen::DoOuterContext(LOuterContext* instr) {
3082 Register context = ToRegister(instr->context()); 3047 Register context = ToRegister(instr->context());
3083 Register result = ToRegister(instr->result()); 3048 Register result = ToRegister(instr->result());
3084 __ mov(result, 3049 __ mov(result,
3085 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); 3050 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
3086 } 3051 }
3087 3052
3088 3053
3089 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3054 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3090 ASSERT(ToRegister(instr->context()).is(esi)); 3055 ASSERT(ToRegister(instr->InputAt(0)).is(esi));
3091 __ push(esi); // The context is the first argument. 3056 __ push(esi); // The context is the first argument.
3092 __ push(Immediate(instr->hydrogen()->pairs())); 3057 __ push(Immediate(instr->hydrogen()->pairs()));
3093 __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags()))); 3058 __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags())));
3094 CallRuntime(Runtime::kDeclareGlobals, 3, instr); 3059 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3095 } 3060 }
3096 3061
3097 3062
3098 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { 3063 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3099 Register context = ToRegister(instr->context()); 3064 Register context = ToRegister(instr->context());
3100 Register result = ToRegister(instr->result()); 3065 Register result = ToRegister(instr->result());
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
3413 __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. 3378 __ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
3414 __ sqrtsd(input_reg, input_reg); 3379 __ sqrtsd(input_reg, input_reg);
3415 __ bind(&done); 3380 __ bind(&done);
3416 } 3381 }
3417 3382
3418 3383
3419 void LCodeGen::DoPower(LPower* instr) { 3384 void LCodeGen::DoPower(LPower* instr) {
3420 Representation exponent_type = instr->hydrogen()->right()->representation(); 3385 Representation exponent_type = instr->hydrogen()->right()->representation();
3421 // Having marked this as a call, we can use any registers. 3386 // Having marked this as a call, we can use any registers.
3422 // Just make sure that the input/output registers are the expected ones. 3387 // Just make sure that the input/output registers are the expected ones.
3423 ASSERT(!instr->right()->IsDoubleRegister() || 3388 ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
3424 ToDoubleRegister(instr->right()).is(xmm1)); 3389 ToDoubleRegister(instr->InputAt(1)).is(xmm1));
3425 ASSERT(!instr->right()->IsRegister() || 3390 ASSERT(!instr->InputAt(1)->IsRegister() ||
3426 ToRegister(instr->right()).is(eax)); 3391 ToRegister(instr->InputAt(1)).is(eax));
3427 ASSERT(ToDoubleRegister(instr->left()).is(xmm2)); 3392 ASSERT(ToDoubleRegister(instr->InputAt(0)).is(xmm2));
3428 ASSERT(ToDoubleRegister(instr->result()).is(xmm3)); 3393 ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
3429 3394
3430 if (exponent_type.IsTagged()) { 3395 if (exponent_type.IsTagged()) {
3431 Label no_deopt; 3396 Label no_deopt;
3432 __ JumpIfSmi(eax, &no_deopt); 3397 __ JumpIfSmi(eax, &no_deopt);
3433 __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx); 3398 __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx);
3434 DeoptimizeIf(not_equal, instr->environment()); 3399 DeoptimizeIf(not_equal, instr->environment());
3435 __ bind(&no_deopt); 3400 __ bind(&no_deopt);
3436 MathPowStub stub(MathPowStub::TAGGED); 3401 MathPowStub stub(MathPowStub::TAGGED);
3437 __ CallStub(&stub); 3402 __ CallStub(&stub);
(...skipping 17 matching lines...) Expand all
3455 virtual LInstruction* instr() { return instr_; } 3420 virtual LInstruction* instr() { return instr_; }
3456 private: 3421 private:
3457 LRandom* instr_; 3422 LRandom* instr_;
3458 }; 3423 };
3459 3424
3460 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 3425 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3461 3426
3462 // Having marked this instruction as a call we can use any 3427 // Having marked this instruction as a call we can use any
3463 // registers. 3428 // registers.
3464 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3429 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3465 ASSERT(ToRegister(instr->global_object()).is(eax)); 3430 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
3466 // Assert that the register size is indeed the size of each seed. 3431 // Assert that the register size is indeed the size of each seed.
3467 static const int kSeedSize = sizeof(uint32_t); 3432 static const int kSeedSize = sizeof(uint32_t);
3468 STATIC_ASSERT(kPointerSize == kSeedSize); 3433 STATIC_ASSERT(kPointerSize == kSeedSize);
3469 3434
3470 __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset)); 3435 __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset));
3471 static const int kRandomSeedOffset = 3436 static const int kRandomSeedOffset =
3472 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize; 3437 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
3473 __ mov(ebx, FieldOperand(eax, kRandomSeedOffset)); 3438 __ mov(ebx, FieldOperand(eax, kRandomSeedOffset));
3474 // ebx: FixedArray of the native context's random seeds 3439 // ebx: FixedArray of the native context's random seeds
3475 3440
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
3712 3677
3713 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 3678 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3714 Register object = ToRegister(instr->object()); 3679 Register object = ToRegister(instr->object());
3715 Register value = ToRegister(instr->value()); 3680 Register value = ToRegister(instr->value());
3716 int offset = instr->offset(); 3681 int offset = instr->offset();
3717 3682
3718 if (!instr->transition().is_null()) { 3683 if (!instr->transition().is_null()) {
3719 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { 3684 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
3720 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); 3685 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition());
3721 } else { 3686 } else {
3722 Register temp = ToRegister(instr->temp()); 3687 Register temp = ToRegister(instr->TempAt(0));
3723 Register temp_map = ToRegister(instr->temp_map()); 3688 Register temp_map = ToRegister(instr->TempAt(1));
3724 __ mov(temp_map, instr->transition()); 3689 __ mov(temp_map, instr->transition());
3725 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); 3690 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map);
3726 // Update the write barrier for the map field. 3691 // Update the write barrier for the map field.
3727 __ RecordWriteField(object, 3692 __ RecordWriteField(object,
3728 HeapObject::kMapOffset, 3693 HeapObject::kMapOffset,
3729 temp_map, 3694 temp_map,
3730 temp, 3695 temp,
3731 kSaveFPRegs, 3696 kSaveFPRegs,
3732 OMIT_REMEMBERED_SET, 3697 OMIT_REMEMBERED_SET,
3733 OMIT_SMI_CHECK); 3698 OMIT_SMI_CHECK);
3734 } 3699 }
3735 } 3700 }
3736 3701
3737 // Do the store. 3702 // Do the store.
3738 HType type = instr->hydrogen()->value()->type(); 3703 HType type = instr->hydrogen()->value()->type();
3739 SmiCheck check_needed = 3704 SmiCheck check_needed =
3740 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3705 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3741 if (instr->is_in_object()) { 3706 if (instr->is_in_object()) {
3742 __ mov(FieldOperand(object, offset), value); 3707 __ mov(FieldOperand(object, offset), value);
3743 if (instr->hydrogen()->NeedsWriteBarrier()) { 3708 if (instr->hydrogen()->NeedsWriteBarrier()) {
3744 Register temp = ToRegister(instr->temp()); 3709 Register temp = ToRegister(instr->TempAt(0));
3745 // Update the write barrier for the object for in-object properties. 3710 // Update the write barrier for the object for in-object properties.
3746 __ RecordWriteField(object, 3711 __ RecordWriteField(object,
3747 offset, 3712 offset,
3748 value, 3713 value,
3749 temp, 3714 temp,
3750 kSaveFPRegs, 3715 kSaveFPRegs,
3751 EMIT_REMEMBERED_SET, 3716 EMIT_REMEMBERED_SET,
3752 check_needed); 3717 check_needed);
3753 } 3718 }
3754 } else { 3719 } else {
3755 Register temp = ToRegister(instr->temp()); 3720 Register temp = ToRegister(instr->TempAt(0));
3756 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); 3721 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset));
3757 __ mov(FieldOperand(temp, offset), value); 3722 __ mov(FieldOperand(temp, offset), value);
3758 if (instr->hydrogen()->NeedsWriteBarrier()) { 3723 if (instr->hydrogen()->NeedsWriteBarrier()) {
3759 // Update the write barrier for the properties array. 3724 // Update the write barrier for the properties array.
3760 // object is used as a scratch register. 3725 // object is used as a scratch register.
3761 __ RecordWriteField(temp, 3726 __ RecordWriteField(temp,
3762 offset, 3727 offset,
3763 value, 3728 value,
3764 object, 3729 object,
3765 kSaveFPRegs, 3730 kSaveFPRegs,
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
3941 3906
3942 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3907 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3943 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3908 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3944 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3909 : isolate()->builtins()->KeyedStoreIC_Initialize();
3945 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3910 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3946 } 3911 }
3947 3912
3948 3913
3949 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 3914 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
3950 Register object_reg = ToRegister(instr->object()); 3915 Register object_reg = ToRegister(instr->object());
3951 Register new_map_reg = ToRegister(instr->new_map_temp()); 3916 Register new_map_reg = ToRegister(instr->new_map_reg());
3952 3917
3953 Handle<Map> from_map = instr->original_map(); 3918 Handle<Map> from_map = instr->original_map();
3954 Handle<Map> to_map = instr->transitioned_map(); 3919 Handle<Map> to_map = instr->transitioned_map();
3955 ElementsKind from_kind = from_map->elements_kind(); 3920 ElementsKind from_kind = from_map->elements_kind();
3956 ElementsKind to_kind = to_map->elements_kind(); 3921 ElementsKind to_kind = to_map->elements_kind();
3957 3922
3958 Label not_applicable; 3923 Label not_applicable;
3959 bool is_simple_map_transition = 3924 bool is_simple_map_transition =
3960 IsSimpleMapChangeTransition(from_kind, to_kind); 3925 IsSimpleMapChangeTransition(from_kind, to_kind);
3961 Label::Distance branch_distance = 3926 Label::Distance branch_distance =
3962 is_simple_map_transition ? Label::kNear : Label::kFar; 3927 is_simple_map_transition ? Label::kNear : Label::kFar;
3963 __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 3928 __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
3964 __ j(not_equal, &not_applicable, branch_distance); 3929 __ j(not_equal, &not_applicable, branch_distance);
3965 if (is_simple_map_transition) { 3930 if (is_simple_map_transition) {
3966 Register object_reg = ToRegister(instr->object()); 3931 Register object_reg = ToRegister(instr->object());
3967 Handle<Map> map = instr->hydrogen()->transitioned_map(); 3932 Handle<Map> map = instr->hydrogen()->transitioned_map();
3968 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), 3933 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset),
3969 Immediate(map)); 3934 Immediate(map));
3970 // Write barrier. 3935 // Write barrier.
3971 ASSERT_NE(instr->temp(), NULL); 3936 ASSERT_NE(instr->temp_reg(), NULL);
3972 __ RecordWriteForMap(object_reg, to_map, new_map_reg, 3937 __ RecordWriteForMap(object_reg, to_map, new_map_reg,
3973 ToRegister(instr->temp()), 3938 ToRegister(instr->temp_reg()),
3974 kDontSaveFPRegs); 3939 kDontSaveFPRegs);
3975 } else if (IsFastSmiElementsKind(from_kind) && 3940 } else if (IsFastSmiElementsKind(from_kind) &&
3976 IsFastDoubleElementsKind(to_kind)) { 3941 IsFastDoubleElementsKind(to_kind)) {
3977 __ mov(new_map_reg, to_map); 3942 __ mov(new_map_reg, to_map);
3978 Register fixed_object_reg = ToRegister(instr->temp()); 3943 Register fixed_object_reg = ToRegister(instr->temp_reg());
3979 ASSERT(fixed_object_reg.is(edx)); 3944 ASSERT(fixed_object_reg.is(edx));
3980 ASSERT(new_map_reg.is(ebx)); 3945 ASSERT(new_map_reg.is(ebx));
3981 __ mov(fixed_object_reg, object_reg); 3946 __ mov(fixed_object_reg, object_reg);
3982 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 3947 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
3983 RelocInfo::CODE_TARGET, instr); 3948 RelocInfo::CODE_TARGET, instr);
3984 } else if (IsFastDoubleElementsKind(from_kind) && 3949 } else if (IsFastDoubleElementsKind(from_kind) &&
3985 IsFastObjectElementsKind(to_kind)) { 3950 IsFastObjectElementsKind(to_kind)) {
3986 __ mov(new_map_reg, to_map); 3951 __ mov(new_map_reg, to_map);
3987 Register fixed_object_reg = ToRegister(instr->temp()); 3952 Register fixed_object_reg = ToRegister(instr->temp_reg());
3988 ASSERT(fixed_object_reg.is(edx)); 3953 ASSERT(fixed_object_reg.is(edx));
3989 ASSERT(new_map_reg.is(ebx)); 3954 ASSERT(new_map_reg.is(ebx));
3990 __ mov(fixed_object_reg, object_reg); 3955 __ mov(fixed_object_reg, object_reg);
3991 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 3956 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
3992 RelocInfo::CODE_TARGET, instr); 3957 RelocInfo::CODE_TARGET, instr);
3993 } else { 3958 } else {
3994 UNREACHABLE(); 3959 UNREACHABLE();
3995 } 3960 }
3996 __ bind(&not_applicable); 3961 __ bind(&not_applicable);
3997 } 3962 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
4110 4075
4111 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4076 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4112 EmitPushTaggedOperand(instr->left()); 4077 EmitPushTaggedOperand(instr->left());
4113 EmitPushTaggedOperand(instr->right()); 4078 EmitPushTaggedOperand(instr->right());
4114 StringAddStub stub(NO_STRING_CHECK_IN_STUB); 4079 StringAddStub stub(NO_STRING_CHECK_IN_STUB);
4115 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 4080 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4116 } 4081 }
4117 4082
4118 4083
4119 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4084 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4120 LOperand* input = instr->value(); 4085 LOperand* input = instr->InputAt(0);
4121 ASSERT(input->IsRegister() || input->IsStackSlot()); 4086 ASSERT(input->IsRegister() || input->IsStackSlot());
4122 LOperand* output = instr->result(); 4087 LOperand* output = instr->result();
4123 ASSERT(output->IsDoubleRegister()); 4088 ASSERT(output->IsDoubleRegister());
4124 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 4089 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
4125 } 4090 }
4126 4091
4127 4092
4128 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4093 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4129 LOperand* input = instr->value(); 4094 LOperand* input = instr->InputAt(0);
4130 LOperand* output = instr->result(); 4095 LOperand* output = instr->result();
4131 LOperand* temp = instr->temp(); 4096 LOperand* temp = instr->TempAt(0);
4132 4097
4133 __ LoadUint32(ToDoubleRegister(output), 4098 __ LoadUint32(ToDoubleRegister(output),
4134 ToRegister(input), 4099 ToRegister(input),
4135 ToDoubleRegister(temp)); 4100 ToDoubleRegister(temp));
4136 } 4101 }
4137 4102
4138 4103
4139 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4104 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4140 class DeferredNumberTagI: public LDeferredCode { 4105 class DeferredNumberTagI: public LDeferredCode {
4141 public: 4106 public:
4142 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4107 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4143 : LDeferredCode(codegen), instr_(instr) { } 4108 : LDeferredCode(codegen), instr_(instr) { }
4144 virtual void Generate() { 4109 virtual void Generate() {
4145 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), SIGNED_INT32); 4110 codegen()->DoDeferredNumberTagI(instr_,
4111 instr_->InputAt(0),
4112 SIGNED_INT32);
4146 } 4113 }
4147 virtual LInstruction* instr() { return instr_; } 4114 virtual LInstruction* instr() { return instr_; }
4148 private: 4115 private:
4149 LNumberTagI* instr_; 4116 LNumberTagI* instr_;
4150 }; 4117 };
4151 4118
4152 LOperand* input = instr->value(); 4119 LOperand* input = instr->InputAt(0);
4153 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4120 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4154 Register reg = ToRegister(input); 4121 Register reg = ToRegister(input);
4155 4122
4156 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4123 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4157 __ SmiTag(reg); 4124 __ SmiTag(reg);
4158 __ j(overflow, deferred->entry()); 4125 __ j(overflow, deferred->entry());
4159 __ bind(deferred->exit()); 4126 __ bind(deferred->exit());
4160 } 4127 }
4161 4128
4162 4129
4163 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4130 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4164 class DeferredNumberTagU: public LDeferredCode { 4131 class DeferredNumberTagU: public LDeferredCode {
4165 public: 4132 public:
4166 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 4133 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4167 : LDeferredCode(codegen), instr_(instr) { } 4134 : LDeferredCode(codegen), instr_(instr) { }
4168 virtual void Generate() { 4135 virtual void Generate() {
4169 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), UNSIGNED_INT32); 4136 codegen()->DoDeferredNumberTagI(instr_,
4137 instr_->InputAt(0),
4138 UNSIGNED_INT32);
4170 } 4139 }
4171 virtual LInstruction* instr() { return instr_; } 4140 virtual LInstruction* instr() { return instr_; }
4172 private: 4141 private:
4173 LNumberTagU* instr_; 4142 LNumberTagU* instr_;
4174 }; 4143 };
4175 4144
4176 LOperand* input = instr->value(); 4145 LOperand* input = instr->InputAt(0);
4177 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4146 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4178 Register reg = ToRegister(input); 4147 Register reg = ToRegister(input);
4179 4148
4180 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4149 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4181 __ cmp(reg, Immediate(Smi::kMaxValue)); 4150 __ cmp(reg, Immediate(Smi::kMaxValue));
4182 __ j(above, deferred->entry()); 4151 __ j(above, deferred->entry());
4183 __ SmiTag(reg); 4152 __ SmiTag(reg);
4184 __ bind(deferred->exit()); 4153 __ bind(deferred->exit());
4185 } 4154 }
4186 4155
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4243 class DeferredNumberTagD: public LDeferredCode { 4212 class DeferredNumberTagD: public LDeferredCode {
4244 public: 4213 public:
4245 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4214 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4246 : LDeferredCode(codegen), instr_(instr) { } 4215 : LDeferredCode(codegen), instr_(instr) { }
4247 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4216 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
4248 virtual LInstruction* instr() { return instr_; } 4217 virtual LInstruction* instr() { return instr_; }
4249 private: 4218 private:
4250 LNumberTagD* instr_; 4219 LNumberTagD* instr_;
4251 }; 4220 };
4252 4221
4253 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4222 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
4254 Register reg = ToRegister(instr->result()); 4223 Register reg = ToRegister(instr->result());
4255 Register tmp = ToRegister(instr->temp()); 4224 Register tmp = ToRegister(instr->TempAt(0));
4256 4225
4257 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4226 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4258 if (FLAG_inline_new) { 4227 if (FLAG_inline_new) {
4259 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); 4228 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry());
4260 } else { 4229 } else {
4261 __ jmp(deferred->entry()); 4230 __ jmp(deferred->entry());
4262 } 4231 }
4263 __ bind(deferred->exit()); 4232 __ bind(deferred->exit());
4264 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 4233 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
4265 } 4234 }
(...skipping 14 matching lines...) Expand all
4280 // not have easy access to the local context. 4249 // not have easy access to the local context.
4281 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4250 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4282 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 4251 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
4283 RecordSafepointWithRegisters( 4252 RecordSafepointWithRegisters(
4284 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4253 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4285 __ StoreToSafepointRegisterSlot(reg, eax); 4254 __ StoreToSafepointRegisterSlot(reg, eax);
4286 } 4255 }
4287 4256
4288 4257
4289 void LCodeGen::DoSmiTag(LSmiTag* instr) { 4258 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4290 LOperand* input = instr->value(); 4259 LOperand* input = instr->InputAt(0);
4291 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4260 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4292 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 4261 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
4293 __ SmiTag(ToRegister(input)); 4262 __ SmiTag(ToRegister(input));
4294 } 4263 }
4295 4264
4296 4265
4297 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4266 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4298 LOperand* input = instr->value(); 4267 LOperand* input = instr->InputAt(0);
4299 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4268 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4300 if (instr->needs_check()) { 4269 if (instr->needs_check()) {
4301 __ test(ToRegister(input), Immediate(kSmiTagMask)); 4270 __ test(ToRegister(input), Immediate(kSmiTagMask));
4302 DeoptimizeIf(not_zero, instr->environment()); 4271 DeoptimizeIf(not_zero, instr->environment());
4303 } else { 4272 } else {
4304 if (FLAG_debug_code) { 4273 if (FLAG_debug_code) {
4305 __ AbortIfNotSmi(ToRegister(input)); 4274 __ AbortIfNotSmi(ToRegister(input));
4306 } 4275 }
4307 } 4276 }
4308 __ SmiUntag(ToRegister(input)); 4277 __ SmiUntag(ToRegister(input));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4357 __ bind(&load_smi); 4326 __ bind(&load_smi);
4358 __ SmiUntag(input_reg); // Untag smi before converting to float. 4327 __ SmiUntag(input_reg); // Untag smi before converting to float.
4359 __ cvtsi2sd(result_reg, Operand(input_reg)); 4328 __ cvtsi2sd(result_reg, Operand(input_reg));
4360 __ SmiTag(input_reg); // Retag smi. 4329 __ SmiTag(input_reg); // Retag smi.
4361 __ bind(&done); 4330 __ bind(&done);
4362 } 4331 }
4363 4332
4364 4333
4365 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 4334 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4366 Label done, heap_number; 4335 Label done, heap_number;
4367 Register input_reg = ToRegister(instr->value()); 4336 Register input_reg = ToRegister(instr->InputAt(0));
4368 4337
4369 // Heap number map check. 4338 // Heap number map check.
4370 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 4339 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
4371 factory()->heap_number_map()); 4340 factory()->heap_number_map());
4372 4341
4373 if (instr->truncating()) { 4342 if (instr->truncating()) {
4374 __ j(equal, &heap_number, Label::kNear); 4343 __ j(equal, &heap_number, Label::kNear);
4375 // Check for undefined. Undefined is converted to zero for truncating 4344 // Check for undefined. Undefined is converted to zero for truncating
4376 // conversions. 4345 // conversions.
4377 __ cmp(input_reg, factory()->undefined_value()); 4346 __ cmp(input_reg, factory()->undefined_value());
(...skipping 20 matching lines...) Expand all
4398 DeoptimizeIf(no_condition, instr->environment()); 4367 DeoptimizeIf(no_condition, instr->environment());
4399 4368
4400 // Reserve space for 64 bit answer. 4369 // Reserve space for 64 bit answer.
4401 __ bind(&convert); 4370 __ bind(&convert);
4402 __ sub(Operand(esp), Immediate(kDoubleSize)); 4371 __ sub(Operand(esp), Immediate(kDoubleSize));
4403 // Do conversion, which cannot fail because we checked the exponent. 4372 // Do conversion, which cannot fail because we checked the exponent.
4404 __ fisttp_d(Operand(esp, 0)); 4373 __ fisttp_d(Operand(esp, 0));
4405 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result. 4374 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result.
4406 __ add(Operand(esp), Immediate(kDoubleSize)); 4375 __ add(Operand(esp), Immediate(kDoubleSize));
4407 } else { 4376 } else {
4408 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 4377 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
4409 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4378 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
4410 __ cvttsd2si(input_reg, Operand(xmm0)); 4379 __ cvttsd2si(input_reg, Operand(xmm0));
4411 __ cmp(input_reg, 0x80000000u); 4380 __ cmp(input_reg, 0x80000000u);
4412 __ j(not_equal, &done); 4381 __ j(not_equal, &done);
4413 // Check if the input was 0x8000000 (kMinInt). 4382 // Check if the input was 0x8000000 (kMinInt).
4414 // If no, then we got an overflow and we deoptimize. 4383 // If no, then we got an overflow and we deoptimize.
4415 ExternalReference min_int = ExternalReference::address_of_min_int(); 4384 ExternalReference min_int = ExternalReference::address_of_min_int();
4416 __ movdbl(xmm_temp, Operand::StaticVariable(min_int)); 4385 __ movdbl(xmm_temp, Operand::StaticVariable(min_int));
4417 __ ucomisd(xmm_temp, xmm0); 4386 __ ucomisd(xmm_temp, xmm0);
4418 DeoptimizeIf(not_equal, instr->environment()); 4387 DeoptimizeIf(not_equal, instr->environment());
4419 DeoptimizeIf(parity_even, instr->environment()); // NaN. 4388 DeoptimizeIf(parity_even, instr->environment()); // NaN.
4420 } 4389 }
4421 } else { 4390 } else {
4422 // Deoptimize if we don't have a heap number. 4391 // Deoptimize if we don't have a heap number.
4423 DeoptimizeIf(not_equal, instr->environment()); 4392 DeoptimizeIf(not_equal, instr->environment());
4424 4393
4425 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 4394 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
4426 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4395 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
4427 __ cvttsd2si(input_reg, Operand(xmm0)); 4396 __ cvttsd2si(input_reg, Operand(xmm0));
4428 __ cvtsi2sd(xmm_temp, Operand(input_reg)); 4397 __ cvtsi2sd(xmm_temp, Operand(input_reg));
4429 __ ucomisd(xmm0, xmm_temp); 4398 __ ucomisd(xmm0, xmm_temp);
4430 DeoptimizeIf(not_equal, instr->environment()); 4399 DeoptimizeIf(not_equal, instr->environment());
4431 DeoptimizeIf(parity_even, instr->environment()); // NaN. 4400 DeoptimizeIf(parity_even, instr->environment()); // NaN.
4432 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4401 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4433 __ test(input_reg, Operand(input_reg)); 4402 __ test(input_reg, Operand(input_reg));
4434 __ j(not_zero, &done); 4403 __ j(not_zero, &done);
4435 __ movmskpd(input_reg, xmm0); 4404 __ movmskpd(input_reg, xmm0);
4436 __ and_(input_reg, 1); 4405 __ and_(input_reg, 1);
4437 DeoptimizeIf(not_zero, instr->environment()); 4406 DeoptimizeIf(not_zero, instr->environment());
4438 } 4407 }
4439 } 4408 }
4440 __ bind(&done); 4409 __ bind(&done);
4441 } 4410 }
4442 4411
4443 4412
4444 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 4413 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4445 class DeferredTaggedToI: public LDeferredCode { 4414 class DeferredTaggedToI: public LDeferredCode {
4446 public: 4415 public:
4447 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4416 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4448 : LDeferredCode(codegen), instr_(instr) { } 4417 : LDeferredCode(codegen), instr_(instr) { }
4449 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 4418 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
4450 virtual LInstruction* instr() { return instr_; } 4419 virtual LInstruction* instr() { return instr_; }
4451 private: 4420 private:
4452 LTaggedToI* instr_; 4421 LTaggedToI* instr_;
4453 }; 4422 };
4454 4423
4455 LOperand* input = instr->value(); 4424 LOperand* input = instr->InputAt(0);
4456 ASSERT(input->IsRegister()); 4425 ASSERT(input->IsRegister());
4457 ASSERT(input->Equals(instr->result())); 4426 ASSERT(input->Equals(instr->result()));
4458 4427
4459 Register input_reg = ToRegister(input); 4428 Register input_reg = ToRegister(input);
4460 4429
4461 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 4430 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4462 4431
4463 // Smi check. 4432 // Smi check.
4464 __ JumpIfNotSmi(input_reg, deferred->entry()); 4433 __ JumpIfNotSmi(input_reg, deferred->entry());
4465 4434
4466 // Smi to int32 conversion 4435 // Smi to int32 conversion
4467 __ SmiUntag(input_reg); // Untag smi. 4436 __ SmiUntag(input_reg); // Untag smi.
4468 4437
4469 __ bind(deferred->exit()); 4438 __ bind(deferred->exit());
4470 } 4439 }
4471 4440
4472 4441
4473 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4442 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4474 LOperand* input = instr->value(); 4443 LOperand* input = instr->InputAt(0);
4475 ASSERT(input->IsRegister()); 4444 ASSERT(input->IsRegister());
4476 LOperand* temp = instr->temp(); 4445 LOperand* temp = instr->TempAt(0);
4477 ASSERT(temp == NULL || temp->IsRegister()); 4446 ASSERT(temp == NULL || temp->IsRegister());
4478 LOperand* result = instr->result(); 4447 LOperand* result = instr->result();
4479 ASSERT(result->IsDoubleRegister()); 4448 ASSERT(result->IsDoubleRegister());
4480 4449
4481 Register input_reg = ToRegister(input); 4450 Register input_reg = ToRegister(input);
4482 XMMRegister result_reg = ToDoubleRegister(result); 4451 XMMRegister result_reg = ToDoubleRegister(result);
4483 4452
4484 bool deoptimize_on_minus_zero = 4453 bool deoptimize_on_minus_zero =
4485 instr->hydrogen()->deoptimize_on_minus_zero(); 4454 instr->hydrogen()->deoptimize_on_minus_zero();
4486 Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg; 4455 Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg;
4487 4456
4488 EmitNumberUntagD(input_reg, 4457 EmitNumberUntagD(input_reg,
4489 temp_reg, 4458 temp_reg,
4490 result_reg, 4459 result_reg,
4491 instr->hydrogen()->deoptimize_on_undefined(), 4460 instr->hydrogen()->deoptimize_on_undefined(),
4492 deoptimize_on_minus_zero, 4461 deoptimize_on_minus_zero,
4493 instr->environment()); 4462 instr->environment());
4494 } 4463 }
4495 4464
4496 4465
4497 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4466 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4498 LOperand* input = instr->value(); 4467 LOperand* input = instr->InputAt(0);
4499 ASSERT(input->IsDoubleRegister()); 4468 ASSERT(input->IsDoubleRegister());
4500 LOperand* result = instr->result(); 4469 LOperand* result = instr->result();
4501 ASSERT(result->IsRegister()); 4470 ASSERT(result->IsRegister());
4502 4471
4503 XMMRegister input_reg = ToDoubleRegister(input); 4472 XMMRegister input_reg = ToDoubleRegister(input);
4504 Register result_reg = ToRegister(result); 4473 Register result_reg = ToRegister(result);
4505 4474
4506 if (instr->truncating()) { 4475 if (instr->truncating()) {
4507 // Performs a truncating conversion of a floating point number as used by 4476 // Performs a truncating conversion of a floating point number as used by
4508 // the JS bitwise operations. 4477 // the JS bitwise operations.
(...skipping 17 matching lines...) Expand all
4526 DeoptimizeIf(no_condition, instr->environment()); 4495 DeoptimizeIf(no_condition, instr->environment());
4527 __ bind(&convert); 4496 __ bind(&convert);
4528 // Do conversion, which cannot fail because we checked the exponent. 4497 // Do conversion, which cannot fail because we checked the exponent.
4529 __ fld_d(Operand(esp, 0)); 4498 __ fld_d(Operand(esp, 0));
4530 __ fisttp_d(Operand(esp, 0)); 4499 __ fisttp_d(Operand(esp, 0));
4531 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result. 4500 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result.
4532 __ add(Operand(esp), Immediate(kDoubleSize)); 4501 __ add(Operand(esp), Immediate(kDoubleSize));
4533 __ bind(&done); 4502 __ bind(&done);
4534 } else { 4503 } else {
4535 Label done; 4504 Label done;
4536 Register temp_reg = ToRegister(instr->temp()); 4505 Register temp_reg = ToRegister(instr->TempAt(0));
4537 XMMRegister xmm_scratch = xmm0; 4506 XMMRegister xmm_scratch = xmm0;
4538 4507
4539 // If cvttsd2si succeeded, we're done. Otherwise, we attempt 4508 // If cvttsd2si succeeded, we're done. Otherwise, we attempt
4540 // manual conversion. 4509 // manual conversion.
4541 __ j(not_equal, &done, Label::kNear); 4510 __ j(not_equal, &done, Label::kNear);
4542 4511
4543 // Get high 32 bits of the input in result_reg and temp_reg. 4512 // Get high 32 bits of the input in result_reg and temp_reg.
4544 __ pshufd(xmm_scratch, input_reg, 1); 4513 __ pshufd(xmm_scratch, input_reg, 1);
4545 __ movd(Operand(temp_reg), xmm_scratch); 4514 __ movd(Operand(temp_reg), xmm_scratch);
4546 __ mov(result_reg, temp_reg); 4515 __ mov(result_reg, temp_reg);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
4605 // deoptimize. 4574 // deoptimize.
4606 __ and_(result_reg, 1); 4575 __ and_(result_reg, 1);
4607 DeoptimizeIf(not_zero, instr->environment()); 4576 DeoptimizeIf(not_zero, instr->environment());
4608 } 4577 }
4609 __ bind(&done); 4578 __ bind(&done);
4610 } 4579 }
4611 } 4580 }
4612 4581
4613 4582
4614 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 4583 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4615 LOperand* input = instr->value(); 4584 LOperand* input = instr->InputAt(0);
4616 __ test(ToOperand(input), Immediate(kSmiTagMask)); 4585 __ test(ToOperand(input), Immediate(kSmiTagMask));
4617 DeoptimizeIf(not_zero, instr->environment()); 4586 DeoptimizeIf(not_zero, instr->environment());
4618 } 4587 }
4619 4588
4620 4589
4621 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 4590 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4622 LOperand* input = instr->value(); 4591 LOperand* input = instr->InputAt(0);
4623 __ test(ToOperand(input), Immediate(kSmiTagMask)); 4592 __ test(ToOperand(input), Immediate(kSmiTagMask));
4624 DeoptimizeIf(zero, instr->environment()); 4593 DeoptimizeIf(zero, instr->environment());
4625 } 4594 }
4626 4595
4627 4596
4628 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 4597 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4629 Register input = ToRegister(instr->value()); 4598 Register input = ToRegister(instr->InputAt(0));
4630 Register temp = ToRegister(instr->temp()); 4599 Register temp = ToRegister(instr->TempAt(0));
4631 4600
4632 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 4601 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
4633 4602
4634 if (instr->hydrogen()->is_interval_check()) { 4603 if (instr->hydrogen()->is_interval_check()) {
4635 InstanceType first; 4604 InstanceType first;
4636 InstanceType last; 4605 InstanceType last;
4637 instr->hydrogen()->GetCheckInterval(&first, &last); 4606 instr->hydrogen()->GetCheckInterval(&first, &last);
4638 4607
4639 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 4608 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
4640 static_cast<int8_t>(first)); 4609 static_cast<int8_t>(first));
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4690 CompareMapMode mode, 4659 CompareMapMode mode,
4691 LEnvironment* env) { 4660 LEnvironment* env) {
4692 Label success; 4661 Label success;
4693 __ CompareMap(reg, map, &success, mode); 4662 __ CompareMap(reg, map, &success, mode);
4694 DeoptimizeIf(not_equal, env); 4663 DeoptimizeIf(not_equal, env);
4695 __ bind(&success); 4664 __ bind(&success);
4696 } 4665 }
4697 4666
4698 4667
4699 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 4668 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4700 LOperand* input = instr->value(); 4669 LOperand* input = instr->InputAt(0);
4701 ASSERT(input->IsRegister()); 4670 ASSERT(input->IsRegister());
4702 Register reg = ToRegister(input); 4671 Register reg = ToRegister(input);
4703 4672
4704 Label success; 4673 Label success;
4705 SmallMapList* map_set = instr->hydrogen()->map_set(); 4674 SmallMapList* map_set = instr->hydrogen()->map_set();
4706 for (int i = 0; i < map_set->length() - 1; i++) { 4675 for (int i = 0; i < map_set->length() - 1; i++) {
4707 Handle<Map> map = map_set->at(i); 4676 Handle<Map> map = map_set->at(i);
4708 __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP); 4677 __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP);
4709 __ j(equal, &success); 4678 __ j(equal, &success);
4710 } 4679 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4756 // smi 4725 // smi
4757 __ bind(&is_smi); 4726 __ bind(&is_smi);
4758 __ SmiUntag(input_reg); 4727 __ SmiUntag(input_reg);
4759 __ ClampUint8(input_reg); 4728 __ ClampUint8(input_reg);
4760 4729
4761 __ bind(&done); 4730 __ bind(&done);
4762 } 4731 }
4763 4732
4764 4733
4765 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 4734 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
4766 Register reg = ToRegister(instr->temp()); 4735 Register reg = ToRegister(instr->TempAt(0));
4767 4736
4768 Handle<JSObject> holder = instr->holder(); 4737 Handle<JSObject> holder = instr->holder();
4769 Handle<JSObject> current_prototype = instr->prototype(); 4738 Handle<JSObject> current_prototype = instr->prototype();
4770 4739
4771 // Load prototype object. 4740 // Load prototype object.
4772 __ LoadHeapObject(reg, current_prototype); 4741 __ LoadHeapObject(reg, current_prototype);
4773 4742
4774 // Check prototype maps up to the holder. 4743 // Check prototype maps up to the holder.
4775 while (!current_prototype.is_identical_to(holder)) { 4744 while (!current_prototype.is_identical_to(holder)) {
4776 DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()), 4745 DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()),
(...skipping 19 matching lines...) Expand all
4796 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); } 4765 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
4797 virtual LInstruction* instr() { return instr_; } 4766 virtual LInstruction* instr() { return instr_; }
4798 private: 4767 private:
4799 LAllocateObject* instr_; 4768 LAllocateObject* instr_;
4800 }; 4769 };
4801 4770
4802 DeferredAllocateObject* deferred = 4771 DeferredAllocateObject* deferred =
4803 new(zone()) DeferredAllocateObject(this, instr); 4772 new(zone()) DeferredAllocateObject(this, instr);
4804 4773
4805 Register result = ToRegister(instr->result()); 4774 Register result = ToRegister(instr->result());
4806 Register scratch = ToRegister(instr->temp()); 4775 Register scratch = ToRegister(instr->TempAt(0));
4807 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); 4776 Handle<JSFunction> constructor = instr->hydrogen()->constructor();
4808 Handle<Map> initial_map(constructor->initial_map()); 4777 Handle<Map> initial_map(constructor->initial_map());
4809 int instance_size = initial_map->instance_size(); 4778 int instance_size = initial_map->instance_size();
4810 ASSERT(initial_map->pre_allocated_property_fields() + 4779 ASSERT(initial_map->pre_allocated_property_fields() +
4811 initial_map->unused_property_fields() - 4780 initial_map->unused_property_fields() -
4812 initial_map->inobject_properties() == 0); 4781 initial_map->inobject_properties() == 0);
4813 4782
4814 // Allocate memory for the object. The initial map might change when 4783 // Allocate memory for the object. The initial map might change when
4815 // the constructor's prototype changes, but instance size and property 4784 // the constructor's prototype changes, but instance size and property
4816 // counts remain unchanged (if slack tracking finished). 4785 // counts remain unchanged (if slack tracking finished).
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
5115 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 5084 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
5116 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); 5085 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr);
5117 } else { 5086 } else {
5118 FastCloneShallowObjectStub stub(properties_count); 5087 FastCloneShallowObjectStub stub(properties_count);
5119 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 5088 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
5120 } 5089 }
5121 } 5090 }
5122 5091
5123 5092
5124 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { 5093 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5125 ASSERT(ToRegister(instr->value()).is(eax)); 5094 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
5126 __ push(eax); 5095 __ push(eax);
5127 CallRuntime(Runtime::kToFastProperties, 1, instr); 5096 CallRuntime(Runtime::kToFastProperties, 1, instr);
5128 } 5097 }
5129 5098
5130 5099
5131 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 5100 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5132 ASSERT(ToRegister(instr->context()).is(esi)); 5101 ASSERT(ToRegister(instr->context()).is(esi));
5133 Label materialized; 5102 Label materialized;
5134 // Registers will be used as follows: 5103 // Registers will be used as follows:
5135 // ecx = literals array. 5104 // ecx = literals array.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
5195 __ push(Immediate(shared_info)); 5164 __ push(Immediate(shared_info));
5196 __ push(Immediate(pretenure 5165 __ push(Immediate(pretenure
5197 ? factory()->true_value() 5166 ? factory()->true_value()
5198 : factory()->false_value())); 5167 : factory()->false_value()));
5199 CallRuntime(Runtime::kNewClosure, 3, instr); 5168 CallRuntime(Runtime::kNewClosure, 3, instr);
5200 } 5169 }
5201 } 5170 }
5202 5171
5203 5172
5204 void LCodeGen::DoTypeof(LTypeof* instr) { 5173 void LCodeGen::DoTypeof(LTypeof* instr) {
5205 LOperand* input = instr->value(); 5174 LOperand* input = instr->InputAt(1);
5206 EmitPushTaggedOperand(input); 5175 EmitPushTaggedOperand(input);
5207 CallRuntime(Runtime::kTypeof, 1, instr); 5176 CallRuntime(Runtime::kTypeof, 1, instr);
5208 } 5177 }
5209 5178
5210 5179
5211 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 5180 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5212 Register input = ToRegister(instr->value()); 5181 Register input = ToRegister(instr->InputAt(0));
5213 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5182 int true_block = chunk_->LookupDestination(instr->true_block_id());
5214 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5183 int false_block = chunk_->LookupDestination(instr->false_block_id());
5215 Label* true_label = chunk_->GetAssemblyLabel(true_block); 5184 Label* true_label = chunk_->GetAssemblyLabel(true_block);
5216 Label* false_label = chunk_->GetAssemblyLabel(false_block); 5185 Label* false_label = chunk_->GetAssemblyLabel(false_block);
5217 5186
5218 Condition final_branch_condition = 5187 Condition final_branch_condition =
5219 EmitTypeofIs(true_label, false_label, input, instr->type_literal()); 5188 EmitTypeofIs(true_label, false_label, input, instr->type_literal());
5220 if (final_branch_condition != no_condition) { 5189 if (final_branch_condition != no_condition) {
5221 EmitBranch(true_block, false_block, final_branch_condition); 5190 EmitBranch(true_block, false_block, final_branch_condition);
5222 } 5191 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
5286 final_branch_condition = zero; 5255 final_branch_condition = zero;
5287 5256
5288 } else { 5257 } else {
5289 __ jmp(false_label); 5258 __ jmp(false_label);
5290 } 5259 }
5291 return final_branch_condition; 5260 return final_branch_condition;
5292 } 5261 }
5293 5262
5294 5263
5295 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5264 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5296 Register temp = ToRegister(instr->temp()); 5265 Register temp = ToRegister(instr->TempAt(0));
5297 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5266 int true_block = chunk_->LookupDestination(instr->true_block_id());
5298 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5267 int false_block = chunk_->LookupDestination(instr->false_block_id());
5299 5268
5300 EmitIsConstructCall(temp); 5269 EmitIsConstructCall(temp);
5301 EmitBranch(true_block, false_block, equal); 5270 EmitBranch(true_block, false_block, equal);
5302 } 5271 }
5303 5272
5304 5273
5305 void LCodeGen::EmitIsConstructCall(Register temp) { 5274 void LCodeGen::EmitIsConstructCall(Register temp) {
5306 // Get the frame pointer for the calling frame. 5275 // Get the frame pointer for the calling frame.
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
5544 FixedArray::kHeaderSize - kPointerSize)); 5513 FixedArray::kHeaderSize - kPointerSize));
5545 __ bind(&done); 5514 __ bind(&done);
5546 } 5515 }
5547 5516
5548 5517
5549 #undef __ 5518 #undef __
5550 5519
5551 } } // namespace v8::internal 5520 } } // namespace v8::internal
5552 5521
5553 #endif // V8_TARGET_ARCH_IA32 5522 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698