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

Side by Side Diff: src/compiler/x87/code-generator-x87.cc

Issue 1636353002: [x87] Keep x87 FPU stack empty when calling or return to natvie C++ function. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler/code-generator-impl.h" 8 #include "src/compiler/code-generator-impl.h"
9 #include "src/compiler/gap-resolver.h" 9 #include "src/compiler/gap-resolver.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 188
189 189
190 class OutOfLineLoadFloat final : public OutOfLineCode { 190 class OutOfLineLoadFloat final : public OutOfLineCode {
191 public: 191 public:
192 OutOfLineLoadFloat(CodeGenerator* gen, X87Register result) 192 OutOfLineLoadFloat(CodeGenerator* gen, X87Register result)
193 : OutOfLineCode(gen), result_(result) {} 193 : OutOfLineCode(gen), result_(result) {}
194 194
195 void Generate() final { 195 void Generate() final {
196 DCHECK(result_.code() == 0); 196 DCHECK(result_.code() == 0);
197 USE(result_); 197 USE(result_);
198 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
199 __ VerifyX87StackDepth(1);
200 }
198 __ fstp(0); 201 __ fstp(0);
199 __ push(Immediate(0xffffffff)); 202 __ push(Immediate(0xffffffff));
200 __ push(Immediate(0x7fffffff)); 203 __ push(Immediate(0x7fffffff));
201 __ fld_d(MemOperand(esp, 0)); 204 __ fld_d(MemOperand(esp, 0));
202 __ lea(esp, Operand(esp, kDoubleSize)); 205 __ lea(esp, Operand(esp, kDoubleSize));
203 } 206 }
204 207
205 private: 208 private:
206 X87Register const result_; 209 X87Register const result_;
207 }; 210 };
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 frame_access_state()->SetFrameAccessToSP(); 360 frame_access_state()->SetFrameAccessToSP();
358 } 361 }
359 362
360 363
361 // Assembles an instruction after register allocation, producing machine code. 364 // Assembles an instruction after register allocation, producing machine code.
362 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { 365 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
363 X87OperandConverter i(this, instr); 366 X87OperandConverter i(this, instr);
364 367
365 switch (ArchOpcodeField::decode(instr->opcode())) { 368 switch (ArchOpcodeField::decode(instr->opcode())) {
366 case kArchCallCodeObject: { 369 case kArchCallCodeObject: {
370 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
371 __ VerifyX87StackDepth(1);
372 }
373 __ fstp(0);
367 EnsureSpaceForLazyDeopt(); 374 EnsureSpaceForLazyDeopt();
368 if (HasImmediateInput(instr, 0)) { 375 if (HasImmediateInput(instr, 0)) {
369 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 376 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
370 __ call(code, RelocInfo::CODE_TARGET); 377 __ call(code, RelocInfo::CODE_TARGET);
371 } else { 378 } else {
372 Register reg = i.InputRegister(0); 379 Register reg = i.InputRegister(0);
373 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); 380 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
374 __ call(reg); 381 __ call(reg);
375 } 382 }
376 RecordCallPosition(instr); 383 RecordCallPosition(instr);
377 bool double_result = 384 bool double_result =
378 instr->HasOutput() && instr->Output()->IsDoubleRegister(); 385 instr->HasOutput() && instr->Output()->IsDoubleRegister();
379 if (double_result) { 386 if (double_result) {
380 __ lea(esp, Operand(esp, -kDoubleSize)); 387 __ lea(esp, Operand(esp, -kDoubleSize));
381 __ fstp_d(Operand(esp, 0)); 388 __ fstp_d(Operand(esp, 0));
382 } 389 }
383 __ fninit(); 390 __ fninit();
384 if (double_result) { 391 if (double_result) {
385 __ fld_d(Operand(esp, 0)); 392 __ fld_d(Operand(esp, 0));
386 __ lea(esp, Operand(esp, kDoubleSize)); 393 __ lea(esp, Operand(esp, kDoubleSize));
387 } else { 394 } else {
388 __ fld1(); 395 __ fld1();
389 } 396 }
390 frame_access_state()->ClearSPDelta(); 397 frame_access_state()->ClearSPDelta();
391 break; 398 break;
392 } 399 }
393 case kArchTailCallCodeObject: { 400 case kArchTailCallCodeObject: {
401 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
402 __ VerifyX87StackDepth(1);
403 }
404 __ fstp(0);
394 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); 405 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
395 AssembleDeconstructActivationRecord(stack_param_delta); 406 AssembleDeconstructActivationRecord(stack_param_delta);
396 if (HasImmediateInput(instr, 0)) { 407 if (HasImmediateInput(instr, 0)) {
397 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 408 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
398 __ jmp(code, RelocInfo::CODE_TARGET); 409 __ jmp(code, RelocInfo::CODE_TARGET);
399 } else { 410 } else {
400 Register reg = i.InputRegister(0); 411 Register reg = i.InputRegister(0);
401 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); 412 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
402 __ jmp(reg); 413 __ jmp(reg);
403 } 414 }
404 frame_access_state()->ClearSPDelta(); 415 frame_access_state()->ClearSPDelta();
405 break; 416 break;
406 } 417 }
407 case kArchCallJSFunction: { 418 case kArchCallJSFunction: {
408 EnsureSpaceForLazyDeopt(); 419 EnsureSpaceForLazyDeopt();
409 Register func = i.InputRegister(0); 420 Register func = i.InputRegister(0);
410 if (FLAG_debug_code) { 421 if (FLAG_debug_code) {
411 // Check the function's context matches the context argument. 422 // Check the function's context matches the context argument.
412 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); 423 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
413 __ Assert(equal, kWrongFunctionContext); 424 __ Assert(equal, kWrongFunctionContext);
414 } 425 }
426 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
427 __ VerifyX87StackDepth(1);
428 }
429 __ fstp(0);
415 __ call(FieldOperand(func, JSFunction::kCodeEntryOffset)); 430 __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
416 RecordCallPosition(instr); 431 RecordCallPosition(instr);
417 bool double_result = 432 bool double_result =
418 instr->HasOutput() && instr->Output()->IsDoubleRegister(); 433 instr->HasOutput() && instr->Output()->IsDoubleRegister();
419 if (double_result) { 434 if (double_result) {
420 __ lea(esp, Operand(esp, -kDoubleSize)); 435 __ lea(esp, Operand(esp, -kDoubleSize));
421 __ fstp_d(Operand(esp, 0)); 436 __ fstp_d(Operand(esp, 0));
422 } 437 }
423 __ fninit(); 438 __ fninit();
424 if (double_result) { 439 if (double_result) {
425 __ fld_d(Operand(esp, 0)); 440 __ fld_d(Operand(esp, 0));
426 __ lea(esp, Operand(esp, kDoubleSize)); 441 __ lea(esp, Operand(esp, kDoubleSize));
427 } else { 442 } else {
428 __ fld1(); 443 __ fld1();
429 } 444 }
430 frame_access_state()->ClearSPDelta(); 445 frame_access_state()->ClearSPDelta();
431 break; 446 break;
432 } 447 }
433 case kArchTailCallJSFunction: { 448 case kArchTailCallJSFunction: {
434 Register func = i.InputRegister(0); 449 Register func = i.InputRegister(0);
435 if (FLAG_debug_code) { 450 if (FLAG_debug_code) {
436 // Check the function's context matches the context argument. 451 // Check the function's context matches the context argument.
437 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); 452 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
438 __ Assert(equal, kWrongFunctionContext); 453 __ Assert(equal, kWrongFunctionContext);
439 } 454 }
455 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
456 __ VerifyX87StackDepth(1);
457 }
458 __ fstp(0);
440 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); 459 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
441 AssembleDeconstructActivationRecord(stack_param_delta); 460 AssembleDeconstructActivationRecord(stack_param_delta);
442 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); 461 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset));
443 frame_access_state()->ClearSPDelta(); 462 frame_access_state()->ClearSPDelta();
444 break; 463 break;
445 } 464 }
446 case kArchLazyBailout: { 465 case kArchLazyBailout: {
447 EnsureSpaceForLazyDeopt(); 466 EnsureSpaceForLazyDeopt();
448 RecordCallPosition(instr); 467 RecordCallPosition(instr);
468 // Lazy Bailout entry, need to re-initialize FPU state.
469 __ fninit();
470 __ fld1();
449 break; 471 break;
450 } 472 }
451 case kArchPrepareCallCFunction: { 473 case kArchPrepareCallCFunction: {
452 // Frame alignment requires using FP-relative frame addressing. 474 // Frame alignment requires using FP-relative frame addressing.
453 frame_access_state()->SetFrameAccessToFP(); 475 frame_access_state()->SetFrameAccessToFP();
454 int const num_parameters = MiscField::decode(instr->opcode()); 476 int const num_parameters = MiscField::decode(instr->opcode());
455 __ PrepareCallCFunction(num_parameters, i.TempRegister(0)); 477 __ PrepareCallCFunction(num_parameters, i.TempRegister(0));
456 break; 478 break;
457 } 479 }
458 case kArchPrepareTailCall: 480 case kArchPrepareTailCall:
459 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); 481 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1));
460 break; 482 break;
461 case kArchCallCFunction: { 483 case kArchCallCFunction: {
484 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
485 __ VerifyX87StackDepth(1);
486 }
487 __ fstp(0);
462 int const num_parameters = MiscField::decode(instr->opcode()); 488 int const num_parameters = MiscField::decode(instr->opcode());
463 if (HasImmediateInput(instr, 0)) { 489 if (HasImmediateInput(instr, 0)) {
464 ExternalReference ref = i.InputExternalReference(0); 490 ExternalReference ref = i.InputExternalReference(0);
465 __ CallCFunction(ref, num_parameters); 491 __ CallCFunction(ref, num_parameters);
466 } else { 492 } else {
467 Register func = i.InputRegister(0); 493 Register func = i.InputRegister(0);
468 __ CallCFunction(func, num_parameters); 494 __ CallCFunction(func, num_parameters);
469 } 495 }
496 bool double_result =
497 instr->HasOutput() && instr->Output()->IsDoubleRegister();
498 if (double_result) {
499 __ lea(esp, Operand(esp, -kDoubleSize));
500 __ fstp_d(Operand(esp, 0));
501 }
502 __ fninit();
503 if (double_result) {
504 __ fld_d(Operand(esp, 0));
505 __ lea(esp, Operand(esp, kDoubleSize));
506 } else {
507 __ fld1();
508 }
470 frame_access_state()->SetFrameAccessToDefault(); 509 frame_access_state()->SetFrameAccessToDefault();
471 frame_access_state()->ClearSPDelta(); 510 frame_access_state()->ClearSPDelta();
472 break; 511 break;
473 } 512 }
474 case kArchJmp: 513 case kArchJmp:
475 AssembleArchJump(i.InputRpo(0)); 514 AssembleArchJump(i.InputRpo(0));
476 break; 515 break;
477 case kArchLookupSwitch: 516 case kArchLookupSwitch:
478 AssembleArchLookupSwitch(instr); 517 AssembleArchLookupSwitch(instr);
479 break; 518 break;
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 break; 721 break;
683 } 722 }
684 case kX87Float32Cmp: { 723 case kX87Float32Cmp: {
685 __ fld_s(MemOperand(esp, kFloatSize)); 724 __ fld_s(MemOperand(esp, kFloatSize));
686 __ fld_s(MemOperand(esp, 0)); 725 __ fld_s(MemOperand(esp, 0));
687 __ FCmp(); 726 __ FCmp();
688 __ lea(esp, Operand(esp, 2 * kFloatSize)); 727 __ lea(esp, Operand(esp, 2 * kFloatSize));
689 break; 728 break;
690 } 729 }
691 case kX87Float32Add: { 730 case kX87Float32Add: {
731 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
732 __ VerifyX87StackDepth(1);
733 }
692 __ X87SetFPUCW(0x027F); 734 __ X87SetFPUCW(0x027F);
693 __ fstp(0); 735 __ fstp(0);
694 __ fld_s(MemOperand(esp, 0)); 736 __ fld_s(MemOperand(esp, 0));
695 __ fld_s(MemOperand(esp, kFloatSize)); 737 __ fld_s(MemOperand(esp, kFloatSize));
696 __ faddp(); 738 __ faddp();
697 // Clear stack. 739 // Clear stack.
698 __ lea(esp, Operand(esp, 2 * kFloatSize)); 740 __ lea(esp, Operand(esp, 2 * kFloatSize));
699 // Restore the default value of control word. 741 // Restore the default value of control word.
700 __ X87SetFPUCW(0x037F); 742 __ X87SetFPUCW(0x037F);
701 break; 743 break;
702 } 744 }
703 case kX87Float32Sub: { 745 case kX87Float32Sub: {
746 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
747 __ VerifyX87StackDepth(1);
748 }
704 __ X87SetFPUCW(0x027F); 749 __ X87SetFPUCW(0x027F);
705 __ fstp(0); 750 __ fstp(0);
706 __ fld_s(MemOperand(esp, kFloatSize)); 751 __ fld_s(MemOperand(esp, kFloatSize));
707 __ fld_s(MemOperand(esp, 0)); 752 __ fld_s(MemOperand(esp, 0));
708 __ fsubp(); 753 __ fsubp();
709 // Clear stack. 754 // Clear stack.
710 __ lea(esp, Operand(esp, 2 * kFloatSize)); 755 __ lea(esp, Operand(esp, 2 * kFloatSize));
711 // Restore the default value of control word. 756 // Restore the default value of control word.
712 __ X87SetFPUCW(0x037F); 757 __ X87SetFPUCW(0x037F);
713 break; 758 break;
714 } 759 }
715 case kX87Float32Mul: { 760 case kX87Float32Mul: {
761 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
762 __ VerifyX87StackDepth(1);
763 }
716 __ X87SetFPUCW(0x027F); 764 __ X87SetFPUCW(0x027F);
717 __ fstp(0); 765 __ fstp(0);
718 __ fld_s(MemOperand(esp, kFloatSize)); 766 __ fld_s(MemOperand(esp, kFloatSize));
719 __ fld_s(MemOperand(esp, 0)); 767 __ fld_s(MemOperand(esp, 0));
720 __ fmulp(); 768 __ fmulp();
721 // Clear stack. 769 // Clear stack.
722 __ lea(esp, Operand(esp, 2 * kFloatSize)); 770 __ lea(esp, Operand(esp, 2 * kFloatSize));
723 // Restore the default value of control word. 771 // Restore the default value of control word.
724 __ X87SetFPUCW(0x037F); 772 __ X87SetFPUCW(0x037F);
725 break; 773 break;
726 } 774 }
727 case kX87Float32Div: { 775 case kX87Float32Div: {
776 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
777 __ VerifyX87StackDepth(1);
778 }
728 __ X87SetFPUCW(0x027F); 779 __ X87SetFPUCW(0x027F);
729 __ fstp(0); 780 __ fstp(0);
730 __ fld_s(MemOperand(esp, kFloatSize)); 781 __ fld_s(MemOperand(esp, kFloatSize));
731 __ fld_s(MemOperand(esp, 0)); 782 __ fld_s(MemOperand(esp, 0));
732 __ fdivp(); 783 __ fdivp();
733 // Clear stack. 784 // Clear stack.
734 __ lea(esp, Operand(esp, 2 * kFloatSize)); 785 __ lea(esp, Operand(esp, 2 * kFloatSize));
735 // Restore the default value of control word. 786 // Restore the default value of control word.
736 __ X87SetFPUCW(0x037F); 787 __ X87SetFPUCW(0x037F);
737 break; 788 break;
738 } 789 }
739 case kX87Float32Max: { 790 case kX87Float32Max: {
740 Label check_nan_left, check_zero, return_left, return_right; 791 Label check_nan_left, check_zero, return_left, return_right;
741 Condition condition = below; 792 Condition condition = below;
793 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
794 __ VerifyX87StackDepth(1);
795 }
742 __ fstp(0); 796 __ fstp(0);
743 __ fld_s(MemOperand(esp, kFloatSize)); 797 __ fld_s(MemOperand(esp, kFloatSize));
744 __ fld_s(MemOperand(esp, 0)); 798 __ fld_s(MemOperand(esp, 0));
745 __ fld(1); 799 __ fld(1);
746 __ fld(1); 800 __ fld(1);
747 __ FCmp(); 801 __ FCmp();
748 802
749 // At least one NaN. 803 // At least one NaN.
750 // Return the second operands if one of the two operands is NaN 804 // Return the second operands if one of the two operands is NaN
751 __ j(parity_even, &return_right, Label::kNear); 805 __ j(parity_even, &return_right, Label::kNear);
(...skipping 14 matching lines...) Expand all
766 __ fxch(); 820 __ fxch();
767 821
768 __ bind(&return_left); 822 __ bind(&return_left);
769 __ fstp(0); 823 __ fstp(0);
770 __ lea(esp, Operand(esp, 2 * kFloatSize)); 824 __ lea(esp, Operand(esp, 2 * kFloatSize));
771 break; 825 break;
772 } 826 }
773 case kX87Float32Min: { 827 case kX87Float32Min: {
774 Label check_nan_left, check_zero, return_left, return_right; 828 Label check_nan_left, check_zero, return_left, return_right;
775 Condition condition = above; 829 Condition condition = above;
830 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
831 __ VerifyX87StackDepth(1);
832 }
776 __ fstp(0); 833 __ fstp(0);
777 __ fld_s(MemOperand(esp, kFloatSize)); 834 __ fld_s(MemOperand(esp, kFloatSize));
778 __ fld_s(MemOperand(esp, 0)); 835 __ fld_s(MemOperand(esp, 0));
779 __ fld(1); 836 __ fld(1);
780 __ fld(1); 837 __ fld(1);
781 __ FCmp(); 838 __ FCmp();
782 // At least one NaN. 839 // At least one NaN.
783 // Return the second operands if one of the two operands is NaN 840 // Return the second operands if one of the two operands is NaN
784 __ j(parity_even, &return_right, Label::kNear); 841 __ j(parity_even, &return_right, Label::kNear);
785 __ j(equal, &check_zero, Label::kNear); // left == right. 842 __ j(equal, &check_zero, Label::kNear); // left == right.
(...skipping 25 matching lines...) Expand all
811 868
812 __ bind(&return_right); 869 __ bind(&return_right);
813 __ fxch(); 870 __ fxch();
814 871
815 __ bind(&return_left); 872 __ bind(&return_left);
816 __ fstp(0); 873 __ fstp(0);
817 __ lea(esp, Operand(esp, 2 * kFloatSize)); 874 __ lea(esp, Operand(esp, 2 * kFloatSize));
818 break; 875 break;
819 } 876 }
820 case kX87Float32Sqrt: { 877 case kX87Float32Sqrt: {
878 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
879 __ VerifyX87StackDepth(1);
880 }
821 __ fstp(0); 881 __ fstp(0);
822 __ fld_s(MemOperand(esp, 0)); 882 __ fld_s(MemOperand(esp, 0));
823 __ fsqrt(); 883 __ fsqrt();
824 __ lea(esp, Operand(esp, kFloatSize)); 884 __ lea(esp, Operand(esp, kFloatSize));
825 break; 885 break;
826 } 886 }
827 case kX87Float32Abs: { 887 case kX87Float32Abs: {
888 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
889 __ VerifyX87StackDepth(1);
890 }
828 __ fstp(0); 891 __ fstp(0);
829 __ fld_s(MemOperand(esp, 0)); 892 __ fld_s(MemOperand(esp, 0));
830 __ fabs(); 893 __ fabs();
831 __ lea(esp, Operand(esp, kFloatSize)); 894 __ lea(esp, Operand(esp, kFloatSize));
832 break; 895 break;
833 } 896 }
834 case kX87Float32Round: { 897 case kX87Float32Round: {
835 RoundingMode mode = 898 RoundingMode mode =
836 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); 899 static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
837 // Set the correct round mode in x87 control register 900 // Set the correct round mode in x87 control register
838 __ X87SetRC((mode << 10)); 901 __ X87SetRC((mode << 10));
839 902
840 if (!instr->InputAt(0)->IsDoubleRegister()) { 903 if (!instr->InputAt(0)->IsDoubleRegister()) {
841 InstructionOperand* input = instr->InputAt(0); 904 InstructionOperand* input = instr->InputAt(0);
842 USE(input); 905 USE(input);
843 DCHECK(input->IsDoubleStackSlot()); 906 DCHECK(input->IsDoubleStackSlot());
907 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
908 __ VerifyX87StackDepth(1);
909 }
844 __ fstp(0); 910 __ fstp(0);
845 __ fld_s(i.InputOperand(0)); 911 __ fld_s(i.InputOperand(0));
846 } 912 }
847 __ frndint(); 913 __ frndint();
848 __ X87SetRC(0x0000); 914 __ X87SetRC(0x0000);
849 break; 915 break;
850 } 916 }
851 case kX87Float64Add: { 917 case kX87Float64Add: {
918 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
919 __ VerifyX87StackDepth(1);
920 }
852 __ X87SetFPUCW(0x027F); 921 __ X87SetFPUCW(0x027F);
853 __ fstp(0); 922 __ fstp(0);
854 __ fld_d(MemOperand(esp, 0)); 923 __ fld_d(MemOperand(esp, 0));
855 __ fld_d(MemOperand(esp, kDoubleSize)); 924 __ fld_d(MemOperand(esp, kDoubleSize));
856 __ faddp(); 925 __ faddp();
857 // Clear stack. 926 // Clear stack.
858 __ lea(esp, Operand(esp, 2 * kDoubleSize)); 927 __ lea(esp, Operand(esp, 2 * kDoubleSize));
859 // Restore the default value of control word. 928 // Restore the default value of control word.
860 __ X87SetFPUCW(0x037F); 929 __ X87SetFPUCW(0x037F);
861 break; 930 break;
862 } 931 }
863 case kX87Float64Sub: { 932 case kX87Float64Sub: {
933 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
934 __ VerifyX87StackDepth(1);
935 }
864 __ X87SetFPUCW(0x027F); 936 __ X87SetFPUCW(0x027F);
865 __ fstp(0); 937 __ fstp(0);
866 __ fld_d(MemOperand(esp, kDoubleSize)); 938 __ fld_d(MemOperand(esp, kDoubleSize));
867 __ fsub_d(MemOperand(esp, 0)); 939 __ fsub_d(MemOperand(esp, 0));
868 // Clear stack. 940 // Clear stack.
869 __ lea(esp, Operand(esp, 2 * kDoubleSize)); 941 __ lea(esp, Operand(esp, 2 * kDoubleSize));
870 // Restore the default value of control word. 942 // Restore the default value of control word.
871 __ X87SetFPUCW(0x037F); 943 __ X87SetFPUCW(0x037F);
872 break; 944 break;
873 } 945 }
874 case kX87Float64Mul: { 946 case kX87Float64Mul: {
947 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
948 __ VerifyX87StackDepth(1);
949 }
875 __ X87SetFPUCW(0x027F); 950 __ X87SetFPUCW(0x027F);
876 __ fstp(0); 951 __ fstp(0);
877 __ fld_d(MemOperand(esp, kDoubleSize)); 952 __ fld_d(MemOperand(esp, kDoubleSize));
878 __ fmul_d(MemOperand(esp, 0)); 953 __ fmul_d(MemOperand(esp, 0));
879 // Clear stack. 954 // Clear stack.
880 __ lea(esp, Operand(esp, 2 * kDoubleSize)); 955 __ lea(esp, Operand(esp, 2 * kDoubleSize));
881 // Restore the default value of control word. 956 // Restore the default value of control word.
882 __ X87SetFPUCW(0x037F); 957 __ X87SetFPUCW(0x037F);
883 break; 958 break;
884 } 959 }
885 case kX87Float64Div: { 960 case kX87Float64Div: {
961 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
962 __ VerifyX87StackDepth(1);
963 }
886 __ X87SetFPUCW(0x027F); 964 __ X87SetFPUCW(0x027F);
887 __ fstp(0); 965 __ fstp(0);
888 __ fld_d(MemOperand(esp, kDoubleSize)); 966 __ fld_d(MemOperand(esp, kDoubleSize));
889 __ fdiv_d(MemOperand(esp, 0)); 967 __ fdiv_d(MemOperand(esp, 0));
890 // Clear stack. 968 // Clear stack.
891 __ lea(esp, Operand(esp, 2 * kDoubleSize)); 969 __ lea(esp, Operand(esp, 2 * kDoubleSize));
892 // Restore the default value of control word. 970 // Restore the default value of control word.
893 __ X87SetFPUCW(0x037F); 971 __ X87SetFPUCW(0x037F);
894 break; 972 break;
895 } 973 }
896 case kX87Float64Mod: { 974 case kX87Float64Mod: {
897 FrameScope frame_scope(&masm_, StackFrame::MANUAL); 975 FrameScope frame_scope(&masm_, StackFrame::MANUAL);
976 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
977 __ VerifyX87StackDepth(1);
978 }
898 __ mov(eax, esp); 979 __ mov(eax, esp);
899 __ PrepareCallCFunction(4, eax); 980 __ PrepareCallCFunction(4, eax);
900 __ fstp(0); 981 __ fstp(0);
901 __ fld_d(MemOperand(eax, 0)); 982 __ fld_d(MemOperand(eax, 0));
902 __ fstp_d(Operand(esp, 1 * kDoubleSize)); 983 __ fstp_d(Operand(esp, 1 * kDoubleSize));
903 __ fld_d(MemOperand(eax, kDoubleSize)); 984 __ fld_d(MemOperand(eax, kDoubleSize));
904 __ fstp_d(Operand(esp, 0)); 985 __ fstp_d(Operand(esp, 0));
905 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), 986 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
906 4); 987 4);
907 __ lea(esp, Operand(esp, 2 * kDoubleSize)); 988 __ lea(esp, Operand(esp, 2 * kDoubleSize));
908 break; 989 break;
909 } 990 }
910 case kX87Float64Max: { 991 case kX87Float64Max: {
911 Label check_zero, return_left, return_right; 992 Label check_zero, return_left, return_right;
912 Condition condition = below; 993 Condition condition = below;
994 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
995 __ VerifyX87StackDepth(1);
996 }
913 __ fstp(0); 997 __ fstp(0);
914 __ fld_d(MemOperand(esp, kDoubleSize)); 998 __ fld_d(MemOperand(esp, kDoubleSize));
915 __ fld_d(MemOperand(esp, 0)); 999 __ fld_d(MemOperand(esp, 0));
916 __ fld(1); 1000 __ fld(1);
917 __ fld(1); 1001 __ fld(1);
918 __ FCmp(); 1002 __ FCmp();
919 __ j(parity_even, &return_right, 1003 __ j(parity_even, &return_right,
920 Label::kNear); // At least one NaN, Return right. 1004 Label::kNear); // At least one NaN, Return right.
921 __ j(equal, &check_zero, Label::kNear); // left == right. 1005 __ j(equal, &check_zero, Label::kNear); // left == right.
922 __ j(condition, &return_left, Label::kNear); 1006 __ j(condition, &return_left, Label::kNear);
923 __ jmp(&return_right, Label::kNear); 1007 __ jmp(&return_right, Label::kNear);
924 1008
925 __ bind(&check_zero); 1009 __ bind(&check_zero);
926 __ fld(0); 1010 __ fld(0);
927 __ fldz(); 1011 __ fldz();
928 __ FCmp(); 1012 __ FCmp();
929 __ j(not_equal, &return_left, Label::kNear); // left == right != 0. 1013 __ j(not_equal, &return_left, Label::kNear); // left == right != 0.
930 1014
931 __ bind(&return_right); 1015 __ bind(&return_right);
932 __ fxch(); 1016 __ fxch();
933 1017
934 __ bind(&return_left); 1018 __ bind(&return_left);
935 __ fstp(0); 1019 __ fstp(0);
936 __ lea(esp, Operand(esp, 2 * kDoubleSize)); 1020 __ lea(esp, Operand(esp, 2 * kDoubleSize));
937 break; 1021 break;
938 } 1022 }
939 case kX87Float64Min: { 1023 case kX87Float64Min: {
940 Label check_zero, return_left, return_right; 1024 Label check_zero, return_left, return_right;
941 Condition condition = above; 1025 Condition condition = above;
1026 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1027 __ VerifyX87StackDepth(1);
1028 }
942 __ fstp(0); 1029 __ fstp(0);
943 __ fld_d(MemOperand(esp, kDoubleSize)); 1030 __ fld_d(MemOperand(esp, kDoubleSize));
944 __ fld_d(MemOperand(esp, 0)); 1031 __ fld_d(MemOperand(esp, 0));
945 __ fld(1); 1032 __ fld(1);
946 __ fld(1); 1033 __ fld(1);
947 __ FCmp(); 1034 __ FCmp();
948 __ j(parity_even, &return_right, 1035 __ j(parity_even, &return_right,
949 Label::kNear); // At least one NaN, return right value. 1036 Label::kNear); // At least one NaN, return right value.
950 __ j(equal, &check_zero, Label::kNear); // left == right. 1037 __ j(equal, &check_zero, Label::kNear); // left == right.
951 __ j(condition, &return_left, Label::kNear); 1038 __ j(condition, &return_left, Label::kNear);
952 __ jmp(&return_right, Label::kNear); 1039 __ jmp(&return_right, Label::kNear);
953 1040
954 __ bind(&check_zero); 1041 __ bind(&check_zero);
955 __ fld(0); 1042 __ fld(0);
956 __ fldz(); 1043 __ fldz();
957 __ FCmp(); 1044 __ FCmp();
958 __ j(not_equal, &return_left, Label::kNear); // left == right != 0. 1045 __ j(not_equal, &return_left, Label::kNear); // left == right != 0.
959 1046
960 __ bind(&return_right); 1047 __ bind(&return_right);
961 __ fxch(); 1048 __ fxch();
962 1049
963 __ bind(&return_left); 1050 __ bind(&return_left);
964 __ fstp(0); 1051 __ fstp(0);
965 __ lea(esp, Operand(esp, 2 * kDoubleSize)); 1052 __ lea(esp, Operand(esp, 2 * kDoubleSize));
966 break; 1053 break;
967 } 1054 }
968 case kX87Float64Abs: { 1055 case kX87Float64Abs: {
1056 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1057 __ VerifyX87StackDepth(1);
1058 }
969 __ fstp(0); 1059 __ fstp(0);
970 __ fld_d(MemOperand(esp, 0)); 1060 __ fld_d(MemOperand(esp, 0));
971 __ fabs(); 1061 __ fabs();
972 __ lea(esp, Operand(esp, kDoubleSize)); 1062 __ lea(esp, Operand(esp, kDoubleSize));
973 break; 1063 break;
974 } 1064 }
975 case kX87Int32ToFloat32: { 1065 case kX87Int32ToFloat32: {
976 InstructionOperand* input = instr->InputAt(0); 1066 InstructionOperand* input = instr->InputAt(0);
977 DCHECK(input->IsRegister() || input->IsStackSlot()); 1067 DCHECK(input->IsRegister() || input->IsStackSlot());
1068 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1069 __ VerifyX87StackDepth(1);
1070 }
978 __ fstp(0); 1071 __ fstp(0);
979 if (input->IsRegister()) { 1072 if (input->IsRegister()) {
980 Register input_reg = i.InputRegister(0); 1073 Register input_reg = i.InputRegister(0);
981 __ push(input_reg); 1074 __ push(input_reg);
982 __ fild_s(Operand(esp, 0)); 1075 __ fild_s(Operand(esp, 0));
983 __ pop(input_reg); 1076 __ pop(input_reg);
984 } else { 1077 } else {
985 __ fild_s(i.InputOperand(0)); 1078 __ fild_s(i.InputOperand(0));
986 } 1079 }
987 break; 1080 break;
988 } 1081 }
989 case kX87Int32ToFloat64: { 1082 case kX87Int32ToFloat64: {
990 InstructionOperand* input = instr->InputAt(0); 1083 InstructionOperand* input = instr->InputAt(0);
991 DCHECK(input->IsRegister() || input->IsStackSlot()); 1084 DCHECK(input->IsRegister() || input->IsStackSlot());
1085 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1086 __ VerifyX87StackDepth(1);
1087 }
992 __ fstp(0); 1088 __ fstp(0);
993 if (input->IsRegister()) { 1089 if (input->IsRegister()) {
994 Register input_reg = i.InputRegister(0); 1090 Register input_reg = i.InputRegister(0);
995 __ push(input_reg); 1091 __ push(input_reg);
996 __ fild_s(Operand(esp, 0)); 1092 __ fild_s(Operand(esp, 0));
997 __ pop(input_reg); 1093 __ pop(input_reg);
998 } else { 1094 } else {
999 __ fild_s(i.InputOperand(0)); 1095 __ fild_s(i.InputOperand(0));
1000 } 1096 }
1001 break; 1097 break;
1002 } 1098 }
1003 case kX87Float32ToFloat64: { 1099 case kX87Float32ToFloat64: {
1004 InstructionOperand* input = instr->InputAt(0); 1100 InstructionOperand* input = instr->InputAt(0);
1005 if (input->IsDoubleRegister()) { 1101 if (input->IsDoubleRegister()) {
1006 __ sub(esp, Immediate(kDoubleSize)); 1102 __ sub(esp, Immediate(kDoubleSize));
1007 __ fstp_d(MemOperand(esp, 0)); 1103 __ fstp_d(MemOperand(esp, 0));
1008 __ fld_d(MemOperand(esp, 0)); 1104 __ fld_d(MemOperand(esp, 0));
1009 __ add(esp, Immediate(kDoubleSize)); 1105 __ add(esp, Immediate(kDoubleSize));
1010 } else { 1106 } else {
1011 DCHECK(input->IsDoubleStackSlot()); 1107 DCHECK(input->IsDoubleStackSlot());
1108 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1109 __ VerifyX87StackDepth(1);
1110 }
1012 __ fstp(0); 1111 __ fstp(0);
1013 __ fld_s(i.InputOperand(0)); 1112 __ fld_s(i.InputOperand(0));
1014 } 1113 }
1015 break; 1114 break;
1016 } 1115 }
1017 case kX87Uint32ToFloat64: { 1116 case kX87Uint32ToFloat64: {
1117 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1118 __ VerifyX87StackDepth(1);
1119 }
1018 __ fstp(0); 1120 __ fstp(0);
1019 __ LoadUint32NoSSE2(i.InputRegister(0)); 1121 __ LoadUint32NoSSE2(i.InputRegister(0));
1020 break; 1122 break;
1021 } 1123 }
1022 case kX87Float32ToInt32: { 1124 case kX87Float32ToInt32: {
1023 if (!instr->InputAt(0)->IsDoubleRegister()) { 1125 if (!instr->InputAt(0)->IsDoubleRegister()) {
1024 __ fld_s(i.InputOperand(0)); 1126 __ fld_s(i.InputOperand(0));
1025 } 1127 }
1026 __ TruncateX87TOSToI(i.OutputRegister(0)); 1128 __ TruncateX87TOSToI(i.OutputRegister(0));
1027 if (!instr->InputAt(0)->IsDoubleRegister()) { 1129 if (!instr->InputAt(0)->IsDoubleRegister()) {
(...skipping 13 matching lines...) Expand all
1041 } 1143 }
1042 case kX87Float64ToFloat32: { 1144 case kX87Float64ToFloat32: {
1043 InstructionOperand* input = instr->InputAt(0); 1145 InstructionOperand* input = instr->InputAt(0);
1044 if (input->IsDoubleRegister()) { 1146 if (input->IsDoubleRegister()) {
1045 __ sub(esp, Immediate(kDoubleSize)); 1147 __ sub(esp, Immediate(kDoubleSize));
1046 __ fstp_s(MemOperand(esp, 0)); 1148 __ fstp_s(MemOperand(esp, 0));
1047 __ fld_s(MemOperand(esp, 0)); 1149 __ fld_s(MemOperand(esp, 0));
1048 __ add(esp, Immediate(kDoubleSize)); 1150 __ add(esp, Immediate(kDoubleSize));
1049 } else { 1151 } else {
1050 DCHECK(input->IsDoubleStackSlot()); 1152 DCHECK(input->IsDoubleStackSlot());
1153 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1154 __ VerifyX87StackDepth(1);
1155 }
1051 __ fstp(0); 1156 __ fstp(0);
1052 __ fld_d(i.InputOperand(0)); 1157 __ fld_d(i.InputOperand(0));
1053 __ sub(esp, Immediate(kDoubleSize)); 1158 __ sub(esp, Immediate(kDoubleSize));
1054 __ fstp_s(MemOperand(esp, 0)); 1159 __ fstp_s(MemOperand(esp, 0));
1055 __ fld_s(MemOperand(esp, 0)); 1160 __ fld_s(MemOperand(esp, 0));
1056 __ add(esp, Immediate(kDoubleSize)); 1161 __ add(esp, Immediate(kDoubleSize));
1057 } 1162 }
1058 break; 1163 break;
1059 } 1164 }
1060 case kX87Float64ToUint32: { 1165 case kX87Float64ToUint32: {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 } 1216 }
1112 case kX87Float64InsertLowWord32: { 1217 case kX87Float64InsertLowWord32: {
1113 __ sub(esp, Immediate(kDoubleSize)); 1218 __ sub(esp, Immediate(kDoubleSize));
1114 __ fstp_d(MemOperand(esp, 0)); 1219 __ fstp_d(MemOperand(esp, 0));
1115 __ mov(MemOperand(esp, 0), i.InputRegister(1)); 1220 __ mov(MemOperand(esp, 0), i.InputRegister(1));
1116 __ fld_d(MemOperand(esp, 0)); 1221 __ fld_d(MemOperand(esp, 0));
1117 __ add(esp, Immediate(kDoubleSize)); 1222 __ add(esp, Immediate(kDoubleSize));
1118 break; 1223 break;
1119 } 1224 }
1120 case kX87Float64Sqrt: { 1225 case kX87Float64Sqrt: {
1226 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1227 __ VerifyX87StackDepth(1);
1228 }
1121 __ X87SetFPUCW(0x027F); 1229 __ X87SetFPUCW(0x027F);
1122 __ fstp(0); 1230 __ fstp(0);
1123 __ fld_d(MemOperand(esp, 0)); 1231 __ fld_d(MemOperand(esp, 0));
1124 __ fsqrt(); 1232 __ fsqrt();
1125 __ lea(esp, Operand(esp, kDoubleSize)); 1233 __ lea(esp, Operand(esp, kDoubleSize));
1126 __ X87SetFPUCW(0x037F); 1234 __ X87SetFPUCW(0x037F);
1127 break; 1235 break;
1128 } 1236 }
1129 case kX87Float64Round: { 1237 case kX87Float64Round: {
1130 RoundingMode mode = 1238 RoundingMode mode =
1131 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); 1239 static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
1132 // Set the correct round mode in x87 control register 1240 // Set the correct round mode in x87 control register
1133 __ X87SetRC((mode << 10)); 1241 __ X87SetRC((mode << 10));
1134 1242
1135 if (!instr->InputAt(0)->IsDoubleRegister()) { 1243 if (!instr->InputAt(0)->IsDoubleRegister()) {
1136 InstructionOperand* input = instr->InputAt(0); 1244 InstructionOperand* input = instr->InputAt(0);
1137 USE(input); 1245 USE(input);
1138 DCHECK(input->IsDoubleStackSlot()); 1246 DCHECK(input->IsDoubleStackSlot());
1247 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1248 __ VerifyX87StackDepth(1);
1249 }
1139 __ fstp(0); 1250 __ fstp(0);
1140 __ fld_d(i.InputOperand(0)); 1251 __ fld_d(i.InputOperand(0));
1141 } 1252 }
1142 __ frndint(); 1253 __ frndint();
1143 __ X87SetRC(0x0000); 1254 __ X87SetRC(0x0000);
1144 break; 1255 break;
1145 } 1256 }
1146 case kX87Float64Cmp: { 1257 case kX87Float64Cmp: {
1147 __ fld_d(MemOperand(esp, kDoubleSize)); 1258 __ fld_d(MemOperand(esp, kDoubleSize));
1148 __ fld_d(MemOperand(esp, 0)); 1259 __ fld_d(MemOperand(esp, 0));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 } else { 1304 } else {
1194 __ mov(operand, i.InputRegister(index)); 1305 __ mov(operand, i.InputRegister(index));
1195 } 1306 }
1196 } 1307 }
1197 break; 1308 break;
1198 case kX87Movsd: { 1309 case kX87Movsd: {
1199 if (instr->HasOutput()) { 1310 if (instr->HasOutput()) {
1200 X87Register output = i.OutputDoubleRegister(); 1311 X87Register output = i.OutputDoubleRegister();
1201 USE(output); 1312 USE(output);
1202 DCHECK(output.code() == 0); 1313 DCHECK(output.code() == 0);
1314 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1315 __ VerifyX87StackDepth(1);
1316 }
1203 __ fstp(0); 1317 __ fstp(0);
1204 __ fld_d(i.MemoryOperand()); 1318 __ fld_d(i.MemoryOperand());
1205 } else { 1319 } else {
1206 size_t index = 0; 1320 size_t index = 0;
1207 Operand operand = i.MemoryOperand(&index); 1321 Operand operand = i.MemoryOperand(&index);
1208 __ fst_d(operand); 1322 __ fst_d(operand);
1209 } 1323 }
1210 break; 1324 break;
1211 } 1325 }
1212 case kX87Movss: { 1326 case kX87Movss: {
1213 if (instr->HasOutput()) { 1327 if (instr->HasOutput()) {
1214 X87Register output = i.OutputDoubleRegister(); 1328 X87Register output = i.OutputDoubleRegister();
1215 USE(output); 1329 USE(output);
1216 DCHECK(output.code() == 0); 1330 DCHECK(output.code() == 0);
1331 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1332 __ VerifyX87StackDepth(1);
1333 }
1217 __ fstp(0); 1334 __ fstp(0);
1218 __ fld_s(i.MemoryOperand()); 1335 __ fld_s(i.MemoryOperand());
1219 } else { 1336 } else {
1220 size_t index = 0; 1337 size_t index = 0;
1221 Operand operand = i.MemoryOperand(&index); 1338 Operand operand = i.MemoryOperand(&index);
1222 __ fst_s(operand); 1339 __ fst_s(operand);
1223 } 1340 }
1224 break; 1341 break;
1225 } 1342 }
1226 case kX87BitcastFI: { 1343 case kX87BitcastFI: {
1227 __ mov(i.OutputRegister(), MemOperand(esp, 0)); 1344 __ mov(i.OutputRegister(), MemOperand(esp, 0));
1228 __ lea(esp, Operand(esp, kFloatSize)); 1345 __ lea(esp, Operand(esp, kFloatSize));
1229 break; 1346 break;
1230 } 1347 }
1231 case kX87BitcastIF: { 1348 case kX87BitcastIF: {
1349 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1350 __ VerifyX87StackDepth(1);
1351 }
1232 __ fstp(0); 1352 __ fstp(0);
1233 if (instr->InputAt(0)->IsRegister()) { 1353 if (instr->InputAt(0)->IsRegister()) {
1234 __ lea(esp, Operand(esp, -kFloatSize)); 1354 __ lea(esp, Operand(esp, -kFloatSize));
1235 __ mov(MemOperand(esp, 0), i.InputRegister(0)); 1355 __ mov(MemOperand(esp, 0), i.InputRegister(0));
1236 __ fld_s(MemOperand(esp, 0)); 1356 __ fld_s(MemOperand(esp, 0));
1237 __ lea(esp, Operand(esp, kFloatSize)); 1357 __ lea(esp, Operand(esp, kFloatSize));
1238 } else { 1358 } else {
1239 __ fld_s(i.InputOperand(0)); 1359 __ fld_s(i.InputOperand(0));
1240 } 1360 }
1241 break; 1361 break;
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 1867
1748 // Initailize FPU state. 1868 // Initailize FPU state.
1749 __ fninit(); 1869 __ fninit();
1750 __ fld1(); 1870 __ fld1();
1751 } 1871 }
1752 1872
1753 1873
1754 void CodeGenerator::AssembleReturn() { 1874 void CodeGenerator::AssembleReturn() {
1755 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 1875 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
1756 1876
1877 // Clear the FPU stack only if there is no return value in the stack.
1878 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1879 __ VerifyX87StackDepth(1);
1880 }
1881 bool clear_stack = true;
1882 for (int i = 0; i < descriptor->ReturnCount(); i++) {
1883 MachineRepresentation rep = descriptor->GetReturnType(i).representation();
1884 LinkageLocation loc = descriptor->GetReturnLocation(i);
1885 if (IsFloatingPoint(rep) && loc == LinkageLocation::ForRegister(0)) {
1886 clear_stack = false;
1887 break;
1888 }
1889 }
1890 if (clear_stack) __ fstp(0);
1891
1757 int pop_count = static_cast<int>(descriptor->StackParameterCount()); 1892 int pop_count = static_cast<int>(descriptor->StackParameterCount());
1758 const RegList saves = descriptor->CalleeSavedRegisters(); 1893 const RegList saves = descriptor->CalleeSavedRegisters();
1759 // Restore registers. 1894 // Restore registers.
1760 if (saves != 0) { 1895 if (saves != 0) {
1761 for (int i = 0; i < Register::kNumRegisters; i++) { 1896 for (int i = 0; i < Register::kNumRegisters; i++) {
1762 if (!((1 << i) & saves)) continue; 1897 if (!((1 << i) & saves)) continue;
1763 __ pop(Register::from_code(i)); 1898 __ pop(Register::from_code(i));
1764 } 1899 }
1765 } 1900 }
1766 1901
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
2021 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 2156 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
2022 __ Nop(padding_size); 2157 __ Nop(padding_size);
2023 } 2158 }
2024 } 2159 }
2025 2160
2026 #undef __ 2161 #undef __
2027 2162
2028 } // namespace compiler 2163 } // namespace compiler
2029 } // namespace internal 2164 } // namespace internal
2030 } // namespace v8 2165 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698