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

Side by Side Diff: src/x64/codegen-x64.cc

Issue 303034: X64/Win64: Alternative implementation of fmod in general. (Closed)
Patch Set: Created 11 years, 1 month 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 | « src/x64/assembler-x64.cc ('k') | src/x64/disasm-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 7677 matching lines...) Expand 10 before | Expand all | Expand 10 after
7688 } 7688 }
7689 } 7689 }
7690 7690
7691 7691
7692 int CompareStub::MinorKey() { 7692 int CompareStub::MinorKey() {
7693 // Encode the two parameters in a unique 16 bit value. 7693 // Encode the two parameters in a unique 16 bit value.
7694 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); 7694 ASSERT(static_cast<unsigned>(cc_) < (1 << 15));
7695 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); 7695 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0);
7696 } 7696 }
7697 7697
7698 #undef __
7699
7700 #define __ masm.
7701
7702 #ifdef _WIN64
7703 typedef double (*ModuloFunction)(double, double);
7704 // Define custom fmod implementation.
7705 ModuloFunction CreateModuloFunction() {
7706 size_t actual_size;
7707 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
7708 &actual_size,
7709 true));
7710 CHECK(buffer);
7711 Assembler masm(buffer, actual_size);
7712
William Hesse 2009/10/23 07:45:16 Put a comment in here that no relocatable addresse
7713 // Windows 64 ABI passes double arguments in xmm0, xmm1 and
7714 // returns result in xmm0.
7715 // Argument backing space is allocated on the stack above
7716 // the return address.
7717
7718 // Compute x mod y.
7719 // Load y and x (use argument backing store as temporary storage).
7720 __ movsd(Operand(rsp, kPointerSize * 2), xmm1);
7721 __ movsd(Operand(rsp, kPointerSize), xmm0);
7722 __ fld_d(Operand(rsp, kPointerSize * 2));
7723 __ fld_d(Operand(rsp, kPointerSize));
7724
7725 // Clear exception flags before operation.
7726 {
7727 Label no_exceptions;
7728 __ fwait();
7729 __ fnstsw_ax();
7730 // Clear if Illegal Operand or Zero Division exceptions are set.
7731 __ testb(rax, Immediate(5));
7732 __ j(zero, &no_exceptions);
7733 __ fnclex();
7734 __ bind(&no_exceptions);
7735 }
7736
7737 // Compute st(0) % st(1)
7738 {
7739 Label partial_remainder_loop;
7740 __ bind(&partial_remainder_loop);
7741 __ fprem();
7742 __ fwait();
7743 __ fnstsw_ax();
7744 __ testl(rax, Immediate(0x400 /* C2 */));
7745 // If C2 is set, computation only has partial result. Loop to
7746 // continue computation.
7747 __ j(not_zero, &partial_remainder_loop);
7748 }
7749
7750 Label valid_result;
7751 Label return_result;
7752 // If Invalid Operand or Zero Division exceptions are set,
7753 // return NaN.
7754 __ testb(rax, Immediate(5));
7755 __ j(zero, &valid_result);
7756 __ fstp(0); // Drop result in st(0).
7757 int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000);
7758 __ movq(rcx, kNaNValue, RelocInfo::NONE);
7759 __ movq(Operand(rsp, kPointerSize), rcx);
7760 __ movsd(xmm0, Operand(rsp, kPointerSize));
7761 __ jmp(&return_result);
7762
7763 // If result is valid, return that.
7764 __ bind(&valid_result);
7765 __ fstp_d(Operand(rsp, kPointerSize));
7766 __ movsd(xmm0, Operand(rsp, kPointerSize));
7767
7768 // Clean up FPU stack and exceptions and return xmm0
7769 __ bind(&return_result);
7770 __ fstp(0); // Unload y.
7771 {
7772 Label no_exceptions;
7773 __ testb(rax, Immediate(0x3f /* Any Exception*/));
7774 __ j(zero, &no_exceptions);
7775 __ fnclex();
7776 __ bind(&no_exceptions);
7777 }
7778 __ ret(0);
7779
7780 CodeDesc desc;
7781 masm.GetCode(&desc);
7782 // Call the function from C++.
7783 return FUNCTION_CAST<ModuloFunction>(buffer);
7784 }
7785
7786 #endif
7698 7787
7699 #undef __ 7788 #undef __
7700 7789
7701 } } // namespace v8::internal 7790 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.cc ('k') | src/x64/disasm-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698