1/*
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
27#define __ GetAssembler()->
28
29namespace 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
53  std::string GetAssemblerCmdName() OVERRIDE {
54    // We assemble and link for MIPS64R6. See GetAssemblerParameters() for details.
55    return "gcc";
56  }
57
58  std::string GetAssemblerParameters() OVERRIDE {
59    // 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);
73  }
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
205  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
270 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
282///////////////////
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
302TEST_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
318TEST_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, 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
506TEST_F(AssemblerMIPS64Test, CvtDL) {
507  DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtdl, "cvt.d.l ${reg1}, ${reg2}"), "cvt.d.l");
508}
509
510TEST_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
530TEST_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
546TEST_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
570////////////////
571// CALL / JMP //
572////////////////
573
574TEST_F(AssemblerMIPS64Test, Jalr) {
575  DriverStr(".set noreorder\n" +
576            RepeatRRNoDupes(&mips64::Mips64Assembler::Jalr, "jalr ${reg1}, ${reg2}"), "jalr");
577}
578
579TEST_F(AssemblerMIPS64Test, Jialc) {
580  mips64::Mips64Label label1, label2;
581  __ Jialc(&label1, mips64::T9);
582  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);
587  __ Jialc(&label2, mips64::T9);
588  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);
593  __ Jialc(&label1, mips64::T9);
594
595  std::string expected =
596      ".set noreorder\n"
597      "lapc $t9, 1f\n"
598      "jialc $t9, 0\n" +
599      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
600      "1:\n"
601      "lapc $t9, 2f\n"
602      "jialc $t9, 0\n" +
603      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
604      "2:\n"
605      "lapc $t9, 1b\n"
606      "jialc $t9, 0\n";
607  DriverStr(expected, "Jialc");
608}
609
610TEST_F(AssemblerMIPS64Test, LongJialc) {
611  mips64::Mips64Label label1, label2;
612  __ Jialc(&label1, mips64::T9);
613  constexpr uint32_t kAdduCount1 = (1u << 18) + 1;
614  for (uint32_t i = 0; i != kAdduCount1; ++i) {
615    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
616  }
617  __ Bind(&label1);
618  __ Jialc(&label2, mips64::T9);
619  constexpr uint32_t kAdduCount2 = (1u << 18) + 1;
620  for (uint32_t i = 0; i != kAdduCount2; ++i) {
621    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
622  }
623  __ Bind(&label2);
624  __ Jialc(&label1, mips64::T9);
625
626  uint32_t offset_forward1 = 3 + kAdduCount1;  // 3: account for auipc, daddiu and jic.
627  offset_forward1 <<= 2;
628  offset_forward1 += (offset_forward1 & 0x8000) << 1;  // Account for sign extension in daddiu.
629
630  uint32_t offset_forward2 = 3 + kAdduCount2;  // 3: account for auipc, daddiu and jic.
631  offset_forward2 <<= 2;
632  offset_forward2 += (offset_forward2 & 0x8000) << 1;  // Account for sign extension in daddiu.
633
634  uint32_t offset_back = -(3 + kAdduCount2);  // 3: account for auipc, daddiu and jic.
635  offset_back <<= 2;
636  offset_back += (offset_back & 0x8000) << 1;  // Account for sign extension in daddiu.
637
638  std::ostringstream oss;
639  oss <<
640      ".set noreorder\n"
641      "auipc $t9, 0x" << std::hex << High16Bits(offset_forward1) << "\n"
642      "daddiu $t9, 0x" << std::hex << Low16Bits(offset_forward1) << "\n"
643      "jialc $t9, 0\n" <<
644      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") <<
645      "1:\n"
646      "auipc $t9, 0x" << std::hex << High16Bits(offset_forward2) << "\n"
647      "daddiu $t9, 0x" << std::hex << Low16Bits(offset_forward2) << "\n"
648      "jialc $t9, 0\n" <<
649      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") <<
650      "2:\n"
651      "auipc $t9, 0x" << std::hex << High16Bits(offset_back) << "\n"
652      "daddiu $t9, 0x" << std::hex << Low16Bits(offset_back) << "\n"
653      "jialc $t9, 0\n";
654  std::string expected = oss.str();
655  DriverStr(expected, "LongJialc");
656}
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
734TEST_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
786TEST_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");
824}
825
826//////////
827// MISC //
828//////////
829
830TEST_F(AssemblerMIPS64Test, Bitswap) {
831  DriverStr(RepeatRR(&mips64::Mips64Assembler::Bitswap, "bitswap ${reg1}, ${reg2}"), "bitswap");
832}
833
834TEST_F(AssemblerMIPS64Test, Dbitswap) {
835  DriverStr(RepeatRR(&mips64::Mips64Assembler::Dbitswap, "dbitswap ${reg1}, ${reg2}"), "dbitswap");
836}
837
838TEST_F(AssemblerMIPS64Test, Seb) {
839  DriverStr(RepeatRR(&mips64::Mips64Assembler::Seb, "seb ${reg1}, ${reg2}"), "seb");
840}
841
842TEST_F(AssemblerMIPS64Test, Seh) {
843  DriverStr(RepeatRR(&mips64::Mips64Assembler::Seh, "seh ${reg1}, ${reg2}"), "seh");
844}
845
846TEST_F(AssemblerMIPS64Test, Dsbh) {
847  DriverStr(RepeatRR(&mips64::Mips64Assembler::Dsbh, "dsbh ${reg1}, ${reg2}"), "dsbh");
848}
849
850TEST_F(AssemblerMIPS64Test, Dshd) {
851  DriverStr(RepeatRR(&mips64::Mips64Assembler::Dshd, "dshd ${reg1}, ${reg2}"), "dshd");
852}
853
854TEST_F(AssemblerMIPS64Test, Dext) {
855  std::vector<mips64::GpuRegister*> reg1_registers = GetRegisters();
856  std::vector<mips64::GpuRegister*> reg2_registers = GetRegisters();
857  WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * 33 * 16);
858  std::ostringstream expected;
859  for (mips64::GpuRegister* reg1 : reg1_registers) {
860    for (mips64::GpuRegister* reg2 : reg2_registers) {
861      for (int32_t pos = 0; pos < 32; pos++) {
862        for (int32_t size = 1; size <= 32; size++) {
863          __ Dext(*reg1, *reg2, pos, size);
864          expected << "dext $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n";
865        }
866      }
867    }
868  }
869
870  DriverStr(expected.str(), "Dext");
871}
872
873TEST_F(AssemblerMIPS64Test, Dinsu) {
874  std::vector<mips64::GpuRegister*> reg1_registers = GetRegisters();
875  std::vector<mips64::GpuRegister*> reg2_registers = GetRegisters();
876  WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * 33 * 16);
877  std::ostringstream expected;
878  for (mips64::GpuRegister* reg1 : reg1_registers) {
879    for (mips64::GpuRegister* reg2 : reg2_registers) {
880      for (int32_t pos = 32; pos < 64; pos++) {
881        for (int32_t size = 1; pos + size <= 64; size++) {
882          __ Dinsu(*reg1, *reg2, pos, size);
883          expected << "dinsu $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n";
884        }
885      }
886    }
887  }
888
889  DriverStr(expected.str(), "Dinsu");
890}
891
892TEST_F(AssemblerMIPS64Test, Wsbh) {
893  DriverStr(RepeatRR(&mips64::Mips64Assembler::Wsbh, "wsbh ${reg1}, ${reg2}"), "wsbh");
894}
895
896TEST_F(AssemblerMIPS64Test, Sll) {
897  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sll, 5, "sll ${reg1}, ${reg2}, {imm}"), "sll");
898}
899
900TEST_F(AssemblerMIPS64Test, Srl) {
901  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Srl, 5, "srl ${reg1}, ${reg2}, {imm}"), "srl");
902}
903
904TEST_F(AssemblerMIPS64Test, Rotr) {
905  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Rotr, 5, "rotr ${reg1}, ${reg2}, {imm}"), "rotr");
906}
907
908TEST_F(AssemblerMIPS64Test, Sra) {
909  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sra, 5, "sra ${reg1}, ${reg2}, {imm}"), "sra");
910}
911
912TEST_F(AssemblerMIPS64Test, Sllv) {
913  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Sllv, "sllv ${reg1}, ${reg2}, ${reg3}"), "sllv");
914}
915
916TEST_F(AssemblerMIPS64Test, Srlv) {
917  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Srlv, "srlv ${reg1}, ${reg2}, ${reg3}"), "srlv");
918}
919
920TEST_F(AssemblerMIPS64Test, Rotrv) {
921  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Rotrv, "rotrv ${reg1}, ${reg2}, ${reg3}"), "rotrv");
922}
923
924TEST_F(AssemblerMIPS64Test, Srav) {
925  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Srav, "srav ${reg1}, ${reg2}, ${reg3}"), "srav");
926}
927
928TEST_F(AssemblerMIPS64Test, Dsll) {
929  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsll, 5, "dsll ${reg1}, ${reg2}, {imm}"), "dsll");
930}
931
932TEST_F(AssemblerMIPS64Test, Dsrl) {
933  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsrl, 5, "dsrl ${reg1}, ${reg2}, {imm}"), "dsrl");
934}
935
936TEST_F(AssemblerMIPS64Test, Drotr) {
937  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Drotr, 5, "drotr ${reg1}, ${reg2}, {imm}"),
938            "drotr");
939}
940
941TEST_F(AssemblerMIPS64Test, Dsra) {
942  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsra, 5, "dsra ${reg1}, ${reg2}, {imm}"), "dsra");
943}
944
945TEST_F(AssemblerMIPS64Test, Dsll32) {
946  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsll32, 5, "dsll32 ${reg1}, ${reg2}, {imm}"),
947            "dsll32");
948}
949
950TEST_F(AssemblerMIPS64Test, Dsrl32) {
951  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsrl32, 5, "dsrl32 ${reg1}, ${reg2}, {imm}"),
952            "dsrl32");
953}
954
955TEST_F(AssemblerMIPS64Test, Drotr32) {
956  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Drotr32, 5, "drotr32 ${reg1}, ${reg2}, {imm}"),
957            "drotr32");
958}
959
960TEST_F(AssemblerMIPS64Test, Dsra32) {
961  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsra32, 5, "dsra32 ${reg1}, ${reg2}, {imm}"),
962            "dsra32");
963}
964
965TEST_F(AssemblerMIPS64Test, Sc) {
966  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sc, -9, "sc ${reg1}, {imm}(${reg2})"), "sc");
967}
968
969TEST_F(AssemblerMIPS64Test, Scd) {
970  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Scd, -9, "scd ${reg1}, {imm}(${reg2})"), "scd");
971}
972
973TEST_F(AssemblerMIPS64Test, Ll) {
974  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Ll, -9, "ll ${reg1}, {imm}(${reg2})"), "ll");
975}
976
977TEST_F(AssemblerMIPS64Test, Lld) {
978  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Lld, -9, "lld ${reg1}, {imm}(${reg2})"), "lld");
979}
980
981TEST_F(AssemblerMIPS64Test, Seleqz) {
982  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Seleqz, "seleqz ${reg1}, ${reg2}, ${reg3}"),
983            "seleqz");
984}
985
986TEST_F(AssemblerMIPS64Test, Selnez) {
987  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Selnez, "selnez ${reg1}, ${reg2}, ${reg3}"),
988            "selnez");
989}
990
991TEST_F(AssemblerMIPS64Test, Clz) {
992  DriverStr(RepeatRR(&mips64::Mips64Assembler::Clz, "clz ${reg1}, ${reg2}"), "clz");
993}
994
995TEST_F(AssemblerMIPS64Test, Clo) {
996  DriverStr(RepeatRR(&mips64::Mips64Assembler::Clo, "clo ${reg1}, ${reg2}"), "clo");
997}
998
999TEST_F(AssemblerMIPS64Test, Dclz) {
1000  DriverStr(RepeatRR(&mips64::Mips64Assembler::Dclz, "dclz ${reg1}, ${reg2}"), "dclz");
1001}
1002
1003TEST_F(AssemblerMIPS64Test, Dclo) {
1004  DriverStr(RepeatRR(&mips64::Mips64Assembler::Dclo, "dclo ${reg1}, ${reg2}"), "dclo");
1005}
1006
1007TEST_F(AssemblerMIPS64Test, LoadFromOffset) {
1008  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A0, 0);
1009  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0);
1010  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 1);
1011  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 256);
1012  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 1000);
1013  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x7FFF);
1014  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x8000);
1015  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x8001);
1016  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x10000);
1017  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x12345678);
1018  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, -256);
1019  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, -32768);
1020  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0xABCDEF00);
1021
1022  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A0, 0);
1023  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0);
1024  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 1);
1025  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 256);
1026  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 1000);
1027  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x7FFF);
1028  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x8000);
1029  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x8001);
1030  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x10000);
1031  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x12345678);
1032  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, -256);
1033  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, -32768);
1034  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0xABCDEF00);
1035
1036  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A0, 0);
1037  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0);
1038  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 2);
1039  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 256);
1040  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 1000);
1041  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x7FFE);
1042  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x8000);
1043  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x8002);
1044  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x10000);
1045  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x12345678);
1046  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, -256);
1047  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, -32768);
1048  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0xABCDEF00);
1049
1050  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A0, 0);
1051  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0);
1052  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 2);
1053  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 256);
1054  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 1000);
1055  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x7FFE);
1056  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x8000);
1057  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x8002);
1058  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x10000);
1059  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x12345678);
1060  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, -256);
1061  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, -32768);
1062  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0xABCDEF00);
1063
1064  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A0, 0);
1065  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0);
1066  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 4);
1067  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 256);
1068  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 1000);
1069  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x7FFC);
1070  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x8000);
1071  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x8004);
1072  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x10000);
1073  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x12345678);
1074  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, -256);
1075  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, -32768);
1076  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0xABCDEF00);
1077
1078  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A0, 0);
1079  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0);
1080  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 4);
1081  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 256);
1082  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 1000);
1083  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x7FFC);
1084  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x8000);
1085  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x8004);
1086  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x10000);
1087  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x12345678);
1088  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, -256);
1089  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, -32768);
1090  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0xABCDEF00);
1091
1092  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A0, 0);
1093  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0);
1094  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 4);
1095  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 256);
1096  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 1000);
1097  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x7FFC);
1098  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x8000);
1099  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x8004);
1100  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x10000);
1101  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x12345678);
1102  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, -256);
1103  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, -32768);
1104  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0xABCDEF00);
1105
1106  const char* expected =
1107      "lb $a0, 0($a0)\n"
1108      "lb $a0, 0($a1)\n"
1109      "lb $a0, 1($a1)\n"
1110      "lb $a0, 256($a1)\n"
1111      "lb $a0, 1000($a1)\n"
1112      "lb $a0, 0x7FFF($a1)\n"
1113      "ori $at, $zero, 0x8000\n"
1114      "daddu $at, $at, $a1\n"
1115      "lb $a0, 0($at)\n"
1116      "ori $at, $zero, 0x8000\n"
1117      "daddu $at, $at, $a1\n"
1118      "lb $a0, 1($at)\n"
1119      "lui $at, 1\n"
1120      "daddu $at, $at, $a1\n"
1121      "lb $a0, 0($at)\n"
1122      "lui $at, 0x1234\n"
1123      "ori $at, 0x5678\n"
1124      "daddu $at, $at, $a1\n"
1125      "lb $a0, 0($at)\n"
1126      "lb $a0, -256($a1)\n"
1127      "lb $a0, -32768($a1)\n"
1128      "lui $at, 0xABCD\n"
1129      "ori $at, 0xEF00\n"
1130      "daddu $at, $at, $a1\n"
1131      "lb $a0, 0($at)\n"
1132
1133      "lbu $a0, 0($a0)\n"
1134      "lbu $a0, 0($a1)\n"
1135      "lbu $a0, 1($a1)\n"
1136      "lbu $a0, 256($a1)\n"
1137      "lbu $a0, 1000($a1)\n"
1138      "lbu $a0, 0x7FFF($a1)\n"
1139      "ori $at, $zero, 0x8000\n"
1140      "daddu $at, $at, $a1\n"
1141      "lbu $a0, 0($at)\n"
1142      "ori $at, $zero, 0x8000\n"
1143      "daddu $at, $at, $a1\n"
1144      "lbu $a0, 1($at)\n"
1145      "lui $at, 1\n"
1146      "daddu $at, $at, $a1\n"
1147      "lbu $a0, 0($at)\n"
1148      "lui $at, 0x1234\n"
1149      "ori $at, 0x5678\n"
1150      "daddu $at, $at, $a1\n"
1151      "lbu $a0, 0($at)\n"
1152      "lbu $a0, -256($a1)\n"
1153      "lbu $a0, -32768($a1)\n"
1154      "lui $at, 0xABCD\n"
1155      "ori $at, 0xEF00\n"
1156      "daddu $at, $at, $a1\n"
1157      "lbu $a0, 0($at)\n"
1158
1159      "lh $a0, 0($a0)\n"
1160      "lh $a0, 0($a1)\n"
1161      "lh $a0, 2($a1)\n"
1162      "lh $a0, 256($a1)\n"
1163      "lh $a0, 1000($a1)\n"
1164      "lh $a0, 0x7FFE($a1)\n"
1165      "ori $at, $zero, 0x8000\n"
1166      "daddu $at, $at, $a1\n"
1167      "lh $a0, 0($at)\n"
1168      "ori $at, $zero, 0x8000\n"
1169      "daddu $at, $at, $a1\n"
1170      "lh $a0, 2($at)\n"
1171      "lui $at, 1\n"
1172      "daddu $at, $at, $a1\n"
1173      "lh $a0, 0($at)\n"
1174      "lui $at, 0x1234\n"
1175      "ori $at, 0x5678\n"
1176      "daddu $at, $at, $a1\n"
1177      "lh $a0, 0($at)\n"
1178      "lh $a0, -256($a1)\n"
1179      "lh $a0, -32768($a1)\n"
1180      "lui $at, 0xABCD\n"
1181      "ori $at, 0xEF00\n"
1182      "daddu $at, $at, $a1\n"
1183      "lh $a0, 0($at)\n"
1184
1185      "lhu $a0, 0($a0)\n"
1186      "lhu $a0, 0($a1)\n"
1187      "lhu $a0, 2($a1)\n"
1188      "lhu $a0, 256($a1)\n"
1189      "lhu $a0, 1000($a1)\n"
1190      "lhu $a0, 0x7FFE($a1)\n"
1191      "ori $at, $zero, 0x8000\n"
1192      "daddu $at, $at, $a1\n"
1193      "lhu $a0, 0($at)\n"
1194      "ori $at, $zero, 0x8000\n"
1195      "daddu $at, $at, $a1\n"
1196      "lhu $a0, 2($at)\n"
1197      "lui $at, 1\n"
1198      "daddu $at, $at, $a1\n"
1199      "lhu $a0, 0($at)\n"
1200      "lui $at, 0x1234\n"
1201      "ori $at, 0x5678\n"
1202      "daddu $at, $at, $a1\n"
1203      "lhu $a0, 0($at)\n"
1204      "lhu $a0, -256($a1)\n"
1205      "lhu $a0, -32768($a1)\n"
1206      "lui $at, 0xABCD\n"
1207      "ori $at, 0xEF00\n"
1208      "daddu $at, $at, $a1\n"
1209      "lhu $a0, 0($at)\n"
1210
1211      "lw $a0, 0($a0)\n"
1212      "lw $a0, 0($a1)\n"
1213      "lw $a0, 4($a1)\n"
1214      "lw $a0, 256($a1)\n"
1215      "lw $a0, 1000($a1)\n"
1216      "lw $a0, 0x7FFC($a1)\n"
1217      "ori $at, $zero, 0x8000\n"
1218      "daddu $at, $at, $a1\n"
1219      "lw $a0, 0($at)\n"
1220      "ori $at, $zero, 0x8000\n"
1221      "daddu $at, $at, $a1\n"
1222      "lw $a0, 4($at)\n"
1223      "lui $at, 1\n"
1224      "daddu $at, $at, $a1\n"
1225      "lw $a0, 0($at)\n"
1226      "lui $at, 0x1234\n"
1227      "ori $at, 0x5678\n"
1228      "daddu $at, $at, $a1\n"
1229      "lw $a0, 0($at)\n"
1230      "lw $a0, -256($a1)\n"
1231      "lw $a0, -32768($a1)\n"
1232      "lui $at, 0xABCD\n"
1233      "ori $at, 0xEF00\n"
1234      "daddu $at, $at, $a1\n"
1235      "lw $a0, 0($at)\n"
1236
1237      "lwu $a0, 0($a0)\n"
1238      "lwu $a0, 0($a1)\n"
1239      "lwu $a0, 4($a1)\n"
1240      "lwu $a0, 256($a1)\n"
1241      "lwu $a0, 1000($a1)\n"
1242      "lwu $a0, 0x7FFC($a1)\n"
1243      "ori $at, $zero, 0x8000\n"
1244      "daddu $at, $at, $a1\n"
1245      "lwu $a0, 0($at)\n"
1246      "ori $at, $zero, 0x8000\n"
1247      "daddu $at, $at, $a1\n"
1248      "lwu $a0, 4($at)\n"
1249      "lui $at, 1\n"
1250      "daddu $at, $at, $a1\n"
1251      "lwu $a0, 0($at)\n"
1252      "lui $at, 0x1234\n"
1253      "ori $at, 0x5678\n"
1254      "daddu $at, $at, $a1\n"
1255      "lwu $a0, 0($at)\n"
1256      "lwu $a0, -256($a1)\n"
1257      "lwu $a0, -32768($a1)\n"
1258      "lui $at, 0xABCD\n"
1259      "ori $at, 0xEF00\n"
1260      "daddu $at, $at, $a1\n"
1261      "lwu $a0, 0($at)\n"
1262
1263      "ld $a0, 0($a0)\n"
1264      "ld $a0, 0($a1)\n"
1265      "lwu $a0, 4($a1)\n"
1266      "lwu $t3, 8($a1)\n"
1267      "dins $a0, $t3, 32, 32\n"
1268      "ld $a0, 256($a1)\n"
1269      "ld $a0, 1000($a1)\n"
1270      "ori $at, $zero, 0x7FF8\n"
1271      "daddu $at, $at, $a1\n"
1272      "lwu $a0, 4($at)\n"
1273      "lwu $t3, 8($at)\n"
1274      "dins $a0, $t3, 32, 32\n"
1275      "ori $at, $zero, 0x8000\n"
1276      "daddu $at, $at, $a1\n"
1277      "ld $a0, 0($at)\n"
1278      "ori $at, $zero, 0x8000\n"
1279      "daddu $at, $at, $a1\n"
1280      "lwu $a0, 4($at)\n"
1281      "lwu $t3, 8($at)\n"
1282      "dins $a0, $t3, 32, 32\n"
1283      "lui $at, 1\n"
1284      "daddu $at, $at, $a1\n"
1285      "ld $a0, 0($at)\n"
1286      "lui $at, 0x1234\n"
1287      "ori $at, 0x5678\n"
1288      "daddu $at, $at, $a1\n"
1289      "ld $a0, 0($at)\n"
1290      "ld $a0, -256($a1)\n"
1291      "ld $a0, -32768($a1)\n"
1292      "lui $at, 0xABCD\n"
1293      "ori $at, 0xEF00\n"
1294      "daddu $at, $at, $a1\n"
1295      "ld $a0, 0($at)\n";
1296  DriverStr(expected, "LoadFromOffset");
1297}
1298
1299TEST_F(AssemblerMIPS64Test, LoadFpuFromOffset) {
1300  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0);
1301  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 4);
1302  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 256);
1303  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x7FFC);
1304  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x8000);
1305  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x8004);
1306  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x10000);
1307  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x12345678);
1308  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, -256);
1309  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, -32768);
1310  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0xABCDEF00);
1311
1312  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0);
1313  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 4);
1314  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 256);
1315  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x7FFC);
1316  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x8000);
1317  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x8004);
1318  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x10000);
1319  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x12345678);
1320  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, -256);
1321  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, -32768);
1322  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0xABCDEF00);
1323
1324  const char* expected =
1325      "lwc1 $f0, 0($a0)\n"
1326      "lwc1 $f0, 4($a0)\n"
1327      "lwc1 $f0, 256($a0)\n"
1328      "lwc1 $f0, 0x7FFC($a0)\n"
1329      "ori $at, $zero, 0x8000\n"
1330      "daddu $at, $at, $a0\n"
1331      "lwc1 $f0, 0($at)\n"
1332      "ori $at, $zero, 0x8000\n"
1333      "daddu $at, $at, $a0\n"
1334      "lwc1 $f0, 4($at)\n"
1335      "lui $at, 1\n"
1336      "daddu $at, $at, $a0\n"
1337      "lwc1 $f0, 0($at)\n"
1338      "lui $at, 0x1234\n"
1339      "ori $at, 0x5678\n"
1340      "daddu $at, $at, $a0\n"
1341      "lwc1 $f0, 0($at)\n"
1342      "lwc1 $f0, -256($a0)\n"
1343      "lwc1 $f0, -32768($a0)\n"
1344      "lui $at, 0xABCD\n"
1345      "ori $at, 0xEF00\n"
1346      "daddu $at, $at, $a0\n"
1347      "lwc1 $f0, 0($at)\n"
1348
1349      "ldc1 $f0, 0($a0)\n"
1350      "lwc1 $f0, 4($a0)\n"
1351      "lw $t3, 8($a0)\n"
1352      "mthc1 $t3, $f0\n"
1353      "ldc1 $f0, 256($a0)\n"
1354      "ori $at, $zero, 0x7FF8\n"
1355      "daddu $at, $at, $a0\n"
1356      "lwc1 $f0, 4($at)\n"
1357      "lw $t3, 8($at)\n"
1358      "mthc1 $t3, $f0\n"
1359      "ori $at, $zero, 0x8000\n"
1360      "daddu $at, $at, $a0\n"
1361      "ldc1 $f0, 0($at)\n"
1362      "ori $at, $zero, 0x8000\n"
1363      "daddu $at, $at, $a0\n"
1364      "lwc1 $f0, 4($at)\n"
1365      "lw $t3, 8($at)\n"
1366      "mthc1 $t3, $f0\n"
1367      "lui $at, 1\n"
1368      "daddu $at, $at, $a0\n"
1369      "ldc1 $f0, 0($at)\n"
1370      "lui $at, 0x1234\n"
1371      "ori $at, 0x5678\n"
1372      "daddu $at, $at, $a0\n"
1373      "ldc1 $f0, 0($at)\n"
1374      "ldc1 $f0, -256($a0)\n"
1375      "ldc1 $f0, -32768($a0)\n"
1376      "lui $at, 0xABCD\n"
1377      "ori $at, 0xEF00\n"
1378      "daddu $at, $at, $a0\n"
1379      "ldc1 $f0, 0($at)\n";
1380  DriverStr(expected, "LoadFpuFromOffset");
1381}
1382
1383TEST_F(AssemblerMIPS64Test, StoreToOffset) {
1384  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A0, 0);
1385  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0);
1386  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 1);
1387  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 256);
1388  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 1000);
1389  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x7FFF);
1390  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x8000);
1391  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x8001);
1392  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x10000);
1393  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x12345678);
1394  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, -256);
1395  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, -32768);
1396  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0xABCDEF00);
1397
1398  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A0, 0);
1399  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0);
1400  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 2);
1401  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 256);
1402  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 1000);
1403  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x7FFE);
1404  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x8000);
1405  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x8002);
1406  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x10000);
1407  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x12345678);
1408  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, -256);
1409  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, -32768);
1410  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0xABCDEF00);
1411
1412  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A0, 0);
1413  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0);
1414  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 4);
1415  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 256);
1416  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 1000);
1417  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x7FFC);
1418  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x8000);
1419  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x8004);
1420  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x10000);
1421  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x12345678);
1422  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, -256);
1423  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, -32768);
1424  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0xABCDEF00);
1425
1426  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A0, 0);
1427  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0);
1428  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 4);
1429  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 256);
1430  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 1000);
1431  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x7FFC);
1432  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x8000);
1433  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x8004);
1434  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x10000);
1435  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x12345678);
1436  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, -256);
1437  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, -32768);
1438  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0xABCDEF00);
1439
1440  const char* expected =
1441      "sb $a0, 0($a0)\n"
1442      "sb $a0, 0($a1)\n"
1443      "sb $a0, 1($a1)\n"
1444      "sb $a0, 256($a1)\n"
1445      "sb $a0, 1000($a1)\n"
1446      "sb $a0, 0x7FFF($a1)\n"
1447      "ori $at, $zero, 0x8000\n"
1448      "daddu $at, $at, $a1\n"
1449      "sb $a0, 0($at)\n"
1450      "ori $at, $zero, 0x8000\n"
1451      "daddu $at, $at, $a1\n"
1452      "sb $a0, 1($at)\n"
1453      "lui $at, 1\n"
1454      "daddu $at, $at, $a1\n"
1455      "sb $a0, 0($at)\n"
1456      "lui $at, 0x1234\n"
1457      "ori $at, 0x5678\n"
1458      "daddu $at, $at, $a1\n"
1459      "sb $a0, 0($at)\n"
1460      "sb $a0, -256($a1)\n"
1461      "sb $a0, -32768($a1)\n"
1462      "lui $at, 0xABCD\n"
1463      "ori $at, 0xEF00\n"
1464      "daddu $at, $at, $a1\n"
1465      "sb $a0, 0($at)\n"
1466
1467      "sh $a0, 0($a0)\n"
1468      "sh $a0, 0($a1)\n"
1469      "sh $a0, 2($a1)\n"
1470      "sh $a0, 256($a1)\n"
1471      "sh $a0, 1000($a1)\n"
1472      "sh $a0, 0x7FFE($a1)\n"
1473      "ori $at, $zero, 0x8000\n"
1474      "daddu $at, $at, $a1\n"
1475      "sh $a0, 0($at)\n"
1476      "ori $at, $zero, 0x8000\n"
1477      "daddu $at, $at, $a1\n"
1478      "sh $a0, 2($at)\n"
1479      "lui $at, 1\n"
1480      "daddu $at, $at, $a1\n"
1481      "sh $a0, 0($at)\n"
1482      "lui $at, 0x1234\n"
1483      "ori $at, 0x5678\n"
1484      "daddu $at, $at, $a1\n"
1485      "sh $a0, 0($at)\n"
1486      "sh $a0, -256($a1)\n"
1487      "sh $a0, -32768($a1)\n"
1488      "lui $at, 0xABCD\n"
1489      "ori $at, 0xEF00\n"
1490      "daddu $at, $at, $a1\n"
1491      "sh $a0, 0($at)\n"
1492
1493      "sw $a0, 0($a0)\n"
1494      "sw $a0, 0($a1)\n"
1495      "sw $a0, 4($a1)\n"
1496      "sw $a0, 256($a1)\n"
1497      "sw $a0, 1000($a1)\n"
1498      "sw $a0, 0x7FFC($a1)\n"
1499      "ori $at, $zero, 0x8000\n"
1500      "daddu $at, $at, $a1\n"
1501      "sw $a0, 0($at)\n"
1502      "ori $at, $zero, 0x8000\n"
1503      "daddu $at, $at, $a1\n"
1504      "sw $a0, 4($at)\n"
1505      "lui $at, 1\n"
1506      "daddu $at, $at, $a1\n"
1507      "sw $a0, 0($at)\n"
1508      "lui $at, 0x1234\n"
1509      "ori $at, 0x5678\n"
1510      "daddu $at, $at, $a1\n"
1511      "sw $a0, 0($at)\n"
1512      "sw $a0, -256($a1)\n"
1513      "sw $a0, -32768($a1)\n"
1514      "lui $at, 0xABCD\n"
1515      "ori $at, 0xEF00\n"
1516      "daddu $at, $at, $a1\n"
1517      "sw $a0, 0($at)\n"
1518
1519      "sd $a0, 0($a0)\n"
1520      "sd $a0, 0($a1)\n"
1521      "sw $a0, 4($a1)\n"
1522      "dsrl32 $t3, $a0, 0\n"
1523      "sw $t3, 8($a1)\n"
1524      "sd $a0, 256($a1)\n"
1525      "sd $a0, 1000($a1)\n"
1526      "ori $at, $zero, 0x7FF8\n"
1527      "daddu $at, $at, $a1\n"
1528      "sw $a0, 4($at)\n"
1529      "dsrl32 $t3, $a0, 0\n"
1530      "sw $t3, 8($at)\n"
1531      "ori $at, $zero, 0x8000\n"
1532      "daddu $at, $at, $a1\n"
1533      "sd $a0, 0($at)\n"
1534      "ori $at, $zero, 0x8000\n"
1535      "daddu $at, $at, $a1\n"
1536      "sw $a0, 4($at)\n"
1537      "dsrl32 $t3, $a0, 0\n"
1538      "sw $t3, 8($at)\n"
1539      "lui $at, 1\n"
1540      "daddu $at, $at, $a1\n"
1541      "sd $a0, 0($at)\n"
1542      "lui $at, 0x1234\n"
1543      "ori $at, 0x5678\n"
1544      "daddu $at, $at, $a1\n"
1545      "sd $a0, 0($at)\n"
1546      "sd $a0, -256($a1)\n"
1547      "sd $a0, -32768($a1)\n"
1548      "lui $at, 0xABCD\n"
1549      "ori $at, 0xEF00\n"
1550      "daddu $at, $at, $a1\n"
1551      "sd $a0, 0($at)\n";
1552  DriverStr(expected, "StoreToOffset");
1553}
1554
1555TEST_F(AssemblerMIPS64Test, StoreFpuToOffset) {
1556  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0);
1557  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 4);
1558  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 256);
1559  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x7FFC);
1560  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x8000);
1561  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x8004);
1562  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x10000);
1563  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x12345678);
1564  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, -256);
1565  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, -32768);
1566  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0xABCDEF00);
1567
1568  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0);
1569  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 4);
1570  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 256);
1571  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x7FFC);
1572  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x8000);
1573  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x8004);
1574  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x10000);
1575  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x12345678);
1576  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, -256);
1577  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, -32768);
1578  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0xABCDEF00);
1579
1580  const char* expected =
1581      "swc1 $f0, 0($a0)\n"
1582      "swc1 $f0, 4($a0)\n"
1583      "swc1 $f0, 256($a0)\n"
1584      "swc1 $f0, 0x7FFC($a0)\n"
1585      "ori $at, $zero, 0x8000\n"
1586      "daddu $at, $at, $a0\n"
1587      "swc1 $f0, 0($at)\n"
1588      "ori $at, $zero, 0x8000\n"
1589      "daddu $at, $at, $a0\n"
1590      "swc1 $f0, 4($at)\n"
1591      "lui $at, 1\n"
1592      "daddu $at, $at, $a0\n"
1593      "swc1 $f0, 0($at)\n"
1594      "lui $at, 0x1234\n"
1595      "ori $at, 0x5678\n"
1596      "daddu $at, $at, $a0\n"
1597      "swc1 $f0, 0($at)\n"
1598      "swc1 $f0, -256($a0)\n"
1599      "swc1 $f0, -32768($a0)\n"
1600      "lui $at, 0xABCD\n"
1601      "ori $at, 0xEF00\n"
1602      "daddu $at, $at, $a0\n"
1603      "swc1 $f0, 0($at)\n"
1604
1605      "sdc1 $f0, 0($a0)\n"
1606      "mfhc1 $t3, $f0\n"
1607      "swc1 $f0, 4($a0)\n"
1608      "sw $t3, 8($a0)\n"
1609      "sdc1 $f0, 256($a0)\n"
1610      "ori $at, $zero, 0x7FF8\n"
1611      "daddu $at, $at, $a0\n"
1612      "mfhc1 $t3, $f0\n"
1613      "swc1 $f0, 4($at)\n"
1614      "sw $t3, 8($at)\n"
1615      "ori $at, $zero, 0x8000\n"
1616      "daddu $at, $at, $a0\n"
1617      "sdc1 $f0, 0($at)\n"
1618      "ori $at, $zero, 0x8000\n"
1619      "daddu $at, $at, $a0\n"
1620      "mfhc1 $t3, $f0\n"
1621      "swc1 $f0, 4($at)\n"
1622      "sw $t3, 8($at)\n"
1623      "lui $at, 1\n"
1624      "daddu $at, $at, $a0\n"
1625      "sdc1 $f0, 0($at)\n"
1626      "lui $at, 0x1234\n"
1627      "ori $at, 0x5678\n"
1628      "daddu $at, $at, $a0\n"
1629      "sdc1 $f0, 0($at)\n"
1630      "sdc1 $f0, -256($a0)\n"
1631      "sdc1 $f0, -32768($a0)\n"
1632      "lui $at, 0xABCD\n"
1633      "ori $at, 0xEF00\n"
1634      "daddu $at, $at, $a0\n"
1635      "sdc1 $f0, 0($at)\n";
1636  DriverStr(expected, "StoreFpuToOffset");
1637}
1638
1639#undef __
1640
1641}  // namespace art
1642