Index: src/x64/codegen-x64.cc |
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc |
index 8947f70055f64745333a35e1b840480e1c0a1796..2584889f087d56ff0fffd6f6521b47a7cf315326 100644 |
--- a/src/x64/codegen-x64.cc |
+++ b/src/x64/codegen-x64.cc |
@@ -54,6 +54,52 @@ void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { |
#define __ masm. |
+ |
+TranscendentalFunction CreateTranscendentalFunction( |
+ TranscendentalCache::Type type) { |
+ size_t actual_size; |
+ // Allocate buffer in executable space. |
+ byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, |
+ &actual_size, |
+ true)); |
+ if (buffer == NULL) { |
+ // Fallback to library function if function cannot be created. |
+ switch (type) { |
+ case TranscendentalCache::SIN: return &sin; |
+ case TranscendentalCache::COS: return &cos; |
+ case TranscendentalCache::TAN: return &tan; |
+ case TranscendentalCache::LOG: return &log; |
+ default: UNIMPLEMENTED(); |
+ } |
+ } |
+ |
+ MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); |
+ // xmm0: raw double input. |
+ // Move double input into registers. |
+ __ push(rbx); |
+ __ push(rdi); |
+ __ movq(rbx, xmm0); |
+ __ push(rbx); |
+ __ fld_d(Operand(rsp, 0)); |
+ TranscendentalCacheStub::GenerateOperation(&masm, type); |
+ // The return value is expected to be in xmm0. |
+ __ fstp_d(Operand(rsp, 0)); |
+ __ pop(rbx); |
+ __ movq(xmm0, rbx); |
+ __ pop(rdi); |
+ __ pop(rbx); |
+ __ Ret(); |
+ |
+ CodeDesc desc; |
+ masm.GetCode(&desc); |
+ ASSERT(desc.reloc_size == 0); |
+ |
+ CPU::FlushICache(buffer, actual_size); |
+ OS::ProtectCode(buffer, actual_size); |
+ return FUNCTION_CAST<TranscendentalFunction>(buffer); |
+} |
+ |
+ |
#ifdef _WIN64 |
typedef double (*ModuloFunction)(double, double); |
// Define custom fmod implementation. |