diff options
author | Ryan <ry@tinyclouds.org> | 2009-04-22 19:35:47 +0200 |
---|---|---|
committer | Ryan <ry@tinyclouds.org> | 2009-04-22 19:35:47 +0200 |
commit | 40c0f755c998d2615fe8466aab20c6d81bd463e7 (patch) | |
tree | 51fcb08ba1bd3f745ceb43fd5f814a5700079881 /deps/v8/test/cctest/test-assembler-ia32.cc | |
parent | a93cf503073ba0258c55dec4dc325bdc1509b739 (diff) | |
download | node-new-40c0f755c998d2615fe8466aab20c6d81bd463e7.tar.gz |
import full versions of dependency libraries!
Diffstat (limited to 'deps/v8/test/cctest/test-assembler-ia32.cc')
-rw-r--r-- | deps/v8/test/cctest/test-assembler-ia32.cc | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/deps/v8/test/cctest/test-assembler-ia32.cc b/deps/v8/test/cctest/test-assembler-ia32.cc new file mode 100644 index 0000000000..9ad7c76f11 --- /dev/null +++ b/deps/v8/test/cctest/test-assembler-ia32.cc @@ -0,0 +1,395 @@ +// Copyright 2006-2008 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <stdlib.h> + +#include "v8.h" + +#include "disassembler.h" +#include "factory.h" +#include "macro-assembler.h" +#include "platform.h" +#include "serialize.h" +#include "cctest.h" + +using namespace v8::internal; + + +typedef int (*F0)(); +typedef int (*F1)(int x); +typedef int (*F2)(int x, int y); + + +static v8::Persistent<v8::Context> env; + + +static void InitializeVM() { + if (env.IsEmpty()) { + env = v8::Context::New(); + } +} + + +#define __ assm. + +TEST(AssemblerIa320) { + InitializeVM(); + v8::HandleScope scope; + + v8::internal::byte buffer[256]; + Assembler assm(buffer, sizeof buffer); + + __ mov(eax, Operand(esp, 4)); + __ add(eax, Operand(esp, 8)); + __ ret(0); + + CodeDesc desc; + assm.GetCode(&desc); + Object* code = Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value())); + CHECK(code->IsCode()); +#ifdef DEBUG + Code::cast(code)->Print(); +#endif + F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry()); + int res = f(3, 4); + ::printf("f() = %d\n", res); + CHECK_EQ(7, res); +} + + +TEST(AssemblerIa321) { + InitializeVM(); + v8::HandleScope scope; + + v8::internal::byte buffer[256]; + Assembler assm(buffer, sizeof buffer); + Label L, C; + + __ mov(edx, Operand(esp, 4)); + __ xor_(eax, Operand(eax)); // clear eax + __ jmp(&C); + + __ bind(&L); + __ add(eax, Operand(edx)); + __ sub(Operand(edx), Immediate(1)); + + __ bind(&C); + __ test(edx, Operand(edx)); + __ j(not_zero, &L, taken); + __ ret(0); + + CodeDesc desc; + assm.GetCode(&desc); + Object* code = Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value())); + CHECK(code->IsCode()); +#ifdef DEBUG + Code::cast(code)->Print(); +#endif + F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry()); + int res = f(100); + ::printf("f() = %d\n", res); + CHECK_EQ(5050, res); +} + + +TEST(AssemblerIa322) { + InitializeVM(); + v8::HandleScope scope; + + v8::internal::byte buffer[256]; + Assembler assm(buffer, sizeof buffer); + Label L, C; + + __ mov(edx, Operand(esp, 4)); + __ mov(eax, 1); + __ jmp(&C); + + __ bind(&L); + __ imul(eax, Operand(edx)); + __ sub(Operand(edx), Immediate(1)); + + __ bind(&C); + __ test(edx, Operand(edx)); + __ j(not_zero, &L, taken); + __ ret(0); + + // some relocated stuff here, not executed + __ mov(eax, Factory::true_value()); + __ jmp(NULL, RelocInfo::RUNTIME_ENTRY); + + CodeDesc desc; + assm.GetCode(&desc); + Object* code = Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value())); + CHECK(code->IsCode()); +#ifdef DEBUG + Code::cast(code)->Print(); +#endif + F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry()); + int res = f(10); + ::printf("f() = %d\n", res); + CHECK_EQ(3628800, res); +} + + +typedef int (*F3)(float x); + +TEST(AssemblerIa323) { + InitializeVM(); + v8::HandleScope scope; + + v8::internal::byte buffer[256]; + Assembler assm(buffer, sizeof buffer); + + CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2)); + { CpuFeatures::Scope fscope(CpuFeatures::SSE2); + __ cvttss2si(eax, Operand(esp, 4)); + __ ret(0); + } + + CodeDesc desc; + assm.GetCode(&desc); + Code* code = + Code::cast(Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value()))); + // don't print the code - our disassembler can't handle cvttss2si + // instead print bytes + Disassembler::Dump(stdout, + code->instruction_start(), + code->instruction_start() + code->instruction_size()); + F3 f = FUNCTION_CAST<F3>(code->entry()); + int res = f(static_cast<float>(-3.1415)); + ::printf("f() = %d\n", res); + CHECK_EQ(-3, res); +} + + +typedef int (*F4)(double x); + +TEST(AssemblerIa324) { + InitializeVM(); + v8::HandleScope scope; + + v8::internal::byte buffer[256]; + Assembler assm(buffer, sizeof buffer); + + CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2)); + CpuFeatures::Scope fscope(CpuFeatures::SSE2); + __ cvttsd2si(eax, Operand(esp, 4)); + __ ret(0); + + CodeDesc desc; + assm.GetCode(&desc); + Code* code = + Code::cast(Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value()))); + // don't print the code - our disassembler can't handle cvttsd2si + // instead print bytes + Disassembler::Dump(stdout, + code->instruction_start(), + code->instruction_start() + code->instruction_size()); + F4 f = FUNCTION_CAST<F4>(code->entry()); + int res = f(2.718281828); + ::printf("f() = %d\n", res); + CHECK_EQ(2, res); +} + + +static int baz = 42; +TEST(AssemblerIa325) { + InitializeVM(); + v8::HandleScope scope; + + v8::internal::byte buffer[256]; + Assembler assm(buffer, sizeof buffer); + + __ mov(eax, Operand(reinterpret_cast<intptr_t>(&baz), RelocInfo::NONE)); + __ ret(0); + + CodeDesc desc; + assm.GetCode(&desc); + Code* code = + Code::cast(Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value()))); + F0 f = FUNCTION_CAST<F0>(code->entry()); + int res = f(); + CHECK_EQ(42, res); +} + + +typedef double (*F5)(double x, double y); + +TEST(AssemblerIa326) { + InitializeVM(); + v8::HandleScope scope; + CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2)); + CpuFeatures::Scope fscope(CpuFeatures::SSE2); + v8::internal::byte buffer[256]; + Assembler assm(buffer, sizeof buffer); + + __ movdbl(xmm0, Operand(esp, 1 * kPointerSize)); + __ movdbl(xmm1, Operand(esp, 3 * kPointerSize)); + __ addsd(xmm0, xmm1); + __ mulsd(xmm0, xmm1); + __ subsd(xmm0, xmm1); + __ divsd(xmm0, xmm1); + // Copy xmm0 to st(0) using eight bytes of stack. + __ sub(Operand(esp), Immediate(8)); + __ movdbl(Operand(esp, 0), xmm0); + __ fld_d(Operand(esp, 0)); + __ add(Operand(esp), Immediate(8)); + __ ret(0); + + CodeDesc desc; + assm.GetCode(&desc); + Code* code = + Code::cast(Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value()))); +#ifdef DEBUG + ::printf("\n---\n"); + // don't print the code - our disassembler can't handle SSE instructions + // instead print bytes + Disassembler::Dump(stdout, + code->instruction_start(), + code->instruction_start() + code->instruction_size()); +#endif + F5 f = FUNCTION_CAST<F5>(code->entry()); + double res = f(2.2, 1.1); + ::printf("f() = %f\n", res); + CHECK(2.29 < res && res < 2.31); +} + + +typedef double (*F6)(int x); + +TEST(AssemblerIa328) { + InitializeVM(); + v8::HandleScope scope; + CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2)); + CpuFeatures::Scope fscope(CpuFeatures::SSE2); + v8::internal::byte buffer[256]; + Assembler assm(buffer, sizeof buffer); + __ mov(eax, Operand(esp, 4)); + __ cvtsi2sd(xmm0, Operand(eax)); + // Copy xmm0 to st(0) using eight bytes of stack. + __ sub(Operand(esp), Immediate(8)); + __ movdbl(Operand(esp, 0), xmm0); + __ fld_d(Operand(esp, 0)); + __ add(Operand(esp), Immediate(8)); + __ ret(0); + CodeDesc desc; + assm.GetCode(&desc); + Code* code = + Code::cast(Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value()))); + CHECK(code->IsCode()); +#ifdef DEBUG + Code::cast(code)->Print(); +#endif + F6 f = FUNCTION_CAST<F6>(Code::cast(code)->entry()); + double res = f(12); + + ::printf("f() = %f\n", res); + CHECK(11.99 < res && res < 12.001); +} + + +typedef int (*F7)(double x, double y); + +TEST(AssemblerIa329) { + InitializeVM(); + v8::HandleScope scope; + v8::internal::byte buffer[256]; + MacroAssembler assm(buffer, sizeof buffer); + enum { kEqual = 0, kGreater = 1, kLess = 2, kNaN = 3, kUndefined = 4 }; + Label equal_l, less_l, greater_l, nan_l; + __ fld_d(Operand(esp, 3 * kPointerSize)); + __ fld_d(Operand(esp, 1 * kPointerSize)); + __ FCmp(); + __ j(parity_even, &nan_l, taken); + __ j(equal, &equal_l, taken); + __ j(below, &less_l, taken); + __ j(above, &greater_l, taken); + + __ mov(eax, kUndefined); + __ ret(0); + + __ bind(&equal_l); + __ mov(eax, kEqual); + __ ret(0); + + __ bind(&greater_l); + __ mov(eax, kGreater); + __ ret(0); + + __ bind(&less_l); + __ mov(eax, kLess); + __ ret(0); + + __ bind(&nan_l); + __ mov(eax, kNaN); + __ ret(0); + + + CodeDesc desc; + assm.GetCode(&desc); + Code* code = + Code::cast(Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value()))); + CHECK(code->IsCode()); +#ifdef DEBUG + Code::cast(code)->Print(); +#endif + + F7 f = FUNCTION_CAST<F7>(Code::cast(code)->entry()); + CHECK_EQ(kLess, f(1.1, 2.2)); + CHECK_EQ(kEqual, f(2.2, 2.2)); + CHECK_EQ(kGreater, f(3.3, 2.2)); + CHECK_EQ(kNaN, f(OS::nan_value(), 1.1)); +} + +#undef __ |