Index: src/ia32/codegen-ia32.cc |
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc |
index 3e085a245dc222ee9a9413419d446935fead0fdf..de6901f9cdbe34d84066b317fd5fb9af5950da80 100644 |
--- a/src/ia32/codegen-ia32.cc |
+++ b/src/ia32/codegen-ia32.cc |
@@ -30,6 +30,7 @@ |
#if defined(V8_TARGET_ARCH_IA32) |
#include "codegen.h" |
+#include "heap.h" |
#include "macro-assembler.h" |
namespace v8 { |
@@ -55,6 +56,53 @@ 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)); |
+ // esp[1 * kPointerSize]: raw double input |
+ // esp[0 * kPointerSize]: return address |
+ // Move double input into registers. |
+ |
+ __ push(ebx); |
+ __ push(edx); |
+ __ push(edi); |
+ __ fld_d(Operand(esp, 4 * kPointerSize)); |
+ __ mov(ebx, Operand(esp, 4 * kPointerSize)); |
+ __ mov(edx, Operand(esp, 5 * kPointerSize)); |
Yang
2012/03/03 11:05:01
Had wrong stack offsets in the first version of th
|
+ TranscendentalCacheStub::GenerateOperation(&masm, type); |
+ // The return value is expected to be on ST(0) of the FPU stack. |
+ __ pop(edi); |
+ __ pop(edx); |
+ __ pop(ebx); |
+ __ 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); |
+} |
+ |
+ |
static void MemCopyWrapper(void* dest, const void* src, size_t size) { |
memcpy(dest, src, size); |
} |