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

Unified Diff: test/cctest/test-code-stub-sh4.cc

Issue 11275184: First draft of the sh4 port Base URL: http://github.com/v8/v8.git@master
Patch Set: Use GYP and fixe some typos Created 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « test/cctest/test-assembler-sh4.cc ('k') | test/cctest/test-macro-assembler-sh4.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-code-stub-sh4.cc
diff --git a/test/cctest/test-code-stub-sh4.cc b/test/cctest/test-code-stub-sh4.cc
new file mode 100644
index 0000000000000000000000000000000000000000..dba83d5d9e4225890210971414166c14b416ea10
--- /dev/null
+++ b/test/cctest/test-code-stub-sh4.cc
@@ -0,0 +1,719 @@
+// Copyright 2011 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 "v8.h"
+
+#include "macro-assembler.h"
+#include "code-stubs.h"
+#include "factory.h"
+#include "platform.h"
+#include "serialize.h"
+#include "cctest.h"
+
+using namespace v8::internal;
+
+Handle<JSFunction>
+CreateJSFunctionFromCode(const char *name, Code *code, Isolate* isolate) {
+ Factory* factory = isolate->factory();
+
+ // Allocate the function
+ Handle<String> symbol = factory->LookupAsciiSymbol(name);
+ Handle<JSFunction> new_function =
+ factory->NewFunctionWithoutPrototype(symbol, CLASSIC_MODE);
+
+ // Bind the code
+ new_function->set_code(code);
+ new_function->shared()->set_code(code);
+ Handle<String> source = factory->NewStringFromAscii(CStrVector("() {}"));
+ Handle<Script> script = factory->NewScript(source);
+ script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
+ new_function->shared()->set_script(*script);
+ new_function->shared()->set_start_position(0);
+ new_function->shared()->set_end_position(source->length());
+ new_function->shared()->DontAdaptArguments();
+
+ return new_function;
+}
+
+#define BEGIN() \
+ FLAG_disable_native_files = true; \
+ FLAG_code_comments = true; \
+ v8::HandleScope scope; \
+ Isolate* isolate = Isolate::Current(); \
+ LocalContext env; \
+ MacroAssembler assm(Isolate::Current(), NULL, 0);
+
+
+#define JIT() \
+ CodeDesc desc; \
+ assm.GetCode(&desc); \
+ Code* code = Code::cast(HEAP-> \
+ CreateCode(desc, \
+ Code::ComputeFlags(Code::BUILTIN), \
+ Handle<Object>(HEAP->null_value()))-> \
+ ToObjectChecked()); \
+ Handle<JSFunction> func = CreateJSFunctionFromCode(__FUNCTION__, \
+ code, isolate);
+
+#define CALL() \
+ CHECK(func->code()->IsCode()); \
+ bool exc; \
+ Handle<Object> receiver(isolate->context()->global_proxy(), isolate); \
+ Handle<Object> result = Execution::Call(func, receiver, 0, NULL, &exc); \
+ if (exc) { result = isolate->factory()->nan_value(); } \
+ (void)0
+
+// #define NOPRINT
+#if defined(DEBUG) && !defined(NOPRINT)
+#define PRINT() Code::cast(func->code())->Print()
+#else
+#define PRINT() (void)0
+#endif
+
+#define GLOBAL_FUNCTION_PTR() (isolate->global_context()->closure())
+#define GLOBAL_PTR() (*(isolate->global_object()))
+#define GLOBAL_CONTEXT_PTR() (*(isolate->global_context()))
+#define GLOBAL_CLOSURE_PTR() (isolate->global_context()->closure())
+#define GLOBAL_OBJECT_FUNCTION_PTR() \
+ (isolate->global_context()->object_function())
+#define GLOBAL_BUILTINS_PTR() (*isolate->builtins())
+
+#define CMT(msg) do { Comment cmnt(&assm, msg); } while (0)
+
+#define __ assm.
+
+// This macro stores in r10 the line number before branching to the error label.
+// At the error label r10 can be moved to r0 such that return code of the
+// function if not 0 indicates an error at the line of the branch.
+#define B_LINE(cond, target) do { \
+ __ mov(r10, Operand(__LINE__)); \
+ if (cond == al) { \
+ __ b(target); \
+ } else { \
+ __ b(cond, target); \
+ } \
+ } while (0);
+
+
+// Test Empty function call
+// This covers JSEntryStub (call to the empty function) builtin.
+// This covers CEntryStub (call to kEmptyFunction) builtin.
+// This Covers also Generate_Adaptor() and JumpToExternalReference()
+TEST(sh4_cs_0) {
+ BEGIN();
+
+ // Force use of empty function (global_context()->closure())
+ Handle<JSFunction> func =
+ Handle<JSFunction>(isolate->global_context()->closure(), isolate);
+
+ fprintf(stderr, "isolate = Isolate::Current(): %p\n",
+ reinterpret_cast<void *>(isolate));
+ fprintf(stderr, "isolate_context = isolate->context(): %p\n",
+ reinterpret_cast<void *>(isolate->context()));
+ fprintf(stderr, "global_context = isolate->global_context(): %p\n",
+ reinterpret_cast<void *>(*isolate->global_context()));
+ fprintf(stderr, "global_context_closure = global_context->closure(): %p\n",
+ reinterpret_cast<void *>(isolate->global_context()->closure()));
+ fprintf(stderr, "global = isolate->global_object(): %p\n",
+ reinterpret_cast<void *>(*isolate->global_object()));
+ fprintf(stderr, "global_proxy = isolate->global_proxy(): %p\n",
+ reinterpret_cast<void *>(isolate->context()->global_proxy()));
+ fprintf(stderr, "closure_code = global_context_closure->code(): %p \n",
+ reinterpret_cast<void *>(func->code()));
+ fprintf(stderr, "closure_entry = code->entry(): %p \n",
+ reinterpret_cast<void *>(func->code()->entry()));
+
+ PRINT();
+
+ CALL();
+
+ // The empty function returns the undefined value.
+ CHECK(result->IsHeapObject());
+ CHECK(HeapObject::cast(*result)->IsUndefined());
+}
+
+// Test empty function that scratches all JS registers
+// (except roots, cp, fp, sp)
+TEST(sh4_cs_1) {
+ BEGIN();
+
+ // We are in a JS context, thus we can scratch caller and callee saved
+ __ Dead(r0, r1, r2, r3);
+ __ Dead(r4, r5, r6, r7);
+ __ Dead(r8, r9, r10, r11);
+
+ __ mov(r0, Operand(Smi::FromInt(0)));
+ __ rts();
+
+ JIT();
+
+ PRINT();
+
+ CALL();
+
+ // The function must return a result as Smi.
+ CHECK(result->IsSmi());
+ CHECK_EQ(0, Smi::cast(*result)->value());
+}
+
+
+// Test CompareInstanceType(), CompareObjectType()
+TEST(sh4_cs_2) {
+ BEGIN();
+
+ Label error;
+
+ // Check that roots is actually te root object
+ CMT("Check roots");
+ __ mov(r0, Operand(ExternalReference::roots_array_start(assm.isolate())));
+ __ cmp(r0, roots);
+ B_LINE(ne, &error);
+
+ // Check that cp is actually the current context
+ CMT("Check cp");
+ __ mov(r0, Operand((intptr_t)GLOBAL_CONTEXT_PTR(),
+ RelocInfo::EXTERNAL_REFERENCE));
+ __ cmp(r0, cp);
+ B_LINE(ne, &error);
+
+ CMT("Check MemOperand(cp, GLOBAL_OBJECT_INDEX) == GLOBAL_PTR())");
+ __ ldr(r0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ mov(r1, Operand((intptr_t)GLOBAL_PTR(), RelocInfo::EXTERNAL_REFERENCE));
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+
+ CMT("Check FieldMemOperand(GLOBAL_PTR(), GlobalContextOffset) "
+ "== GLOBAL_CONTEXT_PTR())");
+ __ ldr(r0, FieldMemOperand(r0,
+ GlobalObject::kGlobalContextOffset));
+ __ mov(r1, Operand((intptr_t)GLOBAL_CONTEXT_PTR(),
+ RelocInfo::EXTERNAL_REFERENCE));
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+
+ CMT("Check MemOperand(GLOBAL_CONTEXT_PTR(), CLOSURE_INDEX) "
+ "== GLOBAL_CLOSURE_PTR())");
+ __ ldr(r0, MemOperand(r0,
+ Context::SlotOffset(Context::CLOSURE_INDEX)));
+ __ mov(r1, Operand((intptr_t)GLOBAL_CLOSURE_PTR(),
+ RelocInfo::EXTERNAL_REFERENCE));
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+
+ CMT("Check CompareInstanceType(GLOBAL_PTR()) == JS_GLOBAL_OBJECT_TYPE");
+ __ mov(r0, Operand((intptr_t)GLOBAL_PTR(),
+ RelocInfo::EXTERNAL_REFERENCE));
+ __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
+ __ CompareInstanceType(r1, r2/*type*/ , JS_GLOBAL_OBJECT_TYPE, eq);
+ B_LINE(f, &error);
+ __ cmp(r2, Operand(JS_GLOBAL_OBJECT_TYPE));
+ B_LINE(f, &error);
+ CMT("Check CompareInstanceType(GLOBAL_PTR()) != JS_VALUE_TYPE");
+ __ CompareInstanceType(r1, r2/*type*/ , JS_VALUE_TYPE, eq);
+ B_LINE(t, &error);
+ CMT("Check CompareInstanceType(GLOBAL_PTR()) >= (ge) FIRST_SPEC_OBJECT_TYPE");
+ __ CompareInstanceType(r1, r2/*type*/ , FIRST_SPEC_OBJECT_TYPE, ge);
+ B_LINE(f, &error);
+ CMT("Check CompareInstanceType(GLOBAL_PTR()) > (hs) FIRST_SPEC_OBJECT_TYPE");
+ __ CompareInstanceType(r1, r2/*type*/ , FIRST_SPEC_OBJECT_TYPE, hs);
+ B_LINE(f, &error);
+
+ CMT("Check CompareObjectType(GLOBAL_PTR()) == JS_GLOBAL_OBJECT_TYPE");
+ __ CompareObjectType(r0, r3/*map*/, r4/*type*/ , JS_GLOBAL_OBJECT_TYPE, eq);
+ B_LINE(f, &error);
+ __ cmp(r1, r3); // check that map matches
+ B_LINE(f, &error);
+ __ cmp(r2, r4); // check that type matches
+
+ // All ok.
+ __ mov(r0, Operand(Smi::FromInt(0)));
+ __ rts();
+
+ __ bind(&error);
+ __ SmiTag(r0, r10);
+ __ rts();
+
+ JIT();
+
+ PRINT();
+
+ CALL();
+
+ // The function must return a result as Smi.
+ CHECK(result->IsSmi());
+ CHECK_EQ(0, Smi::cast(*result)->value());
+}
+
+
+// Test LoadGlobalFunction(), LoadContext(), LoadGlobalFunctionInitialMap()
+// TryGetFunctionPrototype()
+TEST(sh4_cs_3) {
+ BEGIN();
+
+ Label error;
+
+ CMT("Check LoadContext() == @(isolate+kContextAddress)");
+ __ LoadContext(r0, 0);
+ __ mov(r1, Operand(ExternalReference(Isolate::kContextAddress, isolate)));
+ __ ldr(r1, MemOperand(r1));
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+
+ CMT("Check LoadContext() == isolate->context()");
+ __ mov(r1, Operand((intptr_t)isolate->context(),
+ RelocInfo::EXTERNAL_REFERENCE));
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+
+ CMT("Check LoadContext() == isolate->global_context()");
+ __ mov(r1, Operand((intptr_t)GLOBAL_CONTEXT_PTR(),
+ RelocInfo::EXTERNAL_REFERENCE));
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+
+ CMT("Check LoadContext() == LoadContext()->global_object->global_context");
+ __ ldr(r1, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+ __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset));
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+
+ CMT("Check LoadContext(level 1) == NULL");
+ __ LoadContext(r0, 1);
+ __ mov(r1, Operand(0));
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+
+
+ CMT("Check LoadGlobalFunction() == Global Closure");
+ // Check
+ __ LoadGlobalFunction(Context::CLOSURE_INDEX, r0/* Resulting closure*/);
+ __ mov(r1, Operand((intptr_t)GLOBAL_CLOSURE_PTR(),
+ RelocInfo::EXTERNAL_REFERENCE));
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+
+ CMT("Check LoadGlobalFunctionInitialMap() == "
+ "Global Object Function->initial_map()");
+ __ LoadGlobalFunction(Context::OBJECT_FUNCTION_INDEX,
+ r0/* Resulting closure*/);
+ __ mov(r1, Operand((intptr_t)GLOBAL_OBJECT_FUNCTION_PTR(),
+ RelocInfo::EXTERNAL_REFERENCE));
+
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+ __ LoadGlobalFunctionInitialMap(r0, r1/*result map*/, r2/*scratch*/);
+ __ mov(r0, Operand((intptr_t)GLOBAL_OBJECT_FUNCTION_PTR()->
+ prototype_or_initial_map(),
+ RelocInfo::EXTERNAL_REFERENCE));
+ __ cmp(r1, r0);
+ B_LINE(ne, &error);
+
+ Label miss1, miss2, miss3, miss4, skip_proto4;
+ CMT("Check TryGetFunctionPrototype: Smi");
+ __ mov(r0, Operand(Smi::FromInt(1)));
+ __ TryGetFunctionPrototype(r0, r1 /*proto*/, r2 /*scratch*/, &miss1);
+ B_LINE(al, &error);
+ __ bind(&miss1);
+ CMT("Check TryGetFunctionPrototype: Not a function");
+ __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
+ __ TryGetFunctionPrototype(r0, r1 /*proto*/, r2 /*scratch*/, &miss2);
+ B_LINE(al, &error);
+ __ bind(&miss2);
+ CMT("Check TryGetFunctionPrototype(empty_function) == the_hole_value");
+ __ LoadGlobalFunction(Context::CLOSURE_INDEX, r0/* Resulting closure*/);
+ __ TryGetFunctionPrototype(r0, r1 /*proto*/, r2 /*scratch*/, &miss3);
+ B_LINE(al, &error);
+ __ bind(&miss3);
+ __ LoadRoot(r2, Heap::kTheHoleValueRootIndex);
+ __ cmp(r1, r2);
+ B_LINE(ne, &error);
+
+ CMT("Check TryGetFunctionPrototype(global_object_function) == "
+ "initial_map->prototype()");
+ __ LoadGlobalFunction(Context::OBJECT_FUNCTION_INDEX,
+ r0/* Resulting closure*/);
+ __ TryGetFunctionPrototype(r0, r1 /*proto*/, r2 /*scratch*/, &miss4);
+ __ jmp(&skip_proto4);
+ __ bind(&miss4);
+ B_LINE(al, &error);
+ __ bind(&skip_proto4);
+ __ LoadGlobalFunctionInitialMap(r0, r3/*result map*/, r2/*scratch*/);
+ __ ldr(r3, FieldMemOperand(r3, Map::kPrototypeOffset));
+ __ cmp(r1, r3);
+ B_LINE(ne, &error);
+
+ // All ok.
+ __ mov(r0, Operand(Smi::FromInt(0)));
+ __ rts();
+
+ __ bind(&error);
+ __ SmiTag(r0, r10);
+ __ rts();
+
+ JIT();
+
+ PRINT();
+
+ CALL();
+
+ // The function must return a result as Smi.
+ CHECK(result->IsSmi());
+ CHECK_EQ(0, Smi::cast(*result)->value());
+}
+
+
+// Test GetBuiltinFunction()/GetBuiltinEntry()
+TEST(sh4_cs_4) {
+ BEGIN();
+
+ Label error;
+
+ // First check that the builtin function is actually undefined
+ // as we do not activate natives.
+ // Then install the empty function for the purpose of the tests.
+ CHECK(isolate->global_object()->builtins()->
+ javascript_builtin(Builtins::MUL)->IsUndefined());
+ isolate->global_object()->builtins()->
+ set_javascript_builtin(Builtins::MUL,
+ isolate->global_context()->closure());
+ isolate->global_object()->builtins()->
+ set_javascript_builtin_code(Builtins::MUL,
+ isolate->global_context()->closure()->code());
+ CMT("Check GetBuiltinFunction(Builtins::MUL)");
+ __ GetBuiltinFunction(r0, Builtins::MUL);
+ __ mov(r1, Operand((intptr_t)isolate->global_object()->builtins()->
+ javascript_builtin(Builtins::MUL),
+ RelocInfo::EXTERNAL_REFERENCE));
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+
+ CMT("Check GetBuiltinEntry(Builtins::MUL)");
+ __ GetBuiltinEntry(r0, Builtins::MUL);
+ __ mov(r1, Operand((intptr_t)isolate->global_object()->builtins()->
+ javascript_builtin_code(Builtins::MUL)->entry(),
+ RelocInfo::EXTERNAL_REFERENCE));
+ __ cmp(r0, r1);
+ B_LINE(ne, &error);
+
+ // All ok.
+ __ mov(r0, Operand(Smi::FromInt(0)));
+ __ rts();
+
+ __ bind(&error);
+ __ SmiTag(r0, r10);
+ __ rts();
+
+ JIT();
+
+ PRINT();
+
+ CALL();
+
+ // The function must return a result as Smi.
+ CHECK(result->IsSmi());
+ CHECK_EQ(0, Smi::cast(*result)->value());
+}
+
+
+static double
+ObjectToNumber(Object *object) {
+ double cast_value;
+ if (object->IsSmi()) {
+ int int_value = Smi::cast(object)->value();
+ cast_value = static_cast<double>(int_value);
+ } else if (object->IsHeapNumber()) {
+ cast_value = HeapNumber::cast(object)->value();
+ } else {
+ // Return 0 when not a number
+ cast_value = 0;
+ }
+ return cast_value;
+}
+
+// Test TailCallRuntime()
+TEST(sh4_cs_5) {
+ {
+ BEGIN();
+ CMT("Check TailCallRuntime: NumberToJSint32(13)");
+ __ mov(r0, Operand(Smi::FromInt(13)));
+ __ push(r0);
+ __ TailCallRuntime(Runtime::kNumberToJSInt32, 1, 1);
+
+ JIT();
+ PRINT();
+ CALL();
+ CHECK(result->IsNumber());
+ CHECK_EQ(13.0, ObjectToNumber(*result));
+ }
+ {
+ BEGIN();
+ CMT("Check CallRuntime: NumberAdd(7, 27)");
+ {
+ FrameScope scpe(&assm, StackFrame::INTERNAL);
+ __ mov(r0, Operand(Smi::FromInt(7)));
+ __ mov(r1, Operand(Smi::FromInt(27)));
+ __ Push(r0, r1);
+ __ CallRuntime(Runtime::kNumberAdd, 2);
+ }
+ __ Ret();
+ JIT();
+ PRINT();
+ CALL();
+ CHECK(result->IsNumber());
+ CHECK_EQ(34.0, ObjectToNumber(*result));
+ }
+ {
+ BEGIN();
+ CMT("Check CallRuntime: NumberToString(1234)");
+ {
+ FrameScope scpe(&assm, StackFrame::INTERNAL);
+ __ mov(r0, Operand(Smi::FromInt(1234)));
+ __ push(r0);
+ __ CallRuntime(Runtime::kNumberToString, 1);
+ CMT("Check CallRuntime: GlobalPrint(\"1234\")");
+ __ push(r0);
+ __ CallRuntime(Runtime::kGlobalPrint, 1);
+ }
+ __ Ret();
+ JIT();
+ PRINT();
+ CALL();
+ CHECK(result->IsString());
+ CHECK(String::cast(*result)->IsEqualTo(CStrVector("1234")));
+ }
+}
+
+#undef __
+#define __ assm->
+static void
+GenerateNumberFromReg(MacroAssembler *assm, Register heap, Register reg) {
+ ASSERT(!reg.is(r4) && !reg.is(r5) && !reg.is(r6) && !reg.is(r7));
+ Label gc_required, skip, not_smi;
+
+ {
+ FrameScope scpe(assm, StackFrame::INTERNAL);
+ __ Push(r4, r5, r6, r7);
+ __ TrySmiTag(reg, &not_smi, r5/*scratch*/);
+ __ mov(heap, reg);
+ __ jmp(&skip);
+ __ bind(&not_smi);
+ __ LoadRoot(r7, Heap::kHeapNumberMapRootIndex);
+ __ AllocateHeapNumber(r4/*result heap number*/, r5/*scratch*/,
+ r6/*scratch*/, r7/*heap_number_map*/, &gc_required);
+ WriteInt32ToHeapNumberStub stub(reg, r4, r5/*scratch*/);
+ __ CallStub(&stub);
+ __ mov(heap, r4);
+ __ Pop(r6, r7);
+ __ Pop(r4, r5);
+ }
+ __ jmp(&skip);
+ __ bind(&gc_required);
+ __ Abort("GC required while dumping number");
+ __ bind(&skip);
+}
+#undef __
+#define __ assm.
+
+// Test WriteInt32ToHeapNumberStub()
+TEST(sh4_cs_6) {
+ {
+ BEGIN();
+
+ __ mov(r0, Operand(0));
+ GenerateNumberFromReg(&assm, r0, r0);
+ __ Ret();
+
+ JIT();
+ PRINT();
+ CALL();
+ CHECK(result->IsNumber());
+ CHECK_EQ(0, static_cast<int>(ObjectToNumber(*result)));
+ }
+ {
+ BEGIN();
+
+ __ mov(r0, Operand(1234));
+ GenerateNumberFromReg(&assm, r0, r0);
+ __ Ret();
+
+ JIT();
+ PRINT();
+ CALL();
+ CHECK(result->IsNumber());
+ CHECK_EQ(1234, static_cast<int>(ObjectToNumber(*result)));
+ }
+ {
+ BEGIN();
+
+ __ mov(r0, Operand(0x7fffffff));
+ GenerateNumberFromReg(&assm, r0, r0);
+ __ Ret();
+
+ JIT();
+ PRINT();
+ CALL();
+ CHECK(result->IsNumber());
+ CHECK_EQ(0x7fffffff, static_cast<int>(ObjectToNumber(*result)));
+ }
+ {
+ BEGIN();
+
+ __ mov(r0, Operand(0x80000000u));
+ GenerateNumberFromReg(&assm, r0, r0);
+ __ Ret();
+
+ JIT();
+ PRINT();
+ CALL();
+ CHECK(result->IsNumber());
+ CHECK_EQ(0x80000000u, static_cast<int>(ObjectToNumber(*result)));
+ }
+}
+
+#undef __
+#define __ assm->
+static void
+GeneratePrintReg(MacroAssembler *assm, Register reg) {
+ ASSERT(!reg.is(r4) && !reg.is(r5) && !reg.is(r6) && !reg.is(r7));
+ Label gc_required, skip, not_smi;
+ {
+ FrameScope scpe(assm, StackFrame::INTERNAL);
+ // Save reg as it is scratched by WriteInt32ToHeapNumberStub()
+ __ push(reg);
+ __ pushm(kJSCallerSaved);
+ __ TrySmiTag(reg, &not_smi, r5/*scratch*/);
+ __ mov(r4, reg);
+ __ jmp(&skip);
+ __ bind(&not_smi);
+ __ LoadRoot(r7, Heap::kHeapNumberMapRootIndex);
+ __ AllocateHeapNumber(r4/*result heap number*/, r5/*scratch*/,
+ r6/*scratch*/, r7/*heap_number_map*/, &gc_required);
+ WriteInt32ToHeapNumberStub stub(reg, r4, r5/*scratch*/);
+ __ CallStub(&stub);
+ __ jmp(&skip);
+ __ bind(&gc_required);
+ __ Abort("GC required while dumping number");
+ __ bind(&skip);
+ __ push(r4);
+ __ CallRuntime(Runtime::kNumberToString, 1);
+ __ push(r0);
+ __ CallRuntime(Runtime::kGlobalPrint, 1);
+ __ popm(kJSCallerSaved);
+ __ pop(reg);
+ }
+}
+#undef __
+#define __ assm.
+
+// Test GeneratePrintReg()
+TEST(sh4_cs_7) {
+ BEGIN();
+
+ __ mov(r0, Operand(1234));
+ GeneratePrintReg(&assm, r0);
+ __ mov(r0, Operand(0x7fffffff));
+ GeneratePrintReg(&assm, r0);
+ __ mov(r0, Operand(0x80000000));
+ GeneratePrintReg(&assm, r0);
+ __ PrintRegisterValue(r0);
+ __ mov(r0, Operand(0));
+ __ Ret();
+
+ JIT();
+ PRINT();
+ CALL();
+ CHECK(result->IsNumber());
+ CHECK_EQ(0.0, ObjectToNumber(*result));
+}
+
+
+// Test CompareStub()
+TEST(sh4_cs_8) {
+ BEGIN();
+
+ Label error;
+
+ // Enter Fram before call stubs
+ {
+ FrameScope scpe(&assm, StackFrame::INTERNAL);
+
+ CompareStub stub(eq/*cond*/, true/*strict*/, NO_COMPARE_FLAGS, r0, r1);
+#if 1 && defined(DEBUG)
+ stub.GetCode()->Print();
+#endif
+
+ CMT("Check CompareStub(0, 0) == 0");
+ __ mov(r0, Operand(Smi::FromInt(0)));
+ __ mov(r1, Operand(Smi::FromInt(0)));
+ __ CallStub(&stub);
+ __ cmp(r0, Operand(0));
+ B_LINE(ne, &error);
+
+ CMT("Check CompareStub(1, 1) == 0");
+ __ mov(r0, Operand(Smi::FromInt(1)));
+ __ mov(r1, Operand(Smi::FromInt(1)));
+ __ CallStub(&stub);
+ __ cmp(r0, Operand(0));
+ B_LINE(ne, &error);
+
+ CMT("Check CompareStub(0, 1) > 0");
+ __ mov(r0, Operand(Smi::FromInt(0)));
+ __ mov(r1, Operand(Smi::FromInt(1)));
+ __ CallStub(&stub);
+ __ cmpgt(r0, Operand(0));
+ B_LINE(ne, &error);
+
+ CMT("Check CompareStub(-1, 2) > 0");
+ __ mov(r0, Operand(Smi::FromInt(-1)));
+ __ mov(r1, Operand(Smi::FromInt(2)));
+ __ CallStub(&stub);
+ __ cmp(r0, Operand(0));
+ B_LINE(eq, &error);
+
+ // CMT("Check CompareStub(0, heap(0)) == 0");
+ // __ mov(r0, Operand(Smi::FromInt(0)));
+ // __ mov(r1, Operand(0));
+ // GenerateNumberFromReg(&assm, r1, r1);
+ // __ CallStub(&stub);
+ // __ cmp(r0, Operand(0));
+ // B_LINE(ne, &error);
+
+ // All ok.
+ __ mov(r0, Operand(Smi::FromInt(0)));
+ __ rts();
+
+ __ bind(&error);
+ __ SmiTag(r0, r10);
+ __ rts();
+ }
+
+ JIT();
+ PRINT();
+ CALL();
+ CHECK(result->IsNumber());
+ CHECK_EQ(0, static_cast<int>(ObjectToNumber(*result)));
+}
« no previous file with comments | « test/cctest/test-assembler-sh4.cc ('k') | test/cctest/test-macro-assembler-sh4.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698