Index: test/cctest/test-simulator-arm64.cc |
diff --git a/test/cctest/test-simulator-arm.cc b/test/cctest/test-simulator-arm64.cc |
similarity index 75% |
copy from test/cctest/test-simulator-arm.cc |
copy to test/cctest/test-simulator-arm64.cc |
index a34837665e3c041faa5066e9cf58780c15e56569..795541e749afb6e4a5438e1ef127817e6d7fd2df 100644 |
--- a/test/cctest/test-simulator-arm.cc |
+++ b/test/cctest/test-simulator-arm64.cc |
@@ -1,4 +1,4 @@ |
-// Copyright 2016 the V8 project authors. All rights reserved. |
+// Copyright 2017 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: |
@@ -28,8 +28,7 @@ |
#include "src/v8.h" |
#include "test/cctest/cctest.h" |
-#include "src/arm/simulator-arm.h" |
-#include "src/disassembler.h" |
+#include "src/arm64/simulator-arm64.h" |
#include "src/factory.h" |
#include "src/macro-assembler.h" |
@@ -42,11 +41,7 @@ |
using namespace v8::base; |
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* (*F3)(void* p0, int p1, int p2, int p3, int p4); |
- |
-#define __ assm. |
+#define __ masm. |
struct MemoryAccess { |
enum class Kind { |
@@ -67,10 +62,10 @@ struct MemoryAccess { |
MemoryAccess(Kind kind, Size size, size_t offset, int value = 0) |
: kind(kind), size(size), offset(offset), value(value) {} |
- Kind kind; |
- Size size; |
- size_t offset; |
- int value; |
+ Kind kind = Kind::None; |
+ Size size = Size::Byte; |
+ size_t offset = 0; |
+ int value = 0; |
}; |
struct TestData { |
@@ -84,11 +79,11 @@ struct TestData { |
int dummy; |
}; |
-static void AssembleMemoryAccess(Assembler* assembler, MemoryAccess access, |
+static void AssembleMemoryAccess(MacroAssembler* assembler, MemoryAccess access, |
Register dest_reg, Register value_reg, |
Register addr_reg) { |
- Assembler& assm = *assembler; |
- __ add(addr_reg, r0, Operand(access.offset)); |
+ MacroAssembler& masm = *assembler; |
+ __ Add(addr_reg, x0, Operand(access.offset)); |
switch (access.kind) { |
case MemoryAccess::Kind::None: |
@@ -113,15 +108,15 @@ static void AssembleMemoryAccess(Assembler* assembler, MemoryAccess access, |
case MemoryAccess::Kind::LoadExcl: |
switch (access.size) { |
case MemoryAccess::Size::Byte: |
- __ ldrexb(value_reg, addr_reg); |
+ __ ldaxrb(value_reg, addr_reg); |
break; |
case MemoryAccess::Size::HalfWord: |
- __ ldrexh(value_reg, addr_reg); |
+ __ ldaxrh(value_reg, addr_reg); |
break; |
case MemoryAccess::Size::Word: |
- __ ldrex(value_reg, addr_reg); |
+ __ ldaxr(value_reg, addr_reg); |
break; |
} |
break; |
@@ -129,17 +124,17 @@ static void AssembleMemoryAccess(Assembler* assembler, MemoryAccess access, |
case MemoryAccess::Kind::Store: |
switch (access.size) { |
case MemoryAccess::Size::Byte: |
- __ mov(value_reg, Operand(access.value)); |
+ __ Mov(value_reg, Operand(access.value)); |
__ strb(value_reg, MemOperand(addr_reg)); |
break; |
case MemoryAccess::Size::HalfWord: |
- __ mov(value_reg, Operand(access.value)); |
+ __ Mov(value_reg, Operand(access.value)); |
__ strh(value_reg, MemOperand(addr_reg)); |
break; |
case MemoryAccess::Size::Word: |
- __ mov(value_reg, Operand(access.value)); |
+ __ Mov(value_reg, Operand(access.value)); |
__ str(value_reg, MemOperand(addr_reg)); |
break; |
} |
@@ -148,31 +143,31 @@ static void AssembleMemoryAccess(Assembler* assembler, MemoryAccess access, |
case MemoryAccess::Kind::StoreExcl: |
switch (access.size) { |
case MemoryAccess::Size::Byte: |
- __ mov(value_reg, Operand(access.value)); |
- __ strexb(dest_reg, value_reg, addr_reg); |
+ __ Mov(value_reg, Operand(access.value)); |
+ __ stlxrb(dest_reg, value_reg, addr_reg); |
break; |
case MemoryAccess::Size::HalfWord: |
- __ mov(value_reg, Operand(access.value)); |
- __ strexh(dest_reg, value_reg, addr_reg); |
+ __ Mov(value_reg, Operand(access.value)); |
+ __ stlxrh(dest_reg, value_reg, addr_reg); |
break; |
case MemoryAccess::Size::Word: |
- __ mov(value_reg, Operand(access.value)); |
- __ strex(dest_reg, value_reg, addr_reg); |
+ __ Mov(value_reg, Operand(access.value)); |
+ __ stlxr(dest_reg, value_reg, addr_reg); |
break; |
} |
break; |
} |
} |
-static void AssembleLoadExcl(Assembler* assembler, MemoryAccess access, |
+static void AssembleLoadExcl(MacroAssembler* assembler, MemoryAccess access, |
Register value_reg, Register addr_reg) { |
DCHECK(access.kind == MemoryAccess::Kind::LoadExcl); |
AssembleMemoryAccess(assembler, access, no_reg, value_reg, addr_reg); |
} |
-static void AssembleStoreExcl(Assembler* assembler, MemoryAccess access, |
+static void AssembleStoreExcl(MacroAssembler* assembler, MemoryAccess access, |
Register dest_reg, Register value_reg, |
Register addr_reg) { |
DCHECK(access.kind == MemoryAccess::Kind::StoreExcl); |
@@ -184,24 +179,24 @@ static void TestInvalidateExclusiveAccess( |
MemoryAccess access3, int expected_res, TestData expected_data) { |
Isolate* isolate = CcTest::i_isolate(); |
HandleScope scope(isolate); |
+ MacroAssembler masm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
- Assembler assm(isolate, NULL, 0); |
- |
- AssembleLoadExcl(&assm, access1, r1, r1); |
- AssembleMemoryAccess(&assm, access2, r3, r2, r1); |
- AssembleStoreExcl(&assm, access3, r0, r3, r1); |
- |
- __ mov(pc, Operand(lr)); |
+ AssembleLoadExcl(&masm, access1, w1, x1); |
+ AssembleMemoryAccess(&masm, access2, w3, w2, x1); |
+ AssembleStoreExcl(&masm, access3, w0, w3, x1); |
+ __ br(lr); |
CodeDesc desc; |
- assm.GetCode(&desc); |
+ masm.GetCode(&desc); |
Handle<Code> code = isolate->factory()->NewCode( |
desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
- F3 f = FUNCTION_CAST<F3>(code->entry()); |
TestData t = initial_data; |
+ Simulator::CallArgument args[] = { |
+ Simulator::CallArgument(reinterpret_cast<uintptr_t>(&t)), |
+ Simulator::CallArgument::End()}; |
+ Simulator::current(isolate)->CallVoid(code->entry(), args); |
+ int res = Simulator::current(isolate)->wreg(0); |
- int res = |
- reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0)); |
CHECK_EQ(expected_res, res); |
switch (access3.size) { |
case MemoryAccess::Size::Byte: |
@@ -222,53 +217,54 @@ TEST(simulator_invalidate_exclusive_access) { |
using Kind = MemoryAccess::Kind; |
using Size = MemoryAccess::Size; |
- MemoryAccess ldrex_w(Kind::LoadExcl, Size::Word, offsetof(TestData, w)); |
- MemoryAccess strex_w(Kind::StoreExcl, Size::Word, offsetof(TestData, w), 7); |
+ MemoryAccess ldaxr_w(Kind::LoadExcl, Size::Word, offsetof(TestData, w)); |
+ MemoryAccess stlxr_w(Kind::StoreExcl, Size::Word, offsetof(TestData, w), 7); |
// Address mismatch. |
TestInvalidateExclusiveAccess( |
- TestData(1), ldrex_w, |
+ TestData(1), ldaxr_w, |
MemoryAccess(Kind::LoadExcl, Size::Word, offsetof(TestData, dummy)), |
- strex_w, 1, TestData(1)); |
+ stlxr_w, 1, TestData(1)); |
// Size mismatch. |
TestInvalidateExclusiveAccess( |
- TestData(1), ldrex_w, MemoryAccess(), |
+ TestData(1), ldaxr_w, MemoryAccess(), |
MemoryAccess(Kind::StoreExcl, Size::HalfWord, offsetof(TestData, w), 7), |
1, TestData(1)); |
- // Load between ldrex/strex. |
+ // Load between ldaxr/stlxr. |
TestInvalidateExclusiveAccess( |
- TestData(1), ldrex_w, |
- MemoryAccess(Kind::Load, Size::Word, offsetof(TestData, dummy)), strex_w, |
+ TestData(1), ldaxr_w, |
+ MemoryAccess(Kind::Load, Size::Word, offsetof(TestData, dummy)), stlxr_w, |
1, TestData(1)); |
- // Store between ldrex/strex. |
+ // Store between ldaxr/stlxr. |
TestInvalidateExclusiveAccess( |
- TestData(1), ldrex_w, |
- MemoryAccess(Kind::Store, Size::Word, offsetof(TestData, dummy)), strex_w, |
+ TestData(1), ldaxr_w, |
+ MemoryAccess(Kind::Store, Size::Word, offsetof(TestData, dummy)), stlxr_w, |
1, TestData(1)); |
// Match |
- TestInvalidateExclusiveAccess(TestData(1), ldrex_w, MemoryAccess(), strex_w, |
+ TestInvalidateExclusiveAccess(TestData(1), ldaxr_w, MemoryAccess(), stlxr_w, |
0, TestData(7)); |
} |
static int ExecuteMemoryAccess(Isolate* isolate, TestData* test_data, |
MemoryAccess access) { |
HandleScope scope(isolate); |
- Assembler assm(isolate, NULL, 0); |
- AssembleMemoryAccess(&assm, access, r0, r2, r1); |
- __ bx(lr); |
+ MacroAssembler masm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
+ AssembleMemoryAccess(&masm, access, w0, w2, x1); |
+ __ br(lr); |
CodeDesc desc; |
- assm.GetCode(&desc); |
+ masm.GetCode(&desc); |
Handle<Code> code = isolate->factory()->NewCode( |
desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
- F3 f = FUNCTION_CAST<F3>(code->entry()); |
- |
- return reinterpret_cast<int>( |
- CALL_GENERATED_CODE(isolate, f, test_data, 0, 0, 0, 0)); |
+ Simulator::CallArgument args[] = { |
+ Simulator::CallArgument(reinterpret_cast<uintptr_t>(test_data)), |
+ Simulator::CallArgument::End()}; |
+ Simulator::current(isolate)->CallVoid(code->entry(), args); |
+ return Simulator::current(isolate)->wreg(0); |
} |
class MemoryAccessThread : public v8::base::Thread { |
@@ -346,36 +342,36 @@ TEST(simulator_invalidate_exclusive_access_threaded) { |
MemoryAccessThread thread; |
thread.Start(); |
- MemoryAccess ldrex_w(Kind::LoadExcl, Size::Word, offsetof(TestData, w)); |
- MemoryAccess strex_w(Kind::StoreExcl, Size::Word, offsetof(TestData, w), 7); |
+ MemoryAccess ldaxr_w(Kind::LoadExcl, Size::Word, offsetof(TestData, w)); |
+ MemoryAccess stlxr_w(Kind::StoreExcl, Size::Word, offsetof(TestData, w), 7); |
// Exclusive store completed by another thread first. |
test_data = TestData(1); |
thread.NextAndWait(&test_data, MemoryAccess(Kind::LoadExcl, Size::Word, |
offsetof(TestData, w))); |
- ExecuteMemoryAccess(isolate, &test_data, ldrex_w); |
+ ExecuteMemoryAccess(isolate, &test_data, ldaxr_w); |
thread.NextAndWait(&test_data, MemoryAccess(Kind::StoreExcl, Size::Word, |
offsetof(TestData, w), 5)); |
- CHECK_EQ(1, ExecuteMemoryAccess(isolate, &test_data, strex_w)); |
+ CHECK_EQ(1, ExecuteMemoryAccess(isolate, &test_data, stlxr_w)); |
CHECK_EQ(5, test_data.w); |
// Exclusive store completed by another thread; different address, but masked |
// to same |
test_data = TestData(1); |
- ExecuteMemoryAccess(isolate, &test_data, ldrex_w); |
+ ExecuteMemoryAccess(isolate, &test_data, ldaxr_w); |
thread.NextAndWait(&test_data, MemoryAccess(Kind::LoadExcl, Size::Word, |
offsetof(TestData, dummy))); |
thread.NextAndWait(&test_data, MemoryAccess(Kind::StoreExcl, Size::Word, |
offsetof(TestData, dummy), 5)); |
- CHECK_EQ(1, ExecuteMemoryAccess(isolate, &test_data, strex_w)); |
+ CHECK_EQ(1, ExecuteMemoryAccess(isolate, &test_data, stlxr_w)); |
CHECK_EQ(1, test_data.w); |
- // Test failure when store between ldrex/strex. |
+ // Test failure when store between ldaxr/stlxr. |
test_data = TestData(1); |
- ExecuteMemoryAccess(isolate, &test_data, ldrex_w); |
+ ExecuteMemoryAccess(isolate, &test_data, ldaxr_w); |
thread.NextAndWait(&test_data, MemoryAccess(Kind::Store, Size::Word, |
offsetof(TestData, dummy))); |
- CHECK_EQ(1, ExecuteMemoryAccess(isolate, &test_data, strex_w)); |
+ CHECK_EQ(1, ExecuteMemoryAccess(isolate, &test_data, stlxr_w)); |
CHECK_EQ(1, test_data.w); |
thread.Finish(); |