blob: f2cbebbfd72bd9841feb1e43984ac51a05c30591 [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*),
Andreas Gampe2e965ac2016-11-03 17:24:15 -0700215 const std::string& instr_name) {
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700216 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*),
Andreas Gampe2e965ac2016-11-03 17:24:15 -0700244 const std::string& instr_name) {
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700245 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
Alexey Frunze299a9392015-12-08 16:08:02 -0800406TEST_F(AssemblerMIPS64Test, CmpUnS) {
407 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUnS, "cmp.un.s ${reg1}, ${reg2}, ${reg3}"),
408 "cmp.un.s");
409}
410
411TEST_F(AssemblerMIPS64Test, CmpEqS) {
412 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpEqS, "cmp.eq.s ${reg1}, ${reg2}, ${reg3}"),
413 "cmp.eq.s");
414}
415
416TEST_F(AssemblerMIPS64Test, CmpUeqS) {
417 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUeqS, "cmp.ueq.s ${reg1}, ${reg2}, ${reg3}"),
418 "cmp.ueq.s");
419}
420
421TEST_F(AssemblerMIPS64Test, CmpLtS) {
422 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpLtS, "cmp.lt.s ${reg1}, ${reg2}, ${reg3}"),
423 "cmp.lt.s");
424}
425
426TEST_F(AssemblerMIPS64Test, CmpUltS) {
427 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUltS, "cmp.ult.s ${reg1}, ${reg2}, ${reg3}"),
428 "cmp.ult.s");
429}
430
431TEST_F(AssemblerMIPS64Test, CmpLeS) {
432 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpLeS, "cmp.le.s ${reg1}, ${reg2}, ${reg3}"),
433 "cmp.le.s");
434}
435
436TEST_F(AssemblerMIPS64Test, CmpUleS) {
437 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUleS, "cmp.ule.s ${reg1}, ${reg2}, ${reg3}"),
438 "cmp.ule.s");
439}
440
441TEST_F(AssemblerMIPS64Test, CmpOrS) {
442 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpOrS, "cmp.or.s ${reg1}, ${reg2}, ${reg3}"),
443 "cmp.or.s");
444}
445
446TEST_F(AssemblerMIPS64Test, CmpUneS) {
447 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUneS, "cmp.une.s ${reg1}, ${reg2}, ${reg3}"),
448 "cmp.une.s");
449}
450
451TEST_F(AssemblerMIPS64Test, CmpNeS) {
452 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpNeS, "cmp.ne.s ${reg1}, ${reg2}, ${reg3}"),
453 "cmp.ne.s");
454}
455
456TEST_F(AssemblerMIPS64Test, CmpUnD) {
457 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUnD, "cmp.un.d ${reg1}, ${reg2}, ${reg3}"),
458 "cmp.un.d");
459}
460
461TEST_F(AssemblerMIPS64Test, CmpEqD) {
462 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpEqD, "cmp.eq.d ${reg1}, ${reg2}, ${reg3}"),
463 "cmp.eq.d");
464}
465
466TEST_F(AssemblerMIPS64Test, CmpUeqD) {
467 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUeqD, "cmp.ueq.d ${reg1}, ${reg2}, ${reg3}"),
468 "cmp.ueq.d");
469}
470
471TEST_F(AssemblerMIPS64Test, CmpLtD) {
472 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpLtD, "cmp.lt.d ${reg1}, ${reg2}, ${reg3}"),
473 "cmp.lt.d");
474}
475
476TEST_F(AssemblerMIPS64Test, CmpUltD) {
477 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUltD, "cmp.ult.d ${reg1}, ${reg2}, ${reg3}"),
478 "cmp.ult.d");
479}
480
481TEST_F(AssemblerMIPS64Test, CmpLeD) {
482 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpLeD, "cmp.le.d ${reg1}, ${reg2}, ${reg3}"),
483 "cmp.le.d");
484}
485
486TEST_F(AssemblerMIPS64Test, CmpUleD) {
487 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUleD, "cmp.ule.d ${reg1}, ${reg2}, ${reg3}"),
488 "cmp.ule.d");
489}
490
491TEST_F(AssemblerMIPS64Test, CmpOrD) {
492 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpOrD, "cmp.or.d ${reg1}, ${reg2}, ${reg3}"),
493 "cmp.or.d");
494}
495
496TEST_F(AssemblerMIPS64Test, CmpUneD) {
497 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUneD, "cmp.une.d ${reg1}, ${reg2}, ${reg3}"),
498 "cmp.une.d");
499}
500
501TEST_F(AssemblerMIPS64Test, CmpNeD) {
502 DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpNeD, "cmp.ne.d ${reg1}, ${reg2}, ${reg3}"),
503 "cmp.ne.d");
504}
505
Chris Larsendbce0d72015-09-17 13:34:00 -0700506TEST_F(AssemblerMIPS64Test, CvtDL) {
507 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtdl, "cvt.d.l ${reg1}, ${reg2}"), "cvt.d.l");
508}
509
Chris Larsen51417632015-10-02 13:24:25 -0700510TEST_F(AssemblerMIPS64Test, CvtDS) {
511 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtds, "cvt.d.s ${reg1}, ${reg2}"), "cvt.d.s");
512}
513
514TEST_F(AssemblerMIPS64Test, CvtDW) {
515 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtdw, "cvt.d.w ${reg1}, ${reg2}"), "cvt.d.w");
516}
517
518TEST_F(AssemblerMIPS64Test, CvtSL) {
519 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtsl, "cvt.s.l ${reg1}, ${reg2}"), "cvt.s.l");
520}
521
522TEST_F(AssemblerMIPS64Test, CvtSD) {
523 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtsd, "cvt.s.d ${reg1}, ${reg2}"), "cvt.s.d");
524}
525
526TEST_F(AssemblerMIPS64Test, CvtSW) {
527 DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtsw, "cvt.s.w ${reg1}, ${reg2}"), "cvt.s.w");
528}
529
Alexey Frunzebaf60b72015-12-22 15:15:03 -0800530TEST_F(AssemblerMIPS64Test, TruncWS) {
531 DriverStr(RepeatFF(&mips64::Mips64Assembler::TruncWS, "trunc.w.s ${reg1}, ${reg2}"), "trunc.w.s");
532}
533
534TEST_F(AssemblerMIPS64Test, TruncWD) {
535 DriverStr(RepeatFF(&mips64::Mips64Assembler::TruncWD, "trunc.w.d ${reg1}, ${reg2}"), "trunc.w.d");
536}
537
538TEST_F(AssemblerMIPS64Test, TruncLS) {
539 DriverStr(RepeatFF(&mips64::Mips64Assembler::TruncLS, "trunc.l.s ${reg1}, ${reg2}"), "trunc.l.s");
540}
541
542TEST_F(AssemblerMIPS64Test, TruncLD) {
543 DriverStr(RepeatFF(&mips64::Mips64Assembler::TruncLD, "trunc.l.d ${reg1}, ${reg2}"), "trunc.l.d");
544}
545
Lazar Trsicd9672662015-09-03 17:33:01 +0200546TEST_F(AssemblerMIPS64Test, Mfc1) {
547 DriverStr(RepeatRF(&mips64::Mips64Assembler::Mfc1, "mfc1 ${reg1}, ${reg2}"), "Mfc1");
548}
549
550TEST_F(AssemblerMIPS64Test, Mfhc1) {
551 DriverStr(RepeatRF(&mips64::Mips64Assembler::Mfhc1, "mfhc1 ${reg1}, ${reg2}"), "Mfhc1");
552}
553
554TEST_F(AssemblerMIPS64Test, Mtc1) {
555 DriverStr(RepeatRF(&mips64::Mips64Assembler::Mtc1, "mtc1 ${reg1}, ${reg2}"), "Mtc1");
556}
557
558TEST_F(AssemblerMIPS64Test, Mthc1) {
559 DriverStr(RepeatRF(&mips64::Mips64Assembler::Mthc1, "mthc1 ${reg1}, ${reg2}"), "Mthc1");
560}
561
562TEST_F(AssemblerMIPS64Test, Dmfc1) {
563 DriverStr(RepeatRF(&mips64::Mips64Assembler::Dmfc1, "dmfc1 ${reg1}, ${reg2}"), "Dmfc1");
564}
565
566TEST_F(AssemblerMIPS64Test, Dmtc1) {
567 DriverStr(RepeatRF(&mips64::Mips64Assembler::Dmtc1, "dmtc1 ${reg1}, ${reg2}"), "Dmtc1");
568}
569
Chris Larsen51417632015-10-02 13:24:25 -0700570////////////////
571// CALL / JMP //
572////////////////
573
574TEST_F(AssemblerMIPS64Test, Jalr) {
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700575 DriverStr(".set noreorder\n" +
576 RepeatRRNoDupes(&mips64::Mips64Assembler::Jalr, "jalr ${reg1}, ${reg2}"), "jalr");
577}
578
Alexey Frunze19f6c692016-11-30 19:19:55 -0800579TEST_F(AssemblerMIPS64Test, Balc) {
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700580 mips64::Mips64Label label1, label2;
Alexey Frunze19f6c692016-11-30 19:19:55 -0800581 __ Balc(&label1);
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700582 constexpr size_t kAdduCount1 = 63;
583 for (size_t i = 0; i != kAdduCount1; ++i) {
584 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
585 }
586 __ Bind(&label1);
Alexey Frunze19f6c692016-11-30 19:19:55 -0800587 __ Balc(&label2);
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700588 constexpr size_t kAdduCount2 = 64;
589 for (size_t i = 0; i != kAdduCount2; ++i) {
590 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
591 }
592 __ Bind(&label2);
Alexey Frunze19f6c692016-11-30 19:19:55 -0800593 __ Balc(&label1);
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700594
595 std::string expected =
596 ".set noreorder\n"
Alexey Frunze19f6c692016-11-30 19:19:55 -0800597 "balc 1f\n" +
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700598 RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
599 "1:\n"
Alexey Frunze19f6c692016-11-30 19:19:55 -0800600 "balc 2f\n" +
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700601 RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
602 "2:\n"
Alexey Frunze19f6c692016-11-30 19:19:55 -0800603 "balc 1b\n";
604 DriverStr(expected, "Balc");
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700605}
606
Alexey Frunze19f6c692016-11-30 19:19:55 -0800607TEST_F(AssemblerMIPS64Test, LongBalc) {
Vladimir Marko36073942016-12-14 14:18:22 +0000608 constexpr uint32_t kNopCount1 = (1u << 25) + 1;
609 constexpr uint32_t kNopCount2 = (1u << 25) + 1;
610 constexpr uint32_t kRequiredCapacity = (kNopCount1 + kNopCount2 + 6u) * 4u;
611 ASSERT_LT(__ GetBuffer()->Capacity(), kRequiredCapacity);
612 __ GetBuffer()->ExtendCapacity(kRequiredCapacity);
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700613 mips64::Mips64Label label1, label2;
Alexey Frunze19f6c692016-11-30 19:19:55 -0800614 __ Balc(&label1);
Alexey Frunze19f6c692016-11-30 19:19:55 -0800615 for (uint32_t i = 0; i != kNopCount1; ++i) {
616 __ Nop();
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700617 }
618 __ Bind(&label1);
Alexey Frunze19f6c692016-11-30 19:19:55 -0800619 __ Balc(&label2);
Alexey Frunze19f6c692016-11-30 19:19:55 -0800620 for (uint32_t i = 0; i != kNopCount2; ++i) {
621 __ Nop();
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700622 }
623 __ Bind(&label2);
Alexey Frunze19f6c692016-11-30 19:19:55 -0800624 __ Balc(&label1);
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700625
Alexey Frunze19f6c692016-11-30 19:19:55 -0800626 uint32_t offset_forward1 = 2 + kNopCount1; // 2: account for auipc and jialc.
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700627 offset_forward1 <<= 2;
Alexey Frunze19f6c692016-11-30 19:19:55 -0800628 offset_forward1 += (offset_forward1 & 0x8000) << 1; // Account for sign extension in jialc.
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700629
Alexey Frunze19f6c692016-11-30 19:19:55 -0800630 uint32_t offset_forward2 = 2 + kNopCount2; // 2: account for auipc and jialc.
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700631 offset_forward2 <<= 2;
Alexey Frunze19f6c692016-11-30 19:19:55 -0800632 offset_forward2 += (offset_forward2 & 0x8000) << 1; // Account for sign extension in jialc.
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700633
Alexey Frunze19f6c692016-11-30 19:19:55 -0800634 uint32_t offset_back = -(2 + kNopCount2); // 2: account for auipc and jialc.
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700635 offset_back <<= 2;
Alexey Frunze19f6c692016-11-30 19:19:55 -0800636 offset_back += (offset_back & 0x8000) << 1; // Account for sign extension in jialc.
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700637
Alexey Frunze19f6c692016-11-30 19:19:55 -0800638 // Note, we're using the ".fill" directive to tell the assembler to generate many NOPs
639 // instead of generating them ourselves in the source code. This saves a few minutes
640 // of test time.
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700641 std::ostringstream oss;
642 oss <<
643 ".set noreorder\n"
Alexey Frunze19f6c692016-11-30 19:19:55 -0800644 "auipc $at, 0x" << std::hex << High16Bits(offset_forward1) << "\n"
645 "jialc $at, 0x" << std::hex << Low16Bits(offset_forward1) << "\n"
646 ".fill 0x" << std::hex << kNopCount1 << " , 4, 0\n"
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700647 "1:\n"
Alexey Frunze19f6c692016-11-30 19:19:55 -0800648 "auipc $at, 0x" << std::hex << High16Bits(offset_forward2) << "\n"
649 "jialc $at, 0x" << std::hex << Low16Bits(offset_forward2) << "\n"
650 ".fill 0x" << std::hex << kNopCount2 << " , 4, 0\n"
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700651 "2:\n"
Alexey Frunze19f6c692016-11-30 19:19:55 -0800652 "auipc $at, 0x" << std::hex << High16Bits(offset_back) << "\n"
653 "jialc $at, 0x" << std::hex << Low16Bits(offset_back) << "\n";
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700654 std::string expected = oss.str();
Alexey Frunze19f6c692016-11-30 19:19:55 -0800655 DriverStr(expected, "LongBalc");
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700656}
657
658TEST_F(AssemblerMIPS64Test, Bc) {
659 mips64::Mips64Label label1, label2;
660 __ Bc(&label1);
661 constexpr size_t kAdduCount1 = 63;
662 for (size_t i = 0; i != kAdduCount1; ++i) {
663 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
664 }
665 __ Bind(&label1);
666 __ Bc(&label2);
667 constexpr size_t kAdduCount2 = 64;
668 for (size_t i = 0; i != kAdduCount2; ++i) {
669 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
670 }
671 __ Bind(&label2);
672 __ Bc(&label1);
673
674 std::string expected =
675 ".set noreorder\n"
676 "bc 1f\n" +
677 RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
678 "1:\n"
679 "bc 2f\n" +
680 RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
681 "2:\n"
682 "bc 1b\n";
683 DriverStr(expected, "Bc");
684}
685
686TEST_F(AssemblerMIPS64Test, Beqzc) {
687 BranchCondOneRegHelper(&mips64::Mips64Assembler::Beqzc, "Beqzc");
688}
689
690TEST_F(AssemblerMIPS64Test, Bnezc) {
691 BranchCondOneRegHelper(&mips64::Mips64Assembler::Bnezc, "Bnezc");
692}
693
694TEST_F(AssemblerMIPS64Test, Bltzc) {
695 BranchCondOneRegHelper(&mips64::Mips64Assembler::Bltzc, "Bltzc");
696}
697
698TEST_F(AssemblerMIPS64Test, Bgezc) {
699 BranchCondOneRegHelper(&mips64::Mips64Assembler::Bgezc, "Bgezc");
700}
701
702TEST_F(AssemblerMIPS64Test, Blezc) {
703 BranchCondOneRegHelper(&mips64::Mips64Assembler::Blezc, "Blezc");
704}
705
706TEST_F(AssemblerMIPS64Test, Bgtzc) {
707 BranchCondOneRegHelper(&mips64::Mips64Assembler::Bgtzc, "Bgtzc");
708}
709
710TEST_F(AssemblerMIPS64Test, Beqc) {
711 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Beqc, "Beqc");
712}
713
714TEST_F(AssemblerMIPS64Test, Bnec) {
715 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bnec, "Bnec");
716}
717
718TEST_F(AssemblerMIPS64Test, Bltc) {
719 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bltc, "Bltc");
720}
721
722TEST_F(AssemblerMIPS64Test, Bgec) {
723 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bgec, "Bgec");
724}
725
726TEST_F(AssemblerMIPS64Test, Bltuc) {
727 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bltuc, "Bltuc");
728}
729
730TEST_F(AssemblerMIPS64Test, Bgeuc) {
731 BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bgeuc, "Bgeuc");
732}
733
Alexey Frunze299a9392015-12-08 16:08:02 -0800734TEST_F(AssemblerMIPS64Test, Bc1eqz) {
735 mips64::Mips64Label label;
736 __ Bc1eqz(mips64::F0, &label);
737 constexpr size_t kAdduCount1 = 63;
738 for (size_t i = 0; i != kAdduCount1; ++i) {
739 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
740 }
741 __ Bind(&label);
742 constexpr size_t kAdduCount2 = 64;
743 for (size_t i = 0; i != kAdduCount2; ++i) {
744 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
745 }
746 __ Bc1eqz(mips64::F31, &label);
747
748 std::string expected =
749 ".set noreorder\n"
750 "bc1eqz $f0, 1f\n"
751 "nop\n" +
752 RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
753 "1:\n" +
754 RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
755 "bc1eqz $f31, 1b\n"
756 "nop\n";
757 DriverStr(expected, "Bc1eqz");
758}
759
760TEST_F(AssemblerMIPS64Test, Bc1nez) {
761 mips64::Mips64Label label;
762 __ Bc1nez(mips64::F0, &label);
763 constexpr size_t kAdduCount1 = 63;
764 for (size_t i = 0; i != kAdduCount1; ++i) {
765 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
766 }
767 __ Bind(&label);
768 constexpr size_t kAdduCount2 = 64;
769 for (size_t i = 0; i != kAdduCount2; ++i) {
770 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
771 }
772 __ Bc1nez(mips64::F31, &label);
773
774 std::string expected =
775 ".set noreorder\n"
776 "bc1nez $f0, 1f\n"
777 "nop\n" +
778 RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
779 "1:\n" +
780 RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
781 "bc1nez $f31, 1b\n"
782 "nop\n";
783 DriverStr(expected, "Bc1nez");
784}
785
Alexey Frunzea0e87b02015-09-24 22:57:20 -0700786TEST_F(AssemblerMIPS64Test, LongBeqc) {
787 mips64::Mips64Label label;
788 __ Beqc(mips64::A0, mips64::A1, &label);
789 constexpr uint32_t kAdduCount1 = (1u << 15) + 1;
790 for (uint32_t i = 0; i != kAdduCount1; ++i) {
791 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
792 }
793 __ Bind(&label);
794 constexpr uint32_t kAdduCount2 = (1u << 15) + 1;
795 for (uint32_t i = 0; i != kAdduCount2; ++i) {
796 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
797 }
798 __ Beqc(mips64::A2, mips64::A3, &label);
799
800 uint32_t offset_forward = 2 + kAdduCount1; // 2: account for auipc and jic.
801 offset_forward <<= 2;
802 offset_forward += (offset_forward & 0x8000) << 1; // Account for sign extension in jic.
803
804 uint32_t offset_back = -(kAdduCount2 + 1); // 1: account for bnec.
805 offset_back <<= 2;
806 offset_back += (offset_back & 0x8000) << 1; // Account for sign extension in jic.
807
808 std::ostringstream oss;
809 oss <<
810 ".set noreorder\n"
811 "bnec $a0, $a1, 1f\n"
812 "auipc $at, 0x" << std::hex << High16Bits(offset_forward) << "\n"
813 "jic $at, 0x" << std::hex << Low16Bits(offset_forward) << "\n"
814 "1:\n" <<
815 RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") <<
816 "2:\n" <<
817 RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") <<
818 "bnec $a2, $a3, 3f\n"
819 "auipc $at, 0x" << std::hex << High16Bits(offset_back) << "\n"
820 "jic $at, 0x" << std::hex << Low16Bits(offset_back) << "\n"
821 "3:\n";
822 std::string expected = oss.str();
823 DriverStr(expected, "LongBeqc");
Chris Larsen51417632015-10-02 13:24:25 -0700824}
825
Chris Larsendbce0d72015-09-17 13:34:00 -0700826//////////
827// MISC //
828//////////
829
Alexey Frunze19f6c692016-11-30 19:19:55 -0800830TEST_F(AssemblerMIPS64Test, Lwpc) {
831 // Lwpc() takes an unsigned 19-bit immediate, while the GNU assembler needs a signed offset,
832 // hence the sign extension from bit 18 with `imm - ((imm & 0x40000) << 1)`.
833 // The GNU assembler also wants the offset to be a multiple of 4, which it will shift right
834 // by 2 positions when encoding, hence `<< 2` to compensate for that shift.
835 // We capture the value of the immediate with `.set imm, {imm}` because the value is needed
836 // twice for the sign extension, but `{imm}` is substituted only once.
837 const char* code = ".set imm, {imm}\nlw ${reg}, ((imm - ((imm & 0x40000) << 1)) << 2)($pc)";
838 DriverStr(RepeatRIb(&mips64::Mips64Assembler::Lwpc, 19, code), "Lwpc");
839}
840
841TEST_F(AssemblerMIPS64Test, Lwupc) {
842 // The comment for the Lwpc test applies here as well.
843 const char* code = ".set imm, {imm}\nlwu ${reg}, ((imm - ((imm & 0x40000) << 1)) << 2)($pc)";
844 DriverStr(RepeatRIb(&mips64::Mips64Assembler::Lwupc, 19, code), "Lwupc");
845}
846
847TEST_F(AssemblerMIPS64Test, Ldpc) {
848 // The comment for the Lwpc test applies here as well.
849 const char* code = ".set imm, {imm}\nld ${reg}, ((imm - ((imm & 0x20000) << 1)) << 3)($pc)";
850 DriverStr(RepeatRIb(&mips64::Mips64Assembler::Ldpc, 18, code), "Ldpc");
851}
852
853TEST_F(AssemblerMIPS64Test, LoadFarthestNearLabelAddress) {
854 mips64::Mips64Label label;
855 __ LoadLabelAddress(mips64::V0, &label);
856 constexpr uint32_t kAdduCount = 0x3FFDE;
857 for (uint32_t i = 0; i != kAdduCount; ++i) {
858 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
859 }
860 __ Bind(&label);
861
862 std::string expected =
863 "lapc $v0, 1f\n" +
864 RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
865 "1:\n";
866 DriverStr(expected, "LoadFarthestNearLabelAddress");
867 EXPECT_EQ(__ GetLabelLocation(&label), (1 + kAdduCount) * 4);
868}
869
870TEST_F(AssemblerMIPS64Test, LoadNearestFarLabelAddress) {
871 mips64::Mips64Label label;
872 __ LoadLabelAddress(mips64::V0, &label);
873 constexpr uint32_t kAdduCount = 0x3FFDF;
874 for (uint32_t i = 0; i != kAdduCount; ++i) {
875 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
876 }
877 __ Bind(&label);
878
879 std::string expected =
880 "1:\n"
881 "auipc $at, %hi(2f - 1b)\n"
Alexey Frunzef63f5692016-12-13 17:43:11 -0800882 "daddiu $v0, $at, %lo(2f - 1b)\n" +
Alexey Frunze19f6c692016-11-30 19:19:55 -0800883 RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
884 "2:\n";
885 DriverStr(expected, "LoadNearestFarLabelAddress");
886 EXPECT_EQ(__ GetLabelLocation(&label), (2 + kAdduCount) * 4);
887}
888
889TEST_F(AssemblerMIPS64Test, LoadFarthestNearLiteral) {
890 mips64::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
891 __ LoadLiteral(mips64::V0, mips64::kLoadWord, literal);
892 constexpr uint32_t kAdduCount = 0x3FFDE;
893 for (uint32_t i = 0; i != kAdduCount; ++i) {
894 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
895 }
896
897 std::string expected =
898 "lwpc $v0, 1f\n" +
899 RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
900 "1:\n"
901 ".word 0x12345678\n";
902 DriverStr(expected, "LoadFarthestNearLiteral");
903 EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (1 + kAdduCount) * 4);
904}
905
906TEST_F(AssemblerMIPS64Test, LoadNearestFarLiteral) {
907 mips64::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
908 __ LoadLiteral(mips64::V0, mips64::kLoadWord, literal);
909 constexpr uint32_t kAdduCount = 0x3FFDF;
910 for (uint32_t i = 0; i != kAdduCount; ++i) {
911 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
912 }
913
914 std::string expected =
915 "1:\n"
916 "auipc $at, %hi(2f - 1b)\n"
917 "lw $v0, %lo(2f - 1b)($at)\n" +
918 RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
919 "2:\n"
920 ".word 0x12345678\n";
921 DriverStr(expected, "LoadNearestFarLiteral");
922 EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (2 + kAdduCount) * 4);
923}
924
925TEST_F(AssemblerMIPS64Test, LoadFarthestNearLiteralUnsigned) {
926 mips64::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
927 __ LoadLiteral(mips64::V0, mips64::kLoadUnsignedWord, literal);
928 constexpr uint32_t kAdduCount = 0x3FFDE;
929 for (uint32_t i = 0; i != kAdduCount; ++i) {
930 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
931 }
932
933 std::string expected =
934 "lwupc $v0, 1f\n" +
935 RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
936 "1:\n"
937 ".word 0x12345678\n";
938 DriverStr(expected, "LoadFarthestNearLiteralUnsigned");
939 EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (1 + kAdduCount) * 4);
940}
941
942TEST_F(AssemblerMIPS64Test, LoadNearestFarLiteralUnsigned) {
943 mips64::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
944 __ LoadLiteral(mips64::V0, mips64::kLoadUnsignedWord, literal);
945 constexpr uint32_t kAdduCount = 0x3FFDF;
946 for (uint32_t i = 0; i != kAdduCount; ++i) {
947 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
948 }
949
950 std::string expected =
951 "1:\n"
952 "auipc $at, %hi(2f - 1b)\n"
953 "lwu $v0, %lo(2f - 1b)($at)\n" +
954 RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
955 "2:\n"
956 ".word 0x12345678\n";
957 DriverStr(expected, "LoadNearestFarLiteralUnsigned");
958 EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (2 + kAdduCount) * 4);
959}
960
961TEST_F(AssemblerMIPS64Test, LoadFarthestNearLiteralLong) {
962 mips64::Literal* literal = __ NewLiteral<uint64_t>(UINT64_C(0x0123456789ABCDEF));
963 __ LoadLiteral(mips64::V0, mips64::kLoadDoubleword, literal);
964 constexpr uint32_t kAdduCount = 0x3FFDD;
965 for (uint32_t i = 0; i != kAdduCount; ++i) {
966 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
967 }
968
969 std::string expected =
970 "ldpc $v0, 1f\n" +
971 RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
972 "1:\n"
973 ".dword 0x0123456789ABCDEF\n";
974 DriverStr(expected, "LoadFarthestNearLiteralLong");
975 EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (1 + kAdduCount) * 4);
976}
977
978TEST_F(AssemblerMIPS64Test, LoadNearestFarLiteralLong) {
979 mips64::Literal* literal = __ NewLiteral<uint64_t>(UINT64_C(0x0123456789ABCDEF));
980 __ LoadLiteral(mips64::V0, mips64::kLoadDoubleword, literal);
981 constexpr uint32_t kAdduCount = 0x3FFDE;
982 for (uint32_t i = 0; i != kAdduCount; ++i) {
983 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
984 }
985
986 std::string expected =
987 "1:\n"
988 "auipc $at, %hi(2f - 1b)\n"
989 "ld $v0, %lo(2f - 1b)($at)\n" +
990 RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
991 "2:\n"
992 ".dword 0x0123456789ABCDEF\n";
993 DriverStr(expected, "LoadNearestFarLiteralLong");
994 EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (2 + kAdduCount) * 4);
995}
996
997TEST_F(AssemblerMIPS64Test, LongLiteralAlignmentNop) {
998 mips64::Literal* literal1 = __ NewLiteral<uint64_t>(UINT64_C(0x0123456789ABCDEF));
999 mips64::Literal* literal2 = __ NewLiteral<uint64_t>(UINT64_C(0x5555555555555555));
1000 mips64::Literal* literal3 = __ NewLiteral<uint64_t>(UINT64_C(0xAAAAAAAAAAAAAAAA));
1001 __ LoadLiteral(mips64::A1, mips64::kLoadDoubleword, literal1);
1002 __ LoadLiteral(mips64::A2, mips64::kLoadDoubleword, literal2);
1003 __ LoadLiteral(mips64::A3, mips64::kLoadDoubleword, literal3);
1004 __ LoadLabelAddress(mips64::V0, literal1->GetLabel());
1005 __ LoadLabelAddress(mips64::V1, literal2->GetLabel());
1006 // A nop will be inserted here before the 64-bit literals.
1007
1008 std::string expected =
1009 "ldpc $a1, 1f\n"
1010 // The GNU assembler incorrectly requires the ldpc instruction to be located
1011 // at an address that's a multiple of 8. TODO: Remove this workaround if/when
1012 // the assembler is fixed.
1013 // "ldpc $a2, 2f\n"
1014 ".word 0xECD80004\n"
1015 "ldpc $a3, 3f\n"
1016 "lapc $v0, 1f\n"
1017 "lapc $v1, 2f\n"
1018 "nop\n"
1019 "1:\n"
1020 ".dword 0x0123456789ABCDEF\n"
1021 "2:\n"
1022 ".dword 0x5555555555555555\n"
1023 "3:\n"
1024 ".dword 0xAAAAAAAAAAAAAAAA\n";
1025 DriverStr(expected, "LongLiteralAlignmentNop");
1026 EXPECT_EQ(__ GetLabelLocation(literal1->GetLabel()), 6 * 4u);
1027 EXPECT_EQ(__ GetLabelLocation(literal2->GetLabel()), 8 * 4u);
1028 EXPECT_EQ(__ GetLabelLocation(literal3->GetLabel()), 10 * 4u);
1029}
1030
1031TEST_F(AssemblerMIPS64Test, LongLiteralAlignmentNoNop) {
1032 mips64::Literal* literal1 = __ NewLiteral<uint64_t>(UINT64_C(0x0123456789ABCDEF));
1033 mips64::Literal* literal2 = __ NewLiteral<uint64_t>(UINT64_C(0x5555555555555555));
1034 __ LoadLiteral(mips64::A1, mips64::kLoadDoubleword, literal1);
1035 __ LoadLiteral(mips64::A2, mips64::kLoadDoubleword, literal2);
1036 __ LoadLabelAddress(mips64::V0, literal1->GetLabel());
1037 __ LoadLabelAddress(mips64::V1, literal2->GetLabel());
1038
1039 std::string expected =
1040 "ldpc $a1, 1f\n"
1041 // The GNU assembler incorrectly requires the ldpc instruction to be located
1042 // at an address that's a multiple of 8. TODO: Remove this workaround if/when
1043 // the assembler is fixed.
1044 // "ldpc $a2, 2f\n"
1045 ".word 0xECD80003\n"
1046 "lapc $v0, 1f\n"
1047 "lapc $v1, 2f\n"
1048 "1:\n"
1049 ".dword 0x0123456789ABCDEF\n"
1050 "2:\n"
1051 ".dword 0x5555555555555555\n";
1052 DriverStr(expected, "LongLiteralAlignmentNoNop");
1053 EXPECT_EQ(__ GetLabelLocation(literal1->GetLabel()), 4 * 4u);
1054 EXPECT_EQ(__ GetLabelLocation(literal2->GetLabel()), 6 * 4u);
1055}
1056
1057TEST_F(AssemblerMIPS64Test, FarLongLiteralAlignmentNop) {
1058 mips64::Literal* literal = __ NewLiteral<uint64_t>(UINT64_C(0x0123456789ABCDEF));
1059 __ LoadLiteral(mips64::V0, mips64::kLoadDoubleword, literal);
1060 __ LoadLabelAddress(mips64::V1, literal->GetLabel());
1061 constexpr uint32_t kAdduCount = 0x3FFDF;
1062 for (uint32_t i = 0; i != kAdduCount; ++i) {
1063 __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
1064 }
1065 // A nop will be inserted here before the 64-bit literal.
1066
1067 std::string expected =
1068 "1:\n"
1069 "auipc $at, %hi(3f - 1b)\n"
1070 "ld $v0, %lo(3f - 1b)($at)\n"
1071 "2:\n"
1072 "auipc $at, %hi(3f - 2b)\n"
Alexey Frunzef63f5692016-12-13 17:43:11 -08001073 "daddiu $v1, $at, %lo(3f - 2b)\n" +
Alexey Frunze19f6c692016-11-30 19:19:55 -08001074 RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
1075 "nop\n"
1076 "3:\n"
1077 ".dword 0x0123456789ABCDEF\n";
1078 DriverStr(expected, "FarLongLiteralAlignmentNop");
1079 EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (5 + kAdduCount) * 4);
1080}
1081
Chris Larsendbce0d72015-09-17 13:34:00 -07001082TEST_F(AssemblerMIPS64Test, Bitswap) {
1083 DriverStr(RepeatRR(&mips64::Mips64Assembler::Bitswap, "bitswap ${reg1}, ${reg2}"), "bitswap");
1084}
1085
1086TEST_F(AssemblerMIPS64Test, Dbitswap) {
1087 DriverStr(RepeatRR(&mips64::Mips64Assembler::Dbitswap, "dbitswap ${reg1}, ${reg2}"), "dbitswap");
1088}
1089
Chris Larsen51417632015-10-02 13:24:25 -07001090TEST_F(AssemblerMIPS64Test, Seb) {
1091 DriverStr(RepeatRR(&mips64::Mips64Assembler::Seb, "seb ${reg1}, ${reg2}"), "seb");
1092}
1093
1094TEST_F(AssemblerMIPS64Test, Seh) {
1095 DriverStr(RepeatRR(&mips64::Mips64Assembler::Seh, "seh ${reg1}, ${reg2}"), "seh");
1096}
1097
Chris Larsendbce0d72015-09-17 13:34:00 -07001098TEST_F(AssemblerMIPS64Test, Dsbh) {
1099 DriverStr(RepeatRR(&mips64::Mips64Assembler::Dsbh, "dsbh ${reg1}, ${reg2}"), "dsbh");
1100}
1101
1102TEST_F(AssemblerMIPS64Test, Dshd) {
1103 DriverStr(RepeatRR(&mips64::Mips64Assembler::Dshd, "dshd ${reg1}, ${reg2}"), "dshd");
1104}
1105
Lazar Trsicd9672662015-09-03 17:33:01 +02001106TEST_F(AssemblerMIPS64Test, Dext) {
1107 std::vector<mips64::GpuRegister*> reg1_registers = GetRegisters();
1108 std::vector<mips64::GpuRegister*> reg2_registers = GetRegisters();
1109 WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * 33 * 16);
1110 std::ostringstream expected;
1111 for (mips64::GpuRegister* reg1 : reg1_registers) {
1112 for (mips64::GpuRegister* reg2 : reg2_registers) {
1113 for (int32_t pos = 0; pos < 32; pos++) {
1114 for (int32_t size = 1; size <= 32; size++) {
1115 __ Dext(*reg1, *reg2, pos, size);
1116 expected << "dext $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n";
1117 }
1118 }
1119 }
1120 }
1121
1122 DriverStr(expected.str(), "Dext");
1123}
1124
1125TEST_F(AssemblerMIPS64Test, Dinsu) {
1126 std::vector<mips64::GpuRegister*> reg1_registers = GetRegisters();
1127 std::vector<mips64::GpuRegister*> reg2_registers = GetRegisters();
1128 WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * 33 * 16);
1129 std::ostringstream expected;
1130 for (mips64::GpuRegister* reg1 : reg1_registers) {
1131 for (mips64::GpuRegister* reg2 : reg2_registers) {
1132 for (int32_t pos = 32; pos < 64; pos++) {
1133 for (int32_t size = 1; pos + size <= 64; size++) {
1134 __ Dinsu(*reg1, *reg2, pos, size);
1135 expected << "dinsu $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n";
1136 }
1137 }
1138 }
1139 }
1140
1141 DriverStr(expected.str(), "Dinsu");
1142}
1143
Chris Larsene3660592016-11-09 11:13:42 -08001144TEST_F(AssemblerMIPS64Test, Lsa) {
1145 DriverStr(RepeatRRRIb(&mips64::Mips64Assembler::Lsa,
1146 2,
1147 "lsa ${reg1}, ${reg2}, ${reg3}, {imm}",
1148 1),
1149 "lsa");
1150}
1151
1152TEST_F(AssemblerMIPS64Test, Dlsa) {
1153 DriverStr(RepeatRRRIb(&mips64::Mips64Assembler::Dlsa,
1154 2,
1155 "dlsa ${reg1}, ${reg2}, ${reg3}, {imm}",
1156 1),
1157 "dlsa");
1158}
1159
Chris Larsendbce0d72015-09-17 13:34:00 -07001160TEST_F(AssemblerMIPS64Test, Wsbh) {
1161 DriverStr(RepeatRR(&mips64::Mips64Assembler::Wsbh, "wsbh ${reg1}, ${reg2}"), "wsbh");
1162}
1163
Chris Larsen51417632015-10-02 13:24:25 -07001164TEST_F(AssemblerMIPS64Test, Sll) {
1165 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sll, 5, "sll ${reg1}, ${reg2}, {imm}"), "sll");
1166}
1167
1168TEST_F(AssemblerMIPS64Test, Srl) {
1169 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Srl, 5, "srl ${reg1}, ${reg2}, {imm}"), "srl");
1170}
1171
Chris Larsen98a73e12015-10-19 14:17:16 -07001172TEST_F(AssemblerMIPS64Test, Rotr) {
1173 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Rotr, 5, "rotr ${reg1}, ${reg2}, {imm}"), "rotr");
1174}
1175
Chris Larsen51417632015-10-02 13:24:25 -07001176TEST_F(AssemblerMIPS64Test, Sra) {
1177 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sra, 5, "sra ${reg1}, ${reg2}, {imm}"), "sra");
1178}
1179
Chris Larsen98a73e12015-10-19 14:17:16 -07001180TEST_F(AssemblerMIPS64Test, Sllv) {
1181 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Sllv, "sllv ${reg1}, ${reg2}, ${reg3}"), "sllv");
1182}
1183
1184TEST_F(AssemblerMIPS64Test, Srlv) {
1185 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Srlv, "srlv ${reg1}, ${reg2}, ${reg3}"), "srlv");
1186}
1187
1188TEST_F(AssemblerMIPS64Test, Rotrv) {
1189 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Rotrv, "rotrv ${reg1}, ${reg2}, ${reg3}"), "rotrv");
1190}
1191
1192TEST_F(AssemblerMIPS64Test, Srav) {
1193 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Srav, "srav ${reg1}, ${reg2}, ${reg3}"), "srav");
1194}
1195
Chris Larsen51417632015-10-02 13:24:25 -07001196TEST_F(AssemblerMIPS64Test, Dsll) {
1197 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsll, 5, "dsll ${reg1}, ${reg2}, {imm}"), "dsll");
1198}
1199
1200TEST_F(AssemblerMIPS64Test, Dsrl) {
1201 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsrl, 5, "dsrl ${reg1}, ${reg2}, {imm}"), "dsrl");
1202}
1203
Chris Larsen98a73e12015-10-19 14:17:16 -07001204TEST_F(AssemblerMIPS64Test, Drotr) {
1205 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Drotr, 5, "drotr ${reg1}, ${reg2}, {imm}"),
1206 "drotr");
1207}
1208
Chris Larsen51417632015-10-02 13:24:25 -07001209TEST_F(AssemblerMIPS64Test, Dsra) {
1210 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsra, 5, "dsra ${reg1}, ${reg2}, {imm}"), "dsra");
1211}
1212
1213TEST_F(AssemblerMIPS64Test, Dsll32) {
Chris Larsen98a73e12015-10-19 14:17:16 -07001214 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsll32, 5, "dsll32 ${reg1}, ${reg2}, {imm}"),
1215 "dsll32");
Chris Larsen51417632015-10-02 13:24:25 -07001216}
1217
1218TEST_F(AssemblerMIPS64Test, Dsrl32) {
Chris Larsen98a73e12015-10-19 14:17:16 -07001219 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsrl32, 5, "dsrl32 ${reg1}, ${reg2}, {imm}"),
1220 "dsrl32");
1221}
1222
1223TEST_F(AssemblerMIPS64Test, Drotr32) {
1224 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Drotr32, 5, "drotr32 ${reg1}, ${reg2}, {imm}"),
1225 "drotr32");
Chris Larsen51417632015-10-02 13:24:25 -07001226}
1227
1228TEST_F(AssemblerMIPS64Test, Dsra32) {
Chris Larsen98a73e12015-10-19 14:17:16 -07001229 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsra32, 5, "dsra32 ${reg1}, ${reg2}, {imm}"),
1230 "dsra32");
Chris Larsen51417632015-10-02 13:24:25 -07001231}
1232
Chris Larsendbce0d72015-09-17 13:34:00 -07001233TEST_F(AssemblerMIPS64Test, Sc) {
1234 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sc, -9, "sc ${reg1}, {imm}(${reg2})"), "sc");
1235}
1236
1237TEST_F(AssemblerMIPS64Test, Scd) {
1238 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Scd, -9, "scd ${reg1}, {imm}(${reg2})"), "scd");
1239}
1240
1241TEST_F(AssemblerMIPS64Test, Ll) {
1242 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Ll, -9, "ll ${reg1}, {imm}(${reg2})"), "ll");
1243}
1244
1245TEST_F(AssemblerMIPS64Test, Lld) {
1246 DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Lld, -9, "lld ${reg1}, {imm}(${reg2})"), "lld");
1247}
1248
Chris Larsendbce0d72015-09-17 13:34:00 -07001249TEST_F(AssemblerMIPS64Test, Seleqz) {
1250 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Seleqz, "seleqz ${reg1}, ${reg2}, ${reg3}"),
1251 "seleqz");
1252}
1253
1254TEST_F(AssemblerMIPS64Test, Selnez) {
1255 DriverStr(RepeatRRR(&mips64::Mips64Assembler::Selnez, "selnez ${reg1}, ${reg2}, ${reg3}"),
1256 "selnez");
1257}
1258
1259TEST_F(AssemblerMIPS64Test, Clz) {
1260 DriverStr(RepeatRR(&mips64::Mips64Assembler::Clz, "clz ${reg1}, ${reg2}"), "clz");
1261}
1262
1263TEST_F(AssemblerMIPS64Test, Clo) {
1264 DriverStr(RepeatRR(&mips64::Mips64Assembler::Clo, "clo ${reg1}, ${reg2}"), "clo");
1265}
1266
1267TEST_F(AssemblerMIPS64Test, Dclz) {
1268 DriverStr(RepeatRR(&mips64::Mips64Assembler::Dclz, "dclz ${reg1}, ${reg2}"), "dclz");
1269}
1270
1271TEST_F(AssemblerMIPS64Test, Dclo) {
1272 DriverStr(RepeatRR(&mips64::Mips64Assembler::Dclo, "dclo ${reg1}, ${reg2}"), "dclo");
1273}
1274
Lazar Trsicd9672662015-09-03 17:33:01 +02001275TEST_F(AssemblerMIPS64Test, LoadFromOffset) {
1276 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A0, 0);
1277 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0);
1278 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 1);
1279 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 256);
1280 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 1000);
1281 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x7FFF);
1282 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x8000);
1283 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x8001);
1284 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x10000);
1285 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x12345678);
1286 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, -256);
1287 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, -32768);
1288 __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0xABCDEF00);
1289
1290 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A0, 0);
1291 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0);
1292 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 1);
1293 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 256);
1294 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 1000);
1295 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x7FFF);
1296 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x8000);
1297 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x8001);
1298 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x10000);
1299 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x12345678);
1300 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, -256);
1301 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, -32768);
1302 __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0xABCDEF00);
1303
1304 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A0, 0);
1305 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0);
1306 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 2);
1307 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 256);
1308 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 1000);
1309 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x7FFE);
1310 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x8000);
1311 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x8002);
1312 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x10000);
1313 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x12345678);
1314 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, -256);
1315 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, -32768);
1316 __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0xABCDEF00);
1317
1318 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A0, 0);
1319 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0);
1320 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 2);
1321 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 256);
1322 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 1000);
1323 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x7FFE);
1324 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x8000);
1325 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x8002);
1326 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x10000);
1327 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x12345678);
1328 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, -256);
1329 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, -32768);
1330 __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0xABCDEF00);
1331
1332 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A0, 0);
1333 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0);
1334 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 4);
1335 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 256);
1336 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 1000);
1337 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x7FFC);
1338 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x8000);
1339 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x8004);
1340 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x10000);
1341 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x12345678);
1342 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, -256);
1343 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, -32768);
1344 __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0xABCDEF00);
1345
1346 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A0, 0);
1347 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0);
1348 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 4);
1349 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 256);
1350 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 1000);
1351 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x7FFC);
1352 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x8000);
1353 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x8004);
1354 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x10000);
1355 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x12345678);
1356 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, -256);
1357 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, -32768);
1358 __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0xABCDEF00);
1359
1360 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A0, 0);
1361 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0);
1362 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 4);
1363 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 256);
1364 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 1000);
1365 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x7FFC);
1366 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x8000);
1367 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x8004);
1368 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x10000);
1369 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x12345678);
1370 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, -256);
1371 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, -32768);
1372 __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0xABCDEF00);
1373
1374 const char* expected =
1375 "lb $a0, 0($a0)\n"
1376 "lb $a0, 0($a1)\n"
1377 "lb $a0, 1($a1)\n"
1378 "lb $a0, 256($a1)\n"
1379 "lb $a0, 1000($a1)\n"
1380 "lb $a0, 0x7FFF($a1)\n"
1381 "ori $at, $zero, 0x8000\n"
1382 "daddu $at, $at, $a1\n"
1383 "lb $a0, 0($at)\n"
1384 "ori $at, $zero, 0x8000\n"
1385 "daddu $at, $at, $a1\n"
1386 "lb $a0, 1($at)\n"
1387 "lui $at, 1\n"
1388 "daddu $at, $at, $a1\n"
1389 "lb $a0, 0($at)\n"
1390 "lui $at, 0x1234\n"
1391 "ori $at, 0x5678\n"
1392 "daddu $at, $at, $a1\n"
1393 "lb $a0, 0($at)\n"
1394 "lb $a0, -256($a1)\n"
1395 "lb $a0, -32768($a1)\n"
1396 "lui $at, 0xABCD\n"
1397 "ori $at, 0xEF00\n"
1398 "daddu $at, $at, $a1\n"
1399 "lb $a0, 0($at)\n"
1400
1401 "lbu $a0, 0($a0)\n"
1402 "lbu $a0, 0($a1)\n"
1403 "lbu $a0, 1($a1)\n"
1404 "lbu $a0, 256($a1)\n"
1405 "lbu $a0, 1000($a1)\n"
1406 "lbu $a0, 0x7FFF($a1)\n"
1407 "ori $at, $zero, 0x8000\n"
1408 "daddu $at, $at, $a1\n"
1409 "lbu $a0, 0($at)\n"
1410 "ori $at, $zero, 0x8000\n"
1411 "daddu $at, $at, $a1\n"
1412 "lbu $a0, 1($at)\n"
1413 "lui $at, 1\n"
1414 "daddu $at, $at, $a1\n"
1415 "lbu $a0, 0($at)\n"
1416 "lui $at, 0x1234\n"
1417 "ori $at, 0x5678\n"
1418 "daddu $at, $at, $a1\n"
1419 "lbu $a0, 0($at)\n"
1420 "lbu $a0, -256($a1)\n"
1421 "lbu $a0, -32768($a1)\n"
1422 "lui $at, 0xABCD\n"
1423 "ori $at, 0xEF00\n"
1424 "daddu $at, $at, $a1\n"
1425 "lbu $a0, 0($at)\n"
1426
1427 "lh $a0, 0($a0)\n"
1428 "lh $a0, 0($a1)\n"
1429 "lh $a0, 2($a1)\n"
1430 "lh $a0, 256($a1)\n"
1431 "lh $a0, 1000($a1)\n"
1432 "lh $a0, 0x7FFE($a1)\n"
1433 "ori $at, $zero, 0x8000\n"
1434 "daddu $at, $at, $a1\n"
1435 "lh $a0, 0($at)\n"
1436 "ori $at, $zero, 0x8000\n"
1437 "daddu $at, $at, $a1\n"
1438 "lh $a0, 2($at)\n"
1439 "lui $at, 1\n"
1440 "daddu $at, $at, $a1\n"
1441 "lh $a0, 0($at)\n"
1442 "lui $at, 0x1234\n"
1443 "ori $at, 0x5678\n"
1444 "daddu $at, $at, $a1\n"
1445 "lh $a0, 0($at)\n"
1446 "lh $a0, -256($a1)\n"
1447 "lh $a0, -32768($a1)\n"
1448 "lui $at, 0xABCD\n"
1449 "ori $at, 0xEF00\n"
1450 "daddu $at, $at, $a1\n"
1451 "lh $a0, 0($at)\n"
1452
1453 "lhu $a0, 0($a0)\n"
1454 "lhu $a0, 0($a1)\n"
1455 "lhu $a0, 2($a1)\n"
1456 "lhu $a0, 256($a1)\n"
1457 "lhu $a0, 1000($a1)\n"
1458 "lhu $a0, 0x7FFE($a1)\n"
1459 "ori $at, $zero, 0x8000\n"
1460 "daddu $at, $at, $a1\n"
1461 "lhu $a0, 0($at)\n"
1462 "ori $at, $zero, 0x8000\n"
1463 "daddu $at, $at, $a1\n"
1464 "lhu $a0, 2($at)\n"
1465 "lui $at, 1\n"
1466 "daddu $at, $at, $a1\n"
1467 "lhu $a0, 0($at)\n"
1468 "lui $at, 0x1234\n"
1469 "ori $at, 0x5678\n"
1470 "daddu $at, $at, $a1\n"
1471 "lhu $a0, 0($at)\n"
1472 "lhu $a0, -256($a1)\n"
1473 "lhu $a0, -32768($a1)\n"
1474 "lui $at, 0xABCD\n"
1475 "ori $at, 0xEF00\n"
1476 "daddu $at, $at, $a1\n"
1477 "lhu $a0, 0($at)\n"
1478
1479 "lw $a0, 0($a0)\n"
1480 "lw $a0, 0($a1)\n"
1481 "lw $a0, 4($a1)\n"
1482 "lw $a0, 256($a1)\n"
1483 "lw $a0, 1000($a1)\n"
1484 "lw $a0, 0x7FFC($a1)\n"
1485 "ori $at, $zero, 0x8000\n"
1486 "daddu $at, $at, $a1\n"
1487 "lw $a0, 0($at)\n"
1488 "ori $at, $zero, 0x8000\n"
1489 "daddu $at, $at, $a1\n"
1490 "lw $a0, 4($at)\n"
1491 "lui $at, 1\n"
1492 "daddu $at, $at, $a1\n"
1493 "lw $a0, 0($at)\n"
1494 "lui $at, 0x1234\n"
1495 "ori $at, 0x5678\n"
1496 "daddu $at, $at, $a1\n"
1497 "lw $a0, 0($at)\n"
1498 "lw $a0, -256($a1)\n"
1499 "lw $a0, -32768($a1)\n"
1500 "lui $at, 0xABCD\n"
1501 "ori $at, 0xEF00\n"
1502 "daddu $at, $at, $a1\n"
1503 "lw $a0, 0($at)\n"
1504
1505 "lwu $a0, 0($a0)\n"
1506 "lwu $a0, 0($a1)\n"
1507 "lwu $a0, 4($a1)\n"
1508 "lwu $a0, 256($a1)\n"
1509 "lwu $a0, 1000($a1)\n"
1510 "lwu $a0, 0x7FFC($a1)\n"
1511 "ori $at, $zero, 0x8000\n"
1512 "daddu $at, $at, $a1\n"
1513 "lwu $a0, 0($at)\n"
1514 "ori $at, $zero, 0x8000\n"
1515 "daddu $at, $at, $a1\n"
1516 "lwu $a0, 4($at)\n"
1517 "lui $at, 1\n"
1518 "daddu $at, $at, $a1\n"
1519 "lwu $a0, 0($at)\n"
1520 "lui $at, 0x1234\n"
1521 "ori $at, 0x5678\n"
1522 "daddu $at, $at, $a1\n"
1523 "lwu $a0, 0($at)\n"
1524 "lwu $a0, -256($a1)\n"
1525 "lwu $a0, -32768($a1)\n"
1526 "lui $at, 0xABCD\n"
1527 "ori $at, 0xEF00\n"
1528 "daddu $at, $at, $a1\n"
1529 "lwu $a0, 0($at)\n"
1530
1531 "ld $a0, 0($a0)\n"
1532 "ld $a0, 0($a1)\n"
1533 "lwu $a0, 4($a1)\n"
1534 "lwu $t3, 8($a1)\n"
1535 "dins $a0, $t3, 32, 32\n"
1536 "ld $a0, 256($a1)\n"
1537 "ld $a0, 1000($a1)\n"
1538 "ori $at, $zero, 0x7FF8\n"
1539 "daddu $at, $at, $a1\n"
1540 "lwu $a0, 4($at)\n"
1541 "lwu $t3, 8($at)\n"
1542 "dins $a0, $t3, 32, 32\n"
1543 "ori $at, $zero, 0x8000\n"
1544 "daddu $at, $at, $a1\n"
1545 "ld $a0, 0($at)\n"
1546 "ori $at, $zero, 0x8000\n"
1547 "daddu $at, $at, $a1\n"
1548 "lwu $a0, 4($at)\n"
1549 "lwu $t3, 8($at)\n"
1550 "dins $a0, $t3, 32, 32\n"
1551 "lui $at, 1\n"
1552 "daddu $at, $at, $a1\n"
1553 "ld $a0, 0($at)\n"
1554 "lui $at, 0x1234\n"
1555 "ori $at, 0x5678\n"
1556 "daddu $at, $at, $a1\n"
1557 "ld $a0, 0($at)\n"
1558 "ld $a0, -256($a1)\n"
1559 "ld $a0, -32768($a1)\n"
1560 "lui $at, 0xABCD\n"
1561 "ori $at, 0xEF00\n"
1562 "daddu $at, $at, $a1\n"
1563 "ld $a0, 0($at)\n";
1564 DriverStr(expected, "LoadFromOffset");
1565}
1566
1567TEST_F(AssemblerMIPS64Test, LoadFpuFromOffset) {
1568 __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0);
1569 __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 4);
1570 __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 256);
1571 __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x7FFC);
1572 __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x8000);
1573 __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x8004);
1574 __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x10000);
1575 __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x12345678);
1576 __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, -256);
1577 __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, -32768);
1578 __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0xABCDEF00);
1579
1580 __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0);
1581 __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 4);
1582 __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 256);
1583 __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x7FFC);
1584 __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x8000);
1585 __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x8004);
1586 __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x10000);
1587 __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x12345678);
1588 __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, -256);
1589 __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, -32768);
1590 __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0xABCDEF00);
1591
1592 const char* expected =
1593 "lwc1 $f0, 0($a0)\n"
1594 "lwc1 $f0, 4($a0)\n"
1595 "lwc1 $f0, 256($a0)\n"
1596 "lwc1 $f0, 0x7FFC($a0)\n"
1597 "ori $at, $zero, 0x8000\n"
1598 "daddu $at, $at, $a0\n"
1599 "lwc1 $f0, 0($at)\n"
1600 "ori $at, $zero, 0x8000\n"
1601 "daddu $at, $at, $a0\n"
1602 "lwc1 $f0, 4($at)\n"
1603 "lui $at, 1\n"
1604 "daddu $at, $at, $a0\n"
1605 "lwc1 $f0, 0($at)\n"
1606 "lui $at, 0x1234\n"
1607 "ori $at, 0x5678\n"
1608 "daddu $at, $at, $a0\n"
1609 "lwc1 $f0, 0($at)\n"
1610 "lwc1 $f0, -256($a0)\n"
1611 "lwc1 $f0, -32768($a0)\n"
1612 "lui $at, 0xABCD\n"
1613 "ori $at, 0xEF00\n"
1614 "daddu $at, $at, $a0\n"
1615 "lwc1 $f0, 0($at)\n"
1616
1617 "ldc1 $f0, 0($a0)\n"
1618 "lwc1 $f0, 4($a0)\n"
1619 "lw $t3, 8($a0)\n"
1620 "mthc1 $t3, $f0\n"
1621 "ldc1 $f0, 256($a0)\n"
1622 "ori $at, $zero, 0x7FF8\n"
1623 "daddu $at, $at, $a0\n"
1624 "lwc1 $f0, 4($at)\n"
1625 "lw $t3, 8($at)\n"
1626 "mthc1 $t3, $f0\n"
1627 "ori $at, $zero, 0x8000\n"
1628 "daddu $at, $at, $a0\n"
1629 "ldc1 $f0, 0($at)\n"
1630 "ori $at, $zero, 0x8000\n"
1631 "daddu $at, $at, $a0\n"
1632 "lwc1 $f0, 4($at)\n"
1633 "lw $t3, 8($at)\n"
1634 "mthc1 $t3, $f0\n"
1635 "lui $at, 1\n"
1636 "daddu $at, $at, $a0\n"
1637 "ldc1 $f0, 0($at)\n"
1638 "lui $at, 0x1234\n"
1639 "ori $at, 0x5678\n"
1640 "daddu $at, $at, $a0\n"
1641 "ldc1 $f0, 0($at)\n"
1642 "ldc1 $f0, -256($a0)\n"
1643 "ldc1 $f0, -32768($a0)\n"
1644 "lui $at, 0xABCD\n"
1645 "ori $at, 0xEF00\n"
1646 "daddu $at, $at, $a0\n"
1647 "ldc1 $f0, 0($at)\n";
1648 DriverStr(expected, "LoadFpuFromOffset");
1649}
1650
1651TEST_F(AssemblerMIPS64Test, StoreToOffset) {
1652 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A0, 0);
1653 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0);
1654 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 1);
1655 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 256);
1656 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 1000);
1657 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x7FFF);
1658 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x8000);
1659 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x8001);
1660 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x10000);
1661 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x12345678);
1662 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, -256);
1663 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, -32768);
1664 __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0xABCDEF00);
1665
1666 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A0, 0);
1667 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0);
1668 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 2);
1669 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 256);
1670 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 1000);
1671 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x7FFE);
1672 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x8000);
1673 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x8002);
1674 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x10000);
1675 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x12345678);
1676 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, -256);
1677 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, -32768);
1678 __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0xABCDEF00);
1679
1680 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A0, 0);
1681 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0);
1682 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 4);
1683 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 256);
1684 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 1000);
1685 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x7FFC);
1686 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x8000);
1687 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x8004);
1688 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x10000);
1689 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x12345678);
1690 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, -256);
1691 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, -32768);
1692 __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0xABCDEF00);
1693
1694 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A0, 0);
1695 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0);
1696 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 4);
1697 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 256);
1698 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 1000);
1699 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x7FFC);
1700 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x8000);
1701 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x8004);
1702 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x10000);
1703 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x12345678);
1704 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, -256);
1705 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, -32768);
1706 __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0xABCDEF00);
1707
1708 const char* expected =
1709 "sb $a0, 0($a0)\n"
1710 "sb $a0, 0($a1)\n"
1711 "sb $a0, 1($a1)\n"
1712 "sb $a0, 256($a1)\n"
1713 "sb $a0, 1000($a1)\n"
1714 "sb $a0, 0x7FFF($a1)\n"
1715 "ori $at, $zero, 0x8000\n"
1716 "daddu $at, $at, $a1\n"
1717 "sb $a0, 0($at)\n"
1718 "ori $at, $zero, 0x8000\n"
1719 "daddu $at, $at, $a1\n"
1720 "sb $a0, 1($at)\n"
1721 "lui $at, 1\n"
1722 "daddu $at, $at, $a1\n"
1723 "sb $a0, 0($at)\n"
1724 "lui $at, 0x1234\n"
1725 "ori $at, 0x5678\n"
1726 "daddu $at, $at, $a1\n"
1727 "sb $a0, 0($at)\n"
1728 "sb $a0, -256($a1)\n"
1729 "sb $a0, -32768($a1)\n"
1730 "lui $at, 0xABCD\n"
1731 "ori $at, 0xEF00\n"
1732 "daddu $at, $at, $a1\n"
1733 "sb $a0, 0($at)\n"
1734
1735 "sh $a0, 0($a0)\n"
1736 "sh $a0, 0($a1)\n"
1737 "sh $a0, 2($a1)\n"
1738 "sh $a0, 256($a1)\n"
1739 "sh $a0, 1000($a1)\n"
1740 "sh $a0, 0x7FFE($a1)\n"
1741 "ori $at, $zero, 0x8000\n"
1742 "daddu $at, $at, $a1\n"
1743 "sh $a0, 0($at)\n"
1744 "ori $at, $zero, 0x8000\n"
1745 "daddu $at, $at, $a1\n"
1746 "sh $a0, 2($at)\n"
1747 "lui $at, 1\n"
1748 "daddu $at, $at, $a1\n"
1749 "sh $a0, 0($at)\n"
1750 "lui $at, 0x1234\n"
1751 "ori $at, 0x5678\n"
1752 "daddu $at, $at, $a1\n"
1753 "sh $a0, 0($at)\n"
1754 "sh $a0, -256($a1)\n"
1755 "sh $a0, -32768($a1)\n"
1756 "lui $at, 0xABCD\n"
1757 "ori $at, 0xEF00\n"
1758 "daddu $at, $at, $a1\n"
1759 "sh $a0, 0($at)\n"
1760
1761 "sw $a0, 0($a0)\n"
1762 "sw $a0, 0($a1)\n"
1763 "sw $a0, 4($a1)\n"
1764 "sw $a0, 256($a1)\n"
1765 "sw $a0, 1000($a1)\n"
1766 "sw $a0, 0x7FFC($a1)\n"
1767 "ori $at, $zero, 0x8000\n"
1768 "daddu $at, $at, $a1\n"
1769 "sw $a0, 0($at)\n"
1770 "ori $at, $zero, 0x8000\n"
1771 "daddu $at, $at, $a1\n"
1772 "sw $a0, 4($at)\n"
1773 "lui $at, 1\n"
1774 "daddu $at, $at, $a1\n"
1775 "sw $a0, 0($at)\n"
1776 "lui $at, 0x1234\n"
1777 "ori $at, 0x5678\n"
1778 "daddu $at, $at, $a1\n"
1779 "sw $a0, 0($at)\n"
1780 "sw $a0, -256($a1)\n"
1781 "sw $a0, -32768($a1)\n"
1782 "lui $at, 0xABCD\n"
1783 "ori $at, 0xEF00\n"
1784 "daddu $at, $at, $a1\n"
1785 "sw $a0, 0($at)\n"
1786
1787 "sd $a0, 0($a0)\n"
1788 "sd $a0, 0($a1)\n"
1789 "sw $a0, 4($a1)\n"
1790 "dsrl32 $t3, $a0, 0\n"
1791 "sw $t3, 8($a1)\n"
1792 "sd $a0, 256($a1)\n"
1793 "sd $a0, 1000($a1)\n"
1794 "ori $at, $zero, 0x7FF8\n"
1795 "daddu $at, $at, $a1\n"
1796 "sw $a0, 4($at)\n"
1797 "dsrl32 $t3, $a0, 0\n"
1798 "sw $t3, 8($at)\n"
1799 "ori $at, $zero, 0x8000\n"
1800 "daddu $at, $at, $a1\n"
1801 "sd $a0, 0($at)\n"
1802 "ori $at, $zero, 0x8000\n"
1803 "daddu $at, $at, $a1\n"
1804 "sw $a0, 4($at)\n"
1805 "dsrl32 $t3, $a0, 0\n"
1806 "sw $t3, 8($at)\n"
1807 "lui $at, 1\n"
1808 "daddu $at, $at, $a1\n"
1809 "sd $a0, 0($at)\n"
1810 "lui $at, 0x1234\n"
1811 "ori $at, 0x5678\n"
1812 "daddu $at, $at, $a1\n"
1813 "sd $a0, 0($at)\n"
1814 "sd $a0, -256($a1)\n"
1815 "sd $a0, -32768($a1)\n"
1816 "lui $at, 0xABCD\n"
1817 "ori $at, 0xEF00\n"
1818 "daddu $at, $at, $a1\n"
1819 "sd $a0, 0($at)\n";
1820 DriverStr(expected, "StoreToOffset");
1821}
1822
1823TEST_F(AssemblerMIPS64Test, StoreFpuToOffset) {
1824 __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0);
1825 __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 4);
1826 __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 256);
1827 __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x7FFC);
1828 __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x8000);
1829 __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x8004);
1830 __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x10000);
1831 __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x12345678);
1832 __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, -256);
1833 __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, -32768);
1834 __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0xABCDEF00);
1835
1836 __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0);
1837 __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 4);
1838 __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 256);
1839 __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x7FFC);
1840 __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x8000);
1841 __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x8004);
1842 __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x10000);
1843 __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x12345678);
1844 __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, -256);
1845 __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, -32768);
1846 __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0xABCDEF00);
1847
1848 const char* expected =
1849 "swc1 $f0, 0($a0)\n"
1850 "swc1 $f0, 4($a0)\n"
1851 "swc1 $f0, 256($a0)\n"
1852 "swc1 $f0, 0x7FFC($a0)\n"
1853 "ori $at, $zero, 0x8000\n"
1854 "daddu $at, $at, $a0\n"
1855 "swc1 $f0, 0($at)\n"
1856 "ori $at, $zero, 0x8000\n"
1857 "daddu $at, $at, $a0\n"
1858 "swc1 $f0, 4($at)\n"
1859 "lui $at, 1\n"
1860 "daddu $at, $at, $a0\n"
1861 "swc1 $f0, 0($at)\n"
1862 "lui $at, 0x1234\n"
1863 "ori $at, 0x5678\n"
1864 "daddu $at, $at, $a0\n"
1865 "swc1 $f0, 0($at)\n"
1866 "swc1 $f0, -256($a0)\n"
1867 "swc1 $f0, -32768($a0)\n"
1868 "lui $at, 0xABCD\n"
1869 "ori $at, 0xEF00\n"
1870 "daddu $at, $at, $a0\n"
1871 "swc1 $f0, 0($at)\n"
1872
1873 "sdc1 $f0, 0($a0)\n"
1874 "mfhc1 $t3, $f0\n"
1875 "swc1 $f0, 4($a0)\n"
1876 "sw $t3, 8($a0)\n"
1877 "sdc1 $f0, 256($a0)\n"
1878 "ori $at, $zero, 0x7FF8\n"
1879 "daddu $at, $at, $a0\n"
1880 "mfhc1 $t3, $f0\n"
1881 "swc1 $f0, 4($at)\n"
1882 "sw $t3, 8($at)\n"
1883 "ori $at, $zero, 0x8000\n"
1884 "daddu $at, $at, $a0\n"
1885 "sdc1 $f0, 0($at)\n"
1886 "ori $at, $zero, 0x8000\n"
1887 "daddu $at, $at, $a0\n"
1888 "mfhc1 $t3, $f0\n"
1889 "swc1 $f0, 4($at)\n"
1890 "sw $t3, 8($at)\n"
1891 "lui $at, 1\n"
1892 "daddu $at, $at, $a0\n"
1893 "sdc1 $f0, 0($at)\n"
1894 "lui $at, 0x1234\n"
1895 "ori $at, 0x5678\n"
1896 "daddu $at, $at, $a0\n"
1897 "sdc1 $f0, 0($at)\n"
1898 "sdc1 $f0, -256($a0)\n"
1899 "sdc1 $f0, -32768($a0)\n"
1900 "lui $at, 0xABCD\n"
1901 "ori $at, 0xEF00\n"
1902 "daddu $at, $at, $a0\n"
1903 "sdc1 $f0, 0($at)\n";
1904 DriverStr(expected, "StoreFpuToOffset");
1905}
1906
Alexey Frunze0960ac52016-12-20 17:24:59 -08001907//////////////////////////////
1908// Loading/adding Constants //
1909//////////////////////////////
Chris Larsenc733dca2016-05-13 16:11:47 -07001910
1911TEST_F(AssemblerMIPS64Test, LoadConst32) {
1912 // IsUint<16>(value)
1913 __ LoadConst32(mips64::V0, 0);
1914 __ LoadConst32(mips64::V0, 65535);
1915 // IsInt<16>(value)
1916 __ LoadConst32(mips64::V0, -1);
1917 __ LoadConst32(mips64::V0, -32768);
1918 // Everything else
1919 __ LoadConst32(mips64::V0, 65536);
1920 __ LoadConst32(mips64::V0, 65537);
1921 __ LoadConst32(mips64::V0, 2147483647);
1922 __ LoadConst32(mips64::V0, -32769);
1923 __ LoadConst32(mips64::V0, -65536);
1924 __ LoadConst32(mips64::V0, -65537);
1925 __ LoadConst32(mips64::V0, -2147483647);
1926 __ LoadConst32(mips64::V0, -2147483648);
1927
1928 const char* expected =
1929 // IsUint<16>(value)
1930 "ori $v0, $zero, 0\n" // __ LoadConst32(mips64::V0, 0);
1931 "ori $v0, $zero, 65535\n" // __ LoadConst32(mips64::V0, 65535);
1932 // IsInt<16>(value)
1933 "addiu $v0, $zero, -1\n" // __ LoadConst32(mips64::V0, -1);
1934 "addiu $v0, $zero, -32768\n" // __ LoadConst32(mips64::V0, -32768);
1935 // Everything else
1936 "lui $v0, 1\n" // __ LoadConst32(mips64::V0, 65536);
1937 "lui $v0, 1\n" // __ LoadConst32(mips64::V0, 65537);
1938 "ori $v0, 1\n" // "
1939 "lui $v0, 32767\n" // __ LoadConst32(mips64::V0, 2147483647);
1940 "ori $v0, 65535\n" // "
1941 "lui $v0, 65535\n" // __ LoadConst32(mips64::V0, -32769);
1942 "ori $v0, 32767\n" // "
1943 "lui $v0, 65535\n" // __ LoadConst32(mips64::V0, -65536);
1944 "lui $v0, 65534\n" // __ LoadConst32(mips64::V0, -65537);
1945 "ori $v0, 65535\n" // "
1946 "lui $v0, 32768\n" // __ LoadConst32(mips64::V0, -2147483647);
1947 "ori $v0, 1\n" // "
1948 "lui $v0, 32768\n"; // __ LoadConst32(mips64::V0, -2147483648);
1949 DriverStr(expected, "LoadConst32");
1950}
1951
Alexey Frunze0960ac52016-12-20 17:24:59 -08001952TEST_F(AssemblerMIPS64Test, Addiu32) {
1953 __ Addiu32(mips64::A1, mips64::A2, -0x8000);
1954 __ Addiu32(mips64::A1, mips64::A2, +0);
1955 __ Addiu32(mips64::A1, mips64::A2, +0x7FFF);
1956 __ Addiu32(mips64::A1, mips64::A2, -0x8001);
1957 __ Addiu32(mips64::A1, mips64::A2, +0x8000);
1958 __ Addiu32(mips64::A1, mips64::A2, -0x10000);
1959 __ Addiu32(mips64::A1, mips64::A2, +0x10000);
1960 __ Addiu32(mips64::A1, mips64::A2, +0x12345678);
1961
1962 const char* expected =
1963 "addiu $a1, $a2, -0x8000\n"
1964 "addiu $a1, $a2, 0\n"
1965 "addiu $a1, $a2, 0x7FFF\n"
1966 "aui $a1, $a2, 0xFFFF\n"
1967 "addiu $a1, $a1, 0x7FFF\n"
1968 "aui $a1, $a2, 1\n"
1969 "addiu $a1, $a1, -0x8000\n"
1970 "aui $a1, $a2, 0xFFFF\n"
1971 "aui $a1, $a2, 1\n"
1972 "aui $a1, $a2, 0x1234\n"
1973 "addiu $a1, $a1, 0x5678\n";
1974 DriverStr(expected, "Addiu32");
1975}
1976
Chris Larsenc733dca2016-05-13 16:11:47 -07001977static uint64_t SignExtend16To64(uint16_t n) {
1978 return static_cast<int16_t>(n);
1979}
1980
1981// The art::mips64::Mips64Assembler::LoadConst64() method uses a template
1982// to minimize the number of instructions needed to load a 64-bit constant
1983// value into a register. The template calls various methods which emit
1984// MIPS machine instructions. This struct (class) uses the same template
1985// but overrides the definitions of the methods which emit MIPS instructions
1986// to use methods which simulate the operation of the corresponding MIPS
1987// instructions. After invoking LoadConst64() the target register should
1988// contain the same 64-bit value as was input to LoadConst64(). If the
1989// simulated register doesn't contain the correct value then there is probably
1990// an error in the template function.
1991struct LoadConst64Tester {
1992 LoadConst64Tester() {
1993 // Initialize all of the registers for simulation to zero.
1994 for (int r = 0; r < 32; r++) {
1995 regs_[r] = 0;
1996 }
1997 // Clear all of the path flags.
1998 loadconst64_paths_ = art::mips64::kLoadConst64PathZero;
1999 }
2000 void Addiu(mips64::GpuRegister rd, mips64::GpuRegister rs, uint16_t c) {
2001 regs_[rd] = static_cast<int32_t>(regs_[rs] + SignExtend16To64(c));
2002 }
2003 void Daddiu(mips64::GpuRegister rd, mips64::GpuRegister rs, uint16_t c) {
2004 regs_[rd] = regs_[rs] + SignExtend16To64(c);
2005 }
2006 void Dahi(mips64::GpuRegister rd, uint16_t c) {
2007 regs_[rd] += SignExtend16To64(c) << 32;
2008 }
2009 void Dati(mips64::GpuRegister rd, uint16_t c) {
2010 regs_[rd] += SignExtend16To64(c) << 48;
2011 }
2012 void Dinsu(mips64::GpuRegister rt, mips64::GpuRegister rs, int pos, int size) {
2013 CHECK(IsUint<5>(pos - 32)) << pos;
2014 CHECK(IsUint<5>(size - 1)) << size;
2015 CHECK(IsUint<5>(pos + size - 33)) << pos << " + " << size;
2016 uint64_t src_mask = (UINT64_C(1) << size) - 1;
2017 uint64_t dsk_mask = ~(src_mask << pos);
2018
2019 regs_[rt] = (regs_[rt] & dsk_mask) | ((regs_[rs] & src_mask) << pos);
2020 }
2021 void Dsll(mips64::GpuRegister rd, mips64::GpuRegister rt, int shamt) {
2022 regs_[rd] = regs_[rt] << (shamt & 0x1f);
2023 }
2024 void Dsll32(mips64::GpuRegister rd, mips64::GpuRegister rt, int shamt) {
2025 regs_[rd] = regs_[rt] << (32 + (shamt & 0x1f));
2026 }
2027 void Dsrl(mips64::GpuRegister rd, mips64::GpuRegister rt, int shamt) {
2028 regs_[rd] = regs_[rt] >> (shamt & 0x1f);
2029 }
2030 void Dsrl32(mips64::GpuRegister rd, mips64::GpuRegister rt, int shamt) {
2031 regs_[rd] = regs_[rt] >> (32 + (shamt & 0x1f));
2032 }
2033 void Lui(mips64::GpuRegister rd, uint16_t c) {
2034 regs_[rd] = SignExtend16To64(c) << 16;
2035 }
2036 void Ori(mips64::GpuRegister rd, mips64::GpuRegister rs, uint16_t c) {
2037 regs_[rd] = regs_[rs] | c;
2038 }
2039 void LoadConst32(mips64::GpuRegister rd, int32_t c) {
2040 CHECK_NE(rd, 0);
2041 mips64::TemplateLoadConst32<LoadConst64Tester>(this, rd, c);
2042 CHECK_EQ(regs_[rd], static_cast<uint64_t>(c));
2043 }
2044 void LoadConst64(mips64::GpuRegister rd, int64_t c) {
2045 CHECK_NE(rd, 0);
2046 mips64::TemplateLoadConst64<LoadConst64Tester>(this, rd, c);
2047 CHECK_EQ(regs_[rd], static_cast<uint64_t>(c));
2048 }
2049 uint64_t regs_[32];
2050
2051 // Getter function for loadconst64_paths_.
2052 int GetPathsCovered() {
2053 return loadconst64_paths_;
2054 }
2055
2056 void RecordLoadConst64Path(int value) {
2057 loadconst64_paths_ |= value;
2058 }
2059
2060 private:
2061 // This variable holds a bitmask to tell us which paths were taken
2062 // through the template function which loads 64-bit values.
2063 int loadconst64_paths_;
2064};
2065
2066TEST_F(AssemblerMIPS64Test, LoadConst64) {
2067 const uint16_t imms[] = {
2068 0, 1, 2, 3, 4, 0x33, 0x66, 0x55, 0x99, 0xaa, 0xcc, 0xff, 0x5500, 0x5555,
2069 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff, 0x8000, 0x8001, 0x8002, 0x8003, 0x8004,
2070 0xaaaa, 0xfffc, 0xfffd, 0xfffe, 0xffff
2071 };
2072 unsigned d0, d1, d2, d3;
2073 LoadConst64Tester tester;
2074
2075 union {
2076 int64_t v64;
2077 uint16_t v16[4];
2078 } u;
2079
2080 for (d3 = 0; d3 < sizeof imms / sizeof imms[0]; d3++) {
2081 u.v16[3] = imms[d3];
2082
2083 for (d2 = 0; d2 < sizeof imms / sizeof imms[0]; d2++) {
2084 u.v16[2] = imms[d2];
2085
2086 for (d1 = 0; d1 < sizeof imms / sizeof imms[0]; d1++) {
2087 u.v16[1] = imms[d1];
2088
2089 for (d0 = 0; d0 < sizeof imms / sizeof imms[0]; d0++) {
2090 u.v16[0] = imms[d0];
2091
2092 tester.LoadConst64(mips64::V0, u.v64);
2093 }
2094 }
2095 }
2096 }
2097
2098 // Verify that we tested all paths through the "load 64-bit value"
2099 // function template.
2100 EXPECT_EQ(tester.GetPathsCovered(), art::mips64::kLoadConst64PathAllPaths);
2101}
2102
Lazar Trsicd9672662015-09-03 17:33:01 +02002103#undef __
2104
Chris Larsendbce0d72015-09-17 13:34:00 -07002105} // namespace art