• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 #include "unit_test.h"
17 #include "inst_generator.h"
18 #include "optimizer/code_generator/codegen.h"
19 #include "optimizer/optimizations/regalloc/reg_alloc_linear_scan.h"
20 #include "target/amd64/target.h"
21 #include "target/aarch64/target.h"
22 #include "target/aarch32/target.h"
23 
24 namespace panda::compiler {
25 
26 class IntrinsicCodegenTest : public GraphTest {
27 public:
IntrinsicCodegenTest()28     IntrinsicCodegenTest()
29         : alloc_ {SpaceType::SPACE_TYPE_COMPILER},
30           local_alloc_ {SpaceType::SPACE_TYPE_COMPILER},
31           graph_creator_ {alloc_, local_alloc_},
32           aarch64_encoder_ {&alloc_},
33           aarch32_encoder_ {&alloc_},
34           amd64_encoder_ {&alloc_}
35     {
36     }
37 
TryEncode(DataType::Type type,RuntimeInterface::IntrinsicId intrinsic_id,Arch arch,bool prepare_graph)38     bool TryEncode(DataType::Type type, RuntimeInterface::IntrinsicId intrinsic_id, Arch arch, bool prepare_graph)
39     {
40         graph_creator_.SetRuntimeTargetArch(arch);
41         auto inst = GenerateIntrinsic(&alloc_, type, intrinsic_id);
42         auto graph = graph_creator_.GenerateGraph(inst);
43         Codegen codegen(graph);
44         codegen.GetCodeBuilder()->BeginMethod(0, 0);
45         Reg dst = INVALID_REGISTER;
46         Codegen::SRCREGS src;
47         RegMask regmask;
48         if (prepare_graph) {
49             graph->GetAnalysis<LoopAnalyzer>().Run();
50             GraphChecker(graph).Check();
51             RegAllocLinearScan(graph).Run();
52             graph->SetStackSlotsCount(2U);
53             codegen.Initialize();
54             if (inst->GetType() != DataType::VOID) {
55                 dst = codegen.ConvertRegister(0, inst->GetType());
56             }
57             uint8_t reg_id = 2;
58             for (size_t i = 0; i < inst->GetInputsCount(); i++, reg_id += 2) {
59                 if (inst->GetInput(i).GetInst()->IsSaveState()) {
60                     continue;
61                 }
62                 auto type = inst->GetInputType(i);
63                 src[i] = codegen.ConvertRegister(2, type);
64             }
65         }
66         codegen.FillBuiltin(inst, src, dst, &regmask);
67         return codegen.GetEncoder()->GetResult();
68     }
69 
70 private:
71     ArenaAllocator alloc_;
72     ArenaAllocator local_alloc_;
73     GraphCreator graph_creator_;
74     aarch64::Aarch64Encoder aarch64_encoder_;
75     aarch32::Aarch32Encoder aarch32_encoder_;
76     amd64::Amd64Encoder amd64_encoder_;
77 
GenerateIntrinsic(ArenaAllocator * allocator,DataType::Type Type,RuntimeInterface::IntrinsicId intrinsic_id)78     IntrinsicInst *GenerateIntrinsic(ArenaAllocator *allocator, DataType::Type Type,
79                                      RuntimeInterface::IntrinsicId intrinsic_id)
80     {
81         auto inst = Inst::New<IntrinsicInst>(allocator, Opcode::Intrinsic);
82         inst->SetType(Type);
83         inst->SetIntrinsicId(intrinsic_id);
84         return inst;
85     }
86 };
87 
88 #ifdef INTRINSIC_CODEGEN_TEST_ARM64
TEST_F(IntrinsicCodegenTest,EncodingARM64)89 TEST_F(IntrinsicCodegenTest, EncodingARM64)
90 {
91     std::pair<Arch, std::string> arch = std::pair {Arch::AARCH64, "arm64"};
92 #include "intrinsic_codegen_test.inl"
93 }
94 #endif
95 
96 #ifdef INTRINSIC_CODEGEN_TEST_AMD64
TEST_F(IntrinsicCodegenTest,EncodingAMD64)97 TEST_F(IntrinsicCodegenTest, EncodingAMD64)
98 {
99     std::pair<Arch, std::string> arch = std::pair {Arch::X86_64, "amd64"};
100 #include "intrinsic_codegen_test.inl"
101 }
102 #endif
103 
104 #ifdef INTRINSIC_CODEGEN_TEST_ARM32
TEST_F(IntrinsicCodegenTest,EncodingARM32)105 TEST_F(IntrinsicCodegenTest, EncodingARM32)
106 {
107     std::pair<Arch, std::string> arch = std::pair {Arch::AARCH32, "arm32"};
108 #include "intrinsic_codegen_test.inl"
109 }
110 #endif
111 }  // namespace panda::compiler
112