• 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 <random>
17 #include <gtest/gtest.h>
18 
19 #include "mem/code_allocator.h"
20 #include "mem/pool_manager.h"
21 #include "target/aarch64/target.h"
22 #include "mem/base_mem_stats.h"
23 
24 const uint64_t SEED = 0x1234;
25 #ifndef PANDA_NIGHTLY_TEST_ON
26 const uint64_t ITERATION = 40;
27 #else
28 const uint64_t ITERATION = 0xffffff;
29 #endif
30 static inline auto random_gen = std::mt19937_64(SEED);
31 
32 namespace panda::compiler {
33 class Callconv64Test : public ::testing::Test {
34 public:
Callconv64Test()35     Callconv64Test()
36     {
37         panda::mem::MemConfig::Initialize(64_MB, 64_MB, 64_MB, 32_MB);
38         PoolManager::Initialize();
39         allocator_ = new ArenaAllocator(SpaceType::SPACE_TYPE_COMPILER);
40         encoder_ = Encoder::Create(allocator_, Arch::AARCH64, false);
41         encoder_->InitMasm();
42         regfile_ = RegistersDescription::Create(allocator_, Arch::AARCH64);
43         callconv_ = CallingConvention::Create(allocator_, encoder_, regfile_, Arch::AARCH64);
44         mem_stats_ = new BaseMemStats();
45         code_alloc_ = new (std::nothrow) CodeAllocator(mem_stats_);
46     }
~Callconv64Test()47     ~Callconv64Test()
48     {
49         Logger::Destroy();
50         encoder_->~Encoder();
51         delete allocator_;
52         delete code_alloc_;
53         delete mem_stats_;
54         PoolManager::Finalize();
55         panda::mem::MemConfig::Finalize();
56     }
57 
GetAllocator()58     ArenaAllocator *GetAllocator()
59     {
60         return allocator_;
61     }
62 
GetEncoder()63     Encoder *GetEncoder()
64     {
65         return encoder_;
66     }
67 
GetRegfile()68     RegistersDescription *GetRegfile()
69     {
70         return regfile_;
71     }
72 
GetCallconv()73     CallingConvention *GetCallconv()
74     {
75         return callconv_;
76     }
77 
78 private:
79     ArenaAllocator *allocator_ {nullptr};
80     Encoder *encoder_ {nullptr};
81     RegistersDescription *regfile_ {nullptr};
82     CallingConvention *callconv_ {nullptr};
83     CodeAllocator *code_alloc_ {nullptr};
84     BaseMemStats *mem_stats_ {nullptr};
85 };
86 
TEST_F(Callconv64Test,NativeParams)87 TEST_F(Callconv64Test, NativeParams)
88 {
89     // Test for
90     // std::variant<Reg, uint8_t> GetNativeParam(const ArenaVector<TypeInfo>& reg_list,
91     //                                           const TypeInfo& type)
92 
93     // 8 uint8_t params - in registers
94     {
95         auto param_info = GetCallconv()->GetParameterInfo(0);
96         auto ret = param_info->GetNativeParam(INT8_TYPE);
97         EXPECT_TRUE(std::holds_alternative<Reg>(ret));
98         EXPECT_EQ(std::get<Reg>(ret).GetId(), 0);
99         EXPECT_EQ(std::get<Reg>(ret), Reg(0, INT8_TYPE));
100 
101         for (uint32_t i = 1; i <= 7; ++i) {
102             ret = param_info->GetNativeParam(INT8_TYPE);
103             EXPECT_TRUE(std::holds_alternative<Reg>(ret));
104             EXPECT_EQ(std::get<Reg>(ret).GetId(), i);
105             EXPECT_EQ(std::get<Reg>(ret), Reg(i, INT8_TYPE));
106         }
107     }
108 
109     // 8 uint32_t params - in registers
110     {
111         auto param_info = GetCallconv()->GetParameterInfo(0);
112         auto ret = param_info->GetNativeParam(INT32_TYPE);
113         EXPECT_TRUE(std::holds_alternative<Reg>(ret));
114         EXPECT_EQ(std::get<Reg>(ret).GetId(), 0);
115         EXPECT_EQ(std::get<Reg>(ret), Reg(0, INT32_TYPE));
116 
117         for (uint32_t i = 1; i <= 7; ++i) {
118             ret = param_info->GetNativeParam(INT32_TYPE);
119             EXPECT_TRUE(std::holds_alternative<Reg>(ret));
120             EXPECT_EQ(std::get<Reg>(ret).GetId(), i);
121             EXPECT_EQ(std::get<Reg>(ret), Reg(i, INT32_TYPE));
122         }
123     }
124 
125     // 8 uint64_t params - in registers
126     {
127         auto param_info = GetCallconv()->GetParameterInfo(0);
128         auto ret = param_info->GetNativeParam(INT64_TYPE);
129         EXPECT_TRUE(std::holds_alternative<Reg>(ret));
130         EXPECT_EQ(std::get<Reg>(ret).GetId(), 0);
131         EXPECT_EQ(std::get<Reg>(ret), Reg(0, INT64_TYPE));
132 
133         for (uint32_t i = 1; i <= 7; ++i) {
134             ret = param_info->GetNativeParam(INT64_TYPE);
135             EXPECT_TRUE(std::holds_alternative<Reg>(ret));
136             EXPECT_EQ(std::get<Reg>(ret).GetId(), i);
137             EXPECT_EQ(std::get<Reg>(ret), Reg(i, INT64_TYPE));
138         }
139     }
140 
141     // 8 float params - in registers
142     {
143         auto param_info = GetCallconv()->GetParameterInfo(0);
144         auto ret = param_info->GetNativeParam(FLOAT32_TYPE);
145         EXPECT_TRUE(std::holds_alternative<Reg>(ret));
146         EXPECT_EQ(std::get<Reg>(ret).GetId(), 0);
147         EXPECT_EQ(std::get<Reg>(ret), Reg(0, FLOAT32_TYPE));
148 
149         for (uint32_t i = 1; i <= 7; ++i) {
150             ret = param_info->GetNativeParam(FLOAT32_TYPE);
151             EXPECT_TRUE(std::holds_alternative<Reg>(ret));
152             EXPECT_EQ(std::get<Reg>(ret).GetId(), i);
153             EXPECT_EQ(std::get<Reg>(ret), Reg(i, FLOAT32_TYPE));
154         }
155     }
156 
157     // 8 double params - in registers
158     {
159         auto param_info = GetCallconv()->GetParameterInfo(0);
160         auto ret = param_info->GetNativeParam(FLOAT64_TYPE);
161         EXPECT_TRUE(std::holds_alternative<Reg>(ret));
162         EXPECT_EQ(std::get<Reg>(ret).GetId(), 0);
163         EXPECT_EQ(std::get<Reg>(ret), Reg(0, FLOAT64_TYPE));
164 
165         for (uint32_t i = 1; i <= 7; ++i) {
166             ret = param_info->GetNativeParam(FLOAT64_TYPE);
167             EXPECT_TRUE(std::holds_alternative<Reg>(ret));
168             EXPECT_EQ(std::get<Reg>(ret).GetId(), i);
169             EXPECT_EQ(std::get<Reg>(ret), Reg(i, FLOAT64_TYPE));
170         }
171     }
172 }
173 }  // namespace panda::compiler
174