xref: /aosp_15_r20/art/compiler/optimizing/parallel_move_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "base/arena_allocator.h"
18*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
19*795d594fSAndroid Build Coastguard Worker #include "base/malloc_arena_pool.h"
20*795d594fSAndroid Build Coastguard Worker #include "nodes.h"
21*795d594fSAndroid Build Coastguard Worker #include "parallel_move_resolver.h"
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest-typed-test.h"
24*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker constexpr int kScratchRegisterStartIndexForTest = 100;
29*795d594fSAndroid Build Coastguard Worker 
DumpRegisterForTest(std::ostream & os,int reg)30*795d594fSAndroid Build Coastguard Worker static void DumpRegisterForTest(std::ostream& os, int reg) {
31*795d594fSAndroid Build Coastguard Worker   if (reg >= kScratchRegisterStartIndexForTest) {
32*795d594fSAndroid Build Coastguard Worker     os << "T" << reg - kScratchRegisterStartIndexForTest;
33*795d594fSAndroid Build Coastguard Worker   } else {
34*795d594fSAndroid Build Coastguard Worker     os << reg;
35*795d594fSAndroid Build Coastguard Worker   }
36*795d594fSAndroid Build Coastguard Worker }
37*795d594fSAndroid Build Coastguard Worker 
DumpLocationForTest(std::ostream & os,Location location)38*795d594fSAndroid Build Coastguard Worker static void DumpLocationForTest(std::ostream& os, Location location) {
39*795d594fSAndroid Build Coastguard Worker   if (location.IsConstant()) {
40*795d594fSAndroid Build Coastguard Worker     os << "C";
41*795d594fSAndroid Build Coastguard Worker   } else if (location.IsPair()) {
42*795d594fSAndroid Build Coastguard Worker     DumpRegisterForTest(os, location.low());
43*795d594fSAndroid Build Coastguard Worker     os << ",";
44*795d594fSAndroid Build Coastguard Worker     DumpRegisterForTest(os, location.high());
45*795d594fSAndroid Build Coastguard Worker   } else if (location.IsRegister()) {
46*795d594fSAndroid Build Coastguard Worker     DumpRegisterForTest(os, location.reg());
47*795d594fSAndroid Build Coastguard Worker   } else if (location.IsStackSlot()) {
48*795d594fSAndroid Build Coastguard Worker     os << location.GetStackIndex() << "(sp)";
49*795d594fSAndroid Build Coastguard Worker   } else {
50*795d594fSAndroid Build Coastguard Worker     DCHECK(location.IsDoubleStackSlot())<< location;
51*795d594fSAndroid Build Coastguard Worker     os << "2x" << location.GetStackIndex() << "(sp)";
52*795d594fSAndroid Build Coastguard Worker   }
53*795d594fSAndroid Build Coastguard Worker }
54*795d594fSAndroid Build Coastguard Worker 
55*795d594fSAndroid Build Coastguard Worker class TestParallelMoveResolverWithSwap : public ParallelMoveResolverWithSwap {
56*795d594fSAndroid Build Coastguard Worker  public:
TestParallelMoveResolverWithSwap(ArenaAllocator * allocator)57*795d594fSAndroid Build Coastguard Worker   explicit TestParallelMoveResolverWithSwap(ArenaAllocator* allocator)
58*795d594fSAndroid Build Coastguard Worker       : ParallelMoveResolverWithSwap(allocator) {}
59*795d594fSAndroid Build Coastguard Worker 
EmitMove(size_t index)60*795d594fSAndroid Build Coastguard Worker   void EmitMove(size_t index) override {
61*795d594fSAndroid Build Coastguard Worker     MoveOperands* move = moves_[index];
62*795d594fSAndroid Build Coastguard Worker     if (!message_.str().empty()) {
63*795d594fSAndroid Build Coastguard Worker       message_ << " ";
64*795d594fSAndroid Build Coastguard Worker     }
65*795d594fSAndroid Build Coastguard Worker     message_ << "(";
66*795d594fSAndroid Build Coastguard Worker     DumpLocationForTest(message_, move->GetSource());
67*795d594fSAndroid Build Coastguard Worker     message_ << " -> ";
68*795d594fSAndroid Build Coastguard Worker     DumpLocationForTest(message_, move->GetDestination());
69*795d594fSAndroid Build Coastguard Worker     message_ << ")";
70*795d594fSAndroid Build Coastguard Worker   }
71*795d594fSAndroid Build Coastguard Worker 
EmitSwap(size_t index)72*795d594fSAndroid Build Coastguard Worker   void EmitSwap(size_t index) override {
73*795d594fSAndroid Build Coastguard Worker     MoveOperands* move = moves_[index];
74*795d594fSAndroid Build Coastguard Worker     if (!message_.str().empty()) {
75*795d594fSAndroid Build Coastguard Worker       message_ << " ";
76*795d594fSAndroid Build Coastguard Worker     }
77*795d594fSAndroid Build Coastguard Worker     message_ << "(";
78*795d594fSAndroid Build Coastguard Worker     DumpLocationForTest(message_, move->GetSource());
79*795d594fSAndroid Build Coastguard Worker     message_ << " <-> ";
80*795d594fSAndroid Build Coastguard Worker     DumpLocationForTest(message_, move->GetDestination());
81*795d594fSAndroid Build Coastguard Worker     message_ << ")";
82*795d594fSAndroid Build Coastguard Worker   }
83*795d594fSAndroid Build Coastguard Worker 
SpillScratch(int reg)84*795d594fSAndroid Build Coastguard Worker   void SpillScratch([[maybe_unused]] int reg) override {}
RestoreScratch(int reg)85*795d594fSAndroid Build Coastguard Worker   void RestoreScratch([[maybe_unused]] int reg) override {}
86*795d594fSAndroid Build Coastguard Worker 
GetMessage() const87*795d594fSAndroid Build Coastguard Worker   std::string GetMessage() const {
88*795d594fSAndroid Build Coastguard Worker     return  message_.str();
89*795d594fSAndroid Build Coastguard Worker   }
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker  private:
92*795d594fSAndroid Build Coastguard Worker   std::ostringstream message_;
93*795d594fSAndroid Build Coastguard Worker 
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(TestParallelMoveResolverWithSwap);
96*795d594fSAndroid Build Coastguard Worker };
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker class TestParallelMoveResolverNoSwap : public ParallelMoveResolverNoSwap {
99*795d594fSAndroid Build Coastguard Worker  public:
TestParallelMoveResolverNoSwap(ArenaAllocator * allocator)100*795d594fSAndroid Build Coastguard Worker   explicit TestParallelMoveResolverNoSwap(ArenaAllocator* allocator)
101*795d594fSAndroid Build Coastguard Worker       : ParallelMoveResolverNoSwap(allocator), scratch_index_(kScratchRegisterStartIndexForTest) {}
102*795d594fSAndroid Build Coastguard Worker 
PrepareForEmitNativeCode()103*795d594fSAndroid Build Coastguard Worker   void PrepareForEmitNativeCode() override {
104*795d594fSAndroid Build Coastguard Worker     scratch_index_ = kScratchRegisterStartIndexForTest;
105*795d594fSAndroid Build Coastguard Worker   }
106*795d594fSAndroid Build Coastguard Worker 
FinishEmitNativeCode()107*795d594fSAndroid Build Coastguard Worker   void FinishEmitNativeCode() override {}
108*795d594fSAndroid Build Coastguard Worker 
AllocateScratchLocationFor(Location::Kind kind)109*795d594fSAndroid Build Coastguard Worker   Location AllocateScratchLocationFor(Location::Kind kind) override {
110*795d594fSAndroid Build Coastguard Worker     if (kind == Location::kStackSlot || kind == Location::kFpuRegister ||
111*795d594fSAndroid Build Coastguard Worker         kind == Location::kRegister) {
112*795d594fSAndroid Build Coastguard Worker       kind = Location::kRegister;
113*795d594fSAndroid Build Coastguard Worker     } else {
114*795d594fSAndroid Build Coastguard Worker       // Allocate register pair for double stack slot which simulates 32-bit backend's behavior.
115*795d594fSAndroid Build Coastguard Worker       kind = Location::kRegisterPair;
116*795d594fSAndroid Build Coastguard Worker     }
117*795d594fSAndroid Build Coastguard Worker     Location scratch = GetScratchLocation(kind);
118*795d594fSAndroid Build Coastguard Worker     if (scratch.Equals(Location::NoLocation())) {
119*795d594fSAndroid Build Coastguard Worker       AddScratchLocation(Location::RegisterLocation(scratch_index_));
120*795d594fSAndroid Build Coastguard Worker       AddScratchLocation(Location::RegisterLocation(scratch_index_ + 1));
121*795d594fSAndroid Build Coastguard Worker       AddScratchLocation(Location::RegisterPairLocation(scratch_index_, scratch_index_ + 1));
122*795d594fSAndroid Build Coastguard Worker       scratch = (kind == Location::kRegister) ? Location::RegisterLocation(scratch_index_)
123*795d594fSAndroid Build Coastguard Worker           : Location::RegisterPairLocation(scratch_index_, scratch_index_ + 1);
124*795d594fSAndroid Build Coastguard Worker       scratch_index_ += 2;
125*795d594fSAndroid Build Coastguard Worker     }
126*795d594fSAndroid Build Coastguard Worker     return scratch;
127*795d594fSAndroid Build Coastguard Worker   }
128*795d594fSAndroid Build Coastguard Worker 
FreeScratchLocation(Location loc)129*795d594fSAndroid Build Coastguard Worker   void FreeScratchLocation([[maybe_unused]] Location loc) override {}
130*795d594fSAndroid Build Coastguard Worker 
EmitMove(size_t index)131*795d594fSAndroid Build Coastguard Worker   void EmitMove(size_t index) override {
132*795d594fSAndroid Build Coastguard Worker     MoveOperands* move = moves_[index];
133*795d594fSAndroid Build Coastguard Worker     if (!message_.str().empty()) {
134*795d594fSAndroid Build Coastguard Worker       message_ << " ";
135*795d594fSAndroid Build Coastguard Worker     }
136*795d594fSAndroid Build Coastguard Worker     message_ << "(";
137*795d594fSAndroid Build Coastguard Worker     DumpLocationForTest(message_, move->GetSource());
138*795d594fSAndroid Build Coastguard Worker     message_ << " -> ";
139*795d594fSAndroid Build Coastguard Worker     DumpLocationForTest(message_, move->GetDestination());
140*795d594fSAndroid Build Coastguard Worker     message_ << ")";
141*795d594fSAndroid Build Coastguard Worker   }
142*795d594fSAndroid Build Coastguard Worker 
GetMessage() const143*795d594fSAndroid Build Coastguard Worker   std::string GetMessage() const {
144*795d594fSAndroid Build Coastguard Worker     return  message_.str();
145*795d594fSAndroid Build Coastguard Worker   }
146*795d594fSAndroid Build Coastguard Worker 
147*795d594fSAndroid Build Coastguard Worker  private:
148*795d594fSAndroid Build Coastguard Worker   std::ostringstream message_;
149*795d594fSAndroid Build Coastguard Worker 
150*795d594fSAndroid Build Coastguard Worker   int scratch_index_;
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(TestParallelMoveResolverNoSwap);
153*795d594fSAndroid Build Coastguard Worker };
154*795d594fSAndroid Build Coastguard Worker 
BuildParallelMove(ArenaAllocator * allocator,const size_t operands[][2],size_t number_of_moves)155*795d594fSAndroid Build Coastguard Worker static HParallelMove* BuildParallelMove(ArenaAllocator* allocator,
156*795d594fSAndroid Build Coastguard Worker                                         const size_t operands[][2],
157*795d594fSAndroid Build Coastguard Worker                                         size_t number_of_moves) {
158*795d594fSAndroid Build Coastguard Worker   HParallelMove* moves = new (allocator) HParallelMove(allocator);
159*795d594fSAndroid Build Coastguard Worker   for (size_t i = 0; i < number_of_moves; ++i) {
160*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
161*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(operands[i][0]),
162*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(operands[i][1]),
163*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
164*795d594fSAndroid Build Coastguard Worker         nullptr);
165*795d594fSAndroid Build Coastguard Worker   }
166*795d594fSAndroid Build Coastguard Worker   return moves;
167*795d594fSAndroid Build Coastguard Worker }
168*795d594fSAndroid Build Coastguard Worker 
169*795d594fSAndroid Build Coastguard Worker template <typename T>
170*795d594fSAndroid Build Coastguard Worker class ParallelMoveTest : public ::testing::Test {
171*795d594fSAndroid Build Coastguard Worker  public:
172*795d594fSAndroid Build Coastguard Worker   static const bool has_swap;
173*795d594fSAndroid Build Coastguard Worker };
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker template<> const bool ParallelMoveTest<TestParallelMoveResolverWithSwap>::has_swap = true;
176*795d594fSAndroid Build Coastguard Worker template<> const bool ParallelMoveTest<TestParallelMoveResolverNoSwap>::has_swap = false;
177*795d594fSAndroid Build Coastguard Worker 
178*795d594fSAndroid Build Coastguard Worker using ParallelMoveResolverTestTypes =
179*795d594fSAndroid Build Coastguard Worker     ::testing::Types<TestParallelMoveResolverWithSwap, TestParallelMoveResolverNoSwap>;
180*795d594fSAndroid Build Coastguard Worker 
181*795d594fSAndroid Build Coastguard Worker TYPED_TEST_CASE(ParallelMoveTest, ParallelMoveResolverTestTypes);
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker 
TYPED_TEST(ParallelMoveTest,Dependency)184*795d594fSAndroid Build Coastguard Worker TYPED_TEST(ParallelMoveTest, Dependency) {
185*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
186*795d594fSAndroid Build Coastguard Worker   ArenaAllocator allocator(&pool);
187*795d594fSAndroid Build Coastguard Worker 
188*795d594fSAndroid Build Coastguard Worker   {
189*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
190*795d594fSAndroid Build Coastguard Worker     static constexpr size_t moves[][2] = {{0, 1}, {1, 2}};
191*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
192*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
193*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(1 -> 2) (0 -> 1)", resolver.GetMessage().c_str());
194*795d594fSAndroid Build Coastguard Worker     } else {
195*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(1 -> 2) (0 -> 1)", resolver.GetMessage().c_str());
196*795d594fSAndroid Build Coastguard Worker     }
197*795d594fSAndroid Build Coastguard Worker   }
198*795d594fSAndroid Build Coastguard Worker 
199*795d594fSAndroid Build Coastguard Worker   {
200*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
201*795d594fSAndroid Build Coastguard Worker     static constexpr size_t moves[][2] = {{0, 1}, {1, 2}, {2, 3}, {1, 4}};
202*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
203*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
204*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2 -> 3) (1 -> 2) (1 -> 4) (0 -> 1)", resolver.GetMessage().c_str());
205*795d594fSAndroid Build Coastguard Worker     } else {
206*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2 -> 3) (1 -> 2) (0 -> 1) (2 -> 4)", resolver.GetMessage().c_str());
207*795d594fSAndroid Build Coastguard Worker     }
208*795d594fSAndroid Build Coastguard Worker   }
209*795d594fSAndroid Build Coastguard Worker }
210*795d594fSAndroid Build Coastguard Worker 
TYPED_TEST(ParallelMoveTest,Cycle)211*795d594fSAndroid Build Coastguard Worker TYPED_TEST(ParallelMoveTest, Cycle) {
212*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
213*795d594fSAndroid Build Coastguard Worker   ArenaAllocator allocator(&pool);
214*795d594fSAndroid Build Coastguard Worker 
215*795d594fSAndroid Build Coastguard Worker   {
216*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
217*795d594fSAndroid Build Coastguard Worker     static constexpr size_t moves[][2] = {{0, 1}, {1, 0}};
218*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
219*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
220*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(1 <-> 0)", resolver.GetMessage().c_str());
221*795d594fSAndroid Build Coastguard Worker     } else {
222*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(1 -> T0) (0 -> 1) (T0 -> 0)", resolver.GetMessage().c_str());
223*795d594fSAndroid Build Coastguard Worker     }
224*795d594fSAndroid Build Coastguard Worker   }
225*795d594fSAndroid Build Coastguard Worker 
226*795d594fSAndroid Build Coastguard Worker   {
227*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
228*795d594fSAndroid Build Coastguard Worker     static constexpr size_t moves[][2] = {{0, 1}, {1, 2}, {1, 0}};
229*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
230*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
231*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(1 -> 2) (1 <-> 0)", resolver.GetMessage().c_str());
232*795d594fSAndroid Build Coastguard Worker     } else {
233*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(1 -> 2) (0 -> 1) (2 -> 0)", resolver.GetMessage().c_str());
234*795d594fSAndroid Build Coastguard Worker     }
235*795d594fSAndroid Build Coastguard Worker   }
236*795d594fSAndroid Build Coastguard Worker 
237*795d594fSAndroid Build Coastguard Worker   {
238*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
239*795d594fSAndroid Build Coastguard Worker     static constexpr size_t moves[][2] = {{0, 1}, {1, 0}, {0, 2}};
240*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
241*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
242*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0 -> 2) (1 <-> 0)", resolver.GetMessage().c_str());
243*795d594fSAndroid Build Coastguard Worker     } else {
244*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0 -> 2) (1 -> 0) (2 -> 1)", resolver.GetMessage().c_str());
245*795d594fSAndroid Build Coastguard Worker     }
246*795d594fSAndroid Build Coastguard Worker   }
247*795d594fSAndroid Build Coastguard Worker 
248*795d594fSAndroid Build Coastguard Worker   {
249*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
250*795d594fSAndroid Build Coastguard Worker     static constexpr size_t moves[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 0}};
251*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
252*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
253*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(4 <-> 0) (3 <-> 4) (2 <-> 3) (1 <-> 2)", resolver.GetMessage().c_str());
254*795d594fSAndroid Build Coastguard Worker     } else {
255*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(4 -> T0) (3 -> 4) (2 -> 3) (1 -> 2) (0 -> 1) (T0 -> 0)",
256*795d594fSAndroid Build Coastguard Worker           resolver.GetMessage().c_str());
257*795d594fSAndroid Build Coastguard Worker     }
258*795d594fSAndroid Build Coastguard Worker   }
259*795d594fSAndroid Build Coastguard Worker }
260*795d594fSAndroid Build Coastguard Worker 
TYPED_TEST(ParallelMoveTest,ConstantLast)261*795d594fSAndroid Build Coastguard Worker TYPED_TEST(ParallelMoveTest, ConstantLast) {
262*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
263*795d594fSAndroid Build Coastguard Worker   ArenaAllocator allocator(&pool);
264*795d594fSAndroid Build Coastguard Worker   TypeParam resolver(&allocator);
265*795d594fSAndroid Build Coastguard Worker   HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
266*795d594fSAndroid Build Coastguard Worker   moves->AddMove(
267*795d594fSAndroid Build Coastguard Worker       Location::ConstantLocation(new (&allocator) HIntConstant(0)),
268*795d594fSAndroid Build Coastguard Worker       Location::RegisterLocation(0),
269*795d594fSAndroid Build Coastguard Worker       DataType::Type::kInt32,
270*795d594fSAndroid Build Coastguard Worker       nullptr);
271*795d594fSAndroid Build Coastguard Worker   moves->AddMove(
272*795d594fSAndroid Build Coastguard Worker       Location::RegisterLocation(1),
273*795d594fSAndroid Build Coastguard Worker       Location::RegisterLocation(2),
274*795d594fSAndroid Build Coastguard Worker       DataType::Type::kInt32,
275*795d594fSAndroid Build Coastguard Worker       nullptr);
276*795d594fSAndroid Build Coastguard Worker   resolver.EmitNativeCode(moves);
277*795d594fSAndroid Build Coastguard Worker   ASSERT_STREQ("(1 -> 2) (C -> 0)", resolver.GetMessage().c_str());
278*795d594fSAndroid Build Coastguard Worker }
279*795d594fSAndroid Build Coastguard Worker 
TYPED_TEST(ParallelMoveTest,Pairs)280*795d594fSAndroid Build Coastguard Worker TYPED_TEST(ParallelMoveTest, Pairs) {
281*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
282*795d594fSAndroid Build Coastguard Worker   ArenaAllocator allocator(&pool);
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker   {
285*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
286*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
287*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
288*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(2),
289*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(4),
290*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
291*795d594fSAndroid Build Coastguard Worker         nullptr);
292*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
293*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
294*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
295*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
296*795d594fSAndroid Build Coastguard Worker         nullptr);
297*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
298*795d594fSAndroid Build Coastguard Worker     ASSERT_STREQ("(2 -> 4) (0,1 -> 2,3)", resolver.GetMessage().c_str());
299*795d594fSAndroid Build Coastguard Worker   }
300*795d594fSAndroid Build Coastguard Worker 
301*795d594fSAndroid Build Coastguard Worker   {
302*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
303*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
304*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
305*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
306*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
307*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
308*795d594fSAndroid Build Coastguard Worker         nullptr);
309*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
310*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(2),
311*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(4),
312*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
313*795d594fSAndroid Build Coastguard Worker         nullptr);
314*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
315*795d594fSAndroid Build Coastguard Worker     ASSERT_STREQ("(2 -> 4) (0,1 -> 2,3)", resolver.GetMessage().c_str());
316*795d594fSAndroid Build Coastguard Worker   }
317*795d594fSAndroid Build Coastguard Worker 
318*795d594fSAndroid Build Coastguard Worker   {
319*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
320*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
321*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
322*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
323*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
324*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
325*795d594fSAndroid Build Coastguard Worker         nullptr);
326*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
327*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(2),
328*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(0),
329*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
330*795d594fSAndroid Build Coastguard Worker         nullptr);
331*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
332*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
333*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0,1 <-> 2,3)", resolver.GetMessage().c_str());
334*795d594fSAndroid Build Coastguard Worker     } else {
335*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2 -> T0) (0,1 -> 2,3) (T0 -> 0)", resolver.GetMessage().c_str());
336*795d594fSAndroid Build Coastguard Worker     }
337*795d594fSAndroid Build Coastguard Worker   }
338*795d594fSAndroid Build Coastguard Worker   {
339*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
340*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
341*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
342*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(2),
343*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(7),
344*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
345*795d594fSAndroid Build Coastguard Worker         nullptr);
346*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
347*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(7),
348*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(1),
349*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
350*795d594fSAndroid Build Coastguard Worker         nullptr);
351*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
352*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
353*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
354*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
355*795d594fSAndroid Build Coastguard Worker         nullptr);
356*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
357*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
358*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0,1 <-> 2,3) (7 -> 1) (0 -> 7)", resolver.GetMessage().c_str());
359*795d594fSAndroid Build Coastguard Worker     } else {
360*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0,1 -> T0,T1) (7 -> 1) (2 -> 7) (T0,T1 -> 2,3)",
361*795d594fSAndroid Build Coastguard Worker           resolver.GetMessage().c_str());
362*795d594fSAndroid Build Coastguard Worker     }
363*795d594fSAndroid Build Coastguard Worker   }
364*795d594fSAndroid Build Coastguard Worker   {
365*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
366*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
367*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
368*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(2),
369*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(7),
370*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
371*795d594fSAndroid Build Coastguard Worker         nullptr);
372*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
373*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
374*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
375*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
376*795d594fSAndroid Build Coastguard Worker         nullptr);
377*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
378*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(7),
379*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(1),
380*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
381*795d594fSAndroid Build Coastguard Worker         nullptr);
382*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
383*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
384*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0,1 <-> 2,3) (7 -> 1) (0 -> 7)", resolver.GetMessage().c_str());
385*795d594fSAndroid Build Coastguard Worker     } else {
386*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0,1 -> T0,T1) (7 -> 1) (2 -> 7) (T0,T1 -> 2,3)",
387*795d594fSAndroid Build Coastguard Worker           resolver.GetMessage().c_str());
388*795d594fSAndroid Build Coastguard Worker     }
389*795d594fSAndroid Build Coastguard Worker   }
390*795d594fSAndroid Build Coastguard Worker   {
391*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
392*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
393*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
394*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
395*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
396*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
397*795d594fSAndroid Build Coastguard Worker         nullptr);
398*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
399*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(2),
400*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(7),
401*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
402*795d594fSAndroid Build Coastguard Worker         nullptr);
403*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
404*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(7),
405*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(1),
406*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
407*795d594fSAndroid Build Coastguard Worker         nullptr);
408*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
409*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
410*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0,1 <-> 2,3) (7 -> 1) (0 -> 7)", resolver.GetMessage().c_str());
411*795d594fSAndroid Build Coastguard Worker     } else {
412*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(7 -> T0) (2 -> 7) (0,1 -> 2,3) (T0 -> 1)", resolver.GetMessage().c_str());
413*795d594fSAndroid Build Coastguard Worker     }
414*795d594fSAndroid Build Coastguard Worker   }
415*795d594fSAndroid Build Coastguard Worker   {
416*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
417*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
418*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
419*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
420*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
421*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
422*795d594fSAndroid Build Coastguard Worker         nullptr);
423*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
424*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
425*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
426*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
427*795d594fSAndroid Build Coastguard Worker         nullptr);
428*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
429*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
430*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2,3 <-> 0,1)", resolver.GetMessage().c_str());
431*795d594fSAndroid Build Coastguard Worker     } else {
432*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2,3 -> T0,T1) (0,1 -> 2,3) (T0,T1 -> 0,1)", resolver.GetMessage().c_str());
433*795d594fSAndroid Build Coastguard Worker     }
434*795d594fSAndroid Build Coastguard Worker   }
435*795d594fSAndroid Build Coastguard Worker   {
436*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
437*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
438*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
439*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
440*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
441*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
442*795d594fSAndroid Build Coastguard Worker         nullptr);
443*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
444*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
445*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
446*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
447*795d594fSAndroid Build Coastguard Worker         nullptr);
448*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
449*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
450*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0,1 <-> 2,3)", resolver.GetMessage().c_str());
451*795d594fSAndroid Build Coastguard Worker     } else {
452*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0,1 -> T0,T1) (2,3 -> 0,1) (T0,T1 -> 2,3)", resolver.GetMessage().c_str());
453*795d594fSAndroid Build Coastguard Worker     }
454*795d594fSAndroid Build Coastguard Worker   }
455*795d594fSAndroid Build Coastguard Worker }
456*795d594fSAndroid Build Coastguard Worker 
TYPED_TEST(ParallelMoveTest,MultiCycles)457*795d594fSAndroid Build Coastguard Worker TYPED_TEST(ParallelMoveTest, MultiCycles) {
458*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
459*795d594fSAndroid Build Coastguard Worker   ArenaAllocator allocator(&pool);
460*795d594fSAndroid Build Coastguard Worker 
461*795d594fSAndroid Build Coastguard Worker   {
462*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
463*795d594fSAndroid Build Coastguard Worker     static constexpr size_t moves[][2] = {{0, 1}, {1, 0}, {2, 3}, {3, 2}};
464*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
465*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
466*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(1 <-> 0) (3 <-> 2)",  resolver.GetMessage().c_str());
467*795d594fSAndroid Build Coastguard Worker     } else {
468*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(1 -> T0) (0 -> 1) (T0 -> 0) (3 -> T0) (2 -> 3) (T0 -> 2)",
469*795d594fSAndroid Build Coastguard Worker           resolver.GetMessage().c_str());
470*795d594fSAndroid Build Coastguard Worker     }
471*795d594fSAndroid Build Coastguard Worker   }
472*795d594fSAndroid Build Coastguard Worker   {
473*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
474*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
475*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
476*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
477*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
478*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
479*795d594fSAndroid Build Coastguard Worker         nullptr);
480*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
481*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(2),
482*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(0),
483*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
484*795d594fSAndroid Build Coastguard Worker         nullptr);
485*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
486*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(3),
487*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(1),
488*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
489*795d594fSAndroid Build Coastguard Worker         nullptr);
490*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
491*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
492*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0,1 <-> 2,3)", resolver.GetMessage().c_str());
493*795d594fSAndroid Build Coastguard Worker     } else {
494*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2 -> T0) (3 -> T1) (0,1 -> 2,3) (T0 -> 0) (T1 -> 1)",
495*795d594fSAndroid Build Coastguard Worker           resolver.GetMessage().c_str());
496*795d594fSAndroid Build Coastguard Worker     }
497*795d594fSAndroid Build Coastguard Worker   }
498*795d594fSAndroid Build Coastguard Worker   {
499*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
500*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
501*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
502*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(2),
503*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(0),
504*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
505*795d594fSAndroid Build Coastguard Worker         nullptr);
506*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
507*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(3),
508*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(1),
509*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
510*795d594fSAndroid Build Coastguard Worker         nullptr);
511*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
512*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
513*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
514*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
515*795d594fSAndroid Build Coastguard Worker         nullptr);
516*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
517*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
518*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0,1 <-> 2,3)", resolver.GetMessage().c_str());
519*795d594fSAndroid Build Coastguard Worker     } else {
520*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(3 -> T0) (0,1 -> T2,T3) (T0 -> 1) (2 -> 0) (T2,T3 -> 2,3)",
521*795d594fSAndroid Build Coastguard Worker           resolver.GetMessage().c_str());
522*795d594fSAndroid Build Coastguard Worker     }
523*795d594fSAndroid Build Coastguard Worker   }
524*795d594fSAndroid Build Coastguard Worker 
525*795d594fSAndroid Build Coastguard Worker   {
526*795d594fSAndroid Build Coastguard Worker     // Test involving registers used in single context and pair context.
527*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
528*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
529*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
530*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(10),
531*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(5),
532*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
533*795d594fSAndroid Build Coastguard Worker         nullptr);
534*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
535*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(4, 5),
536*795d594fSAndroid Build Coastguard Worker         Location::DoubleStackSlot(32),
537*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
538*795d594fSAndroid Build Coastguard Worker         nullptr);
539*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
540*795d594fSAndroid Build Coastguard Worker         Location::DoubleStackSlot(32),
541*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(10, 11),
542*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
543*795d594fSAndroid Build Coastguard Worker         nullptr);
544*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
545*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
546*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2x32(sp) <-> 10,11) (4,5 <-> 2x32(sp)) (4 -> 5)", resolver.GetMessage().c_str());
547*795d594fSAndroid Build Coastguard Worker     } else {
548*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2x32(sp) -> T0,T1) (4,5 -> 2x32(sp)) (10 -> 5) (T0,T1 -> 10,11)",
549*795d594fSAndroid Build Coastguard Worker           resolver.GetMessage().c_str());
550*795d594fSAndroid Build Coastguard Worker     }
551*795d594fSAndroid Build Coastguard Worker   }
552*795d594fSAndroid Build Coastguard Worker }
553*795d594fSAndroid Build Coastguard Worker 
554*795d594fSAndroid Build Coastguard Worker // Test that we do 64bits moves before 32bits moves.
TYPED_TEST(ParallelMoveTest,CyclesWith64BitsMoves)555*795d594fSAndroid Build Coastguard Worker TYPED_TEST(ParallelMoveTest, CyclesWith64BitsMoves) {
556*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
557*795d594fSAndroid Build Coastguard Worker   ArenaAllocator allocator(&pool);
558*795d594fSAndroid Build Coastguard Worker 
559*795d594fSAndroid Build Coastguard Worker   {
560*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
561*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
562*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
563*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(0),
564*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(1),
565*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
566*795d594fSAndroid Build Coastguard Worker         nullptr);
567*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
568*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(1),
569*795d594fSAndroid Build Coastguard Worker         Location::StackSlot(48),
570*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
571*795d594fSAndroid Build Coastguard Worker         nullptr);
572*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
573*795d594fSAndroid Build Coastguard Worker         Location::StackSlot(48),
574*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(0),
575*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
576*795d594fSAndroid Build Coastguard Worker         nullptr);
577*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
578*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
579*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(0 <-> 1) (48(sp) <-> 0)", resolver.GetMessage().c_str());
580*795d594fSAndroid Build Coastguard Worker     } else {
581*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(48(sp) -> T0) (1 -> 48(sp)) (0 -> 1) (T0 -> 0)",
582*795d594fSAndroid Build Coastguard Worker           resolver.GetMessage().c_str());
583*795d594fSAndroid Build Coastguard Worker     }
584*795d594fSAndroid Build Coastguard Worker   }
585*795d594fSAndroid Build Coastguard Worker 
586*795d594fSAndroid Build Coastguard Worker   {
587*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
588*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
589*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
590*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
591*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
592*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
593*795d594fSAndroid Build Coastguard Worker         nullptr);
594*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
595*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
596*795d594fSAndroid Build Coastguard Worker         Location::DoubleStackSlot(32),
597*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
598*795d594fSAndroid Build Coastguard Worker         nullptr);
599*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
600*795d594fSAndroid Build Coastguard Worker         Location::DoubleStackSlot(32),
601*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
602*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
603*795d594fSAndroid Build Coastguard Worker         nullptr);
604*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
605*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
606*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2x32(sp) <-> 0,1) (2,3 <-> 2x32(sp))", resolver.GetMessage().c_str());
607*795d594fSAndroid Build Coastguard Worker     } else {
608*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2x32(sp) -> T0,T1) (2,3 -> 2x32(sp)) (0,1 -> 2,3) (T0,T1 -> 0,1)",
609*795d594fSAndroid Build Coastguard Worker           resolver.GetMessage().c_str());
610*795d594fSAndroid Build Coastguard Worker     }
611*795d594fSAndroid Build Coastguard Worker   }
612*795d594fSAndroid Build Coastguard Worker }
613*795d594fSAndroid Build Coastguard Worker 
TYPED_TEST(ParallelMoveTest,CyclesWith64BitsMoves2)614*795d594fSAndroid Build Coastguard Worker TYPED_TEST(ParallelMoveTest, CyclesWith64BitsMoves2) {
615*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
616*795d594fSAndroid Build Coastguard Worker   ArenaAllocator allocator(&pool);
617*795d594fSAndroid Build Coastguard Worker 
618*795d594fSAndroid Build Coastguard Worker   {
619*795d594fSAndroid Build Coastguard Worker     TypeParam resolver(&allocator);
620*795d594fSAndroid Build Coastguard Worker     HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
621*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
622*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(0),
623*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(3),
624*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
625*795d594fSAndroid Build Coastguard Worker         nullptr);
626*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
627*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(2, 3),
628*795d594fSAndroid Build Coastguard Worker         Location::RegisterPairLocation(0, 1),
629*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt64,
630*795d594fSAndroid Build Coastguard Worker         nullptr);
631*795d594fSAndroid Build Coastguard Worker     moves->AddMove(
632*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(7),
633*795d594fSAndroid Build Coastguard Worker         Location::RegisterLocation(2),
634*795d594fSAndroid Build Coastguard Worker         DataType::Type::kInt32,
635*795d594fSAndroid Build Coastguard Worker         nullptr);
636*795d594fSAndroid Build Coastguard Worker     resolver.EmitNativeCode(moves);
637*795d594fSAndroid Build Coastguard Worker     if (TestFixture::has_swap) {
638*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2,3 <-> 0,1) (2 -> 3) (7 -> 2)", resolver.GetMessage().c_str());
639*795d594fSAndroid Build Coastguard Worker     } else {
640*795d594fSAndroid Build Coastguard Worker       ASSERT_STREQ("(2,3 -> T0,T1) (0 -> 3) (T0,T1 -> 0,1) (7 -> 2)",
641*795d594fSAndroid Build Coastguard Worker           resolver.GetMessage().c_str());
642*795d594fSAndroid Build Coastguard Worker     }
643*795d594fSAndroid Build Coastguard Worker   }
644*795d594fSAndroid Build Coastguard Worker }
645*795d594fSAndroid Build Coastguard Worker 
646*795d594fSAndroid Build Coastguard Worker }  // namespace art
647