blob: b63914faf7f747ba3bc1514ea62e0fe6b2832365 [file] [log] [blame]
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +02001/*
2 * Copyright (C) 2016 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 "base/arena_allocator.h"
18#include "code_generator_mips.h"
19#include "optimizing_unit_test.h"
20#include "parallel_move_resolver.h"
21#include "utils/assembler_test_base.h"
22#include "utils/mips/assembler_mips.h"
23
24#include "gtest/gtest.h"
25
26namespace art {
27
Vladimir Markoca6fff82017-10-03 14:49:14 +010028class EmitSwapMipsTest : public OptimizingUnitTest {
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +020029 public:
30 void SetUp() OVERRIDE {
Vladimir Markoca6fff82017-10-03 14:49:14 +010031 graph_ = CreateGraph();
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +020032 isa_features_ = MipsInstructionSetFeatures::FromCppDefines();
Vladimir Markoca6fff82017-10-03 14:49:14 +010033 codegen_ = new (graph_->GetAllocator()) mips::CodeGeneratorMIPS(graph_,
34 *isa_features_.get(),
35 CompilerOptions());
36 moves_ = new (GetAllocator()) HParallelMove(GetAllocator());
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +020037 test_helper_.reset(
38 new AssemblerTestInfrastructure(GetArchitectureString(),
39 GetAssemblerCmdName(),
40 GetAssemblerParameters(),
41 GetObjdumpCmdName(),
42 GetObjdumpParameters(),
43 GetDisassembleCmdName(),
44 GetDisassembleParameters(),
45 GetAssemblyHeader()));
46 }
47
48 void TearDown() OVERRIDE {
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +020049 test_helper_.reset();
Vladimir Markoca6fff82017-10-03 14:49:14 +010050 isa_features_.reset();
51 ResetPoolAndAllocator();
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +020052 }
53
54 // Get the typically used name for this architecture.
55 std::string GetArchitectureString() {
56 return "mips";
57 }
58
59 // Get the name of the assembler.
60 std::string GetAssemblerCmdName() {
61 return "as";
62 }
63
64 // Switches to the assembler command.
65 std::string GetAssemblerParameters() {
66 return " --no-warn -32 -march=mips32r2";
67 }
68
69 // Get the name of the objdump.
70 std::string GetObjdumpCmdName() {
71 return "objdump";
72 }
73
74 // Switches to the objdump command.
75 std::string GetObjdumpParameters() {
76 return " -h";
77 }
78
79 // Get the name of the objdump.
80 std::string GetDisassembleCmdName() {
81 return "objdump";
82 }
83
84 // Switches to the objdump command.
85 std::string GetDisassembleParameters() {
86 return " -D -bbinary -mmips:isa32r2";
87 }
88
89 // No need for assembly header here.
90 const char* GetAssemblyHeader() {
91 return nullptr;
92 }
93
Andreas Gampe641a4732017-08-24 13:21:35 -070094 void DriverWrapper(HParallelMove* move,
95 const std::string& assembly_text,
96 const std::string& test_name) {
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +020097 codegen_->GetMoveResolver()->EmitNativeCode(move);
98 assembler_ = codegen_->GetAssembler();
99 assembler_->FinalizeCode();
100 std::unique_ptr<std::vector<uint8_t>> data(new std::vector<uint8_t>(assembler_->CodeSize()));
101 MemoryRegion code(&(*data)[0], data->size());
102 assembler_->FinalizeInstructions(code);
103 test_helper_->Driver(*data, assembly_text, test_name);
104 }
105
106 protected:
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200107 HGraph* graph_;
108 HParallelMove* moves_;
109 mips::CodeGeneratorMIPS* codegen_;
110 mips::MipsAssembler* assembler_;
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200111 std::unique_ptr<AssemblerTestInfrastructure> test_helper_;
112 std::unique_ptr<const MipsInstructionSetFeatures> isa_features_;
113};
114
115TEST_F(EmitSwapMipsTest, TwoRegisters) {
116 moves_->AddMove(
117 Location::RegisterLocation(4),
118 Location::RegisterLocation(5),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100119 DataType::Type::kInt32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200120 nullptr);
121 moves_->AddMove(
122 Location::RegisterLocation(5),
123 Location::RegisterLocation(4),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100124 DataType::Type::kInt32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200125 nullptr);
126 const char* expected =
127 "or $t8, $a1, $zero\n"
128 "or $a1, $a0, $zero\n"
129 "or $a0, $t8, $zero\n";
130 DriverWrapper(moves_, expected, "TwoRegisters");
131}
132
133TEST_F(EmitSwapMipsTest, TwoRegisterPairs) {
134 moves_->AddMove(
135 Location::RegisterPairLocation(4, 5),
136 Location::RegisterPairLocation(6, 7),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100137 DataType::Type::kInt64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200138 nullptr);
139 moves_->AddMove(
140 Location::RegisterPairLocation(6, 7),
141 Location::RegisterPairLocation(4, 5),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100142 DataType::Type::kInt64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200143 nullptr);
144 const char* expected =
145 "or $t8, $a2, $zero\n"
146 "or $a2, $a0, $zero\n"
147 "or $a0, $t8, $zero\n"
148 "or $t8, $a3, $zero\n"
149 "or $a3, $a1, $zero\n"
150 "or $a1, $t8, $zero\n";
151 DriverWrapper(moves_, expected, "TwoRegisterPairs");
152}
153
154TEST_F(EmitSwapMipsTest, TwoFpuRegistersFloat) {
155 moves_->AddMove(
156 Location::FpuRegisterLocation(4),
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800157 Location::FpuRegisterLocation(2),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100158 DataType::Type::kFloat32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200159 nullptr);
160 moves_->AddMove(
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800161 Location::FpuRegisterLocation(2),
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200162 Location::FpuRegisterLocation(4),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100163 DataType::Type::kFloat32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200164 nullptr);
165 const char* expected =
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800166 "mov.s $f6, $f2\n"
167 "mov.s $f2, $f4\n"
168 "mov.s $f4, $f6\n";
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200169 DriverWrapper(moves_, expected, "TwoFpuRegistersFloat");
170}
171
172TEST_F(EmitSwapMipsTest, TwoFpuRegistersDouble) {
173 moves_->AddMove(
174 Location::FpuRegisterLocation(4),
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800175 Location::FpuRegisterLocation(2),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100176 DataType::Type::kFloat64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200177 nullptr);
178 moves_->AddMove(
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800179 Location::FpuRegisterLocation(2),
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200180 Location::FpuRegisterLocation(4),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100181 DataType::Type::kFloat64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200182 nullptr);
183 const char* expected =
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800184 "mov.d $f6, $f2\n"
185 "mov.d $f2, $f4\n"
186 "mov.d $f4, $f6\n";
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200187 DriverWrapper(moves_, expected, "TwoFpuRegistersDouble");
188}
189
190TEST_F(EmitSwapMipsTest, RegisterAndFpuRegister) {
191 moves_->AddMove(
192 Location::RegisterLocation(4),
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800193 Location::FpuRegisterLocation(2),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100194 DataType::Type::kFloat32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200195 nullptr);
196 moves_->AddMove(
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800197 Location::FpuRegisterLocation(2),
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200198 Location::RegisterLocation(4),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100199 DataType::Type::kFloat32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200200 nullptr);
201 const char* expected =
202 "or $t8, $a0, $zero\n"
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800203 "mfc1 $a0, $f2\n"
204 "mtc1 $t8, $f2\n";
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200205 DriverWrapper(moves_, expected, "RegisterAndFpuRegister");
206}
207
208TEST_F(EmitSwapMipsTest, RegisterPairAndFpuRegister) {
209 moves_->AddMove(
210 Location::RegisterPairLocation(4, 5),
211 Location::FpuRegisterLocation(4),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100212 DataType::Type::kFloat64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200213 nullptr);
214 moves_->AddMove(
215 Location::FpuRegisterLocation(4),
216 Location::RegisterPairLocation(4, 5),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100217 DataType::Type::kFloat64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200218 nullptr);
219 const char* expected =
220 "mfc1 $t8, $f4\n"
221 "mfc1 $at, $f5\n"
222 "mtc1 $a0, $f4\n"
223 "mtc1 $a1, $f5\n"
224 "or $a0, $t8, $zero\n"
225 "or $a1, $at, $zero\n";
226 DriverWrapper(moves_, expected, "RegisterPairAndFpuRegister");
227}
228
229TEST_F(EmitSwapMipsTest, TwoStackSlots) {
230 moves_->AddMove(
231 Location::StackSlot(52),
232 Location::StackSlot(48),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100233 DataType::Type::kInt32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200234 nullptr);
235 moves_->AddMove(
236 Location::StackSlot(48),
237 Location::StackSlot(52),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100238 DataType::Type::kInt32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200239 nullptr);
240 const char* expected =
Chris Larsen715f43e2017-10-23 11:00:32 -0700241 "addiu $sp, $sp, -16\n"
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200242 "sw $v0, 0($sp)\n"
Chris Larsen715f43e2017-10-23 11:00:32 -0700243 "lw $v0, 68($sp)\n"
244 "lw $t8, 64($sp)\n"
245 "sw $v0, 64($sp)\n"
246 "sw $t8, 68($sp)\n"
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200247 "lw $v0, 0($sp)\n"
Chris Larsen715f43e2017-10-23 11:00:32 -0700248 "addiu $sp, $sp, 16\n";
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200249 DriverWrapper(moves_, expected, "TwoStackSlots");
250}
251
252TEST_F(EmitSwapMipsTest, TwoDoubleStackSlots) {
253 moves_->AddMove(
254 Location::DoubleStackSlot(56),
255 Location::DoubleStackSlot(48),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100256 DataType::Type::kInt64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200257 nullptr);
258 moves_->AddMove(
259 Location::DoubleStackSlot(48),
260 Location::DoubleStackSlot(56),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100261 DataType::Type::kInt64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200262 nullptr);
263 const char* expected =
Chris Larsen715f43e2017-10-23 11:00:32 -0700264 "addiu $sp, $sp, -16\n"
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200265 "sw $v0, 0($sp)\n"
Chris Larsen715f43e2017-10-23 11:00:32 -0700266 "lw $v0, 72($sp)\n"
267 "lw $t8, 64($sp)\n"
268 "sw $v0, 64($sp)\n"
269 "sw $t8, 72($sp)\n"
270 "lw $v0, 76($sp)\n"
271 "lw $t8, 68($sp)\n"
272 "sw $v0, 68($sp)\n"
273 "sw $t8, 76($sp)\n"
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200274 "lw $v0, 0($sp)\n"
Chris Larsen715f43e2017-10-23 11:00:32 -0700275 "addiu $sp, $sp, 16\n";
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200276 DriverWrapper(moves_, expected, "TwoDoubleStackSlots");
277}
278
279TEST_F(EmitSwapMipsTest, RegisterAndStackSlot) {
280 moves_->AddMove(
281 Location::RegisterLocation(4),
282 Location::StackSlot(48),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100283 DataType::Type::kInt32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200284 nullptr);
285 moves_->AddMove(
286 Location::StackSlot(48),
287 Location::RegisterLocation(4),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100288 DataType::Type::kInt32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200289 nullptr);
290 const char* expected =
291 "or $t8, $a0, $zero\n"
292 "lw $a0, 48($sp)\n"
293 "sw $t8, 48($sp)\n";
294 DriverWrapper(moves_, expected, "RegisterAndStackSlot");
295}
296
297TEST_F(EmitSwapMipsTest, RegisterPairAndDoubleStackSlot) {
298 moves_->AddMove(
299 Location::RegisterPairLocation(4, 5),
300 Location::DoubleStackSlot(32),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100301 DataType::Type::kInt64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200302 nullptr);
303 moves_->AddMove(
304 Location::DoubleStackSlot(32),
305 Location::RegisterPairLocation(4, 5),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100306 DataType::Type::kInt64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200307 nullptr);
308 const char* expected =
309 "or $t8, $a0, $zero\n"
310 "lw $a0, 32($sp)\n"
311 "sw $t8, 32($sp)\n"
312 "or $t8, $a1, $zero\n"
313 "lw $a1, 36($sp)\n"
314 "sw $t8, 36($sp)\n";
315 DriverWrapper(moves_, expected, "RegisterPairAndDoubleStackSlot");
316}
317
318TEST_F(EmitSwapMipsTest, FpuRegisterAndStackSlot) {
319 moves_->AddMove(
320 Location::FpuRegisterLocation(4),
321 Location::StackSlot(48),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100322 DataType::Type::kFloat32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200323 nullptr);
324 moves_->AddMove(
325 Location::StackSlot(48),
326 Location::FpuRegisterLocation(4),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100327 DataType::Type::kFloat32,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200328 nullptr);
329 const char* expected =
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800330 "mov.s $f6, $f4\n"
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200331 "lwc1 $f4, 48($sp)\n"
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800332 "swc1 $f6, 48($sp)\n";
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200333 DriverWrapper(moves_, expected, "FpuRegisterAndStackSlot");
334}
335
336TEST_F(EmitSwapMipsTest, FpuRegisterAndDoubleStackSlot) {
337 moves_->AddMove(
338 Location::FpuRegisterLocation(4),
339 Location::DoubleStackSlot(48),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100340 DataType::Type::kFloat64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200341 nullptr);
342 moves_->AddMove(
343 Location::DoubleStackSlot(48),
344 Location::FpuRegisterLocation(4),
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100345 DataType::Type::kFloat64,
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200346 nullptr);
347 const char* expected =
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800348 "mov.d $f6, $f4\n"
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200349 "ldc1 $f4, 48($sp)\n"
Alexey Frunze1b8464d2016-11-12 17:22:05 -0800350 "sdc1 $f6, 48($sp)\n";
Goran Jakovljevic35dfcaa2016-09-22 09:26:01 +0200351 DriverWrapper(moves_, expected, "FpuRegisterAndDoubleStackSlot");
352}
353
354} // namespace art