Move V8 to external/v8
Change-Id: If68025d67453785a651c5dfb34fad298c16676a4
diff --git a/test/cctest/test-assembler-arm.cc b/test/cctest/test-assembler-arm.cc
new file mode 100644
index 0000000..f6e4d04
--- /dev/null
+++ b/test/cctest/test-assembler-arm.cc
@@ -0,0 +1,227 @@
+// 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 "v8.h"
+
+#include "disassembler.h"
+#include "factory.h"
+#include "arm/simulator-arm.h"
+#include "arm/assembler-arm-inl.h"
+#include "cctest.h"
+
+using namespace v8::internal;
+
+
+// Define these function prototypes to match JSEntryFunction in execution.cc.
+typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
+typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
+typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
+
+
+static v8::Persistent<v8::Context> env;
+
+
+// The test framework does not accept flags on the command line, so we set them
+static void InitializeVM() {
+ // disable compilation of natives by specifying an empty natives file
+ FLAG_natives_file = "";
+
+ // enable generation of comments
+ FLAG_debug_code = true;
+
+ if (env.IsEmpty()) {
+ env = v8::Context::New();
+ }
+}
+
+
+#define __ assm.
+
+TEST(0) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ Assembler assm(NULL, 0);
+
+ __ add(r0, r0, Operand(r1));
+ __ mov(pc, Operand(lr));
+
+ 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 = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 3, 4, 0, 0, 0));
+ ::printf("f() = %d\n", res);
+ CHECK_EQ(7, res);
+}
+
+
+TEST(1) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ Assembler assm(NULL, 0);
+ Label L, C;
+
+ __ mov(r1, Operand(r0));
+ __ mov(r0, Operand(0));
+ __ b(&C);
+
+ __ bind(&L);
+ __ add(r0, r0, Operand(r1));
+ __ sub(r1, r1, Operand(1));
+
+ __ bind(&C);
+ __ teq(r1, Operand(0));
+ __ b(ne, &L);
+ __ mov(pc, Operand(lr));
+
+ 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 = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 100, 0, 0, 0, 0));
+ ::printf("f() = %d\n", res);
+ CHECK_EQ(5050, res);
+}
+
+
+TEST(2) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ Assembler assm(NULL, 0);
+ Label L, C;
+
+ __ mov(r1, Operand(r0));
+ __ mov(r0, Operand(1));
+ __ b(&C);
+
+ __ bind(&L);
+ __ mul(r0, r1, r0);
+ __ sub(r1, r1, Operand(1));
+
+ __ bind(&C);
+ __ teq(r1, Operand(0));
+ __ b(ne, &L);
+ __ mov(pc, Operand(lr));
+
+ // some relocated stuff here, not executed
+ __ RecordComment("dead code, just testing relocations");
+ __ mov(r0, Operand(Factory::true_value()));
+ __ RecordComment("dead code, just testing immediate operands");
+ __ mov(r0, Operand(-1));
+ __ mov(r0, Operand(0xFF000000));
+ __ mov(r0, Operand(0xF0F0F0F0));
+ __ mov(r0, Operand(0xFFF0FFFF));
+
+ 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 = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0));
+ ::printf("f() = %d\n", res);
+ CHECK_EQ(3628800, res);
+}
+
+
+TEST(3) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ typedef struct {
+ int i;
+ char c;
+ int16_t s;
+ } T;
+ T t;
+
+ Assembler assm(NULL, 0);
+ Label L, C;
+
+ __ mov(ip, Operand(sp));
+ __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
+ __ sub(fp, ip, Operand(4));
+ __ mov(r4, Operand(r0));
+ __ ldr(r0, MemOperand(r4, OFFSET_OF(T, i)));
+ __ mov(r2, Operand(r0, ASR, 1));
+ __ str(r2, MemOperand(r4, OFFSET_OF(T, i)));
+ __ ldrsb(r2, MemOperand(r4, OFFSET_OF(T, c)));
+ __ add(r0, r2, Operand(r0));
+ __ mov(r2, Operand(r2, LSL, 2));
+ __ strb(r2, MemOperand(r4, OFFSET_OF(T, c)));
+ __ ldrsh(r2, MemOperand(r4, OFFSET_OF(T, s)));
+ __ add(r0, r2, Operand(r0));
+ __ mov(r2, Operand(r2, ASR, 3));
+ __ strh(r2, MemOperand(r4, OFFSET_OF(T, s)));
+ __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
+
+ 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
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ t.i = 100000;
+ t.c = 10;
+ t.s = 1000;
+ int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0));
+ ::printf("f() = %d\n", res);
+ CHECK_EQ(101010, res);
+ CHECK_EQ(100000/2, t.i);
+ CHECK_EQ(10*4, t.c);
+ CHECK_EQ(1000/8, t.s);
+}
+
+
+#undef __