OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |