1 /*
2  * Copyright (C) 2020 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 <cstring>
20 
21 #include "berberis/base/bit_util.h"
22 #include "berberis/guest_abi/guest_arguments.h"
23 
24 namespace berberis {
25 
26 namespace {
27 
TEST(NdkTest,GuestArgumentsAndResultTest)28 TEST(NdkTest, GuestArgumentsAndResultTest) {
29   union {
30     GuestArgumentBuffer buffer;
31     uint32_t
32         padding[AlignUp(offsetof(GuestArgumentBuffer, argv), sizeof(uint32_t)) / sizeof(uint32_t) +
33                 8];
34   } arguments = {{.argv = {0x55555555}}};
35   arguments.buffer.argv[1] = 0x3fd55555;
36   arguments.buffer.argv[2] = 0x9999999a;
37   arguments.buffer.argv[3] = 0x3fc99999;
38   arguments.buffer.argv[4] = 0x92492492;
39   arguments.buffer.argv[5] = 0x3fc24924;
40   arguments.buffer.argv[6] = 0x745d1746;
41   arguments.buffer.argv[7] = 0x3fb745d1;
42 
43   GuestArgumentsAndResult<double(int, double, int, double)> f1_args(&arguments.buffer);
44   EXPECT_EQ(0x55555555, f1_args.GuestArgument<0>());
45   EXPECT_EQ(1.0 / 5.0, f1_args.GuestArgument<1>());
46   EXPECT_EQ(-0x6db6db6e, f1_args.GuestArgument<2>());
47   EXPECT_EQ(1 / 11.0, f1_args.GuestArgument<3>());
48   EXPECT_EQ(1.0 / 3.0, f1_args.GuestResult());
49 
50   GuestArgumentsAndResult<int(double, int, double, int)> f2_args(&arguments.buffer);
51   EXPECT_EQ(1.0 / 3.0, f2_args.GuestArgument<0>());
52   EXPECT_EQ(-0x66666666, f2_args.GuestArgument<1>());
53   EXPECT_EQ(1.0 / 7.0, f2_args.GuestArgument<2>());
54   EXPECT_EQ(0x745d1746, f2_args.GuestArgument<3>());
55   EXPECT_EQ(0x55555555, f2_args.GuestResult());
56 }
57 
TEST(NdkTest,GuestArgumentsAndResultTestAapcsVfp)58 TEST(NdkTest, GuestArgumentsAndResultTestAapcsVfp) {
59   union {
60     GuestArgumentBuffer buffer;
61     uint32_t
62         padding[AlignUp(offsetof(GuestArgumentBuffer, argv), sizeof(uint32_t)) / sizeof(uint32_t) +
63                 8];
64   } arguments = {{.argv = {0x55555555}}};
65   arguments.buffer.argv[1] = 0x3fd55555;
66   arguments.buffer.argv[2] = 0x9999999a;
67   arguments.buffer.argv[3] = 0x3fc99999;
68   arguments.buffer.argv[4] = 0x92492492;
69   arguments.buffer.argv[5] = 0x3fc24924;
70   arguments.buffer.argv[6] = 0x745d1746;
71   arguments.buffer.argv[7] = 0x3fb745d1;
72 
73   GuestArgumentsAndResult<double(int, double, int, double), GuestAbi::kAapcsVfp> f1_args(
74       &arguments.buffer);
75   EXPECT_EQ(0x55555555, f1_args.GuestArgument<0>());
76   EXPECT_DEATH(f1_args.GuestArgument<1>(),
77                "berberis/guest_abi/guest_arguments_arch.h:[0-9]*: CHECK failed: false");
78   EXPECT_EQ(0x3fd55555, f1_args.GuestArgument<2>());
79   EXPECT_DEATH(f1_args.GuestArgument<3>(),
80                "berberis/guest_abi/guest_arguments_arch.h:[0-9]*: CHECK failed: false");
81   EXPECT_DEATH(f1_args.GuestResult(), "");
82 
83   GuestArgumentsAndResult<int(double, int, double, int), GuestAbi::kAapcsVfp> f2_args(
84       &arguments.buffer);
85   EXPECT_DEATH(f2_args.GuestArgument<0>(),
86                "berberis/guest_abi/guest_arguments_arch.h:[0-9]*: CHECK failed: false");
87   EXPECT_EQ(0x55555555, f2_args.GuestArgument<1>());
88   EXPECT_DEATH(f2_args.GuestArgument<2>(),
89                "berberis/guest_abi/guest_arguments_arch.h:[0-9]*: CHECK failed: false");
90   EXPECT_EQ(0x3fd55555, f2_args.GuestArgument<3>());
91   EXPECT_EQ(0x55555555, f2_args.GuestResult());
92 }
93 
94 }  // namespace
95 
96 }  // namespace berberis
97