summaryrefslogtreecommitdiff
path: root/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc')
-rw-r--r--deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc119
1 files changed, 116 insertions, 3 deletions
diff --git a/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc b/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc
index 57e82ecde3..b78cc71037 100644
--- a/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc
+++ b/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "src/arm64/macro-assembler-arm64-inl.h"
-#include "src/macro-assembler.h"
-#include "src/simulator.h"
+#include "src/codegen/arm64/macro-assembler-arm64-inl.h"
+#include "src/codegen/macro-assembler.h"
+#include "src/execution/simulator.h"
+#include "src/utils/ostreams.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
@@ -69,6 +70,118 @@ TEST_F(TurboAssemblerTest, TestCheck) {
ASSERT_DEATH_IF_SUPPORTED({ f.Call(17); }, ERROR_MESSAGE("abort: no reason"));
}
+struct MoveObjectAndSlotTestCase {
+ const char* comment;
+ Register dst_object;
+ Register dst_slot;
+ Register object;
+ Register offset_register = no_reg;
+};
+
+const MoveObjectAndSlotTestCase kMoveObjectAndSlotTestCases[] = {
+ {"no overlap", x0, x1, x2},
+ {"no overlap", x0, x1, x2, x3},
+
+ {"object == dst_object", x2, x1, x2},
+ {"object == dst_object", x2, x1, x2, x3},
+
+ {"object == dst_slot", x1, x2, x2},
+ {"object == dst_slot", x1, x2, x2, x3},
+
+ {"offset == dst_object", x0, x1, x2, x0},
+
+ {"offset == dst_object && object == dst_slot", x0, x1, x1, x0},
+
+ {"offset == dst_slot", x0, x1, x2, x1},
+
+ {"offset == dst_slot && object == dst_object", x0, x1, x0, x1}};
+
+// Make sure we include offsets that cannot be encoded in an add instruction.
+const int kOffsets[] = {0, 42, kMaxRegularHeapObjectSize, 0x101001};
+
+template <typename T>
+class TurboAssemblerTestWithParam : public TurboAssemblerTest,
+ public ::testing::WithParamInterface<T> {};
+
+using TurboAssemblerTestMoveObjectAndSlot =
+ TurboAssemblerTestWithParam<MoveObjectAndSlotTestCase>;
+
+TEST_P(TurboAssemblerTestMoveObjectAndSlot, MoveObjectAndSlot) {
+ const MoveObjectAndSlotTestCase test_case = GetParam();
+ TRACED_FOREACH(int32_t, offset, kOffsets) {
+ auto buffer = AllocateAssemblerBuffer();
+ TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ buffer->CreateView());
+
+ __ Push(x0, padreg);
+ __ Mov(test_case.object, x1);
+
+ Register src_object = test_case.object;
+ Register dst_object = test_case.dst_object;
+ Register dst_slot = test_case.dst_slot;
+
+ Operand offset_operand(0);
+ if (test_case.offset_register.Is(no_reg)) {
+ offset_operand = Operand(offset);
+ } else {
+ __ Mov(test_case.offset_register, Operand(offset));
+ offset_operand = Operand(test_case.offset_register);
+ }
+
+ std::stringstream comment;
+ comment << "-- " << test_case.comment << ": MoveObjectAndSlot("
+ << dst_object << ", " << dst_slot << ", " << src_object << ", ";
+ if (test_case.offset_register.Is(no_reg)) {
+ comment << "#" << offset;
+ } else {
+ comment << test_case.offset_register;
+ }
+ comment << ") --";
+ __ RecordComment(comment.str().c_str());
+ __ MoveObjectAndSlot(dst_object, dst_slot, src_object, offset_operand);
+ __ RecordComment("--");
+
+ // The `result` pointer was saved on the stack.
+ UseScratchRegisterScope temps(&tasm);
+ Register scratch = temps.AcquireX();
+ __ Pop(padreg, scratch);
+ __ Str(dst_object, MemOperand(scratch));
+ __ Str(dst_slot, MemOperand(scratch, kSystemPointerSize));
+
+ __ Ret();
+
+ CodeDesc desc;
+ tasm.GetCode(nullptr, &desc);
+ if (FLAG_print_code) {
+ Handle<Code> code =
+ Factory::CodeBuilder(isolate(), desc, Code::STUB).Build();
+ StdoutStream os;
+ code->Print(os);
+ }
+
+ buffer->MakeExecutable();
+ // We need an isolate here to execute in the simulator.
+ auto f = GeneratedCode<void, byte**, byte*>::FromBuffer(isolate(),
+ buffer->start());
+
+ byte* object = new byte[offset];
+ byte* result[] = {nullptr, nullptr};
+
+ f.Call(result, object);
+
+ // The first element must be the address of the object, and the second the
+ // slot addressed by `offset`.
+ EXPECT_EQ(result[0], &object[0]);
+ EXPECT_EQ(result[1], &object[offset]);
+
+ delete[] object;
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(TurboAssemblerTest,
+ TurboAssemblerTestMoveObjectAndSlot,
+ ::testing::ValuesIn(kMoveObjectAndSlotTestCases));
+
#undef __
#undef ERROR_MESSAGE