Chromium Code Reviews| Index: runtime/vm/assembler_dbc_test.cc |
| diff --git a/runtime/vm/assembler_dbc_test.cc b/runtime/vm/assembler_dbc_test.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..afbc4579cc36d8cb503b6067bc70a1d178394223 |
| --- /dev/null |
| +++ b/runtime/vm/assembler_dbc_test.cc |
| @@ -0,0 +1,432 @@ |
| +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +#include "vm/globals.h" |
| +#if defined(TARGET_ARCH_DBC) |
| + |
| +#include "vm/assembler.h" |
| +#include "vm/unit_test.h" |
| + |
| +namespace dart { |
| + |
| +#define __ assembler-> |
| + |
| +ASSEMBLER_TEST_GENERATE(Simple, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(Simple, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +// - AddTOS; SubTOS; MulTOS; BitOrTOS; BitAndTOS; EqualTOS; LessThanTOS; |
| +// GreaterThanTOS; |
| +// |
| +// Smi fast-path for a corresponding method. Checks if SP[0] and SP[-1] are |
| +// both smis and result of SP[0] <op> SP[-1] is a smi - if this is true |
| +// then pops operands and pushes result on the stack and skips the next |
| +// instruction (which implements a slow path fallback). |
| +ASSEMBLER_TEST_GENERATE(AddTOS, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(-42))); |
| + __ PushConstant(Smi::Handle(Smi::New(84))); |
| + __ AddTOS(); |
| + // TODO(zra): Test fail over to the runtime call. |
|
Ivan Posva
2016/04/29 05:57:53
You have this TODO here, but not in the other plac
zra
2016/04/29 16:08:57
On further thought, I think this is not the right
|
| + __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped. |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(AddTOS, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(SubTOS, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(30))); |
| + __ PushConstant(Smi::Handle(Smi::New(-12))); |
| + __ SubTOS(); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped. |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(SubTOS, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(MulTOS, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(-6))); |
| + __ PushConstant(Smi::Handle(Smi::New(-7))); |
| + __ MulTOS(); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped. |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(MulTOS, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(BitOrTOS, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(0x22))); |
| + __ PushConstant(Smi::Handle(Smi::New(0x08))); |
| + __ BitOrTOS(); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped. |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(BitOrTOS, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(BitAndTOS, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(0x2a))); |
| + __ PushConstant(Smi::Handle(Smi::New(0xaa))); |
| + __ BitAndTOS(); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped. |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(BitAndTOS, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(EqualTOSTrue, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ EqualTOS(); |
| + __ PushConstant(Bool::False()); // Should be skipped. |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(EqualTOSTrue, test) { |
| + EXPECT(EXECUTE_TEST_CODE_BOOL(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(EqualTOSFalse, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ PushConstant(Smi::Handle(Smi::New(-42))); |
| + __ EqualTOS(); |
| + __ PushConstant(Bool::True()); // Should be skipped. |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(EqualTOSFalse, test) { |
| + EXPECT(!EXECUTE_TEST_CODE_BOOL(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(LessThanTOSTrue, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(-42))); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ LessThanTOS(); |
| + __ PushConstant(Bool::False()); // Should be skipped. |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(LessThanTOSTrue, test) { |
| + EXPECT(EXECUTE_TEST_CODE_BOOL(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(LessThanTOSFalse, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ PushConstant(Smi::Handle(Smi::New(-42))); |
| + __ LessThanTOS(); |
| + __ PushConstant(Bool::False()); // Should be skipped. |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(LessThanTOSFalse, test) { |
| + EXPECT(!EXECUTE_TEST_CODE_BOOL(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(GreaterThanTOSTrue, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ PushConstant(Smi::Handle(Smi::New(-42))); |
| + __ GreaterThanTOS(); |
| + __ PushConstant(Bool::False()); // Should be skipped. |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(GreaterThanTOSTrue, test) { |
| + EXPECT(EXECUTE_TEST_CODE_BOOL(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(GreaterThanTOSFalse, assembler) { |
| + __ PushConstant(Smi::Handle(Smi::New(-42))); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ GreaterThanTOS(); |
| + __ PushConstant(Bool::False()); // Should be skipped. |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(GreaterThanTOSFalse, test) { |
| + EXPECT(!EXECUTE_TEST_CODE_BOOL(test->code())); |
| +} |
| + |
| + |
| + |
| +// - IfNeStrictTOS; IfEqStrictTOS; IfNeStrictNumTOS; IfEqStrictNumTOS |
| +// |
| +// Skips the next instruction unless the given condition holds. 'Num' |
| +// variants perform number check while non-Num variants just compare |
| +// RawObject pointers. |
| +// |
| +// Used to implement conditional jump: |
| +// |
| +// IfNeStrictTOS |
| +// Jump T ;; jump if not equal |
| +ASSEMBLER_TEST_GENERATE(IfNeStrictTOSTaken, assembler) { |
| + Label branch_taken; |
| + const Array& array1 = Array::Handle(Array::New(1, Heap::kOld)); |
| + const Array& array2 = Array::Handle(Array::New(2, Heap::kOld)); |
| + __ PushConstant(array1); |
| + __ PushConstant(array2); |
| + __ IfNeStrictTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(IfNeStrictTOSTaken, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(IfNeStrictTOSNotTaken, assembler) { |
| + Label branch_taken; |
| + const Array& array1 = Array::Handle(Array::New(1, Heap::kOld)); |
| + __ PushConstant(array1); |
| + __ PushConstant(array1); |
| + __ IfNeStrictTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| +} |
| + |
| +ASSEMBLER_TEST_RUN(IfNeStrictTOSNotTaken, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +// TODO(zra): Also add tests that use Mint, Bignum. |
| +ASSEMBLER_TEST_GENERATE(IfNeStrictNumTOSTaken, assembler) { |
| + Label branch_taken; |
| + __ PushConstant(Smi::Handle(Smi::New(-1))); |
| + __ PushConstant(Smi::Handle(Smi::New(1))); |
| + __ IfNeStrictNumTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(IfNeStrictNumTOSTaken, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(IfNeStrictNumTOSNotTaken, assembler) { |
| + Label branch_taken; |
| + __ PushConstant(Smi::Handle(Smi::New(1))); |
| + __ PushConstant(Smi::Handle(Smi::New(1))); |
| + __ IfNeStrictNumTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| +} |
| + |
| +ASSEMBLER_TEST_RUN(IfNeStrictNumTOSNotTaken, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(IfNeStrictNumTOSTakenDouble, assembler) { |
| + Label branch_taken; |
| + __ PushConstant(Double::Handle(Double::New(-1.0, Heap::kOld))); |
| + __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld))); |
| + __ IfNeStrictNumTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(IfNeStrictNumTOSTakenDouble, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(IfNeStrictNumTOSNotTakenDouble, assembler) { |
| + Label branch_taken; |
| + __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld))); |
| + __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld))); |
| + __ IfNeStrictNumTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| +} |
| + |
| +ASSEMBLER_TEST_RUN(IfNeStrictNumTOSNotTakenDouble, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(IfEqStrictTOSTaken, assembler) { |
| + Label branch_taken; |
| + const Array& array1 = Array::Handle(Array::New(1, Heap::kOld)); |
| + __ PushConstant(array1); |
| + __ PushConstant(array1); |
| + __ IfEqStrictTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(IfEqStrictTOSTaken, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(IfEqStrictTOSNotTaken, assembler) { |
| + Label branch_taken; |
| + const Array& array1 = Array::Handle(Array::New(1, Heap::kOld)); |
| + const Array& array2 = Array::Handle(Array::New(2, Heap::kOld)); |
| + __ PushConstant(array1); |
| + __ PushConstant(array2); |
| + __ IfEqStrictTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| +} |
| + |
| +ASSEMBLER_TEST_RUN(IfEqStrictTOSNotTaken, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +// TODO(zra): Also add tests that use Mint, Bignum. |
| +ASSEMBLER_TEST_GENERATE(IfEqStrictNumTOSTaken, assembler) { |
| + Label branch_taken; |
| + __ PushConstant(Smi::Handle(Smi::New(1))); |
| + __ PushConstant(Smi::Handle(Smi::New(1))); |
| + __ IfEqStrictNumTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(IfEqStrictNumTOSTaken, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(IfEqStrictNumTOSNotTaken, assembler) { |
| + Label branch_taken; |
| + __ PushConstant(Smi::Handle(Smi::New(-1))); |
| + __ PushConstant(Smi::Handle(Smi::New(1))); |
| + __ IfEqStrictNumTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(IfEqStrictNumTOSNotTaken, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(IfEqStrictNumTOSTakenDouble, assembler) { |
| + Label branch_taken; |
| + __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld))); |
| + __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld))); |
| + __ IfEqStrictNumTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(IfEqStrictNumTOSTakenDouble, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_GENERATE(IfEqStrictNumTOSNotTakenDouble, assembler) { |
| + Label branch_taken; |
| + __ PushConstant(Double::Handle(Double::New(-1.0, Heap::kOld))); |
| + __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld))); |
| + __ IfEqStrictNumTOS(); |
| + __ Jump(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(42))); |
| + __ ReturnTOS(); |
| + __ Bind(&branch_taken); |
| + __ PushConstant(Smi::Handle(Smi::New(0))); |
| + __ ReturnTOS(); |
| +} |
| + |
| + |
| +ASSEMBLER_TEST_RUN(IfEqStrictNumTOSNotTakenDouble, test) { |
| + EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code())); |
| +} |
| + |
| +} // namespace dart |
| + |
| +#endif // defined(TARGET_ARCH_DBC) |