1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef COMPILER_TESTS_CODEGEN_CODEGEN_TEST_H
17 #define COMPILER_TESTS_CODEGEN_CODEGEN_TEST_H
18
19 #include <random>
20
21 #include "optimizer/code_generator/codegen.h"
22 #include "optimizer/ir/basicblock.h"
23 #include "optimizer/ir/inst.h"
24 #include "optimizer/optimizations/if_conversion.h"
25 #include "optimizer/optimizations/lowering.h"
26 #include "optimizer/optimizations/regalloc/reg_alloc.h"
27 #include "optimizer/optimizations/regalloc/reg_alloc_linear_scan.h"
28 #include "optimizer_run.h"
29 #include "compiler/inplace_task_runner.h"
30 #include "compiler/compiler_task_runner.h"
31
32 #include "libpandabase/macros.h"
33 #include "libpandabase/utils/utils.h"
34 #include "gtest/gtest.h"
35 #include "compiler/tests/unit_test.h"
36 #include "utils/bit_utils.h"
37 #include "compiler/tests/vixl_exec_module.h"
38
39 namespace ark::compiler {
40
41 class CodegenTest : public GraphTest {
42 public:
CodegenTest()43 CodegenTest() : execModule_(GetAllocator(), GetGraph()->GetRuntime())
44 {
45 #ifndef NDEBUG
46 // GraphChecker hack: LowLevel instructions may appear only after Lowering pass:
47 GetGraph()->SetLowLevelInstructionsEnabled();
48 #endif
49 }
50 ~CodegenTest() override = default;
51
52 NO_COPY_SEMANTIC(CodegenTest);
53 NO_MOVE_SEMANTIC(CodegenTest);
54
GetExecModule()55 VixlExecModule &GetExecModule()
56 {
57 return execModule_;
58 }
59
60 template <typename T>
61 void CheckStoreArray();
62
63 template <typename T>
64 void CheckLoadArray();
65
66 template <typename T>
67 void CheckStoreArrayPair(bool imm);
68
69 template <typename T>
70 void CheckLoadArrayPair(bool imm);
71
72 template <typename T>
73 void CheckCmp(bool isFcmpg = false);
74
75 template <typename T>
76 void CheckReturnValue(Graph *graph, T expectedValue);
77
78 template <typename T>
79 void CheckBounds(uint64_t count);
80
81 template <Opcode OPCODE, uint32_t L, uint32_t R, ShiftType SHIFT_TYPE, uint32_t SHIFT, uint32_t ERV>
82 void TestBinaryOperationWithShiftedOperand();
83
84 void CreateGraphForOverflowTest(Graph *graph, Opcode overflowOpcode);
85
86 private:
87 VixlExecModule execModule_;
88 };
89
RunCodegen(Graph * graph)90 inline bool RunCodegen(Graph *graph)
91 {
92 return graph->RunPass<Codegen>();
93 }
94
95 template <typename T>
CheckReturnValue(Graph * graph,T expectedValue)96 void CodegenTest::CheckReturnValue(Graph *graph, [[maybe_unused]] T expectedValue)
97 {
98 SetNumVirtRegs(0U);
99 RegAlloc(graph);
100 EXPECT_TRUE(RunCodegen(graph));
101
102 auto codeEntry = reinterpret_cast<char *>(graph->GetCode().Data());
103 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
104 auto codeExit = codeEntry + graph->GetCode().Size();
105
106 ASSERT(codeEntry != nullptr);
107 ASSERT(codeExit != nullptr);
108
109 GetExecModule().SetInstructions(codeEntry, codeExit);
110 GetExecModule().SetDump(false);
111
112 GetExecModule().Execute();
113 auto rv = GetExecModule().GetRetValue<T>();
114 EXPECT_EQ(rv, expectedValue);
115 }
116
117 } // namespace ark::compiler
118
119 #endif // COMPILER_TESTS_CODEGEN_CODEGEN_TEST_H
120