• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstdint>
20 
21 #include "berberis/assembler/machine_code.h"
22 #include "berberis/guest_state/guest_addr.h"
23 
24 #include "lite_translator.h"
25 #include "register_maintainer.h"
26 
27 namespace berberis {
28 
29 namespace {
30 
TEST(Riscv64LiteTranslatorTest,GetMappedRegs)31 TEST(Riscv64LiteTranslatorTest, GetMappedRegs) {
32   MachineCode machine_code;
33   LiteTranslator translator(&machine_code, 0);
34   auto [mapped_reg, is_new] = translator.GetMappedRegisterOrMap(1);
35   EXPECT_TRUE(is_new);
36   auto [mapped_reg2, is_new2] = translator.GetMappedRegisterOrMap(1);
37   EXPECT_FALSE(is_new2);
38   EXPECT_EQ(mapped_reg, mapped_reg2);
39   auto [mapped_reg3, is_new3] = translator.GetMappedRegisterOrMap(2);
40   EXPECT_TRUE(is_new3);
41   EXPECT_NE(mapped_reg, mapped_reg3);
42 }
43 
TEST(Riscv64LiteTranslatorTest,GetRegs)44 TEST(Riscv64LiteTranslatorTest, GetRegs) {
45   // if size of machine_code does not change load is skipped.
46   MachineCode machine_code;
47   LiteTranslator translator(&machine_code, 0);
48   translator.GetReg(1);
49   EXPECT_TRUE(translator.gp_maintainer()->IsMapped(1));
50   int size1 = machine_code.install_size();
51   translator.GetReg(1);
52   int size2 = machine_code.install_size();
53   EXPECT_EQ(size1, size2);
54   translator.GetReg(2);
55   EXPECT_TRUE(translator.gp_maintainer()->IsMapped(2));
56   int size3 = machine_code.install_size();
57   EXPECT_LT(size2, size3);
58   translator.GetReg(3);
59   EXPECT_TRUE(translator.gp_maintainer()->IsMapped(3));
60   int size4 = machine_code.install_size();
61   EXPECT_LT(size3, size4);
62 }
63 
TEST(Riscv64LiteTranslatorTest,GetFpReg)64 TEST(Riscv64LiteTranslatorTest, GetFpReg) {
65   // if size of machine_code does not change load is skipped.
66   MachineCode machine_code;
67   LiteTranslator translator(&machine_code, 0);
68   translator.GetFpReg(1);
69   EXPECT_TRUE(translator.simd_maintainer()->IsMapped(1));
70   int size1 = machine_code.install_size();
71   translator.GetFpReg(1);
72   int size2 = machine_code.install_size();
73   EXPECT_EQ(size1, size2);
74   translator.GetFpReg(2);
75   EXPECT_TRUE(translator.simd_maintainer()->IsMapped(2));
76   int size3 = machine_code.install_size();
77   EXPECT_LT(size2, size3);
78   translator.GetFpReg(3);
79   EXPECT_TRUE(translator.simd_maintainer()->IsMapped(3));
80   int size4 = machine_code.install_size();
81   EXPECT_LT(size3, size4);
82 }
83 
TEST(Riscv64LiteTranslatorTest,NanBoxAndSetFpReg)84 TEST(Riscv64LiteTranslatorTest, NanBoxAndSetFpReg) {
85   MachineCode machine_code;
86   LiteTranslator translator(&machine_code, 0);
87   LiteTranslator::FpRegister reg;
88   int32_t offset = offsetof(ThreadState, cpu.f) + 1 * sizeof(LiteTranslator::Float64);
89   size_t store_insn_base = machine_code.install_size();
90   translator.StoreFpReg(reg, offset);
91   size_t store_insn_size = machine_code.install_size() - store_insn_base;
92 
93   size_t mov_insn_base = machine_code.install_size();
94   translator.MoveFpReg(reg, reg);
95   size_t mov_insn_size = machine_code.install_size() - mov_insn_base;
96 
97   size_t nan_box_insn_base = machine_code.install_size();
98   translator.NanBoxFpReg<LiteTranslator::Float32>(reg);
99   size_t nan_box_insn_size = machine_code.install_size() - nan_box_insn_base;
100 
101   ASSERT_NE(store_insn_size, mov_insn_size);
102 
103   size_t nan_box_and_set_base = machine_code.install_size();
104   translator.NanBoxAndSetFpReg<LiteTranslator::Float32>(1, reg);
105   EXPECT_EQ(nan_box_insn_size + mov_insn_size, machine_code.install_size() - nan_box_and_set_base);
106 
107   nan_box_and_set_base = machine_code.install_size();
108   translator.NanBoxAndSetFpReg<LiteTranslator::Float32>(1, reg);
109   EXPECT_EQ(nan_box_insn_size + mov_insn_size, machine_code.install_size() - nan_box_and_set_base);
110 }
111 
TEST(Riscv64LiteTranslatorTest,SetReg)112 TEST(Riscv64LiteTranslatorTest, SetReg) {
113   MachineCode machine_code;
114   LiteTranslator translator(&machine_code, 0);
115   LiteTranslator::Register reg;
116   int32_t offset = offsetof(ThreadState, cpu.x[0]) + 1 * 8;
117   size_t store_insn_base = machine_code.install_size();
118   translator.as()->Movq({.base = translator.as()->rbp, .disp = offset}, reg);
119   size_t store_insn_size = machine_code.install_size() - store_insn_base;
120 
121   size_t mov_insn_base = machine_code.install_size();
122   translator.as()->Movq(reg, reg);
123   size_t mov_insn_size = machine_code.install_size() - mov_insn_base;
124 
125   ASSERT_NE(store_insn_size, mov_insn_size);
126 
127   size_t set_base = machine_code.install_size();
128   translator.SetReg(1, reg);
129   EXPECT_EQ(mov_insn_size, machine_code.install_size() - set_base);
130 
131   set_base = machine_code.install_size();
132   translator.SetReg(1, reg);
133   EXPECT_EQ(mov_insn_size, machine_code.install_size() - set_base);
134 }
135 
136 }  // namespace
137 
138 }  // namespace berberis
139