blob: 29a5a88316d3bf6b1c24aa20c5787b572ba58de2 [file] [log] [blame]
Chris Larsendbce0d72015-09-17 13:34:00 -07001/*
2 * Copyright (C) 2015 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 "assembler_mips64.h"
18
19#include <inttypes.h>
20#include <map>
21#include <random>
22
23#include "base/bit_utils.h"
24#include "base/stl_util.h"
25#include "utils/assembler_test.h"
26
Alexey Frunzea0e87b02015-09-24 22:57:20 -070027#define __ GetAssembler()->
28
Chris Larsendbce0d72015-09-17 13:34:00 -070029namespace art {
30
31struct MIPS64CpuRegisterCompare {
32 bool operator()(const mips64::GpuRegister& a, const mips64::GpuRegister& b) const {
33 return a < b;
34 }
35};
36
37class AssemblerMIPS64Test : public AssemblerTest<mips64::Mips64Assembler,
38 mips64::GpuRegister,
39 mips64::FpuRegister,
40 uint32_t> {
41 public:
42 typedef AssemblerTest<mips64::Mips64Assembler,
43 mips64::GpuRegister,
44 mips64::FpuRegister,
45 uint32_t> Base;
46
47 protected:
48 // Get the typically used name for this architecture, e.g., aarch64, x86-64, ...
49 std::string GetArchitectureString() OVERRIDE {
50 return "mips64";
51 }
52
Alexey Frunzea0e87b02015-09-24 22:57:20 -070053 std::string GetAssemblerCmdName() OVERRIDE {
54 // We assemble and link for MIPS64R6. See GetAssemblerParameters() for details.
55 return "gcc";
56 }
57
Chris Larsendbce0d72015-09-17 13:34:00 -070058 std::string GetAssemblerParameters() OVERRIDE {
Alexey Frunzea0e87b02015-09-24 22:57:20 -070059 // We assemble and link for MIPS64R6. The reason is that object files produced for MIPS64R6
60 // (and MIPS32R6) with the GNU assembler don't have correct final offsets in PC-relative
61 // branches in the .text section and so they require a relocation pass (there's a relocation
62 // section, .rela.text, that has the needed info to fix up the branches).
63 return " -march=mips64r6 -Wa,--no-warn -Wl,-Ttext=0 -Wl,-e0 -nostdlib";
64 }
65
66 void Pad(std::vector<uint8_t>& data) OVERRIDE {
67 // The GNU linker unconditionally pads the code segment with NOPs to a size that is a multiple
68 // of 16 and there doesn't appear to be a way to suppress this padding. Our assembler doesn't
69 // pad, so, in order for two assembler outputs to match, we need to match the padding as well.
70 // NOP is encoded as four zero bytes on MIPS.
71 size_t pad_size = RoundUp(data.size(), 16u) - data.size();
72 data.insert(data.end(), pad_size, 0);
Chris Larsendbce0d72015-09-17 13:34:00 -070073 }
74
75 std::string GetDisassembleParameters() OVERRIDE {
76 return " -D -bbinary -mmips:isa64r6";
77 }
78
79 void SetUpHelpers() OVERRIDE {
80 if (registers_.size() == 0) {
81 registers_.push_back(new mips64::GpuRegister(mips64::ZERO));
82 registers_.push_back(new mips64::GpuRegister(mips64::AT));
83 registers_.push_back(new mips64::GpuRegister(mips64::V0));
84 registers_.push_back(new mips64::GpuRegister(mips64::V1));
85 registers_.push_back(new mips64::GpuRegister(mips64::A0));
86 registers_.push_back(new mips64::GpuRegister(mips64::A1));
87 registers_.push_back(new mips64::GpuRegister(mips64::A2));
88 registers_.push_back(new mips64::GpuRegister(mips64::A3));
89 registers_.push_back(new mips64::GpuRegister(mips64::A4));
90 registers_.push_back(new mips64::GpuRegister(mips64::A5));
91 registers_.push_back(new mips64::GpuRegister(mips64::A6));
92 registers_.push_back(new mips64::GpuRegister(mips64::A7));
93 registers_.push_back(new mips64::GpuRegister(mips64::T0));
94 registers_.push_back(new mips64::GpuRegister(mips64::T1));
95 registers_.push_back(new mips64::GpuRegister(mips64::T2));
96 registers_.push_back(new mips64::GpuRegister(mips64::T3));
97 registers_.push_back(new mips64::GpuRegister(mips64::S0));
98 registers_.push_back(new mips64::GpuRegister(mips64::S1));
99 registers_.push_back(new mips64::GpuRegister(mips64::S2));
100 registers_.push_back(new mips64::GpuRegister(mips64::S3));
101 registers_.push_back(new mips64::GpuRegister(mips64::S4));
102 registers_.push_back(new mips64::GpuRegister(mips64::S5));
103 registers_.push_back(new mips64::GpuRegister(mips64::S6));
104 registers_.push_back(new mips64::GpuRegister(mips64::S7));
105 registers_.push_back(new mips64::GpuRegister(mips64::T8));
106 registers_.push_back(new mips64::GpuRegister(mips64::T9));
107 registers_.push_back(new mips64::GpuRegister(mips64::K0));
108 registers_.push_back(new mips64::GpuRegister(mips64::K1));
109 registers_.push_back(new mips64::GpuRegister(mips64::GP));
110 registers_.push_back(new mips64::GpuRegister(mips64::SP));
111 registers_.push_back(new mips64::GpuRegister(mips64::S8));
112 registers_.push_back(new mips64::GpuRegister(mips64::RA));
113
114 secondary_register_names_.emplace(mips64::GpuRegister(mips64::ZERO), "zero");
115 secondary_register_names_.emplace(mips64::GpuRegister(mips64::AT), "at");
116 secondary_register_names_.emplace(mips64::GpuRegister(mips64::V0), "v0");
117 secondary_register_names_.emplace(mips64::GpuRegister(mips64::V1), "v1");
118 secondary_register_names_.emplace(mips64::GpuRegister(mips64::A0), "a0");
119 secondary_register_names_.emplace(mips64::GpuRegister(mips64::A1), "a1");
120 secondary_register_names_.emplace(mips64::GpuRegister(mips64::A2), "a2");
121 secondary_register_names_.emplace(mips64::GpuRegister(mips64::A3), "a3");
122 secondary_register_names_.emplace(mips64::GpuRegister(mips64::A4), "a4");
123 secondary_register_names_.emplace(mips64::GpuRegister(mips64::A5), "a5");
124 secondary_register_names_.emplace(mips64::GpuRegister(mips64::A6), "a6");
125 secondary_register_names_.emplace(mips64::GpuRegister(mips64::A7), "a7");
126 secondary_register_names_.emplace(mips64::GpuRegister(mips64::T0), "t0");
127 secondary_register_names_.emplace(mips64::GpuRegister(mips64::T1), "t1");
128 secondary_register_names_.emplace(mips64::GpuRegister(mips64::T2), "t2");
129 secondary_register_names_.emplace(mips64::GpuRegister(mips64::T3), "t3");
130 secondary_register_names_.emplace(mips64::GpuRegister(mips64::S0), "s0");
131 secondary_register_names_.emplace(mips64::GpuRegister(mips64::S1), "s1");
132 secondary_register_names_.emplace(mips64::GpuRegister(mips64::S2), "s2");
133 secondary_register_names_.emplace(mips64::GpuRegister(mips64::S3), "s3");
134 secondary_register_names_.emplace(mips64::GpuRegister(mips64::S4), "s4");
135 secondary_register_names_.emplace(mips64::GpuRegister(mips64::S5), "s5");
136 secondary_register_names_.emplace(mips64::GpuRegister(mips64::S6), "s6");
137 secondary_register_names_.emplace(mips64::GpuRegister(mips64::S7), "s7");
138 secondary_register_names_.emplace(mips64::GpuRegister(mips64::T8), "t8");
139 secondary_register_names_.emplace(mips64::GpuRegister(mips64::T9), "t9");
140 secondary_register_names_.emplace(mips64::GpuRegister(mips64::K0), "k0");
141 secondary_register_names_.emplace(mips64::GpuRegister(mips64::K1), "k1");
142 secondary_register_names_.emplace(mips64::GpuRegister(mips64::GP), "gp");
143 secondary_register_names_.emplace(mips64::GpuRegister(mips64::SP), "sp");
144 secondary_register_names_.emplace(mips64::GpuRegister(mips64::S8), "s8");
145 secondary_register_names_.emplace(mips64::GpuRegister(mips64::RA), "ra");
146
147 fp_registers_.push_back(new mips64::FpuRegister(mips64::F0));
148 fp_registers_.push_back(new mips64::FpuRegister(mips64::F1));
149 fp_registers_.push_back(new mips64::FpuRegister(mips64::F2));
150 fp_registers_.push_back(new mips64::FpuRegister(mips64::F3));
151 fp_registers_.push_back(new mips64::FpuRegister(mips64::F4));
152 fp_registers_.push_back(new mips64::FpuRegister(mips64::F5));
153 fp_registers_.push_back(new mips64::FpuRegister(mips64::F6));
154 fp_registers_.push_back(new mips64::FpuRegister(mips64::F7));
155 fp_registers_.push_back(new mips64::FpuRegister(mips64::F8));
156 fp_registers_.push_back(new mips64::FpuRegister(mips64::F9));
157 fp_registers_.push_back(new mips64::FpuRegister(mips64::F10));
158 fp_registers_.push_back(new mips64::FpuRegister(mips64::F11));
159 fp_registers_.push_back(new mips64::FpuRegister(mips64::F12));
160 fp_registers_.push_back(new mips64::FpuRegister(mips64::F13));
161 fp_registers_.push_back(new mips64::FpuRegister(mips64::F14));
162 fp_registers_.push_back(new mips64::FpuRegister(mips64::F15));
163 fp_registers_.push_back(new mips64::FpuRegister(mips64::F16));
164 fp_registers_.push_back(new mips64::FpuRegister(mips64::F17));
165 fp_registers_.push_back(new mips64::FpuRegister(mips64::F18));
166 fp_registers_.push_back(new mips64::FpuRegister(mips64::F19));
167 fp_registers_.push_back(new mips64::FpuRegister(mips64::F20));
168 fp_registers_.push_back(new mips64::FpuRegister(mips64::F21));
169 fp_registers_.push_back(new mips64::FpuRegister(mips64::F22));
170 fp_registers_.push_back(new mips64::FpuRegister(mips64::F23));
171 fp_registers_.push_back(new mips64::FpuRegister(mips64::F24));
172 fp_registers_.push_back(new mips64::FpuRegister(mips64::F25));
173 fp_registers_.push_back(new mips64::FpuRegister(mips64::F26));
174 fp_registers_.push_back(new mips64::FpuRegister(mips64::F27));
175 fp_registers_.push_back(new mips64::FpuRegister(mips64::F28));
176 fp_registers_.push_back(new mips64::FpuRegister(mips64::F29));
177 fp_registers_.push_back(new mips64::FpuRegister(mips64::F30));
178 fp_registers_.push_back(new mips64::FpuRegister(mips64::F31));
179 }
180 }
181
182 void TearDown() OVERRIDE {
183 AssemblerTest::TearDown();
184 STLDeleteElements(&registers_);
185 STLDeleteElements(&fp_registers_);
186 }
187
188 std::vector<mips64::GpuRegister*> GetRegisters() OVERRIDE {
189 return registers_;
190 }
191
192 std::vector<mips64::FpuRegister*> GetFPRegisters() OVERRIDE {
193 return fp_registers_;
194 }
195
196 uint32_t CreateImmediate(int64_t imm_value) OVERRIDE {
197 return imm_value;
198 }
199
200 std::string GetSecondaryRegisterName(const mips64::GpuRegister& reg) OVERRIDE {
201 CHECK(secondary_register_names_.find(reg) != secondary_register_names_.end());
202 return secondary_register_names_[reg];
203 }
204
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700205 std::string RepeatInsn(size_t count, const std::string& insn) {
206 std::string result;
207 for (; count != 0u; --count) {
208 result += insn;
209 }
210 return result;
211 }
212
213 void BranchCondOneRegHelper(void (mips64::Mips64Assembler::*f)(mips64::GpuRegister,
214 mips64::Mips64Label*),
215 std::string instr_name) {
216 mips64::Mips64Label label;
217 (Base::GetAssembler()->*f)(mips64::A0, &label);
218 constexpr size_t kAdduCount1 = 63;
219 for (size_t i = 0; i != kAdduCount1; ++i) {
220 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
221 }
222 __ Bind(&label);
223 constexpr size_t kAdduCount2 = 64;
224 for (size_t i = 0; i != kAdduCount2; ++i) {
225 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
226 }
227 (Base::GetAssembler()->*f)(mips64::A1, &label);
228
229 std::string expected =
230 ".set noreorder\n" +
231 instr_name + " $a0, 1f\n"
232 "nop\n" +
233 RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
234 "1:\n" +
235 RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
236 instr_name + " $a1, 1b\n"
237 "nop\n";
238 DriverStr(expected, instr_name);
239 }
240
241 void BranchCondTwoRegsHelper(void (mips64::Mips64Assembler::*f)(mips64::GpuRegister,
242 mips64::GpuRegister,
243 mips64::Mips64Label*),
244 std::string instr_name) {
245 mips64::Mips64Label label;
246 (Base::GetAssembler()->*f)(mips64::A0, mips64::A1, &label);
247 constexpr size_t kAdduCount1 = 63;
248 for (size_t i = 0; i != kAdduCount1; ++i) {
249 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
250 }
251 __ Bind(&label);
252 constexpr size_t kAdduCount2 = 64;
253 for (size_t i = 0; i != kAdduCount2; ++i) {
254 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
255 }
256 (Base::GetAssembler()->*f)(mips64::A2, mips64::A3, &label);
257
258 std::string expected =
259 ".set noreorder\n" +
260 instr_name + " $a0, $a1, 1f\n"
261 "nop\n" +
262 RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
263 "1:\n" +
264 RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
265 instr_name + " $a2, $a3, 1b\n"
266 "nop\n";
267 DriverStr(expected, instr_name);
268 }
269
Chris Larsendbce0d72015-09-17 13:34:00 -0700270 private:
271 std::vector<mips64::GpuRegister*> registers_;
272 std::map<mips64::GpuRegister, std::string, MIPS64CpuRegisterCompare> secondary_register_names_;
273
274 std::vector<mips64::FpuRegister*> fp_registers_;
275};
276
277
278TEST_F(AssemblerMIPS64Test, Toolchain) {
279 EXPECT_TRUE(CheckTools());
280}
281
Chris Larsendbce0d72015-09-17 13:34:00 -0700282///////////////////
283// FP Operations //
284///////////////////
285
286TEST_F(AssemblerMIPS64Test, SqrtS) {
287 DriverStr(RepeatFF(&mips64::Mips64Assembler::SqrtS, "sqrt.s ${reg1}, ${reg2}"), "sqrt.s");
288}
289
290TEST_F(AssemblerMIPS64Test, SqrtD) {
291 DriverStr(RepeatFF(&mips64::Mips64Assembler::SqrtD, "sqrt.d ${reg1}, ${reg2}"), "sqrt.d");
292}
293
294TEST_F(AssemblerMIPS64Test, AbsS) {
295 DriverStr(RepeatFF(&mips64::Mips64Assembler::AbsS, "abs.s ${reg1}, ${reg2}"), "abs.s");
296}
297
298TEST_F(AssemblerMIPS64Test, AbsD) {
299 DriverStr(RepeatFF(&mips64::Mips64Assembler::AbsD, "abs.d ${reg1}, ${reg2}"), "abs.d");
300}
301
Chris Larsen51417632015-10-02 13:24:25 -0700302TEST_F(AssemblerMIPS64Test, MovS) {
303 DriverStr(RepeatFF(&mips64::Mips64Assembler::MovS, "mov.s ${reg1}, ${reg2}"), "mov.s");
304}
305
306TEST_F(AssemblerMIPS64Test, MovD) {
307 DriverStr(RepeatFF(&mips64::Mips64Assembler::MovD, "mov.d ${reg1}, ${reg2}"), "mov.d");
308}
309
310TEST_F(AssemblerMIPS64Test, NegS) {
311 DriverStr(RepeatFF(&mips64::Mips64Assembler::NegS, "neg.s ${reg1}, ${reg2}"), "neg.s");
312}
313
314TEST_F(AssemblerMIPS64Test, NegD) {
315 DriverStr(RepeatFF(&mips64::Mips64Assembler::NegD, "neg.d ${reg1}, ${reg2}"), "neg.d");
316}
317
Chris Larsendbce0d72015-09-17 13:34:00 -0700318TEST_F(AssemblerMIPS64Test, RoundLS) {
319 DriverStr(RepeatFF(&mips64::Mips64Assembler::RoundLS, "round.l.s ${reg1}, ${reg2}"), "round.l.s");
320}
321
322TEST_F(AssemblerMIPS64Test, RoundLD) {
323 DriverStr(RepeatFF(&mips64::Mips64Assembler::RoundLD, "round.l.d ${reg1}, ${reg2}"), "round.l.d");
324}
325
326TEST_F(AssemblerMIPS64Test, RoundWS) {
327 DriverStr(RepeatFF(&mips64::Mips64Assembler::RoundWS, "round.w.s ${reg1}, ${reg2}"), "round.w.s");
328}
329
330TEST_F(AssemblerMIPS64Test, RoundWD) {
331 DriverStr(RepeatFF(&mips64::Mips64Assembler::RoundWD, "round.w.d ${reg1}, ${reg2}"), "round.w.d");
332}
333
334TEST_F(AssemblerMIPS64Test, CeilLS) {
335 DriverStr(RepeatFF(&mips64::Mips64Assembler::CeilLS, "ceil.l.s ${reg1}, ${reg2}"), "ceil.l.s");
336}
337
338TEST_F(AssemblerMIPS64Test, CeilLD) {
339 DriverStr(RepeatFF(&mips64::Mips64Assembler::CeilLD, "ceil.l.d ${reg1}, ${reg2}"), "ceil.l.d");
340}
341
342TEST_F(AssemblerMIPS64Test, CeilWS) {
343 DriverStr(RepeatFF(&mips64::Mips64Assembler::CeilWS, "ceil.w.s ${reg1}, ${reg2}"), "ceil.w.s");
344}
345
346TEST_F(AssemblerMIPS64Test, CeilWD) {
347 DriverStr(RepeatFF(&mips64::Mips64Assembler::CeilWD, "ceil.w.d ${reg1}, ${reg2}"), "ceil.w.d");
348}
349
350TEST_F(AssemblerMIPS64Test, FloorLS) {
351 DriverStr(RepeatFF(&mips64::Mips64Assembler::FloorLS, "floor.l.s ${reg1}, ${reg2}"), "floor.l.s");
352}
353
354TEST_F(AssemblerMIPS64Test, FloorLD) {
355 DriverStr(RepeatFF(&mips64::Mips64Assembler::FloorLD, "floor.l.d ${reg1}, ${reg2}"), "floor.l.d");
356}
357
358TEST_F(AssemblerMIPS64Test, FloorWS) {
359 DriverStr(RepeatFF(&mips64::Mips64Assembler::FloorWS, "floor.w.s ${reg1}, ${reg2}"), "floor.w.s");
360}
361
362TEST_F(AssemblerMIPS64Test, FloorWD) {
363 DriverStr(RepeatFF(&mips64::Mips64Assembler::FloorWD, "floor.w.d ${reg1}, ${reg2}"), "floor.w.d");
364}
365
366TEST_F(AssemblerMIPS64Test, SelS) {
367 DriverStr(RepeatFFF(&mips64::Mips64Assembler::SelS, "sel.s ${reg1}, ${reg2}, ${reg3}"), "sel.s");
368}
369
370TEST_F(AssemblerMIPS64Test, SelD) {
371 DriverStr(RepeatFFF(&mips64::Mips64Assembler::SelD, "sel.d ${reg1}, ${reg2}, ${reg3}"), "sel.d");
372}
373
374TEST_F(AssemblerMIPS64Test, RintS) {
375 DriverStr(RepeatFF(&mips64::Mips64Assembler::RintS, "rint.s ${reg1}, ${reg2}"), "rint.s");
376}
377
378TEST_F(AssemblerMIPS64Test, RintD) {
379 DriverStr(RepeatFF(&mips64::Mips64Assembler::RintD, "rint.d ${reg1}, ${reg2}"), "rint.d");
380}
381
382TEST_F(AssemblerMIPS64Test, ClassS) {
383 DriverStr(RepeatFF(&mips64::Mips64Assembler::ClassS, "class.s ${reg1}, ${reg2}"), "class.s");
384}
385
386TEST_F(AssemblerMIPS64Test, ClassD) {
387 DriverStr(RepeatFF(&mips64::Mips64Assembler::ClassD, "class.d ${reg1}, ${reg2}"), "class.d");
388}
389
390TEST_F(AssemblerMIPS64Test, MinS) {
391 DriverStr(RepeatFFF(&mips64::Mips64Assembler::MinS, "min.s ${reg1}, ${reg2}, ${reg3}"), "min.s");
392}
393
394TEST_F(AssemblerMIPS64Test, MinD) {
395 DriverStr(RepeatFFF(&mips64::Mips64Assembler::MinD, "min.d ${reg1}, ${reg2}, ${reg3}"), "min.d");
396}
397
398TEST_F(AssemblerMIPS64Test, MaxS) {
399 DriverStr(RepeatFFF(&mips64::Mips64Assembler::MaxS, "max.s ${reg1}, ${reg2}, ${reg3}"), "max.s");
400}
401
402TEST_F(AssemblerMIPS64Test, MaxD) {
403 DriverStr(RepeatFFF(&mips64::Mips64Assembler::MaxD, "max.d ${reg1}, ${reg2}, ${reg3}"), "max.d");
404}
405
406TEST_F(AssemblerMIPS64Test, CvtDL) {
407 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtdl, "cvt.d.l ${reg1}, ${reg2}"), "cvt.d.l");
408}
409
Chris Larsen51417632015-10-02 13:24:25 -0700410TEST_F(AssemblerMIPS64Test, CvtDS) {
411 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtds, "cvt.d.s ${reg1}, ${reg2}"), "cvt.d.s");
412}
413
414TEST_F(AssemblerMIPS64Test, CvtDW) {
415 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtdw, "cvt.d.w ${reg1}, ${reg2}"), "cvt.d.w");
416}
417
418TEST_F(AssemblerMIPS64Test, CvtSL) {
419 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtsl, "cvt.s.l ${reg1}, ${reg2}"), "cvt.s.l");
420}
421
422TEST_F(AssemblerMIPS64Test, CvtSD) {
423 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtsd, "cvt.s.d ${reg1}, ${reg2}"), "cvt.s.d");
424}
425
426TEST_F(AssemblerMIPS64Test, CvtSW) {
427 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtsw, "cvt.s.w ${reg1}, ${reg2}"), "cvt.s.w");
428}
429
430////////////////
431// CALL / JMP //
432////////////////
433
434TEST_F(AssemblerMIPS64Test, Jalr) {
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700435 DriverStr(".set noreorder\n" +
436 RepeatRRNoDupes(&mips64::Mips64Assembler::Jalr, "jalr ${reg1}, ${reg2}"), "jalr");
437}
438
439TEST_F(AssemblerMIPS64Test, Jialc) {
440 mips64::Mips64Label label1, label2;
441 __ Jialc(&label1, mips64::T9);
442 constexpr size_t kAdduCount1 = 63;
443 for (size_t i = 0; i != kAdduCount1; ++i) {
444 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
445 }
446 __ Bind(&label1);
447 __ Jialc(&label2, mips64::T9);
448 constexpr size_t kAdduCount2 = 64;
449 for (size_t i = 0; i != kAdduCount2; ++i) {
450 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
451 }
452 __ Bind(&label2);
453 __ Jialc(&label1, mips64::T9);
454
455 std::string expected =
456 ".set noreorder\n"
457 "lapc $t9, 1f\n"
458 "jialc $t9, 0\n" +
459 RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
460 "1:\n"
461 "lapc $t9, 2f\n"
462 "jialc $t9, 0\n" +
463 RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
464 "2:\n"
465 "lapc $t9, 1b\n"
466 "jialc $t9, 0\n";
467 DriverStr(expected, "Jialc");
468}
469
470TEST_F(AssemblerMIPS64Test, LongJialc) {
471 mips64::Mips64Label label1, label2;
472 __ Jialc(&label1, mips64::T9);
473 constexpr uint32_t kAdduCount1 = (1u << 18) + 1;
474 for (uint32_t i = 0; i != kAdduCount1; ++i) {
475 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
476 }
477 __ Bind(&label1);
478 __ Jialc(&label2, mips64::T9);
479 constexpr uint32_t kAdduCount2 = (1u << 18) + 1;
480 for (uint32_t i = 0; i != kAdduCount2; ++i) {
481 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
482 }
483 __ Bind(&label2);
484 __ Jialc(&label1, mips64::T9);
485
486 uint32_t offset_forward1 = 3 + kAdduCount1; // 3: account for auipc, daddiu and jic.
487 offset_forward1 <<= 2;
488 offset_forward1 += (offset_forward1 & 0x8000) << 1; // Account for sign extension in daddiu.
489
490 uint32_t offset_forward2 = 3 + kAdduCount2; // 3: account for auipc, daddiu and jic.
491 offset_forward2 <<= 2;
492 offset_forward2 += (offset_forward2 & 0x8000) << 1; // Account for sign extension in daddiu.
493
494 uint32_t offset_back = -(3 + kAdduCount2); // 3: account for auipc, daddiu and jic.
495 offset_back <<= 2;
496 offset_back += (offset_back & 0x8000) << 1; // Account for sign extension in daddiu.
497
498 std::ostringstream oss;
499 oss <<
500 ".set noreorder\n"
501 "auipc $t9, 0x" << std::hex << High16Bits(offset_forward1) << "\n"
502 "daddiu $t9, 0x" << std::hex << Low16Bits(offset_forward1) << "\n"
503 "jialc $t9, 0\n" <<
504 RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") <<
505 "1:\n"
506 "auipc $t9, 0x" << std::hex << High16Bits(offset_forward2) << "\n"
507 "daddiu $t9, 0x" << std::hex << Low16Bits(offset_forward2) << "\n"
508 "jialc $t9, 0\n" <<
509 RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") <<
510 "2:\n"
511 "auipc $t9, 0x" << std::hex << High16Bits(offset_back) << "\n"
512 "daddiu $t9, 0x" << std::hex << Low16Bits(offset_back) << "\n"
513 "jialc $t9, 0\n";
514 std::string expected = oss.str();
515 DriverStr(expected, "LongJialc");
516}
517
518TEST_F(AssemblerMIPS64Test, Bc) {
519 mips64::Mips64Label label1, label2;
520 __ Bc(&label1);
521 constexpr size_t kAdduCount1 = 63;
522 for (size_t i = 0; i != kAdduCount1; ++i) {
523 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
524 }
525 __ Bind(&label1);
526 __ Bc(&label2);
527 constexpr size_t kAdduCount2 = 64;
528 for (size_t i = 0; i != kAdduCount2; ++i) {
529 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
530 }
531 __ Bind(&label2);
532 __ Bc(&label1);
533
534 std::string expected =
535 ".set noreorder\n"
536 "bc 1f\n" +
537 RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
538 "1:\n"
539 "bc 2f\n" +
540 RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
541 "2:\n"
542 "bc 1b\n";
543 DriverStr(expected, "Bc");
544}
545
546TEST_F(AssemblerMIPS64Test, Beqzc) {
547 BranchCondOneRegHelper(&mips64::Mips64Assembler::Beqzc, "Beqzc");
548}
549
550TEST_F(AssemblerMIPS64Test, Bnezc) {
551 BranchCondOneRegHelper(&mips64::Mips64Assembler::Bnezc, "Bnezc");
552}
553
554TEST_F(AssemblerMIPS64Test, Bltzc) {
555 BranchCondOneRegHelper(&mips64::Mips64Assembler::Bltzc, "Bltzc");
556}
557
558TEST_F(AssemblerMIPS64Test, Bgezc) {
559 BranchCondOneRegHelper(&mips64::Mips64Assembler::Bgezc, "Bgezc");
560}
561
562TEST_F(AssemblerMIPS64Test, Blezc) {
563 BranchCondOneRegHelper(&mips64::Mips64Assembler::Blezc, "Blezc");
564}
565
566TEST_F(AssemblerMIPS64Test, Bgtzc) {
567 BranchCondOneRegHelper(&mips64::Mips64Assembler::Bgtzc, "Bgtzc");
568}
569
570TEST_F(AssemblerMIPS64Test, Beqc) {
571 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Beqc, "Beqc");
572}
573
574TEST_F(AssemblerMIPS64Test, Bnec) {
575 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bnec, "Bnec");
576}
577
578TEST_F(AssemblerMIPS64Test, Bltc) {
579 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bltc, "Bltc");
580}
581
582TEST_F(AssemblerMIPS64Test, Bgec) {
583 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bgec, "Bgec");
584}
585
586TEST_F(AssemblerMIPS64Test, Bltuc) {
587 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bltuc, "Bltuc");
588}
589
590TEST_F(AssemblerMIPS64Test, Bgeuc) {
591 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bgeuc, "Bgeuc");
592}
593
594TEST_F(AssemblerMIPS64Test, LongBeqc) {
595 mips64::Mips64Label label;
596 __ Beqc(mips64::A0, mips64::A1, &label);
597 constexpr uint32_t kAdduCount1 = (1u << 15) + 1;
598 for (uint32_t i = 0; i != kAdduCount1; ++i) {
599 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
600 }
601 __ Bind(&label);
602 constexpr uint32_t kAdduCount2 = (1u << 15) + 1;
603 for (uint32_t i = 0; i != kAdduCount2; ++i) {
604 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
605 }
606 __ Beqc(mips64::A2, mips64::A3, &label);
607
608 uint32_t offset_forward = 2 + kAdduCount1; // 2: account for auipc and jic.
609 offset_forward <<= 2;
610 offset_forward += (offset_forward & 0x8000) << 1; // Account for sign extension in jic.
611
612 uint32_t offset_back = -(kAdduCount2 + 1); // 1: account for bnec.
613 offset_back <<= 2;
614 offset_back += (offset_back & 0x8000) << 1; // Account for sign extension in jic.
615
616 std::ostringstream oss;
617 oss <<
618 ".set noreorder\n"
619 "bnec $a0, $a1, 1f\n"
620 "auipc $at, 0x" << std::hex << High16Bits(offset_forward) << "\n"
621 "jic $at, 0x" << std::hex << Low16Bits(offset_forward) << "\n"
622 "1:\n" <<
623 RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") <<
624 "2:\n" <<
625 RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") <<
626 "bnec $a2, $a3, 3f\n"
627 "auipc $at, 0x" << std::hex << High16Bits(offset_back) << "\n"
628 "jic $at, 0x" << std::hex << Low16Bits(offset_back) << "\n"
629 "3:\n";
630 std::string expected = oss.str();
631 DriverStr(expected, "LongBeqc");
Chris Larsen51417632015-10-02 13:24:25 -0700632}
633
Chris Larsendbce0d72015-09-17 13:34:00 -0700634//////////
635// MISC //
636//////////
637
638TEST_F(AssemblerMIPS64Test, Bitswap) {
639 DriverStr(RepeatRR(&mips64::Mips64Assembler::Bitswap, "bitswap ${reg1}, ${reg2}"), "bitswap");
640}
641
642TEST_F(AssemblerMIPS64Test, Dbitswap) {
643 DriverStr(RepeatRR(&mips64::Mips64Assembler::Dbitswap, "dbitswap ${reg1}, ${reg2}"), "dbitswap");
644}
645
Chris Larsen51417632015-10-02 13:24:25 -0700646TEST_F(AssemblerMIPS64Test, Seb) {
647 DriverStr(RepeatRR(&mips64::Mips64Assembler::Seb, "seb ${reg1}, ${reg2}"), "seb");
648}
649
650TEST_F(AssemblerMIPS64Test, Seh) {
651 DriverStr(RepeatRR(&mips64::Mips64Assembler::Seh, "seh ${reg1}, ${reg2}"), "seh");
652}
653
Chris Larsendbce0d72015-09-17 13:34:00 -0700654TEST_F(AssemblerMIPS64Test, Dsbh) {
655 DriverStr(RepeatRR(&mips64::Mips64Assembler::Dsbh, "dsbh ${reg1}, ${reg2}"), "dsbh");
656}
657
658TEST_F(AssemblerMIPS64Test, Dshd) {
659 DriverStr(RepeatRR(&mips64::Mips64Assembler::Dshd, "dshd ${reg1}, ${reg2}"), "dshd");
660}
661
662TEST_F(AssemblerMIPS64Test, Wsbh) {
663 DriverStr(RepeatRR(&mips64::Mips64Assembler::Wsbh, "wsbh ${reg1}, ${reg2}"), "wsbh");
664}
665
Chris Larsen51417632015-10-02 13:24:25 -0700666TEST_F(AssemblerMIPS64Test, Sll) {
667 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sll, 5, "sll ${reg1}, ${reg2}, {imm}"), "sll");
668}
669
670TEST_F(AssemblerMIPS64Test, Srl) {
671 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Srl, 5, "srl ${reg1}, ${reg2}, {imm}"), "srl");
672}
673
Chris Larsen98a73e12015-10-19 14:17:16 -0700674TEST_F(AssemblerMIPS64Test, Rotr) {
675 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Rotr, 5, "rotr ${reg1}, ${reg2}, {imm}"), "rotr");
676}
677
Chris Larsen51417632015-10-02 13:24:25 -0700678TEST_F(AssemblerMIPS64Test, Sra) {
679 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sra, 5, "sra ${reg1}, ${reg2}, {imm}"), "sra");
680}
681
Chris Larsen98a73e12015-10-19 14:17:16 -0700682TEST_F(AssemblerMIPS64Test, Sllv) {
683 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Sllv, "sllv ${reg1}, ${reg2}, ${reg3}"), "sllv");
684}
685
686TEST_F(AssemblerMIPS64Test, Srlv) {
687 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Srlv, "srlv ${reg1}, ${reg2}, ${reg3}"), "srlv");
688}
689
690TEST_F(AssemblerMIPS64Test, Rotrv) {
691 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Rotrv, "rotrv ${reg1}, ${reg2}, ${reg3}"), "rotrv");
692}
693
694TEST_F(AssemblerMIPS64Test, Srav) {
695 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Srav, "srav ${reg1}, ${reg2}, ${reg3}"), "srav");
696}
697
Chris Larsen51417632015-10-02 13:24:25 -0700698TEST_F(AssemblerMIPS64Test, Dsll) {
699 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsll, 5, "dsll ${reg1}, ${reg2}, {imm}"), "dsll");
700}
701
702TEST_F(AssemblerMIPS64Test, Dsrl) {
703 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsrl, 5, "dsrl ${reg1}, ${reg2}, {imm}"), "dsrl");
704}
705
Chris Larsen98a73e12015-10-19 14:17:16 -0700706TEST_F(AssemblerMIPS64Test, Drotr) {
707 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Drotr, 5, "drotr ${reg1}, ${reg2}, {imm}"),
708 "drotr");
709}
710
Chris Larsen51417632015-10-02 13:24:25 -0700711TEST_F(AssemblerMIPS64Test, Dsra) {
712 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsra, 5, "dsra ${reg1}, ${reg2}, {imm}"), "dsra");
713}
714
715TEST_F(AssemblerMIPS64Test, Dsll32) {
Chris Larsen98a73e12015-10-19 14:17:16 -0700716 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsll32, 5, "dsll32 ${reg1}, ${reg2}, {imm}"),
717 "dsll32");
Chris Larsen51417632015-10-02 13:24:25 -0700718}
719
720TEST_F(AssemblerMIPS64Test, Dsrl32) {
Chris Larsen98a73e12015-10-19 14:17:16 -0700721 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsrl32, 5, "dsrl32 ${reg1}, ${reg2}, {imm}"),
722 "dsrl32");
723}
724
725TEST_F(AssemblerMIPS64Test, Drotr32) {
726 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Drotr32, 5, "drotr32 ${reg1}, ${reg2}, {imm}"),
727 "drotr32");
Chris Larsen51417632015-10-02 13:24:25 -0700728}
729
730TEST_F(AssemblerMIPS64Test, Dsra32) {
Chris Larsen98a73e12015-10-19 14:17:16 -0700731 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsra32, 5, "dsra32 ${reg1}, ${reg2}, {imm}"),
732 "dsra32");
Chris Larsen51417632015-10-02 13:24:25 -0700733}
734
Chris Larsendbce0d72015-09-17 13:34:00 -0700735TEST_F(AssemblerMIPS64Test, Sc) {
736 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sc, -9, "sc ${reg1}, {imm}(${reg2})"), "sc");
737}
738
739TEST_F(AssemblerMIPS64Test, Scd) {
740 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Scd, -9, "scd ${reg1}, {imm}(${reg2})"), "scd");
741}
742
743TEST_F(AssemblerMIPS64Test, Ll) {
744 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Ll, -9, "ll ${reg1}, {imm}(${reg2})"), "ll");
745}
746
747TEST_F(AssemblerMIPS64Test, Lld) {
748 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Lld, -9, "lld ${reg1}, {imm}(${reg2})"), "lld");
749}
750
Chris Larsendbce0d72015-09-17 13:34:00 -0700751TEST_F(AssemblerMIPS64Test, Seleqz) {
752 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Seleqz, "seleqz ${reg1}, ${reg2}, ${reg3}"),
753 "seleqz");
754}
755
756TEST_F(AssemblerMIPS64Test, Selnez) {
757 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Selnez, "selnez ${reg1}, ${reg2}, ${reg3}"),
758 "selnez");
759}
760
761TEST_F(AssemblerMIPS64Test, Clz) {
762 DriverStr(RepeatRR(&mips64::Mips64Assembler::Clz, "clz ${reg1}, ${reg2}"), "clz");
763}
764
765TEST_F(AssemblerMIPS64Test, Clo) {
766 DriverStr(RepeatRR(&mips64::Mips64Assembler::Clo, "clo ${reg1}, ${reg2}"), "clo");
767}
768
769TEST_F(AssemblerMIPS64Test, Dclz) {
770 DriverStr(RepeatRR(&mips64::Mips64Assembler::Dclz, "dclz ${reg1}, ${reg2}"), "dclz");
771}
772
773TEST_F(AssemblerMIPS64Test, Dclo) {
774 DriverStr(RepeatRR(&mips64::Mips64Assembler::Dclo, "dclo ${reg1}, ${reg2}"), "dclo");
775}
776
777} // namespace art