1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "gtest/gtest.h"
18 
19 #include "berberis/calling_conventions/calling_conventions_arm64.h"
20 
21 namespace berberis::arm64 {
22 
23 namespace {
24 
TEST(CallingConventions_arm64,Smoke)25 TEST(CallingConventions_arm64, Smoke) {
26   CallingConventions conv;
27   ArgLocation loc;
28 
29   loc = conv.GetNextIntArgLoc(4, 4);
30   EXPECT_EQ(loc.kind, kArgLocationInt);
31   EXPECT_EQ(loc.offset, 0u);
32 
33   loc = conv.GetNextIntArgLoc(16, 16);
34   EXPECT_EQ(loc.kind, kArgLocationInt);
35   EXPECT_EQ(loc.offset, 2u);
36 
37   loc = conv.GetNextIntArgLoc(8, 8);
38   EXPECT_EQ(loc.kind, kArgLocationInt);
39   EXPECT_EQ(loc.offset, 4u);
40 
41   loc = conv.GetNextIntArgLoc(16, 16);
42   EXPECT_EQ(loc.kind, kArgLocationInt);
43   EXPECT_EQ(loc.offset, 6u);
44 
45   loc = conv.GetNextIntArgLoc(4, 4);
46   EXPECT_EQ(loc.kind, kArgLocationStack);
47   EXPECT_EQ(loc.offset, 0u);
48 
49   loc = conv.GetNextIntArgLoc(4, 4);
50   EXPECT_EQ(loc.kind, kArgLocationStack);
51   EXPECT_EQ(loc.offset, 8u);
52 
53   loc = conv.GetNextFpArgLoc(16, 16);
54   EXPECT_EQ(loc.kind, kArgLocationSimd);
55   EXPECT_EQ(loc.offset, 0u);
56 
57   loc = conv.GetNextFpArgLoc(16, 16);
58   EXPECT_EQ(loc.kind, kArgLocationSimd);
59   EXPECT_EQ(loc.offset, 1u);
60 
61   loc = conv.GetIntResLoc(1);
62   EXPECT_EQ(loc.kind, kArgLocationInt);
63   EXPECT_EQ(loc.offset, 0u);
64 }
65 
TEST(CallingConventions_arm64,LastIntRegNotUsed)66 TEST(CallingConventions_arm64, LastIntRegNotUsed) {
67   CallingConventions conv;
68   ArgLocation loc;
69 
70   // Use 7 of 8 int regs.
71   conv.GetNextIntArgLoc(4, 4);
72   conv.GetNextIntArgLoc(4, 4);
73   conv.GetNextIntArgLoc(4, 4);
74   conv.GetNextIntArgLoc(4, 4);
75   conv.GetNextIntArgLoc(4, 4);
76   conv.GetNextIntArgLoc(4, 4);
77   loc = conv.GetNextIntArgLoc(4, 4);
78   EXPECT_EQ(loc.kind, kArgLocationInt);
79   EXPECT_EQ(loc.offset, 6u);
80 
81   // Add param that doesn't fit in the last reg.
82   loc = conv.GetNextIntArgLoc(16, 16);
83   EXPECT_EQ(loc.kind, kArgLocationStack);
84   EXPECT_EQ(loc.offset, 0u);
85 
86   // Add param that can fit in the last reg, but still goes to stack.
87   loc = conv.GetNextIntArgLoc(4, 4);
88   EXPECT_EQ(loc.kind, kArgLocationStack);
89   EXPECT_EQ(loc.offset, 16u);
90 }
91 
92 }  // namespace
93 
94 }  // namespace berberis::arm64
95