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                              const 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                               const 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, FloorWS) {
565  DriverStr(RepeatFF(&mips::MipsAssembler::FloorWS, "floor.w.s ${reg1}, ${reg2}"), "floor.w.s");
566}
567
568TEST_F(AssemblerMIPSTest, FloorWD) {
569  DriverStr(RepeatFF(&mips::MipsAssembler::FloorWD, "floor.w.d ${reg1}, ${reg2}"), "floor.w.d");
570}
571
572TEST_F(AssemblerMIPSTest, CunS) {
573  DriverStr(RepeatIbFF(&mips::MipsAssembler::CunS, 3, "c.un.s $fcc{imm}, ${reg1}, ${reg2}"),
574            "CunS");
575}
576
577TEST_F(AssemblerMIPSTest, CeqS) {
578  DriverStr(RepeatIbFF(&mips::MipsAssembler::CeqS, 3, "c.eq.s $fcc{imm}, ${reg1}, ${reg2}"),
579            "CeqS");
580}
581
582TEST_F(AssemblerMIPSTest, CueqS) {
583  DriverStr(RepeatIbFF(&mips::MipsAssembler::CueqS, 3, "c.ueq.s $fcc{imm}, ${reg1}, ${reg2}"),
584            "CueqS");
585}
586
587TEST_F(AssemblerMIPSTest, ColtS) {
588  DriverStr(RepeatIbFF(&mips::MipsAssembler::ColtS, 3, "c.olt.s $fcc{imm}, ${reg1}, ${reg2}"),
589            "ColtS");
590}
591
592TEST_F(AssemblerMIPSTest, CultS) {
593  DriverStr(RepeatIbFF(&mips::MipsAssembler::CultS, 3, "c.ult.s $fcc{imm}, ${reg1}, ${reg2}"),
594            "CultS");
595}
596
597TEST_F(AssemblerMIPSTest, ColeS) {
598  DriverStr(RepeatIbFF(&mips::MipsAssembler::ColeS, 3, "c.ole.s $fcc{imm}, ${reg1}, ${reg2}"),
599            "ColeS");
600}
601
602TEST_F(AssemblerMIPSTest, CuleS) {
603  DriverStr(RepeatIbFF(&mips::MipsAssembler::CuleS, 3, "c.ule.s $fcc{imm}, ${reg1}, ${reg2}"),
604            "CuleS");
605}
606
607TEST_F(AssemblerMIPSTest, CunD) {
608  DriverStr(RepeatIbFF(&mips::MipsAssembler::CunD, 3, "c.un.d $fcc{imm}, ${reg1}, ${reg2}"),
609            "CunD");
610}
611
612TEST_F(AssemblerMIPSTest, CeqD) {
613  DriverStr(RepeatIbFF(&mips::MipsAssembler::CeqD, 3, "c.eq.d $fcc{imm}, ${reg1}, ${reg2}"),
614            "CeqD");
615}
616
617TEST_F(AssemblerMIPSTest, CueqD) {
618  DriverStr(RepeatIbFF(&mips::MipsAssembler::CueqD, 3, "c.ueq.d $fcc{imm}, ${reg1}, ${reg2}"),
619            "CueqD");
620}
621
622TEST_F(AssemblerMIPSTest, ColtD) {
623  DriverStr(RepeatIbFF(&mips::MipsAssembler::ColtD, 3, "c.olt.d $fcc{imm}, ${reg1}, ${reg2}"),
624            "ColtD");
625}
626
627TEST_F(AssemblerMIPSTest, CultD) {
628  DriverStr(RepeatIbFF(&mips::MipsAssembler::CultD, 3, "c.ult.d $fcc{imm}, ${reg1}, ${reg2}"),
629            "CultD");
630}
631
632TEST_F(AssemblerMIPSTest, ColeD) {
633  DriverStr(RepeatIbFF(&mips::MipsAssembler::ColeD, 3, "c.ole.d $fcc{imm}, ${reg1}, ${reg2}"),
634            "ColeD");
635}
636
637TEST_F(AssemblerMIPSTest, CuleD) {
638  DriverStr(RepeatIbFF(&mips::MipsAssembler::CuleD, 3, "c.ule.d $fcc{imm}, ${reg1}, ${reg2}"),
639            "CuleD");
640}
641
642TEST_F(AssemblerMIPSTest, Movf) {
643  DriverStr(RepeatRRIb(&mips::MipsAssembler::Movf, 3, "movf ${reg1}, ${reg2}, $fcc{imm}"), "Movf");
644}
645
646TEST_F(AssemblerMIPSTest, Movt) {
647  DriverStr(RepeatRRIb(&mips::MipsAssembler::Movt, 3, "movt ${reg1}, ${reg2}, $fcc{imm}"), "Movt");
648}
649
650TEST_F(AssemblerMIPSTest, MovfS) {
651  DriverStr(RepeatFFIb(&mips::MipsAssembler::MovfS, 3, "movf.s ${reg1}, ${reg2}, $fcc{imm}"),
652            "MovfS");
653}
654
655TEST_F(AssemblerMIPSTest, MovfD) {
656  DriverStr(RepeatFFIb(&mips::MipsAssembler::MovfD, 3, "movf.d ${reg1}, ${reg2}, $fcc{imm}"),
657            "MovfD");
658}
659
660TEST_F(AssemblerMIPSTest, MovtS) {
661  DriverStr(RepeatFFIb(&mips::MipsAssembler::MovtS, 3, "movt.s ${reg1}, ${reg2}, $fcc{imm}"),
662            "MovtS");
663}
664
665TEST_F(AssemblerMIPSTest, MovtD) {
666  DriverStr(RepeatFFIb(&mips::MipsAssembler::MovtD, 3, "movt.d ${reg1}, ${reg2}, $fcc{imm}"),
667            "MovtD");
668}
669
670TEST_F(AssemblerMIPSTest, MovzS) {
671  DriverStr(RepeatFFR(&mips::MipsAssembler::MovzS, "movz.s ${reg1}, ${reg2}, ${reg3}"), "MovzS");
672}
673
674TEST_F(AssemblerMIPSTest, MovzD) {
675  DriverStr(RepeatFFR(&mips::MipsAssembler::MovzD, "movz.d ${reg1}, ${reg2}, ${reg3}"), "MovzD");
676}
677
678TEST_F(AssemblerMIPSTest, MovnS) {
679  DriverStr(RepeatFFR(&mips::MipsAssembler::MovnS, "movn.s ${reg1}, ${reg2}, ${reg3}"), "MovnS");
680}
681
682TEST_F(AssemblerMIPSTest, MovnD) {
683  DriverStr(RepeatFFR(&mips::MipsAssembler::MovnD, "movn.d ${reg1}, ${reg2}, ${reg3}"), "MovnD");
684}
685
686TEST_F(AssemblerMIPSTest, CvtSW) {
687  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtsw, "cvt.s.w ${reg1}, ${reg2}"), "CvtSW");
688}
689
690TEST_F(AssemblerMIPSTest, CvtDW) {
691  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtdw, "cvt.d.w ${reg1}, ${reg2}"), "CvtDW");
692}
693
694TEST_F(AssemblerMIPSTest, CvtSL) {
695  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtsl, "cvt.s.l ${reg1}, ${reg2}"), "CvtSL");
696}
697
698TEST_F(AssemblerMIPSTest, CvtDL) {
699  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtdl, "cvt.d.l ${reg1}, ${reg2}"), "CvtDL");
700}
701
702TEST_F(AssemblerMIPSTest, CvtSD) {
703  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtsd, "cvt.s.d ${reg1}, ${reg2}"), "CvtSD");
704}
705
706TEST_F(AssemblerMIPSTest, CvtDS) {
707  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtds, "cvt.d.s ${reg1}, ${reg2}"), "CvtDS");
708}
709
710TEST_F(AssemblerMIPSTest, TruncWS) {
711  DriverStr(RepeatFF(&mips::MipsAssembler::TruncWS, "trunc.w.s ${reg1}, ${reg2}"), "TruncWS");
712}
713
714TEST_F(AssemblerMIPSTest, TruncWD) {
715  DriverStr(RepeatFF(&mips::MipsAssembler::TruncWD, "trunc.w.d ${reg1}, ${reg2}"), "TruncWD");
716}
717
718TEST_F(AssemblerMIPSTest, TruncLS) {
719  DriverStr(RepeatFF(&mips::MipsAssembler::TruncLS, "trunc.l.s ${reg1}, ${reg2}"), "TruncLS");
720}
721
722TEST_F(AssemblerMIPSTest, TruncLD) {
723  DriverStr(RepeatFF(&mips::MipsAssembler::TruncLD, "trunc.l.d ${reg1}, ${reg2}"), "TruncLD");
724}
725
726TEST_F(AssemblerMIPSTest, Mfc1) {
727  DriverStr(RepeatRF(&mips::MipsAssembler::Mfc1, "mfc1 ${reg1}, ${reg2}"), "Mfc1");
728}
729
730TEST_F(AssemblerMIPSTest, Mtc1) {
731  DriverStr(RepeatRF(&mips::MipsAssembler::Mtc1, "mtc1 ${reg1}, ${reg2}"), "Mtc1");
732}
733
734TEST_F(AssemblerMIPSTest, Mfhc1) {
735  DriverStr(RepeatRF(&mips::MipsAssembler::Mfhc1, "mfhc1 ${reg1}, ${reg2}"), "Mfhc1");
736}
737
738TEST_F(AssemblerMIPSTest, Mthc1) {
739  DriverStr(RepeatRF(&mips::MipsAssembler::Mthc1, "mthc1 ${reg1}, ${reg2}"), "Mthc1");
740}
741
742TEST_F(AssemblerMIPSTest, Lwc1) {
743  DriverStr(RepeatFRIb(&mips::MipsAssembler::Lwc1, -16, "lwc1 ${reg1}, {imm}(${reg2})"), "Lwc1");
744}
745
746TEST_F(AssemblerMIPSTest, Ldc1) {
747  DriverStr(RepeatFRIb(&mips::MipsAssembler::Ldc1, -16, "ldc1 ${reg1}, {imm}(${reg2})"), "Ldc1");
748}
749
750TEST_F(AssemblerMIPSTest, Swc1) {
751  DriverStr(RepeatFRIb(&mips::MipsAssembler::Swc1, -16, "swc1 ${reg1}, {imm}(${reg2})"), "Swc1");
752}
753
754TEST_F(AssemblerMIPSTest, Sdc1) {
755  DriverStr(RepeatFRIb(&mips::MipsAssembler::Sdc1, -16, "sdc1 ${reg1}, {imm}(${reg2})"), "Sdc1");
756}
757
758TEST_F(AssemblerMIPSTest, Move) {
759  DriverStr(RepeatRR(&mips::MipsAssembler::Move, "or ${reg1}, ${reg2}, $zero"), "Move");
760}
761
762TEST_F(AssemblerMIPSTest, Clear) {
763  DriverStr(RepeatR(&mips::MipsAssembler::Clear, "or ${reg}, $zero, $zero"), "Clear");
764}
765
766TEST_F(AssemblerMIPSTest, Not) {
767  DriverStr(RepeatRR(&mips::MipsAssembler::Not, "nor ${reg1}, ${reg2}, $zero"), "Not");
768}
769
770TEST_F(AssemblerMIPSTest, Addiu32) {
771  __ Addiu32(mips::A1, mips::A2, -0x8000);
772  __ Addiu32(mips::A1, mips::A2, +0);
773  __ Addiu32(mips::A1, mips::A2, +0x7FFF);
774  __ Addiu32(mips::A1, mips::A2, -0x10000);
775  __ Addiu32(mips::A1, mips::A2, -0x8001);
776  __ Addiu32(mips::A1, mips::A2, +0x8000);
777  __ Addiu32(mips::A1, mips::A2, +0xFFFE);
778  __ Addiu32(mips::A1, mips::A2, -0x10001);
779  __ Addiu32(mips::A1, mips::A2, +0xFFFF);
780  __ Addiu32(mips::A1, mips::A2, +0x10000);
781  __ Addiu32(mips::A1, mips::A2, +0x10001);
782  __ Addiu32(mips::A1, mips::A2, +0x12345678);
783
784  const char* expected =
785      "addiu $a1, $a2, -0x8000\n"
786      "addiu $a1, $a2, 0\n"
787      "addiu $a1, $a2, 0x7FFF\n"
788      "addiu $at, $a2, -0x8000\n"
789      "addiu $a1, $at, -0x8000\n"
790      "addiu $at, $a2, -0x8000\n"
791      "addiu $a1, $at, -1\n"
792      "addiu $at, $a2, 0x7FFF\n"
793      "addiu $a1, $at, 1\n"
794      "addiu $at, $a2, 0x7FFF\n"
795      "addiu $a1, $at, 0x7FFF\n"
796      "lui $at, 0xFFFE\n"
797      "ori $at, $at, 0xFFFF\n"
798      "addu $a1, $a2, $at\n"
799      "ori $at, $zero, 0xFFFF\n"
800      "addu $a1, $a2, $at\n"
801      "lui $at, 1\n"
802      "addu $a1, $a2, $at\n"
803      "lui $at, 1\n"
804      "ori $at, $at, 1\n"
805      "addu $a1, $a2, $at\n"
806      "lui $at, 0x1234\n"
807      "ori $at, $at, 0x5678\n"
808      "addu $a1, $a2, $at\n";
809  DriverStr(expected, "Addiu32");
810}
811
812TEST_F(AssemblerMIPSTest, LoadFromOffset) {
813  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, -0x8000);
814  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0);
815  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0x7FF8);
816  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0x7FFB);
817  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0x7FFC);
818  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0x7FFF);
819  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, -0xFFF0);
820  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, -0x8008);
821  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, -0x8001);
822  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0x8000);
823  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0xFFF0);
824  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, -0x17FE8);
825  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, -0x0FFF8);
826  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, -0x0FFF1);
827  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0x0FFF1);
828  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0x0FFF8);
829  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0x17FE8);
830  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, -0x17FF0);
831  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, -0x17FE9);
832  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0x17FE9);
833  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0x17FF0);
834  __ LoadFromOffset(mips::kLoadSignedByte, mips::A3, mips::A1, +0x12345678);
835
836  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, -0x8000);
837  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0);
838  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0x7FF8);
839  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0x7FFB);
840  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0x7FFC);
841  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0x7FFF);
842  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, -0xFFF0);
843  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, -0x8008);
844  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, -0x8001);
845  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0x8000);
846  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0xFFF0);
847  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, -0x17FE8);
848  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, -0x0FFF8);
849  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, -0x0FFF1);
850  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0x0FFF1);
851  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0x0FFF8);
852  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0x17FE8);
853  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, -0x17FF0);
854  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, -0x17FE9);
855  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0x17FE9);
856  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0x17FF0);
857  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A3, mips::A1, +0x12345678);
858
859  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, -0x8000);
860  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0);
861  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0x7FF8);
862  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0x7FFB);
863  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0x7FFC);
864  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0x7FFF);
865  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, -0xFFF0);
866  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, -0x8008);
867  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, -0x8001);
868  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0x8000);
869  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0xFFF0);
870  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, -0x17FE8);
871  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, -0x0FFF8);
872  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, -0x0FFF1);
873  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0x0FFF1);
874  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0x0FFF8);
875  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0x17FE8);
876  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, -0x17FF0);
877  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, -0x17FE9);
878  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0x17FE9);
879  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0x17FF0);
880  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A3, mips::A1, +0x12345678);
881
882  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, -0x8000);
883  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0);
884  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0x7FF8);
885  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0x7FFB);
886  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0x7FFC);
887  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0x7FFF);
888  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, -0xFFF0);
889  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, -0x8008);
890  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, -0x8001);
891  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0x8000);
892  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0xFFF0);
893  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, -0x17FE8);
894  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, -0x0FFF8);
895  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, -0x0FFF1);
896  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0x0FFF1);
897  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0x0FFF8);
898  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0x17FE8);
899  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, -0x17FF0);
900  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, -0x17FE9);
901  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0x17FE9);
902  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0x17FF0);
903  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A3, mips::A1, +0x12345678);
904
905  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, -0x8000);
906  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0);
907  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0x7FF8);
908  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0x7FFB);
909  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0x7FFC);
910  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0x7FFF);
911  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, -0xFFF0);
912  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, -0x8008);
913  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, -0x8001);
914  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0x8000);
915  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0xFFF0);
916  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, -0x17FE8);
917  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, -0x0FFF8);
918  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, -0x0FFF1);
919  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0x0FFF1);
920  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0x0FFF8);
921  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0x17FE8);
922  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, -0x17FF0);
923  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, -0x17FE9);
924  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0x17FE9);
925  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0x17FF0);
926  __ LoadFromOffset(mips::kLoadWord, mips::A3, mips::A1, +0x12345678);
927
928  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, -0x8000);
929  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0);
930  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0x7FF8);
931  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0x7FFB);
932  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0x7FFC);
933  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0x7FFF);
934  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, -0xFFF0);
935  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, -0x8008);
936  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, -0x8001);
937  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0x8000);
938  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0xFFF0);
939  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, -0x17FE8);
940  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, -0x0FFF8);
941  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, -0x0FFF1);
942  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0x0FFF1);
943  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0x0FFF8);
944  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0x17FE8);
945  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, -0x17FF0);
946  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, -0x17FE9);
947  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0x17FE9);
948  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0x17FF0);
949  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, +0x12345678);
950
951  const char* expected =
952      "lb $a3, -0x8000($a1)\n"
953      "lb $a3, 0($a1)\n"
954      "lb $a3, 0x7FF8($a1)\n"
955      "lb $a3, 0x7FFB($a1)\n"
956      "lb $a3, 0x7FFC($a1)\n"
957      "lb $a3, 0x7FFF($a1)\n"
958      "addiu $at, $a1, -0x7FF8\n"
959      "lb $a3, -0x7FF8($at)\n"
960      "addiu $at, $a1, -0x7FF8\n"
961      "lb $a3, -0x10($at)\n"
962      "addiu $at, $a1, -0x7FF8\n"
963      "lb $a3, -9($at)\n"
964      "addiu $at, $a1, 0x7FF8\n"
965      "lb $a3, 8($at)\n"
966      "addiu $at, $a1, 0x7FF8\n"
967      "lb $a3, 0x7FF8($at)\n"
968      "addiu $at, $a1, -0x7FF8\n"
969      "addiu $at, $at, -0x7FF8\n"
970      "lb $a3, -0x7FF8($at)\n"
971      "addiu $at, $a1, -0x7FF8\n"
972      "addiu $at, $at, -0x7FF8\n"
973      "lb $a3, -8($at)\n"
974      "addiu $at, $a1, -0x7FF8\n"
975      "addiu $at, $at, -0x7FF8\n"
976      "lb $a3, -1($at)\n"
977      "addiu $at, $a1, 0x7FF8\n"
978      "addiu $at, $at, 0x7FF8\n"
979      "lb $a3, 1($at)\n"
980      "addiu $at, $a1, 0x7FF8\n"
981      "addiu $at, $at, 0x7FF8\n"
982      "lb $a3, 8($at)\n"
983      "addiu $at, $a1, 0x7FF8\n"
984      "addiu $at, $at, 0x7FF8\n"
985      "lb $a3, 0x7FF8($at)\n"
986      "lui $at, 0xFFFE\n"
987      "ori $at, $at, 0x8010\n"
988      "addu $at, $at, $a1\n"
989      "lb $a3, 0($at)\n"
990      "lui $at, 0xFFFE\n"
991      "ori $at, $at, 0x8010\n"
992      "addu $at, $at, $a1\n"
993      "lb $a3, 7($at)\n"
994      "lui $at, 0x1\n"
995      "ori $at, $at, 0x7FE8\n"
996      "addu $at, $at, $a1\n"
997      "lb $a3, 1($at)\n"
998      "lui $at, 0x1\n"
999      "ori $at, $at, 0x7FF0\n"
1000      "addu $at, $at, $a1\n"
1001      "lb $a3, 0($at)\n"
1002      "lui $at, 0x1234\n"
1003      "ori $at, $at, 0x5678\n"
1004      "addu $at, $at, $a1\n"
1005      "lb $a3, 0($at)\n"
1006
1007      "lbu $a3, -0x8000($a1)\n"
1008      "lbu $a3, 0($a1)\n"
1009      "lbu $a3, 0x7FF8($a1)\n"
1010      "lbu $a3, 0x7FFB($a1)\n"
1011      "lbu $a3, 0x7FFC($a1)\n"
1012      "lbu $a3, 0x7FFF($a1)\n"
1013      "addiu $at, $a1, -0x7FF8\n"
1014      "lbu $a3, -0x7FF8($at)\n"
1015      "addiu $at, $a1, -0x7FF8\n"
1016      "lbu $a3, -0x10($at)\n"
1017      "addiu $at, $a1, -0x7FF8\n"
1018      "lbu $a3, -9($at)\n"
1019      "addiu $at, $a1, 0x7FF8\n"
1020      "lbu $a3, 8($at)\n"
1021      "addiu $at, $a1, 0x7FF8\n"
1022      "lbu $a3, 0x7FF8($at)\n"
1023      "addiu $at, $a1, -0x7FF8\n"
1024      "addiu $at, $at, -0x7FF8\n"
1025      "lbu $a3, -0x7FF8($at)\n"
1026      "addiu $at, $a1, -0x7FF8\n"
1027      "addiu $at, $at, -0x7FF8\n"
1028      "lbu $a3, -8($at)\n"
1029      "addiu $at, $a1, -0x7FF8\n"
1030      "addiu $at, $at, -0x7FF8\n"
1031      "lbu $a3, -1($at)\n"
1032      "addiu $at, $a1, 0x7FF8\n"
1033      "addiu $at, $at, 0x7FF8\n"
1034      "lbu $a3, 1($at)\n"
1035      "addiu $at, $a1, 0x7FF8\n"
1036      "addiu $at, $at, 0x7FF8\n"
1037      "lbu $a3, 8($at)\n"
1038      "addiu $at, $a1, 0x7FF8\n"
1039      "addiu $at, $at, 0x7FF8\n"
1040      "lbu $a3, 0x7FF8($at)\n"
1041      "lui $at, 0xFFFE\n"
1042      "ori $at, $at, 0x8010\n"
1043      "addu $at, $at, $a1\n"
1044      "lbu $a3, 0($at)\n"
1045      "lui $at, 0xFFFE\n"
1046      "ori $at, $at, 0x8010\n"
1047      "addu $at, $at, $a1\n"
1048      "lbu $a3, 7($at)\n"
1049      "lui $at, 0x1\n"
1050      "ori $at, $at, 0x7FE8\n"
1051      "addu $at, $at, $a1\n"
1052      "lbu $a3, 1($at)\n"
1053      "lui $at, 0x1\n"
1054      "ori $at, $at, 0x7FF0\n"
1055      "addu $at, $at, $a1\n"
1056      "lbu $a3, 0($at)\n"
1057      "lui $at, 0x1234\n"
1058      "ori $at, $at, 0x5678\n"
1059      "addu $at, $at, $a1\n"
1060      "lbu $a3, 0($at)\n"
1061
1062      "lh $a3, -0x8000($a1)\n"
1063      "lh $a3, 0($a1)\n"
1064      "lh $a3, 0x7FF8($a1)\n"
1065      "lh $a3, 0x7FFB($a1)\n"
1066      "lh $a3, 0x7FFC($a1)\n"
1067      "lh $a3, 0x7FFF($a1)\n"
1068      "addiu $at, $a1, -0x7FF8\n"
1069      "lh $a3, -0x7FF8($at)\n"
1070      "addiu $at, $a1, -0x7FF8\n"
1071      "lh $a3, -0x10($at)\n"
1072      "addiu $at, $a1, -0x7FF8\n"
1073      "lh $a3, -9($at)\n"
1074      "addiu $at, $a1, 0x7FF8\n"
1075      "lh $a3, 8($at)\n"
1076      "addiu $at, $a1, 0x7FF8\n"
1077      "lh $a3, 0x7FF8($at)\n"
1078      "addiu $at, $a1, -0x7FF8\n"
1079      "addiu $at, $at, -0x7FF8\n"
1080      "lh $a3, -0x7FF8($at)\n"
1081      "addiu $at, $a1, -0x7FF8\n"
1082      "addiu $at, $at, -0x7FF8\n"
1083      "lh $a3, -8($at)\n"
1084      "addiu $at, $a1, -0x7FF8\n"
1085      "addiu $at, $at, -0x7FF8\n"
1086      "lh $a3, -1($at)\n"
1087      "addiu $at, $a1, 0x7FF8\n"
1088      "addiu $at, $at, 0x7FF8\n"
1089      "lh $a3, 1($at)\n"
1090      "addiu $at, $a1, 0x7FF8\n"
1091      "addiu $at, $at, 0x7FF8\n"
1092      "lh $a3, 8($at)\n"
1093      "addiu $at, $a1, 0x7FF8\n"
1094      "addiu $at, $at, 0x7FF8\n"
1095      "lh $a3, 0x7FF8($at)\n"
1096      "lui $at, 0xFFFE\n"
1097      "ori $at, $at, 0x8010\n"
1098      "addu $at, $at, $a1\n"
1099      "lh $a3, 0($at)\n"
1100      "lui $at, 0xFFFE\n"
1101      "ori $at, $at, 0x8010\n"
1102      "addu $at, $at, $a1\n"
1103      "lh $a3, 7($at)\n"
1104      "lui $at, 0x1\n"
1105      "ori $at, $at, 0x7FE8\n"
1106      "addu $at, $at, $a1\n"
1107      "lh $a3, 1($at)\n"
1108      "lui $at, 0x1\n"
1109      "ori $at, $at, 0x7FF0\n"
1110      "addu $at, $at, $a1\n"
1111      "lh $a3, 0($at)\n"
1112      "lui $at, 0x1234\n"
1113      "ori $at, $at, 0x5678\n"
1114      "addu $at, $at, $a1\n"
1115      "lh $a3, 0($at)\n"
1116
1117      "lhu $a3, -0x8000($a1)\n"
1118      "lhu $a3, 0($a1)\n"
1119      "lhu $a3, 0x7FF8($a1)\n"
1120      "lhu $a3, 0x7FFB($a1)\n"
1121      "lhu $a3, 0x7FFC($a1)\n"
1122      "lhu $a3, 0x7FFF($a1)\n"
1123      "addiu $at, $a1, -0x7FF8\n"
1124      "lhu $a3, -0x7FF8($at)\n"
1125      "addiu $at, $a1, -0x7FF8\n"
1126      "lhu $a3, -0x10($at)\n"
1127      "addiu $at, $a1, -0x7FF8\n"
1128      "lhu $a3, -9($at)\n"
1129      "addiu $at, $a1, 0x7FF8\n"
1130      "lhu $a3, 8($at)\n"
1131      "addiu $at, $a1, 0x7FF8\n"
1132      "lhu $a3, 0x7FF8($at)\n"
1133      "addiu $at, $a1, -0x7FF8\n"
1134      "addiu $at, $at, -0x7FF8\n"
1135      "lhu $a3, -0x7FF8($at)\n"
1136      "addiu $at, $a1, -0x7FF8\n"
1137      "addiu $at, $at, -0x7FF8\n"
1138      "lhu $a3, -8($at)\n"
1139      "addiu $at, $a1, -0x7FF8\n"
1140      "addiu $at, $at, -0x7FF8\n"
1141      "lhu $a3, -1($at)\n"
1142      "addiu $at, $a1, 0x7FF8\n"
1143      "addiu $at, $at, 0x7FF8\n"
1144      "lhu $a3, 1($at)\n"
1145      "addiu $at, $a1, 0x7FF8\n"
1146      "addiu $at, $at, 0x7FF8\n"
1147      "lhu $a3, 8($at)\n"
1148      "addiu $at, $a1, 0x7FF8\n"
1149      "addiu $at, $at, 0x7FF8\n"
1150      "lhu $a3, 0x7FF8($at)\n"
1151      "lui $at, 0xFFFE\n"
1152      "ori $at, $at, 0x8010\n"
1153      "addu $at, $at, $a1\n"
1154      "lhu $a3, 0($at)\n"
1155      "lui $at, 0xFFFE\n"
1156      "ori $at, $at, 0x8010\n"
1157      "addu $at, $at, $a1\n"
1158      "lhu $a3, 7($at)\n"
1159      "lui $at, 0x1\n"
1160      "ori $at, $at, 0x7FE8\n"
1161      "addu $at, $at, $a1\n"
1162      "lhu $a3, 1($at)\n"
1163      "lui $at, 0x1\n"
1164      "ori $at, $at, 0x7FF0\n"
1165      "addu $at, $at, $a1\n"
1166      "lhu $a3, 0($at)\n"
1167      "lui $at, 0x1234\n"
1168      "ori $at, $at, 0x5678\n"
1169      "addu $at, $at, $a1\n"
1170      "lhu $a3, 0($at)\n"
1171
1172      "lw $a3, -0x8000($a1)\n"
1173      "lw $a3, 0($a1)\n"
1174      "lw $a3, 0x7FF8($a1)\n"
1175      "lw $a3, 0x7FFB($a1)\n"
1176      "lw $a3, 0x7FFC($a1)\n"
1177      "lw $a3, 0x7FFF($a1)\n"
1178      "addiu $at, $a1, -0x7FF8\n"
1179      "lw $a3, -0x7FF8($at)\n"
1180      "addiu $at, $a1, -0x7FF8\n"
1181      "lw $a3, -0x10($at)\n"
1182      "addiu $at, $a1, -0x7FF8\n"
1183      "lw $a3, -9($at)\n"
1184      "addiu $at, $a1, 0x7FF8\n"
1185      "lw $a3, 8($at)\n"
1186      "addiu $at, $a1, 0x7FF8\n"
1187      "lw $a3, 0x7FF8($at)\n"
1188      "addiu $at, $a1, -0x7FF8\n"
1189      "addiu $at, $at, -0x7FF8\n"
1190      "lw $a3, -0x7FF8($at)\n"
1191      "addiu $at, $a1, -0x7FF8\n"
1192      "addiu $at, $at, -0x7FF8\n"
1193      "lw $a3, -8($at)\n"
1194      "addiu $at, $a1, -0x7FF8\n"
1195      "addiu $at, $at, -0x7FF8\n"
1196      "lw $a3, -1($at)\n"
1197      "addiu $at, $a1, 0x7FF8\n"
1198      "addiu $at, $at, 0x7FF8\n"
1199      "lw $a3, 1($at)\n"
1200      "addiu $at, $a1, 0x7FF8\n"
1201      "addiu $at, $at, 0x7FF8\n"
1202      "lw $a3, 8($at)\n"
1203      "addiu $at, $a1, 0x7FF8\n"
1204      "addiu $at, $at, 0x7FF8\n"
1205      "lw $a3, 0x7FF8($at)\n"
1206      "lui $at, 0xFFFE\n"
1207      "ori $at, $at, 0x8010\n"
1208      "addu $at, $at, $a1\n"
1209      "lw $a3, 0($at)\n"
1210      "lui $at, 0xFFFE\n"
1211      "ori $at, $at, 0x8010\n"
1212      "addu $at, $at, $a1\n"
1213      "lw $a3, 7($at)\n"
1214      "lui $at, 0x1\n"
1215      "ori $at, $at, 0x7FE8\n"
1216      "addu $at, $at, $a1\n"
1217      "lw $a3, 1($at)\n"
1218      "lui $at, 0x1\n"
1219      "ori $at, $at, 0x7FF0\n"
1220      "addu $at, $at, $a1\n"
1221      "lw $a3, 0($at)\n"
1222      "lui $at, 0x1234\n"
1223      "ori $at, $at, 0x5678\n"
1224      "addu $at, $at, $a1\n"
1225      "lw $a3, 0($at)\n"
1226
1227      "lw $a0, -0x8000($a2)\n"
1228      "lw $a1, -0x7FFC($a2)\n"
1229      "lw $a0, 0($a2)\n"
1230      "lw $a1, 4($a2)\n"
1231      "lw $a0, 0x7FF8($a2)\n"
1232      "lw $a1, 0x7FFC($a2)\n"
1233      "lw $a0, 0x7FFB($a2)\n"
1234      "lw $a1, 0x7FFF($a2)\n"
1235      "addiu $at, $a2, 0x7FF8\n"
1236      "lw $a0, 4($at)\n"
1237      "lw $a1, 8($at)\n"
1238      "addiu $at, $a2, 0x7FF8\n"
1239      "lw $a0, 7($at)\n"
1240      "lw $a1, 11($at)\n"
1241      "addiu $at, $a2, -0x7FF8\n"
1242      "lw $a0, -0x7FF8($at)\n"
1243      "lw $a1, -0x7FF4($at)\n"
1244      "addiu $at, $a2, -0x7FF8\n"
1245      "lw $a0, -0x10($at)\n"
1246      "lw $a1, -0xC($at)\n"
1247      "addiu $at, $a2, -0x7FF8\n"
1248      "lw $a0, -9($at)\n"
1249      "lw $a1, -5($at)\n"
1250      "addiu $at, $a2, 0x7FF8\n"
1251      "lw $a0, 8($at)\n"
1252      "lw $a1, 12($at)\n"
1253      "addiu $at, $a2, 0x7FF8\n"
1254      "lw $a0, 0x7FF8($at)\n"
1255      "lw $a1, 0x7FFC($at)\n"
1256      "addiu $at, $a2, -0x7FF8\n"
1257      "addiu $at, $at, -0x7FF8\n"
1258      "lw $a0, -0x7FF8($at)\n"
1259      "lw $a1, -0x7FF4($at)\n"
1260      "addiu $at, $a2, -0x7FF8\n"
1261      "addiu $at, $at, -0x7FF8\n"
1262      "lw $a0, -8($at)\n"
1263      "lw $a1, -4($at)\n"
1264      "addiu $at, $a2, -0x7FF8\n"
1265      "addiu $at, $at, -0x7FF8\n"
1266      "lw $a0, -1($at)\n"
1267      "lw $a1, 3($at)\n"
1268      "addiu $at, $a2, 0x7FF8\n"
1269      "addiu $at, $at, 0x7FF8\n"
1270      "lw $a0, 1($at)\n"
1271      "lw $a1, 5($at)\n"
1272      "addiu $at, $a2, 0x7FF8\n"
1273      "addiu $at, $at, 0x7FF8\n"
1274      "lw $a0, 8($at)\n"
1275      "lw $a1, 12($at)\n"
1276      "addiu $at, $a2, 0x7FF8\n"
1277      "addiu $at, $at, 0x7FF8\n"
1278      "lw $a0, 0x7FF8($at)\n"
1279      "lw $a1, 0x7FFC($at)\n"
1280      "lui $at, 0xFFFE\n"
1281      "ori $at, $at, 0x8010\n"
1282      "addu $at, $at, $a2\n"
1283      "lw $a0, 0($at)\n"
1284      "lw $a1, 4($at)\n"
1285      "lui $at, 0xFFFE\n"
1286      "ori $at, $at, 0x8010\n"
1287      "addu $at, $at, $a2\n"
1288      "lw $a0, 7($at)\n"
1289      "lw $a1, 11($at)\n"
1290      "lui $at, 0x1\n"
1291      "ori $at, $at, 0x7FE8\n"
1292      "addu $at, $at, $a2\n"
1293      "lw $a0, 1($at)\n"
1294      "lw $a1, 5($at)\n"
1295      "lui $at, 0x1\n"
1296      "ori $at, $at, 0x7FF0\n"
1297      "addu $at, $at, $a2\n"
1298      "lw $a0, 0($at)\n"
1299      "lw $a1, 4($at)\n"
1300      "lui $at, 0x1234\n"
1301      "ori $at, $at, 0x5678\n"
1302      "addu $at, $at, $a2\n"
1303      "lw $a0, 0($at)\n"
1304      "lw $a1, 4($at)\n";
1305  DriverStr(expected, "LoadFromOffset");
1306}
1307
1308TEST_F(AssemblerMIPSTest, LoadSFromOffset) {
1309  __ LoadSFromOffset(mips::F2, mips::A0, -0x8000);
1310  __ LoadSFromOffset(mips::F2, mips::A0, +0);
1311  __ LoadSFromOffset(mips::F2, mips::A0, +0x7FF8);
1312  __ LoadSFromOffset(mips::F2, mips::A0, +0x7FFB);
1313  __ LoadSFromOffset(mips::F2, mips::A0, +0x7FFC);
1314  __ LoadSFromOffset(mips::F2, mips::A0, +0x7FFF);
1315  __ LoadSFromOffset(mips::F2, mips::A0, -0xFFF0);
1316  __ LoadSFromOffset(mips::F2, mips::A0, -0x8008);
1317  __ LoadSFromOffset(mips::F2, mips::A0, -0x8001);
1318  __ LoadSFromOffset(mips::F2, mips::A0, +0x8000);
1319  __ LoadSFromOffset(mips::F2, mips::A0, +0xFFF0);
1320  __ LoadSFromOffset(mips::F2, mips::A0, -0x17FE8);
1321  __ LoadSFromOffset(mips::F2, mips::A0, -0x0FFF8);
1322  __ LoadSFromOffset(mips::F2, mips::A0, -0x0FFF1);
1323  __ LoadSFromOffset(mips::F2, mips::A0, +0x0FFF1);
1324  __ LoadSFromOffset(mips::F2, mips::A0, +0x0FFF8);
1325  __ LoadSFromOffset(mips::F2, mips::A0, +0x17FE8);
1326  __ LoadSFromOffset(mips::F2, mips::A0, -0x17FF0);
1327  __ LoadSFromOffset(mips::F2, mips::A0, -0x17FE9);
1328  __ LoadSFromOffset(mips::F2, mips::A0, +0x17FE9);
1329  __ LoadSFromOffset(mips::F2, mips::A0, +0x17FF0);
1330  __ LoadSFromOffset(mips::F2, mips::A0, +0x12345678);
1331
1332  const char* expected =
1333      "lwc1 $f2, -0x8000($a0)\n"
1334      "lwc1 $f2, 0($a0)\n"
1335      "lwc1 $f2, 0x7FF8($a0)\n"
1336      "lwc1 $f2, 0x7FFB($a0)\n"
1337      "lwc1 $f2, 0x7FFC($a0)\n"
1338      "lwc1 $f2, 0x7FFF($a0)\n"
1339      "addiu $at, $a0, -0x7FF8\n"
1340      "lwc1 $f2, -0x7FF8($at)\n"
1341      "addiu $at, $a0, -0x7FF8\n"
1342      "lwc1 $f2, -0x10($at)\n"
1343      "addiu $at, $a0, -0x7FF8\n"
1344      "lwc1 $f2, -9($at)\n"
1345      "addiu $at, $a0, 0x7FF8\n"
1346      "lwc1 $f2, 8($at)\n"
1347      "addiu $at, $a0, 0x7FF8\n"
1348      "lwc1 $f2, 0x7FF8($at)\n"
1349      "addiu $at, $a0, -0x7FF8\n"
1350      "addiu $at, $at, -0x7FF8\n"
1351      "lwc1 $f2, -0x7FF8($at)\n"
1352      "addiu $at, $a0, -0x7FF8\n"
1353      "addiu $at, $at, -0x7FF8\n"
1354      "lwc1 $f2, -8($at)\n"
1355      "addiu $at, $a0, -0x7FF8\n"
1356      "addiu $at, $at, -0x7FF8\n"
1357      "lwc1 $f2, -1($at)\n"
1358      "addiu $at, $a0, 0x7FF8\n"
1359      "addiu $at, $at, 0x7FF8\n"
1360      "lwc1 $f2, 1($at)\n"
1361      "addiu $at, $a0, 0x7FF8\n"
1362      "addiu $at, $at, 0x7FF8\n"
1363      "lwc1 $f2, 8($at)\n"
1364      "addiu $at, $a0, 0x7FF8\n"
1365      "addiu $at, $at, 0x7FF8\n"
1366      "lwc1 $f2, 0x7FF8($at)\n"
1367      "lui $at, 0xFFFE\n"
1368      "ori $at, $at, 0x8010\n"
1369      "addu $at, $at, $a0\n"
1370      "lwc1 $f2, 0($at)\n"
1371      "lui $at, 0xFFFE\n"
1372      "ori $at, $at, 0x8010\n"
1373      "addu $at, $at, $a0\n"
1374      "lwc1 $f2, 7($at)\n"
1375      "lui $at, 0x1\n"
1376      "ori $at, $at, 0x7FE8\n"
1377      "addu $at, $at, $a0\n"
1378      "lwc1 $f2, 1($at)\n"
1379      "lui $at, 0x1\n"
1380      "ori $at, $at, 0x7FF0\n"
1381      "addu $at, $at, $a0\n"
1382      "lwc1 $f2, 0($at)\n"
1383      "lui $at, 0x1234\n"
1384      "ori $at, $at, 0x5678\n"
1385      "addu $at, $at, $a0\n"
1386      "lwc1 $f2, 0($at)\n";
1387  DriverStr(expected, "LoadSFromOffset");
1388}
1389
1390TEST_F(AssemblerMIPSTest, LoadDFromOffset) {
1391  __ LoadDFromOffset(mips::F0, mips::A0, -0x8000);
1392  __ LoadDFromOffset(mips::F0, mips::A0, +0);
1393  __ LoadDFromOffset(mips::F0, mips::A0, +0x7FF8);
1394  __ LoadDFromOffset(mips::F0, mips::A0, +0x7FFB);
1395  __ LoadDFromOffset(mips::F0, mips::A0, +0x7FFC);
1396  __ LoadDFromOffset(mips::F0, mips::A0, +0x7FFF);
1397  __ LoadDFromOffset(mips::F0, mips::A0, -0xFFF0);
1398  __ LoadDFromOffset(mips::F0, mips::A0, -0x8008);
1399  __ LoadDFromOffset(mips::F0, mips::A0, -0x8001);
1400  __ LoadDFromOffset(mips::F0, mips::A0, +0x8000);
1401  __ LoadDFromOffset(mips::F0, mips::A0, +0xFFF0);
1402  __ LoadDFromOffset(mips::F0, mips::A0, -0x17FE8);
1403  __ LoadDFromOffset(mips::F0, mips::A0, -0x0FFF8);
1404  __ LoadDFromOffset(mips::F0, mips::A0, -0x0FFF1);
1405  __ LoadDFromOffset(mips::F0, mips::A0, +0x0FFF1);
1406  __ LoadDFromOffset(mips::F0, mips::A0, +0x0FFF8);
1407  __ LoadDFromOffset(mips::F0, mips::A0, +0x17FE8);
1408  __ LoadDFromOffset(mips::F0, mips::A0, -0x17FF0);
1409  __ LoadDFromOffset(mips::F0, mips::A0, -0x17FE9);
1410  __ LoadDFromOffset(mips::F0, mips::A0, +0x17FE9);
1411  __ LoadDFromOffset(mips::F0, mips::A0, +0x17FF0);
1412  __ LoadDFromOffset(mips::F0, mips::A0, +0x12345678);
1413
1414  const char* expected =
1415      "ldc1 $f0, -0x8000($a0)\n"
1416      "ldc1 $f0, 0($a0)\n"
1417      "ldc1 $f0, 0x7FF8($a0)\n"
1418      "lwc1 $f0, 0x7FFB($a0)\n"
1419      "lwc1 $f1, 0x7FFF($a0)\n"
1420      "addiu $at, $a0, 0x7FF8\n"
1421      "lwc1 $f0, 4($at)\n"
1422      "lwc1 $f1, 8($at)\n"
1423      "addiu $at, $a0, 0x7FF8\n"
1424      "lwc1 $f0, 7($at)\n"
1425      "lwc1 $f1, 11($at)\n"
1426      "addiu $at, $a0, -0x7FF8\n"
1427      "ldc1 $f0, -0x7FF8($at)\n"
1428      "addiu $at, $a0, -0x7FF8\n"
1429      "ldc1 $f0, -0x10($at)\n"
1430      "addiu $at, $a0, -0x7FF8\n"
1431      "lwc1 $f0, -9($at)\n"
1432      "lwc1 $f1, -5($at)\n"
1433      "addiu $at, $a0, 0x7FF8\n"
1434      "ldc1 $f0, 8($at)\n"
1435      "addiu $at, $a0, 0x7FF8\n"
1436      "ldc1 $f0, 0x7FF8($at)\n"
1437      "addiu $at, $a0, -0x7FF8\n"
1438      "addiu $at, $at, -0x7FF8\n"
1439      "ldc1 $f0, -0x7FF8($at)\n"
1440      "addiu $at, $a0, -0x7FF8\n"
1441      "addiu $at, $at, -0x7FF8\n"
1442      "ldc1 $f0, -8($at)\n"
1443      "addiu $at, $a0, -0x7FF8\n"
1444      "addiu $at, $at, -0x7FF8\n"
1445      "lwc1 $f0, -1($at)\n"
1446      "lwc1 $f1, 3($at)\n"
1447      "addiu $at, $a0, 0x7FF8\n"
1448      "addiu $at, $at, 0x7FF8\n"
1449      "lwc1 $f0, 1($at)\n"
1450      "lwc1 $f1, 5($at)\n"
1451      "addiu $at, $a0, 0x7FF8\n"
1452      "addiu $at, $at, 0x7FF8\n"
1453      "ldc1 $f0, 8($at)\n"
1454      "addiu $at, $a0, 0x7FF8\n"
1455      "addiu $at, $at, 0x7FF8\n"
1456      "ldc1 $f0, 0x7FF8($at)\n"
1457      "lui $at, 0xFFFE\n"
1458      "ori $at, $at, 0x8010\n"
1459      "addu $at, $at, $a0\n"
1460      "ldc1 $f0, 0($at)\n"
1461      "lui $at, 0xFFFE\n"
1462      "ori $at, $at, 0x8010\n"
1463      "addu $at, $at, $a0\n"
1464      "lwc1 $f0, 7($at)\n"
1465      "lwc1 $f1, 11($at)\n"
1466      "lui $at, 0x1\n"
1467      "ori $at, $at, 0x7FE8\n"
1468      "addu $at, $at, $a0\n"
1469      "lwc1 $f0, 1($at)\n"
1470      "lwc1 $f1, 5($at)\n"
1471      "lui $at, 0x1\n"
1472      "ori $at, $at, 0x7FF0\n"
1473      "addu $at, $at, $a0\n"
1474      "ldc1 $f0, 0($at)\n"
1475      "lui $at, 0x1234\n"
1476      "ori $at, $at, 0x5678\n"
1477      "addu $at, $at, $a0\n"
1478      "ldc1 $f0, 0($at)\n";
1479  DriverStr(expected, "LoadDFromOffset");
1480}
1481
1482TEST_F(AssemblerMIPSTest, StoreToOffset) {
1483  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, -0x8000);
1484  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0);
1485  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0x7FF8);
1486  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0x7FFB);
1487  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0x7FFC);
1488  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0x7FFF);
1489  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, -0xFFF0);
1490  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, -0x8008);
1491  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, -0x8001);
1492  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0x8000);
1493  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0xFFF0);
1494  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, -0x17FE8);
1495  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, -0x0FFF8);
1496  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, -0x0FFF1);
1497  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0x0FFF1);
1498  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0x0FFF8);
1499  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0x17FE8);
1500  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, -0x17FF0);
1501  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, -0x17FE9);
1502  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0x17FE9);
1503  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0x17FF0);
1504  __ StoreToOffset(mips::kStoreByte, mips::A3, mips::A1, +0x12345678);
1505
1506  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, -0x8000);
1507  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0);
1508  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0x7FF8);
1509  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0x7FFB);
1510  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0x7FFC);
1511  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0x7FFF);
1512  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, -0xFFF0);
1513  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, -0x8008);
1514  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, -0x8001);
1515  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0x8000);
1516  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0xFFF0);
1517  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, -0x17FE8);
1518  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, -0x0FFF8);
1519  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, -0x0FFF1);
1520  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0x0FFF1);
1521  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0x0FFF8);
1522  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0x17FE8);
1523  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, -0x17FF0);
1524  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, -0x17FE9);
1525  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0x17FE9);
1526  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0x17FF0);
1527  __ StoreToOffset(mips::kStoreHalfword, mips::A3, mips::A1, +0x12345678);
1528
1529  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, -0x8000);
1530  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0);
1531  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0x7FF8);
1532  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0x7FFB);
1533  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0x7FFC);
1534  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0x7FFF);
1535  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, -0xFFF0);
1536  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, -0x8008);
1537  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, -0x8001);
1538  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0x8000);
1539  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0xFFF0);
1540  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, -0x17FE8);
1541  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, -0x0FFF8);
1542  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, -0x0FFF1);
1543  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0x0FFF1);
1544  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0x0FFF8);
1545  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0x17FE8);
1546  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, -0x17FF0);
1547  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, -0x17FE9);
1548  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0x17FE9);
1549  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0x17FF0);
1550  __ StoreToOffset(mips::kStoreWord, mips::A3, mips::A1, +0x12345678);
1551
1552  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, -0x8000);
1553  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0);
1554  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0x7FF8);
1555  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0x7FFB);
1556  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0x7FFC);
1557  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0x7FFF);
1558  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, -0xFFF0);
1559  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, -0x8008);
1560  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, -0x8001);
1561  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0x8000);
1562  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0xFFF0);
1563  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, -0x17FE8);
1564  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, -0x0FFF8);
1565  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, -0x0FFF1);
1566  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0x0FFF1);
1567  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0x0FFF8);
1568  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0x17FE8);
1569  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, -0x17FF0);
1570  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, -0x17FE9);
1571  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0x17FE9);
1572  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0x17FF0);
1573  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, +0x12345678);
1574
1575  const char* expected =
1576      "sb $a3, -0x8000($a1)\n"
1577      "sb $a3, 0($a1)\n"
1578      "sb $a3, 0x7FF8($a1)\n"
1579      "sb $a3, 0x7FFB($a1)\n"
1580      "sb $a3, 0x7FFC($a1)\n"
1581      "sb $a3, 0x7FFF($a1)\n"
1582      "addiu $at, $a1, -0x7FF8\n"
1583      "sb $a3, -0x7FF8($at)\n"
1584      "addiu $at, $a1, -0x7FF8\n"
1585      "sb $a3, -0x10($at)\n"
1586      "addiu $at, $a1, -0x7FF8\n"
1587      "sb $a3, -9($at)\n"
1588      "addiu $at, $a1, 0x7FF8\n"
1589      "sb $a3, 8($at)\n"
1590      "addiu $at, $a1, 0x7FF8\n"
1591      "sb $a3, 0x7FF8($at)\n"
1592      "addiu $at, $a1, -0x7FF8\n"
1593      "addiu $at, $at, -0x7FF8\n"
1594      "sb $a3, -0x7FF8($at)\n"
1595      "addiu $at, $a1, -0x7FF8\n"
1596      "addiu $at, $at, -0x7FF8\n"
1597      "sb $a3, -8($at)\n"
1598      "addiu $at, $a1, -0x7FF8\n"
1599      "addiu $at, $at, -0x7FF8\n"
1600      "sb $a3, -1($at)\n"
1601      "addiu $at, $a1, 0x7FF8\n"
1602      "addiu $at, $at, 0x7FF8\n"
1603      "sb $a3, 1($at)\n"
1604      "addiu $at, $a1, 0x7FF8\n"
1605      "addiu $at, $at, 0x7FF8\n"
1606      "sb $a3, 8($at)\n"
1607      "addiu $at, $a1, 0x7FF8\n"
1608      "addiu $at, $at, 0x7FF8\n"
1609      "sb $a3, 0x7FF8($at)\n"
1610      "lui $at, 0xFFFE\n"
1611      "ori $at, $at, 0x8010\n"
1612      "addu $at, $at, $a1\n"
1613      "sb $a3, 0($at)\n"
1614      "lui $at, 0xFFFE\n"
1615      "ori $at, $at, 0x8010\n"
1616      "addu $at, $at, $a1\n"
1617      "sb $a3, 7($at)\n"
1618      "lui $at, 0x1\n"
1619      "ori $at, $at, 0x7FE8\n"
1620      "addu $at, $at, $a1\n"
1621      "sb $a3, 1($at)\n"
1622      "lui $at, 0x1\n"
1623      "ori $at, $at, 0x7FF0\n"
1624      "addu $at, $at, $a1\n"
1625      "sb $a3, 0($at)\n"
1626      "lui $at, 0x1234\n"
1627      "ori $at, $at, 0x5678\n"
1628      "addu $at, $at, $a1\n"
1629      "sb $a3, 0($at)\n"
1630
1631      "sh $a3, -0x8000($a1)\n"
1632      "sh $a3, 0($a1)\n"
1633      "sh $a3, 0x7FF8($a1)\n"
1634      "sh $a3, 0x7FFB($a1)\n"
1635      "sh $a3, 0x7FFC($a1)\n"
1636      "sh $a3, 0x7FFF($a1)\n"
1637      "addiu $at, $a1, -0x7FF8\n"
1638      "sh $a3, -0x7FF8($at)\n"
1639      "addiu $at, $a1, -0x7FF8\n"
1640      "sh $a3, -0x10($at)\n"
1641      "addiu $at, $a1, -0x7FF8\n"
1642      "sh $a3, -9($at)\n"
1643      "addiu $at, $a1, 0x7FF8\n"
1644      "sh $a3, 8($at)\n"
1645      "addiu $at, $a1, 0x7FF8\n"
1646      "sh $a3, 0x7FF8($at)\n"
1647      "addiu $at, $a1, -0x7FF8\n"
1648      "addiu $at, $at, -0x7FF8\n"
1649      "sh $a3, -0x7FF8($at)\n"
1650      "addiu $at, $a1, -0x7FF8\n"
1651      "addiu $at, $at, -0x7FF8\n"
1652      "sh $a3, -8($at)\n"
1653      "addiu $at, $a1, -0x7FF8\n"
1654      "addiu $at, $at, -0x7FF8\n"
1655      "sh $a3, -1($at)\n"
1656      "addiu $at, $a1, 0x7FF8\n"
1657      "addiu $at, $at, 0x7FF8\n"
1658      "sh $a3, 1($at)\n"
1659      "addiu $at, $a1, 0x7FF8\n"
1660      "addiu $at, $at, 0x7FF8\n"
1661      "sh $a3, 8($at)\n"
1662      "addiu $at, $a1, 0x7FF8\n"
1663      "addiu $at, $at, 0x7FF8\n"
1664      "sh $a3, 0x7FF8($at)\n"
1665      "lui $at, 0xFFFE\n"
1666      "ori $at, $at, 0x8010\n"
1667      "addu $at, $at, $a1\n"
1668      "sh $a3, 0($at)\n"
1669      "lui $at, 0xFFFE\n"
1670      "ori $at, $at, 0x8010\n"
1671      "addu $at, $at, $a1\n"
1672      "sh $a3, 7($at)\n"
1673      "lui $at, 0x1\n"
1674      "ori $at, $at, 0x7FE8\n"
1675      "addu $at, $at, $a1\n"
1676      "sh $a3, 1($at)\n"
1677      "lui $at, 0x1\n"
1678      "ori $at, $at, 0x7FF0\n"
1679      "addu $at, $at, $a1\n"
1680      "sh $a3, 0($at)\n"
1681      "lui $at, 0x1234\n"
1682      "ori $at, $at, 0x5678\n"
1683      "addu $at, $at, $a1\n"
1684      "sh $a3, 0($at)\n"
1685
1686      "sw $a3, -0x8000($a1)\n"
1687      "sw $a3, 0($a1)\n"
1688      "sw $a3, 0x7FF8($a1)\n"
1689      "sw $a3, 0x7FFB($a1)\n"
1690      "sw $a3, 0x7FFC($a1)\n"
1691      "sw $a3, 0x7FFF($a1)\n"
1692      "addiu $at, $a1, -0x7FF8\n"
1693      "sw $a3, -0x7FF8($at)\n"
1694      "addiu $at, $a1, -0x7FF8\n"
1695      "sw $a3, -0x10($at)\n"
1696      "addiu $at, $a1, -0x7FF8\n"
1697      "sw $a3, -9($at)\n"
1698      "addiu $at, $a1, 0x7FF8\n"
1699      "sw $a3, 8($at)\n"
1700      "addiu $at, $a1, 0x7FF8\n"
1701      "sw $a3, 0x7FF8($at)\n"
1702      "addiu $at, $a1, -0x7FF8\n"
1703      "addiu $at, $at, -0x7FF8\n"
1704      "sw $a3, -0x7FF8($at)\n"
1705      "addiu $at, $a1, -0x7FF8\n"
1706      "addiu $at, $at, -0x7FF8\n"
1707      "sw $a3, -8($at)\n"
1708      "addiu $at, $a1, -0x7FF8\n"
1709      "addiu $at, $at, -0x7FF8\n"
1710      "sw $a3, -1($at)\n"
1711      "addiu $at, $a1, 0x7FF8\n"
1712      "addiu $at, $at, 0x7FF8\n"
1713      "sw $a3, 1($at)\n"
1714      "addiu $at, $a1, 0x7FF8\n"
1715      "addiu $at, $at, 0x7FF8\n"
1716      "sw $a3, 8($at)\n"
1717      "addiu $at, $a1, 0x7FF8\n"
1718      "addiu $at, $at, 0x7FF8\n"
1719      "sw $a3, 0x7FF8($at)\n"
1720      "lui $at, 0xFFFE\n"
1721      "ori $at, $at, 0x8010\n"
1722      "addu $at, $at, $a1\n"
1723      "sw $a3, 0($at)\n"
1724      "lui $at, 0xFFFE\n"
1725      "ori $at, $at, 0x8010\n"
1726      "addu $at, $at, $a1\n"
1727      "sw $a3, 7($at)\n"
1728      "lui $at, 0x1\n"
1729      "ori $at, $at, 0x7FE8\n"
1730      "addu $at, $at, $a1\n"
1731      "sw $a3, 1($at)\n"
1732      "lui $at, 0x1\n"
1733      "ori $at, $at, 0x7FF0\n"
1734      "addu $at, $at, $a1\n"
1735      "sw $a3, 0($at)\n"
1736      "lui $at, 0x1234\n"
1737      "ori $at, $at, 0x5678\n"
1738      "addu $at, $at, $a1\n"
1739      "sw $a3, 0($at)\n"
1740
1741      "sw $a0, -0x8000($a2)\n"
1742      "sw $a1, -0x7FFC($a2)\n"
1743      "sw $a0, 0($a2)\n"
1744      "sw $a1, 4($a2)\n"
1745      "sw $a0, 0x7FF8($a2)\n"
1746      "sw $a1, 0x7FFC($a2)\n"
1747      "sw $a0, 0x7FFB($a2)\n"
1748      "sw $a1, 0x7FFF($a2)\n"
1749      "addiu $at, $a2, 0x7FF8\n"
1750      "sw $a0, 4($at)\n"
1751      "sw $a1, 8($at)\n"
1752      "addiu $at, $a2, 0x7FF8\n"
1753      "sw $a0, 7($at)\n"
1754      "sw $a1, 11($at)\n"
1755      "addiu $at, $a2, -0x7FF8\n"
1756      "sw $a0, -0x7FF8($at)\n"
1757      "sw $a1, -0x7FF4($at)\n"
1758      "addiu $at, $a2, -0x7FF8\n"
1759      "sw $a0, -0x10($at)\n"
1760      "sw $a1, -0xC($at)\n"
1761      "addiu $at, $a2, -0x7FF8\n"
1762      "sw $a0, -9($at)\n"
1763      "sw $a1, -5($at)\n"
1764      "addiu $at, $a2, 0x7FF8\n"
1765      "sw $a0, 8($at)\n"
1766      "sw $a1, 12($at)\n"
1767      "addiu $at, $a2, 0x7FF8\n"
1768      "sw $a0, 0x7FF8($at)\n"
1769      "sw $a1, 0x7FFC($at)\n"
1770      "addiu $at, $a2, -0x7FF8\n"
1771      "addiu $at, $at, -0x7FF8\n"
1772      "sw $a0, -0x7FF8($at)\n"
1773      "sw $a1, -0x7FF4($at)\n"
1774      "addiu $at, $a2, -0x7FF8\n"
1775      "addiu $at, $at, -0x7FF8\n"
1776      "sw $a0, -8($at)\n"
1777      "sw $a1, -4($at)\n"
1778      "addiu $at, $a2, -0x7FF8\n"
1779      "addiu $at, $at, -0x7FF8\n"
1780      "sw $a0, -1($at)\n"
1781      "sw $a1, 3($at)\n"
1782      "addiu $at, $a2, 0x7FF8\n"
1783      "addiu $at, $at, 0x7FF8\n"
1784      "sw $a0, 1($at)\n"
1785      "sw $a1, 5($at)\n"
1786      "addiu $at, $a2, 0x7FF8\n"
1787      "addiu $at, $at, 0x7FF8\n"
1788      "sw $a0, 8($at)\n"
1789      "sw $a1, 12($at)\n"
1790      "addiu $at, $a2, 0x7FF8\n"
1791      "addiu $at, $at, 0x7FF8\n"
1792      "sw $a0, 0x7FF8($at)\n"
1793      "sw $a1, 0x7FFC($at)\n"
1794      "lui $at, 0xFFFE\n"
1795      "ori $at, $at, 0x8010\n"
1796      "addu $at, $at, $a2\n"
1797      "sw $a0, 0($at)\n"
1798      "sw $a1, 4($at)\n"
1799      "lui $at, 0xFFFE\n"
1800      "ori $at, $at, 0x8010\n"
1801      "addu $at, $at, $a2\n"
1802      "sw $a0, 7($at)\n"
1803      "sw $a1, 11($at)\n"
1804      "lui $at, 0x1\n"
1805      "ori $at, $at, 0x7FE8\n"
1806      "addu $at, $at, $a2\n"
1807      "sw $a0, 1($at)\n"
1808      "sw $a1, 5($at)\n"
1809      "lui $at, 0x1\n"
1810      "ori $at, $at, 0x7FF0\n"
1811      "addu $at, $at, $a2\n"
1812      "sw $a0, 0($at)\n"
1813      "sw $a1, 4($at)\n"
1814      "lui $at, 0x1234\n"
1815      "ori $at, $at, 0x5678\n"
1816      "addu $at, $at, $a2\n"
1817      "sw $a0, 0($at)\n"
1818      "sw $a1, 4($at)\n";
1819  DriverStr(expected, "StoreToOffset");
1820}
1821
1822TEST_F(AssemblerMIPSTest, StoreSToOffset) {
1823  __ StoreSToOffset(mips::F2, mips::A0, -0x8000);
1824  __ StoreSToOffset(mips::F2, mips::A0, +0);
1825  __ StoreSToOffset(mips::F2, mips::A0, +0x7FF8);
1826  __ StoreSToOffset(mips::F2, mips::A0, +0x7FFB);
1827  __ StoreSToOffset(mips::F2, mips::A0, +0x7FFC);
1828  __ StoreSToOffset(mips::F2, mips::A0, +0x7FFF);
1829  __ StoreSToOffset(mips::F2, mips::A0, -0xFFF0);
1830  __ StoreSToOffset(mips::F2, mips::A0, -0x8008);
1831  __ StoreSToOffset(mips::F2, mips::A0, -0x8001);
1832  __ StoreSToOffset(mips::F2, mips::A0, +0x8000);
1833  __ StoreSToOffset(mips::F2, mips::A0, +0xFFF0);
1834  __ StoreSToOffset(mips::F2, mips::A0, -0x17FE8);
1835  __ StoreSToOffset(mips::F2, mips::A0, -0x0FFF8);
1836  __ StoreSToOffset(mips::F2, mips::A0, -0x0FFF1);
1837  __ StoreSToOffset(mips::F2, mips::A0, +0x0FFF1);
1838  __ StoreSToOffset(mips::F2, mips::A0, +0x0FFF8);
1839  __ StoreSToOffset(mips::F2, mips::A0, +0x17FE8);
1840  __ StoreSToOffset(mips::F2, mips::A0, -0x17FF0);
1841  __ StoreSToOffset(mips::F2, mips::A0, -0x17FE9);
1842  __ StoreSToOffset(mips::F2, mips::A0, +0x17FE9);
1843  __ StoreSToOffset(mips::F2, mips::A0, +0x17FF0);
1844  __ StoreSToOffset(mips::F2, mips::A0, +0x12345678);
1845
1846  const char* expected =
1847      "swc1 $f2, -0x8000($a0)\n"
1848      "swc1 $f2, 0($a0)\n"
1849      "swc1 $f2, 0x7FF8($a0)\n"
1850      "swc1 $f2, 0x7FFB($a0)\n"
1851      "swc1 $f2, 0x7FFC($a0)\n"
1852      "swc1 $f2, 0x7FFF($a0)\n"
1853      "addiu $at, $a0, -0x7FF8\n"
1854      "swc1 $f2, -0x7FF8($at)\n"
1855      "addiu $at, $a0, -0x7FF8\n"
1856      "swc1 $f2, -0x10($at)\n"
1857      "addiu $at, $a0, -0x7FF8\n"
1858      "swc1 $f2, -9($at)\n"
1859      "addiu $at, $a0, 0x7FF8\n"
1860      "swc1 $f2, 8($at)\n"
1861      "addiu $at, $a0, 0x7FF8\n"
1862      "swc1 $f2, 0x7FF8($at)\n"
1863      "addiu $at, $a0, -0x7FF8\n"
1864      "addiu $at, $at, -0x7FF8\n"
1865      "swc1 $f2, -0x7FF8($at)\n"
1866      "addiu $at, $a0, -0x7FF8\n"
1867      "addiu $at, $at, -0x7FF8\n"
1868      "swc1 $f2, -8($at)\n"
1869      "addiu $at, $a0, -0x7FF8\n"
1870      "addiu $at, $at, -0x7FF8\n"
1871      "swc1 $f2, -1($at)\n"
1872      "addiu $at, $a0, 0x7FF8\n"
1873      "addiu $at, $at, 0x7FF8\n"
1874      "swc1 $f2, 1($at)\n"
1875      "addiu $at, $a0, 0x7FF8\n"
1876      "addiu $at, $at, 0x7FF8\n"
1877      "swc1 $f2, 8($at)\n"
1878      "addiu $at, $a0, 0x7FF8\n"
1879      "addiu $at, $at, 0x7FF8\n"
1880      "swc1 $f2, 0x7FF8($at)\n"
1881      "lui $at, 0xFFFE\n"
1882      "ori $at, $at, 0x8010\n"
1883      "addu $at, $at, $a0\n"
1884      "swc1 $f2, 0($at)\n"
1885      "lui $at, 0xFFFE\n"
1886      "ori $at, $at, 0x8010\n"
1887      "addu $at, $at, $a0\n"
1888      "swc1 $f2, 7($at)\n"
1889      "lui $at, 0x1\n"
1890      "ori $at, $at, 0x7FE8\n"
1891      "addu $at, $at, $a0\n"
1892      "swc1 $f2, 1($at)\n"
1893      "lui $at, 0x1\n"
1894      "ori $at, $at, 0x7FF0\n"
1895      "addu $at, $at, $a0\n"
1896      "swc1 $f2, 0($at)\n"
1897      "lui $at, 0x1234\n"
1898      "ori $at, $at, 0x5678\n"
1899      "addu $at, $at, $a0\n"
1900      "swc1 $f2, 0($at)\n";
1901  DriverStr(expected, "StoreSToOffset");
1902}
1903
1904TEST_F(AssemblerMIPSTest, StoreDToOffset) {
1905  __ StoreDToOffset(mips::F0, mips::A0, -0x8000);
1906  __ StoreDToOffset(mips::F0, mips::A0, +0);
1907  __ StoreDToOffset(mips::F0, mips::A0, +0x7FF8);
1908  __ StoreDToOffset(mips::F0, mips::A0, +0x7FFB);
1909  __ StoreDToOffset(mips::F0, mips::A0, +0x7FFC);
1910  __ StoreDToOffset(mips::F0, mips::A0, +0x7FFF);
1911  __ StoreDToOffset(mips::F0, mips::A0, -0xFFF0);
1912  __ StoreDToOffset(mips::F0, mips::A0, -0x8008);
1913  __ StoreDToOffset(mips::F0, mips::A0, -0x8001);
1914  __ StoreDToOffset(mips::F0, mips::A0, +0x8000);
1915  __ StoreDToOffset(mips::F0, mips::A0, +0xFFF0);
1916  __ StoreDToOffset(mips::F0, mips::A0, -0x17FE8);
1917  __ StoreDToOffset(mips::F0, mips::A0, -0x0FFF8);
1918  __ StoreDToOffset(mips::F0, mips::A0, -0x0FFF1);
1919  __ StoreDToOffset(mips::F0, mips::A0, +0x0FFF1);
1920  __ StoreDToOffset(mips::F0, mips::A0, +0x0FFF8);
1921  __ StoreDToOffset(mips::F0, mips::A0, +0x17FE8);
1922  __ StoreDToOffset(mips::F0, mips::A0, -0x17FF0);
1923  __ StoreDToOffset(mips::F0, mips::A0, -0x17FE9);
1924  __ StoreDToOffset(mips::F0, mips::A0, +0x17FE9);
1925  __ StoreDToOffset(mips::F0, mips::A0, +0x17FF0);
1926  __ StoreDToOffset(mips::F0, mips::A0, +0x12345678);
1927
1928  const char* expected =
1929      "sdc1 $f0, -0x8000($a0)\n"
1930      "sdc1 $f0, 0($a0)\n"
1931      "sdc1 $f0, 0x7FF8($a0)\n"
1932      "swc1 $f0, 0x7FFB($a0)\n"
1933      "swc1 $f1, 0x7FFF($a0)\n"
1934      "addiu $at, $a0, 0x7FF8\n"
1935      "swc1 $f0, 4($at)\n"
1936      "swc1 $f1, 8($at)\n"
1937      "addiu $at, $a0, 0x7FF8\n"
1938      "swc1 $f0, 7($at)\n"
1939      "swc1 $f1, 11($at)\n"
1940      "addiu $at, $a0, -0x7FF8\n"
1941      "sdc1 $f0, -0x7FF8($at)\n"
1942      "addiu $at, $a0, -0x7FF8\n"
1943      "sdc1 $f0, -0x10($at)\n"
1944      "addiu $at, $a0, -0x7FF8\n"
1945      "swc1 $f0, -9($at)\n"
1946      "swc1 $f1, -5($at)\n"
1947      "addiu $at, $a0, 0x7FF8\n"
1948      "sdc1 $f0, 8($at)\n"
1949      "addiu $at, $a0, 0x7FF8\n"
1950      "sdc1 $f0, 0x7FF8($at)\n"
1951      "addiu $at, $a0, -0x7FF8\n"
1952      "addiu $at, $at, -0x7FF8\n"
1953      "sdc1 $f0, -0x7FF8($at)\n"
1954      "addiu $at, $a0, -0x7FF8\n"
1955      "addiu $at, $at, -0x7FF8\n"
1956      "sdc1 $f0, -8($at)\n"
1957      "addiu $at, $a0, -0x7FF8\n"
1958      "addiu $at, $at, -0x7FF8\n"
1959      "swc1 $f0, -1($at)\n"
1960      "swc1 $f1, 3($at)\n"
1961      "addiu $at, $a0, 0x7FF8\n"
1962      "addiu $at, $at, 0x7FF8\n"
1963      "swc1 $f0, 1($at)\n"
1964      "swc1 $f1, 5($at)\n"
1965      "addiu $at, $a0, 0x7FF8\n"
1966      "addiu $at, $at, 0x7FF8\n"
1967      "sdc1 $f0, 8($at)\n"
1968      "addiu $at, $a0, 0x7FF8\n"
1969      "addiu $at, $at, 0x7FF8\n"
1970      "sdc1 $f0, 0x7FF8($at)\n"
1971      "lui $at, 0xFFFE\n"
1972      "ori $at, $at, 0x8010\n"
1973      "addu $at, $at, $a0\n"
1974      "sdc1 $f0, 0($at)\n"
1975      "lui $at, 0xFFFE\n"
1976      "ori $at, $at, 0x8010\n"
1977      "addu $at, $at, $a0\n"
1978      "swc1 $f0, 7($at)\n"
1979      "swc1 $f1, 11($at)\n"
1980      "lui $at, 0x1\n"
1981      "ori $at, $at, 0x7FE8\n"
1982      "addu $at, $at, $a0\n"
1983      "swc1 $f0, 1($at)\n"
1984      "swc1 $f1, 5($at)\n"
1985      "lui $at, 0x1\n"
1986      "ori $at, $at, 0x7FF0\n"
1987      "addu $at, $at, $a0\n"
1988      "sdc1 $f0, 0($at)\n"
1989      "lui $at, 0x1234\n"
1990      "ori $at, $at, 0x5678\n"
1991      "addu $at, $at, $a0\n"
1992      "sdc1 $f0, 0($at)\n";
1993  DriverStr(expected, "StoreDToOffset");
1994}
1995
1996TEST_F(AssemblerMIPSTest, StoreConstToOffset) {
1997  __ StoreConstToOffset(mips::kStoreByte, 0xFF, mips::A1, +0, mips::T8);
1998  __ StoreConstToOffset(mips::kStoreHalfword, 0xFFFF, mips::A1, +0, mips::T8);
1999  __ StoreConstToOffset(mips::kStoreWord, 0x12345678, mips::A1, +0, mips::T8);
2000  __ StoreConstToOffset(mips::kStoreDoubleword, 0x123456789ABCDEF0, mips::A1, +0, mips::T8);
2001
2002  __ StoreConstToOffset(mips::kStoreByte, 0, mips::A1, +0, mips::T8);
2003  __ StoreConstToOffset(mips::kStoreHalfword, 0, mips::A1, +0, mips::T8);
2004  __ StoreConstToOffset(mips::kStoreWord, 0, mips::A1, +0, mips::T8);
2005  __ StoreConstToOffset(mips::kStoreDoubleword, 0, mips::A1, +0, mips::T8);
2006
2007  __ StoreConstToOffset(mips::kStoreDoubleword, 0x1234567812345678, mips::A1, +0, mips::T8);
2008  __ StoreConstToOffset(mips::kStoreDoubleword, 0x1234567800000000, mips::A1, +0, mips::T8);
2009  __ StoreConstToOffset(mips::kStoreDoubleword, 0x0000000012345678, mips::A1, +0, mips::T8);
2010
2011  __ StoreConstToOffset(mips::kStoreWord, 0, mips::T8, +0, mips::T8);
2012  __ StoreConstToOffset(mips::kStoreWord, 0x12345678, mips::T8, +0, mips::T8);
2013
2014  __ StoreConstToOffset(mips::kStoreWord, 0, mips::A1, -0xFFF0, mips::T8);
2015  __ StoreConstToOffset(mips::kStoreWord, 0x12345678, mips::A1, +0xFFF0, mips::T8);
2016
2017  __ StoreConstToOffset(mips::kStoreWord, 0, mips::T8, -0xFFF0, mips::T8);
2018  __ StoreConstToOffset(mips::kStoreWord, 0x12345678, mips::T8, +0xFFF0, mips::T8);
2019
2020  const char* expected =
2021      "ori $t8, $zero, 0xFF\n"
2022      "sb $t8, 0($a1)\n"
2023      "ori $t8, $zero, 0xFFFF\n"
2024      "sh $t8, 0($a1)\n"
2025      "lui $t8, 0x1234\n"
2026      "ori $t8, $t8, 0x5678\n"
2027      "sw $t8, 0($a1)\n"
2028      "lui $t8, 0x9ABC\n"
2029      "ori $t8, $t8, 0xDEF0\n"
2030      "sw $t8, 0($a1)\n"
2031      "lui $t8, 0x1234\n"
2032      "ori $t8, $t8, 0x5678\n"
2033      "sw $t8, 4($a1)\n"
2034
2035      "sb $zero, 0($a1)\n"
2036      "sh $zero, 0($a1)\n"
2037      "sw $zero, 0($a1)\n"
2038      "sw $zero, 0($a1)\n"
2039      "sw $zero, 4($a1)\n"
2040
2041      "lui $t8, 0x1234\n"
2042      "ori $t8, $t8, 0x5678\n"
2043      "sw $t8, 0($a1)\n"
2044      "sw $t8, 4($a1)\n"
2045      "sw $zero, 0($a1)\n"
2046      "lui $t8, 0x1234\n"
2047      "ori $t8, $t8, 0x5678\n"
2048      "sw $t8, 4($a1)\n"
2049      "lui $t8, 0x1234\n"
2050      "ori $t8, $t8, 0x5678\n"
2051      "sw $t8, 0($a1)\n"
2052      "sw $zero, 4($a1)\n"
2053
2054      "sw $zero, 0($t8)\n"
2055      "lui $at, 0x1234\n"
2056      "ori $at, $at, 0x5678\n"
2057      "sw $at, 0($t8)\n"
2058
2059      "addiu $at, $a1, -0x7FF8\n"
2060      "sw $zero, -0x7FF8($at)\n"
2061      "addiu $at, $a1, 0x7FF8\n"
2062      "lui $t8, 0x1234\n"
2063      "ori $t8, $t8, 0x5678\n"
2064      "sw $t8, 0x7FF8($at)\n"
2065
2066      "addiu $at, $t8, -0x7FF8\n"
2067      "sw $zero, -0x7FF8($at)\n"
2068      "addiu $at, $t8, 0x7FF8\n"
2069      "lui $t8, 0x1234\n"
2070      "ori $t8, $t8, 0x5678\n"
2071      "sw $t8, 0x7FF8($at)\n";
2072  DriverStr(expected, "StoreConstToOffset");
2073}
2074
2075TEST_F(AssemblerMIPSTest, B) {
2076  mips::MipsLabel label1, label2;
2077  __ B(&label1);
2078  constexpr size_t kAdduCount1 = 63;
2079  for (size_t i = 0; i != kAdduCount1; ++i) {
2080    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2081  }
2082  __ Bind(&label1);
2083  __ B(&label2);
2084  constexpr size_t kAdduCount2 = 64;
2085  for (size_t i = 0; i != kAdduCount2; ++i) {
2086    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2087  }
2088  __ Bind(&label2);
2089  __ B(&label1);
2090
2091  std::string expected =
2092      ".set noreorder\n"
2093      "b 1f\n"
2094      "nop\n" +
2095      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
2096      "1:\n"
2097      "b 2f\n"
2098      "nop\n" +
2099      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
2100      "2:\n"
2101      "b 1b\n"
2102      "nop\n";
2103  DriverStr(expected, "B");
2104}
2105
2106TEST_F(AssemblerMIPSTest, Beq) {
2107  __ SetReorder(false);
2108  BranchCondTwoRegsHelper(&mips::MipsAssembler::Beq, "Beq");
2109}
2110
2111TEST_F(AssemblerMIPSTest, Bne) {
2112  __ SetReorder(false);
2113  BranchCondTwoRegsHelper(&mips::MipsAssembler::Bne, "Bne");
2114}
2115
2116TEST_F(AssemblerMIPSTest, Beqz) {
2117  __ SetReorder(false);
2118  mips::MipsLabel label;
2119  __ Beqz(mips::A0, &label);
2120  constexpr size_t kAdduCount1 = 63;
2121  for (size_t i = 0; i != kAdduCount1; ++i) {
2122    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2123  }
2124  __ Bind(&label);
2125  constexpr size_t kAdduCount2 = 64;
2126  for (size_t i = 0; i != kAdduCount2; ++i) {
2127    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2128  }
2129  __ Beqz(mips::A1, &label);
2130
2131  std::string expected =
2132      ".set noreorder\n"
2133      "beq $zero, $a0, 1f\n"
2134      "nop\n" +
2135      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
2136      "1:\n" +
2137      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
2138      "beq $zero, $a1, 1b\n"
2139      "nop\n";
2140  DriverStr(expected, "Beqz");
2141}
2142
2143TEST_F(AssemblerMIPSTest, Bnez) {
2144  __ SetReorder(false);
2145  mips::MipsLabel label;
2146  __ Bnez(mips::A0, &label);
2147  constexpr size_t kAdduCount1 = 63;
2148  for (size_t i = 0; i != kAdduCount1; ++i) {
2149    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2150  }
2151  __ Bind(&label);
2152  constexpr size_t kAdduCount2 = 64;
2153  for (size_t i = 0; i != kAdduCount2; ++i) {
2154    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2155  }
2156  __ Bnez(mips::A1, &label);
2157
2158  std::string expected =
2159      ".set noreorder\n"
2160      "bne $zero, $a0, 1f\n"
2161      "nop\n" +
2162      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
2163      "1:\n" +
2164      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
2165      "bne $zero, $a1, 1b\n"
2166      "nop\n";
2167  DriverStr(expected, "Bnez");
2168}
2169
2170TEST_F(AssemblerMIPSTest, Bltz) {
2171  __ SetReorder(false);
2172  BranchCondOneRegHelper(&mips::MipsAssembler::Bltz, "Bltz");
2173}
2174
2175TEST_F(AssemblerMIPSTest, Bgez) {
2176  __ SetReorder(false);
2177  BranchCondOneRegHelper(&mips::MipsAssembler::Bgez, "Bgez");
2178}
2179
2180TEST_F(AssemblerMIPSTest, Blez) {
2181  __ SetReorder(false);
2182  BranchCondOneRegHelper(&mips::MipsAssembler::Blez, "Blez");
2183}
2184
2185TEST_F(AssemblerMIPSTest, Bgtz) {
2186  __ SetReorder(false);
2187  BranchCondOneRegHelper(&mips::MipsAssembler::Bgtz, "Bgtz");
2188}
2189
2190TEST_F(AssemblerMIPSTest, Blt) {
2191  __ SetReorder(false);
2192  mips::MipsLabel label;
2193  __ Blt(mips::A0, mips::A1, &label);
2194  constexpr size_t kAdduCount1 = 63;
2195  for (size_t i = 0; i != kAdduCount1; ++i) {
2196    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2197  }
2198  __ Bind(&label);
2199  constexpr size_t kAdduCount2 = 64;
2200  for (size_t i = 0; i != kAdduCount2; ++i) {
2201    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2202  }
2203  __ Blt(mips::A2, mips::A3, &label);
2204
2205  std::string expected =
2206      ".set noreorder\n"
2207      "slt $at, $a0, $a1\n"
2208      "bne $zero, $at, 1f\n"
2209      "nop\n" +
2210      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
2211      "1:\n" +
2212      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
2213      "slt $at, $a2, $a3\n"
2214      "bne $zero, $at, 1b\n"
2215      "nop\n";
2216  DriverStr(expected, "Blt");
2217}
2218
2219TEST_F(AssemblerMIPSTest, Bge) {
2220  __ SetReorder(false);
2221  mips::MipsLabel label;
2222  __ Bge(mips::A0, mips::A1, &label);
2223  constexpr size_t kAdduCount1 = 63;
2224  for (size_t i = 0; i != kAdduCount1; ++i) {
2225    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2226  }
2227  __ Bind(&label);
2228  constexpr size_t kAdduCount2 = 64;
2229  for (size_t i = 0; i != kAdduCount2; ++i) {
2230    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2231  }
2232  __ Bge(mips::A2, mips::A3, &label);
2233
2234  std::string expected =
2235      ".set noreorder\n"
2236      "slt $at, $a0, $a1\n"
2237      "beq $zero, $at, 1f\n"
2238      "nop\n" +
2239      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
2240      "1:\n" +
2241      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
2242      "slt $at, $a2, $a3\n"
2243      "beq $zero, $at, 1b\n"
2244      "nop\n";
2245  DriverStr(expected, "Bge");
2246}
2247
2248TEST_F(AssemblerMIPSTest, Bltu) {
2249  __ SetReorder(false);
2250  mips::MipsLabel label;
2251  __ Bltu(mips::A0, mips::A1, &label);
2252  constexpr size_t kAdduCount1 = 63;
2253  for (size_t i = 0; i != kAdduCount1; ++i) {
2254    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2255  }
2256  __ Bind(&label);
2257  constexpr size_t kAdduCount2 = 64;
2258  for (size_t i = 0; i != kAdduCount2; ++i) {
2259    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2260  }
2261  __ Bltu(mips::A2, mips::A3, &label);
2262
2263  std::string expected =
2264      ".set noreorder\n"
2265      "sltu $at, $a0, $a1\n"
2266      "bne $zero, $at, 1f\n"
2267      "nop\n" +
2268      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
2269      "1:\n" +
2270      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
2271      "sltu $at, $a2, $a3\n"
2272      "bne $zero, $at, 1b\n"
2273      "nop\n";
2274  DriverStr(expected, "Bltu");
2275}
2276
2277TEST_F(AssemblerMIPSTest, Bgeu) {
2278  __ SetReorder(false);
2279  mips::MipsLabel label;
2280  __ Bgeu(mips::A0, mips::A1, &label);
2281  constexpr size_t kAdduCount1 = 63;
2282  for (size_t i = 0; i != kAdduCount1; ++i) {
2283    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2284  }
2285  __ Bind(&label);
2286  constexpr size_t kAdduCount2 = 64;
2287  for (size_t i = 0; i != kAdduCount2; ++i) {
2288    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2289  }
2290  __ Bgeu(mips::A2, mips::A3, &label);
2291
2292  std::string expected =
2293      ".set noreorder\n"
2294      "sltu $at, $a0, $a1\n"
2295      "beq $zero, $at, 1f\n"
2296      "nop\n" +
2297      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
2298      "1:\n" +
2299      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
2300      "sltu $at, $a2, $a3\n"
2301      "beq $zero, $at, 1b\n"
2302      "nop\n";
2303  DriverStr(expected, "Bgeu");
2304}
2305
2306TEST_F(AssemblerMIPSTest, Bc1f) {
2307  __ SetReorder(false);
2308  mips::MipsLabel label;
2309  __ Bc1f(0, &label);
2310  constexpr size_t kAdduCount1 = 63;
2311  for (size_t i = 0; i != kAdduCount1; ++i) {
2312    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2313  }
2314  __ Bind(&label);
2315  constexpr size_t kAdduCount2 = 64;
2316  for (size_t i = 0; i != kAdduCount2; ++i) {
2317    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2318  }
2319  __ Bc1f(7, &label);
2320
2321  std::string expected =
2322      ".set noreorder\n"
2323      "bc1f $fcc0, 1f\n"
2324      "nop\n" +
2325      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
2326      "1:\n" +
2327      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
2328      "bc1f $fcc7, 1b\n"
2329      "nop\n";
2330  DriverStr(expected, "Bc1f");
2331}
2332
2333TEST_F(AssemblerMIPSTest, Bc1t) {
2334  __ SetReorder(false);
2335  mips::MipsLabel label;
2336  __ Bc1t(0, &label);
2337  constexpr size_t kAdduCount1 = 63;
2338  for (size_t i = 0; i != kAdduCount1; ++i) {
2339    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2340  }
2341  __ Bind(&label);
2342  constexpr size_t kAdduCount2 = 64;
2343  for (size_t i = 0; i != kAdduCount2; ++i) {
2344    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2345  }
2346  __ Bc1t(7, &label);
2347
2348  std::string expected =
2349      ".set noreorder\n"
2350      "bc1t $fcc0, 1f\n"
2351      "nop\n" +
2352      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
2353      "1:\n" +
2354      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
2355      "bc1t $fcc7, 1b\n"
2356      "nop\n";
2357  DriverStr(expected, "Bc1t");
2358}
2359
2360///////////////////////
2361// Loading Constants //
2362///////////////////////
2363
2364TEST_F(AssemblerMIPSTest, LoadConst32) {
2365  // IsUint<16>(value)
2366  __ LoadConst32(mips::V0, 0);
2367  __ LoadConst32(mips::V0, 65535);
2368  // IsInt<16>(value)
2369  __ LoadConst32(mips::V0, -1);
2370  __ LoadConst32(mips::V0, -32768);
2371  // Everything else
2372  __ LoadConst32(mips::V0, 65536);
2373  __ LoadConst32(mips::V0, 65537);
2374  __ LoadConst32(mips::V0, 2147483647);
2375  __ LoadConst32(mips::V0, -32769);
2376  __ LoadConst32(mips::V0, -65536);
2377  __ LoadConst32(mips::V0, -65537);
2378  __ LoadConst32(mips::V0, -2147483647);
2379  __ LoadConst32(mips::V0, -2147483648);
2380
2381  const char* expected =
2382      // IsUint<16>(value)
2383      "ori $v0, $zero, 0\n"         // __ LoadConst32(mips::V0, 0);
2384      "ori $v0, $zero, 65535\n"     // __ LoadConst32(mips::V0, 65535);
2385      // IsInt<16>(value)
2386      "addiu $v0, $zero, -1\n"      // __ LoadConst32(mips::V0, -1);
2387      "addiu $v0, $zero, -32768\n"  // __ LoadConst32(mips::V0, -32768);
2388      // Everything else
2389      "lui $v0, 1\n"                // __ LoadConst32(mips::V0, 65536);
2390      "lui $v0, 1\n"                // __ LoadConst32(mips::V0, 65537);
2391      "ori $v0, 1\n"                //                 "
2392      "lui $v0, 32767\n"            // __ LoadConst32(mips::V0, 2147483647);
2393      "ori $v0, 65535\n"            //                 "
2394      "lui $v0, 65535\n"            // __ LoadConst32(mips::V0, -32769);
2395      "ori $v0, 32767\n"            //                 "
2396      "lui $v0, 65535\n"            // __ LoadConst32(mips::V0, -65536);
2397      "lui $v0, 65534\n"            // __ LoadConst32(mips::V0, -65537);
2398      "ori $v0, 65535\n"            //                 "
2399      "lui $v0, 32768\n"            // __ LoadConst32(mips::V0, -2147483647);
2400      "ori $v0, 1\n"                //                 "
2401      "lui $v0, 32768\n";           // __ LoadConst32(mips::V0, -2147483648);
2402  DriverStr(expected, "LoadConst32");
2403}
2404
2405TEST_F(AssemblerMIPSTest, LoadFarthestNearLabelAddress) {
2406  mips::MipsLabel label;
2407  __ BindPcRelBaseLabel();
2408  __ LoadLabelAddress(mips::V0, mips::V1, &label);
2409  constexpr size_t kAddiuCount = 0x1FDE;
2410  for (size_t i = 0; i != kAddiuCount; ++i) {
2411    __ Addiu(mips::A0, mips::A1, 0);
2412  }
2413  __ Bind(&label);
2414
2415  std::string expected =
2416      "1:\n"
2417      "addiu $v0, $v1, %lo(2f - 1b)\n" +
2418      RepeatInsn(kAddiuCount, "addiu $a0, $a1, %hi(2f - 1b)\n") +
2419      "2:\n";
2420  DriverStr(expected, "LoadFarthestNearLabelAddress");
2421}
2422
2423TEST_F(AssemblerMIPSTest, LoadNearestFarLabelAddress) {
2424  mips::MipsLabel label;
2425  __ BindPcRelBaseLabel();
2426  __ LoadLabelAddress(mips::V0, mips::V1, &label);
2427  constexpr size_t kAdduCount = 0x1FDF;
2428  for (size_t i = 0; i != kAdduCount; ++i) {
2429    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2430  }
2431  __ Bind(&label);
2432
2433  std::string expected =
2434      "1:\n"
2435      "lui $at, %hi(2f - 1b)\n"
2436      "ori $at, $at, %lo(2f - 1b)\n"
2437      "addu $v0, $at, $v1\n" +
2438      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
2439      "2:\n";
2440  DriverStr(expected, "LoadNearestFarLabelAddress");
2441}
2442
2443TEST_F(AssemblerMIPSTest, LoadFarthestNearLiteral) {
2444  mips::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
2445  __ BindPcRelBaseLabel();
2446  __ LoadLiteral(mips::V0, mips::V1, literal);
2447  constexpr size_t kAddiuCount = 0x1FDE;
2448  for (size_t i = 0; i != kAddiuCount; ++i) {
2449    __ Addiu(mips::A0, mips::A1, 0);
2450  }
2451
2452  std::string expected =
2453      "1:\n"
2454      "lw $v0, %lo(2f - 1b)($v1)\n" +
2455      RepeatInsn(kAddiuCount, "addiu $a0, $a1, %hi(2f - 1b)\n") +
2456      "2:\n"
2457      ".word 0x12345678\n";
2458  DriverStr(expected, "LoadFarthestNearLiteral");
2459}
2460
2461TEST_F(AssemblerMIPSTest, LoadNearestFarLiteral) {
2462  mips::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
2463  __ BindPcRelBaseLabel();
2464  __ LoadLiteral(mips::V0, mips::V1, literal);
2465  constexpr size_t kAdduCount = 0x1FDF;
2466  for (size_t i = 0; i != kAdduCount; ++i) {
2467    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2468  }
2469
2470  std::string expected =
2471      "1:\n"
2472      "lui $at, %hi(2f - 1b)\n"
2473      "addu $at, $at, $v1\n"
2474      "lw $v0, %lo(2f - 1b)($at)\n" +
2475      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
2476      "2:\n"
2477      ".word 0x12345678\n";
2478  DriverStr(expected, "LoadNearestFarLiteral");
2479}
2480
2481TEST_F(AssemblerMIPSTest, ImpossibleReordering) {
2482  mips::MipsLabel label1, label2;
2483  __ SetReorder(true);
2484
2485  __ B(&label1);  // No preceding or target instruction for the delay slot.
2486
2487  __ Addu(mips::T0, mips::T1, mips::T2);
2488  __ Bind(&label1);
2489  __ B(&label1);  // The preceding label prevents moving Addu into the delay slot.
2490  __ B(&label1);  // No preceding or target instruction for the delay slot.
2491
2492  __ Addu(mips::T0, mips::T1, mips::T2);
2493  __ Beqz(mips::T0, &label1);  // T0 dependency.
2494
2495  __ Or(mips::T1, mips::T2, mips::T3);
2496  __ Bne(mips::T2, mips::T1, &label1);  // T1 dependency.
2497
2498  __ And(mips::T0, mips::T1, mips::T2);
2499  __ Blt(mips::T1, mips::T0, &label1);  // T0 dependency.
2500
2501  __ Xor(mips::AT, mips::T0, mips::T1);
2502  __ Bge(mips::T1, mips::T0, &label1);  // AT dependency.
2503
2504  __ Subu(mips::T0, mips::T1, mips::AT);
2505  __ Bltu(mips::T1, mips::T0, &label1);  // AT dependency.
2506
2507  __ ColtS(1, mips::F2, mips::F4);
2508  __ Bc1t(1, &label1);  // cc1 dependency.
2509
2510  __ Move(mips::T0, mips::RA);
2511  __ Bal(&label1);  // RA dependency.
2512
2513  __ Lw(mips::RA, mips::T0, 0);
2514  __ Bal(&label1);  // RA dependency.
2515
2516  __ LlR2(mips::T9, mips::T0, 0);
2517  __ Jalr(mips::T9);  // T9 dependency.
2518
2519  __ Sw(mips::RA, mips::T0, 0);
2520  __ Jalr(mips::T9);  // RA dependency.
2521
2522  __ Lw(mips::T1, mips::T0, 0);
2523  __ Jalr(mips::T1, mips::T9);  // T1 dependency.
2524
2525  __ ScR2(mips::T9, mips::T0, 0);
2526  __ Jr(mips::T9);  // T9 dependency.
2527
2528  __ Bind(&label2);
2529
2530  __ Bnez(mips::T0, &label2);  // No preceding instruction for the delay slot.
2531
2532  __ Bgeu(mips::T1, mips::T0, &label2);  // No preceding instruction for the delay slot.
2533
2534  __ Bc1f(2, &label2);  // No preceding instruction for the delay slot.
2535
2536  __ Bal(&label2);  // No preceding instruction for the delay slot.
2537
2538  __ Jalr(mips::T9);  // No preceding instruction for the delay slot.
2539
2540  __ Addu(mips::T0, mips::T1, mips::T2);
2541  __ CodePosition();  // Drops the delay slot candidate (the last instruction).
2542  __ Beq(mips::T1, mips::T2, &label2);  // No preceding or target instruction for the delay slot.
2543
2544  std::string expected =
2545      ".set noreorder\n"
2546      "b 1f\n"
2547      "nop\n"
2548
2549      "addu $t0, $t1, $t2\n"
2550      "1:\n"
2551      "b 1b\n"
2552      "nop\n"
2553      "b 1b\n"
2554      "nop\n"
2555
2556      "addu $t0, $t1, $t2\n"
2557      "beq $zero, $t0, 1b\n"
2558      "nop\n"
2559
2560      "or $t1, $t2, $t3\n"
2561      "bne $t2, $t1, 1b\n"
2562      "nop\n"
2563
2564      "and $t0, $t1, $t2\n"
2565      "slt $at, $t1, $t0\n"
2566      "bne $zero, $at, 1b\n"
2567      "nop\n"
2568
2569      "xor $at, $t0, $t1\n"
2570      "slt $at, $t1, $t0\n"
2571      "beq $zero, $at, 1b\n"
2572      "nop\n"
2573
2574      "subu $t0, $t1, $at\n"
2575      "sltu $at, $t1, $t0\n"
2576      "bne $zero, $at, 1b\n"
2577      "nop\n"
2578
2579      "c.olt.s $fcc1, $f2, $f4\n"
2580      "bc1t $fcc1, 1b\n"
2581      "nop\n"
2582
2583      "or $t0, $ra, $zero\n"
2584      "bal 1b\n"
2585      "nop\n"
2586
2587      "lw $ra, 0($t0)\n"
2588      "bal 1b\n"
2589      "nop\n"
2590
2591      "ll $t9, 0($t0)\n"
2592      "jalr $t9\n"
2593      "nop\n"
2594
2595      "sw $ra, 0($t0)\n"
2596      "jalr $t9\n"
2597      "nop\n"
2598
2599      "lw $t1, 0($t0)\n"
2600      "jalr $t1, $t9\n"
2601      "nop\n"
2602
2603      "sc $t9, 0($t0)\n"
2604      "jalr $zero, $t9\n"
2605      "nop\n"
2606
2607      "2:\n"
2608
2609      "bne $zero, $t0, 2b\n"
2610      "nop\n"
2611
2612      "sltu $at, $t1, $t0\n"
2613      "beq $zero, $at, 2b\n"
2614      "nop\n"
2615
2616      "bc1f $fcc2, 2b\n"
2617      "nop\n"
2618
2619      "bal 2b\n"
2620      "nop\n"
2621
2622      "jalr $t9\n"
2623      "nop\n"
2624
2625      "addu $t0, $t1, $t2\n"
2626      "beq $t1, $t2, 2b\n"
2627      "nop\n";
2628  DriverStr(expected, "ImpossibleReordering");
2629}
2630
2631TEST_F(AssemblerMIPSTest, Reordering) {
2632  mips::MipsLabel label1, label2;
2633  __ SetReorder(true);
2634
2635  __ Bind(&label1);
2636  __ Bind(&label2);
2637
2638  __ Addu(mips::T0, mips::T1, mips::T2);
2639  __ Beqz(mips::T1, &label1);
2640
2641  __ Or(mips::T1, mips::T2, mips::T3);
2642  __ Bne(mips::T2, mips::T3, &label1);
2643
2644  __ And(mips::T0, mips::T1, mips::T2);
2645  __ Blt(mips::T1, mips::T2, &label1);
2646
2647  __ Xor(mips::T2, mips::T0, mips::T1);
2648  __ Bge(mips::T1, mips::T0, &label1);
2649
2650  __ Subu(mips::T2, mips::T1, mips::T0);
2651  __ Bltu(mips::T1, mips::T0, &label1);
2652
2653  __ ColtS(0, mips::F2, mips::F4);
2654  __ Bc1t(1, &label1);
2655
2656  __ Move(mips::T0, mips::T1);
2657  __ Bal(&label1);
2658
2659  __ LlR2(mips::T1, mips::T0, 0);
2660  __ Jalr(mips::T9);
2661
2662  __ ScR2(mips::T1, mips::T0, 0);
2663  __ Jr(mips::T9);
2664
2665  std::string expected =
2666      ".set noreorder\n"
2667      "1:\n"
2668
2669      "beq $zero, $t1, 1b\n"
2670      "addu $t0, $t1, $t2\n"
2671
2672      "bne $t2, $t3, 1b\n"
2673      "or $t1, $t2, $t3\n"
2674
2675      "slt $at, $t1, $t2\n"
2676      "bne $zero, $at, 1b\n"
2677      "and $t0, $t1, $t2\n"
2678
2679      "slt $at, $t1, $t0\n"
2680      "beq $zero, $at, 1b\n"
2681      "xor $t2, $t0, $t1\n"
2682
2683      "sltu $at, $t1, $t0\n"
2684      "bne $zero, $at, 1b\n"
2685      "subu $t2, $t1, $t0\n"
2686
2687      "bc1t $fcc1, 1b\n"
2688      "c.olt.s $fcc0, $f2, $f4\n"
2689
2690      "bal 1b\n"
2691      "or $t0, $t1, $zero\n"
2692
2693      "jalr $t9\n"
2694      "ll $t1, 0($t0)\n"
2695
2696      "jalr $zero, $t9\n"
2697      "sc $t1, 0($t0)\n";
2698  DriverStr(expected, "Reordering");
2699}
2700
2701TEST_F(AssemblerMIPSTest, AbsorbTargetInstruction) {
2702  mips::MipsLabel label1, label2, label3, label4, label5, label6;
2703  __ SetReorder(true);
2704
2705  __ B(&label1);
2706  __ Bind(&label1);
2707  __ Addu(mips::T0, mips::T1, mips::T2);
2708
2709  __ Bind(&label2);
2710  __ Xor(mips::T0, mips::T1, mips::T2);
2711  __ Addu(mips::T0, mips::T1, mips::T2);
2712  __ Bind(&label3);  // Prevents reordering ADDU above with B below.
2713  __ B(&label2);
2714
2715  __ B(&label4);
2716  __ Bind(&label4);
2717  __ Addu(mips::T0, mips::T1, mips::T2);
2718  __ CodePosition();  // Prevents absorbing ADDU above.
2719
2720  __ B(&label5);
2721  __ Bind(&label5);
2722  __ Addu(mips::T0, mips::T1, mips::T2);
2723  __ Bind(&label6);
2724  __ CodePosition();  // Even across Bind(), CodePosition() prevents absorbing the ADDU above.
2725
2726  std::string expected =
2727      ".set noreorder\n"
2728      "b 1f\n"
2729      "addu $t0, $t1, $t2\n"
2730      "addu $t0, $t1, $t2\n"
2731      "1:\n"
2732
2733      "xor $t0, $t1, $t2\n"
2734      "2:\n"
2735      "addu $t0, $t1, $t2\n"
2736      "b 2b\n"
2737      "xor $t0, $t1, $t2\n"
2738
2739      "b 4f\n"
2740      "nop\n"
2741      "4:\n"
2742      "addu $t0, $t1, $t2\n"
2743
2744      "b 5f\n"
2745      "nop\n"
2746      "5:\n"
2747      "addu $t0, $t1, $t2\n";
2748  DriverStr(expected, "AbsorbTargetInstruction");
2749}
2750
2751TEST_F(AssemblerMIPSTest, SetReorder) {
2752  mips::MipsLabel label1, label2, label3, label4, label5, label6;
2753
2754  __ SetReorder(true);
2755  __ Bind(&label1);
2756  __ Addu(mips::T0, mips::T1, mips::T2);
2757  __ B(&label1);
2758  __ B(&label5);
2759  __ B(&label6);
2760
2761  __ SetReorder(false);
2762  __ Bind(&label2);
2763  __ Addu(mips::T0, mips::T1, mips::T2);
2764  __ B(&label2);
2765  __ B(&label5);
2766  __ B(&label6);
2767
2768  __ SetReorder(true);
2769  __ Bind(&label3);
2770  __ Addu(mips::T0, mips::T1, mips::T2);
2771  __ B(&label3);
2772  __ B(&label5);
2773  __ B(&label6);
2774
2775  __ SetReorder(false);
2776  __ Bind(&label4);
2777  __ Addu(mips::T0, mips::T1, mips::T2);
2778  __ B(&label4);
2779  __ B(&label5);
2780  __ B(&label6);
2781
2782  __ SetReorder(true);
2783  __ Bind(&label5);
2784  __ Subu(mips::T0, mips::T1, mips::T2);
2785
2786  __ SetReorder(false);
2787  __ Bind(&label6);
2788  __ Xor(mips::T0, mips::T1, mips::T2);
2789
2790  std::string expected =
2791      ".set noreorder\n"
2792      "1:\n"
2793      "b 1b\n"
2794      "addu $t0, $t1, $t2\n"
2795      "b 55f\n"
2796      "subu $t0, $t1, $t2\n"
2797      "b 6f\n"
2798      "nop\n"
2799
2800      "2:\n"
2801      "addu $t0, $t1, $t2\n"
2802      "b 2b\n"
2803      "nop\n"
2804      "b 5f\n"
2805      "nop\n"
2806      "b 6f\n"
2807      "nop\n"
2808
2809      "3:\n"
2810      "b 3b\n"
2811      "addu $t0, $t1, $t2\n"
2812      "b 55f\n"
2813      "subu $t0, $t1, $t2\n"
2814      "b 6f\n"
2815      "nop\n"
2816
2817      "4:\n"
2818      "addu $t0, $t1, $t2\n"
2819      "b 4b\n"
2820      "nop\n"
2821      "b 5f\n"
2822      "nop\n"
2823      "b 6f\n"
2824      "nop\n"
2825
2826      "5:\n"
2827      "subu $t0, $t1, $t2\n"
2828      "55:\n"
2829      "6:\n"
2830      "xor $t0, $t1, $t2\n";
2831  DriverStr(expected, "SetReorder");
2832}
2833
2834TEST_F(AssemblerMIPSTest, LongBranchReorder) {
2835  mips::MipsLabel label;
2836  __ SetReorder(true);
2837  __ Subu(mips::T0, mips::T1, mips::T2);
2838  __ B(&label);
2839  constexpr uint32_t kAdduCount1 = (1u << 15) + 1;
2840  for (size_t i = 0; i != kAdduCount1; ++i) {
2841    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2842  }
2843  __ Bind(&label);
2844  constexpr uint32_t kAdduCount2 = (1u << 15) + 1;
2845  for (size_t i = 0; i != kAdduCount2; ++i) {
2846    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
2847  }
2848  __ Subu(mips::T0, mips::T1, mips::T2);
2849  __ B(&label);
2850
2851  // Account for 5 extra instructions: ori, addu, lw, jalr, addiu.
2852  uint32_t offset_forward = (kAdduCount1 + 5) * sizeof(uint32_t);
2853  // Account for 5 extra instructions: subu, addiu, sw, nal, lui.
2854  uint32_t offset_back = -(kAdduCount1 + 5) * sizeof(uint32_t);
2855
2856  std::ostringstream oss;
2857  oss <<
2858      ".set noreorder\n"
2859      "subu $t0, $t1, $t2\n"
2860      "addiu $sp, $sp, -4\n"
2861      "sw $ra, 0($sp)\n"
2862      "bltzal $zero, .+4\n"
2863      "lui $at, 0x" << std::hex << High16Bits(offset_forward) << "\n"
2864      "ori $at, $at, 0x" << std::hex << Low16Bits(offset_forward) << "\n"
2865      "addu $at, $at, $ra\n"
2866      "lw $ra, 0($sp)\n"
2867      "jalr $zero, $at\n"
2868      "addiu $sp, $sp, 4\n" <<
2869      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") <<
2870      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") <<
2871      "subu $t0, $t1, $t2\n"
2872      "addiu $sp, $sp, -4\n"
2873      "sw $ra, 0($sp)\n"
2874      "bltzal $zero, .+4\n"
2875      "lui $at, 0x" << std::hex << High16Bits(offset_back) << "\n"
2876      "ori $at, $at, 0x" << std::hex << Low16Bits(offset_back) << "\n"
2877      "addu $at, $at, $ra\n"
2878      "lw $ra, 0($sp)\n"
2879      "jalr $zero, $at\n"
2880      "addiu $sp, $sp, 4\n";
2881  std::string expected = oss.str();
2882  DriverStr(expected, "LongBranchReorder");
2883}
2884
2885#undef __
2886
2887}  // namespace art
2888