assembler_mips64_test.cc revision dcabc8b740bf3066d59348ffdf21c164d2b27cb4
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                                                 mips64::VectorRegister> {
42 public:
43  typedef AssemblerTest<mips64::Mips64Assembler,
44                        mips64::GpuRegister,
45                        mips64::FpuRegister,
46                        uint32_t,
47                        mips64::VectorRegister> Base;
48
49 protected:
50  // Get the typically used name for this architecture, e.g., aarch64, x86-64, ...
51  std::string GetArchitectureString() OVERRIDE {
52    return "mips64";
53  }
54
55  std::string GetAssemblerCmdName() OVERRIDE {
56    // We assemble and link for MIPS64R6. See GetAssemblerParameters() for details.
57    return "gcc";
58  }
59
60  std::string GetAssemblerParameters() OVERRIDE {
61    // We assemble and link for MIPS64R6. The reason is that object files produced for MIPS64R6
62    // (and MIPS32R6) with the GNU assembler don't have correct final offsets in PC-relative
63    // branches in the .text section and so they require a relocation pass (there's a relocation
64    // section, .rela.text, that has the needed info to fix up the branches).
65    return " -march=mips64r6 -mmsa -Wa,--no-warn -Wl,-Ttext=0 -Wl,-e0 -nostdlib";
66  }
67
68  void Pad(std::vector<uint8_t>& data) OVERRIDE {
69    // The GNU linker unconditionally pads the code segment with NOPs to a size that is a multiple
70    // of 16 and there doesn't appear to be a way to suppress this padding. Our assembler doesn't
71    // pad, so, in order for two assembler outputs to match, we need to match the padding as well.
72    // NOP is encoded as four zero bytes on MIPS.
73    size_t pad_size = RoundUp(data.size(), 16u) - data.size();
74    data.insert(data.end(), pad_size, 0);
75  }
76
77  std::string GetDisassembleParameters() OVERRIDE {
78    return " -D -bbinary -mmips:isa64r6";
79  }
80
81  void SetUpHelpers() OVERRIDE {
82    if (registers_.size() == 0) {
83      registers_.push_back(new mips64::GpuRegister(mips64::ZERO));
84      registers_.push_back(new mips64::GpuRegister(mips64::AT));
85      registers_.push_back(new mips64::GpuRegister(mips64::V0));
86      registers_.push_back(new mips64::GpuRegister(mips64::V1));
87      registers_.push_back(new mips64::GpuRegister(mips64::A0));
88      registers_.push_back(new mips64::GpuRegister(mips64::A1));
89      registers_.push_back(new mips64::GpuRegister(mips64::A2));
90      registers_.push_back(new mips64::GpuRegister(mips64::A3));
91      registers_.push_back(new mips64::GpuRegister(mips64::A4));
92      registers_.push_back(new mips64::GpuRegister(mips64::A5));
93      registers_.push_back(new mips64::GpuRegister(mips64::A6));
94      registers_.push_back(new mips64::GpuRegister(mips64::A7));
95      registers_.push_back(new mips64::GpuRegister(mips64::T0));
96      registers_.push_back(new mips64::GpuRegister(mips64::T1));
97      registers_.push_back(new mips64::GpuRegister(mips64::T2));
98      registers_.push_back(new mips64::GpuRegister(mips64::T3));
99      registers_.push_back(new mips64::GpuRegister(mips64::S0));
100      registers_.push_back(new mips64::GpuRegister(mips64::S1));
101      registers_.push_back(new mips64::GpuRegister(mips64::S2));
102      registers_.push_back(new mips64::GpuRegister(mips64::S3));
103      registers_.push_back(new mips64::GpuRegister(mips64::S4));
104      registers_.push_back(new mips64::GpuRegister(mips64::S5));
105      registers_.push_back(new mips64::GpuRegister(mips64::S6));
106      registers_.push_back(new mips64::GpuRegister(mips64::S7));
107      registers_.push_back(new mips64::GpuRegister(mips64::T8));
108      registers_.push_back(new mips64::GpuRegister(mips64::T9));
109      registers_.push_back(new mips64::GpuRegister(mips64::K0));
110      registers_.push_back(new mips64::GpuRegister(mips64::K1));
111      registers_.push_back(new mips64::GpuRegister(mips64::GP));
112      registers_.push_back(new mips64::GpuRegister(mips64::SP));
113      registers_.push_back(new mips64::GpuRegister(mips64::S8));
114      registers_.push_back(new mips64::GpuRegister(mips64::RA));
115
116      secondary_register_names_.emplace(mips64::GpuRegister(mips64::ZERO), "zero");
117      secondary_register_names_.emplace(mips64::GpuRegister(mips64::AT), "at");
118      secondary_register_names_.emplace(mips64::GpuRegister(mips64::V0), "v0");
119      secondary_register_names_.emplace(mips64::GpuRegister(mips64::V1), "v1");
120      secondary_register_names_.emplace(mips64::GpuRegister(mips64::A0), "a0");
121      secondary_register_names_.emplace(mips64::GpuRegister(mips64::A1), "a1");
122      secondary_register_names_.emplace(mips64::GpuRegister(mips64::A2), "a2");
123      secondary_register_names_.emplace(mips64::GpuRegister(mips64::A3), "a3");
124      secondary_register_names_.emplace(mips64::GpuRegister(mips64::A4), "a4");
125      secondary_register_names_.emplace(mips64::GpuRegister(mips64::A5), "a5");
126      secondary_register_names_.emplace(mips64::GpuRegister(mips64::A6), "a6");
127      secondary_register_names_.emplace(mips64::GpuRegister(mips64::A7), "a7");
128      secondary_register_names_.emplace(mips64::GpuRegister(mips64::T0), "t0");
129      secondary_register_names_.emplace(mips64::GpuRegister(mips64::T1), "t1");
130      secondary_register_names_.emplace(mips64::GpuRegister(mips64::T2), "t2");
131      secondary_register_names_.emplace(mips64::GpuRegister(mips64::T3), "t3");
132      secondary_register_names_.emplace(mips64::GpuRegister(mips64::S0), "s0");
133      secondary_register_names_.emplace(mips64::GpuRegister(mips64::S1), "s1");
134      secondary_register_names_.emplace(mips64::GpuRegister(mips64::S2), "s2");
135      secondary_register_names_.emplace(mips64::GpuRegister(mips64::S3), "s3");
136      secondary_register_names_.emplace(mips64::GpuRegister(mips64::S4), "s4");
137      secondary_register_names_.emplace(mips64::GpuRegister(mips64::S5), "s5");
138      secondary_register_names_.emplace(mips64::GpuRegister(mips64::S6), "s6");
139      secondary_register_names_.emplace(mips64::GpuRegister(mips64::S7), "s7");
140      secondary_register_names_.emplace(mips64::GpuRegister(mips64::T8), "t8");
141      secondary_register_names_.emplace(mips64::GpuRegister(mips64::T9), "t9");
142      secondary_register_names_.emplace(mips64::GpuRegister(mips64::K0), "k0");
143      secondary_register_names_.emplace(mips64::GpuRegister(mips64::K1), "k1");
144      secondary_register_names_.emplace(mips64::GpuRegister(mips64::GP), "gp");
145      secondary_register_names_.emplace(mips64::GpuRegister(mips64::SP), "sp");
146      secondary_register_names_.emplace(mips64::GpuRegister(mips64::S8), "s8");
147      secondary_register_names_.emplace(mips64::GpuRegister(mips64::RA), "ra");
148
149      fp_registers_.push_back(new mips64::FpuRegister(mips64::F0));
150      fp_registers_.push_back(new mips64::FpuRegister(mips64::F1));
151      fp_registers_.push_back(new mips64::FpuRegister(mips64::F2));
152      fp_registers_.push_back(new mips64::FpuRegister(mips64::F3));
153      fp_registers_.push_back(new mips64::FpuRegister(mips64::F4));
154      fp_registers_.push_back(new mips64::FpuRegister(mips64::F5));
155      fp_registers_.push_back(new mips64::FpuRegister(mips64::F6));
156      fp_registers_.push_back(new mips64::FpuRegister(mips64::F7));
157      fp_registers_.push_back(new mips64::FpuRegister(mips64::F8));
158      fp_registers_.push_back(new mips64::FpuRegister(mips64::F9));
159      fp_registers_.push_back(new mips64::FpuRegister(mips64::F10));
160      fp_registers_.push_back(new mips64::FpuRegister(mips64::F11));
161      fp_registers_.push_back(new mips64::FpuRegister(mips64::F12));
162      fp_registers_.push_back(new mips64::FpuRegister(mips64::F13));
163      fp_registers_.push_back(new mips64::FpuRegister(mips64::F14));
164      fp_registers_.push_back(new mips64::FpuRegister(mips64::F15));
165      fp_registers_.push_back(new mips64::FpuRegister(mips64::F16));
166      fp_registers_.push_back(new mips64::FpuRegister(mips64::F17));
167      fp_registers_.push_back(new mips64::FpuRegister(mips64::F18));
168      fp_registers_.push_back(new mips64::FpuRegister(mips64::F19));
169      fp_registers_.push_back(new mips64::FpuRegister(mips64::F20));
170      fp_registers_.push_back(new mips64::FpuRegister(mips64::F21));
171      fp_registers_.push_back(new mips64::FpuRegister(mips64::F22));
172      fp_registers_.push_back(new mips64::FpuRegister(mips64::F23));
173      fp_registers_.push_back(new mips64::FpuRegister(mips64::F24));
174      fp_registers_.push_back(new mips64::FpuRegister(mips64::F25));
175      fp_registers_.push_back(new mips64::FpuRegister(mips64::F26));
176      fp_registers_.push_back(new mips64::FpuRegister(mips64::F27));
177      fp_registers_.push_back(new mips64::FpuRegister(mips64::F28));
178      fp_registers_.push_back(new mips64::FpuRegister(mips64::F29));
179      fp_registers_.push_back(new mips64::FpuRegister(mips64::F30));
180      fp_registers_.push_back(new mips64::FpuRegister(mips64::F31));
181
182      vec_registers_.push_back(new mips64::VectorRegister(mips64::W0));
183      vec_registers_.push_back(new mips64::VectorRegister(mips64::W1));
184      vec_registers_.push_back(new mips64::VectorRegister(mips64::W2));
185      vec_registers_.push_back(new mips64::VectorRegister(mips64::W3));
186      vec_registers_.push_back(new mips64::VectorRegister(mips64::W4));
187      vec_registers_.push_back(new mips64::VectorRegister(mips64::W5));
188      vec_registers_.push_back(new mips64::VectorRegister(mips64::W6));
189      vec_registers_.push_back(new mips64::VectorRegister(mips64::W7));
190      vec_registers_.push_back(new mips64::VectorRegister(mips64::W8));
191      vec_registers_.push_back(new mips64::VectorRegister(mips64::W9));
192      vec_registers_.push_back(new mips64::VectorRegister(mips64::W10));
193      vec_registers_.push_back(new mips64::VectorRegister(mips64::W11));
194      vec_registers_.push_back(new mips64::VectorRegister(mips64::W12));
195      vec_registers_.push_back(new mips64::VectorRegister(mips64::W13));
196      vec_registers_.push_back(new mips64::VectorRegister(mips64::W14));
197      vec_registers_.push_back(new mips64::VectorRegister(mips64::W15));
198      vec_registers_.push_back(new mips64::VectorRegister(mips64::W16));
199      vec_registers_.push_back(new mips64::VectorRegister(mips64::W17));
200      vec_registers_.push_back(new mips64::VectorRegister(mips64::W18));
201      vec_registers_.push_back(new mips64::VectorRegister(mips64::W19));
202      vec_registers_.push_back(new mips64::VectorRegister(mips64::W20));
203      vec_registers_.push_back(new mips64::VectorRegister(mips64::W21));
204      vec_registers_.push_back(new mips64::VectorRegister(mips64::W22));
205      vec_registers_.push_back(new mips64::VectorRegister(mips64::W23));
206      vec_registers_.push_back(new mips64::VectorRegister(mips64::W24));
207      vec_registers_.push_back(new mips64::VectorRegister(mips64::W25));
208      vec_registers_.push_back(new mips64::VectorRegister(mips64::W26));
209      vec_registers_.push_back(new mips64::VectorRegister(mips64::W27));
210      vec_registers_.push_back(new mips64::VectorRegister(mips64::W28));
211      vec_registers_.push_back(new mips64::VectorRegister(mips64::W29));
212      vec_registers_.push_back(new mips64::VectorRegister(mips64::W30));
213      vec_registers_.push_back(new mips64::VectorRegister(mips64::W31));
214    }
215  }
216
217  void TearDown() OVERRIDE {
218    AssemblerTest::TearDown();
219    STLDeleteElements(&registers_);
220    STLDeleteElements(&fp_registers_);
221  }
222
223  std::vector<mips64::GpuRegister*> GetRegisters() OVERRIDE {
224    return registers_;
225  }
226
227  std::vector<mips64::FpuRegister*> GetFPRegisters() OVERRIDE {
228    return fp_registers_;
229  }
230
231  std::vector<mips64::VectorRegister*> GetVectorRegisters() OVERRIDE {
232    return vec_registers_;
233  }
234
235  uint32_t CreateImmediate(int64_t imm_value) OVERRIDE {
236    return imm_value;
237  }
238
239  std::string GetSecondaryRegisterName(const mips64::GpuRegister& reg) OVERRIDE {
240    CHECK(secondary_register_names_.find(reg) != secondary_register_names_.end());
241    return secondary_register_names_[reg];
242  }
243
244  std::string RepeatInsn(size_t count, const std::string& insn) {
245    std::string result;
246    for (; count != 0u; --count) {
247      result += insn;
248    }
249    return result;
250  }
251
252  void BranchCondOneRegHelper(void (mips64::Mips64Assembler::*f)(mips64::GpuRegister,
253                                                                 mips64::Mips64Label*),
254                              const std::string& instr_name) {
255    mips64::Mips64Label label;
256    (Base::GetAssembler()->*f)(mips64::A0, &label);
257    constexpr size_t kAdduCount1 = 63;
258    for (size_t i = 0; i != kAdduCount1; ++i) {
259      __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
260    }
261    __ Bind(&label);
262    constexpr size_t kAdduCount2 = 64;
263    for (size_t i = 0; i != kAdduCount2; ++i) {
264      __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
265    }
266    (Base::GetAssembler()->*f)(mips64::A1, &label);
267
268    std::string expected =
269        ".set noreorder\n" +
270        instr_name + " $a0, 1f\n"
271        "nop\n" +
272        RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
273        "1:\n" +
274        RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
275        instr_name + " $a1, 1b\n"
276        "nop\n";
277    DriverStr(expected, instr_name);
278  }
279
280  void BranchCondTwoRegsHelper(void (mips64::Mips64Assembler::*f)(mips64::GpuRegister,
281                                                                  mips64::GpuRegister,
282                                                                  mips64::Mips64Label*),
283                               const std::string& instr_name) {
284    mips64::Mips64Label label;
285    (Base::GetAssembler()->*f)(mips64::A0, mips64::A1, &label);
286    constexpr size_t kAdduCount1 = 63;
287    for (size_t i = 0; i != kAdduCount1; ++i) {
288      __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
289    }
290    __ Bind(&label);
291    constexpr size_t kAdduCount2 = 64;
292    for (size_t i = 0; i != kAdduCount2; ++i) {
293      __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
294    }
295    (Base::GetAssembler()->*f)(mips64::A2, mips64::A3, &label);
296
297    std::string expected =
298        ".set noreorder\n" +
299        instr_name + " $a0, $a1, 1f\n"
300        "nop\n" +
301        RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
302        "1:\n" +
303        RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
304        instr_name + " $a2, $a3, 1b\n"
305        "nop\n";
306    DriverStr(expected, instr_name);
307  }
308
309 private:
310  std::vector<mips64::GpuRegister*> registers_;
311  std::map<mips64::GpuRegister, std::string, MIPS64CpuRegisterCompare> secondary_register_names_;
312
313  std::vector<mips64::FpuRegister*> fp_registers_;
314  std::vector<mips64::VectorRegister*> vec_registers_;
315};
316
317
318TEST_F(AssemblerMIPS64Test, Toolchain) {
319  EXPECT_TRUE(CheckTools());
320}
321
322///////////////////
323// FP Operations //
324///////////////////
325
326TEST_F(AssemblerMIPS64Test, AddS) {
327  DriverStr(RepeatFFF(&mips64::Mips64Assembler::AddS, "add.s ${reg1}, ${reg2}, ${reg3}"), "add.s");
328}
329
330TEST_F(AssemblerMIPS64Test, AddD) {
331  DriverStr(RepeatFFF(&mips64::Mips64Assembler::AddD, "add.d ${reg1}, ${reg2}, ${reg3}"), "add.d");
332}
333
334TEST_F(AssemblerMIPS64Test, SubS) {
335  DriverStr(RepeatFFF(&mips64::Mips64Assembler::SubS, "sub.s ${reg1}, ${reg2}, ${reg3}"), "sub.s");
336}
337
338TEST_F(AssemblerMIPS64Test, SubD) {
339  DriverStr(RepeatFFF(&mips64::Mips64Assembler::SubD, "sub.d ${reg1}, ${reg2}, ${reg3}"), "sub.d");
340}
341
342TEST_F(AssemblerMIPS64Test, MulS) {
343  DriverStr(RepeatFFF(&mips64::Mips64Assembler::MulS, "mul.s ${reg1}, ${reg2}, ${reg3}"), "mul.s");
344}
345
346TEST_F(AssemblerMIPS64Test, MulD) {
347  DriverStr(RepeatFFF(&mips64::Mips64Assembler::MulD, "mul.d ${reg1}, ${reg2}, ${reg3}"), "mul.d");
348}
349
350TEST_F(AssemblerMIPS64Test, DivS) {
351  DriverStr(RepeatFFF(&mips64::Mips64Assembler::DivS, "div.s ${reg1}, ${reg2}, ${reg3}"), "div.s");
352}
353
354TEST_F(AssemblerMIPS64Test, DivD) {
355  DriverStr(RepeatFFF(&mips64::Mips64Assembler::DivD, "div.d ${reg1}, ${reg2}, ${reg3}"), "div.d");
356}
357
358TEST_F(AssemblerMIPS64Test, SqrtS) {
359  DriverStr(RepeatFF(&mips64::Mips64Assembler::SqrtS, "sqrt.s ${reg1}, ${reg2}"), "sqrt.s");
360}
361
362TEST_F(AssemblerMIPS64Test, SqrtD) {
363  DriverStr(RepeatFF(&mips64::Mips64Assembler::SqrtD, "sqrt.d ${reg1}, ${reg2}"), "sqrt.d");
364}
365
366TEST_F(AssemblerMIPS64Test, AbsS) {
367  DriverStr(RepeatFF(&mips64::Mips64Assembler::AbsS, "abs.s ${reg1}, ${reg2}"), "abs.s");
368}
369
370TEST_F(AssemblerMIPS64Test, AbsD) {
371  DriverStr(RepeatFF(&mips64::Mips64Assembler::AbsD, "abs.d ${reg1}, ${reg2}"), "abs.d");
372}
373
374TEST_F(AssemblerMIPS64Test, MovS) {
375  DriverStr(RepeatFF(&mips64::Mips64Assembler::MovS, "mov.s ${reg1}, ${reg2}"), "mov.s");
376}
377
378TEST_F(AssemblerMIPS64Test, MovD) {
379  DriverStr(RepeatFF(&mips64::Mips64Assembler::MovD, "mov.d ${reg1}, ${reg2}"), "mov.d");
380}
381
382TEST_F(AssemblerMIPS64Test, NegS) {
383  DriverStr(RepeatFF(&mips64::Mips64Assembler::NegS, "neg.s ${reg1}, ${reg2}"), "neg.s");
384}
385
386TEST_F(AssemblerMIPS64Test, NegD) {
387  DriverStr(RepeatFF(&mips64::Mips64Assembler::NegD, "neg.d ${reg1}, ${reg2}"), "neg.d");
388}
389
390TEST_F(AssemblerMIPS64Test, RoundLS) {
391  DriverStr(RepeatFF(&mips64::Mips64Assembler::RoundLS, "round.l.s ${reg1}, ${reg2}"), "round.l.s");
392}
393
394TEST_F(AssemblerMIPS64Test, RoundLD) {
395  DriverStr(RepeatFF(&mips64::Mips64Assembler::RoundLD, "round.l.d ${reg1}, ${reg2}"), "round.l.d");
396}
397
398TEST_F(AssemblerMIPS64Test, RoundWS) {
399  DriverStr(RepeatFF(&mips64::Mips64Assembler::RoundWS, "round.w.s ${reg1}, ${reg2}"), "round.w.s");
400}
401
402TEST_F(AssemblerMIPS64Test, RoundWD) {
403  DriverStr(RepeatFF(&mips64::Mips64Assembler::RoundWD, "round.w.d ${reg1}, ${reg2}"), "round.w.d");
404}
405
406TEST_F(AssemblerMIPS64Test, CeilLS) {
407  DriverStr(RepeatFF(&mips64::Mips64Assembler::CeilLS, "ceil.l.s ${reg1}, ${reg2}"), "ceil.l.s");
408}
409
410TEST_F(AssemblerMIPS64Test, CeilLD) {
411  DriverStr(RepeatFF(&mips64::Mips64Assembler::CeilLD, "ceil.l.d ${reg1}, ${reg2}"), "ceil.l.d");
412}
413
414TEST_F(AssemblerMIPS64Test, CeilWS) {
415  DriverStr(RepeatFF(&mips64::Mips64Assembler::CeilWS, "ceil.w.s ${reg1}, ${reg2}"), "ceil.w.s");
416}
417
418TEST_F(AssemblerMIPS64Test, CeilWD) {
419  DriverStr(RepeatFF(&mips64::Mips64Assembler::CeilWD, "ceil.w.d ${reg1}, ${reg2}"), "ceil.w.d");
420}
421
422TEST_F(AssemblerMIPS64Test, FloorLS) {
423  DriverStr(RepeatFF(&mips64::Mips64Assembler::FloorLS, "floor.l.s ${reg1}, ${reg2}"), "floor.l.s");
424}
425
426TEST_F(AssemblerMIPS64Test, FloorLD) {
427  DriverStr(RepeatFF(&mips64::Mips64Assembler::FloorLD, "floor.l.d ${reg1}, ${reg2}"), "floor.l.d");
428}
429
430TEST_F(AssemblerMIPS64Test, FloorWS) {
431  DriverStr(RepeatFF(&mips64::Mips64Assembler::FloorWS, "floor.w.s ${reg1}, ${reg2}"), "floor.w.s");
432}
433
434TEST_F(AssemblerMIPS64Test, FloorWD) {
435  DriverStr(RepeatFF(&mips64::Mips64Assembler::FloorWD, "floor.w.d ${reg1}, ${reg2}"), "floor.w.d");
436}
437
438TEST_F(AssemblerMIPS64Test, SelS) {
439  DriverStr(RepeatFFF(&mips64::Mips64Assembler::SelS, "sel.s ${reg1}, ${reg2}, ${reg3}"), "sel.s");
440}
441
442TEST_F(AssemblerMIPS64Test, SelD) {
443  DriverStr(RepeatFFF(&mips64::Mips64Assembler::SelD, "sel.d ${reg1}, ${reg2}, ${reg3}"), "sel.d");
444}
445
446TEST_F(AssemblerMIPS64Test, RintS) {
447  DriverStr(RepeatFF(&mips64::Mips64Assembler::RintS, "rint.s ${reg1}, ${reg2}"), "rint.s");
448}
449
450TEST_F(AssemblerMIPS64Test, RintD) {
451  DriverStr(RepeatFF(&mips64::Mips64Assembler::RintD, "rint.d ${reg1}, ${reg2}"), "rint.d");
452}
453
454TEST_F(AssemblerMIPS64Test, ClassS) {
455  DriverStr(RepeatFF(&mips64::Mips64Assembler::ClassS, "class.s ${reg1}, ${reg2}"), "class.s");
456}
457
458TEST_F(AssemblerMIPS64Test, ClassD) {
459  DriverStr(RepeatFF(&mips64::Mips64Assembler::ClassD, "class.d ${reg1}, ${reg2}"), "class.d");
460}
461
462TEST_F(AssemblerMIPS64Test, MinS) {
463  DriverStr(RepeatFFF(&mips64::Mips64Assembler::MinS, "min.s ${reg1}, ${reg2}, ${reg3}"), "min.s");
464}
465
466TEST_F(AssemblerMIPS64Test, MinD) {
467  DriverStr(RepeatFFF(&mips64::Mips64Assembler::MinD, "min.d ${reg1}, ${reg2}, ${reg3}"), "min.d");
468}
469
470TEST_F(AssemblerMIPS64Test, MaxS) {
471  DriverStr(RepeatFFF(&mips64::Mips64Assembler::MaxS, "max.s ${reg1}, ${reg2}, ${reg3}"), "max.s");
472}
473
474TEST_F(AssemblerMIPS64Test, MaxD) {
475  DriverStr(RepeatFFF(&mips64::Mips64Assembler::MaxD, "max.d ${reg1}, ${reg2}, ${reg3}"), "max.d");
476}
477
478TEST_F(AssemblerMIPS64Test, CmpUnS) {
479  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUnS, "cmp.un.s ${reg1}, ${reg2}, ${reg3}"),
480            "cmp.un.s");
481}
482
483TEST_F(AssemblerMIPS64Test, CmpEqS) {
484  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpEqS, "cmp.eq.s ${reg1}, ${reg2}, ${reg3}"),
485            "cmp.eq.s");
486}
487
488TEST_F(AssemblerMIPS64Test, CmpUeqS) {
489  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUeqS, "cmp.ueq.s ${reg1}, ${reg2}, ${reg3}"),
490            "cmp.ueq.s");
491}
492
493TEST_F(AssemblerMIPS64Test, CmpLtS) {
494  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpLtS, "cmp.lt.s ${reg1}, ${reg2}, ${reg3}"),
495            "cmp.lt.s");
496}
497
498TEST_F(AssemblerMIPS64Test, CmpUltS) {
499  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUltS, "cmp.ult.s ${reg1}, ${reg2}, ${reg3}"),
500            "cmp.ult.s");
501}
502
503TEST_F(AssemblerMIPS64Test, CmpLeS) {
504  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpLeS, "cmp.le.s ${reg1}, ${reg2}, ${reg3}"),
505            "cmp.le.s");
506}
507
508TEST_F(AssemblerMIPS64Test, CmpUleS) {
509  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUleS, "cmp.ule.s ${reg1}, ${reg2}, ${reg3}"),
510            "cmp.ule.s");
511}
512
513TEST_F(AssemblerMIPS64Test, CmpOrS) {
514  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpOrS, "cmp.or.s ${reg1}, ${reg2}, ${reg3}"),
515            "cmp.or.s");
516}
517
518TEST_F(AssemblerMIPS64Test, CmpUneS) {
519  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUneS, "cmp.une.s ${reg1}, ${reg2}, ${reg3}"),
520            "cmp.une.s");
521}
522
523TEST_F(AssemblerMIPS64Test, CmpNeS) {
524  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpNeS, "cmp.ne.s ${reg1}, ${reg2}, ${reg3}"),
525            "cmp.ne.s");
526}
527
528TEST_F(AssemblerMIPS64Test, CmpUnD) {
529  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUnD, "cmp.un.d ${reg1}, ${reg2}, ${reg3}"),
530            "cmp.un.d");
531}
532
533TEST_F(AssemblerMIPS64Test, CmpEqD) {
534  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpEqD, "cmp.eq.d ${reg1}, ${reg2}, ${reg3}"),
535            "cmp.eq.d");
536}
537
538TEST_F(AssemblerMIPS64Test, CmpUeqD) {
539  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUeqD, "cmp.ueq.d ${reg1}, ${reg2}, ${reg3}"),
540            "cmp.ueq.d");
541}
542
543TEST_F(AssemblerMIPS64Test, CmpLtD) {
544  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpLtD, "cmp.lt.d ${reg1}, ${reg2}, ${reg3}"),
545            "cmp.lt.d");
546}
547
548TEST_F(AssemblerMIPS64Test, CmpUltD) {
549  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUltD, "cmp.ult.d ${reg1}, ${reg2}, ${reg3}"),
550            "cmp.ult.d");
551}
552
553TEST_F(AssemblerMIPS64Test, CmpLeD) {
554  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpLeD, "cmp.le.d ${reg1}, ${reg2}, ${reg3}"),
555            "cmp.le.d");
556}
557
558TEST_F(AssemblerMIPS64Test, CmpUleD) {
559  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUleD, "cmp.ule.d ${reg1}, ${reg2}, ${reg3}"),
560            "cmp.ule.d");
561}
562
563TEST_F(AssemblerMIPS64Test, CmpOrD) {
564  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpOrD, "cmp.or.d ${reg1}, ${reg2}, ${reg3}"),
565            "cmp.or.d");
566}
567
568TEST_F(AssemblerMIPS64Test, CmpUneD) {
569  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpUneD, "cmp.une.d ${reg1}, ${reg2}, ${reg3}"),
570            "cmp.une.d");
571}
572
573TEST_F(AssemblerMIPS64Test, CmpNeD) {
574  DriverStr(RepeatFFF(&mips64::Mips64Assembler::CmpNeD, "cmp.ne.d ${reg1}, ${reg2}, ${reg3}"),
575            "cmp.ne.d");
576}
577
578TEST_F(AssemblerMIPS64Test, CvtDL) {
579  DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtdl, "cvt.d.l ${reg1}, ${reg2}"), "cvt.d.l");
580}
581
582TEST_F(AssemblerMIPS64Test, CvtDS) {
583  DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtds, "cvt.d.s ${reg1}, ${reg2}"), "cvt.d.s");
584}
585
586TEST_F(AssemblerMIPS64Test, CvtDW) {
587  DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtdw, "cvt.d.w ${reg1}, ${reg2}"), "cvt.d.w");
588}
589
590TEST_F(AssemblerMIPS64Test, CvtSL) {
591  DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtsl, "cvt.s.l ${reg1}, ${reg2}"), "cvt.s.l");
592}
593
594TEST_F(AssemblerMIPS64Test, CvtSD) {
595  DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtsd, "cvt.s.d ${reg1}, ${reg2}"), "cvt.s.d");
596}
597
598TEST_F(AssemblerMIPS64Test, CvtSW) {
599  DriverStr(RepeatFF(&mips64::Mips64Assembler::Cvtsw, "cvt.s.w ${reg1}, ${reg2}"), "cvt.s.w");
600}
601
602TEST_F(AssemblerMIPS64Test, TruncWS) {
603  DriverStr(RepeatFF(&mips64::Mips64Assembler::TruncWS, "trunc.w.s ${reg1}, ${reg2}"), "trunc.w.s");
604}
605
606TEST_F(AssemblerMIPS64Test, TruncWD) {
607  DriverStr(RepeatFF(&mips64::Mips64Assembler::TruncWD, "trunc.w.d ${reg1}, ${reg2}"), "trunc.w.d");
608}
609
610TEST_F(AssemblerMIPS64Test, TruncLS) {
611  DriverStr(RepeatFF(&mips64::Mips64Assembler::TruncLS, "trunc.l.s ${reg1}, ${reg2}"), "trunc.l.s");
612}
613
614TEST_F(AssemblerMIPS64Test, TruncLD) {
615  DriverStr(RepeatFF(&mips64::Mips64Assembler::TruncLD, "trunc.l.d ${reg1}, ${reg2}"), "trunc.l.d");
616}
617
618TEST_F(AssemblerMIPS64Test, Mfc1) {
619  DriverStr(RepeatRF(&mips64::Mips64Assembler::Mfc1, "mfc1 ${reg1}, ${reg2}"), "Mfc1");
620}
621
622TEST_F(AssemblerMIPS64Test, Mfhc1) {
623  DriverStr(RepeatRF(&mips64::Mips64Assembler::Mfhc1, "mfhc1 ${reg1}, ${reg2}"), "Mfhc1");
624}
625
626TEST_F(AssemblerMIPS64Test, Mtc1) {
627  DriverStr(RepeatRF(&mips64::Mips64Assembler::Mtc1, "mtc1 ${reg1}, ${reg2}"), "Mtc1");
628}
629
630TEST_F(AssemblerMIPS64Test, Mthc1) {
631  DriverStr(RepeatRF(&mips64::Mips64Assembler::Mthc1, "mthc1 ${reg1}, ${reg2}"), "Mthc1");
632}
633
634TEST_F(AssemblerMIPS64Test, Dmfc1) {
635  DriverStr(RepeatRF(&mips64::Mips64Assembler::Dmfc1, "dmfc1 ${reg1}, ${reg2}"), "Dmfc1");
636}
637
638TEST_F(AssemblerMIPS64Test, Dmtc1) {
639  DriverStr(RepeatRF(&mips64::Mips64Assembler::Dmtc1, "dmtc1 ${reg1}, ${reg2}"), "Dmtc1");
640}
641
642TEST_F(AssemblerMIPS64Test, Lwc1) {
643  DriverStr(RepeatFRIb(&mips64::Mips64Assembler::Lwc1, -16, "lwc1 ${reg1}, {imm}(${reg2})"),
644            "lwc1");
645}
646
647TEST_F(AssemblerMIPS64Test, Ldc1) {
648  DriverStr(RepeatFRIb(&mips64::Mips64Assembler::Ldc1, -16, "ldc1 ${reg1}, {imm}(${reg2})"),
649            "ldc1");
650}
651
652TEST_F(AssemblerMIPS64Test, Swc1) {
653  DriverStr(RepeatFRIb(&mips64::Mips64Assembler::Swc1, -16, "swc1 ${reg1}, {imm}(${reg2})"),
654            "swc1");
655}
656
657TEST_F(AssemblerMIPS64Test, Sdc1) {
658  DriverStr(RepeatFRIb(&mips64::Mips64Assembler::Sdc1, -16, "sdc1 ${reg1}, {imm}(${reg2})"),
659            "sdc1");
660}
661
662////////////////
663// CALL / JMP //
664////////////////
665
666TEST_F(AssemblerMIPS64Test, Jalr) {
667  DriverStr(".set noreorder\n" +
668            RepeatRRNoDupes(&mips64::Mips64Assembler::Jalr, "jalr ${reg1}, ${reg2}"), "jalr");
669}
670
671TEST_F(AssemblerMIPS64Test, Balc) {
672  mips64::Mips64Label label1, label2;
673  __ Balc(&label1);
674  constexpr size_t kAdduCount1 = 63;
675  for (size_t i = 0; i != kAdduCount1; ++i) {
676    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
677  }
678  __ Bind(&label1);
679  __ Balc(&label2);
680  constexpr size_t kAdduCount2 = 64;
681  for (size_t i = 0; i != kAdduCount2; ++i) {
682    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
683  }
684  __ Bind(&label2);
685  __ Balc(&label1);
686
687  std::string expected =
688      ".set noreorder\n"
689      "balc 1f\n" +
690      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
691      "1:\n"
692      "balc 2f\n" +
693      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
694      "2:\n"
695      "balc 1b\n";
696  DriverStr(expected, "Balc");
697}
698
699TEST_F(AssemblerMIPS64Test, LongBalc) {
700  constexpr uint32_t kNopCount1 = (1u << 25) + 1;
701  constexpr uint32_t kNopCount2 = (1u << 25) + 1;
702  constexpr uint32_t kRequiredCapacity = (kNopCount1 + kNopCount2 + 6u) * 4u;
703  ASSERT_LT(__ GetBuffer()->Capacity(), kRequiredCapacity);
704  __ GetBuffer()->ExtendCapacity(kRequiredCapacity);
705  mips64::Mips64Label label1, label2;
706  __ Balc(&label1);
707  for (uint32_t i = 0; i != kNopCount1; ++i) {
708    __ Nop();
709  }
710  __ Bind(&label1);
711  __ Balc(&label2);
712  for (uint32_t i = 0; i != kNopCount2; ++i) {
713    __ Nop();
714  }
715  __ Bind(&label2);
716  __ Balc(&label1);
717
718  uint32_t offset_forward1 = 2 + kNopCount1;  // 2: account for auipc and jialc.
719  offset_forward1 <<= 2;
720  offset_forward1 += (offset_forward1 & 0x8000) << 1;  // Account for sign extension in jialc.
721
722  uint32_t offset_forward2 = 2 + kNopCount2;  // 2: account for auipc and jialc.
723  offset_forward2 <<= 2;
724  offset_forward2 += (offset_forward2 & 0x8000) << 1;  // Account for sign extension in jialc.
725
726  uint32_t offset_back = -(2 + kNopCount2);  // 2: account for auipc and jialc.
727  offset_back <<= 2;
728  offset_back += (offset_back & 0x8000) << 1;  // Account for sign extension in jialc.
729
730  // Note, we're using the ".fill" directive to tell the assembler to generate many NOPs
731  // instead of generating them ourselves in the source code. This saves a few minutes
732  // of test time.
733  std::ostringstream oss;
734  oss <<
735      ".set noreorder\n"
736      "auipc $at, 0x" << std::hex << High16Bits(offset_forward1) << "\n"
737      "jialc $at, 0x" << std::hex << Low16Bits(offset_forward1) << "\n"
738      ".fill 0x" << std::hex << kNopCount1 << " , 4, 0\n"
739      "1:\n"
740      "auipc $at, 0x" << std::hex << High16Bits(offset_forward2) << "\n"
741      "jialc $at, 0x" << std::hex << Low16Bits(offset_forward2) << "\n"
742      ".fill 0x" << std::hex << kNopCount2 << " , 4, 0\n"
743      "2:\n"
744      "auipc $at, 0x" << std::hex << High16Bits(offset_back) << "\n"
745      "jialc $at, 0x" << std::hex << Low16Bits(offset_back) << "\n";
746  std::string expected = oss.str();
747  DriverStr(expected, "LongBalc");
748}
749
750TEST_F(AssemblerMIPS64Test, Bc) {
751  mips64::Mips64Label label1, label2;
752  __ Bc(&label1);
753  constexpr size_t kAdduCount1 = 63;
754  for (size_t i = 0; i != kAdduCount1; ++i) {
755    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
756  }
757  __ Bind(&label1);
758  __ Bc(&label2);
759  constexpr size_t kAdduCount2 = 64;
760  for (size_t i = 0; i != kAdduCount2; ++i) {
761    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
762  }
763  __ Bind(&label2);
764  __ Bc(&label1);
765
766  std::string expected =
767      ".set noreorder\n"
768      "bc 1f\n" +
769      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
770      "1:\n"
771      "bc 2f\n" +
772      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
773      "2:\n"
774      "bc 1b\n";
775  DriverStr(expected, "Bc");
776}
777
778TEST_F(AssemblerMIPS64Test, Beqzc) {
779  BranchCondOneRegHelper(&mips64::Mips64Assembler::Beqzc, "Beqzc");
780}
781
782TEST_F(AssemblerMIPS64Test, Bnezc) {
783  BranchCondOneRegHelper(&mips64::Mips64Assembler::Bnezc, "Bnezc");
784}
785
786TEST_F(AssemblerMIPS64Test, Bltzc) {
787  BranchCondOneRegHelper(&mips64::Mips64Assembler::Bltzc, "Bltzc");
788}
789
790TEST_F(AssemblerMIPS64Test, Bgezc) {
791  BranchCondOneRegHelper(&mips64::Mips64Assembler::Bgezc, "Bgezc");
792}
793
794TEST_F(AssemblerMIPS64Test, Blezc) {
795  BranchCondOneRegHelper(&mips64::Mips64Assembler::Blezc, "Blezc");
796}
797
798TEST_F(AssemblerMIPS64Test, Bgtzc) {
799  BranchCondOneRegHelper(&mips64::Mips64Assembler::Bgtzc, "Bgtzc");
800}
801
802TEST_F(AssemblerMIPS64Test, Beqc) {
803  BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Beqc, "Beqc");
804}
805
806TEST_F(AssemblerMIPS64Test, Bnec) {
807  BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bnec, "Bnec");
808}
809
810TEST_F(AssemblerMIPS64Test, Bltc) {
811  BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bltc, "Bltc");
812}
813
814TEST_F(AssemblerMIPS64Test, Bgec) {
815  BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bgec, "Bgec");
816}
817
818TEST_F(AssemblerMIPS64Test, Bltuc) {
819  BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bltuc, "Bltuc");
820}
821
822TEST_F(AssemblerMIPS64Test, Bgeuc) {
823  BranchCondTwoRegsHelper(&mips64::Mips64Assembler::Bgeuc, "Bgeuc");
824}
825
826TEST_F(AssemblerMIPS64Test, Bc1eqz) {
827    mips64::Mips64Label label;
828    __ Bc1eqz(mips64::F0, &label);
829    constexpr size_t kAdduCount1 = 63;
830    for (size_t i = 0; i != kAdduCount1; ++i) {
831      __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
832    }
833    __ Bind(&label);
834    constexpr size_t kAdduCount2 = 64;
835    for (size_t i = 0; i != kAdduCount2; ++i) {
836      __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
837    }
838    __ Bc1eqz(mips64::F31, &label);
839
840    std::string expected =
841        ".set noreorder\n"
842        "bc1eqz $f0, 1f\n"
843        "nop\n" +
844        RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
845        "1:\n" +
846        RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
847        "bc1eqz $f31, 1b\n"
848        "nop\n";
849    DriverStr(expected, "Bc1eqz");
850}
851
852TEST_F(AssemblerMIPS64Test, Bc1nez) {
853    mips64::Mips64Label label;
854    __ Bc1nez(mips64::F0, &label);
855    constexpr size_t kAdduCount1 = 63;
856    for (size_t i = 0; i != kAdduCount1; ++i) {
857      __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
858    }
859    __ Bind(&label);
860    constexpr size_t kAdduCount2 = 64;
861    for (size_t i = 0; i != kAdduCount2; ++i) {
862      __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
863    }
864    __ Bc1nez(mips64::F31, &label);
865
866    std::string expected =
867        ".set noreorder\n"
868        "bc1nez $f0, 1f\n"
869        "nop\n" +
870        RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
871        "1:\n" +
872        RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
873        "bc1nez $f31, 1b\n"
874        "nop\n";
875    DriverStr(expected, "Bc1nez");
876}
877
878TEST_F(AssemblerMIPS64Test, LongBeqc) {
879  mips64::Mips64Label label;
880  __ Beqc(mips64::A0, mips64::A1, &label);
881  constexpr uint32_t kAdduCount1 = (1u << 15) + 1;
882  for (uint32_t i = 0; i != kAdduCount1; ++i) {
883    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
884  }
885  __ Bind(&label);
886  constexpr uint32_t kAdduCount2 = (1u << 15) + 1;
887  for (uint32_t i = 0; i != kAdduCount2; ++i) {
888    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
889  }
890  __ Beqc(mips64::A2, mips64::A3, &label);
891
892  uint32_t offset_forward = 2 + kAdduCount1;  // 2: account for auipc and jic.
893  offset_forward <<= 2;
894  offset_forward += (offset_forward & 0x8000) << 1;  // Account for sign extension in jic.
895
896  uint32_t offset_back = -(kAdduCount2 + 1);  // 1: account for bnec.
897  offset_back <<= 2;
898  offset_back += (offset_back & 0x8000) << 1;  // Account for sign extension in jic.
899
900  std::ostringstream oss;
901  oss <<
902      ".set noreorder\n"
903      "bnec $a0, $a1, 1f\n"
904      "auipc $at, 0x" << std::hex << High16Bits(offset_forward) << "\n"
905      "jic $at, 0x" << std::hex << Low16Bits(offset_forward) << "\n"
906      "1:\n" <<
907      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") <<
908      "2:\n" <<
909      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") <<
910      "bnec $a2, $a3, 3f\n"
911      "auipc $at, 0x" << std::hex << High16Bits(offset_back) << "\n"
912      "jic $at, 0x" << std::hex << Low16Bits(offset_back) << "\n"
913      "3:\n";
914  std::string expected = oss.str();
915  DriverStr(expected, "LongBeqc");
916}
917
918//////////
919// MISC //
920//////////
921
922TEST_F(AssemblerMIPS64Test, Lwpc) {
923  // Lwpc() takes an unsigned 19-bit immediate, while the GNU assembler needs a signed offset,
924  // hence the sign extension from bit 18 with `imm - ((imm & 0x40000) << 1)`.
925  // The GNU assembler also wants the offset to be a multiple of 4, which it will shift right
926  // by 2 positions when encoding, hence `<< 2` to compensate for that shift.
927  // We capture the value of the immediate with `.set imm, {imm}` because the value is needed
928  // twice for the sign extension, but `{imm}` is substituted only once.
929  const char* code = ".set imm, {imm}\nlw ${reg}, ((imm - ((imm & 0x40000) << 1)) << 2)($pc)";
930  DriverStr(RepeatRIb(&mips64::Mips64Assembler::Lwpc, 19, code), "Lwpc");
931}
932
933TEST_F(AssemblerMIPS64Test, Lwupc) {
934  // The comment for the Lwpc test applies here as well.
935  const char* code = ".set imm, {imm}\nlwu ${reg}, ((imm - ((imm & 0x40000) << 1)) << 2)($pc)";
936  DriverStr(RepeatRIb(&mips64::Mips64Assembler::Lwupc, 19, code), "Lwupc");
937}
938
939TEST_F(AssemblerMIPS64Test, Ldpc) {
940  // The comment for the Lwpc test applies here as well.
941  const char* code = ".set imm, {imm}\nld ${reg}, ((imm - ((imm & 0x20000) << 1)) << 3)($pc)";
942  DriverStr(RepeatRIb(&mips64::Mips64Assembler::Ldpc, 18, code), "Ldpc");
943}
944
945TEST_F(AssemblerMIPS64Test, Auipc) {
946  DriverStr(RepeatRIb(&mips64::Mips64Assembler::Auipc, 16, "auipc ${reg}, {imm}"), "Auipc");
947}
948
949TEST_F(AssemblerMIPS64Test, Addiupc) {
950  // The comment from the Lwpc() test applies to this Addiupc() test as well.
951  const char* code = ".set imm, {imm}\naddiupc ${reg}, (imm - ((imm & 0x40000) << 1)) << 2";
952  DriverStr(RepeatRIb(&mips64::Mips64Assembler::Addiupc, 19, code), "Addiupc");
953}
954
955TEST_F(AssemblerMIPS64Test, LoadFarthestNearLabelAddress) {
956  mips64::Mips64Label label;
957  __ LoadLabelAddress(mips64::V0, &label);
958  constexpr uint32_t kAdduCount = 0x3FFDE;
959  for (uint32_t i = 0; i != kAdduCount; ++i) {
960    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
961  }
962  __ Bind(&label);
963
964  std::string expected =
965      "lapc $v0, 1f\n" +
966      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
967      "1:\n";
968  DriverStr(expected, "LoadFarthestNearLabelAddress");
969  EXPECT_EQ(__ GetLabelLocation(&label), (1 + kAdduCount) * 4);
970}
971
972TEST_F(AssemblerMIPS64Test, LoadNearestFarLabelAddress) {
973  mips64::Mips64Label label;
974  __ LoadLabelAddress(mips64::V0, &label);
975  constexpr uint32_t kAdduCount = 0x3FFDF;
976  for (uint32_t i = 0; i != kAdduCount; ++i) {
977    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
978  }
979  __ Bind(&label);
980
981  std::string expected =
982      "1:\n"
983      "auipc $at, %hi(2f - 1b)\n"
984      "daddiu $v0, $at, %lo(2f - 1b)\n" +
985      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
986      "2:\n";
987  DriverStr(expected, "LoadNearestFarLabelAddress");
988  EXPECT_EQ(__ GetLabelLocation(&label), (2 + kAdduCount) * 4);
989}
990
991TEST_F(AssemblerMIPS64Test, LoadFarthestNearLiteral) {
992  mips64::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
993  __ LoadLiteral(mips64::V0, mips64::kLoadWord, literal);
994  constexpr uint32_t kAdduCount = 0x3FFDE;
995  for (uint32_t i = 0; i != kAdduCount; ++i) {
996    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
997  }
998
999  std::string expected =
1000      "lwpc $v0, 1f\n" +
1001      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
1002      "1:\n"
1003      ".word 0x12345678\n";
1004  DriverStr(expected, "LoadFarthestNearLiteral");
1005  EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (1 + kAdduCount) * 4);
1006}
1007
1008TEST_F(AssemblerMIPS64Test, LoadNearestFarLiteral) {
1009  mips64::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
1010  __ LoadLiteral(mips64::V0, mips64::kLoadWord, literal);
1011  constexpr uint32_t kAdduCount = 0x3FFDF;
1012  for (uint32_t i = 0; i != kAdduCount; ++i) {
1013    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
1014  }
1015
1016  std::string expected =
1017      "1:\n"
1018      "auipc $at, %hi(2f - 1b)\n"
1019      "lw $v0, %lo(2f - 1b)($at)\n" +
1020      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
1021      "2:\n"
1022      ".word 0x12345678\n";
1023  DriverStr(expected, "LoadNearestFarLiteral");
1024  EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (2 + kAdduCount) * 4);
1025}
1026
1027TEST_F(AssemblerMIPS64Test, LoadFarthestNearLiteralUnsigned) {
1028  mips64::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
1029  __ LoadLiteral(mips64::V0, mips64::kLoadUnsignedWord, literal);
1030  constexpr uint32_t kAdduCount = 0x3FFDE;
1031  for (uint32_t i = 0; i != kAdduCount; ++i) {
1032    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
1033  }
1034
1035  std::string expected =
1036      "lwupc $v0, 1f\n" +
1037      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
1038      "1:\n"
1039      ".word 0x12345678\n";
1040  DriverStr(expected, "LoadFarthestNearLiteralUnsigned");
1041  EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (1 + kAdduCount) * 4);
1042}
1043
1044TEST_F(AssemblerMIPS64Test, LoadNearestFarLiteralUnsigned) {
1045  mips64::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
1046  __ LoadLiteral(mips64::V0, mips64::kLoadUnsignedWord, literal);
1047  constexpr uint32_t kAdduCount = 0x3FFDF;
1048  for (uint32_t i = 0; i != kAdduCount; ++i) {
1049    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
1050  }
1051
1052  std::string expected =
1053      "1:\n"
1054      "auipc $at, %hi(2f - 1b)\n"
1055      "lwu $v0, %lo(2f - 1b)($at)\n" +
1056      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
1057      "2:\n"
1058      ".word 0x12345678\n";
1059  DriverStr(expected, "LoadNearestFarLiteralUnsigned");
1060  EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (2 + kAdduCount) * 4);
1061}
1062
1063TEST_F(AssemblerMIPS64Test, LoadFarthestNearLiteralLong) {
1064  mips64::Literal* literal = __ NewLiteral<uint64_t>(UINT64_C(0x0123456789ABCDEF));
1065  __ LoadLiteral(mips64::V0, mips64::kLoadDoubleword, literal);
1066  constexpr uint32_t kAdduCount = 0x3FFDD;
1067  for (uint32_t i = 0; i != kAdduCount; ++i) {
1068    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
1069  }
1070
1071  std::string expected =
1072      "ldpc $v0, 1f\n" +
1073      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
1074      "1:\n"
1075      ".dword 0x0123456789ABCDEF\n";
1076  DriverStr(expected, "LoadFarthestNearLiteralLong");
1077  EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (1 + kAdduCount) * 4);
1078}
1079
1080TEST_F(AssemblerMIPS64Test, LoadNearestFarLiteralLong) {
1081  mips64::Literal* literal = __ NewLiteral<uint64_t>(UINT64_C(0x0123456789ABCDEF));
1082  __ LoadLiteral(mips64::V0, mips64::kLoadDoubleword, literal);
1083  constexpr uint32_t kAdduCount = 0x3FFDE;
1084  for (uint32_t i = 0; i != kAdduCount; ++i) {
1085    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
1086  }
1087
1088  std::string expected =
1089      "1:\n"
1090      "auipc $at, %hi(2f - 1b)\n"
1091      "ld $v0, %lo(2f - 1b)($at)\n" +
1092      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
1093      "2:\n"
1094      ".dword 0x0123456789ABCDEF\n";
1095  DriverStr(expected, "LoadNearestFarLiteralLong");
1096  EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (2 + kAdduCount) * 4);
1097}
1098
1099TEST_F(AssemblerMIPS64Test, LongLiteralAlignmentNop) {
1100  mips64::Literal* literal1 = __ NewLiteral<uint64_t>(UINT64_C(0x0123456789ABCDEF));
1101  mips64::Literal* literal2 = __ NewLiteral<uint64_t>(UINT64_C(0x5555555555555555));
1102  mips64::Literal* literal3 = __ NewLiteral<uint64_t>(UINT64_C(0xAAAAAAAAAAAAAAAA));
1103  __ LoadLiteral(mips64::A1, mips64::kLoadDoubleword, literal1);
1104  __ LoadLiteral(mips64::A2, mips64::kLoadDoubleword, literal2);
1105  __ LoadLiteral(mips64::A3, mips64::kLoadDoubleword, literal3);
1106  __ LoadLabelAddress(mips64::V0, literal1->GetLabel());
1107  __ LoadLabelAddress(mips64::V1, literal2->GetLabel());
1108  // A nop will be inserted here before the 64-bit literals.
1109
1110  std::string expected =
1111      "ldpc $a1, 1f\n"
1112      // The GNU assembler incorrectly requires the ldpc instruction to be located
1113      // at an address that's a multiple of 8. TODO: Remove this workaround if/when
1114      // the assembler is fixed.
1115      // "ldpc $a2, 2f\n"
1116      ".word 0xECD80004\n"
1117      "ldpc $a3, 3f\n"
1118      "lapc $v0, 1f\n"
1119      "lapc $v1, 2f\n"
1120      "nop\n"
1121      "1:\n"
1122      ".dword 0x0123456789ABCDEF\n"
1123      "2:\n"
1124      ".dword 0x5555555555555555\n"
1125      "3:\n"
1126      ".dword 0xAAAAAAAAAAAAAAAA\n";
1127  DriverStr(expected, "LongLiteralAlignmentNop");
1128  EXPECT_EQ(__ GetLabelLocation(literal1->GetLabel()), 6 * 4u);
1129  EXPECT_EQ(__ GetLabelLocation(literal2->GetLabel()), 8 * 4u);
1130  EXPECT_EQ(__ GetLabelLocation(literal3->GetLabel()), 10 * 4u);
1131}
1132
1133TEST_F(AssemblerMIPS64Test, LongLiteralAlignmentNoNop) {
1134  mips64::Literal* literal1 = __ NewLiteral<uint64_t>(UINT64_C(0x0123456789ABCDEF));
1135  mips64::Literal* literal2 = __ NewLiteral<uint64_t>(UINT64_C(0x5555555555555555));
1136  __ LoadLiteral(mips64::A1, mips64::kLoadDoubleword, literal1);
1137  __ LoadLiteral(mips64::A2, mips64::kLoadDoubleword, literal2);
1138  __ LoadLabelAddress(mips64::V0, literal1->GetLabel());
1139  __ LoadLabelAddress(mips64::V1, literal2->GetLabel());
1140
1141  std::string expected =
1142      "ldpc $a1, 1f\n"
1143      // The GNU assembler incorrectly requires the ldpc instruction to be located
1144      // at an address that's a multiple of 8. TODO: Remove this workaround if/when
1145      // the assembler is fixed.
1146      // "ldpc $a2, 2f\n"
1147      ".word 0xECD80003\n"
1148      "lapc $v0, 1f\n"
1149      "lapc $v1, 2f\n"
1150      "1:\n"
1151      ".dword 0x0123456789ABCDEF\n"
1152      "2:\n"
1153      ".dword 0x5555555555555555\n";
1154  DriverStr(expected, "LongLiteralAlignmentNoNop");
1155  EXPECT_EQ(__ GetLabelLocation(literal1->GetLabel()), 4 * 4u);
1156  EXPECT_EQ(__ GetLabelLocation(literal2->GetLabel()), 6 * 4u);
1157}
1158
1159TEST_F(AssemblerMIPS64Test, FarLongLiteralAlignmentNop) {
1160  mips64::Literal* literal = __ NewLiteral<uint64_t>(UINT64_C(0x0123456789ABCDEF));
1161  __ LoadLiteral(mips64::V0, mips64::kLoadDoubleword, literal);
1162  __ LoadLabelAddress(mips64::V1, literal->GetLabel());
1163  constexpr uint32_t kAdduCount = 0x3FFDF;
1164  for (uint32_t i = 0; i != kAdduCount; ++i) {
1165    __ Addu(mips64::ZERO, mips64::ZERO, mips64::ZERO);
1166  }
1167  // A nop will be inserted here before the 64-bit literal.
1168
1169  std::string expected =
1170      "1:\n"
1171      "auipc $at, %hi(3f - 1b)\n"
1172      "ld $v0, %lo(3f - 1b)($at)\n"
1173      "2:\n"
1174      "auipc $at, %hi(3f - 2b)\n"
1175      "daddiu $v1, $at, %lo(3f - 2b)\n" +
1176      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
1177      "nop\n"
1178      "3:\n"
1179      ".dword 0x0123456789ABCDEF\n";
1180  DriverStr(expected, "FarLongLiteralAlignmentNop");
1181  EXPECT_EQ(__ GetLabelLocation(literal->GetLabel()), (5 + kAdduCount) * 4);
1182}
1183
1184TEST_F(AssemblerMIPS64Test, Addu) {
1185  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Addu, "addu ${reg1}, ${reg2}, ${reg3}"), "addu");
1186}
1187
1188TEST_F(AssemblerMIPS64Test, Addiu) {
1189  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Addiu, -16, "addiu ${reg1}, ${reg2}, {imm}"),
1190            "addiu");
1191}
1192
1193TEST_F(AssemblerMIPS64Test, Daddu) {
1194  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Daddu, "daddu ${reg1}, ${reg2}, ${reg3}"), "daddu");
1195}
1196
1197TEST_F(AssemblerMIPS64Test, Daddiu) {
1198  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Daddiu, -16, "daddiu ${reg1}, ${reg2}, {imm}"),
1199            "daddiu");
1200}
1201
1202TEST_F(AssemblerMIPS64Test, Subu) {
1203  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Subu, "subu ${reg1}, ${reg2}, ${reg3}"), "subu");
1204}
1205
1206TEST_F(AssemblerMIPS64Test, Dsubu) {
1207  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Dsubu, "dsubu ${reg1}, ${reg2}, ${reg3}"), "dsubu");
1208}
1209
1210TEST_F(AssemblerMIPS64Test, MulR6) {
1211  DriverStr(RepeatRRR(&mips64::Mips64Assembler::MulR6, "mul ${reg1}, ${reg2}, ${reg3}"), "mulR6");
1212}
1213
1214TEST_F(AssemblerMIPS64Test, DivR6) {
1215  DriverStr(RepeatRRR(&mips64::Mips64Assembler::DivR6, "div ${reg1}, ${reg2}, ${reg3}"), "divR6");
1216}
1217
1218TEST_F(AssemblerMIPS64Test, ModR6) {
1219  DriverStr(RepeatRRR(&mips64::Mips64Assembler::ModR6, "mod ${reg1}, ${reg2}, ${reg3}"), "modR6");
1220}
1221
1222TEST_F(AssemblerMIPS64Test, DivuR6) {
1223  DriverStr(RepeatRRR(&mips64::Mips64Assembler::DivuR6, "divu ${reg1}, ${reg2}, ${reg3}"),
1224            "divuR6");
1225}
1226
1227TEST_F(AssemblerMIPS64Test, ModuR6) {
1228  DriverStr(RepeatRRR(&mips64::Mips64Assembler::ModuR6, "modu ${reg1}, ${reg2}, ${reg3}"),
1229            "moduR6");
1230}
1231
1232TEST_F(AssemblerMIPS64Test, Dmul) {
1233  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Dmul, "dmul ${reg1}, ${reg2}, ${reg3}"), "dmul");
1234}
1235
1236TEST_F(AssemblerMIPS64Test, Ddiv) {
1237  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Ddiv, "ddiv ${reg1}, ${reg2}, ${reg3}"), "ddiv");
1238}
1239
1240TEST_F(AssemblerMIPS64Test, Dmod) {
1241  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Dmod, "dmod ${reg1}, ${reg2}, ${reg3}"), "dmod");
1242}
1243
1244TEST_F(AssemblerMIPS64Test, Ddivu) {
1245  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Ddivu, "ddivu ${reg1}, ${reg2}, ${reg3}"), "ddivu");
1246}
1247
1248TEST_F(AssemblerMIPS64Test, Dmodu) {
1249  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Dmodu, "dmodu ${reg1}, ${reg2}, ${reg3}"), "dmodu");
1250}
1251
1252TEST_F(AssemblerMIPS64Test, And) {
1253  DriverStr(RepeatRRR(&mips64::Mips64Assembler::And, "and ${reg1}, ${reg2}, ${reg3}"), "and");
1254}
1255
1256TEST_F(AssemblerMIPS64Test, Andi) {
1257  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Andi, 16, "andi ${reg1}, ${reg2}, {imm}"), "andi");
1258}
1259
1260TEST_F(AssemblerMIPS64Test, Or) {
1261  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Or, "or ${reg1}, ${reg2}, ${reg3}"), "or");
1262}
1263
1264TEST_F(AssemblerMIPS64Test, Ori) {
1265  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Ori, 16, "ori ${reg1}, ${reg2}, {imm}"), "ori");
1266}
1267
1268TEST_F(AssemblerMIPS64Test, Xor) {
1269  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Xor, "xor ${reg1}, ${reg2}, ${reg3}"), "xor");
1270}
1271
1272TEST_F(AssemblerMIPS64Test, Xori) {
1273  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Xori, 16, "xori ${reg1}, ${reg2}, {imm}"), "xori");
1274}
1275
1276TEST_F(AssemblerMIPS64Test, Nor) {
1277  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Nor, "nor ${reg1}, ${reg2}, ${reg3}"), "nor");
1278}
1279
1280TEST_F(AssemblerMIPS64Test, Lb) {
1281  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Lb, -16, "lb ${reg1}, {imm}(${reg2})"), "lb");
1282}
1283
1284TEST_F(AssemblerMIPS64Test, Lh) {
1285  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Lh, -16, "lh ${reg1}, {imm}(${reg2})"), "lh");
1286}
1287
1288TEST_F(AssemblerMIPS64Test, Lw) {
1289  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Lw, -16, "lw ${reg1}, {imm}(${reg2})"), "lw");
1290}
1291
1292TEST_F(AssemblerMIPS64Test, Ld) {
1293  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Ld, -16, "ld ${reg1}, {imm}(${reg2})"), "ld");
1294}
1295
1296TEST_F(AssemblerMIPS64Test, Lbu) {
1297  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Lbu, -16, "lbu ${reg1}, {imm}(${reg2})"), "lbu");
1298}
1299
1300TEST_F(AssemblerMIPS64Test, Lhu) {
1301  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Lhu, -16, "lhu ${reg1}, {imm}(${reg2})"), "lhu");
1302}
1303
1304TEST_F(AssemblerMIPS64Test, Lwu) {
1305  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Lwu, -16, "lwu ${reg1}, {imm}(${reg2})"), "lwu");
1306}
1307
1308TEST_F(AssemblerMIPS64Test, Lui) {
1309  DriverStr(RepeatRIb(&mips64::Mips64Assembler::Lui, 16, "lui ${reg}, {imm}"), "lui");
1310}
1311
1312TEST_F(AssemblerMIPS64Test, Daui) {
1313  std::vector<mips64::GpuRegister*> reg1_registers = GetRegisters();
1314  std::vector<mips64::GpuRegister*> reg2_registers = GetRegisters();
1315  reg2_registers.erase(reg2_registers.begin());  // reg2 can't be ZERO, remove it.
1316  std::vector<int64_t> imms = CreateImmediateValuesBits(/* imm_bits */ 16, /* as_uint */ true);
1317  WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * imms.size());
1318  std::ostringstream expected;
1319  for (mips64::GpuRegister* reg1 : reg1_registers) {
1320    for (mips64::GpuRegister* reg2 : reg2_registers) {
1321      for (int64_t imm : imms) {
1322        __ Daui(*reg1, *reg2, imm);
1323        expected << "daui $" << *reg1 << ", $" << *reg2 << ", " << imm << "\n";
1324      }
1325    }
1326  }
1327  DriverStr(expected.str(), "daui");
1328}
1329
1330TEST_F(AssemblerMIPS64Test, Dahi) {
1331  DriverStr(RepeatRIb(&mips64::Mips64Assembler::Dahi, 16, "dahi ${reg}, ${reg}, {imm}"), "dahi");
1332}
1333
1334TEST_F(AssemblerMIPS64Test, Dati) {
1335  DriverStr(RepeatRIb(&mips64::Mips64Assembler::Dati, 16, "dati ${reg}, ${reg}, {imm}"), "dati");
1336}
1337
1338TEST_F(AssemblerMIPS64Test, Sb) {
1339  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sb, -16, "sb ${reg1}, {imm}(${reg2})"), "sb");
1340}
1341
1342TEST_F(AssemblerMIPS64Test, Sh) {
1343  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sh, -16, "sh ${reg1}, {imm}(${reg2})"), "sh");
1344}
1345
1346TEST_F(AssemblerMIPS64Test, Sw) {
1347  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sw, -16, "sw ${reg1}, {imm}(${reg2})"), "sw");
1348}
1349
1350TEST_F(AssemblerMIPS64Test, Sd) {
1351  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sd, -16, "sd ${reg1}, {imm}(${reg2})"), "sd");
1352}
1353
1354TEST_F(AssemblerMIPS64Test, Slt) {
1355  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Slt, "slt ${reg1}, ${reg2}, ${reg3}"), "slt");
1356}
1357
1358TEST_F(AssemblerMIPS64Test, Sltu) {
1359  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Sltu, "sltu ${reg1}, ${reg2}, ${reg3}"), "sltu");
1360}
1361
1362TEST_F(AssemblerMIPS64Test, Slti) {
1363  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Slti, -16, "slti ${reg1}, ${reg2}, {imm}"),
1364            "slti");
1365}
1366
1367TEST_F(AssemblerMIPS64Test, Sltiu) {
1368  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sltiu, -16, "sltiu ${reg1}, ${reg2}, {imm}"),
1369            "sltiu");
1370}
1371
1372TEST_F(AssemblerMIPS64Test, Move) {
1373  DriverStr(RepeatRR(&mips64::Mips64Assembler::Move, "or ${reg1}, ${reg2}, $zero"), "move");
1374}
1375
1376TEST_F(AssemblerMIPS64Test, Clear) {
1377  DriverStr(RepeatR(&mips64::Mips64Assembler::Clear, "or ${reg}, $zero, $zero"), "clear");
1378}
1379
1380TEST_F(AssemblerMIPS64Test, Not) {
1381  DriverStr(RepeatRR(&mips64::Mips64Assembler::Not, "nor ${reg1}, ${reg2}, $zero"), "not");
1382}
1383
1384TEST_F(AssemblerMIPS64Test, Bitswap) {
1385  DriverStr(RepeatRR(&mips64::Mips64Assembler::Bitswap, "bitswap ${reg1}, ${reg2}"), "bitswap");
1386}
1387
1388TEST_F(AssemblerMIPS64Test, Dbitswap) {
1389  DriverStr(RepeatRR(&mips64::Mips64Assembler::Dbitswap, "dbitswap ${reg1}, ${reg2}"), "dbitswap");
1390}
1391
1392TEST_F(AssemblerMIPS64Test, Seb) {
1393  DriverStr(RepeatRR(&mips64::Mips64Assembler::Seb, "seb ${reg1}, ${reg2}"), "seb");
1394}
1395
1396TEST_F(AssemblerMIPS64Test, Seh) {
1397  DriverStr(RepeatRR(&mips64::Mips64Assembler::Seh, "seh ${reg1}, ${reg2}"), "seh");
1398}
1399
1400TEST_F(AssemblerMIPS64Test, Dsbh) {
1401  DriverStr(RepeatRR(&mips64::Mips64Assembler::Dsbh, "dsbh ${reg1}, ${reg2}"), "dsbh");
1402}
1403
1404TEST_F(AssemblerMIPS64Test, Dshd) {
1405  DriverStr(RepeatRR(&mips64::Mips64Assembler::Dshd, "dshd ${reg1}, ${reg2}"), "dshd");
1406}
1407
1408TEST_F(AssemblerMIPS64Test, Dext) {
1409  std::vector<mips64::GpuRegister*> reg1_registers = GetRegisters();
1410  std::vector<mips64::GpuRegister*> reg2_registers = GetRegisters();
1411  WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * 33 * 16);
1412  std::ostringstream expected;
1413  for (mips64::GpuRegister* reg1 : reg1_registers) {
1414    for (mips64::GpuRegister* reg2 : reg2_registers) {
1415      for (int32_t pos = 0; pos < 32; pos++) {
1416        for (int32_t size = 1; size <= 32; size++) {
1417          __ Dext(*reg1, *reg2, pos, size);
1418          expected << "dext $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n";
1419        }
1420      }
1421    }
1422  }
1423
1424  DriverStr(expected.str(), "Dext");
1425}
1426
1427TEST_F(AssemblerMIPS64Test, Dinsu) {
1428  std::vector<mips64::GpuRegister*> reg1_registers = GetRegisters();
1429  std::vector<mips64::GpuRegister*> reg2_registers = GetRegisters();
1430  WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * 33 * 16);
1431  std::ostringstream expected;
1432  for (mips64::GpuRegister* reg1 : reg1_registers) {
1433    for (mips64::GpuRegister* reg2 : reg2_registers) {
1434      for (int32_t pos = 32; pos < 64; pos++) {
1435        for (int32_t size = 1; pos + size <= 64; size++) {
1436          __ Dinsu(*reg1, *reg2, pos, size);
1437          expected << "dinsu $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n";
1438        }
1439      }
1440    }
1441  }
1442
1443  DriverStr(expected.str(), "Dinsu");
1444}
1445
1446TEST_F(AssemblerMIPS64Test, Lsa) {
1447  DriverStr(RepeatRRRIb(&mips64::Mips64Assembler::Lsa,
1448                        2,
1449                        "lsa ${reg1}, ${reg2}, ${reg3}, {imm}",
1450                        1),
1451            "lsa");
1452}
1453
1454TEST_F(AssemblerMIPS64Test, Dlsa) {
1455  DriverStr(RepeatRRRIb(&mips64::Mips64Assembler::Dlsa,
1456                        2,
1457                        "dlsa ${reg1}, ${reg2}, ${reg3}, {imm}",
1458                        1),
1459            "dlsa");
1460}
1461
1462TEST_F(AssemblerMIPS64Test, Wsbh) {
1463  DriverStr(RepeatRR(&mips64::Mips64Assembler::Wsbh, "wsbh ${reg1}, ${reg2}"), "wsbh");
1464}
1465
1466TEST_F(AssemblerMIPS64Test, Sll) {
1467  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sll, 5, "sll ${reg1}, ${reg2}, {imm}"), "sll");
1468}
1469
1470TEST_F(AssemblerMIPS64Test, Srl) {
1471  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Srl, 5, "srl ${reg1}, ${reg2}, {imm}"), "srl");
1472}
1473
1474TEST_F(AssemblerMIPS64Test, Rotr) {
1475  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Rotr, 5, "rotr ${reg1}, ${reg2}, {imm}"), "rotr");
1476}
1477
1478TEST_F(AssemblerMIPS64Test, Sra) {
1479  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sra, 5, "sra ${reg1}, ${reg2}, {imm}"), "sra");
1480}
1481
1482TEST_F(AssemblerMIPS64Test, Sllv) {
1483  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Sllv, "sllv ${reg1}, ${reg2}, ${reg3}"), "sllv");
1484}
1485
1486TEST_F(AssemblerMIPS64Test, Srlv) {
1487  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Srlv, "srlv ${reg1}, ${reg2}, ${reg3}"), "srlv");
1488}
1489
1490TEST_F(AssemblerMIPS64Test, Rotrv) {
1491  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Rotrv, "rotrv ${reg1}, ${reg2}, ${reg3}"), "rotrv");
1492}
1493
1494TEST_F(AssemblerMIPS64Test, Srav) {
1495  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Srav, "srav ${reg1}, ${reg2}, ${reg3}"), "srav");
1496}
1497
1498TEST_F(AssemblerMIPS64Test, Dsll) {
1499  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsll, 5, "dsll ${reg1}, ${reg2}, {imm}"), "dsll");
1500}
1501
1502TEST_F(AssemblerMIPS64Test, Dsrl) {
1503  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsrl, 5, "dsrl ${reg1}, ${reg2}, {imm}"), "dsrl");
1504}
1505
1506TEST_F(AssemblerMIPS64Test, Drotr) {
1507  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Drotr, 5, "drotr ${reg1}, ${reg2}, {imm}"),
1508            "drotr");
1509}
1510
1511TEST_F(AssemblerMIPS64Test, Dsra) {
1512  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsra, 5, "dsra ${reg1}, ${reg2}, {imm}"), "dsra");
1513}
1514
1515TEST_F(AssemblerMIPS64Test, Dsll32) {
1516  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsll32, 5, "dsll32 ${reg1}, ${reg2}, {imm}"),
1517            "dsll32");
1518}
1519
1520TEST_F(AssemblerMIPS64Test, Dsrl32) {
1521  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsrl32, 5, "dsrl32 ${reg1}, ${reg2}, {imm}"),
1522            "dsrl32");
1523}
1524
1525TEST_F(AssemblerMIPS64Test, Drotr32) {
1526  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Drotr32, 5, "drotr32 ${reg1}, ${reg2}, {imm}"),
1527            "drotr32");
1528}
1529
1530TEST_F(AssemblerMIPS64Test, Dsra32) {
1531  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Dsra32, 5, "dsra32 ${reg1}, ${reg2}, {imm}"),
1532            "dsra32");
1533}
1534
1535TEST_F(AssemblerMIPS64Test, Dsllv) {
1536  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Dsllv, "dsllv ${reg1}, ${reg2}, ${reg3}"), "dsllv");
1537}
1538
1539TEST_F(AssemblerMIPS64Test, Dsrlv) {
1540  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Dsrlv, "dsrlv ${reg1}, ${reg2}, ${reg3}"), "dsrlv");
1541}
1542
1543TEST_F(AssemblerMIPS64Test, Dsrav) {
1544  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Dsrav, "dsrav ${reg1}, ${reg2}, ${reg3}"), "dsrav");
1545}
1546
1547TEST_F(AssemblerMIPS64Test, Sc) {
1548  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Sc, -9, "sc ${reg1}, {imm}(${reg2})"), "sc");
1549}
1550
1551TEST_F(AssemblerMIPS64Test, Scd) {
1552  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Scd, -9, "scd ${reg1}, {imm}(${reg2})"), "scd");
1553}
1554
1555TEST_F(AssemblerMIPS64Test, Ll) {
1556  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Ll, -9, "ll ${reg1}, {imm}(${reg2})"), "ll");
1557}
1558
1559TEST_F(AssemblerMIPS64Test, Lld) {
1560  DriverStr(RepeatRRIb(&mips64::Mips64Assembler::Lld, -9, "lld ${reg1}, {imm}(${reg2})"), "lld");
1561}
1562
1563TEST_F(AssemblerMIPS64Test, Seleqz) {
1564  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Seleqz, "seleqz ${reg1}, ${reg2}, ${reg3}"),
1565            "seleqz");
1566}
1567
1568TEST_F(AssemblerMIPS64Test, Selnez) {
1569  DriverStr(RepeatRRR(&mips64::Mips64Assembler::Selnez, "selnez ${reg1}, ${reg2}, ${reg3}"),
1570            "selnez");
1571}
1572
1573TEST_F(AssemblerMIPS64Test, Clz) {
1574  DriverStr(RepeatRR(&mips64::Mips64Assembler::Clz, "clz ${reg1}, ${reg2}"), "clz");
1575}
1576
1577TEST_F(AssemblerMIPS64Test, Clo) {
1578  DriverStr(RepeatRR(&mips64::Mips64Assembler::Clo, "clo ${reg1}, ${reg2}"), "clo");
1579}
1580
1581TEST_F(AssemblerMIPS64Test, Dclz) {
1582  DriverStr(RepeatRR(&mips64::Mips64Assembler::Dclz, "dclz ${reg1}, ${reg2}"), "dclz");
1583}
1584
1585TEST_F(AssemblerMIPS64Test, Dclo) {
1586  DriverStr(RepeatRR(&mips64::Mips64Assembler::Dclo, "dclo ${reg1}, ${reg2}"), "dclo");
1587}
1588
1589TEST_F(AssemblerMIPS64Test, LoadFromOffset) {
1590  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A0, 0);
1591  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0);
1592  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 1);
1593  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 256);
1594  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 1000);
1595  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x7FFF);
1596  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x8000);
1597  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x8001);
1598  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x10000);
1599  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x12345678);
1600  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, -256);
1601  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, -32768);
1602  __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0xABCDEF00);
1603
1604  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A0, 0);
1605  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0);
1606  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 1);
1607  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 256);
1608  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 1000);
1609  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x7FFF);
1610  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x8000);
1611  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x8001);
1612  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x10000);
1613  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x12345678);
1614  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, -256);
1615  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, -32768);
1616  __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0xABCDEF00);
1617
1618  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A0, 0);
1619  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0);
1620  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 2);
1621  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 256);
1622  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 1000);
1623  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x7FFE);
1624  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x8000);
1625  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x8002);
1626  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x10000);
1627  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x12345678);
1628  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, -256);
1629  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, -32768);
1630  __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0xABCDEF00);
1631
1632  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A0, 0);
1633  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0);
1634  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 2);
1635  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 256);
1636  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 1000);
1637  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x7FFE);
1638  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x8000);
1639  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x8002);
1640  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x10000);
1641  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x12345678);
1642  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, -256);
1643  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, -32768);
1644  __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0xABCDEF00);
1645
1646  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A0, 0);
1647  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0);
1648  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 4);
1649  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 256);
1650  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 1000);
1651  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x7FFC);
1652  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x8000);
1653  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x8004);
1654  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x10000);
1655  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x12345678);
1656  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, -256);
1657  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, -32768);
1658  __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0xABCDEF00);
1659
1660  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A0, 0);
1661  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0);
1662  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 4);
1663  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 256);
1664  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 1000);
1665  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x7FFC);
1666  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x8000);
1667  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x8004);
1668  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x10000);
1669  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x12345678);
1670  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, -256);
1671  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, -32768);
1672  __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0xABCDEF00);
1673
1674  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A0, 0);
1675  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0);
1676  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 4);
1677  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 256);
1678  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 1000);
1679  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x7FFC);
1680  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x8000);
1681  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x8004);
1682  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x10000);
1683  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x12345678);
1684  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, -256);
1685  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, -32768);
1686  __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0xABCDEF00);
1687
1688  const char* expected =
1689      "lb $a0, 0($a0)\n"
1690      "lb $a0, 0($a1)\n"
1691      "lb $a0, 1($a1)\n"
1692      "lb $a0, 256($a1)\n"
1693      "lb $a0, 1000($a1)\n"
1694      "lb $a0, 0x7FFF($a1)\n"
1695      "ori $at, $zero, 0x8000\n"
1696      "daddu $at, $at, $a1\n"
1697      "lb $a0, 0($at)\n"
1698      "ori $at, $zero, 0x8000\n"
1699      "daddu $at, $at, $a1\n"
1700      "lb $a0, 1($at)\n"
1701      "lui $at, 1\n"
1702      "daddu $at, $at, $a1\n"
1703      "lb $a0, 0($at)\n"
1704      "lui $at, 0x1234\n"
1705      "ori $at, 0x5678\n"
1706      "daddu $at, $at, $a1\n"
1707      "lb $a0, 0($at)\n"
1708      "lb $a0, -256($a1)\n"
1709      "lb $a0, -32768($a1)\n"
1710      "lui $at, 0xABCD\n"
1711      "ori $at, 0xEF00\n"
1712      "daddu $at, $at, $a1\n"
1713      "lb $a0, 0($at)\n"
1714
1715      "lbu $a0, 0($a0)\n"
1716      "lbu $a0, 0($a1)\n"
1717      "lbu $a0, 1($a1)\n"
1718      "lbu $a0, 256($a1)\n"
1719      "lbu $a0, 1000($a1)\n"
1720      "lbu $a0, 0x7FFF($a1)\n"
1721      "ori $at, $zero, 0x8000\n"
1722      "daddu $at, $at, $a1\n"
1723      "lbu $a0, 0($at)\n"
1724      "ori $at, $zero, 0x8000\n"
1725      "daddu $at, $at, $a1\n"
1726      "lbu $a0, 1($at)\n"
1727      "lui $at, 1\n"
1728      "daddu $at, $at, $a1\n"
1729      "lbu $a0, 0($at)\n"
1730      "lui $at, 0x1234\n"
1731      "ori $at, 0x5678\n"
1732      "daddu $at, $at, $a1\n"
1733      "lbu $a0, 0($at)\n"
1734      "lbu $a0, -256($a1)\n"
1735      "lbu $a0, -32768($a1)\n"
1736      "lui $at, 0xABCD\n"
1737      "ori $at, 0xEF00\n"
1738      "daddu $at, $at, $a1\n"
1739      "lbu $a0, 0($at)\n"
1740
1741      "lh $a0, 0($a0)\n"
1742      "lh $a0, 0($a1)\n"
1743      "lh $a0, 2($a1)\n"
1744      "lh $a0, 256($a1)\n"
1745      "lh $a0, 1000($a1)\n"
1746      "lh $a0, 0x7FFE($a1)\n"
1747      "ori $at, $zero, 0x8000\n"
1748      "daddu $at, $at, $a1\n"
1749      "lh $a0, 0($at)\n"
1750      "ori $at, $zero, 0x8000\n"
1751      "daddu $at, $at, $a1\n"
1752      "lh $a0, 2($at)\n"
1753      "lui $at, 1\n"
1754      "daddu $at, $at, $a1\n"
1755      "lh $a0, 0($at)\n"
1756      "lui $at, 0x1234\n"
1757      "ori $at, 0x5678\n"
1758      "daddu $at, $at, $a1\n"
1759      "lh $a0, 0($at)\n"
1760      "lh $a0, -256($a1)\n"
1761      "lh $a0, -32768($a1)\n"
1762      "lui $at, 0xABCD\n"
1763      "ori $at, 0xEF00\n"
1764      "daddu $at, $at, $a1\n"
1765      "lh $a0, 0($at)\n"
1766
1767      "lhu $a0, 0($a0)\n"
1768      "lhu $a0, 0($a1)\n"
1769      "lhu $a0, 2($a1)\n"
1770      "lhu $a0, 256($a1)\n"
1771      "lhu $a0, 1000($a1)\n"
1772      "lhu $a0, 0x7FFE($a1)\n"
1773      "ori $at, $zero, 0x8000\n"
1774      "daddu $at, $at, $a1\n"
1775      "lhu $a0, 0($at)\n"
1776      "ori $at, $zero, 0x8000\n"
1777      "daddu $at, $at, $a1\n"
1778      "lhu $a0, 2($at)\n"
1779      "lui $at, 1\n"
1780      "daddu $at, $at, $a1\n"
1781      "lhu $a0, 0($at)\n"
1782      "lui $at, 0x1234\n"
1783      "ori $at, 0x5678\n"
1784      "daddu $at, $at, $a1\n"
1785      "lhu $a0, 0($at)\n"
1786      "lhu $a0, -256($a1)\n"
1787      "lhu $a0, -32768($a1)\n"
1788      "lui $at, 0xABCD\n"
1789      "ori $at, 0xEF00\n"
1790      "daddu $at, $at, $a1\n"
1791      "lhu $a0, 0($at)\n"
1792
1793      "lw $a0, 0($a0)\n"
1794      "lw $a0, 0($a1)\n"
1795      "lw $a0, 4($a1)\n"
1796      "lw $a0, 256($a1)\n"
1797      "lw $a0, 1000($a1)\n"
1798      "lw $a0, 0x7FFC($a1)\n"
1799      "ori $at, $zero, 0x8000\n"
1800      "daddu $at, $at, $a1\n"
1801      "lw $a0, 0($at)\n"
1802      "ori $at, $zero, 0x8000\n"
1803      "daddu $at, $at, $a1\n"
1804      "lw $a0, 4($at)\n"
1805      "lui $at, 1\n"
1806      "daddu $at, $at, $a1\n"
1807      "lw $a0, 0($at)\n"
1808      "lui $at, 0x1234\n"
1809      "ori $at, 0x5678\n"
1810      "daddu $at, $at, $a1\n"
1811      "lw $a0, 0($at)\n"
1812      "lw $a0, -256($a1)\n"
1813      "lw $a0, -32768($a1)\n"
1814      "lui $at, 0xABCD\n"
1815      "ori $at, 0xEF00\n"
1816      "daddu $at, $at, $a1\n"
1817      "lw $a0, 0($at)\n"
1818
1819      "lwu $a0, 0($a0)\n"
1820      "lwu $a0, 0($a1)\n"
1821      "lwu $a0, 4($a1)\n"
1822      "lwu $a0, 256($a1)\n"
1823      "lwu $a0, 1000($a1)\n"
1824      "lwu $a0, 0x7FFC($a1)\n"
1825      "ori $at, $zero, 0x8000\n"
1826      "daddu $at, $at, $a1\n"
1827      "lwu $a0, 0($at)\n"
1828      "ori $at, $zero, 0x8000\n"
1829      "daddu $at, $at, $a1\n"
1830      "lwu $a0, 4($at)\n"
1831      "lui $at, 1\n"
1832      "daddu $at, $at, $a1\n"
1833      "lwu $a0, 0($at)\n"
1834      "lui $at, 0x1234\n"
1835      "ori $at, 0x5678\n"
1836      "daddu $at, $at, $a1\n"
1837      "lwu $a0, 0($at)\n"
1838      "lwu $a0, -256($a1)\n"
1839      "lwu $a0, -32768($a1)\n"
1840      "lui $at, 0xABCD\n"
1841      "ori $at, 0xEF00\n"
1842      "daddu $at, $at, $a1\n"
1843      "lwu $a0, 0($at)\n"
1844
1845      "ld $a0, 0($a0)\n"
1846      "ld $a0, 0($a1)\n"
1847      "lwu $a0, 4($a1)\n"
1848      "lwu $t3, 8($a1)\n"
1849      "dins $a0, $t3, 32, 32\n"
1850      "ld $a0, 256($a1)\n"
1851      "ld $a0, 1000($a1)\n"
1852      "ori $at, $zero, 0x7FF8\n"
1853      "daddu $at, $at, $a1\n"
1854      "lwu $a0, 4($at)\n"
1855      "lwu $t3, 8($at)\n"
1856      "dins $a0, $t3, 32, 32\n"
1857      "ori $at, $zero, 0x8000\n"
1858      "daddu $at, $at, $a1\n"
1859      "ld $a0, 0($at)\n"
1860      "ori $at, $zero, 0x8000\n"
1861      "daddu $at, $at, $a1\n"
1862      "lwu $a0, 4($at)\n"
1863      "lwu $t3, 8($at)\n"
1864      "dins $a0, $t3, 32, 32\n"
1865      "lui $at, 1\n"
1866      "daddu $at, $at, $a1\n"
1867      "ld $a0, 0($at)\n"
1868      "lui $at, 0x1234\n"
1869      "ori $at, 0x5678\n"
1870      "daddu $at, $at, $a1\n"
1871      "ld $a0, 0($at)\n"
1872      "ld $a0, -256($a1)\n"
1873      "ld $a0, -32768($a1)\n"
1874      "lui $at, 0xABCD\n"
1875      "ori $at, 0xEF00\n"
1876      "daddu $at, $at, $a1\n"
1877      "ld $a0, 0($at)\n";
1878  DriverStr(expected, "LoadFromOffset");
1879}
1880
1881TEST_F(AssemblerMIPS64Test, LoadFpuFromOffset) {
1882  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0);
1883  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 4);
1884  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 256);
1885  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x7FFC);
1886  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x8000);
1887  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x8004);
1888  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x10000);
1889  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x12345678);
1890  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, -256);
1891  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, -32768);
1892  __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0xABCDEF00);
1893
1894  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0);
1895  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 4);
1896  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 256);
1897  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x7FFC);
1898  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x8000);
1899  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x8004);
1900  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x10000);
1901  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x12345678);
1902  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, -256);
1903  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, -32768);
1904  __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0xABCDEF00);
1905
1906  const char* expected =
1907      "lwc1 $f0, 0($a0)\n"
1908      "lwc1 $f0, 4($a0)\n"
1909      "lwc1 $f0, 256($a0)\n"
1910      "lwc1 $f0, 0x7FFC($a0)\n"
1911      "ori $at, $zero, 0x8000\n"
1912      "daddu $at, $at, $a0\n"
1913      "lwc1 $f0, 0($at)\n"
1914      "ori $at, $zero, 0x8000\n"
1915      "daddu $at, $at, $a0\n"
1916      "lwc1 $f0, 4($at)\n"
1917      "lui $at, 1\n"
1918      "daddu $at, $at, $a0\n"
1919      "lwc1 $f0, 0($at)\n"
1920      "lui $at, 0x1234\n"
1921      "ori $at, 0x5678\n"
1922      "daddu $at, $at, $a0\n"
1923      "lwc1 $f0, 0($at)\n"
1924      "lwc1 $f0, -256($a0)\n"
1925      "lwc1 $f0, -32768($a0)\n"
1926      "lui $at, 0xABCD\n"
1927      "ori $at, 0xEF00\n"
1928      "daddu $at, $at, $a0\n"
1929      "lwc1 $f0, 0($at)\n"
1930
1931      "ldc1 $f0, 0($a0)\n"
1932      "lwc1 $f0, 4($a0)\n"
1933      "lw $t3, 8($a0)\n"
1934      "mthc1 $t3, $f0\n"
1935      "ldc1 $f0, 256($a0)\n"
1936      "ori $at, $zero, 0x7FF8\n"
1937      "daddu $at, $at, $a0\n"
1938      "lwc1 $f0, 4($at)\n"
1939      "lw $t3, 8($at)\n"
1940      "mthc1 $t3, $f0\n"
1941      "ori $at, $zero, 0x8000\n"
1942      "daddu $at, $at, $a0\n"
1943      "ldc1 $f0, 0($at)\n"
1944      "ori $at, $zero, 0x8000\n"
1945      "daddu $at, $at, $a0\n"
1946      "lwc1 $f0, 4($at)\n"
1947      "lw $t3, 8($at)\n"
1948      "mthc1 $t3, $f0\n"
1949      "lui $at, 1\n"
1950      "daddu $at, $at, $a0\n"
1951      "ldc1 $f0, 0($at)\n"
1952      "lui $at, 0x1234\n"
1953      "ori $at, 0x5678\n"
1954      "daddu $at, $at, $a0\n"
1955      "ldc1 $f0, 0($at)\n"
1956      "ldc1 $f0, -256($a0)\n"
1957      "ldc1 $f0, -32768($a0)\n"
1958      "lui $at, 0xABCD\n"
1959      "ori $at, 0xEF00\n"
1960      "daddu $at, $at, $a0\n"
1961      "ldc1 $f0, 0($at)\n";
1962  DriverStr(expected, "LoadFpuFromOffset");
1963}
1964
1965TEST_F(AssemblerMIPS64Test, StoreToOffset) {
1966  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A0, 0);
1967  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0);
1968  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 1);
1969  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 256);
1970  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 1000);
1971  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x7FFF);
1972  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x8000);
1973  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x8001);
1974  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x10000);
1975  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x12345678);
1976  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, -256);
1977  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, -32768);
1978  __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0xABCDEF00);
1979
1980  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A0, 0);
1981  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0);
1982  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 2);
1983  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 256);
1984  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 1000);
1985  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x7FFE);
1986  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x8000);
1987  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x8002);
1988  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x10000);
1989  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x12345678);
1990  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, -256);
1991  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, -32768);
1992  __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0xABCDEF00);
1993
1994  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A0, 0);
1995  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0);
1996  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 4);
1997  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 256);
1998  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 1000);
1999  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x7FFC);
2000  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x8000);
2001  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x8004);
2002  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x10000);
2003  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x12345678);
2004  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, -256);
2005  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, -32768);
2006  __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0xABCDEF00);
2007
2008  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A0, 0);
2009  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0);
2010  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 4);
2011  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 256);
2012  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 1000);
2013  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x7FFC);
2014  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x8000);
2015  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x8004);
2016  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x10000);
2017  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x12345678);
2018  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, -256);
2019  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, -32768);
2020  __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0xABCDEF00);
2021
2022  const char* expected =
2023      "sb $a0, 0($a0)\n"
2024      "sb $a0, 0($a1)\n"
2025      "sb $a0, 1($a1)\n"
2026      "sb $a0, 256($a1)\n"
2027      "sb $a0, 1000($a1)\n"
2028      "sb $a0, 0x7FFF($a1)\n"
2029      "ori $at, $zero, 0x8000\n"
2030      "daddu $at, $at, $a1\n"
2031      "sb $a0, 0($at)\n"
2032      "ori $at, $zero, 0x8000\n"
2033      "daddu $at, $at, $a1\n"
2034      "sb $a0, 1($at)\n"
2035      "lui $at, 1\n"
2036      "daddu $at, $at, $a1\n"
2037      "sb $a0, 0($at)\n"
2038      "lui $at, 0x1234\n"
2039      "ori $at, 0x5678\n"
2040      "daddu $at, $at, $a1\n"
2041      "sb $a0, 0($at)\n"
2042      "sb $a0, -256($a1)\n"
2043      "sb $a0, -32768($a1)\n"
2044      "lui $at, 0xABCD\n"
2045      "ori $at, 0xEF00\n"
2046      "daddu $at, $at, $a1\n"
2047      "sb $a0, 0($at)\n"
2048
2049      "sh $a0, 0($a0)\n"
2050      "sh $a0, 0($a1)\n"
2051      "sh $a0, 2($a1)\n"
2052      "sh $a0, 256($a1)\n"
2053      "sh $a0, 1000($a1)\n"
2054      "sh $a0, 0x7FFE($a1)\n"
2055      "ori $at, $zero, 0x8000\n"
2056      "daddu $at, $at, $a1\n"
2057      "sh $a0, 0($at)\n"
2058      "ori $at, $zero, 0x8000\n"
2059      "daddu $at, $at, $a1\n"
2060      "sh $a0, 2($at)\n"
2061      "lui $at, 1\n"
2062      "daddu $at, $at, $a1\n"
2063      "sh $a0, 0($at)\n"
2064      "lui $at, 0x1234\n"
2065      "ori $at, 0x5678\n"
2066      "daddu $at, $at, $a1\n"
2067      "sh $a0, 0($at)\n"
2068      "sh $a0, -256($a1)\n"
2069      "sh $a0, -32768($a1)\n"
2070      "lui $at, 0xABCD\n"
2071      "ori $at, 0xEF00\n"
2072      "daddu $at, $at, $a1\n"
2073      "sh $a0, 0($at)\n"
2074
2075      "sw $a0, 0($a0)\n"
2076      "sw $a0, 0($a1)\n"
2077      "sw $a0, 4($a1)\n"
2078      "sw $a0, 256($a1)\n"
2079      "sw $a0, 1000($a1)\n"
2080      "sw $a0, 0x7FFC($a1)\n"
2081      "ori $at, $zero, 0x8000\n"
2082      "daddu $at, $at, $a1\n"
2083      "sw $a0, 0($at)\n"
2084      "ori $at, $zero, 0x8000\n"
2085      "daddu $at, $at, $a1\n"
2086      "sw $a0, 4($at)\n"
2087      "lui $at, 1\n"
2088      "daddu $at, $at, $a1\n"
2089      "sw $a0, 0($at)\n"
2090      "lui $at, 0x1234\n"
2091      "ori $at, 0x5678\n"
2092      "daddu $at, $at, $a1\n"
2093      "sw $a0, 0($at)\n"
2094      "sw $a0, -256($a1)\n"
2095      "sw $a0, -32768($a1)\n"
2096      "lui $at, 0xABCD\n"
2097      "ori $at, 0xEF00\n"
2098      "daddu $at, $at, $a1\n"
2099      "sw $a0, 0($at)\n"
2100
2101      "sd $a0, 0($a0)\n"
2102      "sd $a0, 0($a1)\n"
2103      "sw $a0, 4($a1)\n"
2104      "dsrl32 $t3, $a0, 0\n"
2105      "sw $t3, 8($a1)\n"
2106      "sd $a0, 256($a1)\n"
2107      "sd $a0, 1000($a1)\n"
2108      "ori $at, $zero, 0x7FF8\n"
2109      "daddu $at, $at, $a1\n"
2110      "sw $a0, 4($at)\n"
2111      "dsrl32 $t3, $a0, 0\n"
2112      "sw $t3, 8($at)\n"
2113      "ori $at, $zero, 0x8000\n"
2114      "daddu $at, $at, $a1\n"
2115      "sd $a0, 0($at)\n"
2116      "ori $at, $zero, 0x8000\n"
2117      "daddu $at, $at, $a1\n"
2118      "sw $a0, 4($at)\n"
2119      "dsrl32 $t3, $a0, 0\n"
2120      "sw $t3, 8($at)\n"
2121      "lui $at, 1\n"
2122      "daddu $at, $at, $a1\n"
2123      "sd $a0, 0($at)\n"
2124      "lui $at, 0x1234\n"
2125      "ori $at, 0x5678\n"
2126      "daddu $at, $at, $a1\n"
2127      "sd $a0, 0($at)\n"
2128      "sd $a0, -256($a1)\n"
2129      "sd $a0, -32768($a1)\n"
2130      "lui $at, 0xABCD\n"
2131      "ori $at, 0xEF00\n"
2132      "daddu $at, $at, $a1\n"
2133      "sd $a0, 0($at)\n";
2134  DriverStr(expected, "StoreToOffset");
2135}
2136
2137TEST_F(AssemblerMIPS64Test, StoreFpuToOffset) {
2138  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0);
2139  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 4);
2140  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 256);
2141  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x7FFC);
2142  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x8000);
2143  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x8004);
2144  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x10000);
2145  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x12345678);
2146  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, -256);
2147  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, -32768);
2148  __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0xABCDEF00);
2149
2150  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0);
2151  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 4);
2152  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 256);
2153  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x7FFC);
2154  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x8000);
2155  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x8004);
2156  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x10000);
2157  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x12345678);
2158  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, -256);
2159  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, -32768);
2160  __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0xABCDEF00);
2161
2162  const char* expected =
2163      "swc1 $f0, 0($a0)\n"
2164      "swc1 $f0, 4($a0)\n"
2165      "swc1 $f0, 256($a0)\n"
2166      "swc1 $f0, 0x7FFC($a0)\n"
2167      "ori $at, $zero, 0x8000\n"
2168      "daddu $at, $at, $a0\n"
2169      "swc1 $f0, 0($at)\n"
2170      "ori $at, $zero, 0x8000\n"
2171      "daddu $at, $at, $a0\n"
2172      "swc1 $f0, 4($at)\n"
2173      "lui $at, 1\n"
2174      "daddu $at, $at, $a0\n"
2175      "swc1 $f0, 0($at)\n"
2176      "lui $at, 0x1234\n"
2177      "ori $at, 0x5678\n"
2178      "daddu $at, $at, $a0\n"
2179      "swc1 $f0, 0($at)\n"
2180      "swc1 $f0, -256($a0)\n"
2181      "swc1 $f0, -32768($a0)\n"
2182      "lui $at, 0xABCD\n"
2183      "ori $at, 0xEF00\n"
2184      "daddu $at, $at, $a0\n"
2185      "swc1 $f0, 0($at)\n"
2186
2187      "sdc1 $f0, 0($a0)\n"
2188      "mfhc1 $t3, $f0\n"
2189      "swc1 $f0, 4($a0)\n"
2190      "sw $t3, 8($a0)\n"
2191      "sdc1 $f0, 256($a0)\n"
2192      "ori $at, $zero, 0x7FF8\n"
2193      "daddu $at, $at, $a0\n"
2194      "mfhc1 $t3, $f0\n"
2195      "swc1 $f0, 4($at)\n"
2196      "sw $t3, 8($at)\n"
2197      "ori $at, $zero, 0x8000\n"
2198      "daddu $at, $at, $a0\n"
2199      "sdc1 $f0, 0($at)\n"
2200      "ori $at, $zero, 0x8000\n"
2201      "daddu $at, $at, $a0\n"
2202      "mfhc1 $t3, $f0\n"
2203      "swc1 $f0, 4($at)\n"
2204      "sw $t3, 8($at)\n"
2205      "lui $at, 1\n"
2206      "daddu $at, $at, $a0\n"
2207      "sdc1 $f0, 0($at)\n"
2208      "lui $at, 0x1234\n"
2209      "ori $at, 0x5678\n"
2210      "daddu $at, $at, $a0\n"
2211      "sdc1 $f0, 0($at)\n"
2212      "sdc1 $f0, -256($a0)\n"
2213      "sdc1 $f0, -32768($a0)\n"
2214      "lui $at, 0xABCD\n"
2215      "ori $at, 0xEF00\n"
2216      "daddu $at, $at, $a0\n"
2217      "sdc1 $f0, 0($at)\n";
2218  DriverStr(expected, "StoreFpuToOffset");
2219}
2220
2221//////////////////////////////
2222// Loading/adding Constants //
2223//////////////////////////////
2224
2225TEST_F(AssemblerMIPS64Test, LoadConst32) {
2226  // IsUint<16>(value)
2227  __ LoadConst32(mips64::V0, 0);
2228  __ LoadConst32(mips64::V0, 65535);
2229  // IsInt<16>(value)
2230  __ LoadConst32(mips64::V0, -1);
2231  __ LoadConst32(mips64::V0, -32768);
2232  // Everything else
2233  __ LoadConst32(mips64::V0, 65536);
2234  __ LoadConst32(mips64::V0, 65537);
2235  __ LoadConst32(mips64::V0, 2147483647);
2236  __ LoadConst32(mips64::V0, -32769);
2237  __ LoadConst32(mips64::V0, -65536);
2238  __ LoadConst32(mips64::V0, -65537);
2239  __ LoadConst32(mips64::V0, -2147483647);
2240  __ LoadConst32(mips64::V0, -2147483648);
2241
2242  const char* expected =
2243      // IsUint<16>(value)
2244      "ori $v0, $zero, 0\n"         // __ LoadConst32(mips64::V0, 0);
2245      "ori $v0, $zero, 65535\n"     // __ LoadConst32(mips64::V0, 65535);
2246      // IsInt<16>(value)
2247      "addiu $v0, $zero, -1\n"      // __ LoadConst32(mips64::V0, -1);
2248      "addiu $v0, $zero, -32768\n"  // __ LoadConst32(mips64::V0, -32768);
2249      // Everything else
2250      "lui $v0, 1\n"                // __ LoadConst32(mips64::V0, 65536);
2251      "lui $v0, 1\n"                // __ LoadConst32(mips64::V0, 65537);
2252      "ori $v0, 1\n"                //                 "
2253      "lui $v0, 32767\n"            // __ LoadConst32(mips64::V0, 2147483647);
2254      "ori $v0, 65535\n"            //                 "
2255      "lui $v0, 65535\n"            // __ LoadConst32(mips64::V0, -32769);
2256      "ori $v0, 32767\n"            //                 "
2257      "lui $v0, 65535\n"            // __ LoadConst32(mips64::V0, -65536);
2258      "lui $v0, 65534\n"            // __ LoadConst32(mips64::V0, -65537);
2259      "ori $v0, 65535\n"            //                 "
2260      "lui $v0, 32768\n"            // __ LoadConst32(mips64::V0, -2147483647);
2261      "ori $v0, 1\n"                //                 "
2262      "lui $v0, 32768\n";           // __ LoadConst32(mips64::V0, -2147483648);
2263  DriverStr(expected, "LoadConst32");
2264}
2265
2266TEST_F(AssemblerMIPS64Test, Addiu32) {
2267  __ Addiu32(mips64::A1, mips64::A2, -0x8000);
2268  __ Addiu32(mips64::A1, mips64::A2, +0);
2269  __ Addiu32(mips64::A1, mips64::A2, +0x7FFF);
2270  __ Addiu32(mips64::A1, mips64::A2, -0x8001);
2271  __ Addiu32(mips64::A1, mips64::A2, +0x8000);
2272  __ Addiu32(mips64::A1, mips64::A2, -0x10000);
2273  __ Addiu32(mips64::A1, mips64::A2, +0x10000);
2274  __ Addiu32(mips64::A1, mips64::A2, +0x12345678);
2275
2276  const char* expected =
2277      "addiu $a1, $a2, -0x8000\n"
2278      "addiu $a1, $a2, 0\n"
2279      "addiu $a1, $a2, 0x7FFF\n"
2280      "aui $a1, $a2, 0xFFFF\n"
2281      "addiu $a1, $a1, 0x7FFF\n"
2282      "aui $a1, $a2, 1\n"
2283      "addiu $a1, $a1, -0x8000\n"
2284      "aui $a1, $a2, 0xFFFF\n"
2285      "aui $a1, $a2, 1\n"
2286      "aui $a1, $a2, 0x1234\n"
2287      "addiu $a1, $a1, 0x5678\n";
2288  DriverStr(expected, "Addiu32");
2289}
2290
2291static uint64_t SignExtend16To64(uint16_t n) {
2292  return static_cast<int16_t>(n);
2293}
2294
2295// The art::mips64::Mips64Assembler::LoadConst64() method uses a template
2296// to minimize the number of instructions needed to load a 64-bit constant
2297// value into a register. The template calls various methods which emit
2298// MIPS machine instructions. This struct (class) uses the same template
2299// but overrides the definitions of the methods which emit MIPS instructions
2300// to use methods which simulate the operation of the corresponding MIPS
2301// instructions. After invoking LoadConst64() the target register should
2302// contain the same 64-bit value as was input to LoadConst64(). If the
2303// simulated register doesn't contain the correct value then there is probably
2304// an error in the template function.
2305struct LoadConst64Tester {
2306  LoadConst64Tester() {
2307    // Initialize all of the registers for simulation to zero.
2308    for (int r = 0; r < 32; r++) {
2309      regs_[r] = 0;
2310    }
2311    // Clear all of the path flags.
2312    loadconst64_paths_ = art::mips64::kLoadConst64PathZero;
2313  }
2314  void Addiu(mips64::GpuRegister rd, mips64::GpuRegister rs, uint16_t c) {
2315    regs_[rd] = static_cast<int32_t>(regs_[rs] + SignExtend16To64(c));
2316  }
2317  void Daddiu(mips64::GpuRegister rd, mips64::GpuRegister rs, uint16_t c) {
2318    regs_[rd] = regs_[rs] + SignExtend16To64(c);
2319  }
2320  void Dahi(mips64::GpuRegister rd, uint16_t c) {
2321    regs_[rd] += SignExtend16To64(c) << 32;
2322  }
2323  void Dati(mips64::GpuRegister rd, uint16_t c) {
2324    regs_[rd] += SignExtend16To64(c) << 48;
2325  }
2326  void Dinsu(mips64::GpuRegister rt, mips64::GpuRegister rs, int pos, int size) {
2327    CHECK(IsUint<5>(pos - 32)) << pos;
2328    CHECK(IsUint<5>(size - 1)) << size;
2329    CHECK(IsUint<5>(pos + size - 33)) << pos << " + " << size;
2330    uint64_t src_mask = (UINT64_C(1) << size) - 1;
2331    uint64_t dsk_mask = ~(src_mask << pos);
2332
2333    regs_[rt] = (regs_[rt] & dsk_mask) | ((regs_[rs] & src_mask) << pos);
2334  }
2335  void Dsll(mips64::GpuRegister rd, mips64::GpuRegister rt, int shamt) {
2336    regs_[rd] = regs_[rt] << (shamt & 0x1f);
2337  }
2338  void Dsll32(mips64::GpuRegister rd, mips64::GpuRegister rt, int shamt) {
2339    regs_[rd] = regs_[rt] << (32 + (shamt & 0x1f));
2340  }
2341  void Dsrl(mips64::GpuRegister rd, mips64::GpuRegister rt, int shamt) {
2342    regs_[rd] = regs_[rt] >> (shamt & 0x1f);
2343  }
2344  void Dsrl32(mips64::GpuRegister rd, mips64::GpuRegister rt, int shamt) {
2345    regs_[rd] = regs_[rt] >> (32 + (shamt & 0x1f));
2346  }
2347  void Lui(mips64::GpuRegister rd, uint16_t c) {
2348    regs_[rd] = SignExtend16To64(c) << 16;
2349  }
2350  void Ori(mips64::GpuRegister rd, mips64::GpuRegister rs, uint16_t c) {
2351    regs_[rd] = regs_[rs] | c;
2352  }
2353  void LoadConst32(mips64::GpuRegister rd, int32_t c) {
2354    CHECK_NE(rd, 0);
2355    mips64::TemplateLoadConst32<LoadConst64Tester>(this, rd, c);
2356    CHECK_EQ(regs_[rd], static_cast<uint64_t>(c));
2357  }
2358  void LoadConst64(mips64::GpuRegister rd, int64_t c) {
2359    CHECK_NE(rd, 0);
2360    mips64::TemplateLoadConst64<LoadConst64Tester>(this, rd, c);
2361    CHECK_EQ(regs_[rd], static_cast<uint64_t>(c));
2362  }
2363  uint64_t regs_[32];
2364
2365  // Getter function for loadconst64_paths_.
2366  int GetPathsCovered() {
2367    return loadconst64_paths_;
2368  }
2369
2370  void RecordLoadConst64Path(int value) {
2371    loadconst64_paths_ |= value;
2372  }
2373
2374 private:
2375  // This variable holds a bitmask to tell us which paths were taken
2376  // through the template function which loads 64-bit values.
2377  int loadconst64_paths_;
2378};
2379
2380TEST_F(AssemblerMIPS64Test, LoadConst64) {
2381  const uint16_t imms[] = {
2382      0, 1, 2, 3, 4, 0x33, 0x66, 0x55, 0x99, 0xaa, 0xcc, 0xff, 0x5500, 0x5555,
2383      0x7ffc, 0x7ffd, 0x7ffe, 0x7fff, 0x8000, 0x8001, 0x8002, 0x8003, 0x8004,
2384      0xaaaa, 0xfffc, 0xfffd, 0xfffe, 0xffff
2385  };
2386  unsigned d0, d1, d2, d3;
2387  LoadConst64Tester tester;
2388
2389  union {
2390    int64_t v64;
2391    uint16_t v16[4];
2392  } u;
2393
2394  for (d3 = 0; d3 < sizeof imms / sizeof imms[0]; d3++) {
2395    u.v16[3] = imms[d3];
2396
2397    for (d2 = 0; d2 < sizeof imms / sizeof imms[0]; d2++) {
2398      u.v16[2] = imms[d2];
2399
2400      for (d1 = 0; d1 < sizeof imms / sizeof imms[0]; d1++) {
2401        u.v16[1] = imms[d1];
2402
2403        for (d0 = 0; d0 < sizeof imms / sizeof imms[0]; d0++) {
2404          u.v16[0] = imms[d0];
2405
2406          tester.LoadConst64(mips64::V0, u.v64);
2407        }
2408      }
2409    }
2410  }
2411
2412  // Verify that we tested all paths through the "load 64-bit value"
2413  // function template.
2414  EXPECT_EQ(tester.GetPathsCovered(), art::mips64::kLoadConst64PathAllPaths);
2415}
2416
2417// MSA instructions.
2418
2419TEST_F(AssemblerMIPS64Test, AndV) {
2420  DriverStr(RepeatVVV(&mips64::Mips64Assembler::AndV, "and.v ${reg1}, ${reg2}, ${reg3}"), "and.v");
2421}
2422
2423TEST_F(AssemblerMIPS64Test, OrV) {
2424  DriverStr(RepeatVVV(&mips64::Mips64Assembler::OrV, "or.v ${reg1}, ${reg2}, ${reg3}"), "or.v");
2425}
2426
2427TEST_F(AssemblerMIPS64Test, NorV) {
2428  DriverStr(RepeatVVV(&mips64::Mips64Assembler::NorV, "nor.v ${reg1}, ${reg2}, ${reg3}"), "nor.v");
2429}
2430
2431TEST_F(AssemblerMIPS64Test, XorV) {
2432  DriverStr(RepeatVVV(&mips64::Mips64Assembler::XorV, "xor.v ${reg1}, ${reg2}, ${reg3}"), "xor.v");
2433}
2434
2435TEST_F(AssemblerMIPS64Test, AddvB) {
2436  DriverStr(RepeatVVV(&mips64::Mips64Assembler::AddvB, "addv.b ${reg1}, ${reg2}, ${reg3}"),
2437            "addv.b");
2438}
2439
2440TEST_F(AssemblerMIPS64Test, AddvH) {
2441  DriverStr(RepeatVVV(&mips64::Mips64Assembler::AddvH, "addv.h ${reg1}, ${reg2}, ${reg3}"),
2442            "addv.h");
2443}
2444
2445TEST_F(AssemblerMIPS64Test, AddvW) {
2446  DriverStr(RepeatVVV(&mips64::Mips64Assembler::AddvW, "addv.w ${reg1}, ${reg2}, ${reg3}"),
2447            "addv.w");
2448}
2449
2450TEST_F(AssemblerMIPS64Test, AddvD) {
2451  DriverStr(RepeatVVV(&mips64::Mips64Assembler::AddvD, "addv.d ${reg1}, ${reg2}, ${reg3}"),
2452            "addv.d");
2453}
2454
2455TEST_F(AssemblerMIPS64Test, SubvB) {
2456  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SubvB, "subv.b ${reg1}, ${reg2}, ${reg3}"),
2457            "subv.b");
2458}
2459
2460TEST_F(AssemblerMIPS64Test, SubvH) {
2461  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SubvH, "subv.h ${reg1}, ${reg2}, ${reg3}"),
2462            "subv.h");
2463}
2464
2465TEST_F(AssemblerMIPS64Test, SubvW) {
2466  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SubvW, "subv.w ${reg1}, ${reg2}, ${reg3}"),
2467            "subv.w");
2468}
2469
2470TEST_F(AssemblerMIPS64Test, SubvD) {
2471  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SubvD, "subv.d ${reg1}, ${reg2}, ${reg3}"),
2472            "subv.d");
2473}
2474
2475TEST_F(AssemblerMIPS64Test, MulvB) {
2476  DriverStr(RepeatVVV(&mips64::Mips64Assembler::MulvB, "mulv.b ${reg1}, ${reg2}, ${reg3}"),
2477            "mulv.b");
2478}
2479
2480TEST_F(AssemblerMIPS64Test, MulvH) {
2481  DriverStr(RepeatVVV(&mips64::Mips64Assembler::MulvH, "mulv.h ${reg1}, ${reg2}, ${reg3}"),
2482            "mulv.h");
2483}
2484
2485TEST_F(AssemblerMIPS64Test, MulvW) {
2486  DriverStr(RepeatVVV(&mips64::Mips64Assembler::MulvW, "mulv.w ${reg1}, ${reg2}, ${reg3}"),
2487            "mulv.w");
2488}
2489
2490TEST_F(AssemblerMIPS64Test, MulvD) {
2491  DriverStr(RepeatVVV(&mips64::Mips64Assembler::MulvD, "mulv.d ${reg1}, ${reg2}, ${reg3}"),
2492            "mulv.d");
2493}
2494
2495TEST_F(AssemblerMIPS64Test, Div_sB) {
2496  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Div_sB, "div_s.b ${reg1}, ${reg2}, ${reg3}"),
2497            "div_s.b");
2498}
2499
2500TEST_F(AssemblerMIPS64Test, Div_sH) {
2501  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Div_sH, "div_s.h ${reg1}, ${reg2}, ${reg3}"),
2502            "div_s.h");
2503}
2504
2505TEST_F(AssemblerMIPS64Test, Div_sW) {
2506  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Div_sW, "div_s.w ${reg1}, ${reg2}, ${reg3}"),
2507            "div_s.w");
2508}
2509
2510TEST_F(AssemblerMIPS64Test, Div_sD) {
2511  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Div_sD, "div_s.d ${reg1}, ${reg2}, ${reg3}"),
2512            "div_s.d");
2513}
2514
2515TEST_F(AssemblerMIPS64Test, Div_uB) {
2516  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Div_uB, "div_u.b ${reg1}, ${reg2}, ${reg3}"),
2517            "div_u.b");
2518}
2519
2520TEST_F(AssemblerMIPS64Test, Div_uH) {
2521  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Div_uH, "div_u.h ${reg1}, ${reg2}, ${reg3}"),
2522            "div_u.h");
2523}
2524
2525TEST_F(AssemblerMIPS64Test, Div_uW) {
2526  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Div_uW, "div_u.w ${reg1}, ${reg2}, ${reg3}"),
2527            "div_u.w");
2528}
2529
2530TEST_F(AssemblerMIPS64Test, Div_uD) {
2531  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Div_uD, "div_u.d ${reg1}, ${reg2}, ${reg3}"),
2532            "div_u.d");
2533}
2534
2535TEST_F(AssemblerMIPS64Test, Mod_sB) {
2536  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Mod_sB, "mod_s.b ${reg1}, ${reg2}, ${reg3}"),
2537            "mod_s.b");
2538}
2539
2540TEST_F(AssemblerMIPS64Test, Mod_sH) {
2541  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Mod_sH, "mod_s.h ${reg1}, ${reg2}, ${reg3}"),
2542            "mod_s.h");
2543}
2544
2545TEST_F(AssemblerMIPS64Test, Mod_sW) {
2546  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Mod_sW, "mod_s.w ${reg1}, ${reg2}, ${reg3}"),
2547            "mod_s.w");
2548}
2549
2550TEST_F(AssemblerMIPS64Test, Mod_sD) {
2551  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Mod_sD, "mod_s.d ${reg1}, ${reg2}, ${reg3}"),
2552            "mod_s.d");
2553}
2554
2555TEST_F(AssemblerMIPS64Test, Mod_uB) {
2556  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Mod_uB, "mod_u.b ${reg1}, ${reg2}, ${reg3}"),
2557            "mod_u.b");
2558}
2559
2560TEST_F(AssemblerMIPS64Test, Mod_uH) {
2561  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Mod_uH, "mod_u.h ${reg1}, ${reg2}, ${reg3}"),
2562            "mod_u.h");
2563}
2564
2565TEST_F(AssemblerMIPS64Test, Mod_uW) {
2566  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Mod_uW, "mod_u.w ${reg1}, ${reg2}, ${reg3}"),
2567            "mod_u.w");
2568}
2569
2570TEST_F(AssemblerMIPS64Test, Mod_uD) {
2571  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Mod_uD, "mod_u.d ${reg1}, ${reg2}, ${reg3}"),
2572            "mod_u.d");
2573}
2574
2575TEST_F(AssemblerMIPS64Test, FaddW) {
2576  DriverStr(RepeatVVV(&mips64::Mips64Assembler::FaddW, "fadd.w ${reg1}, ${reg2}, ${reg3}"),
2577            "fadd.w");
2578}
2579
2580TEST_F(AssemblerMIPS64Test, FaddD) {
2581  DriverStr(RepeatVVV(&mips64::Mips64Assembler::FaddD, "fadd.d ${reg1}, ${reg2}, ${reg3}"),
2582            "fadd.d");
2583}
2584
2585TEST_F(AssemblerMIPS64Test, FsubW) {
2586  DriverStr(RepeatVVV(&mips64::Mips64Assembler::FsubW, "fsub.w ${reg1}, ${reg2}, ${reg3}"),
2587            "fsub.w");
2588}
2589
2590TEST_F(AssemblerMIPS64Test, FsubD) {
2591  DriverStr(RepeatVVV(&mips64::Mips64Assembler::FsubD, "fsub.d ${reg1}, ${reg2}, ${reg3}"),
2592            "fsub.d");
2593}
2594
2595TEST_F(AssemblerMIPS64Test, FmulW) {
2596  DriverStr(RepeatVVV(&mips64::Mips64Assembler::FmulW, "fmul.w ${reg1}, ${reg2}, ${reg3}"),
2597            "fmul.w");
2598}
2599
2600TEST_F(AssemblerMIPS64Test, FmulD) {
2601  DriverStr(RepeatVVV(&mips64::Mips64Assembler::FmulD, "fmul.d ${reg1}, ${reg2}, ${reg3}"),
2602            "fmul.d");
2603}
2604
2605TEST_F(AssemblerMIPS64Test, FdivW) {
2606  DriverStr(RepeatVVV(&mips64::Mips64Assembler::FdivW, "fdiv.w ${reg1}, ${reg2}, ${reg3}"),
2607            "fdiv.w");
2608}
2609
2610TEST_F(AssemblerMIPS64Test, FdivD) {
2611  DriverStr(RepeatVVV(&mips64::Mips64Assembler::FdivD, "fdiv.d ${reg1}, ${reg2}, ${reg3}"),
2612            "fdiv.d");
2613}
2614
2615TEST_F(AssemblerMIPS64Test, Ffint_sW) {
2616  DriverStr(RepeatVV(&mips64::Mips64Assembler::Ffint_sW, "ffint_s.w ${reg1}, ${reg2}"),
2617            "ffint_s.w");
2618}
2619
2620TEST_F(AssemblerMIPS64Test, Ffint_sD) {
2621  DriverStr(RepeatVV(&mips64::Mips64Assembler::Ffint_sD, "ffint_s.d ${reg1}, ${reg2}"),
2622            "ffint_s.d");
2623}
2624
2625TEST_F(AssemblerMIPS64Test, Ftint_sW) {
2626  DriverStr(RepeatVV(&mips64::Mips64Assembler::Ftint_sW, "ftint_s.w ${reg1}, ${reg2}"),
2627            "ftint_s.w");
2628}
2629
2630TEST_F(AssemblerMIPS64Test, Ftint_sD) {
2631  DriverStr(RepeatVV(&mips64::Mips64Assembler::Ftint_sD, "ftint_s.d ${reg1}, ${reg2}"),
2632            "ftint_s.d");
2633}
2634
2635TEST_F(AssemblerMIPS64Test, SllB) {
2636  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SllB, "sll.b ${reg1}, ${reg2}, ${reg3}"), "sll.b");
2637}
2638
2639TEST_F(AssemblerMIPS64Test, SllH) {
2640  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SllH, "sll.h ${reg1}, ${reg2}, ${reg3}"), "sll.h");
2641}
2642
2643TEST_F(AssemblerMIPS64Test, SllW) {
2644  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SllW, "sll.w ${reg1}, ${reg2}, ${reg3}"), "sll.w");
2645}
2646
2647TEST_F(AssemblerMIPS64Test, SllD) {
2648  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SllD, "sll.d ${reg1}, ${reg2}, ${reg3}"), "sll.d");
2649}
2650
2651TEST_F(AssemblerMIPS64Test, SraB) {
2652  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SraB, "sra.b ${reg1}, ${reg2}, ${reg3}"), "sra.b");
2653}
2654
2655TEST_F(AssemblerMIPS64Test, SraH) {
2656  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SraH, "sra.h ${reg1}, ${reg2}, ${reg3}"), "sra.h");
2657}
2658
2659TEST_F(AssemblerMIPS64Test, SraW) {
2660  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SraW, "sra.w ${reg1}, ${reg2}, ${reg3}"), "sra.w");
2661}
2662
2663TEST_F(AssemblerMIPS64Test, SraD) {
2664  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SraD, "sra.d ${reg1}, ${reg2}, ${reg3}"), "sra.d");
2665}
2666
2667TEST_F(AssemblerMIPS64Test, SrlB) {
2668  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SrlB, "srl.b ${reg1}, ${reg2}, ${reg3}"), "srl.b");
2669}
2670
2671TEST_F(AssemblerMIPS64Test, SrlH) {
2672  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SrlH, "srl.h ${reg1}, ${reg2}, ${reg3}"), "srl.h");
2673}
2674
2675TEST_F(AssemblerMIPS64Test, SrlW) {
2676  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SrlW, "srl.w ${reg1}, ${reg2}, ${reg3}"), "srl.w");
2677}
2678
2679TEST_F(AssemblerMIPS64Test, SrlD) {
2680  DriverStr(RepeatVVV(&mips64::Mips64Assembler::SrlD, "srl.d ${reg1}, ${reg2}, ${reg3}"), "srl.d");
2681}
2682
2683TEST_F(AssemblerMIPS64Test, SlliB) {
2684  DriverStr(RepeatVVIb(&mips64::Mips64Assembler::SlliB, 3, "slli.b ${reg1}, ${reg2}, {imm}"),
2685            "slli.b");
2686}
2687
2688TEST_F(AssemblerMIPS64Test, SlliH) {
2689  DriverStr(RepeatVVIb(&mips64::Mips64Assembler::SlliH, 4, "slli.h ${reg1}, ${reg2}, {imm}"),
2690            "slli.h");
2691}
2692
2693TEST_F(AssemblerMIPS64Test, SlliW) {
2694  DriverStr(RepeatVVIb(&mips64::Mips64Assembler::SlliW, 5, "slli.w ${reg1}, ${reg2}, {imm}"),
2695            "slli.w");
2696}
2697
2698TEST_F(AssemblerMIPS64Test, SlliD) {
2699  DriverStr(RepeatVVIb(&mips64::Mips64Assembler::SlliD, 6, "slli.d ${reg1}, ${reg2}, {imm}"),
2700            "slli.d");
2701}
2702
2703TEST_F(AssemblerMIPS64Test, MoveV) {
2704  DriverStr(RepeatVV(&mips64::Mips64Assembler::MoveV, "move.v ${reg1}, ${reg2}"), "move.v");
2705}
2706
2707TEST_F(AssemblerMIPS64Test, SplatiB) {
2708  DriverStr(RepeatVVIb(&mips64::Mips64Assembler::SplatiB, 4, "splati.b ${reg1}, ${reg2}[{imm}]"),
2709            "splati.b");
2710}
2711
2712TEST_F(AssemblerMIPS64Test, SplatiH) {
2713  DriverStr(RepeatVVIb(&mips64::Mips64Assembler::SplatiH, 3, "splati.h ${reg1}, ${reg2}[{imm}]"),
2714            "splati.h");
2715}
2716
2717TEST_F(AssemblerMIPS64Test, SplatiW) {
2718  DriverStr(RepeatVVIb(&mips64::Mips64Assembler::SplatiW, 2, "splati.w ${reg1}, ${reg2}[{imm}]"),
2719            "splati.w");
2720}
2721
2722TEST_F(AssemblerMIPS64Test, SplatiD) {
2723  DriverStr(RepeatVVIb(&mips64::Mips64Assembler::SplatiD, 1, "splati.d ${reg1}, ${reg2}[{imm}]"),
2724            "splati.d");
2725}
2726
2727TEST_F(AssemblerMIPS64Test, FillB) {
2728  DriverStr(RepeatVR(&mips64::Mips64Assembler::FillB, "fill.b ${reg1}, ${reg2}"), "fill.b");
2729}
2730
2731TEST_F(AssemblerMIPS64Test, FillH) {
2732  DriverStr(RepeatVR(&mips64::Mips64Assembler::FillH, "fill.h ${reg1}, ${reg2}"), "fill.h");
2733}
2734
2735TEST_F(AssemblerMIPS64Test, FillW) {
2736  DriverStr(RepeatVR(&mips64::Mips64Assembler::FillW, "fill.w ${reg1}, ${reg2}"), "fill.w");
2737}
2738
2739TEST_F(AssemblerMIPS64Test, FillD) {
2740  DriverStr(RepeatVR(&mips64::Mips64Assembler::FillD, "fill.d ${reg1}, ${reg2}"), "fill.d");
2741}
2742
2743TEST_F(AssemblerMIPS64Test, LdB) {
2744  DriverStr(RepeatVRIb(&mips64::Mips64Assembler::LdB, -10, "ld.b ${reg1}, {imm}(${reg2})"), "ld.b");
2745}
2746
2747TEST_F(AssemblerMIPS64Test, LdH) {
2748  DriverStr(RepeatVRIb(&mips64::Mips64Assembler::LdH, -10, "ld.h ${reg1}, {imm}(${reg2})", 0, 2),
2749            "ld.h");
2750}
2751
2752TEST_F(AssemblerMIPS64Test, LdW) {
2753  DriverStr(RepeatVRIb(&mips64::Mips64Assembler::LdW, -10, "ld.w ${reg1}, {imm}(${reg2})", 0, 4),
2754            "ld.w");
2755}
2756
2757TEST_F(AssemblerMIPS64Test, LdD) {
2758  DriverStr(RepeatVRIb(&mips64::Mips64Assembler::LdD, -10, "ld.d ${reg1}, {imm}(${reg2})", 0, 8),
2759            "ld.d");
2760}
2761
2762TEST_F(AssemblerMIPS64Test, StB) {
2763  DriverStr(RepeatVRIb(&mips64::Mips64Assembler::StB, -10, "st.b ${reg1}, {imm}(${reg2})"), "st.b");
2764}
2765
2766TEST_F(AssemblerMIPS64Test, StH) {
2767  DriverStr(RepeatVRIb(&mips64::Mips64Assembler::StH, -10, "st.h ${reg1}, {imm}(${reg2})", 0, 2),
2768            "st.h");
2769}
2770
2771TEST_F(AssemblerMIPS64Test, StW) {
2772  DriverStr(RepeatVRIb(&mips64::Mips64Assembler::StW, -10, "st.w ${reg1}, {imm}(${reg2})", 0, 4),
2773            "st.w");
2774}
2775
2776TEST_F(AssemblerMIPS64Test, StD) {
2777  DriverStr(RepeatVRIb(&mips64::Mips64Assembler::StD, -10, "st.d ${reg1}, {imm}(${reg2})", 0, 8),
2778            "st.d");
2779}
2780
2781#undef __
2782
2783}  // namespace art
2784