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