xref: /aosp_15_r20/external/vixl/test/aarch32/test-utils-aarch32.h (revision f5c631da2f1efdd72b5fd1e20510e4042af13d77)
1*f5c631daSSadaf Ebrahimi // Copyright 2017, VIXL authors
2*f5c631daSSadaf Ebrahimi // All rights reserved.
3*f5c631daSSadaf Ebrahimi //
4*f5c631daSSadaf Ebrahimi // Redistribution and use in source and binary forms, with or without
5*f5c631daSSadaf Ebrahimi // modification, are permitted provided that the following conditions are met:
6*f5c631daSSadaf Ebrahimi //
7*f5c631daSSadaf Ebrahimi //   * Redistributions of source code must retain the above copyright notice,
8*f5c631daSSadaf Ebrahimi //     this list of conditions and the following disclaimer.
9*f5c631daSSadaf Ebrahimi //   * Redistributions in binary form must reproduce the above copyright notice,
10*f5c631daSSadaf Ebrahimi //     this list of conditions and the following disclaimer in the documentation
11*f5c631daSSadaf Ebrahimi //     and/or other materials provided with the distribution.
12*f5c631daSSadaf Ebrahimi //   * Neither the name of ARM Limited nor the names of its contributors may be
13*f5c631daSSadaf Ebrahimi //     used to endorse or promote products derived from this software without
14*f5c631daSSadaf Ebrahimi //     specific prior written permission.
15*f5c631daSSadaf Ebrahimi //
16*f5c631daSSadaf Ebrahimi // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17*f5c631daSSadaf Ebrahimi // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*f5c631daSSadaf Ebrahimi // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*f5c631daSSadaf Ebrahimi // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20*f5c631daSSadaf Ebrahimi // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*f5c631daSSadaf Ebrahimi // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22*f5c631daSSadaf Ebrahimi // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23*f5c631daSSadaf Ebrahimi // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*f5c631daSSadaf Ebrahimi // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25*f5c631daSSadaf Ebrahimi // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*f5c631daSSadaf Ebrahimi 
27*f5c631daSSadaf Ebrahimi #ifndef VIXL_AARCH32_TEST_UTILS_AARCH32_H_
28*f5c631daSSadaf Ebrahimi #define VIXL_AARCH32_TEST_UTILS_AARCH32_H_
29*f5c631daSSadaf Ebrahimi 
30*f5c631daSSadaf Ebrahimi #include "../test-pool-manager.h"
31*f5c631daSSadaf Ebrahimi #include "../test-runner.h"
32*f5c631daSSadaf Ebrahimi #include "aarch32/constants-aarch32.h"
33*f5c631daSSadaf Ebrahimi #include "aarch32/instructions-aarch32.h"
34*f5c631daSSadaf Ebrahimi #include "aarch32/macro-assembler-aarch32.h"
35*f5c631daSSadaf Ebrahimi 
36*f5c631daSSadaf Ebrahimi namespace vixl {
37*f5c631daSSadaf Ebrahimi 
38*f5c631daSSadaf Ebrahimi namespace aarch32 {
39*f5c631daSSadaf Ebrahimi 
40*f5c631daSSadaf Ebrahimi class TestMacroAssembler {
41*f5c631daSSadaf Ebrahimi  public:
TestMacroAssembler(MacroAssembler * masm)42*f5c631daSSadaf Ebrahimi   explicit TestMacroAssembler(MacroAssembler* masm)
43*f5c631daSSadaf Ebrahimi       : test(&masm->pool_manager_) {}
GetPoolCheckpoint()44*f5c631daSSadaf Ebrahimi   int32_t GetPoolCheckpoint() const { return test.GetPoolCheckpoint(); }
GetPoolSize()45*f5c631daSSadaf Ebrahimi   int GetPoolSize() const { return test.GetPoolSize(); }
PoolIsEmpty()46*f5c631daSSadaf Ebrahimi   bool PoolIsEmpty() const { return test.PoolIsEmpty(); }
47*f5c631daSSadaf Ebrahimi 
48*f5c631daSSadaf Ebrahimi  private:
49*f5c631daSSadaf Ebrahimi   TestPoolManager test;
50*f5c631daSSadaf Ebrahimi };
51*f5c631daSSadaf Ebrahimi 
52*f5c631daSSadaf Ebrahimi // Only check the simulator tests when we can actually run them.
53*f5c631daSSadaf Ebrahimi // TODO: Improve this.
54*f5c631daSSadaf Ebrahimi #if defined(__arm__)
55*f5c631daSSadaf Ebrahimi static const bool kCheckSimulatorTestResults = true;
56*f5c631daSSadaf Ebrahimi #else
57*f5c631daSSadaf Ebrahimi static const bool kCheckSimulatorTestResults = false;
58*f5c631daSSadaf Ebrahimi #endif
59*f5c631daSSadaf Ebrahimi 
60*f5c631daSSadaf Ebrahimi // Helper constants used to check for condition code combinations.  These are
61*f5c631daSSadaf Ebrahimi // not part of instruction definitions as no instruction uses them directly.
62*f5c631daSSadaf Ebrahimi const uint32_t NoFlag = 0x0;
63*f5c631daSSadaf Ebrahimi const uint32_t NFlag = 0x80000000;
64*f5c631daSSadaf Ebrahimi const uint32_t ZFlag = 0x40000000;
65*f5c631daSSadaf Ebrahimi const uint32_t CFlag = 0x20000000;
66*f5c631daSSadaf Ebrahimi const uint32_t VFlag = 0x10000000;
67*f5c631daSSadaf Ebrahimi const uint32_t NZFlag = NFlag | ZFlag;
68*f5c631daSSadaf Ebrahimi const uint32_t NCFlag = NFlag | CFlag;
69*f5c631daSSadaf Ebrahimi const uint32_t NVFlag = NFlag | VFlag;
70*f5c631daSSadaf Ebrahimi const uint32_t ZCFlag = ZFlag | CFlag;
71*f5c631daSSadaf Ebrahimi const uint32_t ZVFlag = ZFlag | VFlag;
72*f5c631daSSadaf Ebrahimi const uint32_t CVFlag = CFlag | VFlag;
73*f5c631daSSadaf Ebrahimi const uint32_t NZCFlag = NFlag | ZFlag | CFlag;
74*f5c631daSSadaf Ebrahimi const uint32_t NZVFlag = NFlag | ZFlag | VFlag;
75*f5c631daSSadaf Ebrahimi const uint32_t NCVFlag = NFlag | CFlag | VFlag;
76*f5c631daSSadaf Ebrahimi const uint32_t ZCVFlag = ZFlag | CFlag | VFlag;
77*f5c631daSSadaf Ebrahimi const uint32_t NZCVFlag = NFlag | ZFlag | CFlag | VFlag;
78*f5c631daSSadaf Ebrahimi const uint32_t QFlag = 0x08000000;
79*f5c631daSSadaf Ebrahimi 
80*f5c631daSSadaf Ebrahimi const uint32_t GE0Flag = 0x00010000;
81*f5c631daSSadaf Ebrahimi const uint32_t GE1Flag = 0x00020000;
82*f5c631daSSadaf Ebrahimi const uint32_t GE2Flag = 0x00040000;
83*f5c631daSSadaf Ebrahimi const uint32_t GE3Flag = 0x00080000;
84*f5c631daSSadaf Ebrahimi const uint32_t GE01Flag = GE0Flag | GE1Flag;
85*f5c631daSSadaf Ebrahimi const uint32_t GE02Flag = GE0Flag | GE2Flag;
86*f5c631daSSadaf Ebrahimi const uint32_t GE03Flag = GE0Flag | GE3Flag;
87*f5c631daSSadaf Ebrahimi const uint32_t GE12Flag = GE1Flag | GE2Flag;
88*f5c631daSSadaf Ebrahimi const uint32_t GE13Flag = GE1Flag | GE3Flag;
89*f5c631daSSadaf Ebrahimi const uint32_t GE23Flag = GE2Flag | GE3Flag;
90*f5c631daSSadaf Ebrahimi const uint32_t GE012Flag = GE0Flag | GE1Flag | GE2Flag;
91*f5c631daSSadaf Ebrahimi const uint32_t GE013Flag = GE0Flag | GE1Flag | GE3Flag;
92*f5c631daSSadaf Ebrahimi const uint32_t GE023Flag = GE0Flag | GE2Flag | GE3Flag;
93*f5c631daSSadaf Ebrahimi const uint32_t GE123Flag = GE1Flag | GE2Flag | GE3Flag;
94*f5c631daSSadaf Ebrahimi const uint32_t GE0123Flag = GE0Flag | GE1Flag | GE2Flag | GE3Flag;
95*f5c631daSSadaf Ebrahimi const uint32_t GEFlags = GE0123Flag;
96*f5c631daSSadaf Ebrahimi 
97*f5c631daSSadaf Ebrahimi struct vec128_t {
98*f5c631daSSadaf Ebrahimi   uint64_t l;
99*f5c631daSSadaf Ebrahimi   uint64_t h;
100*f5c631daSSadaf Ebrahimi };
101*f5c631daSSadaf Ebrahimi 
102*f5c631daSSadaf Ebrahimi class RegisterDump {
103*f5c631daSSadaf Ebrahimi  public:
RegisterDump()104*f5c631daSSadaf Ebrahimi   RegisterDump() : completed_(false) {
105*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(sizeof(dump_.r_[0]) == kRegSizeInBytes);
106*f5c631daSSadaf Ebrahimi   }
107*f5c631daSSadaf Ebrahimi 
108*f5c631daSSadaf Ebrahimi   // The Dump method generates code to store a snapshot of the register values.
109*f5c631daSSadaf Ebrahimi   // It needs to be able to use the stack temporarily.
110*f5c631daSSadaf Ebrahimi   //
111*f5c631daSSadaf Ebrahimi   // The dumping code is generated though the given MacroAssembler. No registers
112*f5c631daSSadaf Ebrahimi   // are corrupted in the process apart for the program counter, but the stack
113*f5c631daSSadaf Ebrahimi   // is used briefly.  Note the program counter cannot be retrieved from the
114*f5c631daSSadaf Ebrahimi   // register dump anyway.
115*f5c631daSSadaf Ebrahimi   void Dump(MacroAssembler* masm);
116*f5c631daSSadaf Ebrahimi 
117*f5c631daSSadaf Ebrahimi   // Register accessors.
reg(unsigned code)118*f5c631daSSadaf Ebrahimi   int32_t reg(unsigned code) const {
119*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsComplete());
120*f5c631daSSadaf Ebrahimi     // The collected program counter should not be accessed.
121*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(code != kPcCode);
122*f5c631daSSadaf Ebrahimi     return dump_.r_[code];
123*f5c631daSSadaf Ebrahimi   }
124*f5c631daSSadaf Ebrahimi 
125*f5c631daSSadaf Ebrahimi   // QRegister accessors
GetQRegisterBits(unsigned code)126*f5c631daSSadaf Ebrahimi   vec128_t GetQRegisterBits(unsigned code) const {
127*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsComplete());
128*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(code < kNumberOfQRegisters);
129*f5c631daSSadaf Ebrahimi     vec128_t content = {dump_.d_[code * 2], dump_.d_[(code * 2) + 1]};
130*f5c631daSSadaf Ebrahimi     return content;
131*f5c631daSSadaf Ebrahimi   }
132*f5c631daSSadaf Ebrahimi 
133*f5c631daSSadaf Ebrahimi   // DRegister accessors
GetDRegisterBits(unsigned code)134*f5c631daSSadaf Ebrahimi   uint64_t GetDRegisterBits(unsigned code) const {
135*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsComplete());
136*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(code < kMaxNumberOfDRegisters);
137*f5c631daSSadaf Ebrahimi     return dump_.d_[code];
138*f5c631daSSadaf Ebrahimi   }
139*f5c631daSSadaf Ebrahimi 
140*f5c631daSSadaf Ebrahimi   // SRegister accessors
GetSRegisterBits(unsigned code)141*f5c631daSSadaf Ebrahimi   uint32_t GetSRegisterBits(unsigned code) const {
142*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsComplete());
143*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(code < kNumberOfSRegisters);
144*f5c631daSSadaf Ebrahimi     if ((code % 2) == 0) {
145*f5c631daSSadaf Ebrahimi       return GetDRegisterBits(code / 2) & 0xffffffff;
146*f5c631daSSadaf Ebrahimi     } else {
147*f5c631daSSadaf Ebrahimi       return GetDRegisterBits(code / 2) >> 32;
148*f5c631daSSadaf Ebrahimi     }
149*f5c631daSSadaf Ebrahimi     VIXL_UNREACHABLE();
150*f5c631daSSadaf Ebrahimi     return 0;
151*f5c631daSSadaf Ebrahimi   }
152*f5c631daSSadaf Ebrahimi 
153*f5c631daSSadaf Ebrahimi   // Stack pointer accessors.
spreg()154*f5c631daSSadaf Ebrahimi   int32_t spreg() const { return reg(kSPRegNum); }
155*f5c631daSSadaf Ebrahimi 
156*f5c631daSSadaf Ebrahimi   // Flags accessors.
flags_nzcv()157*f5c631daSSadaf Ebrahimi   uint32_t flags_nzcv() const {
158*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(IsComplete());
159*f5c631daSSadaf Ebrahimi     return dump_.flags_ & NZCVFlag;
160*f5c631daSSadaf Ebrahimi   }
161*f5c631daSSadaf Ebrahimi 
IsComplete()162*f5c631daSSadaf Ebrahimi   bool IsComplete() const { return completed_; }
163*f5c631daSSadaf Ebrahimi 
164*f5c631daSSadaf Ebrahimi  private:
165*f5c631daSSadaf Ebrahimi   // Indicate whether the dump operation has been completed.
166*f5c631daSSadaf Ebrahimi   bool completed_;
167*f5c631daSSadaf Ebrahimi 
168*f5c631daSSadaf Ebrahimi   // Store all the dumped elements in a simple struct so the implementation can
169*f5c631daSSadaf Ebrahimi   // use offsetof to quickly find the correct field.
170*f5c631daSSadaf Ebrahimi   struct dump_t {
171*f5c631daSSadaf Ebrahimi     // Core registers, except for PC.
172*f5c631daSSadaf Ebrahimi     uint32_t r_[kNumberOfRegisters - 1];
173*f5c631daSSadaf Ebrahimi     uint64_t d_[kMaxNumberOfDRegisters];
174*f5c631daSSadaf Ebrahimi 
175*f5c631daSSadaf Ebrahimi     // NZCV flags, stored in bits 28 to 31.
176*f5c631daSSadaf Ebrahimi     // bit[31] : Negative
177*f5c631daSSadaf Ebrahimi     // bit[30] : Zero
178*f5c631daSSadaf Ebrahimi     // bit[29] : Carry
179*f5c631daSSadaf Ebrahimi     // bit[28] : oVerflow
180*f5c631daSSadaf Ebrahimi     uint32_t flags_;
181*f5c631daSSadaf Ebrahimi   } dump_;
182*f5c631daSSadaf Ebrahimi };
183*f5c631daSSadaf Ebrahimi 
184*f5c631daSSadaf Ebrahimi bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg);
185*f5c631daSSadaf Ebrahimi bool Equal32(uint32_t expected, const RegisterDump* core, uint32_t result);
186*f5c631daSSadaf Ebrahimi bool Equal32(uint32_t expected,
187*f5c631daSSadaf Ebrahimi              const RegisterDump* core,
188*f5c631daSSadaf Ebrahimi              const SRegister& sreg);
189*f5c631daSSadaf Ebrahimi bool Equal64(uint64_t expected,
190*f5c631daSSadaf Ebrahimi              const RegisterDump* core,
191*f5c631daSSadaf Ebrahimi              const DRegister& dreg);
192*f5c631daSSadaf Ebrahimi bool Equal128(uint64_t expected_h,
193*f5c631daSSadaf Ebrahimi               uint64_t expected_l,
194*f5c631daSSadaf Ebrahimi               const RegisterDump* core,
195*f5c631daSSadaf Ebrahimi               const QRegister& qreg);
196*f5c631daSSadaf Ebrahimi bool EqualFP32(float expected, const RegisterDump* core, const SRegister& dreg);
197*f5c631daSSadaf Ebrahimi bool EqualFP64(double expected,
198*f5c631daSSadaf Ebrahimi                const RegisterDump* core,
199*f5c631daSSadaf Ebrahimi                const DRegister& dreg);
200*f5c631daSSadaf Ebrahimi bool EqualNzcv(uint32_t expected, uint32_t result);
201*f5c631daSSadaf Ebrahimi 
202*f5c631daSSadaf Ebrahimi }  // namespace aarch32
203*f5c631daSSadaf Ebrahimi }  // namespace vixl
204*f5c631daSSadaf Ebrahimi 
205*f5c631daSSadaf Ebrahimi #endif  // VIXL_AARCH32_TEST_UTILS_AARCH32_H_
206