| 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 |