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_mips.h"
18
19#include <map>
20
21#include "base/stl_util.h"
22#include "utils/assembler_test.h"
23
24#define __ GetAssembler()->
25
26namespace art {
27
28struct MIPSCpuRegisterCompare {
29  bool operator()(const mips::Register& a, const mips::Register& b) const {
30    return a < b;
31  }
32};
33
34class AssemblerMIPSTest : public AssemblerTest<mips::MipsAssembler,
35                                               mips::Register,
36                                               mips::FRegister,
37                                               uint32_t> {
38 public:
39  typedef AssemblerTest<mips::MipsAssembler, mips::Register, mips::FRegister, uint32_t> Base;
40
41 protected:
42  // Get the typically used name for this architecture, e.g., aarch64, x86-64, ...
43  std::string GetArchitectureString() OVERRIDE {
44    return "mips";
45  }
46
47  std::string GetAssemblerParameters() OVERRIDE {
48    return " --no-warn -32 -march=mips32r2";
49  }
50
51  std::string GetDisassembleParameters() OVERRIDE {
52    return " -D -bbinary -mmips:isa32r2";
53  }
54
55  void SetUpHelpers() OVERRIDE {
56    if (registers_.size() == 0) {
57      registers_.push_back(new mips::Register(mips::ZERO));
58      registers_.push_back(new mips::Register(mips::AT));
59      registers_.push_back(new mips::Register(mips::V0));
60      registers_.push_back(new mips::Register(mips::V1));
61      registers_.push_back(new mips::Register(mips::A0));
62      registers_.push_back(new mips::Register(mips::A1));
63      registers_.push_back(new mips::Register(mips::A2));
64      registers_.push_back(new mips::Register(mips::A3));
65      registers_.push_back(new mips::Register(mips::T0));
66      registers_.push_back(new mips::Register(mips::T1));
67      registers_.push_back(new mips::Register(mips::T2));
68      registers_.push_back(new mips::Register(mips::T3));
69      registers_.push_back(new mips::Register(mips::T4));
70      registers_.push_back(new mips::Register(mips::T5));
71      registers_.push_back(new mips::Register(mips::T6));
72      registers_.push_back(new mips::Register(mips::T7));
73      registers_.push_back(new mips::Register(mips::S0));
74      registers_.push_back(new mips::Register(mips::S1));
75      registers_.push_back(new mips::Register(mips::S2));
76      registers_.push_back(new mips::Register(mips::S3));
77      registers_.push_back(new mips::Register(mips::S4));
78      registers_.push_back(new mips::Register(mips::S5));
79      registers_.push_back(new mips::Register(mips::S6));
80      registers_.push_back(new mips::Register(mips::S7));
81      registers_.push_back(new mips::Register(mips::T8));
82      registers_.push_back(new mips::Register(mips::T9));
83      registers_.push_back(new mips::Register(mips::K0));
84      registers_.push_back(new mips::Register(mips::K1));
85      registers_.push_back(new mips::Register(mips::GP));
86      registers_.push_back(new mips::Register(mips::SP));
87      registers_.push_back(new mips::Register(mips::FP));
88      registers_.push_back(new mips::Register(mips::RA));
89
90      secondary_register_names_.emplace(mips::Register(mips::ZERO), "zero");
91      secondary_register_names_.emplace(mips::Register(mips::AT), "at");
92      secondary_register_names_.emplace(mips::Register(mips::V0), "v0");
93      secondary_register_names_.emplace(mips::Register(mips::V1), "v1");
94      secondary_register_names_.emplace(mips::Register(mips::A0), "a0");
95      secondary_register_names_.emplace(mips::Register(mips::A1), "a1");
96      secondary_register_names_.emplace(mips::Register(mips::A2), "a2");
97      secondary_register_names_.emplace(mips::Register(mips::A3), "a3");
98      secondary_register_names_.emplace(mips::Register(mips::T0), "t0");
99      secondary_register_names_.emplace(mips::Register(mips::T1), "t1");
100      secondary_register_names_.emplace(mips::Register(mips::T2), "t2");
101      secondary_register_names_.emplace(mips::Register(mips::T3), "t3");
102      secondary_register_names_.emplace(mips::Register(mips::T4), "t4");
103      secondary_register_names_.emplace(mips::Register(mips::T5), "t5");
104      secondary_register_names_.emplace(mips::Register(mips::T6), "t6");
105      secondary_register_names_.emplace(mips::Register(mips::T7), "t7");
106      secondary_register_names_.emplace(mips::Register(mips::S0), "s0");
107      secondary_register_names_.emplace(mips::Register(mips::S1), "s1");
108      secondary_register_names_.emplace(mips::Register(mips::S2), "s2");
109      secondary_register_names_.emplace(mips::Register(mips::S3), "s3");
110      secondary_register_names_.emplace(mips::Register(mips::S4), "s4");
111      secondary_register_names_.emplace(mips::Register(mips::S5), "s5");
112      secondary_register_names_.emplace(mips::Register(mips::S6), "s6");
113      secondary_register_names_.emplace(mips::Register(mips::S7), "s7");
114      secondary_register_names_.emplace(mips::Register(mips::T8), "t8");
115      secondary_register_names_.emplace(mips::Register(mips::T9), "t9");
116      secondary_register_names_.emplace(mips::Register(mips::K0), "k0");
117      secondary_register_names_.emplace(mips::Register(mips::K1), "k1");
118      secondary_register_names_.emplace(mips::Register(mips::GP), "gp");
119      secondary_register_names_.emplace(mips::Register(mips::SP), "sp");
120      secondary_register_names_.emplace(mips::Register(mips::FP), "fp");
121      secondary_register_names_.emplace(mips::Register(mips::RA), "ra");
122
123      fp_registers_.push_back(new mips::FRegister(mips::F0));
124      fp_registers_.push_back(new mips::FRegister(mips::F1));
125      fp_registers_.push_back(new mips::FRegister(mips::F2));
126      fp_registers_.push_back(new mips::FRegister(mips::F3));
127      fp_registers_.push_back(new mips::FRegister(mips::F4));
128      fp_registers_.push_back(new mips::FRegister(mips::F5));
129      fp_registers_.push_back(new mips::FRegister(mips::F6));
130      fp_registers_.push_back(new mips::FRegister(mips::F7));
131      fp_registers_.push_back(new mips::FRegister(mips::F8));
132      fp_registers_.push_back(new mips::FRegister(mips::F9));
133      fp_registers_.push_back(new mips::FRegister(mips::F10));
134      fp_registers_.push_back(new mips::FRegister(mips::F11));
135      fp_registers_.push_back(new mips::FRegister(mips::F12));
136      fp_registers_.push_back(new mips::FRegister(mips::F13));
137      fp_registers_.push_back(new mips::FRegister(mips::F14));
138      fp_registers_.push_back(new mips::FRegister(mips::F15));
139      fp_registers_.push_back(new mips::FRegister(mips::F16));
140      fp_registers_.push_back(new mips::FRegister(mips::F17));
141      fp_registers_.push_back(new mips::FRegister(mips::F18));
142      fp_registers_.push_back(new mips::FRegister(mips::F19));
143      fp_registers_.push_back(new mips::FRegister(mips::F20));
144      fp_registers_.push_back(new mips::FRegister(mips::F21));
145      fp_registers_.push_back(new mips::FRegister(mips::F22));
146      fp_registers_.push_back(new mips::FRegister(mips::F23));
147      fp_registers_.push_back(new mips::FRegister(mips::F24));
148      fp_registers_.push_back(new mips::FRegister(mips::F25));
149      fp_registers_.push_back(new mips::FRegister(mips::F26));
150      fp_registers_.push_back(new mips::FRegister(mips::F27));
151      fp_registers_.push_back(new mips::FRegister(mips::F28));
152      fp_registers_.push_back(new mips::FRegister(mips::F29));
153      fp_registers_.push_back(new mips::FRegister(mips::F30));
154      fp_registers_.push_back(new mips::FRegister(mips::F31));
155    }
156  }
157
158  void TearDown() OVERRIDE {
159    AssemblerTest::TearDown();
160    STLDeleteElements(&registers_);
161    STLDeleteElements(&fp_registers_);
162  }
163
164  std::vector<mips::Register*> GetRegisters() OVERRIDE {
165    return registers_;
166  }
167
168  std::vector<mips::FRegister*> GetFPRegisters() OVERRIDE {
169    return fp_registers_;
170  }
171
172  uint32_t CreateImmediate(int64_t imm_value) OVERRIDE {
173    return imm_value;
174  }
175
176  std::string GetSecondaryRegisterName(const mips::Register& reg) OVERRIDE {
177    CHECK(secondary_register_names_.find(reg) != secondary_register_names_.end());
178    return secondary_register_names_[reg];
179  }
180
181  std::string RepeatInsn(size_t count, const std::string& insn) {
182    std::string result;
183    for (; count != 0u; --count) {
184      result += insn;
185    }
186    return result;
187  }
188
189  void BranchCondOneRegHelper(void (mips::MipsAssembler::*f)(mips::Register,
190                                                             mips::MipsLabel*),
191                              std::string instr_name) {
192    mips::MipsLabel label;
193    (Base::GetAssembler()->*f)(mips::A0, &label);
194    constexpr size_t kAdduCount1 = 63;
195    for (size_t i = 0; i != kAdduCount1; ++i) {
196      __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
197    }
198    __ Bind(&label);
199    constexpr size_t kAdduCount2 = 64;
200    for (size_t i = 0; i != kAdduCount2; ++i) {
201      __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
202    }
203    (Base::GetAssembler()->*f)(mips::A1, &label);
204
205    std::string expected =
206        ".set noreorder\n" +
207        instr_name + " $a0, 1f\n"
208        "nop\n" +
209        RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
210        "1:\n" +
211        RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
212        instr_name + " $a1, 1b\n"
213        "nop\n";
214    DriverStr(expected, instr_name);
215  }
216
217  void BranchCondTwoRegsHelper(void (mips::MipsAssembler::*f)(mips::Register,
218                                                              mips::Register,
219                                                              mips::MipsLabel*),
220                               std::string instr_name) {
221    mips::MipsLabel label;
222    (Base::GetAssembler()->*f)(mips::A0, mips::A1, &label);
223    constexpr size_t kAdduCount1 = 63;
224    for (size_t i = 0; i != kAdduCount1; ++i) {
225      __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
226    }
227    __ Bind(&label);
228    constexpr size_t kAdduCount2 = 64;
229    for (size_t i = 0; i != kAdduCount2; ++i) {
230      __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
231    }
232    (Base::GetAssembler()->*f)(mips::A2, mips::A3, &label);
233
234    std::string expected =
235        ".set noreorder\n" +
236        instr_name + " $a0, $a1, 1f\n"
237        "nop\n" +
238        RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
239        "1:\n" +
240        RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
241        instr_name + " $a2, $a3, 1b\n"
242        "nop\n";
243    DriverStr(expected, instr_name);
244  }
245
246 private:
247  std::vector<mips::Register*> registers_;
248  std::map<mips::Register, std::string, MIPSCpuRegisterCompare> secondary_register_names_;
249
250  std::vector<mips::FRegister*> fp_registers_;
251};
252
253
254TEST_F(AssemblerMIPSTest, Toolchain) {
255  EXPECT_TRUE(CheckTools());
256}
257
258TEST_F(AssemblerMIPSTest, Addu) {
259  DriverStr(RepeatRRR(&mips::MipsAssembler::Addu, "addu ${reg1}, ${reg2}, ${reg3}"), "Addu");
260}
261
262TEST_F(AssemblerMIPSTest, Addiu) {
263  DriverStr(RepeatRRIb(&mips::MipsAssembler::Addiu, -16, "addiu ${reg1}, ${reg2}, {imm}"), "Addiu");
264}
265
266TEST_F(AssemblerMIPSTest, Subu) {
267  DriverStr(RepeatRRR(&mips::MipsAssembler::Subu, "subu ${reg1}, ${reg2}, ${reg3}"), "Subu");
268}
269
270TEST_F(AssemblerMIPSTest, MultR2) {
271  DriverStr(RepeatRR(&mips::MipsAssembler::MultR2, "mult ${reg1}, ${reg2}"), "MultR2");
272}
273
274TEST_F(AssemblerMIPSTest, MultuR2) {
275  DriverStr(RepeatRR(&mips::MipsAssembler::MultuR2, "multu ${reg1}, ${reg2}"), "MultuR2");
276}
277
278TEST_F(AssemblerMIPSTest, DivR2Basic) {
279  DriverStr(RepeatRR(&mips::MipsAssembler::DivR2, "div $zero, ${reg1}, ${reg2}"), "DivR2Basic");
280}
281
282TEST_F(AssemblerMIPSTest, DivuR2Basic) {
283  DriverStr(RepeatRR(&mips::MipsAssembler::DivuR2, "divu $zero, ${reg1}, ${reg2}"), "DivuR2Basic");
284}
285
286TEST_F(AssemblerMIPSTest, MulR2) {
287  DriverStr(RepeatRRR(&mips::MipsAssembler::MulR2, "mul ${reg1}, ${reg2}, ${reg3}"), "MulR2");
288}
289
290TEST_F(AssemblerMIPSTest, DivR2) {
291  DriverStr(RepeatRRR(&mips::MipsAssembler::DivR2, "div $zero, ${reg2}, ${reg3}\nmflo ${reg1}"),
292            "DivR2");
293}
294
295TEST_F(AssemblerMIPSTest, ModR2) {
296  DriverStr(RepeatRRR(&mips::MipsAssembler::ModR2, "div $zero, ${reg2}, ${reg3}\nmfhi ${reg1}"),
297            "ModR2");
298}
299
300TEST_F(AssemblerMIPSTest, DivuR2) {
301  DriverStr(RepeatRRR(&mips::MipsAssembler::DivuR2, "divu $zero, ${reg2}, ${reg3}\nmflo ${reg1}"),
302            "DivuR2");
303}
304
305TEST_F(AssemblerMIPSTest, ModuR2) {
306  DriverStr(RepeatRRR(&mips::MipsAssembler::ModuR2, "divu $zero, ${reg2}, ${reg3}\nmfhi ${reg1}"),
307            "ModuR2");
308}
309
310TEST_F(AssemblerMIPSTest, And) {
311  DriverStr(RepeatRRR(&mips::MipsAssembler::And, "and ${reg1}, ${reg2}, ${reg3}"), "And");
312}
313
314TEST_F(AssemblerMIPSTest, Andi) {
315  DriverStr(RepeatRRIb(&mips::MipsAssembler::Andi, 16, "andi ${reg1}, ${reg2}, {imm}"), "Andi");
316}
317
318TEST_F(AssemblerMIPSTest, Or) {
319  DriverStr(RepeatRRR(&mips::MipsAssembler::Or, "or ${reg1}, ${reg2}, ${reg3}"), "Or");
320}
321
322TEST_F(AssemblerMIPSTest, Ori) {
323  DriverStr(RepeatRRIb(&mips::MipsAssembler::Ori, 16, "ori ${reg1}, ${reg2}, {imm}"), "Ori");
324}
325
326TEST_F(AssemblerMIPSTest, Xor) {
327  DriverStr(RepeatRRR(&mips::MipsAssembler::Xor, "xor ${reg1}, ${reg2}, ${reg3}"), "Xor");
328}
329
330TEST_F(AssemblerMIPSTest, Xori) {
331  DriverStr(RepeatRRIb(&mips::MipsAssembler::Xori, 16, "xori ${reg1}, ${reg2}, {imm}"), "Xori");
332}
333
334TEST_F(AssemblerMIPSTest, Nor) {
335  DriverStr(RepeatRRR(&mips::MipsAssembler::Nor, "nor ${reg1}, ${reg2}, ${reg3}"), "Nor");
336}
337
338//////////
339// MISC //
340//////////
341
342TEST_F(AssemblerMIPSTest, Movz) {
343  DriverStr(RepeatRRR(&mips::MipsAssembler::Movz, "movz ${reg1}, ${reg2}, ${reg3}"), "Movz");
344}
345
346TEST_F(AssemblerMIPSTest, Movn) {
347  DriverStr(RepeatRRR(&mips::MipsAssembler::Movn, "movn ${reg1}, ${reg2}, ${reg3}"), "Movn");
348}
349
350TEST_F(AssemblerMIPSTest, Seb) {
351  DriverStr(RepeatRR(&mips::MipsAssembler::Seb, "seb ${reg1}, ${reg2}"), "Seb");
352}
353
354TEST_F(AssemblerMIPSTest, Seh) {
355  DriverStr(RepeatRR(&mips::MipsAssembler::Seh, "seh ${reg1}, ${reg2}"), "Seh");
356}
357
358TEST_F(AssemblerMIPSTest, Sll) {
359  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sll, 5, "sll ${reg1}, ${reg2}, {imm}"), "Sll");
360}
361
362TEST_F(AssemblerMIPSTest, Srl) {
363  DriverStr(RepeatRRIb(&mips::MipsAssembler::Srl, 5, "srl ${reg1}, ${reg2}, {imm}"), "Srl");
364}
365
366TEST_F(AssemblerMIPSTest, Sra) {
367  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sra, 5, "sra ${reg1}, ${reg2}, {imm}"), "Sra");
368}
369
370TEST_F(AssemblerMIPSTest, Sllv) {
371  DriverStr(RepeatRRR(&mips::MipsAssembler::Sllv, "sllv ${reg1}, ${reg2}, ${reg3}"), "Sllv");
372}
373
374TEST_F(AssemblerMIPSTest, Srlv) {
375  DriverStr(RepeatRRR(&mips::MipsAssembler::Srlv, "srlv ${reg1}, ${reg2}, ${reg3}"), "Srlv");
376}
377
378TEST_F(AssemblerMIPSTest, Rotrv) {
379  DriverStr(RepeatRRR(&mips::MipsAssembler::Rotrv, "rotrv ${reg1}, ${reg2}, ${reg3}"), "rotrv");
380}
381
382TEST_F(AssemblerMIPSTest, Srav) {
383  DriverStr(RepeatRRR(&mips::MipsAssembler::Srav, "srav ${reg1}, ${reg2}, ${reg3}"), "Srav");
384}
385
386TEST_F(AssemblerMIPSTest, Ins) {
387  std::vector<mips::Register*> regs = GetRegisters();
388  WarnOnCombinations(regs.size() * regs.size() * 33 * 16);
389  std::string expected;
390  for (mips::Register* reg1 : regs) {
391    for (mips::Register* reg2 : regs) {
392      for (int32_t pos = 0; pos < 32; pos++) {
393        for (int32_t size = 1; pos + size <= 32; size++) {
394          __ Ins(*reg1, *reg2, pos, size);
395          std::ostringstream instr;
396          instr << "ins $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n";
397          expected += instr.str();
398        }
399      }
400    }
401  }
402  DriverStr(expected, "Ins");
403}
404
405TEST_F(AssemblerMIPSTest, Ext) {
406  std::vector<mips::Register*> regs = GetRegisters();
407  WarnOnCombinations(regs.size() * regs.size() * 33 * 16);
408  std::string expected;
409  for (mips::Register* reg1 : regs) {
410    for (mips::Register* reg2 : regs) {
411      for (int32_t pos = 0; pos < 32; pos++) {
412        for (int32_t size = 1; pos + size <= 32; size++) {
413          __ Ext(*reg1, *reg2, pos, size);
414          std::ostringstream instr;
415          instr << "ext $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n";
416          expected += instr.str();
417        }
418      }
419    }
420  }
421  DriverStr(expected, "Ext");
422}
423
424TEST_F(AssemblerMIPSTest, ClzR2) {
425  DriverStr(RepeatRR(&mips::MipsAssembler::ClzR2, "clz ${reg1}, ${reg2}"), "clzR2");
426}
427
428TEST_F(AssemblerMIPSTest, CloR2) {
429  DriverStr(RepeatRR(&mips::MipsAssembler::CloR2, "clo ${reg1}, ${reg2}"), "cloR2");
430}
431
432TEST_F(AssemblerMIPSTest, Lb) {
433  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lb, -16, "lb ${reg1}, {imm}(${reg2})"), "Lb");
434}
435
436TEST_F(AssemblerMIPSTest, Lh) {
437  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lh, -16, "lh ${reg1}, {imm}(${reg2})"), "Lh");
438}
439
440TEST_F(AssemblerMIPSTest, Lwl) {
441  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lwl, -16, "lwl ${reg1}, {imm}(${reg2})"), "Lwl");
442}
443
444TEST_F(AssemblerMIPSTest, Lw) {
445  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lw, -16, "lw ${reg1}, {imm}(${reg2})"), "Lw");
446}
447
448TEST_F(AssemblerMIPSTest, Lwr) {
449  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lwr, -16, "lwr ${reg1}, {imm}(${reg2})"), "Lwr");
450}
451
452TEST_F(AssemblerMIPSTest, Lbu) {
453  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lbu, -16, "lbu ${reg1}, {imm}(${reg2})"), "Lbu");
454}
455
456TEST_F(AssemblerMIPSTest, Lhu) {
457  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lhu, -16, "lhu ${reg1}, {imm}(${reg2})"), "Lhu");
458}
459
460TEST_F(AssemblerMIPSTest, Lui) {
461  DriverStr(RepeatRIb(&mips::MipsAssembler::Lui, 16, "lui ${reg}, {imm}"), "Lui");
462}
463
464TEST_F(AssemblerMIPSTest, Mfhi) {
465  DriverStr(RepeatR(&mips::MipsAssembler::Mfhi, "mfhi ${reg}"), "Mfhi");
466}
467
468TEST_F(AssemblerMIPSTest, Mflo) {
469  DriverStr(RepeatR(&mips::MipsAssembler::Mflo, "mflo ${reg}"), "Mflo");
470}
471
472TEST_F(AssemblerMIPSTest, Sb) {
473  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sb, -16, "sb ${reg1}, {imm}(${reg2})"), "Sb");
474}
475
476TEST_F(AssemblerMIPSTest, Sh) {
477  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sh, -16, "sh ${reg1}, {imm}(${reg2})"), "Sh");
478}
479
480TEST_F(AssemblerMIPSTest, Swl) {
481  DriverStr(RepeatRRIb(&mips::MipsAssembler::Swl, -16, "swl ${reg1}, {imm}(${reg2})"), "Swl");
482}
483
484TEST_F(AssemblerMIPSTest, Sw) {
485  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sw, -16, "sw ${reg1}, {imm}(${reg2})"), "Sw");
486}
487
488TEST_F(AssemblerMIPSTest, Swr) {
489  DriverStr(RepeatRRIb(&mips::MipsAssembler::Swr, -16, "swr ${reg1}, {imm}(${reg2})"), "Swr");
490}
491
492TEST_F(AssemblerMIPSTest, LlR2) {
493  DriverStr(RepeatRRIb(&mips::MipsAssembler::LlR2, -16, "ll ${reg1}, {imm}(${reg2})"), "LlR2");
494}
495
496TEST_F(AssemblerMIPSTest, ScR2) {
497  DriverStr(RepeatRRIb(&mips::MipsAssembler::ScR2, -16, "sc ${reg1}, {imm}(${reg2})"), "ScR2");
498}
499
500TEST_F(AssemblerMIPSTest, Slt) {
501  DriverStr(RepeatRRR(&mips::MipsAssembler::Slt, "slt ${reg1}, ${reg2}, ${reg3}"), "Slt");
502}
503
504TEST_F(AssemblerMIPSTest, Sltu) {
505  DriverStr(RepeatRRR(&mips::MipsAssembler::Sltu, "sltu ${reg1}, ${reg2}, ${reg3}"), "Sltu");
506}
507
508TEST_F(AssemblerMIPSTest, Slti) {
509  DriverStr(RepeatRRIb(&mips::MipsAssembler::Slti, -16, "slti ${reg1}, ${reg2}, {imm}"), "Slti");
510}
511
512TEST_F(AssemblerMIPSTest, Sltiu) {
513  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sltiu, -16, "sltiu ${reg1}, ${reg2}, {imm}"), "Sltiu");
514}
515
516TEST_F(AssemblerMIPSTest, AddS) {
517  DriverStr(RepeatFFF(&mips::MipsAssembler::AddS, "add.s ${reg1}, ${reg2}, ${reg3}"), "AddS");
518}
519
520TEST_F(AssemblerMIPSTest, AddD) {
521  DriverStr(RepeatFFF(&mips::MipsAssembler::AddD, "add.d ${reg1}, ${reg2}, ${reg3}"), "AddD");
522}
523
524TEST_F(AssemblerMIPSTest, SubS) {
525  DriverStr(RepeatFFF(&mips::MipsAssembler::SubS, "sub.s ${reg1}, ${reg2}, ${reg3}"), "SubS");
526}
527
528TEST_F(AssemblerMIPSTest, SubD) {
529  DriverStr(RepeatFFF(&mips::MipsAssembler::SubD, "sub.d ${reg1}, ${reg2}, ${reg3}"), "SubD");
530}
531
532TEST_F(AssemblerMIPSTest, MulS) {
533  DriverStr(RepeatFFF(&mips::MipsAssembler::MulS, "mul.s ${reg1}, ${reg2}, ${reg3}"), "MulS");
534}
535
536TEST_F(AssemblerMIPSTest, MulD) {
537  DriverStr(RepeatFFF(&mips::MipsAssembler::MulD, "mul.d ${reg1}, ${reg2}, ${reg3}"), "MulD");
538}
539
540TEST_F(AssemblerMIPSTest, DivS) {
541  DriverStr(RepeatFFF(&mips::MipsAssembler::DivS, "div.s ${reg1}, ${reg2}, ${reg3}"), "DivS");
542}
543
544TEST_F(AssemblerMIPSTest, DivD) {
545  DriverStr(RepeatFFF(&mips::MipsAssembler::DivD, "div.d ${reg1}, ${reg2}, ${reg3}"), "DivD");
546}
547
548TEST_F(AssemblerMIPSTest, MovS) {
549  DriverStr(RepeatFF(&mips::MipsAssembler::MovS, "mov.s ${reg1}, ${reg2}"), "MovS");
550}
551
552TEST_F(AssemblerMIPSTest, MovD) {
553  DriverStr(RepeatFF(&mips::MipsAssembler::MovD, "mov.d ${reg1}, ${reg2}"), "MovD");
554}
555
556TEST_F(AssemblerMIPSTest, NegS) {
557  DriverStr(RepeatFF(&mips::MipsAssembler::NegS, "neg.s ${reg1}, ${reg2}"), "NegS");
558}
559
560TEST_F(AssemblerMIPSTest, NegD) {
561  DriverStr(RepeatFF(&mips::MipsAssembler::NegD, "neg.d ${reg1}, ${reg2}"), "NegD");
562}
563
564TEST_F(AssemblerMIPSTest, CunS) {
565  DriverStr(RepeatIbFF(&mips::MipsAssembler::CunS, 3, "c.un.s $fcc{imm}, ${reg1}, ${reg2}"),
566            "CunS");
567}
568
569TEST_F(AssemblerMIPSTest, CeqS) {
570  DriverStr(RepeatIbFF(&mips::MipsAssembler::CeqS, 3, "c.eq.s $fcc{imm}, ${reg1}, ${reg2}"),
571            "CeqS");
572}
573
574TEST_F(AssemblerMIPSTest, CueqS) {
575  DriverStr(RepeatIbFF(&mips::MipsAssembler::CueqS, 3, "c.ueq.s $fcc{imm}, ${reg1}, ${reg2}"),
576            "CueqS");
577}
578
579TEST_F(AssemblerMIPSTest, ColtS) {
580  DriverStr(RepeatIbFF(&mips::MipsAssembler::ColtS, 3, "c.olt.s $fcc{imm}, ${reg1}, ${reg2}"),
581            "ColtS");
582}
583
584TEST_F(AssemblerMIPSTest, CultS) {
585  DriverStr(RepeatIbFF(&mips::MipsAssembler::CultS, 3, "c.ult.s $fcc{imm}, ${reg1}, ${reg2}"),
586            "CultS");
587}
588
589TEST_F(AssemblerMIPSTest, ColeS) {
590  DriverStr(RepeatIbFF(&mips::MipsAssembler::ColeS, 3, "c.ole.s $fcc{imm}, ${reg1}, ${reg2}"),
591            "ColeS");
592}
593
594TEST_F(AssemblerMIPSTest, CuleS) {
595  DriverStr(RepeatIbFF(&mips::MipsAssembler::CuleS, 3, "c.ule.s $fcc{imm}, ${reg1}, ${reg2}"),
596            "CuleS");
597}
598
599TEST_F(AssemblerMIPSTest, CunD) {
600  DriverStr(RepeatIbFF(&mips::MipsAssembler::CunD, 3, "c.un.d $fcc{imm}, ${reg1}, ${reg2}"),
601            "CunD");
602}
603
604TEST_F(AssemblerMIPSTest, CeqD) {
605  DriverStr(RepeatIbFF(&mips::MipsAssembler::CeqD, 3, "c.eq.d $fcc{imm}, ${reg1}, ${reg2}"),
606            "CeqD");
607}
608
609TEST_F(AssemblerMIPSTest, CueqD) {
610  DriverStr(RepeatIbFF(&mips::MipsAssembler::CueqD, 3, "c.ueq.d $fcc{imm}, ${reg1}, ${reg2}"),
611            "CueqD");
612}
613
614TEST_F(AssemblerMIPSTest, ColtD) {
615  DriverStr(RepeatIbFF(&mips::MipsAssembler::ColtD, 3, "c.olt.d $fcc{imm}, ${reg1}, ${reg2}"),
616            "ColtD");
617}
618
619TEST_F(AssemblerMIPSTest, CultD) {
620  DriverStr(RepeatIbFF(&mips::MipsAssembler::CultD, 3, "c.ult.d $fcc{imm}, ${reg1}, ${reg2}"),
621            "CultD");
622}
623
624TEST_F(AssemblerMIPSTest, ColeD) {
625  DriverStr(RepeatIbFF(&mips::MipsAssembler::ColeD, 3, "c.ole.d $fcc{imm}, ${reg1}, ${reg2}"),
626            "ColeD");
627}
628
629TEST_F(AssemblerMIPSTest, CuleD) {
630  DriverStr(RepeatIbFF(&mips::MipsAssembler::CuleD, 3, "c.ule.d $fcc{imm}, ${reg1}, ${reg2}"),
631            "CuleD");
632}
633
634TEST_F(AssemblerMIPSTest, Movf) {
635  DriverStr(RepeatRRIb(&mips::MipsAssembler::Movf, 3, "movf ${reg1}, ${reg2}, $fcc{imm}"), "Movf");
636}
637
638TEST_F(AssemblerMIPSTest, Movt) {
639  DriverStr(RepeatRRIb(&mips::MipsAssembler::Movt, 3, "movt ${reg1}, ${reg2}, $fcc{imm}"), "Movt");
640}
641
642TEST_F(AssemblerMIPSTest, CvtSW) {
643  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtsw, "cvt.s.w ${reg1}, ${reg2}"), "CvtSW");
644}
645
646TEST_F(AssemblerMIPSTest, CvtDW) {
647  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtdw, "cvt.d.w ${reg1}, ${reg2}"), "CvtDW");
648}
649
650TEST_F(AssemblerMIPSTest, CvtSL) {
651  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtsl, "cvt.s.l ${reg1}, ${reg2}"), "CvtSL");
652}
653
654TEST_F(AssemblerMIPSTest, CvtDL) {
655  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtdl, "cvt.d.l ${reg1}, ${reg2}"), "CvtDL");
656}
657
658TEST_F(AssemblerMIPSTest, CvtSD) {
659  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtsd, "cvt.s.d ${reg1}, ${reg2}"), "CvtSD");
660}
661
662TEST_F(AssemblerMIPSTest, CvtDS) {
663  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtds, "cvt.d.s ${reg1}, ${reg2}"), "CvtDS");
664}
665
666TEST_F(AssemblerMIPSTest, TruncWS) {
667  DriverStr(RepeatFF(&mips::MipsAssembler::TruncWS, "trunc.w.s ${reg1}, ${reg2}"), "TruncWS");
668}
669
670TEST_F(AssemblerMIPSTest, TruncWD) {
671  DriverStr(RepeatFF(&mips::MipsAssembler::TruncWD, "trunc.w.d ${reg1}, ${reg2}"), "TruncWD");
672}
673
674TEST_F(AssemblerMIPSTest, TruncLS) {
675  DriverStr(RepeatFF(&mips::MipsAssembler::TruncLS, "trunc.l.s ${reg1}, ${reg2}"), "TruncLS");
676}
677
678TEST_F(AssemblerMIPSTest, TruncLD) {
679  DriverStr(RepeatFF(&mips::MipsAssembler::TruncLD, "trunc.l.d ${reg1}, ${reg2}"), "TruncLD");
680}
681
682TEST_F(AssemblerMIPSTest, Mfc1) {
683  DriverStr(RepeatRF(&mips::MipsAssembler::Mfc1, "mfc1 ${reg1}, ${reg2}"), "Mfc1");
684}
685
686TEST_F(AssemblerMIPSTest, Mtc1) {
687  DriverStr(RepeatRF(&mips::MipsAssembler::Mtc1, "mtc1 ${reg1}, ${reg2}"), "Mtc1");
688}
689
690TEST_F(AssemblerMIPSTest, Mfhc1) {
691  DriverStr(RepeatRF(&mips::MipsAssembler::Mfhc1, "mfhc1 ${reg1}, ${reg2}"), "Mfhc1");
692}
693
694TEST_F(AssemblerMIPSTest, Mthc1) {
695  DriverStr(RepeatRF(&mips::MipsAssembler::Mthc1, "mthc1 ${reg1}, ${reg2}"), "Mthc1");
696}
697
698TEST_F(AssemblerMIPSTest, Lwc1) {
699  DriverStr(RepeatFRIb(&mips::MipsAssembler::Lwc1, -16, "lwc1 ${reg1}, {imm}(${reg2})"), "Lwc1");
700}
701
702TEST_F(AssemblerMIPSTest, Ldc1) {
703  DriverStr(RepeatFRIb(&mips::MipsAssembler::Ldc1, -16, "ldc1 ${reg1}, {imm}(${reg2})"), "Ldc1");
704}
705
706TEST_F(AssemblerMIPSTest, Swc1) {
707  DriverStr(RepeatFRIb(&mips::MipsAssembler::Swc1, -16, "swc1 ${reg1}, {imm}(${reg2})"), "Swc1");
708}
709
710TEST_F(AssemblerMIPSTest, Sdc1) {
711  DriverStr(RepeatFRIb(&mips::MipsAssembler::Sdc1, -16, "sdc1 ${reg1}, {imm}(${reg2})"), "Sdc1");
712}
713
714TEST_F(AssemblerMIPSTest, Move) {
715  DriverStr(RepeatRR(&mips::MipsAssembler::Move, "or ${reg1}, ${reg2}, $zero"), "Move");
716}
717
718TEST_F(AssemblerMIPSTest, Clear) {
719  DriverStr(RepeatR(&mips::MipsAssembler::Clear, "or ${reg}, $zero, $zero"), "Clear");
720}
721
722TEST_F(AssemblerMIPSTest, Not) {
723  DriverStr(RepeatRR(&mips::MipsAssembler::Not, "nor ${reg1}, ${reg2}, $zero"), "Not");
724}
725
726TEST_F(AssemblerMIPSTest, LoadFromOffset) {
727  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A0, 0);
728  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0);
729  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 256);
730  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 1000);
731  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0x8000);
732  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0x10000);
733  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0x12345678);
734  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, -256);
735  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0xFFFF8000);
736  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0xABCDEF00);
737
738  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A0, 0);
739  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0);
740  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 256);
741  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 1000);
742  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0x8000);
743  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0x10000);
744  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0x12345678);
745  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, -256);
746  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0xFFFF8000);
747  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0xABCDEF00);
748
749  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A0, 0);
750  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0);
751  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 256);
752  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 1000);
753  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0x8000);
754  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0x10000);
755  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0x12345678);
756  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, -256);
757  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0xFFFF8000);
758  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0xABCDEF00);
759
760  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A0, 0);
761  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0);
762  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 256);
763  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 1000);
764  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0x8000);
765  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0x10000);
766  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0x12345678);
767  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, -256);
768  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0xFFFF8000);
769  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0xABCDEF00);
770
771  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A0, 0);
772  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0);
773  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 256);
774  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 1000);
775  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0x8000);
776  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0x10000);
777  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0x12345678);
778  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, -256);
779  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0xFFFF8000);
780  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0xABCDEF00);
781
782  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A0, 0);
783  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A1, 0);
784  __ LoadFromOffset(mips::kLoadDoubleword, mips::A1, mips::A0, 0);
785  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0);
786  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 256);
787  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 1000);
788  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0x8000);
789  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0x10000);
790  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0x12345678);
791  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, -256);
792  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0xFFFF8000);
793  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0xABCDEF00);
794
795  const char* expected =
796      "lb $a0, 0($a0)\n"
797      "lb $a0, 0($a1)\n"
798      "lb $a0, 256($a1)\n"
799      "lb $a0, 1000($a1)\n"
800      "ori $at, $zero, 0x8000\n"
801      "addu $at, $at, $a1\n"
802      "lb $a0, 0($at)\n"
803      "lui $at, 1\n"
804      "addu $at, $at, $a1\n"
805      "lb $a0, 0($at)\n"
806      "lui $at, 0x1234\n"
807      "ori $at, 0x5678\n"
808      "addu $at, $at, $a1\n"
809      "lb $a0, 0($at)\n"
810      "lb $a0, -256($a1)\n"
811      "lb $a0, 0xFFFF8000($a1)\n"
812      "lui $at, 0xABCD\n"
813      "ori $at, 0xEF00\n"
814      "addu $at, $at, $a1\n"
815      "lb $a0, 0($at)\n"
816
817      "lbu $a0, 0($a0)\n"
818      "lbu $a0, 0($a1)\n"
819      "lbu $a0, 256($a1)\n"
820      "lbu $a0, 1000($a1)\n"
821      "ori $at, $zero, 0x8000\n"
822      "addu $at, $at, $a1\n"
823      "lbu $a0, 0($at)\n"
824      "lui $at, 1\n"
825      "addu $at, $at, $a1\n"
826      "lbu $a0, 0($at)\n"
827      "lui $at, 0x1234\n"
828      "ori $at, 0x5678\n"
829      "addu $at, $at, $a1\n"
830      "lbu $a0, 0($at)\n"
831      "lbu $a0, -256($a1)\n"
832      "lbu $a0, 0xFFFF8000($a1)\n"
833      "lui $at, 0xABCD\n"
834      "ori $at, 0xEF00\n"
835      "addu $at, $at, $a1\n"
836      "lbu $a0, 0($at)\n"
837
838      "lh $a0, 0($a0)\n"
839      "lh $a0, 0($a1)\n"
840      "lh $a0, 256($a1)\n"
841      "lh $a0, 1000($a1)\n"
842      "ori $at, $zero, 0x8000\n"
843      "addu $at, $at, $a1\n"
844      "lh $a0, 0($at)\n"
845      "lui $at, 1\n"
846      "addu $at, $at, $a1\n"
847      "lh $a0, 0($at)\n"
848      "lui $at, 0x1234\n"
849      "ori $at, 0x5678\n"
850      "addu $at, $at, $a1\n"
851      "lh $a0, 0($at)\n"
852      "lh $a0, -256($a1)\n"
853      "lh $a0, 0xFFFF8000($a1)\n"
854      "lui $at, 0xABCD\n"
855      "ori $at, 0xEF00\n"
856      "addu $at, $at, $a1\n"
857      "lh $a0, 0($at)\n"
858
859      "lhu $a0, 0($a0)\n"
860      "lhu $a0, 0($a1)\n"
861      "lhu $a0, 256($a1)\n"
862      "lhu $a0, 1000($a1)\n"
863      "ori $at, $zero, 0x8000\n"
864      "addu $at, $at, $a1\n"
865      "lhu $a0, 0($at)\n"
866      "lui $at, 1\n"
867      "addu $at, $at, $a1\n"
868      "lhu $a0, 0($at)\n"
869      "lui $at, 0x1234\n"
870      "ori $at, 0x5678\n"
871      "addu $at, $at, $a1\n"
872      "lhu $a0, 0($at)\n"
873      "lhu $a0, -256($a1)\n"
874      "lhu $a0, 0xFFFF8000($a1)\n"
875      "lui $at, 0xABCD\n"
876      "ori $at, 0xEF00\n"
877      "addu $at, $at, $a1\n"
878      "lhu $a0, 0($at)\n"
879
880      "lw $a0, 0($a0)\n"
881      "lw $a0, 0($a1)\n"
882      "lw $a0, 256($a1)\n"
883      "lw $a0, 1000($a1)\n"
884      "ori $at, $zero, 0x8000\n"
885      "addu $at, $at, $a1\n"
886      "lw $a0, 0($at)\n"
887      "lui $at, 1\n"
888      "addu $at, $at, $a1\n"
889      "lw $a0, 0($at)\n"
890      "lui $at, 0x1234\n"
891      "ori $at, 0x5678\n"
892      "addu $at, $at, $a1\n"
893      "lw $a0, 0($at)\n"
894      "lw $a0, -256($a1)\n"
895      "lw $a0, 0xFFFF8000($a1)\n"
896      "lui $at, 0xABCD\n"
897      "ori $at, 0xEF00\n"
898      "addu $at, $at, $a1\n"
899      "lw $a0, 0($at)\n"
900
901      "lw $a1, 4($a0)\n"
902      "lw $a0, 0($a0)\n"
903      "lw $a0, 0($a1)\n"
904      "lw $a1, 4($a1)\n"
905      "lw $a1, 0($a0)\n"
906      "lw $a2, 4($a0)\n"
907      "lw $a0, 0($a2)\n"
908      "lw $a1, 4($a2)\n"
909      "lw $a0, 256($a2)\n"
910      "lw $a1, 260($a2)\n"
911      "lw $a0, 1000($a2)\n"
912      "lw $a1, 1004($a2)\n"
913      "ori $at, $zero, 0x8000\n"
914      "addu $at, $at, $a2\n"
915      "lw $a0, 0($at)\n"
916      "lw $a1, 4($at)\n"
917      "lui $at, 1\n"
918      "addu $at, $at, $a2\n"
919      "lw $a0, 0($at)\n"
920      "lw $a1, 4($at)\n"
921      "lui $at, 0x1234\n"
922      "ori $at, 0x5678\n"
923      "addu $at, $at, $a2\n"
924      "lw $a0, 0($at)\n"
925      "lw $a1, 4($at)\n"
926      "lw $a0, -256($a2)\n"
927      "lw $a1, -252($a2)\n"
928      "lw $a0, 0xFFFF8000($a2)\n"
929      "lw $a1, 0xFFFF8004($a2)\n"
930      "lui $at, 0xABCD\n"
931      "ori $at, 0xEF00\n"
932      "addu $at, $at, $a2\n"
933      "lw $a0, 0($at)\n"
934      "lw $a1, 4($at)\n";
935  DriverStr(expected, "LoadFromOffset");
936}
937
938TEST_F(AssemblerMIPSTest, LoadSFromOffset) {
939  __ LoadSFromOffset(mips::F0, mips::A0, 0);
940  __ LoadSFromOffset(mips::F0, mips::A0, 4);
941  __ LoadSFromOffset(mips::F0, mips::A0, 256);
942  __ LoadSFromOffset(mips::F0, mips::A0, 0x8000);
943  __ LoadSFromOffset(mips::F0, mips::A0, 0x10000);
944  __ LoadSFromOffset(mips::F0, mips::A0, 0x12345678);
945  __ LoadSFromOffset(mips::F0, mips::A0, -256);
946  __ LoadSFromOffset(mips::F0, mips::A0, 0xFFFF8000);
947  __ LoadSFromOffset(mips::F0, mips::A0, 0xABCDEF00);
948
949  const char* expected =
950      "lwc1 $f0, 0($a0)\n"
951      "lwc1 $f0, 4($a0)\n"
952      "lwc1 $f0, 256($a0)\n"
953      "ori $at, $zero, 0x8000\n"
954      "addu $at, $at, $a0\n"
955      "lwc1 $f0, 0($at)\n"
956      "lui $at, 1\n"
957      "addu $at, $at, $a0\n"
958      "lwc1 $f0, 0($at)\n"
959      "lui $at, 0x1234\n"
960      "ori $at, 0x5678\n"
961      "addu $at, $at, $a0\n"
962      "lwc1 $f0, 0($at)\n"
963      "lwc1 $f0, -256($a0)\n"
964      "lwc1 $f0, 0xFFFF8000($a0)\n"
965      "lui $at, 0xABCD\n"
966      "ori $at, 0xEF00\n"
967      "addu $at, $at, $a0\n"
968      "lwc1 $f0, 0($at)\n";
969  DriverStr(expected, "LoadSFromOffset");
970}
971
972
973TEST_F(AssemblerMIPSTest, LoadDFromOffset) {
974  __ LoadDFromOffset(mips::F0, mips::A0, 0);
975  __ LoadDFromOffset(mips::F0, mips::A0, 4);
976  __ LoadDFromOffset(mips::F0, mips::A0, 256);
977  __ LoadDFromOffset(mips::F0, mips::A0, 0x8000);
978  __ LoadDFromOffset(mips::F0, mips::A0, 0x10000);
979  __ LoadDFromOffset(mips::F0, mips::A0, 0x12345678);
980  __ LoadDFromOffset(mips::F0, mips::A0, -256);
981  __ LoadDFromOffset(mips::F0, mips::A0, 0xFFFF8000);
982  __ LoadDFromOffset(mips::F0, mips::A0, 0xABCDEF00);
983
984  const char* expected =
985      "ldc1 $f0, 0($a0)\n"
986      "lwc1 $f0, 4($a0)\n"
987      "lwc1 $f1, 8($a0)\n"
988      "ldc1 $f0, 256($a0)\n"
989      "ori $at, $zero, 0x8000\n"
990      "addu $at, $at, $a0\n"
991      "ldc1 $f0, 0($at)\n"
992      "lui $at, 1\n"
993      "addu $at, $at, $a0\n"
994      "ldc1 $f0, 0($at)\n"
995      "lui $at, 0x1234\n"
996      "ori $at, 0x5678\n"
997      "addu $at, $at, $a0\n"
998      "ldc1 $f0, 0($at)\n"
999      "ldc1 $f0, -256($a0)\n"
1000      "ldc1 $f0, 0xFFFF8000($a0)\n"
1001      "lui $at, 0xABCD\n"
1002      "ori $at, 0xEF00\n"
1003      "addu $at, $at, $a0\n"
1004      "ldc1 $f0, 0($at)\n";
1005  DriverStr(expected, "LoadDFromOffset");
1006}
1007
1008TEST_F(AssemblerMIPSTest, StoreToOffset) {
1009  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A0, 0);
1010  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0);
1011  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 256);
1012  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 1000);
1013  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0x8000);
1014  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0x10000);
1015  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0x12345678);
1016  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, -256);
1017  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0xFFFF8000);
1018  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0xABCDEF00);
1019
1020  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A0, 0);
1021  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0);
1022  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 256);
1023  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 1000);
1024  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0x8000);
1025  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0x10000);
1026  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0x12345678);
1027  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, -256);
1028  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0xFFFF8000);
1029  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0xABCDEF00);
1030
1031  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A0, 0);
1032  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0);
1033  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 256);
1034  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 1000);
1035  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0x8000);
1036  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0x10000);
1037  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0x12345678);
1038  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, -256);
1039  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0xFFFF8000);
1040  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0xABCDEF00);
1041
1042  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0);
1043  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 256);
1044  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 1000);
1045  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0x8000);
1046  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0x10000);
1047  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0x12345678);
1048  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, -256);
1049  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0xFFFF8000);
1050  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0xABCDEF00);
1051
1052  const char* expected =
1053      "sb $a0, 0($a0)\n"
1054      "sb $a0, 0($a1)\n"
1055      "sb $a0, 256($a1)\n"
1056      "sb $a0, 1000($a1)\n"
1057      "ori $at, $zero, 0x8000\n"
1058      "addu $at, $at, $a1\n"
1059      "sb $a0, 0($at)\n"
1060      "lui $at, 1\n"
1061      "addu $at, $at, $a1\n"
1062      "sb $a0, 0($at)\n"
1063      "lui $at, 0x1234\n"
1064      "ori $at, 0x5678\n"
1065      "addu $at, $at, $a1\n"
1066      "sb $a0, 0($at)\n"
1067      "sb $a0, -256($a1)\n"
1068      "sb $a0, 0xFFFF8000($a1)\n"
1069      "lui $at, 0xABCD\n"
1070      "ori $at, 0xEF00\n"
1071      "addu $at, $at, $a1\n"
1072      "sb $a0, 0($at)\n"
1073
1074      "sh $a0, 0($a0)\n"
1075      "sh $a0, 0($a1)\n"
1076      "sh $a0, 256($a1)\n"
1077      "sh $a0, 1000($a1)\n"
1078      "ori $at, $zero, 0x8000\n"
1079      "addu $at, $at, $a1\n"
1080      "sh $a0, 0($at)\n"
1081      "lui $at, 1\n"
1082      "addu $at, $at, $a1\n"
1083      "sh $a0, 0($at)\n"
1084      "lui $at, 0x1234\n"
1085      "ori $at, 0x5678\n"
1086      "addu $at, $at, $a1\n"
1087      "sh $a0, 0($at)\n"
1088      "sh $a0, -256($a1)\n"
1089      "sh $a0, 0xFFFF8000($a1)\n"
1090      "lui $at, 0xABCD\n"
1091      "ori $at, 0xEF00\n"
1092      "addu $at, $at, $a1\n"
1093      "sh $a0, 0($at)\n"
1094
1095      "sw $a0, 0($a0)\n"
1096      "sw $a0, 0($a1)\n"
1097      "sw $a0, 256($a1)\n"
1098      "sw $a0, 1000($a1)\n"
1099      "ori $at, $zero, 0x8000\n"
1100      "addu $at, $at, $a1\n"
1101      "sw $a0, 0($at)\n"
1102      "lui $at, 1\n"
1103      "addu $at, $at, $a1\n"
1104      "sw $a0, 0($at)\n"
1105      "lui $at, 0x1234\n"
1106      "ori $at, 0x5678\n"
1107      "addu $at, $at, $a1\n"
1108      "sw $a0, 0($at)\n"
1109      "sw $a0, -256($a1)\n"
1110      "sw $a0, 0xFFFF8000($a1)\n"
1111      "lui $at, 0xABCD\n"
1112      "ori $at, 0xEF00\n"
1113      "addu $at, $at, $a1\n"
1114      "sw $a0, 0($at)\n"
1115
1116      "sw $a0, 0($a2)\n"
1117      "sw $a1, 4($a2)\n"
1118      "sw $a0, 256($a2)\n"
1119      "sw $a1, 260($a2)\n"
1120      "sw $a0, 1000($a2)\n"
1121      "sw $a1, 1004($a2)\n"
1122      "ori $at, $zero, 0x8000\n"
1123      "addu $at, $at, $a2\n"
1124      "sw $a0, 0($at)\n"
1125      "sw $a1, 4($at)\n"
1126      "lui $at, 1\n"
1127      "addu $at, $at, $a2\n"
1128      "sw $a0, 0($at)\n"
1129      "sw $a1, 4($at)\n"
1130      "lui $at, 0x1234\n"
1131      "ori $at, 0x5678\n"
1132      "addu $at, $at, $a2\n"
1133      "sw $a0, 0($at)\n"
1134      "sw $a1, 4($at)\n"
1135      "sw $a0, -256($a2)\n"
1136      "sw $a1, -252($a2)\n"
1137      "sw $a0, 0xFFFF8000($a2)\n"
1138      "sw $a1, 0xFFFF8004($a2)\n"
1139      "lui $at, 0xABCD\n"
1140      "ori $at, 0xEF00\n"
1141      "addu $at, $at, $a2\n"
1142      "sw $a0, 0($at)\n"
1143      "sw $a1, 4($at)\n";
1144  DriverStr(expected, "StoreToOffset");
1145}
1146
1147TEST_F(AssemblerMIPSTest, StoreSToOffset) {
1148  __ StoreSToOffset(mips::F0, mips::A0, 0);
1149  __ StoreSToOffset(mips::F0, mips::A0, 4);
1150  __ StoreSToOffset(mips::F0, mips::A0, 256);
1151  __ StoreSToOffset(mips::F0, mips::A0, 0x8000);
1152  __ StoreSToOffset(mips::F0, mips::A0, 0x10000);
1153  __ StoreSToOffset(mips::F0, mips::A0, 0x12345678);
1154  __ StoreSToOffset(mips::F0, mips::A0, -256);
1155  __ StoreSToOffset(mips::F0, mips::A0, 0xFFFF8000);
1156  __ StoreSToOffset(mips::F0, mips::A0, 0xABCDEF00);
1157
1158  const char* expected =
1159      "swc1 $f0, 0($a0)\n"
1160      "swc1 $f0, 4($a0)\n"
1161      "swc1 $f0, 256($a0)\n"
1162      "ori $at, $zero, 0x8000\n"
1163      "addu $at, $at, $a0\n"
1164      "swc1 $f0, 0($at)\n"
1165      "lui $at, 1\n"
1166      "addu $at, $at, $a0\n"
1167      "swc1 $f0, 0($at)\n"
1168      "lui $at, 0x1234\n"
1169      "ori $at, 0x5678\n"
1170      "addu $at, $at, $a0\n"
1171      "swc1 $f0, 0($at)\n"
1172      "swc1 $f0, -256($a0)\n"
1173      "swc1 $f0, 0xFFFF8000($a0)\n"
1174      "lui $at, 0xABCD\n"
1175      "ori $at, 0xEF00\n"
1176      "addu $at, $at, $a0\n"
1177      "swc1 $f0, 0($at)\n";
1178  DriverStr(expected, "StoreSToOffset");
1179}
1180
1181TEST_F(AssemblerMIPSTest, StoreDToOffset) {
1182  __ StoreDToOffset(mips::F0, mips::A0, 0);
1183  __ StoreDToOffset(mips::F0, mips::A0, 4);
1184  __ StoreDToOffset(mips::F0, mips::A0, 256);
1185  __ StoreDToOffset(mips::F0, mips::A0, 0x8000);
1186  __ StoreDToOffset(mips::F0, mips::A0, 0x10000);
1187  __ StoreDToOffset(mips::F0, mips::A0, 0x12345678);
1188  __ StoreDToOffset(mips::F0, mips::A0, -256);
1189  __ StoreDToOffset(mips::F0, mips::A0, 0xFFFF8000);
1190  __ StoreDToOffset(mips::F0, mips::A0, 0xABCDEF00);
1191
1192  const char* expected =
1193      "sdc1 $f0, 0($a0)\n"
1194      "swc1 $f0, 4($a0)\n"
1195      "swc1 $f1, 8($a0)\n"
1196      "sdc1 $f0, 256($a0)\n"
1197      "ori $at, $zero, 0x8000\n"
1198      "addu $at, $at, $a0\n"
1199      "sdc1 $f0, 0($at)\n"
1200      "lui $at, 1\n"
1201      "addu $at, $at, $a0\n"
1202      "sdc1 $f0, 0($at)\n"
1203      "lui $at, 0x1234\n"
1204      "ori $at, 0x5678\n"
1205      "addu $at, $at, $a0\n"
1206      "sdc1 $f0, 0($at)\n"
1207      "sdc1 $f0, -256($a0)\n"
1208      "sdc1 $f0, 0xFFFF8000($a0)\n"
1209      "lui $at, 0xABCD\n"
1210      "ori $at, 0xEF00\n"
1211      "addu $at, $at, $a0\n"
1212      "sdc1 $f0, 0($at)\n";
1213  DriverStr(expected, "StoreDToOffset");
1214}
1215
1216TEST_F(AssemblerMIPSTest, B) {
1217  mips::MipsLabel label1, label2;
1218  __ B(&label1);
1219  constexpr size_t kAdduCount1 = 63;
1220  for (size_t i = 0; i != kAdduCount1; ++i) {
1221    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1222  }
1223  __ Bind(&label1);
1224  __ B(&label2);
1225  constexpr size_t kAdduCount2 = 64;
1226  for (size_t i = 0; i != kAdduCount2; ++i) {
1227    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1228  }
1229  __ Bind(&label2);
1230  __ B(&label1);
1231
1232  std::string expected =
1233      ".set noreorder\n"
1234      "b 1f\n"
1235      "nop\n" +
1236      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
1237      "1:\n"
1238      "b 2f\n"
1239      "nop\n" +
1240      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
1241      "2:\n"
1242      "b 1b\n"
1243      "nop\n";
1244  DriverStr(expected, "B");
1245}
1246
1247TEST_F(AssemblerMIPSTest, Beq) {
1248  BranchCondTwoRegsHelper(&mips::MipsAssembler::Beq, "Beq");
1249}
1250
1251TEST_F(AssemblerMIPSTest, Bne) {
1252  BranchCondTwoRegsHelper(&mips::MipsAssembler::Bne, "Bne");
1253}
1254
1255TEST_F(AssemblerMIPSTest, Beqz) {
1256  mips::MipsLabel label;
1257  __ Beqz(mips::A0, &label);
1258  constexpr size_t kAdduCount1 = 63;
1259  for (size_t i = 0; i != kAdduCount1; ++i) {
1260    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1261  }
1262  __ Bind(&label);
1263  constexpr size_t kAdduCount2 = 64;
1264  for (size_t i = 0; i != kAdduCount2; ++i) {
1265    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1266  }
1267  __ Beqz(mips::A1, &label);
1268
1269  std::string expected =
1270      ".set noreorder\n"
1271      "beq $zero, $a0, 1f\n"
1272      "nop\n" +
1273      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
1274      "1:\n" +
1275      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
1276      "beq $zero, $a1, 1b\n"
1277      "nop\n";
1278  DriverStr(expected, "Beqz");
1279}
1280
1281TEST_F(AssemblerMIPSTest, Bnez) {
1282  mips::MipsLabel label;
1283  __ Bnez(mips::A0, &label);
1284  constexpr size_t kAdduCount1 = 63;
1285  for (size_t i = 0; i != kAdduCount1; ++i) {
1286    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1287  }
1288  __ Bind(&label);
1289  constexpr size_t kAdduCount2 = 64;
1290  for (size_t i = 0; i != kAdduCount2; ++i) {
1291    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1292  }
1293  __ Bnez(mips::A1, &label);
1294
1295  std::string expected =
1296      ".set noreorder\n"
1297      "bne $zero, $a0, 1f\n"
1298      "nop\n" +
1299      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
1300      "1:\n" +
1301      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
1302      "bne $zero, $a1, 1b\n"
1303      "nop\n";
1304  DriverStr(expected, "Bnez");
1305}
1306
1307TEST_F(AssemblerMIPSTest, Bltz) {
1308  BranchCondOneRegHelper(&mips::MipsAssembler::Bltz, "Bltz");
1309}
1310
1311TEST_F(AssemblerMIPSTest, Bgez) {
1312  BranchCondOneRegHelper(&mips::MipsAssembler::Bgez, "Bgez");
1313}
1314
1315TEST_F(AssemblerMIPSTest, Blez) {
1316  BranchCondOneRegHelper(&mips::MipsAssembler::Blez, "Blez");
1317}
1318
1319TEST_F(AssemblerMIPSTest, Bgtz) {
1320  BranchCondOneRegHelper(&mips::MipsAssembler::Bgtz, "Bgtz");
1321}
1322
1323TEST_F(AssemblerMIPSTest, Blt) {
1324  mips::MipsLabel label;
1325  __ Blt(mips::A0, mips::A1, &label);
1326  constexpr size_t kAdduCount1 = 63;
1327  for (size_t i = 0; i != kAdduCount1; ++i) {
1328    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1329  }
1330  __ Bind(&label);
1331  constexpr size_t kAdduCount2 = 64;
1332  for (size_t i = 0; i != kAdduCount2; ++i) {
1333    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1334  }
1335  __ Blt(mips::A2, mips::A3, &label);
1336
1337  std::string expected =
1338      ".set noreorder\n"
1339      "slt $at, $a0, $a1\n"
1340      "bne $zero, $at, 1f\n"
1341      "nop\n" +
1342      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
1343      "1:\n" +
1344      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
1345      "slt $at, $a2, $a3\n"
1346      "bne $zero, $at, 1b\n"
1347      "nop\n";
1348  DriverStr(expected, "Blt");
1349}
1350
1351TEST_F(AssemblerMIPSTest, Bge) {
1352  mips::MipsLabel label;
1353  __ Bge(mips::A0, mips::A1, &label);
1354  constexpr size_t kAdduCount1 = 63;
1355  for (size_t i = 0; i != kAdduCount1; ++i) {
1356    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1357  }
1358  __ Bind(&label);
1359  constexpr size_t kAdduCount2 = 64;
1360  for (size_t i = 0; i != kAdduCount2; ++i) {
1361    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1362  }
1363  __ Bge(mips::A2, mips::A3, &label);
1364
1365  std::string expected =
1366      ".set noreorder\n"
1367      "slt $at, $a0, $a1\n"
1368      "beq $zero, $at, 1f\n"
1369      "nop\n" +
1370      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
1371      "1:\n" +
1372      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
1373      "slt $at, $a2, $a3\n"
1374      "beq $zero, $at, 1b\n"
1375      "nop\n";
1376  DriverStr(expected, "Bge");
1377}
1378
1379TEST_F(AssemblerMIPSTest, Bltu) {
1380  mips::MipsLabel label;
1381  __ Bltu(mips::A0, mips::A1, &label);
1382  constexpr size_t kAdduCount1 = 63;
1383  for (size_t i = 0; i != kAdduCount1; ++i) {
1384    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1385  }
1386  __ Bind(&label);
1387  constexpr size_t kAdduCount2 = 64;
1388  for (size_t i = 0; i != kAdduCount2; ++i) {
1389    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1390  }
1391  __ Bltu(mips::A2, mips::A3, &label);
1392
1393  std::string expected =
1394      ".set noreorder\n"
1395      "sltu $at, $a0, $a1\n"
1396      "bne $zero, $at, 1f\n"
1397      "nop\n" +
1398      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
1399      "1:\n" +
1400      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
1401      "sltu $at, $a2, $a3\n"
1402      "bne $zero, $at, 1b\n"
1403      "nop\n";
1404  DriverStr(expected, "Bltu");
1405}
1406
1407TEST_F(AssemblerMIPSTest, Bgeu) {
1408  mips::MipsLabel label;
1409  __ Bgeu(mips::A0, mips::A1, &label);
1410  constexpr size_t kAdduCount1 = 63;
1411  for (size_t i = 0; i != kAdduCount1; ++i) {
1412    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1413  }
1414  __ Bind(&label);
1415  constexpr size_t kAdduCount2 = 64;
1416  for (size_t i = 0; i != kAdduCount2; ++i) {
1417    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1418  }
1419  __ Bgeu(mips::A2, mips::A3, &label);
1420
1421  std::string expected =
1422      ".set noreorder\n"
1423      "sltu $at, $a0, $a1\n"
1424      "beq $zero, $at, 1f\n"
1425      "nop\n" +
1426      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
1427      "1:\n" +
1428      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
1429      "sltu $at, $a2, $a3\n"
1430      "beq $zero, $at, 1b\n"
1431      "nop\n";
1432  DriverStr(expected, "Bgeu");
1433}
1434
1435TEST_F(AssemblerMIPSTest, Bc1f) {
1436  mips::MipsLabel label;
1437  __ Bc1f(0, &label);
1438  constexpr size_t kAdduCount1 = 63;
1439  for (size_t i = 0; i != kAdduCount1; ++i) {
1440    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1441  }
1442  __ Bind(&label);
1443  constexpr size_t kAdduCount2 = 64;
1444  for (size_t i = 0; i != kAdduCount2; ++i) {
1445    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1446  }
1447  __ Bc1f(7, &label);
1448
1449  std::string expected =
1450      ".set noreorder\n"
1451      "bc1f $fcc0, 1f\n"
1452      "nop\n" +
1453      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
1454      "1:\n" +
1455      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
1456      "bc1f $fcc7, 1b\n"
1457      "nop\n";
1458  DriverStr(expected, "Bc1f");
1459}
1460
1461TEST_F(AssemblerMIPSTest, Bc1t) {
1462  mips::MipsLabel label;
1463  __ Bc1t(0, &label);
1464  constexpr size_t kAdduCount1 = 63;
1465  for (size_t i = 0; i != kAdduCount1; ++i) {
1466    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1467  }
1468  __ Bind(&label);
1469  constexpr size_t kAdduCount2 = 64;
1470  for (size_t i = 0; i != kAdduCount2; ++i) {
1471    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
1472  }
1473  __ Bc1t(7, &label);
1474
1475  std::string expected =
1476      ".set noreorder\n"
1477      "bc1t $fcc0, 1f\n"
1478      "nop\n" +
1479      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
1480      "1:\n" +
1481      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
1482      "bc1t $fcc7, 1b\n"
1483      "nop\n";
1484  DriverStr(expected, "Bc1t");
1485}
1486
1487#undef __
1488
1489}  // namespace art
1490