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

Side by Side Diff: src/x64/lithium-codegen-x64.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/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 // context in the fixed part of the frame. 344 // context in the fixed part of the frame.
345 return Operand(rbp, -(index + 3) * kPointerSize); 345 return Operand(rbp, -(index + 3) * kPointerSize);
346 } else { 346 } else {
347 // Incoming parameter. Skip the return address. 347 // Incoming parameter. Skip the return address.
348 return Operand(rbp, -(index - 1) * kPointerSize); 348 return Operand(rbp, -(index - 1) * kPointerSize);
349 } 349 }
350 } 350 }
351 351
352 352
353 void LCodeGen::WriteTranslation(LEnvironment* environment, 353 void LCodeGen::WriteTranslation(LEnvironment* environment,
354 Translation* translation, 354 Translation* translation) {
355 int* arguments_index,
356 int* arguments_count) {
357 if (environment == NULL) return; 355 if (environment == NULL) return;
358 356
359 // The translation includes one command per value in the environment. 357 // The translation includes one command per value in the environment.
360 int translation_size = environment->values()->length(); 358 int translation_size = environment->values()->length();
361 // The output frame height does not include the parameters. 359 // The output frame height does not include the parameters.
362 int height = translation_size - environment->parameter_count(); 360 int height = translation_size - environment->parameter_count();
363 361
364 // Function parameters are arguments to the outermost environment. The 362 WriteTranslation(environment->outer(), translation);
365 // arguments index points to the first element of a sequence of tagged
366 // values on the stack that represent the arguments. This needs to be
367 // kept in sync with the LArgumentsElements implementation.
368 *arguments_index = -environment->parameter_count();
369 *arguments_count = environment->parameter_count();
370
371 WriteTranslation(environment->outer(),
372 translation,
373 arguments_index,
374 arguments_count);
375 int closure_id = *info()->closure() != *environment->closure() 363 int closure_id = *info()->closure() != *environment->closure()
376 ? DefineDeoptimizationLiteral(environment->closure()) 364 ? DefineDeoptimizationLiteral(environment->closure())
377 : Translation::kSelfLiteralId; 365 : Translation::kSelfLiteralId;
378 366
379 switch (environment->frame_type()) { 367 switch (environment->frame_type()) {
380 case JS_FUNCTION: 368 case JS_FUNCTION:
381 translation->BeginJSFrame(environment->ast_id(), closure_id, height); 369 translation->BeginJSFrame(environment->ast_id(), closure_id, height);
382 break; 370 break;
383 case JS_CONSTRUCT: 371 case JS_CONSTRUCT:
384 translation->BeginConstructStubFrame(closure_id, translation_size); 372 translation->BeginConstructStubFrame(closure_id, translation_size);
385 break; 373 break;
386 case JS_GETTER: 374 case JS_GETTER:
387 ASSERT(translation_size == 1); 375 ASSERT(translation_size == 1);
388 ASSERT(height == 0); 376 ASSERT(height == 0);
389 translation->BeginGetterStubFrame(closure_id); 377 translation->BeginGetterStubFrame(closure_id);
390 break; 378 break;
391 case JS_SETTER: 379 case JS_SETTER:
392 ASSERT(translation_size == 2); 380 ASSERT(translation_size == 2);
393 ASSERT(height == 0); 381 ASSERT(height == 0);
394 translation->BeginSetterStubFrame(closure_id); 382 translation->BeginSetterStubFrame(closure_id);
395 break; 383 break;
396 case ARGUMENTS_ADAPTOR: 384 case ARGUMENTS_ADAPTOR:
397 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 385 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
398 break; 386 break;
399 } 387 }
400
401 // Inlined frames which push their arguments cause the index to be
402 // bumped and a new stack area to be used for materialization.
403 if (environment->entry() != NULL &&
404 environment->entry()->arguments_pushed()) {
405 *arguments_index = *arguments_index < 0
406 ? GetStackSlotCount()
407 : *arguments_index + *arguments_count;
408 *arguments_count = environment->entry()->arguments_count() + 1;
409 }
410
411 for (int i = 0; i < translation_size; ++i) { 388 for (int i = 0; i < translation_size; ++i) {
412 LOperand* value = environment->values()->at(i); 389 LOperand* value = environment->values()->at(i);
413 // spilled_registers_ and spilled_double_registers_ are either 390 // spilled_registers_ and spilled_double_registers_ are either
414 // both NULL or both set. 391 // both NULL or both set.
415 if (environment->spilled_registers() != NULL && value != NULL) { 392 if (environment->spilled_registers() != NULL && value != NULL) {
416 if (value->IsRegister() && 393 if (value->IsRegister() &&
417 environment->spilled_registers()[value->index()] != NULL) { 394 environment->spilled_registers()[value->index()] != NULL) {
418 translation->MarkDuplicate(); 395 translation->MarkDuplicate();
419 AddToTranslation(translation, 396 AddToTranslation(translation,
420 environment->spilled_registers()[value->index()], 397 environment->spilled_registers()[value->index()],
421 environment->HasTaggedValueAt(i), 398 environment->HasTaggedValueAt(i),
422 environment->HasUint32ValueAt(i), 399 environment->HasUint32ValueAt(i));
423 *arguments_index,
424 *arguments_count);
425 } else if ( 400 } else if (
426 value->IsDoubleRegister() && 401 value->IsDoubleRegister() &&
427 environment->spilled_double_registers()[value->index()] != NULL) { 402 environment->spilled_double_registers()[value->index()] != NULL) {
428 translation->MarkDuplicate(); 403 translation->MarkDuplicate();
429 AddToTranslation( 404 AddToTranslation(
430 translation, 405 translation,
431 environment->spilled_double_registers()[value->index()], 406 environment->spilled_double_registers()[value->index()],
432 false, 407 false,
433 false, 408 false);
434 *arguments_index,
435 *arguments_count);
436 } 409 }
437 } 410 }
438 411
439 AddToTranslation(translation, 412 AddToTranslation(translation,
440 value, 413 value,
441 environment->HasTaggedValueAt(i), 414 environment->HasTaggedValueAt(i),
442 environment->HasUint32ValueAt(i), 415 environment->HasUint32ValueAt(i));
443 *arguments_index,
444 *arguments_count);
445 } 416 }
446 } 417 }
447 418
448 419
449 void LCodeGen::AddToTranslation(Translation* translation, 420 void LCodeGen::AddToTranslation(Translation* translation,
450 LOperand* op, 421 LOperand* op,
451 bool is_tagged, 422 bool is_tagged,
452 bool is_uint32, 423 bool is_uint32) {
453 int arguments_index,
454 int arguments_count) {
455 if (op == NULL) { 424 if (op == NULL) {
456 // TODO(twuerthinger): Introduce marker operands to indicate that this value 425 // TODO(twuerthinger): Introduce marker operands to indicate that this value
457 // is not present and must be reconstructed from the deoptimizer. Currently 426 // is not present and must be reconstructed from the deoptimizer. Currently
458 // this is only used for the arguments object. 427 // this is only used for the arguments object.
459 translation->StoreArgumentsObject(arguments_index, arguments_count); 428 translation->StoreArgumentsObject();
460 } else if (op->IsStackSlot()) { 429 } else if (op->IsStackSlot()) {
461 if (is_tagged) { 430 if (is_tagged) {
462 translation->StoreStackSlot(op->index()); 431 translation->StoreStackSlot(op->index());
463 } else if (is_uint32) { 432 } else if (is_uint32) {
464 translation->StoreUint32StackSlot(op->index()); 433 translation->StoreUint32StackSlot(op->index());
465 } else { 434 } else {
466 translation->StoreInt32StackSlot(op->index()); 435 translation->StoreInt32StackSlot(op->index());
467 } 436 }
468 } else if (op->IsDoubleStackSlot()) { 437 } else if (op->IsDoubleStackSlot()) {
469 translation->StoreDoubleStackSlot(op->index()); 438 translation->StoreDoubleStackSlot(op->index());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 // 0 ..................................................... size-1 524 // 0 ..................................................... size-1
556 // [parameters] [locals] [expression stack including arguments] 525 // [parameters] [locals] [expression stack including arguments]
557 526
558 // Layout of the translation: 527 // Layout of the translation:
559 // 0 ........................................................ size - 1 + 4 528 // 0 ........................................................ size - 1 + 4
560 // [expression stack including arguments] [locals] [4 words] [parameters] 529 // [expression stack including arguments] [locals] [4 words] [parameters]
561 // |>------------ translation_size ------------<| 530 // |>------------ translation_size ------------<|
562 531
563 int frame_count = 0; 532 int frame_count = 0;
564 int jsframe_count = 0; 533 int jsframe_count = 0;
565 int args_index = 0;
566 int args_count = 0;
567 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 534 for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
568 ++frame_count; 535 ++frame_count;
569 if (e->frame_type() == JS_FUNCTION) { 536 if (e->frame_type() == JS_FUNCTION) {
570 ++jsframe_count; 537 ++jsframe_count;
571 } 538 }
572 } 539 }
573 Translation translation(&translations_, frame_count, jsframe_count, zone()); 540 Translation translation(&translations_, frame_count, jsframe_count,
574 WriteTranslation(environment, &translation, &args_index, &args_count); 541 environment->zone());
542 WriteTranslation(environment, &translation);
575 int deoptimization_index = deoptimizations_.length(); 543 int deoptimization_index = deoptimizations_.length();
576 int pc_offset = masm()->pc_offset(); 544 int pc_offset = masm()->pc_offset();
577 environment->Register(deoptimization_index, 545 environment->Register(deoptimization_index,
578 translation.index(), 546 translation.index(),
579 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 547 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
580 deoptimizations_.Add(environment, environment->zone()); 548 deoptimizations_.Add(environment, environment->zone());
581 } 549 }
582 } 550 }
583 551
584 552
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 } 779 }
812 780
813 781
814 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 782 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
815 // Nothing to do. 783 // Nothing to do.
816 } 784 }
817 785
818 786
819 void LCodeGen::DoModI(LModI* instr) { 787 void LCodeGen::DoModI(LModI* instr) {
820 if (instr->hydrogen()->HasPowerOf2Divisor()) { 788 if (instr->hydrogen()->HasPowerOf2Divisor()) {
821 Register dividend = ToRegister(instr->left()); 789 Register dividend = ToRegister(instr->InputAt(0));
822 790
823 int32_t divisor = 791 int32_t divisor =
824 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 792 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
825 793
826 if (divisor < 0) divisor = -divisor; 794 if (divisor < 0) divisor = -divisor;
827 795
828 Label positive_dividend, done; 796 Label positive_dividend, done;
829 __ testl(dividend, dividend); 797 __ testl(dividend, dividend);
830 __ j(not_sign, &positive_dividend, Label::kNear); 798 __ j(not_sign, &positive_dividend, Label::kNear);
831 __ negl(dividend); 799 __ negl(dividend);
832 __ andl(dividend, Immediate(divisor - 1)); 800 __ andl(dividend, Immediate(divisor - 1));
833 __ negl(dividend); 801 __ negl(dividend);
834 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 802 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
835 __ j(not_zero, &done, Label::kNear); 803 __ j(not_zero, &done, Label::kNear);
836 DeoptimizeIf(no_condition, instr->environment()); 804 DeoptimizeIf(no_condition, instr->environment());
837 } else { 805 } else {
838 __ jmp(&done, Label::kNear); 806 __ jmp(&done, Label::kNear);
839 } 807 }
840 __ bind(&positive_dividend); 808 __ bind(&positive_dividend);
841 __ andl(dividend, Immediate(divisor - 1)); 809 __ andl(dividend, Immediate(divisor - 1));
842 __ bind(&done); 810 __ bind(&done);
843 } else { 811 } else {
844 Label done, remainder_eq_dividend, slow, do_subtraction, both_positive; 812 Label done, remainder_eq_dividend, slow, do_subtraction, both_positive;
845 Register left_reg = ToRegister(instr->left()); 813 Register left_reg = ToRegister(instr->InputAt(0));
846 Register right_reg = ToRegister(instr->right()); 814 Register right_reg = ToRegister(instr->InputAt(1));
847 Register result_reg = ToRegister(instr->result()); 815 Register result_reg = ToRegister(instr->result());
848 816
849 ASSERT(left_reg.is(rax)); 817 ASSERT(left_reg.is(rax));
850 ASSERT(result_reg.is(rdx)); 818 ASSERT(result_reg.is(rdx));
851 ASSERT(!right_reg.is(rax)); 819 ASSERT(!right_reg.is(rax));
852 ASSERT(!right_reg.is(rdx)); 820 ASSERT(!right_reg.is(rdx));
853 821
854 // Check for x % 0. 822 // Check for x % 0.
855 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 823 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
856 __ testl(right_reg, right_reg); 824 __ testl(right_reg, right_reg);
857 DeoptimizeIf(zero, instr->environment()); 825 DeoptimizeIf(zero, instr->environment());
858 } 826 }
859 827
860 __ testl(left_reg, left_reg); 828 __ testl(left_reg, left_reg);
861 __ j(zero, &remainder_eq_dividend, Label::kNear); 829 __ j(zero, &remainder_eq_dividend, Label::kNear);
862 __ j(sign, &slow, Label::kNear); 830 __ j(sign, &slow, Label::kNear);
863 831
864 __ testl(right_reg, right_reg); 832 __ testl(right_reg, right_reg);
865 __ j(not_sign, &both_positive, Label::kNear); 833 __ j(not_sign, &both_positive, Label::kNear);
866 // The sign of the divisor doesn't matter. 834 // The sign of the divisor doesn't matter.
867 __ neg(right_reg); 835 __ neg(right_reg);
868 836
869 __ bind(&both_positive); 837 __ bind(&both_positive);
870 // If the dividend is smaller than the nonnegative 838 // If the dividend is smaller than the nonnegative
871 // divisor, the dividend is the result. 839 // divisor, the dividend is the result.
872 __ cmpl(left_reg, right_reg); 840 __ cmpl(left_reg, right_reg);
873 __ j(less, &remainder_eq_dividend, Label::kNear); 841 __ j(less, &remainder_eq_dividend, Label::kNear);
874 842
875 // Check if the divisor is a PowerOfTwo integer. 843 // Check if the divisor is a PowerOfTwo integer.
876 Register scratch = ToRegister(instr->temp()); 844 Register scratch = ToRegister(instr->TempAt(0));
877 __ movl(scratch, right_reg); 845 __ movl(scratch, right_reg);
878 __ subl(scratch, Immediate(1)); 846 __ subl(scratch, Immediate(1));
879 __ testl(scratch, right_reg); 847 __ testl(scratch, right_reg);
880 __ j(not_zero, &do_subtraction, Label::kNear); 848 __ j(not_zero, &do_subtraction, Label::kNear);
881 __ andl(left_reg, scratch); 849 __ andl(left_reg, scratch);
882 __ jmp(&remainder_eq_dividend, Label::kNear); 850 __ jmp(&remainder_eq_dividend, Label::kNear);
883 851
884 __ bind(&do_subtraction); 852 __ bind(&do_subtraction);
885 const int kUnfolds = 3; 853 const int kUnfolds = 3;
886 // Try a few subtractions of the dividend. 854 // Try a few subtractions of the dividend.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 891
924 __ bind(&remainder_eq_dividend); 892 __ bind(&remainder_eq_dividend);
925 __ movl(result_reg, left_reg); 893 __ movl(result_reg, left_reg);
926 894
927 __ bind(&done); 895 __ bind(&done);
928 } 896 }
929 } 897 }
930 898
931 899
932 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { 900 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
933 ASSERT(instr->right()->IsConstantOperand()); 901 ASSERT(instr->InputAt(1)->IsConstantOperand());
934 902
935 const Register dividend = ToRegister(instr->left()); 903 const Register dividend = ToRegister(instr->InputAt(0));
936 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); 904 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1)));
937 const Register result = ToRegister(instr->result()); 905 const Register result = ToRegister(instr->result());
938 906
939 switch (divisor) { 907 switch (divisor) {
940 case 0: 908 case 0:
941 DeoptimizeIf(no_condition, instr->environment()); 909 DeoptimizeIf(no_condition, instr->environment());
942 return; 910 return;
943 911
944 case 1: 912 case 1:
945 if (!result.is(dividend)) { 913 if (!result.is(dividend)) {
946 __ movl(result, dividend); 914 __ movl(result, dividend);
(...skipping 24 matching lines...) Expand all
971 DeoptimizeIf(zero, instr->environment()); 939 DeoptimizeIf(zero, instr->environment());
972 } 940 }
973 __ sar(result, Immediate(power)); 941 __ sar(result, Immediate(power));
974 } else { 942 } else {
975 if (!result.is(dividend)) { 943 if (!result.is(dividend)) {
976 __ movl(result, dividend); 944 __ movl(result, dividend);
977 } 945 }
978 __ sarl(result, Immediate(power)); 946 __ sarl(result, Immediate(power));
979 } 947 }
980 } else { 948 } else {
981 Register reg1 = ToRegister(instr->temp()); 949 Register reg1 = ToRegister(instr->TempAt(0));
982 Register reg2 = ToRegister(instr->result()); 950 Register reg2 = ToRegister(instr->result());
983 951
984 // Find b which: 2^b < divisor_abs < 2^(b+1). 952 // Find b which: 2^b < divisor_abs < 2^(b+1).
985 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs); 953 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
986 unsigned shift = 32 + b; // Precision +1bit (effectively). 954 unsigned shift = 32 + b; // Precision +1bit (effectively).
987 double multiplier_f = 955 double multiplier_f =
988 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs; 956 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs;
989 int64_t multiplier; 957 int64_t multiplier;
990 if (multiplier_f - floor(multiplier_f) < 0.5) { 958 if (multiplier_f - floor(multiplier_f) < 0.5) {
991 multiplier = static_cast<int64_t>(floor(multiplier_f)); 959 multiplier = static_cast<int64_t>(floor(multiplier_f));
(...skipping 14 matching lines...) Expand all
1006 // Result just fit in r64, because it's int32 * uint32. 974 // Result just fit in r64, because it's int32 * uint32.
1007 __ imul(reg2, reg1); 975 __ imul(reg2, reg1);
1008 976
1009 __ addq(reg2, Immediate(1 << 30)); 977 __ addq(reg2, Immediate(1 << 30));
1010 __ sar(reg2, Immediate(shift)); 978 __ sar(reg2, Immediate(shift));
1011 } 979 }
1012 } 980 }
1013 981
1014 982
1015 void LCodeGen::DoDivI(LDivI* instr) { 983 void LCodeGen::DoDivI(LDivI* instr) {
1016 LOperand* right = instr->right(); 984 LOperand* right = instr->InputAt(1);
1017 ASSERT(ToRegister(instr->result()).is(rax)); 985 ASSERT(ToRegister(instr->result()).is(rax));
1018 ASSERT(ToRegister(instr->left()).is(rax)); 986 ASSERT(ToRegister(instr->InputAt(0)).is(rax));
1019 ASSERT(!ToRegister(instr->right()).is(rax)); 987 ASSERT(!ToRegister(instr->InputAt(1)).is(rax));
1020 ASSERT(!ToRegister(instr->right()).is(rdx)); 988 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx));
1021 989
1022 Register left_reg = rax; 990 Register left_reg = rax;
1023 991
1024 // Check for x / 0. 992 // Check for x / 0.
1025 Register right_reg = ToRegister(right); 993 Register right_reg = ToRegister(right);
1026 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 994 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1027 __ testl(right_reg, right_reg); 995 __ testl(right_reg, right_reg);
1028 DeoptimizeIf(zero, instr->environment()); 996 DeoptimizeIf(zero, instr->environment());
1029 } 997 }
1030 998
(...skipping 21 matching lines...) Expand all
1052 __ cdq(); 1020 __ cdq();
1053 __ idivl(right_reg); 1021 __ idivl(right_reg);
1054 1022
1055 // Deoptimize if remainder is not 0. 1023 // Deoptimize if remainder is not 0.
1056 __ testl(rdx, rdx); 1024 __ testl(rdx, rdx);
1057 DeoptimizeIf(not_zero, instr->environment()); 1025 DeoptimizeIf(not_zero, instr->environment());
1058 } 1026 }
1059 1027
1060 1028
1061 void LCodeGen::DoMulI(LMulI* instr) { 1029 void LCodeGen::DoMulI(LMulI* instr) {
1062 Register left = ToRegister(instr->left()); 1030 Register left = ToRegister(instr->InputAt(0));
1063 LOperand* right = instr->right(); 1031 LOperand* right = instr->InputAt(1);
1064 1032
1065 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1033 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1066 __ movl(kScratchRegister, left); 1034 __ movl(kScratchRegister, left);
1067 } 1035 }
1068 1036
1069 bool can_overflow = 1037 bool can_overflow =
1070 instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1038 instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1071 if (right->IsConstantOperand()) { 1039 if (right->IsConstantOperand()) {
1072 int right_value = ToInteger32(LConstantOperand::cast(right)); 1040 int right_value = ToInteger32(LConstantOperand::cast(right));
1073 if (right_value == -1) { 1041 if (right_value == -1) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 if (can_overflow) { 1086 if (can_overflow) {
1119 DeoptimizeIf(overflow, instr->environment()); 1087 DeoptimizeIf(overflow, instr->environment());
1120 } 1088 }
1121 1089
1122 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1090 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1123 // Bail out if the result is supposed to be negative zero. 1091 // Bail out if the result is supposed to be negative zero.
1124 Label done; 1092 Label done;
1125 __ testl(left, left); 1093 __ testl(left, left);
1126 __ j(not_zero, &done, Label::kNear); 1094 __ j(not_zero, &done, Label::kNear);
1127 if (right->IsConstantOperand()) { 1095 if (right->IsConstantOperand()) {
1128 if (ToInteger32(LConstantOperand::cast(right)) < 0) { 1096 if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
1129 DeoptimizeIf(no_condition, instr->environment()); 1097 DeoptimizeIf(no_condition, instr->environment());
1130 } else if (ToInteger32(LConstantOperand::cast(right)) == 0) {
1131 __ cmpl(kScratchRegister, Immediate(0));
1132 DeoptimizeIf(less, instr->environment());
1133 } 1098 }
1134 } else if (right->IsStackSlot()) { 1099 } else if (right->IsStackSlot()) {
1135 __ orl(kScratchRegister, ToOperand(right)); 1100 __ orl(kScratchRegister, ToOperand(right));
1136 DeoptimizeIf(sign, instr->environment()); 1101 DeoptimizeIf(sign, instr->environment());
1137 } else { 1102 } else {
1138 // Test the non-zero operand for negative sign. 1103 // Test the non-zero operand for negative sign.
1139 __ orl(kScratchRegister, ToRegister(right)); 1104 __ orl(kScratchRegister, ToRegister(right));
1140 DeoptimizeIf(sign, instr->environment()); 1105 DeoptimizeIf(sign, instr->environment());
1141 } 1106 }
1142 __ bind(&done); 1107 __ bind(&done);
1143 } 1108 }
1144 } 1109 }
1145 1110
1146 1111
1147 void LCodeGen::DoBitI(LBitI* instr) { 1112 void LCodeGen::DoBitI(LBitI* instr) {
1148 LOperand* left = instr->left(); 1113 LOperand* left = instr->InputAt(0);
1149 LOperand* right = instr->right(); 1114 LOperand* right = instr->InputAt(1);
1150 ASSERT(left->Equals(instr->result())); 1115 ASSERT(left->Equals(instr->result()));
1151 ASSERT(left->IsRegister()); 1116 ASSERT(left->IsRegister());
1152 1117
1153 if (right->IsConstantOperand()) { 1118 if (right->IsConstantOperand()) {
1154 int right_operand = ToInteger32(LConstantOperand::cast(right)); 1119 int right_operand = ToInteger32(LConstantOperand::cast(right));
1155 switch (instr->op()) { 1120 switch (instr->op()) {
1156 case Token::BIT_AND: 1121 case Token::BIT_AND:
1157 __ andl(ToRegister(left), Immediate(right_operand)); 1122 __ andl(ToRegister(left), Immediate(right_operand));
1158 break; 1123 break;
1159 case Token::BIT_OR: 1124 case Token::BIT_OR:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 break; 1160 break;
1196 default: 1161 default:
1197 UNREACHABLE(); 1162 UNREACHABLE();
1198 break; 1163 break;
1199 } 1164 }
1200 } 1165 }
1201 } 1166 }
1202 1167
1203 1168
1204 void LCodeGen::DoShiftI(LShiftI* instr) { 1169 void LCodeGen::DoShiftI(LShiftI* instr) {
1205 LOperand* left = instr->left(); 1170 LOperand* left = instr->InputAt(0);
1206 LOperand* right = instr->right(); 1171 LOperand* right = instr->InputAt(1);
1207 ASSERT(left->Equals(instr->result())); 1172 ASSERT(left->Equals(instr->result()));
1208 ASSERT(left->IsRegister()); 1173 ASSERT(left->IsRegister());
1209 if (right->IsRegister()) { 1174 if (right->IsRegister()) {
1210 ASSERT(ToRegister(right).is(rcx)); 1175 ASSERT(ToRegister(right).is(rcx));
1211 1176
1212 switch (instr->op()) { 1177 switch (instr->op()) {
1213 case Token::SAR: 1178 case Token::SAR:
1214 __ sarl_cl(ToRegister(left)); 1179 __ sarl_cl(ToRegister(left));
1215 break; 1180 break;
1216 case Token::SHR: 1181 case Token::SHR:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1251 break; 1216 break;
1252 default: 1217 default:
1253 UNREACHABLE(); 1218 UNREACHABLE();
1254 break; 1219 break;
1255 } 1220 }
1256 } 1221 }
1257 } 1222 }
1258 1223
1259 1224
1260 void LCodeGen::DoSubI(LSubI* instr) { 1225 void LCodeGen::DoSubI(LSubI* instr) {
1261 LOperand* left = instr->left(); 1226 LOperand* left = instr->InputAt(0);
1262 LOperand* right = instr->right(); 1227 LOperand* right = instr->InputAt(1);
1263 ASSERT(left->Equals(instr->result())); 1228 ASSERT(left->Equals(instr->result()));
1264 1229
1265 if (right->IsConstantOperand()) { 1230 if (right->IsConstantOperand()) {
1266 __ subl(ToRegister(left), 1231 __ subl(ToRegister(left),
1267 Immediate(ToInteger32(LConstantOperand::cast(right)))); 1232 Immediate(ToInteger32(LConstantOperand::cast(right))));
1268 } else if (right->IsRegister()) { 1233 } else if (right->IsRegister()) {
1269 __ subl(ToRegister(left), ToRegister(right)); 1234 __ subl(ToRegister(left), ToRegister(right));
1270 } else { 1235 } else {
1271 __ subl(ToRegister(left), ToOperand(right)); 1236 __ subl(ToRegister(left), ToOperand(right));
1272 } 1237 }
(...skipping 13 matching lines...) Expand all
1286 void LCodeGen::DoConstantD(LConstantD* instr) { 1251 void LCodeGen::DoConstantD(LConstantD* instr) {
1287 ASSERT(instr->result()->IsDoubleRegister()); 1252 ASSERT(instr->result()->IsDoubleRegister());
1288 XMMRegister res = ToDoubleRegister(instr->result()); 1253 XMMRegister res = ToDoubleRegister(instr->result());
1289 double v = instr->value(); 1254 double v = instr->value();
1290 uint64_t int_val = BitCast<uint64_t, double>(v); 1255 uint64_t int_val = BitCast<uint64_t, double>(v);
1291 // Use xor to produce +0.0 in a fast and compact way, but avoid to 1256 // Use xor to produce +0.0 in a fast and compact way, but avoid to
1292 // do so if the constant is -0.0. 1257 // do so if the constant is -0.0.
1293 if (int_val == 0) { 1258 if (int_val == 0) {
1294 __ xorps(res, res); 1259 __ xorps(res, res);
1295 } else { 1260 } else {
1296 Register tmp = ToRegister(instr->temp()); 1261 Register tmp = ToRegister(instr->TempAt(0));
1297 __ Set(tmp, int_val); 1262 __ Set(tmp, int_val);
1298 __ movq(res, tmp); 1263 __ movq(res, tmp);
1299 } 1264 }
1300 } 1265 }
1301 1266
1302 1267
1303 void LCodeGen::DoConstantT(LConstantT* instr) { 1268 void LCodeGen::DoConstantT(LConstantT* instr) {
1304 Handle<Object> value = instr->value(); 1269 Handle<Object> value = instr->value();
1305 if (value->IsSmi()) { 1270 if (value->IsSmi()) {
1306 __ Move(ToRegister(instr->result()), value); 1271 __ Move(ToRegister(instr->result()), value);
1307 } else { 1272 } else {
1308 __ LoadHeapObject(ToRegister(instr->result()), 1273 __ LoadHeapObject(ToRegister(instr->result()),
1309 Handle<HeapObject>::cast(value)); 1274 Handle<HeapObject>::cast(value));
1310 } 1275 }
1311 } 1276 }
1312 1277
1313 1278
1314 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1279 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1315 Register result = ToRegister(instr->result()); 1280 Register result = ToRegister(instr->result());
1316 Register array = ToRegister(instr->value()); 1281 Register array = ToRegister(instr->InputAt(0));
1317 __ movq(result, FieldOperand(array, JSArray::kLengthOffset)); 1282 __ movq(result, FieldOperand(array, JSArray::kLengthOffset));
1318 } 1283 }
1319 1284
1320 1285
1321 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { 1286 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
1322 Register result = ToRegister(instr->result()); 1287 Register result = ToRegister(instr->result());
1323 Register array = ToRegister(instr->value()); 1288 Register array = ToRegister(instr->InputAt(0));
1324 __ movq(result, FieldOperand(array, FixedArrayBase::kLengthOffset)); 1289 __ movq(result, FieldOperand(array, FixedArrayBase::kLengthOffset));
1325 } 1290 }
1326 1291
1327 1292
1328 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1293 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1329 Register result = ToRegister(instr->result()); 1294 Register result = ToRegister(instr->result());
1330 Register map = ToRegister(instr->value()); 1295 Register map = ToRegister(instr->InputAt(0));
1331 __ EnumLength(result, map); 1296 __ EnumLength(result, map);
1332 } 1297 }
1333 1298
1334 1299
1335 void LCodeGen::DoElementsKind(LElementsKind* instr) { 1300 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1336 Register result = ToRegister(instr->result()); 1301 Register result = ToRegister(instr->result());
1337 Register input = ToRegister(instr->value()); 1302 Register input = ToRegister(instr->InputAt(0));
1338 1303
1339 // Load map into |result|. 1304 // Load map into |result|.
1340 __ movq(result, FieldOperand(input, HeapObject::kMapOffset)); 1305 __ movq(result, FieldOperand(input, HeapObject::kMapOffset));
1341 // Load the map's "bit field 2" into |result|. We only need the first byte. 1306 // Load the map's "bit field 2" into |result|. We only need the first byte.
1342 __ movzxbq(result, FieldOperand(result, Map::kBitField2Offset)); 1307 __ movzxbq(result, FieldOperand(result, Map::kBitField2Offset));
1343 // Retrieve elements_kind from bit field 2. 1308 // Retrieve elements_kind from bit field 2.
1344 __ and_(result, Immediate(Map::kElementsKindMask)); 1309 __ and_(result, Immediate(Map::kElementsKindMask));
1345 __ shr(result, Immediate(Map::kElementsKindShift)); 1310 __ shr(result, Immediate(Map::kElementsKindShift));
1346 } 1311 }
1347 1312
1348 1313
1349 void LCodeGen::DoValueOf(LValueOf* instr) { 1314 void LCodeGen::DoValueOf(LValueOf* instr) {
1350 Register input = ToRegister(instr->value()); 1315 Register input = ToRegister(instr->InputAt(0));
1351 Register result = ToRegister(instr->result()); 1316 Register result = ToRegister(instr->result());
1352 ASSERT(input.is(result)); 1317 ASSERT(input.is(result));
1353 Label done; 1318 Label done;
1354 // If the object is a smi return the object. 1319 // If the object is a smi return the object.
1355 __ JumpIfSmi(input, &done, Label::kNear); 1320 __ JumpIfSmi(input, &done, Label::kNear);
1356 1321
1357 // If the object is not a value type, return the object. 1322 // If the object is not a value type, return the object.
1358 __ CmpObjectType(input, JS_VALUE_TYPE, kScratchRegister); 1323 __ CmpObjectType(input, JS_VALUE_TYPE, kScratchRegister);
1359 __ j(not_equal, &done, Label::kNear); 1324 __ j(not_equal, &done, Label::kNear);
1360 __ movq(result, FieldOperand(input, JSValue::kValueOffset)); 1325 __ movq(result, FieldOperand(input, JSValue::kValueOffset));
1361 1326
1362 __ bind(&done); 1327 __ bind(&done);
1363 } 1328 }
1364 1329
1365 1330
1366 void LCodeGen::DoDateField(LDateField* instr) { 1331 void LCodeGen::DoDateField(LDateField* instr) {
1367 Register object = ToRegister(instr->date()); 1332 Register object = ToRegister(instr->InputAt(0));
1368 Register result = ToRegister(instr->result()); 1333 Register result = ToRegister(instr->result());
1369 Smi* index = instr->index(); 1334 Smi* index = instr->index();
1370 Label runtime, done, not_date_object; 1335 Label runtime, done, not_date_object;
1371 ASSERT(object.is(result)); 1336 ASSERT(object.is(result));
1372 ASSERT(object.is(rax)); 1337 ASSERT(object.is(rax));
1373 1338
1374 Condition cc = masm()->CheckSmi(object); 1339 Condition cc = masm()->CheckSmi(object);
1375 DeoptimizeIf(cc, instr->environment()); 1340 DeoptimizeIf(cc, instr->environment());
1376 __ CmpObjectType(object, JS_DATE_TYPE, kScratchRegister); 1341 __ CmpObjectType(object, JS_DATE_TYPE, kScratchRegister);
1377 DeoptimizeIf(not_equal, instr->environment()); 1342 DeoptimizeIf(not_equal, instr->environment());
(...skipping 21 matching lines...) Expand all
1399 __ movq(rsi, index, RelocInfo::NONE); 1364 __ movq(rsi, index, RelocInfo::NONE);
1400 #endif 1365 #endif
1401 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 1366 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
1402 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1367 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1403 __ bind(&done); 1368 __ bind(&done);
1404 } 1369 }
1405 } 1370 }
1406 1371
1407 1372
1408 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1373 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1409 LOperand* input = instr->value(); 1374 LOperand* input = instr->InputAt(0);
1410 ASSERT(input->Equals(instr->result())); 1375 ASSERT(input->Equals(instr->result()));
1411 __ not_(ToRegister(input)); 1376 __ not_(ToRegister(input));
1412 } 1377 }
1413 1378
1414 1379
1415 void LCodeGen::DoThrow(LThrow* instr) { 1380 void LCodeGen::DoThrow(LThrow* instr) {
1416 __ push(ToRegister(instr->value())); 1381 __ push(ToRegister(instr->InputAt(0)));
1417 CallRuntime(Runtime::kThrow, 1, instr); 1382 CallRuntime(Runtime::kThrow, 1, instr);
1418 1383
1419 if (FLAG_debug_code) { 1384 if (FLAG_debug_code) {
1420 Comment("Unreachable code."); 1385 Comment("Unreachable code.");
1421 __ int3(); 1386 __ int3();
1422 } 1387 }
1423 } 1388 }
1424 1389
1425 1390
1426 void LCodeGen::DoAddI(LAddI* instr) { 1391 void LCodeGen::DoAddI(LAddI* instr) {
1427 LOperand* left = instr->left(); 1392 LOperand* left = instr->InputAt(0);
1428 LOperand* right = instr->right(); 1393 LOperand* right = instr->InputAt(1);
1429 ASSERT(left->Equals(instr->result())); 1394 ASSERT(left->Equals(instr->result()));
1430 1395
1431 if (right->IsConstantOperand()) { 1396 if (right->IsConstantOperand()) {
1432 __ addl(ToRegister(left), 1397 __ addl(ToRegister(left),
1433 Immediate(ToInteger32(LConstantOperand::cast(right)))); 1398 Immediate(ToInteger32(LConstantOperand::cast(right))));
1434 } else if (right->IsRegister()) { 1399 } else if (right->IsRegister()) {
1435 __ addl(ToRegister(left), ToRegister(right)); 1400 __ addl(ToRegister(left), ToRegister(right));
1436 } else { 1401 } else {
1437 __ addl(ToRegister(left), ToOperand(right)); 1402 __ addl(ToRegister(left), ToOperand(right));
1438 } 1403 }
1439 1404
1440 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1405 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1441 DeoptimizeIf(overflow, instr->environment()); 1406 DeoptimizeIf(overflow, instr->environment());
1442 } 1407 }
1443 } 1408 }
1444 1409
1445 1410
1446 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1411 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1447 LOperand* left = instr->left(); 1412 LOperand* left = instr->InputAt(0);
1448 LOperand* right = instr->right(); 1413 LOperand* right = instr->InputAt(1);
1449 ASSERT(left->Equals(instr->result())); 1414 ASSERT(left->Equals(instr->result()));
1450 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1415 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1451 if (instr->hydrogen()->representation().IsInteger32()) { 1416 if (instr->hydrogen()->representation().IsInteger32()) {
1452 Label return_left; 1417 Label return_left;
1453 Condition condition = (operation == HMathMinMax::kMathMin) 1418 Condition condition = (operation == HMathMinMax::kMathMin)
1454 ? less_equal 1419 ? less_equal
1455 : greater_equal; 1420 : greater_equal;
1456 Register left_reg = ToRegister(left); 1421 Register left_reg = ToRegister(left);
1457 if (right->IsConstantOperand()) { 1422 if (right->IsConstantOperand()) {
1458 Immediate right_imm = 1423 Immediate right_imm =
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1503 __ j(parity_even, &return_left, Label::kNear); 1468 __ j(parity_even, &return_left, Label::kNear);
1504 __ bind(&return_right); 1469 __ bind(&return_right);
1505 __ movsd(left_reg, right_reg); 1470 __ movsd(left_reg, right_reg);
1506 1471
1507 __ bind(&return_left); 1472 __ bind(&return_left);
1508 } 1473 }
1509 } 1474 }
1510 1475
1511 1476
1512 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1477 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1513 XMMRegister left = ToDoubleRegister(instr->left()); 1478 XMMRegister left = ToDoubleRegister(instr->InputAt(0));
1514 XMMRegister right = ToDoubleRegister(instr->right()); 1479 XMMRegister right = ToDoubleRegister(instr->InputAt(1));
1515 XMMRegister result = ToDoubleRegister(instr->result()); 1480 XMMRegister result = ToDoubleRegister(instr->result());
1516 // All operations except MOD are computed in-place. 1481 // All operations except MOD are computed in-place.
1517 ASSERT(instr->op() == Token::MOD || left.is(result)); 1482 ASSERT(instr->op() == Token::MOD || left.is(result));
1518 switch (instr->op()) { 1483 switch (instr->op()) {
1519 case Token::ADD: 1484 case Token::ADD:
1520 __ addsd(left, right); 1485 __ addsd(left, right);
1521 break; 1486 break;
1522 case Token::SUB: 1487 case Token::SUB:
1523 __ subsd(left, right); 1488 __ subsd(left, right);
1524 break; 1489 break;
(...skipping 13 matching lines...) Expand all
1538 __ movaps(result, xmm0); 1503 __ movaps(result, xmm0);
1539 break; 1504 break;
1540 default: 1505 default:
1541 UNREACHABLE(); 1506 UNREACHABLE();
1542 break; 1507 break;
1543 } 1508 }
1544 } 1509 }
1545 1510
1546 1511
1547 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1512 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1548 ASSERT(ToRegister(instr->left()).is(rdx)); 1513 ASSERT(ToRegister(instr->InputAt(0)).is(rdx));
1549 ASSERT(ToRegister(instr->right()).is(rax)); 1514 ASSERT(ToRegister(instr->InputAt(1)).is(rax));
1550 ASSERT(ToRegister(instr->result()).is(rax)); 1515 ASSERT(ToRegister(instr->result()).is(rax));
1551 1516
1552 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 1517 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
1553 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1518 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1554 __ nop(); // Signals no inlined code. 1519 __ nop(); // Signals no inlined code.
1555 } 1520 }
1556 1521
1557 1522
1558 int LCodeGen::GetNextEmittedBlock(int block) { 1523 int LCodeGen::GetNextEmittedBlock(int block) {
1559 for (int i = block + 1; i < graph()->blocks()->length(); ++i) { 1524 for (int i = block + 1; i < graph()->blocks()->length(); ++i) {
(...skipping 23 matching lines...) Expand all
1583 } 1548 }
1584 } 1549 }
1585 1550
1586 1551
1587 void LCodeGen::DoBranch(LBranch* instr) { 1552 void LCodeGen::DoBranch(LBranch* instr) {
1588 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1553 int true_block = chunk_->LookupDestination(instr->true_block_id());
1589 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1554 int false_block = chunk_->LookupDestination(instr->false_block_id());
1590 1555
1591 Representation r = instr->hydrogen()->value()->representation(); 1556 Representation r = instr->hydrogen()->value()->representation();
1592 if (r.IsInteger32()) { 1557 if (r.IsInteger32()) {
1593 Register reg = ToRegister(instr->value()); 1558 Register reg = ToRegister(instr->InputAt(0));
1594 __ testl(reg, reg); 1559 __ testl(reg, reg);
1595 EmitBranch(true_block, false_block, not_zero); 1560 EmitBranch(true_block, false_block, not_zero);
1596 } else if (r.IsDouble()) { 1561 } else if (r.IsDouble()) {
1597 XMMRegister reg = ToDoubleRegister(instr->value()); 1562 XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
1598 __ xorps(xmm0, xmm0); 1563 __ xorps(xmm0, xmm0);
1599 __ ucomisd(reg, xmm0); 1564 __ ucomisd(reg, xmm0);
1600 EmitBranch(true_block, false_block, not_equal); 1565 EmitBranch(true_block, false_block, not_equal);
1601 } else { 1566 } else {
1602 ASSERT(r.IsTagged()); 1567 ASSERT(r.IsTagged());
1603 Register reg = ToRegister(instr->value()); 1568 Register reg = ToRegister(instr->InputAt(0));
1604 HType type = instr->hydrogen()->value()->type(); 1569 HType type = instr->hydrogen()->value()->type();
1605 if (type.IsBoolean()) { 1570 if (type.IsBoolean()) {
1606 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 1571 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1607 EmitBranch(true_block, false_block, equal); 1572 EmitBranch(true_block, false_block, equal);
1608 } else if (type.IsSmi()) { 1573 } else if (type.IsSmi()) {
1609 __ SmiCompare(reg, Smi::FromInt(0)); 1574 __ SmiCompare(reg, Smi::FromInt(0));
1610 EmitBranch(true_block, false_block, not_equal); 1575 EmitBranch(true_block, false_block, not_equal);
1611 } else { 1576 } else {
1612 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1577 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1613 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1578 Label* false_label = chunk_->GetAssemblyLabel(false_block);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 case Token::IN: 1695 case Token::IN:
1731 case Token::INSTANCEOF: 1696 case Token::INSTANCEOF:
1732 default: 1697 default:
1733 UNREACHABLE(); 1698 UNREACHABLE();
1734 } 1699 }
1735 return cond; 1700 return cond;
1736 } 1701 }
1737 1702
1738 1703
1739 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1704 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
1740 LOperand* left = instr->left(); 1705 LOperand* left = instr->InputAt(0);
1741 LOperand* right = instr->right(); 1706 LOperand* right = instr->InputAt(1);
1742 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1707 int false_block = chunk_->LookupDestination(instr->false_block_id());
1743 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1708 int true_block = chunk_->LookupDestination(instr->true_block_id());
1744 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1709 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1745 1710
1746 if (left->IsConstantOperand() && right->IsConstantOperand()) { 1711 if (left->IsConstantOperand() && right->IsConstantOperand()) {
1747 // We can statically evaluate the comparison. 1712 // We can statically evaluate the comparison.
1748 double left_val = ToDouble(LConstantOperand::cast(left)); 1713 double left_val = ToDouble(LConstantOperand::cast(left));
1749 double right_val = ToDouble(LConstantOperand::cast(right)); 1714 double right_val = ToDouble(LConstantOperand::cast(right));
1750 int next_block = 1715 int next_block =
1751 EvalComparison(instr->op(), left_val, right_val) ? true_block 1716 EvalComparison(instr->op(), left_val, right_val) ? true_block
(...skipping 26 matching lines...) Expand all
1778 __ cmpl(ToRegister(left), ToOperand(right)); 1743 __ cmpl(ToRegister(left), ToOperand(right));
1779 } 1744 }
1780 } 1745 }
1781 } 1746 }
1782 EmitBranch(true_block, false_block, cc); 1747 EmitBranch(true_block, false_block, cc);
1783 } 1748 }
1784 } 1749 }
1785 1750
1786 1751
1787 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 1752 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
1788 Register left = ToRegister(instr->left()); 1753 Register left = ToRegister(instr->InputAt(0));
1789 Register right = ToRegister(instr->right()); 1754 Register right = ToRegister(instr->InputAt(1));
1790 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1755 int false_block = chunk_->LookupDestination(instr->false_block_id());
1791 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1756 int true_block = chunk_->LookupDestination(instr->true_block_id());
1792 1757
1793 __ cmpq(left, right); 1758 __ cmpq(left, right);
1794 EmitBranch(true_block, false_block, equal); 1759 EmitBranch(true_block, false_block, equal);
1795 } 1760 }
1796 1761
1797 1762
1798 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 1763 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
1799 Register left = ToRegister(instr->left()); 1764 Register left = ToRegister(instr->InputAt(0));
1800 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1765 int true_block = chunk_->LookupDestination(instr->true_block_id());
1801 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1766 int false_block = chunk_->LookupDestination(instr->false_block_id());
1802 1767
1803 __ cmpq(left, Immediate(instr->hydrogen()->right())); 1768 __ cmpq(left, Immediate(instr->hydrogen()->right()));
1804 EmitBranch(true_block, false_block, equal); 1769 EmitBranch(true_block, false_block, equal);
1805 } 1770 }
1806 1771
1807 1772
1808 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) { 1773 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
1809 Register reg = ToRegister(instr->value()); 1774 Register reg = ToRegister(instr->InputAt(0));
1810 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1775 int false_block = chunk_->LookupDestination(instr->false_block_id());
1811 1776
1812 // If the expression is known to be untagged or a smi, then it's definitely 1777 // If the expression is known to be untagged or a smi, then it's definitely
1813 // not null, and it can't be a an undetectable object. 1778 // not null, and it can't be a an undetectable object.
1814 if (instr->hydrogen()->representation().IsSpecialization() || 1779 if (instr->hydrogen()->representation().IsSpecialization() ||
1815 instr->hydrogen()->type().IsSmi()) { 1780 instr->hydrogen()->type().IsSmi()) {
1816 EmitGoto(false_block); 1781 EmitGoto(false_block);
1817 return; 1782 return;
1818 } 1783 }
1819 1784
1820 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1785 int true_block = chunk_->LookupDestination(instr->true_block_id());
1821 Heap::RootListIndex nil_value = instr->nil() == kNullValue ? 1786 Heap::RootListIndex nil_value = instr->nil() == kNullValue ?
1822 Heap::kNullValueRootIndex : 1787 Heap::kNullValueRootIndex :
1823 Heap::kUndefinedValueRootIndex; 1788 Heap::kUndefinedValueRootIndex;
1824 __ CompareRoot(reg, nil_value); 1789 __ CompareRoot(reg, nil_value);
1825 if (instr->kind() == kStrictEquality) { 1790 if (instr->kind() == kStrictEquality) {
1826 EmitBranch(true_block, false_block, equal); 1791 EmitBranch(true_block, false_block, equal);
1827 } else { 1792 } else {
1828 Heap::RootListIndex other_nil_value = instr->nil() == kNullValue ? 1793 Heap::RootListIndex other_nil_value = instr->nil() == kNullValue ?
1829 Heap::kUndefinedValueRootIndex : 1794 Heap::kUndefinedValueRootIndex :
1830 Heap::kNullValueRootIndex; 1795 Heap::kNullValueRootIndex;
1831 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1796 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1832 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1797 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1833 __ j(equal, true_label); 1798 __ j(equal, true_label);
1834 __ CompareRoot(reg, other_nil_value); 1799 __ CompareRoot(reg, other_nil_value);
1835 __ j(equal, true_label); 1800 __ j(equal, true_label);
1836 __ JumpIfSmi(reg, false_label); 1801 __ JumpIfSmi(reg, false_label);
1837 // Check for undetectable objects by looking in the bit field in 1802 // Check for undetectable objects by looking in the bit field in
1838 // the map. The object has already been smi checked. 1803 // the map. The object has already been smi checked.
1839 Register scratch = ToRegister(instr->temp()); 1804 Register scratch = ToRegister(instr->TempAt(0));
1840 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset)); 1805 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1841 __ testb(FieldOperand(scratch, Map::kBitFieldOffset), 1806 __ testb(FieldOperand(scratch, Map::kBitFieldOffset),
1842 Immediate(1 << Map::kIsUndetectable)); 1807 Immediate(1 << Map::kIsUndetectable));
1843 EmitBranch(true_block, false_block, not_zero); 1808 EmitBranch(true_block, false_block, not_zero);
1844 } 1809 }
1845 } 1810 }
1846 1811
1847 1812
1848 Condition LCodeGen::EmitIsObject(Register input, 1813 Condition LCodeGen::EmitIsObject(Register input,
1849 Label* is_not_object, 1814 Label* is_not_object,
(...skipping 14 matching lines...) Expand all
1864 __ movzxbl(kScratchRegister, 1829 __ movzxbl(kScratchRegister,
1865 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); 1830 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset));
1866 __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 1831 __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
1867 __ j(below, is_not_object); 1832 __ j(below, is_not_object);
1868 __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 1833 __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
1869 return below_equal; 1834 return below_equal;
1870 } 1835 }
1871 1836
1872 1837
1873 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1838 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1874 Register reg = ToRegister(instr->value()); 1839 Register reg = ToRegister(instr->InputAt(0));
1875 1840
1876 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1841 int true_block = chunk_->LookupDestination(instr->true_block_id());
1877 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1842 int false_block = chunk_->LookupDestination(instr->false_block_id());
1878 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1843 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1879 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1844 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1880 1845
1881 Condition true_cond = EmitIsObject(reg, false_label, true_label); 1846 Condition true_cond = EmitIsObject(reg, false_label, true_label);
1882 1847
1883 EmitBranch(true_block, false_block, true_cond); 1848 EmitBranch(true_block, false_block, true_cond);
1884 } 1849 }
1885 1850
1886 1851
1887 Condition LCodeGen::EmitIsString(Register input, 1852 Condition LCodeGen::EmitIsString(Register input,
1888 Register temp1, 1853 Register temp1,
1889 Label* is_not_string) { 1854 Label* is_not_string) {
1890 __ JumpIfSmi(input, is_not_string); 1855 __ JumpIfSmi(input, is_not_string);
1891 Condition cond = masm_->IsObjectStringType(input, temp1, temp1); 1856 Condition cond = masm_->IsObjectStringType(input, temp1, temp1);
1892 1857
1893 return cond; 1858 return cond;
1894 } 1859 }
1895 1860
1896 1861
1897 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 1862 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
1898 Register reg = ToRegister(instr->value()); 1863 Register reg = ToRegister(instr->InputAt(0));
1899 Register temp = ToRegister(instr->temp()); 1864 Register temp = ToRegister(instr->TempAt(0));
1900 1865
1901 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1866 int true_block = chunk_->LookupDestination(instr->true_block_id());
1902 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1867 int false_block = chunk_->LookupDestination(instr->false_block_id());
1903 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1868 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1904 1869
1905 Condition true_cond = EmitIsString(reg, temp, false_label); 1870 Condition true_cond = EmitIsString(reg, temp, false_label);
1906 1871
1907 EmitBranch(true_block, false_block, true_cond); 1872 EmitBranch(true_block, false_block, true_cond);
1908 } 1873 }
1909 1874
1910 1875
1911 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 1876 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
1912 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1877 int true_block = chunk_->LookupDestination(instr->true_block_id());
1913 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1878 int false_block = chunk_->LookupDestination(instr->false_block_id());
1914 1879
1915 Condition is_smi; 1880 Condition is_smi;
1916 if (instr->value()->IsRegister()) { 1881 if (instr->InputAt(0)->IsRegister()) {
1917 Register input = ToRegister(instr->value()); 1882 Register input = ToRegister(instr->InputAt(0));
1918 is_smi = masm()->CheckSmi(input); 1883 is_smi = masm()->CheckSmi(input);
1919 } else { 1884 } else {
1920 Operand input = ToOperand(instr->value()); 1885 Operand input = ToOperand(instr->InputAt(0));
1921 is_smi = masm()->CheckSmi(input); 1886 is_smi = masm()->CheckSmi(input);
1922 } 1887 }
1923 EmitBranch(true_block, false_block, is_smi); 1888 EmitBranch(true_block, false_block, is_smi);
1924 } 1889 }
1925 1890
1926 1891
1927 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 1892 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
1928 Register input = ToRegister(instr->value()); 1893 Register input = ToRegister(instr->InputAt(0));
1929 Register temp = ToRegister(instr->temp()); 1894 Register temp = ToRegister(instr->TempAt(0));
1930 1895
1931 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1896 int true_block = chunk_->LookupDestination(instr->true_block_id());
1932 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1897 int false_block = chunk_->LookupDestination(instr->false_block_id());
1933 1898
1934 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 1899 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
1935 __ movq(temp, FieldOperand(input, HeapObject::kMapOffset)); 1900 __ movq(temp, FieldOperand(input, HeapObject::kMapOffset));
1936 __ testb(FieldOperand(temp, Map::kBitFieldOffset), 1901 __ testb(FieldOperand(temp, Map::kBitFieldOffset),
1937 Immediate(1 << Map::kIsUndetectable)); 1902 Immediate(1 << Map::kIsUndetectable));
1938 EmitBranch(true_block, false_block, not_zero); 1903 EmitBranch(true_block, false_block, not_zero);
1939 } 1904 }
(...skipping 28 matching lines...) Expand all
1968 InstanceType to = instr->to(); 1933 InstanceType to = instr->to();
1969 if (from == to) return equal; 1934 if (from == to) return equal;
1970 if (to == LAST_TYPE) return above_equal; 1935 if (to == LAST_TYPE) return above_equal;
1971 if (from == FIRST_TYPE) return below_equal; 1936 if (from == FIRST_TYPE) return below_equal;
1972 UNREACHABLE(); 1937 UNREACHABLE();
1973 return equal; 1938 return equal;
1974 } 1939 }
1975 1940
1976 1941
1977 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 1942 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1978 Register input = ToRegister(instr->value()); 1943 Register input = ToRegister(instr->InputAt(0));
1979 1944
1980 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1945 int true_block = chunk_->LookupDestination(instr->true_block_id());
1981 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1946 int false_block = chunk_->LookupDestination(instr->false_block_id());
1982 1947
1983 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1948 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1984 1949
1985 __ JumpIfSmi(input, false_label); 1950 __ JumpIfSmi(input, false_label);
1986 1951
1987 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister); 1952 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister);
1988 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 1953 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
1989 } 1954 }
1990 1955
1991 1956
1992 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 1957 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
1993 Register input = ToRegister(instr->value()); 1958 Register input = ToRegister(instr->InputAt(0));
1994 Register result = ToRegister(instr->result()); 1959 Register result = ToRegister(instr->result());
1995 1960
1996 __ AbortIfNotString(input); 1961 __ AbortIfNotString(input);
1997 1962
1998 __ movl(result, FieldOperand(input, String::kHashFieldOffset)); 1963 __ movl(result, FieldOperand(input, String::kHashFieldOffset));
1999 ASSERT(String::kHashShift >= kSmiTagSize); 1964 ASSERT(String::kHashShift >= kSmiTagSize);
2000 __ IndexFromHash(result, result); 1965 __ IndexFromHash(result, result);
2001 } 1966 }
2002 1967
2003 1968
2004 void LCodeGen::DoHasCachedArrayIndexAndBranch( 1969 void LCodeGen::DoHasCachedArrayIndexAndBranch(
2005 LHasCachedArrayIndexAndBranch* instr) { 1970 LHasCachedArrayIndexAndBranch* instr) {
2006 Register input = ToRegister(instr->value()); 1971 Register input = ToRegister(instr->InputAt(0));
2007 1972
2008 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1973 int true_block = chunk_->LookupDestination(instr->true_block_id());
2009 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1974 int false_block = chunk_->LookupDestination(instr->false_block_id());
2010 1975
2011 __ testl(FieldOperand(input, String::kHashFieldOffset), 1976 __ testl(FieldOperand(input, String::kHashFieldOffset),
2012 Immediate(String::kContainsCachedArrayIndexMask)); 1977 Immediate(String::kContainsCachedArrayIndexMask));
2013 EmitBranch(true_block, false_block, equal); 1978 EmitBranch(true_block, false_block, equal);
2014 } 1979 }
2015 1980
2016 1981
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2076 // classes and it doesn't have to because you can't access it with natives 2041 // classes and it doesn't have to because you can't access it with natives
2077 // syntax. Since both sides are symbols it is sufficient to use an identity 2042 // syntax. Since both sides are symbols it is sufficient to use an identity
2078 // comparison. 2043 // comparison.
2079 ASSERT(class_name->IsSymbol()); 2044 ASSERT(class_name->IsSymbol());
2080 __ Cmp(temp, class_name); 2045 __ Cmp(temp, class_name);
2081 // End with the answer in the z flag. 2046 // End with the answer in the z flag.
2082 } 2047 }
2083 2048
2084 2049
2085 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2050 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2086 Register input = ToRegister(instr->value()); 2051 Register input = ToRegister(instr->InputAt(0));
2087 Register temp = ToRegister(instr->temp()); 2052 Register temp = ToRegister(instr->TempAt(0));
2088 Register temp2 = ToRegister(instr->temp2()); 2053 Register temp2 = ToRegister(instr->TempAt(1));
2089 Handle<String> class_name = instr->hydrogen()->class_name(); 2054 Handle<String> class_name = instr->hydrogen()->class_name();
2090 2055
2091 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2056 int true_block = chunk_->LookupDestination(instr->true_block_id());
2092 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2057 int false_block = chunk_->LookupDestination(instr->false_block_id());
2093 2058
2094 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2059 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2095 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2060 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2096 2061
2097 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 2062 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
2098 2063
2099 EmitBranch(true_block, false_block, equal); 2064 EmitBranch(true_block, false_block, equal);
2100 } 2065 }
2101 2066
2102 2067
2103 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2068 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2104 Register reg = ToRegister(instr->value()); 2069 Register reg = ToRegister(instr->InputAt(0));
2105 int true_block = instr->true_block_id(); 2070 int true_block = instr->true_block_id();
2106 int false_block = instr->false_block_id(); 2071 int false_block = instr->false_block_id();
2107 2072
2108 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 2073 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2109 EmitBranch(true_block, false_block, equal); 2074 EmitBranch(true_block, false_block, equal);
2110 } 2075 }
2111 2076
2112 2077
2113 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2078 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2114 InstanceofStub stub(InstanceofStub::kNoFlags); 2079 InstanceofStub stub(InstanceofStub::kNoFlags);
2115 __ push(ToRegister(instr->left())); 2080 __ push(ToRegister(instr->InputAt(0)));
2116 __ push(ToRegister(instr->right())); 2081 __ push(ToRegister(instr->InputAt(1)));
2117 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2082 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2118 Label true_value, done; 2083 Label true_value, done;
2119 __ testq(rax, rax); 2084 __ testq(rax, rax);
2120 __ j(zero, &true_value, Label::kNear); 2085 __ j(zero, &true_value, Label::kNear);
2121 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); 2086 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2122 __ jmp(&done, Label::kNear); 2087 __ jmp(&done, Label::kNear);
2123 __ bind(&true_value); 2088 __ bind(&true_value);
2124 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); 2089 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2125 __ bind(&done); 2090 __ bind(&done);
2126 } 2091 }
(...skipping 13 matching lines...) Expand all
2140 private: 2105 private:
2141 LInstanceOfKnownGlobal* instr_; 2106 LInstanceOfKnownGlobal* instr_;
2142 Label map_check_; 2107 Label map_check_;
2143 }; 2108 };
2144 2109
2145 2110
2146 DeferredInstanceOfKnownGlobal* deferred; 2111 DeferredInstanceOfKnownGlobal* deferred;
2147 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 2112 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2148 2113
2149 Label done, false_result; 2114 Label done, false_result;
2150 Register object = ToRegister(instr->value()); 2115 Register object = ToRegister(instr->InputAt(0));
2151 2116
2152 // A Smi is not an instance of anything. 2117 // A Smi is not an instance of anything.
2153 __ JumpIfSmi(object, &false_result); 2118 __ JumpIfSmi(object, &false_result);
2154 2119
2155 // This is the inlined call site instanceof cache. The two occurences of the 2120 // This is the inlined call site instanceof cache. The two occurences of the
2156 // hole value will be patched to the last map/result pair generated by the 2121 // hole value will be patched to the last map/result pair generated by the
2157 // instanceof stub. 2122 // instanceof stub.
2158 Label cache_miss; 2123 Label cache_miss;
2159 // Use a temp register to avoid memory operands with variable lengths. 2124 // Use a temp register to avoid memory operands with variable lengths.
2160 Register map = ToRegister(instr->temp()); 2125 Register map = ToRegister(instr->TempAt(0));
2161 __ movq(map, FieldOperand(object, HeapObject::kMapOffset)); 2126 __ movq(map, FieldOperand(object, HeapObject::kMapOffset));
2162 __ bind(deferred->map_check()); // Label for calculating code patching. 2127 __ bind(deferred->map_check()); // Label for calculating code patching.
2163 Handle<JSGlobalPropertyCell> cache_cell = 2128 Handle<JSGlobalPropertyCell> cache_cell =
2164 factory()->NewJSGlobalPropertyCell(factory()->the_hole_value()); 2129 factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
2165 __ movq(kScratchRegister, cache_cell, RelocInfo::GLOBAL_PROPERTY_CELL); 2130 __ movq(kScratchRegister, cache_cell, RelocInfo::GLOBAL_PROPERTY_CELL);
2166 __ cmpq(map, Operand(kScratchRegister, 0)); 2131 __ cmpq(map, Operand(kScratchRegister, 0));
2167 __ j(not_equal, &cache_miss, Label::kNear); 2132 __ j(not_equal, &cache_miss, Label::kNear);
2168 // Patched to load either true or false. 2133 // Patched to load either true or false.
2169 __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); 2134 __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
2170 #ifdef DEBUG 2135 #ifdef DEBUG
(...skipping 22 matching lines...) Expand all
2193 2158
2194 2159
2195 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 2160 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
2196 Label* map_check) { 2161 Label* map_check) {
2197 { 2162 {
2198 PushSafepointRegistersScope scope(this); 2163 PushSafepointRegistersScope scope(this);
2199 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( 2164 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>(
2200 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck); 2165 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck);
2201 InstanceofStub stub(flags); 2166 InstanceofStub stub(flags);
2202 2167
2203 __ push(ToRegister(instr->value())); 2168 __ push(ToRegister(instr->InputAt(0)));
2204 __ PushHeapObject(instr->function()); 2169 __ PushHeapObject(instr->function());
2205 2170
2206 static const int kAdditionalDelta = 10; 2171 static const int kAdditionalDelta = 10;
2207 int delta = 2172 int delta =
2208 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 2173 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
2209 ASSERT(delta >= 0); 2174 ASSERT(delta >= 0);
2210 __ push_imm32(delta); 2175 __ push_imm32(delta);
2211 2176
2212 // We are pushing three values on the stack but recording a 2177 // We are pushing three values on the stack but recording a
2213 // safepoint with two arguments because stub is going to 2178 // safepoint with two arguments because stub is going to
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2293 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 2258 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2294 Register value = ToRegister(instr->value()); 2259 Register value = ToRegister(instr->value());
2295 Handle<JSGlobalPropertyCell> cell_handle = instr->hydrogen()->cell(); 2260 Handle<JSGlobalPropertyCell> cell_handle = instr->hydrogen()->cell();
2296 2261
2297 // If the cell we are storing to contains the hole it could have 2262 // If the cell we are storing to contains the hole it could have
2298 // been deleted from the property dictionary. In that case, we need 2263 // been deleted from the property dictionary. In that case, we need
2299 // to update the property details in the property dictionary to mark 2264 // to update the property details in the property dictionary to mark
2300 // it as no longer deleted. We deoptimize in that case. 2265 // it as no longer deleted. We deoptimize in that case.
2301 if (instr->hydrogen()->RequiresHoleCheck()) { 2266 if (instr->hydrogen()->RequiresHoleCheck()) {
2302 // We have a temp because CompareRoot might clobber kScratchRegister. 2267 // We have a temp because CompareRoot might clobber kScratchRegister.
2303 Register cell = ToRegister(instr->temp()); 2268 Register cell = ToRegister(instr->TempAt(0));
2304 ASSERT(!value.is(cell)); 2269 ASSERT(!value.is(cell));
2305 __ movq(cell, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL); 2270 __ movq(cell, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
2306 __ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex); 2271 __ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex);
2307 DeoptimizeIf(equal, instr->environment()); 2272 DeoptimizeIf(equal, instr->environment());
2308 // Store the value. 2273 // Store the value.
2309 __ movq(Operand(cell, 0), value); 2274 __ movq(Operand(cell, 0), value);
2310 } else { 2275 } else {
2311 // Store the value. 2276 // Store the value.
2312 __ movq(kScratchRegister, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL); 2277 __ movq(kScratchRegister, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
2313 __ movq(Operand(kScratchRegister, 0), value); 2278 __ movq(Operand(kScratchRegister, 0), value);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2361 __ j(not_equal, &skip_assignment); 2326 __ j(not_equal, &skip_assignment);
2362 } 2327 }
2363 } 2328 }
2364 __ movq(target, value); 2329 __ movq(target, value);
2365 2330
2366 if (instr->hydrogen()->NeedsWriteBarrier()) { 2331 if (instr->hydrogen()->NeedsWriteBarrier()) {
2367 HType type = instr->hydrogen()->value()->type(); 2332 HType type = instr->hydrogen()->value()->type();
2368 SmiCheck check_needed = 2333 SmiCheck check_needed =
2369 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2334 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2370 int offset = Context::SlotOffset(instr->slot_index()); 2335 int offset = Context::SlotOffset(instr->slot_index());
2371 Register scratch = ToRegister(instr->temp()); 2336 Register scratch = ToRegister(instr->TempAt(0));
2372 __ RecordWriteContextSlot(context, 2337 __ RecordWriteContextSlot(context,
2373 offset, 2338 offset,
2374 value, 2339 value,
2375 scratch, 2340 scratch,
2376 kSaveFPRegs, 2341 kSaveFPRegs,
2377 EMIT_REMEMBERED_SET, 2342 EMIT_REMEMBERED_SET,
2378 check_needed); 2343 check_needed);
2379 } 2344 }
2380 2345
2381 __ bind(&skip_assignment); 2346 __ bind(&skip_assignment);
2382 } 2347 }
2383 2348
2384 2349
2385 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 2350 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2386 Register object = ToRegister(instr->object()); 2351 Register object = ToRegister(instr->InputAt(0));
2387 Register result = ToRegister(instr->result()); 2352 Register result = ToRegister(instr->result());
2388 if (instr->hydrogen()->is_in_object()) { 2353 if (instr->hydrogen()->is_in_object()) {
2389 __ movq(result, FieldOperand(object, instr->hydrogen()->offset())); 2354 __ movq(result, FieldOperand(object, instr->hydrogen()->offset()));
2390 } else { 2355 } else {
2391 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2356 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
2392 __ movq(result, FieldOperand(result, instr->hydrogen()->offset())); 2357 __ movq(result, FieldOperand(result, instr->hydrogen()->offset()));
2393 } 2358 }
2394 } 2359 }
2395 2360
2396 2361
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
2548 __ bind(&non_instance); 2513 __ bind(&non_instance);
2549 __ movq(result, FieldOperand(result, Map::kConstructorOffset)); 2514 __ movq(result, FieldOperand(result, Map::kConstructorOffset));
2550 2515
2551 // All done. 2516 // All done.
2552 __ bind(&done); 2517 __ bind(&done);
2553 } 2518 }
2554 2519
2555 2520
2556 void LCodeGen::DoLoadElements(LLoadElements* instr) { 2521 void LCodeGen::DoLoadElements(LLoadElements* instr) {
2557 Register result = ToRegister(instr->result()); 2522 Register result = ToRegister(instr->result());
2558 Register input = ToRegister(instr->object()); 2523 Register input = ToRegister(instr->InputAt(0));
2559 __ movq(result, FieldOperand(input, JSObject::kElementsOffset)); 2524 __ movq(result, FieldOperand(input, JSObject::kElementsOffset));
2560 if (FLAG_debug_code) { 2525 if (FLAG_debug_code) {
2561 Label done, ok, fail; 2526 Label done, ok, fail;
2562 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), 2527 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
2563 Heap::kFixedArrayMapRootIndex); 2528 Heap::kFixedArrayMapRootIndex);
2564 __ j(equal, &done, Label::kNear); 2529 __ j(equal, &done, Label::kNear);
2565 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), 2530 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
2566 Heap::kFixedCOWArrayMapRootIndex); 2531 Heap::kFixedCOWArrayMapRootIndex);
2567 __ j(equal, &done, Label::kNear); 2532 __ j(equal, &done, Label::kNear);
2568 Register temp((result.is(rax)) ? rbx : rax); 2533 Register temp((result.is(rax)) ? rbx : rax);
(...skipping 15 matching lines...) Expand all
2584 __ bind(&ok); 2549 __ bind(&ok);
2585 __ pop(temp); 2550 __ pop(temp);
2586 __ bind(&done); 2551 __ bind(&done);
2587 } 2552 }
2588 } 2553 }
2589 2554
2590 2555
2591 void LCodeGen::DoLoadExternalArrayPointer( 2556 void LCodeGen::DoLoadExternalArrayPointer(
2592 LLoadExternalArrayPointer* instr) { 2557 LLoadExternalArrayPointer* instr) {
2593 Register result = ToRegister(instr->result()); 2558 Register result = ToRegister(instr->result());
2594 Register input = ToRegister(instr->object()); 2559 Register input = ToRegister(instr->InputAt(0));
2595 __ movq(result, FieldOperand(input, 2560 __ movq(result, FieldOperand(input,
2596 ExternalPixelArray::kExternalPointerOffset)); 2561 ExternalPixelArray::kExternalPointerOffset));
2597 } 2562 }
2598 2563
2599 2564
2600 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2565 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2601 Register arguments = ToRegister(instr->arguments()); 2566 Register arguments = ToRegister(instr->arguments());
2602 Register length = ToRegister(instr->length()); 2567 Register length = ToRegister(instr->length());
2603 Register result = ToRegister(instr->result()); 2568 Register result = ToRegister(instr->result());
2604 2569
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2832 } 2797 }
2833 } 2798 }
2834 2799
2835 2800
2836 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 2801 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
2837 Register result = ToRegister(instr->result()); 2802 Register result = ToRegister(instr->result());
2838 2803
2839 Label done; 2804 Label done;
2840 2805
2841 // If no arguments adaptor frame the number of arguments is fixed. 2806 // If no arguments adaptor frame the number of arguments is fixed.
2842 if (instr->elements()->IsRegister()) { 2807 if (instr->InputAt(0)->IsRegister()) {
2843 __ cmpq(rbp, ToRegister(instr->elements())); 2808 __ cmpq(rbp, ToRegister(instr->InputAt(0)));
2844 } else { 2809 } else {
2845 __ cmpq(rbp, ToOperand(instr->elements())); 2810 __ cmpq(rbp, ToOperand(instr->InputAt(0)));
2846 } 2811 }
2847 __ movl(result, Immediate(scope()->num_parameters())); 2812 __ movl(result, Immediate(scope()->num_parameters()));
2848 __ j(equal, &done, Label::kNear); 2813 __ j(equal, &done, Label::kNear);
2849 2814
2850 // Arguments adaptor frame present. Get argument length from there. 2815 // Arguments adaptor frame present. Get argument length from there.
2851 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 2816 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2852 __ SmiToInteger32(result, 2817 __ SmiToInteger32(result,
2853 Operand(result, 2818 Operand(result,
2854 ArgumentsAdaptorFrameConstants::kLengthOffset)); 2819 ArgumentsAdaptorFrameConstants::kLengthOffset));
2855 2820
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2943 SafepointGenerator safepoint_generator( 2908 SafepointGenerator safepoint_generator(
2944 this, pointers, Safepoint::kLazyDeopt); 2909 this, pointers, Safepoint::kLazyDeopt);
2945 ParameterCount actual(rax); 2910 ParameterCount actual(rax);
2946 __ InvokeFunction(function, actual, CALL_FUNCTION, 2911 __ InvokeFunction(function, actual, CALL_FUNCTION,
2947 safepoint_generator, CALL_AS_METHOD); 2912 safepoint_generator, CALL_AS_METHOD);
2948 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2913 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2949 } 2914 }
2950 2915
2951 2916
2952 void LCodeGen::DoPushArgument(LPushArgument* instr) { 2917 void LCodeGen::DoPushArgument(LPushArgument* instr) {
2953 LOperand* argument = instr->value(); 2918 LOperand* argument = instr->InputAt(0);
2954 EmitPushTaggedOperand(argument); 2919 EmitPushTaggedOperand(argument);
2955 } 2920 }
2956 2921
2957 2922
2958 void LCodeGen::DoDrop(LDrop* instr) { 2923 void LCodeGen::DoDrop(LDrop* instr) {
2959 __ Drop(instr->count()); 2924 __ Drop(instr->count());
2960 } 2925 }
2961 2926
2962 2927
2963 void LCodeGen::DoThisFunction(LThisFunction* instr) { 2928 void LCodeGen::DoThisFunction(LThisFunction* instr) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3053 ASSERT(ToRegister(instr->result()).is(rax)); 3018 ASSERT(ToRegister(instr->result()).is(rax));
3054 CallKnownFunction(instr->function(), 3019 CallKnownFunction(instr->function(),
3055 instr->arity(), 3020 instr->arity(),
3056 instr, 3021 instr,
3057 CALL_AS_METHOD, 3022 CALL_AS_METHOD,
3058 RDI_UNINITIALIZED); 3023 RDI_UNINITIALIZED);
3059 } 3024 }
3060 3025
3061 3026
3062 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 3027 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
3063 Register input_reg = ToRegister(instr->value()); 3028 Register input_reg = ToRegister(instr->InputAt(0));
3064 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 3029 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
3065 Heap::kHeapNumberMapRootIndex); 3030 Heap::kHeapNumberMapRootIndex);
3066 DeoptimizeIf(not_equal, instr->environment()); 3031 DeoptimizeIf(not_equal, instr->environment());
3067 3032
3068 Label done; 3033 Label done;
3069 Register tmp = input_reg.is(rax) ? rcx : rax; 3034 Register tmp = input_reg.is(rax) ? rcx : rax;
3070 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx; 3035 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx;
3071 3036
3072 // Preserve the value of all registers. 3037 // Preserve the value of all registers.
3073 PushSafepointRegistersScope scope(this); 3038 PushSafepointRegistersScope scope(this);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3105 __ shl(tmp2, Immediate(1)); 3070 __ shl(tmp2, Immediate(1));
3106 __ shr(tmp2, Immediate(1)); 3071 __ shr(tmp2, Immediate(1));
3107 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); 3072 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
3108 __ StoreToSafepointRegisterSlot(input_reg, tmp); 3073 __ StoreToSafepointRegisterSlot(input_reg, tmp);
3109 3074
3110 __ bind(&done); 3075 __ bind(&done);
3111 } 3076 }
3112 3077
3113 3078
3114 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 3079 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
3115 Register input_reg = ToRegister(instr->value()); 3080 Register input_reg = ToRegister(instr->InputAt(0));
3116 __ testl(input_reg, input_reg); 3081 __ testl(input_reg, input_reg);
3117 Label is_positive; 3082 Label is_positive;
3118 __ j(not_sign, &is_positive); 3083 __ j(not_sign, &is_positive);
3119 __ negl(input_reg); // Sets flags. 3084 __ negl(input_reg); // Sets flags.
3120 DeoptimizeIf(negative, instr->environment()); 3085 DeoptimizeIf(negative, instr->environment());
3121 __ bind(&is_positive); 3086 __ bind(&is_positive);
3122 } 3087 }
3123 3088
3124 3089
3125 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 3090 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
3126 // Class for deferred case. 3091 // Class for deferred case.
3127 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3092 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3128 public: 3093 public:
3129 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3094 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
3130 LUnaryMathOperation* instr) 3095 LUnaryMathOperation* instr)
3131 : LDeferredCode(codegen), instr_(instr) { } 3096 : LDeferredCode(codegen), instr_(instr) { }
3132 virtual void Generate() { 3097 virtual void Generate() {
3133 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3098 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3134 } 3099 }
3135 virtual LInstruction* instr() { return instr_; } 3100 virtual LInstruction* instr() { return instr_; }
3136 private: 3101 private:
3137 LUnaryMathOperation* instr_; 3102 LUnaryMathOperation* instr_;
3138 }; 3103 };
3139 3104
3140 ASSERT(instr->value()->Equals(instr->result())); 3105 ASSERT(instr->InputAt(0)->Equals(instr->result()));
3141 Representation r = instr->hydrogen()->value()->representation(); 3106 Representation r = instr->hydrogen()->value()->representation();
3142 3107
3143 if (r.IsDouble()) { 3108 if (r.IsDouble()) {
3144 XMMRegister scratch = xmm0; 3109 XMMRegister scratch = xmm0;
3145 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3110 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
3146 __ xorps(scratch, scratch); 3111 __ xorps(scratch, scratch);
3147 __ subsd(scratch, input_reg); 3112 __ subsd(scratch, input_reg);
3148 __ andpd(input_reg, scratch); 3113 __ andpd(input_reg, scratch);
3149 } else if (r.IsInteger32()) { 3114 } else if (r.IsInteger32()) {
3150 EmitIntegerMathAbs(instr); 3115 EmitIntegerMathAbs(instr);
3151 } else { // Tagged case. 3116 } else { // Tagged case.
3152 DeferredMathAbsTaggedHeapNumber* deferred = 3117 DeferredMathAbsTaggedHeapNumber* deferred =
3153 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 3118 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3154 Register input_reg = ToRegister(instr->value()); 3119 Register input_reg = ToRegister(instr->InputAt(0));
3155 // Smi check. 3120 // Smi check.
3156 __ JumpIfNotSmi(input_reg, deferred->entry()); 3121 __ JumpIfNotSmi(input_reg, deferred->entry());
3157 __ SmiToInteger32(input_reg, input_reg); 3122 __ SmiToInteger32(input_reg, input_reg);
3158 EmitIntegerMathAbs(instr); 3123 EmitIntegerMathAbs(instr);
3159 __ Integer32ToSmi(input_reg, input_reg); 3124 __ Integer32ToSmi(input_reg, input_reg);
3160 __ bind(deferred->exit()); 3125 __ bind(deferred->exit());
3161 } 3126 }
3162 } 3127 }
3163 3128
3164 3129
3165 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 3130 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
3166 XMMRegister xmm_scratch = xmm0; 3131 XMMRegister xmm_scratch = xmm0;
3167 Register output_reg = ToRegister(instr->result()); 3132 Register output_reg = ToRegister(instr->result());
3168 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3133 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
3169 3134
3170 if (CpuFeatures::IsSupported(SSE4_1)) { 3135 if (CpuFeatures::IsSupported(SSE4_1)) {
3171 CpuFeatures::Scope scope(SSE4_1); 3136 CpuFeatures::Scope scope(SSE4_1);
3172 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3137 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3173 // Deoptimize if minus zero. 3138 // Deoptimize if minus zero.
3174 __ movq(output_reg, input_reg); 3139 __ movq(output_reg, input_reg);
3175 __ subq(output_reg, Immediate(1)); 3140 __ subq(output_reg, Immediate(1));
3176 DeoptimizeIf(overflow, instr->environment()); 3141 DeoptimizeIf(overflow, instr->environment());
3177 } 3142 }
3178 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown); 3143 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3217 DeoptimizeIf(overflow, instr->environment()); 3182 DeoptimizeIf(overflow, instr->environment());
3218 3183
3219 __ bind(&done); 3184 __ bind(&done);
3220 } 3185 }
3221 } 3186 }
3222 3187
3223 3188
3224 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 3189 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
3225 const XMMRegister xmm_scratch = xmm0; 3190 const XMMRegister xmm_scratch = xmm0;
3226 Register output_reg = ToRegister(instr->result()); 3191 Register output_reg = ToRegister(instr->result());
3227 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3192 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
3228 3193
3229 Label done; 3194 Label done;
3230 // xmm_scratch = 0.5 3195 // xmm_scratch = 0.5
3231 __ movq(kScratchRegister, V8_INT64_C(0x3FE0000000000000), RelocInfo::NONE); 3196 __ movq(kScratchRegister, V8_INT64_C(0x3FE0000000000000), RelocInfo::NONE);
3232 __ movq(xmm_scratch, kScratchRegister); 3197 __ movq(xmm_scratch, kScratchRegister);
3233 Label below_half; 3198 Label below_half;
3234 __ ucomisd(xmm_scratch, input_reg); 3199 __ ucomisd(xmm_scratch, input_reg);
3235 // If input_reg is NaN, this doesn't jump. 3200 // If input_reg is NaN, this doesn't jump.
3236 __ j(above, &below_half, Label::kNear); 3201 __ j(above, &below_half, Label::kNear);
3237 // input = input + 0.5 3202 // input = input + 0.5
(...skipping 24 matching lines...) Expand all
3262 __ ucomisd(input_reg, xmm_scratch); 3227 __ ucomisd(input_reg, xmm_scratch);
3263 DeoptimizeIf(below, instr->environment()); 3228 DeoptimizeIf(below, instr->environment());
3264 } 3229 }
3265 __ xorl(output_reg, output_reg); 3230 __ xorl(output_reg, output_reg);
3266 3231
3267 __ bind(&done); 3232 __ bind(&done);
3268 } 3233 }
3269 3234
3270 3235
3271 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3236 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3272 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3237 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
3273 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 3238 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3274 __ sqrtsd(input_reg, input_reg); 3239 __ sqrtsd(input_reg, input_reg);
3275 } 3240 }
3276 3241
3277 3242
3278 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3243 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
3279 XMMRegister xmm_scratch = xmm0; 3244 XMMRegister xmm_scratch = xmm0;
3280 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3245 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
3281 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 3246 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3282 3247
3283 // Note that according to ECMA-262 15.8.2.13: 3248 // Note that according to ECMA-262 15.8.2.13:
3284 // Math.pow(-Infinity, 0.5) == Infinity 3249 // Math.pow(-Infinity, 0.5) == Infinity
3285 // Math.sqrt(-Infinity) == NaN 3250 // Math.sqrt(-Infinity) == NaN
3286 Label done, sqrt; 3251 Label done, sqrt;
3287 // Check base for -Infinity. According to IEEE-754, double-precision 3252 // Check base for -Infinity. According to IEEE-754, double-precision
3288 // -Infinity has the highest 12 bits set and the lowest 52 bits cleared. 3253 // -Infinity has the highest 12 bits set and the lowest 52 bits cleared.
3289 __ movq(kScratchRegister, V8_INT64_C(0xFFF0000000000000), RelocInfo::NONE); 3254 __ movq(kScratchRegister, V8_INT64_C(0xFFF0000000000000), RelocInfo::NONE);
3290 __ movq(xmm_scratch, kScratchRegister); 3255 __ movq(xmm_scratch, kScratchRegister);
(...skipping 20 matching lines...) Expand all
3311 Representation exponent_type = instr->hydrogen()->right()->representation(); 3276 Representation exponent_type = instr->hydrogen()->right()->representation();
3312 // Having marked this as a call, we can use any registers. 3277 // Having marked this as a call, we can use any registers.
3313 // Just make sure that the input/output registers are the expected ones. 3278 // Just make sure that the input/output registers are the expected ones.
3314 3279
3315 // Choose register conforming to calling convention (when bailing out). 3280 // Choose register conforming to calling convention (when bailing out).
3316 #ifdef _WIN64 3281 #ifdef _WIN64
3317 Register exponent = rdx; 3282 Register exponent = rdx;
3318 #else 3283 #else
3319 Register exponent = rdi; 3284 Register exponent = rdi;
3320 #endif 3285 #endif
3321 ASSERT(!instr->right()->IsRegister() || 3286 ASSERT(!instr->InputAt(1)->IsRegister() ||
3322 ToRegister(instr->right()).is(exponent)); 3287 ToRegister(instr->InputAt(1)).is(exponent));
3323 ASSERT(!instr->right()->IsDoubleRegister() || 3288 ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
3324 ToDoubleRegister(instr->right()).is(xmm1)); 3289 ToDoubleRegister(instr->InputAt(1)).is(xmm1));
3325 ASSERT(ToDoubleRegister(instr->left()).is(xmm2)); 3290 ASSERT(ToDoubleRegister(instr->InputAt(0)).is(xmm2));
3326 ASSERT(ToDoubleRegister(instr->result()).is(xmm3)); 3291 ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
3327 3292
3328 if (exponent_type.IsTagged()) { 3293 if (exponent_type.IsTagged()) {
3329 Label no_deopt; 3294 Label no_deopt;
3330 __ JumpIfSmi(exponent, &no_deopt); 3295 __ JumpIfSmi(exponent, &no_deopt);
3331 __ CmpObjectType(exponent, HEAP_NUMBER_TYPE, rcx); 3296 __ CmpObjectType(exponent, HEAP_NUMBER_TYPE, rcx);
3332 DeoptimizeIf(not_equal, instr->environment()); 3297 DeoptimizeIf(not_equal, instr->environment());
3333 __ bind(&no_deopt); 3298 __ bind(&no_deopt);
3334 MathPowStub stub(MathPowStub::TAGGED); 3299 MathPowStub stub(MathPowStub::TAGGED);
3335 __ CallStub(&stub); 3300 __ CallStub(&stub);
(...skipping 21 matching lines...) Expand all
3357 3322
3358 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 3323 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3359 3324
3360 // Having marked this instruction as a call we can use any 3325 // Having marked this instruction as a call we can use any
3361 // registers. 3326 // registers.
3362 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3327 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3363 3328
3364 // Choose the right register for the first argument depending on 3329 // Choose the right register for the first argument depending on
3365 // calling convention. 3330 // calling convention.
3366 #ifdef _WIN64 3331 #ifdef _WIN64
3367 ASSERT(ToRegister(instr->global_object()).is(rcx)); 3332 ASSERT(ToRegister(instr->InputAt(0)).is(rcx));
3368 Register global_object = rcx; 3333 Register global_object = rcx;
3369 #else 3334 #else
3370 ASSERT(ToRegister(instr->global_object()).is(rdi)); 3335 ASSERT(ToRegister(instr->InputAt(0)).is(rdi));
3371 Register global_object = rdi; 3336 Register global_object = rdi;
3372 #endif 3337 #endif
3373 3338
3374 static const int kSeedSize = sizeof(uint32_t); 3339 static const int kSeedSize = sizeof(uint32_t);
3375 STATIC_ASSERT(kPointerSize == 2 * kSeedSize); 3340 STATIC_ASSERT(kPointerSize == 2 * kSeedSize);
3376 3341
3377 __ movq(global_object, 3342 __ movq(global_object,
3378 FieldOperand(global_object, GlobalObject::kNativeContextOffset)); 3343 FieldOperand(global_object, GlobalObject::kNativeContextOffset));
3379 static const int kRandomSeedOffset = 3344 static const int kRandomSeedOffset =
3380 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize; 3345 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
3575 ASSERT(ToRegister(instr->result()).is(rax)); 3540 ASSERT(ToRegister(instr->result()).is(rax));
3576 CallKnownFunction(instr->target(), 3541 CallKnownFunction(instr->target(),
3577 instr->arity(), 3542 instr->arity(),
3578 instr, 3543 instr,
3579 CALL_AS_FUNCTION, 3544 CALL_AS_FUNCTION,
3580 RDI_UNINITIALIZED); 3545 RDI_UNINITIALIZED);
3581 } 3546 }
3582 3547
3583 3548
3584 void LCodeGen::DoCallNew(LCallNew* instr) { 3549 void LCodeGen::DoCallNew(LCallNew* instr) {
3585 ASSERT(ToRegister(instr->constructor()).is(rdi)); 3550 ASSERT(ToRegister(instr->InputAt(0)).is(rdi));
3586 ASSERT(ToRegister(instr->result()).is(rax)); 3551 ASSERT(ToRegister(instr->result()).is(rax));
3587 3552
3588 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 3553 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
3589 __ Set(rax, instr->arity()); 3554 __ Set(rax, instr->arity());
3590 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 3555 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3591 } 3556 }
3592 3557
3593 3558
3594 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 3559 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3595 CallRuntime(instr->function(), instr->arity(), instr); 3560 CallRuntime(instr->function(), instr->arity(), instr);
3596 } 3561 }
3597 3562
3598 3563
3599 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 3564 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3600 Register object = ToRegister(instr->object()); 3565 Register object = ToRegister(instr->object());
3601 Register value = ToRegister(instr->value()); 3566 Register value = ToRegister(instr->value());
3602 int offset = instr->offset(); 3567 int offset = instr->offset();
3603 3568
3604 if (!instr->transition().is_null()) { 3569 if (!instr->transition().is_null()) {
3605 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { 3570 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
3606 __ Move(FieldOperand(object, HeapObject::kMapOffset), 3571 __ Move(FieldOperand(object, HeapObject::kMapOffset),
3607 instr->transition()); 3572 instr->transition());
3608 } else { 3573 } else {
3609 Register temp = ToRegister(instr->temp()); 3574 Register temp = ToRegister(instr->TempAt(0));
3610 __ Move(kScratchRegister, instr->transition()); 3575 __ Move(kScratchRegister, instr->transition());
3611 __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister); 3576 __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister);
3612 // Update the write barrier for the map field. 3577 // Update the write barrier for the map field.
3613 __ RecordWriteField(object, 3578 __ RecordWriteField(object,
3614 HeapObject::kMapOffset, 3579 HeapObject::kMapOffset,
3615 kScratchRegister, 3580 kScratchRegister,
3616 temp, 3581 temp,
3617 kSaveFPRegs, 3582 kSaveFPRegs,
3618 OMIT_REMEMBERED_SET, 3583 OMIT_REMEMBERED_SET,
3619 OMIT_SMI_CHECK); 3584 OMIT_SMI_CHECK);
3620 } 3585 }
3621 } 3586 }
3622 3587
3623 // Do the store. 3588 // Do the store.
3624 HType type = instr->hydrogen()->value()->type(); 3589 HType type = instr->hydrogen()->value()->type();
3625 SmiCheck check_needed = 3590 SmiCheck check_needed =
3626 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3591 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3627 if (instr->is_in_object()) { 3592 if (instr->is_in_object()) {
3628 __ movq(FieldOperand(object, offset), value); 3593 __ movq(FieldOperand(object, offset), value);
3629 if (instr->hydrogen()->NeedsWriteBarrier()) { 3594 if (instr->hydrogen()->NeedsWriteBarrier()) {
3630 Register temp = ToRegister(instr->temp()); 3595 Register temp = ToRegister(instr->TempAt(0));
3631 // Update the write barrier for the object for in-object properties. 3596 // Update the write barrier for the object for in-object properties.
3632 __ RecordWriteField(object, 3597 __ RecordWriteField(object,
3633 offset, 3598 offset,
3634 value, 3599 value,
3635 temp, 3600 temp,
3636 kSaveFPRegs, 3601 kSaveFPRegs,
3637 EMIT_REMEMBERED_SET, 3602 EMIT_REMEMBERED_SET,
3638 check_needed); 3603 check_needed);
3639 } 3604 }
3640 } else { 3605 } else {
3641 Register temp = ToRegister(instr->temp()); 3606 Register temp = ToRegister(instr->TempAt(0));
3642 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset)); 3607 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset));
3643 __ movq(FieldOperand(temp, offset), value); 3608 __ movq(FieldOperand(temp, offset), value);
3644 if (instr->hydrogen()->NeedsWriteBarrier()) { 3609 if (instr->hydrogen()->NeedsWriteBarrier()) {
3645 // Update the write barrier for the properties array. 3610 // Update the write barrier for the properties array.
3646 // object is used as a scratch register. 3611 // object is used as a scratch register.
3647 __ RecordWriteField(temp, 3612 __ RecordWriteField(temp,
3648 offset, 3613 offset,
3649 value, 3614 value,
3650 object, 3615 object,
3651 kSaveFPRegs, 3616 kSaveFPRegs,
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3770 } 3735 }
3771 } else { 3736 } else {
3772 Register reg2 = ToRegister(instr->index()); 3737 Register reg2 = ToRegister(instr->index());
3773 if (FLAG_debug_code && 3738 if (FLAG_debug_code &&
3774 !instr->hydrogen()->index()->representation().IsTagged()) { 3739 !instr->hydrogen()->index()->representation().IsTagged()) {
3775 __ AbortIfNotZeroExtended(reg2); 3740 __ AbortIfNotZeroExtended(reg2);
3776 } 3741 }
3777 __ cmpq(reg, reg2); 3742 __ cmpq(reg, reg2);
3778 } 3743 }
3779 } else { 3744 } else {
3780 Operand length = ToOperand(instr->length());
3781 if (instr->index()->IsConstantOperand()) { 3745 if (instr->index()->IsConstantOperand()) {
3782 int constant_index = 3746 __ cmpq(ToOperand(instr->length()),
3783 ToInteger32(LConstantOperand::cast(instr->index())); 3747 Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
3784 if (instr->hydrogen()->length()->representation().IsTagged()) {
3785 __ Cmp(length, Smi::FromInt(constant_index));
3786 } else {
3787 __ cmpq(length, Immediate(constant_index));
3788 }
3789 } else { 3748 } else {
3790 __ cmpq(length, ToRegister(instr->index())); 3749 __ cmpq(ToOperand(instr->length()), ToRegister(instr->index()));
3791 } 3750 }
3792 } 3751 }
3793 DeoptimizeIf(below_equal, instr->environment()); 3752 DeoptimizeIf(below_equal, instr->environment());
3794 } 3753 }
3795 3754
3796 3755
3797 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3756 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
3798 Register value = ToRegister(instr->value()); 3757 Register value = ToRegister(instr->value());
3799 Register elements = ToRegister(instr->object()); 3758 Register elements = ToRegister(instr->object());
3800 LOperand* key = instr->key(); 3759 LOperand* key = instr->key();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3890 3849
3891 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3850 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3892 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3851 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3893 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3852 : isolate()->builtins()->KeyedStoreIC_Initialize();
3894 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3853 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3895 } 3854 }
3896 3855
3897 3856
3898 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 3857 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
3899 Register object_reg = ToRegister(instr->object()); 3858 Register object_reg = ToRegister(instr->object());
3900 Register new_map_reg = ToRegister(instr->new_map_temp()); 3859 Register new_map_reg = ToRegister(instr->new_map_reg());
3901 3860
3902 Handle<Map> from_map = instr->original_map(); 3861 Handle<Map> from_map = instr->original_map();
3903 Handle<Map> to_map = instr->transitioned_map(); 3862 Handle<Map> to_map = instr->transitioned_map();
3904 ElementsKind from_kind = from_map->elements_kind(); 3863 ElementsKind from_kind = from_map->elements_kind();
3905 ElementsKind to_kind = to_map->elements_kind(); 3864 ElementsKind to_kind = to_map->elements_kind();
3906 3865
3907 Label not_applicable; 3866 Label not_applicable;
3908 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 3867 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
3909 __ j(not_equal, &not_applicable); 3868 __ j(not_equal, &not_applicable);
3910 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); 3869 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT);
3911 if (IsSimpleMapChangeTransition(from_kind, to_kind)) { 3870 if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
3912 __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); 3871 __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg);
3913 // Write barrier. 3872 // Write barrier.
3914 ASSERT_NE(instr->temp(), NULL); 3873 ASSERT_NE(instr->temp_reg(), NULL);
3915 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 3874 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
3916 ToRegister(instr->temp()), kDontSaveFPRegs); 3875 ToRegister(instr->temp_reg()), kDontSaveFPRegs);
3917 } else if (IsFastSmiElementsKind(from_kind) && 3876 } else if (IsFastSmiElementsKind(from_kind) &&
3918 IsFastDoubleElementsKind(to_kind)) { 3877 IsFastDoubleElementsKind(to_kind)) {
3919 Register fixed_object_reg = ToRegister(instr->temp()); 3878 Register fixed_object_reg = ToRegister(instr->temp_reg());
3920 ASSERT(fixed_object_reg.is(rdx)); 3879 ASSERT(fixed_object_reg.is(rdx));
3921 ASSERT(new_map_reg.is(rbx)); 3880 ASSERT(new_map_reg.is(rbx));
3922 __ movq(fixed_object_reg, object_reg); 3881 __ movq(fixed_object_reg, object_reg);
3923 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 3882 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
3924 RelocInfo::CODE_TARGET, instr); 3883 RelocInfo::CODE_TARGET, instr);
3925 } else if (IsFastDoubleElementsKind(from_kind) && 3884 } else if (IsFastDoubleElementsKind(from_kind) &&
3926 IsFastObjectElementsKind(to_kind)) { 3885 IsFastObjectElementsKind(to_kind)) {
3927 Register fixed_object_reg = ToRegister(instr->temp()); 3886 Register fixed_object_reg = ToRegister(instr->temp_reg());
3928 ASSERT(fixed_object_reg.is(rdx)); 3887 ASSERT(fixed_object_reg.is(rdx));
3929 ASSERT(new_map_reg.is(rbx)); 3888 ASSERT(new_map_reg.is(rbx));
3930 __ movq(fixed_object_reg, object_reg); 3889 __ movq(fixed_object_reg, object_reg);
3931 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 3890 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
3932 RelocInfo::CODE_TARGET, instr); 3891 RelocInfo::CODE_TARGET, instr);
3933 } else { 3892 } else {
3934 UNREACHABLE(); 3893 UNREACHABLE();
3935 } 3894 }
3936 __ bind(&not_applicable); 3895 __ bind(&not_applicable);
3937 } 3896 }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
4048 4007
4049 4008
4050 void LCodeGen::DoStringLength(LStringLength* instr) { 4009 void LCodeGen::DoStringLength(LStringLength* instr) {
4051 Register string = ToRegister(instr->string()); 4010 Register string = ToRegister(instr->string());
4052 Register result = ToRegister(instr->result()); 4011 Register result = ToRegister(instr->result());
4053 __ movq(result, FieldOperand(string, String::kLengthOffset)); 4012 __ movq(result, FieldOperand(string, String::kLengthOffset));
4054 } 4013 }
4055 4014
4056 4015
4057 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4016 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4058 LOperand* input = instr->value(); 4017 LOperand* input = instr->InputAt(0);
4059 ASSERT(input->IsRegister() || input->IsStackSlot()); 4018 ASSERT(input->IsRegister() || input->IsStackSlot());
4060 LOperand* output = instr->result(); 4019 LOperand* output = instr->result();
4061 ASSERT(output->IsDoubleRegister()); 4020 ASSERT(output->IsDoubleRegister());
4062 if (input->IsRegister()) { 4021 if (input->IsRegister()) {
4063 __ cvtlsi2sd(ToDoubleRegister(output), ToRegister(input)); 4022 __ cvtlsi2sd(ToDoubleRegister(output), ToRegister(input));
4064 } else { 4023 } else {
4065 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input)); 4024 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input));
4066 } 4025 }
4067 } 4026 }
4068 4027
4069 4028
4070 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4029 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4071 LOperand* input = instr->value(); 4030 LOperand* input = instr->InputAt(0);
4072 LOperand* output = instr->result(); 4031 LOperand* output = instr->result();
4073 LOperand* temp = instr->temp(); 4032 LOperand* temp = instr->TempAt(0);
4074 4033
4075 __ LoadUint32(ToDoubleRegister(output), 4034 __ LoadUint32(ToDoubleRegister(output),
4076 ToRegister(input), 4035 ToRegister(input),
4077 ToDoubleRegister(temp)); 4036 ToDoubleRegister(temp));
4078 } 4037 }
4079 4038
4080 4039
4081 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4040 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4082 LOperand* input = instr->value(); 4041 LOperand* input = instr->InputAt(0);
4083 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4042 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4084 Register reg = ToRegister(input); 4043 Register reg = ToRegister(input);
4085 4044
4086 __ Integer32ToSmi(reg, reg); 4045 __ Integer32ToSmi(reg, reg);
4087 } 4046 }
4088 4047
4089 4048
4090 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4049 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4091 class DeferredNumberTagU: public LDeferredCode { 4050 class DeferredNumberTagU: public LDeferredCode {
4092 public: 4051 public:
4093 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 4052 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4094 : LDeferredCode(codegen), instr_(instr) { } 4053 : LDeferredCode(codegen), instr_(instr) { }
4095 virtual void Generate() { 4054 virtual void Generate() {
4096 codegen()->DoDeferredNumberTagU(instr_); 4055 codegen()->DoDeferredNumberTagU(instr_);
4097 } 4056 }
4098 virtual LInstruction* instr() { return instr_; } 4057 virtual LInstruction* instr() { return instr_; }
4099 private: 4058 private:
4100 LNumberTagU* instr_; 4059 LNumberTagU* instr_;
4101 }; 4060 };
4102 4061
4103 LOperand* input = instr->value(); 4062 LOperand* input = instr->InputAt(0);
4104 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4063 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4105 Register reg = ToRegister(input); 4064 Register reg = ToRegister(input);
4106 4065
4107 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4066 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4108 __ cmpl(reg, Immediate(Smi::kMaxValue)); 4067 __ cmpl(reg, Immediate(Smi::kMaxValue));
4109 __ j(above, deferred->entry()); 4068 __ j(above, deferred->entry());
4110 __ Integer32ToSmi(reg, reg); 4069 __ Integer32ToSmi(reg, reg);
4111 __ bind(deferred->exit()); 4070 __ bind(deferred->exit());
4112 } 4071 }
4113 4072
4114 4073
4115 void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) { 4074 void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) {
4116 Label slow; 4075 Label slow;
4117 Register reg = ToRegister(instr->value()); 4076 Register reg = ToRegister(instr->InputAt(0));
4118 Register tmp = reg.is(rax) ? rcx : rax; 4077 Register tmp = reg.is(rax) ? rcx : rax;
4119 4078
4120 // Preserve the value of all registers. 4079 // Preserve the value of all registers.
4121 PushSafepointRegistersScope scope(this); 4080 PushSafepointRegistersScope scope(this);
4122 4081
4123 Label done; 4082 Label done;
4124 // Load value into xmm1 which will be preserved across potential call to 4083 // Load value into xmm1 which will be preserved across potential call to
4125 // runtime (MacroAssembler::EnterExitFrameEpilogue preserves only allocatable 4084 // runtime (MacroAssembler::EnterExitFrameEpilogue preserves only allocatable
4126 // XMM registers on x64). 4085 // XMM registers on x64).
4127 __ LoadUint32(xmm1, reg, xmm0); 4086 __ LoadUint32(xmm1, reg, xmm0);
(...skipping 26 matching lines...) Expand all
4154 class DeferredNumberTagD: public LDeferredCode { 4113 class DeferredNumberTagD: public LDeferredCode {
4155 public: 4114 public:
4156 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4115 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4157 : LDeferredCode(codegen), instr_(instr) { } 4116 : LDeferredCode(codegen), instr_(instr) { }
4158 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4117 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
4159 virtual LInstruction* instr() { return instr_; } 4118 virtual LInstruction* instr() { return instr_; }
4160 private: 4119 private:
4161 LNumberTagD* instr_; 4120 LNumberTagD* instr_;
4162 }; 4121 };
4163 4122
4164 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4123 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
4165 Register reg = ToRegister(instr->result()); 4124 Register reg = ToRegister(instr->result());
4166 Register tmp = ToRegister(instr->temp()); 4125 Register tmp = ToRegister(instr->TempAt(0));
4167 4126
4168 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4127 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4169 if (FLAG_inline_new) { 4128 if (FLAG_inline_new) {
4170 __ AllocateHeapNumber(reg, tmp, deferred->entry()); 4129 __ AllocateHeapNumber(reg, tmp, deferred->entry());
4171 } else { 4130 } else {
4172 __ jmp(deferred->entry()); 4131 __ jmp(deferred->entry());
4173 } 4132 }
4174 __ bind(deferred->exit()); 4133 __ bind(deferred->exit());
4175 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 4134 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
4176 } 4135 }
(...skipping 10 matching lines...) Expand all
4187 PushSafepointRegistersScope scope(this); 4146 PushSafepointRegistersScope scope(this);
4188 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 4147 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4189 // Ensure that value in rax survives popping registers. 4148 // Ensure that value in rax survives popping registers.
4190 __ movq(kScratchRegister, rax); 4149 __ movq(kScratchRegister, rax);
4191 } 4150 }
4192 __ movq(reg, kScratchRegister); 4151 __ movq(reg, kScratchRegister);
4193 } 4152 }
4194 4153
4195 4154
4196 void LCodeGen::DoSmiTag(LSmiTag* instr) { 4155 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4197 ASSERT(instr->value()->Equals(instr->result())); 4156 ASSERT(instr->InputAt(0)->Equals(instr->result()));
4198 Register input = ToRegister(instr->value()); 4157 Register input = ToRegister(instr->InputAt(0));
4199 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 4158 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
4200 __ Integer32ToSmi(input, input); 4159 __ Integer32ToSmi(input, input);
4201 } 4160 }
4202 4161
4203 4162
4204 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4163 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4205 ASSERT(instr->value()->Equals(instr->result())); 4164 ASSERT(instr->InputAt(0)->Equals(instr->result()));
4206 Register input = ToRegister(instr->value()); 4165 Register input = ToRegister(instr->InputAt(0));
4207 if (instr->needs_check()) { 4166 if (instr->needs_check()) {
4208 Condition is_smi = __ CheckSmi(input); 4167 Condition is_smi = __ CheckSmi(input);
4209 DeoptimizeIf(NegateCondition(is_smi), instr->environment()); 4168 DeoptimizeIf(NegateCondition(is_smi), instr->environment());
4210 } else { 4169 } else {
4211 if (FLAG_debug_code) { 4170 if (FLAG_debug_code) {
4212 __ AbortIfNotSmi(input); 4171 __ AbortIfNotSmi(input);
4213 } 4172 }
4214 } 4173 }
4215 __ SmiToInteger32(input, input); 4174 __ SmiToInteger32(input, input);
4216 } 4175 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4261 // Smi to XMM conversion 4220 // Smi to XMM conversion
4262 __ bind(&load_smi); 4221 __ bind(&load_smi);
4263 __ SmiToInteger32(kScratchRegister, input_reg); 4222 __ SmiToInteger32(kScratchRegister, input_reg);
4264 __ cvtlsi2sd(result_reg, kScratchRegister); 4223 __ cvtlsi2sd(result_reg, kScratchRegister);
4265 __ bind(&done); 4224 __ bind(&done);
4266 } 4225 }
4267 4226
4268 4227
4269 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 4228 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4270 Label done, heap_number; 4229 Label done, heap_number;
4271 Register input_reg = ToRegister(instr->value()); 4230 Register input_reg = ToRegister(instr->InputAt(0));
4272 4231
4273 // Heap number map check. 4232 // Heap number map check.
4274 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 4233 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
4275 Heap::kHeapNumberMapRootIndex); 4234 Heap::kHeapNumberMapRootIndex);
4276 4235
4277 if (instr->truncating()) { 4236 if (instr->truncating()) {
4278 __ j(equal, &heap_number, Label::kNear); 4237 __ j(equal, &heap_number, Label::kNear);
4279 // Check for undefined. Undefined is converted to zero for truncating 4238 // Check for undefined. Undefined is converted to zero for truncating
4280 // conversions. 4239 // conversions.
4281 __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); 4240 __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
4282 DeoptimizeIf(not_equal, instr->environment()); 4241 DeoptimizeIf(not_equal, instr->environment());
4283 __ Set(input_reg, 0); 4242 __ Set(input_reg, 0);
4284 __ jmp(&done, Label::kNear); 4243 __ jmp(&done, Label::kNear);
4285 4244
4286 __ bind(&heap_number); 4245 __ bind(&heap_number);
4287 4246
4288 __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4247 __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
4289 __ cvttsd2siq(input_reg, xmm0); 4248 __ cvttsd2siq(input_reg, xmm0);
4290 __ Set(kScratchRegister, V8_UINT64_C(0x8000000000000000)); 4249 __ Set(kScratchRegister, V8_UINT64_C(0x8000000000000000));
4291 __ cmpq(input_reg, kScratchRegister); 4250 __ cmpq(input_reg, kScratchRegister);
4292 DeoptimizeIf(equal, instr->environment()); 4251 DeoptimizeIf(equal, instr->environment());
4293 } else { 4252 } else {
4294 // Deoptimize if we don't have a heap number. 4253 // Deoptimize if we don't have a heap number.
4295 DeoptimizeIf(not_equal, instr->environment()); 4254 DeoptimizeIf(not_equal, instr->environment());
4296 4255
4297 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 4256 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
4298 __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4257 __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
4299 __ cvttsd2si(input_reg, xmm0); 4258 __ cvttsd2si(input_reg, xmm0);
4300 __ cvtlsi2sd(xmm_temp, input_reg); 4259 __ cvtlsi2sd(xmm_temp, input_reg);
4301 __ ucomisd(xmm0, xmm_temp); 4260 __ ucomisd(xmm0, xmm_temp);
4302 DeoptimizeIf(not_equal, instr->environment()); 4261 DeoptimizeIf(not_equal, instr->environment());
4303 DeoptimizeIf(parity_even, instr->environment()); // NaN. 4262 DeoptimizeIf(parity_even, instr->environment()); // NaN.
4304 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4263 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4305 __ testl(input_reg, input_reg); 4264 __ testl(input_reg, input_reg);
4306 __ j(not_zero, &done); 4265 __ j(not_zero, &done);
4307 __ movmskpd(input_reg, xmm0); 4266 __ movmskpd(input_reg, xmm0);
4308 __ andl(input_reg, Immediate(1)); 4267 __ andl(input_reg, Immediate(1));
4309 DeoptimizeIf(not_zero, instr->environment()); 4268 DeoptimizeIf(not_zero, instr->environment());
4310 } 4269 }
4311 } 4270 }
4312 __ bind(&done); 4271 __ bind(&done);
4313 } 4272 }
4314 4273
4315 4274
4316 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 4275 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4317 class DeferredTaggedToI: public LDeferredCode { 4276 class DeferredTaggedToI: public LDeferredCode {
4318 public: 4277 public:
4319 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4278 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4320 : LDeferredCode(codegen), instr_(instr) { } 4279 : LDeferredCode(codegen), instr_(instr) { }
4321 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 4280 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
4322 virtual LInstruction* instr() { return instr_; } 4281 virtual LInstruction* instr() { return instr_; }
4323 private: 4282 private:
4324 LTaggedToI* instr_; 4283 LTaggedToI* instr_;
4325 }; 4284 };
4326 4285
4327 LOperand* input = instr->value(); 4286 LOperand* input = instr->InputAt(0);
4328 ASSERT(input->IsRegister()); 4287 ASSERT(input->IsRegister());
4329 ASSERT(input->Equals(instr->result())); 4288 ASSERT(input->Equals(instr->result()));
4330 4289
4331 Register input_reg = ToRegister(input); 4290 Register input_reg = ToRegister(input);
4332 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 4291 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4333 __ JumpIfNotSmi(input_reg, deferred->entry()); 4292 __ JumpIfNotSmi(input_reg, deferred->entry());
4334 __ SmiToInteger32(input_reg, input_reg); 4293 __ SmiToInteger32(input_reg, input_reg);
4335 __ bind(deferred->exit()); 4294 __ bind(deferred->exit());
4336 } 4295 }
4337 4296
4338 4297
4339 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4298 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4340 LOperand* input = instr->value(); 4299 LOperand* input = instr->InputAt(0);
4341 ASSERT(input->IsRegister()); 4300 ASSERT(input->IsRegister());
4342 LOperand* result = instr->result(); 4301 LOperand* result = instr->result();
4343 ASSERT(result->IsDoubleRegister()); 4302 ASSERT(result->IsDoubleRegister());
4344 4303
4345 Register input_reg = ToRegister(input); 4304 Register input_reg = ToRegister(input);
4346 XMMRegister result_reg = ToDoubleRegister(result); 4305 XMMRegister result_reg = ToDoubleRegister(result);
4347 4306
4348 EmitNumberUntagD(input_reg, result_reg, 4307 EmitNumberUntagD(input_reg, result_reg,
4349 instr->hydrogen()->deoptimize_on_undefined(), 4308 instr->hydrogen()->deoptimize_on_undefined(),
4350 instr->hydrogen()->deoptimize_on_minus_zero(), 4309 instr->hydrogen()->deoptimize_on_minus_zero(),
4351 instr->environment()); 4310 instr->environment());
4352 } 4311 }
4353 4312
4354 4313
4355 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4314 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4356 LOperand* input = instr->value(); 4315 LOperand* input = instr->InputAt(0);
4357 ASSERT(input->IsDoubleRegister()); 4316 ASSERT(input->IsDoubleRegister());
4358 LOperand* result = instr->result(); 4317 LOperand* result = instr->result();
4359 ASSERT(result->IsRegister()); 4318 ASSERT(result->IsRegister());
4360 4319
4361 XMMRegister input_reg = ToDoubleRegister(input); 4320 XMMRegister input_reg = ToDoubleRegister(input);
4362 Register result_reg = ToRegister(result); 4321 Register result_reg = ToRegister(result);
4363 4322
4364 if (instr->truncating()) { 4323 if (instr->truncating()) {
4365 // Performs a truncating conversion of a floating point number as used by 4324 // Performs a truncating conversion of a floating point number as used by
4366 // the JS bitwise operations. 4325 // the JS bitwise operations.
(...skipping 19 matching lines...) Expand all
4386 // deoptimize. 4345 // deoptimize.
4387 __ andl(result_reg, Immediate(1)); 4346 __ andl(result_reg, Immediate(1));
4388 DeoptimizeIf(not_zero, instr->environment()); 4347 DeoptimizeIf(not_zero, instr->environment());
4389 __ bind(&done); 4348 __ bind(&done);
4390 } 4349 }
4391 } 4350 }
4392 } 4351 }
4393 4352
4394 4353
4395 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 4354 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4396 LOperand* input = instr->value(); 4355 LOperand* input = instr->InputAt(0);
4397 Condition cc = masm()->CheckSmi(ToRegister(input)); 4356 Condition cc = masm()->CheckSmi(ToRegister(input));
4398 DeoptimizeIf(NegateCondition(cc), instr->environment()); 4357 DeoptimizeIf(NegateCondition(cc), instr->environment());
4399 } 4358 }
4400 4359
4401 4360
4402 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 4361 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4403 LOperand* input = instr->value(); 4362 LOperand* input = instr->InputAt(0);
4404 Condition cc = masm()->CheckSmi(ToRegister(input)); 4363 Condition cc = masm()->CheckSmi(ToRegister(input));
4405 DeoptimizeIf(cc, instr->environment()); 4364 DeoptimizeIf(cc, instr->environment());
4406 } 4365 }
4407 4366
4408 4367
4409 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 4368 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4410 Register input = ToRegister(instr->value()); 4369 Register input = ToRegister(instr->InputAt(0));
4411 4370
4412 __ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset)); 4371 __ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset));
4413 4372
4414 if (instr->hydrogen()->is_interval_check()) { 4373 if (instr->hydrogen()->is_interval_check()) {
4415 InstanceType first; 4374 InstanceType first;
4416 InstanceType last; 4375 InstanceType last;
4417 instr->hydrogen()->GetCheckInterval(&first, &last); 4376 instr->hydrogen()->GetCheckInterval(&first, &last);
4418 4377
4419 __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), 4378 __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset),
4420 Immediate(static_cast<int8_t>(first))); 4379 Immediate(static_cast<int8_t>(first)));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4472 CompareMapMode mode, 4431 CompareMapMode mode,
4473 LEnvironment* env) { 4432 LEnvironment* env) {
4474 Label success; 4433 Label success;
4475 __ CompareMap(reg, map, &success, mode); 4434 __ CompareMap(reg, map, &success, mode);
4476 DeoptimizeIf(not_equal, env); 4435 DeoptimizeIf(not_equal, env);
4477 __ bind(&success); 4436 __ bind(&success);
4478 } 4437 }
4479 4438
4480 4439
4481 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 4440 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4482 LOperand* input = instr->value(); 4441 LOperand* input = instr->InputAt(0);
4483 ASSERT(input->IsRegister()); 4442 ASSERT(input->IsRegister());
4484 Register reg = ToRegister(input); 4443 Register reg = ToRegister(input);
4485 4444
4486 Label success; 4445 Label success;
4487 SmallMapList* map_set = instr->hydrogen()->map_set(); 4446 SmallMapList* map_set = instr->hydrogen()->map_set();
4488 for (int i = 0; i < map_set->length() - 1; i++) { 4447 for (int i = 0; i < map_set->length() - 1; i++) {
4489 Handle<Map> map = map_set->at(i); 4448 Handle<Map> map = map_set->at(i);
4490 __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP); 4449 __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP);
4491 __ j(equal, &success); 4450 __ j(equal, &success);
4492 } 4451 }
4493 Handle<Map> map = map_set->last(); 4452 Handle<Map> map = map_set->last();
4494 DoCheckMapCommon(reg, map, REQUIRE_EXACT_MAP, instr->environment()); 4453 DoCheckMapCommon(reg, map, REQUIRE_EXACT_MAP, instr->environment());
4495 __ bind(&success); 4454 __ bind(&success);
4496 } 4455 }
4497 4456
4498 4457
4499 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 4458 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
4500 XMMRegister value_reg = ToDoubleRegister(instr->unclamped()); 4459 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
4501 Register result_reg = ToRegister(instr->result()); 4460 Register result_reg = ToRegister(instr->result());
4502 Register temp_reg = ToRegister(instr->temp()); 4461 Register temp_reg = ToRegister(instr->TempAt(0));
4503 __ ClampDoubleToUint8(value_reg, xmm0, result_reg, temp_reg); 4462 __ ClampDoubleToUint8(value_reg, xmm0, result_reg, temp_reg);
4504 } 4463 }
4505 4464
4506 4465
4507 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 4466 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
4508 ASSERT(instr->unclamped()->Equals(instr->result())); 4467 ASSERT(instr->unclamped()->Equals(instr->result()));
4509 Register value_reg = ToRegister(instr->result()); 4468 Register value_reg = ToRegister(instr->result());
4510 __ ClampUint8(value_reg); 4469 __ ClampUint8(value_reg);
4511 } 4470 }
4512 4471
4513 4472
4514 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 4473 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
4515 ASSERT(instr->unclamped()->Equals(instr->result())); 4474 ASSERT(instr->unclamped()->Equals(instr->result()));
4516 Register input_reg = ToRegister(instr->unclamped()); 4475 Register input_reg = ToRegister(instr->unclamped());
4517 Register temp_reg = ToRegister(instr->temp()); 4476 Register temp_reg = ToRegister(instr->TempAt(0));
4518 XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp2()); 4477 XMMRegister temp_xmm_reg = ToDoubleRegister(instr->TempAt(1));
4519 Label is_smi, done, heap_number; 4478 Label is_smi, done, heap_number;
4520 4479
4521 __ JumpIfSmi(input_reg, &is_smi); 4480 __ JumpIfSmi(input_reg, &is_smi);
4522 4481
4523 // Check for heap number 4482 // Check for heap number
4524 __ Cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 4483 __ Cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
4525 factory()->heap_number_map()); 4484 factory()->heap_number_map());
4526 __ j(equal, &heap_number, Label::kNear); 4485 __ j(equal, &heap_number, Label::kNear);
4527 4486
4528 // Check for undefined. Undefined is converted to zero for clamping 4487 // Check for undefined. Undefined is converted to zero for clamping
(...skipping 12 matching lines...) Expand all
4541 // smi 4500 // smi
4542 __ bind(&is_smi); 4501 __ bind(&is_smi);
4543 __ SmiToInteger32(input_reg, input_reg); 4502 __ SmiToInteger32(input_reg, input_reg);
4544 __ ClampUint8(input_reg); 4503 __ ClampUint8(input_reg);
4545 4504
4546 __ bind(&done); 4505 __ bind(&done);
4547 } 4506 }
4548 4507
4549 4508
4550 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 4509 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
4551 Register reg = ToRegister(instr->temp()); 4510 Register reg = ToRegister(instr->TempAt(0));
4552 4511
4553 Handle<JSObject> holder = instr->holder(); 4512 Handle<JSObject> holder = instr->holder();
4554 Handle<JSObject> current_prototype = instr->prototype(); 4513 Handle<JSObject> current_prototype = instr->prototype();
4555 4514
4556 // Load prototype object. 4515 // Load prototype object.
4557 __ LoadHeapObject(reg, current_prototype); 4516 __ LoadHeapObject(reg, current_prototype);
4558 4517
4559 // Check prototype maps up to the holder. 4518 // Check prototype maps up to the holder.
4560 while (!current_prototype.is_identical_to(holder)) { 4519 while (!current_prototype.is_identical_to(holder)) {
4561 DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()), 4520 DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()),
(...skipping 18 matching lines...) Expand all
4580 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); } 4539 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
4581 virtual LInstruction* instr() { return instr_; } 4540 virtual LInstruction* instr() { return instr_; }
4582 private: 4541 private:
4583 LAllocateObject* instr_; 4542 LAllocateObject* instr_;
4584 }; 4543 };
4585 4544
4586 DeferredAllocateObject* deferred = 4545 DeferredAllocateObject* deferred =
4587 new(zone()) DeferredAllocateObject(this, instr); 4546 new(zone()) DeferredAllocateObject(this, instr);
4588 4547
4589 Register result = ToRegister(instr->result()); 4548 Register result = ToRegister(instr->result());
4590 Register scratch = ToRegister(instr->temp()); 4549 Register scratch = ToRegister(instr->TempAt(0));
4591 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); 4550 Handle<JSFunction> constructor = instr->hydrogen()->constructor();
4592 Handle<Map> initial_map(constructor->initial_map()); 4551 Handle<Map> initial_map(constructor->initial_map());
4593 int instance_size = initial_map->instance_size(); 4552 int instance_size = initial_map->instance_size();
4594 ASSERT(initial_map->pre_allocated_property_fields() + 4553 ASSERT(initial_map->pre_allocated_property_fields() +
4595 initial_map->unused_property_fields() - 4554 initial_map->unused_property_fields() -
4596 initial_map->inobject_properties() == 0); 4555 initial_map->inobject_properties() == 0);
4597 4556
4598 // Allocate memory for the object. The initial map might change when 4557 // Allocate memory for the object. The initial map might change when
4599 // the constructor's prototype changes, but instance size and property 4558 // the constructor's prototype changes, but instance size and property
4600 // counts remain unchanged (if slack tracking finished). 4559 // counts remain unchanged (if slack tracking finished).
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
4882 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 4841 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
4883 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); 4842 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr);
4884 } else { 4843 } else {
4885 FastCloneShallowObjectStub stub(properties_count); 4844 FastCloneShallowObjectStub stub(properties_count);
4886 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 4845 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4887 } 4846 }
4888 } 4847 }
4889 4848
4890 4849
4891 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { 4850 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
4892 ASSERT(ToRegister(instr->value()).is(rax)); 4851 ASSERT(ToRegister(instr->InputAt(0)).is(rax));
4893 __ push(rax); 4852 __ push(rax);
4894 CallRuntime(Runtime::kToFastProperties, 1, instr); 4853 CallRuntime(Runtime::kToFastProperties, 1, instr);
4895 } 4854 }
4896 4855
4897 4856
4898 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 4857 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
4899 Label materialized; 4858 Label materialized;
4900 // Registers will be used as follows: 4859 // Registers will be used as follows:
4901 // rcx = literals array. 4860 // rcx = literals array.
4902 // rbx = regexp literal. 4861 // rbx = regexp literal.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4959 __ Push(shared_info); 4918 __ Push(shared_info);
4960 __ PushRoot(pretenure ? 4919 __ PushRoot(pretenure ?
4961 Heap::kTrueValueRootIndex : 4920 Heap::kTrueValueRootIndex :
4962 Heap::kFalseValueRootIndex); 4921 Heap::kFalseValueRootIndex);
4963 CallRuntime(Runtime::kNewClosure, 3, instr); 4922 CallRuntime(Runtime::kNewClosure, 3, instr);
4964 } 4923 }
4965 } 4924 }
4966 4925
4967 4926
4968 void LCodeGen::DoTypeof(LTypeof* instr) { 4927 void LCodeGen::DoTypeof(LTypeof* instr) {
4969 LOperand* input = instr->value(); 4928 LOperand* input = instr->InputAt(0);
4970 EmitPushTaggedOperand(input); 4929 EmitPushTaggedOperand(input);
4971 CallRuntime(Runtime::kTypeof, 1, instr); 4930 CallRuntime(Runtime::kTypeof, 1, instr);
4972 } 4931 }
4973 4932
4974 4933
4975 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { 4934 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
4976 ASSERT(!operand->IsDoubleRegister()); 4935 ASSERT(!operand->IsDoubleRegister());
4977 if (operand->IsConstantOperand()) { 4936 if (operand->IsConstantOperand()) {
4978 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); 4937 Handle<Object> object = ToHandle(LConstantOperand::cast(operand));
4979 if (object->IsSmi()) { 4938 if (object->IsSmi()) {
4980 __ Push(Handle<Smi>::cast(object)); 4939 __ Push(Handle<Smi>::cast(object));
4981 } else { 4940 } else {
4982 __ PushHeapObject(Handle<HeapObject>::cast(object)); 4941 __ PushHeapObject(Handle<HeapObject>::cast(object));
4983 } 4942 }
4984 } else if (operand->IsRegister()) { 4943 } else if (operand->IsRegister()) {
4985 __ push(ToRegister(operand)); 4944 __ push(ToRegister(operand));
4986 } else { 4945 } else {
4987 __ push(ToOperand(operand)); 4946 __ push(ToOperand(operand));
4988 } 4947 }
4989 } 4948 }
4990 4949
4991 4950
4992 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 4951 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
4993 Register input = ToRegister(instr->value()); 4952 Register input = ToRegister(instr->InputAt(0));
4994 int true_block = chunk_->LookupDestination(instr->true_block_id()); 4953 int true_block = chunk_->LookupDestination(instr->true_block_id());
4995 int false_block = chunk_->LookupDestination(instr->false_block_id()); 4954 int false_block = chunk_->LookupDestination(instr->false_block_id());
4996 Label* true_label = chunk_->GetAssemblyLabel(true_block); 4955 Label* true_label = chunk_->GetAssemblyLabel(true_block);
4997 Label* false_label = chunk_->GetAssemblyLabel(false_block); 4956 Label* false_label = chunk_->GetAssemblyLabel(false_block);
4998 4957
4999 Condition final_branch_condition = 4958 Condition final_branch_condition =
5000 EmitTypeofIs(true_label, false_label, input, instr->type_literal()); 4959 EmitTypeofIs(true_label, false_label, input, instr->type_literal());
5001 if (final_branch_condition != no_condition) { 4960 if (final_branch_condition != no_condition) {
5002 EmitBranch(true_block, false_block, final_branch_condition); 4961 EmitBranch(true_block, false_block, final_branch_condition);
5003 } 4962 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
5069 5028
5070 } else { 5029 } else {
5071 __ jmp(false_label); 5030 __ jmp(false_label);
5072 } 5031 }
5073 5032
5074 return final_branch_condition; 5033 return final_branch_condition;
5075 } 5034 }
5076 5035
5077 5036
5078 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5037 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5079 Register temp = ToRegister(instr->temp()); 5038 Register temp = ToRegister(instr->TempAt(0));
5080 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5039 int true_block = chunk_->LookupDestination(instr->true_block_id());
5081 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5040 int false_block = chunk_->LookupDestination(instr->false_block_id());
5082 5041
5083 EmitIsConstructCall(temp); 5042 EmitIsConstructCall(temp);
5084 EmitBranch(true_block, false_block, equal); 5043 EmitBranch(true_block, false_block, equal);
5085 } 5044 }
5086 5045
5087 5046
5088 void LCodeGen::EmitIsConstructCall(Register temp) { 5047 void LCodeGen::EmitIsConstructCall(Register temp) {
5089 // Get the frame pointer for the calling frame. 5048 // Get the frame pointer for the calling frame.
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
5322 FixedArray::kHeaderSize - kPointerSize)); 5281 FixedArray::kHeaderSize - kPointerSize));
5323 __ bind(&done); 5282 __ bind(&done);
5324 } 5283 }
5325 5284
5326 5285
5327 #undef __ 5286 #undef __
5328 5287
5329 } } // namespace v8::internal 5288 } } // namespace v8::internal
5330 5289
5331 #endif // V8_TARGET_ARCH_X64 5290 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698