blob: 98fc44ba5d2e06e5a3369597f60fe0716ed9ce8d [file] [log] [blame]
Lena Djokic2e0a7e52017-07-06 11:55:24 +02001/*
2 * Copyright (C) 2017 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 AssemblerMIPS32r5Test : public AssemblerTest<mips::MipsAssembler,
Aart Bikcaa31e72017-09-14 17:08:50 -070035 mips::MipsLabel,
Lena Djokic2e0a7e52017-07-06 11:55:24 +020036 mips::Register,
37 mips::FRegister,
38 uint32_t,
39 mips::VectorRegister> {
40 public:
Andreas Gampec55bb392018-09-21 00:02:02 +000041 using Base = AssemblerTest<mips::MipsAssembler,
42 mips::MipsLabel,
43 mips::Register,
44 mips::FRegister,
45 uint32_t,
46 mips::VectorRegister>;
Lena Djokic2e0a7e52017-07-06 11:55:24 +020047
Vladimir Marko9a6ca9f2018-05-04 13:06:55 +010048 // These tests were taking too long, so we hide the DriverStr() from AssemblerTest<>
49 // and reimplement it without the verification against `assembly_string`. b/73903608
50 void DriverStr(const std::string& assembly_string ATTRIBUTE_UNUSED,
51 const std::string& test_name ATTRIBUTE_UNUSED) {
52 GetAssembler()->FinalizeCode();
53 std::vector<uint8_t> data(GetAssembler()->CodeSize());
54 MemoryRegion code(data.data(), data.size());
55 GetAssembler()->FinalizeInstructions(code);
56 }
57
Lena Djokic2e0a7e52017-07-06 11:55:24 +020058 AssemblerMIPS32r5Test() :
59 instruction_set_features_(MipsInstructionSetFeatures::FromVariant("mips32r5", nullptr)) {
60 }
61
62 protected:
63 // Get the typically used name for this architecture, e.g., aarch64, x86-64, ...
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010064 std::string GetArchitectureString() override {
Lena Djokic2e0a7e52017-07-06 11:55:24 +020065 return "mips";
66 }
67
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010068 std::string GetAssemblerParameters() override {
Lena Djokic2e0a7e52017-07-06 11:55:24 +020069 return " --no-warn -32 -march=mips32r5 -mmsa";
70 }
71
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010072 void Pad(std::vector<uint8_t>& data) override {
Lena Djokic2e0a7e52017-07-06 11:55:24 +020073 // The GNU linker unconditionally pads the code segment with NOPs to a size that is a multiple
74 // of 16 and there doesn't appear to be a way to suppress this padding. Our assembler doesn't
75 // pad, so, in order for two assembler outputs to match, we need to match the padding as well.
76 // NOP is encoded as four zero bytes on MIPS.
77 size_t pad_size = RoundUp(data.size(), 16u) - data.size();
78 data.insert(data.end(), pad_size, 0);
79 }
80
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010081 std::string GetDisassembleParameters() override {
Lena Djokic2e0a7e52017-07-06 11:55:24 +020082 return " -D -bbinary -mmips:isa32r5";
83 }
84
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010085 mips::MipsAssembler* CreateAssembler(ArenaAllocator* allocator) override {
Vladimir Markoe764d2e2017-10-05 14:35:55 +010086 return new (allocator) mips::MipsAssembler(allocator, instruction_set_features_.get());
Lena Djokic2e0a7e52017-07-06 11:55:24 +020087 }
88
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010089 void SetUpHelpers() override {
Lena Djokic2e0a7e52017-07-06 11:55:24 +020090 if (registers_.size() == 0) {
91 registers_.push_back(new mips::Register(mips::ZERO));
92 registers_.push_back(new mips::Register(mips::AT));
93 registers_.push_back(new mips::Register(mips::V0));
94 registers_.push_back(new mips::Register(mips::V1));
95 registers_.push_back(new mips::Register(mips::A0));
96 registers_.push_back(new mips::Register(mips::A1));
97 registers_.push_back(new mips::Register(mips::A2));
98 registers_.push_back(new mips::Register(mips::A3));
99 registers_.push_back(new mips::Register(mips::T0));
100 registers_.push_back(new mips::Register(mips::T1));
101 registers_.push_back(new mips::Register(mips::T2));
102 registers_.push_back(new mips::Register(mips::T3));
103 registers_.push_back(new mips::Register(mips::T4));
104 registers_.push_back(new mips::Register(mips::T5));
105 registers_.push_back(new mips::Register(mips::T6));
106 registers_.push_back(new mips::Register(mips::T7));
107 registers_.push_back(new mips::Register(mips::S0));
108 registers_.push_back(new mips::Register(mips::S1));
109 registers_.push_back(new mips::Register(mips::S2));
110 registers_.push_back(new mips::Register(mips::S3));
111 registers_.push_back(new mips::Register(mips::S4));
112 registers_.push_back(new mips::Register(mips::S5));
113 registers_.push_back(new mips::Register(mips::S6));
114 registers_.push_back(new mips::Register(mips::S7));
115 registers_.push_back(new mips::Register(mips::T8));
116 registers_.push_back(new mips::Register(mips::T9));
117 registers_.push_back(new mips::Register(mips::K0));
118 registers_.push_back(new mips::Register(mips::K1));
119 registers_.push_back(new mips::Register(mips::GP));
120 registers_.push_back(new mips::Register(mips::SP));
121 registers_.push_back(new mips::Register(mips::FP));
122 registers_.push_back(new mips::Register(mips::RA));
123
124 secondary_register_names_.emplace(mips::Register(mips::ZERO), "zero");
125 secondary_register_names_.emplace(mips::Register(mips::AT), "at");
126 secondary_register_names_.emplace(mips::Register(mips::V0), "v0");
127 secondary_register_names_.emplace(mips::Register(mips::V1), "v1");
128 secondary_register_names_.emplace(mips::Register(mips::A0), "a0");
129 secondary_register_names_.emplace(mips::Register(mips::A1), "a1");
130 secondary_register_names_.emplace(mips::Register(mips::A2), "a2");
131 secondary_register_names_.emplace(mips::Register(mips::A3), "a3");
132 secondary_register_names_.emplace(mips::Register(mips::T0), "t0");
133 secondary_register_names_.emplace(mips::Register(mips::T1), "t1");
134 secondary_register_names_.emplace(mips::Register(mips::T2), "t2");
135 secondary_register_names_.emplace(mips::Register(mips::T3), "t3");
136 secondary_register_names_.emplace(mips::Register(mips::T4), "t4");
137 secondary_register_names_.emplace(mips::Register(mips::T5), "t5");
138 secondary_register_names_.emplace(mips::Register(mips::T6), "t6");
139 secondary_register_names_.emplace(mips::Register(mips::T7), "t7");
140 secondary_register_names_.emplace(mips::Register(mips::S0), "s0");
141 secondary_register_names_.emplace(mips::Register(mips::S1), "s1");
142 secondary_register_names_.emplace(mips::Register(mips::S2), "s2");
143 secondary_register_names_.emplace(mips::Register(mips::S3), "s3");
144 secondary_register_names_.emplace(mips::Register(mips::S4), "s4");
145 secondary_register_names_.emplace(mips::Register(mips::S5), "s5");
146 secondary_register_names_.emplace(mips::Register(mips::S6), "s6");
147 secondary_register_names_.emplace(mips::Register(mips::S7), "s7");
148 secondary_register_names_.emplace(mips::Register(mips::T8), "t8");
149 secondary_register_names_.emplace(mips::Register(mips::T9), "t9");
150 secondary_register_names_.emplace(mips::Register(mips::K0), "k0");
151 secondary_register_names_.emplace(mips::Register(mips::K1), "k1");
152 secondary_register_names_.emplace(mips::Register(mips::GP), "gp");
153 secondary_register_names_.emplace(mips::Register(mips::SP), "sp");
154 secondary_register_names_.emplace(mips::Register(mips::FP), "fp");
155 secondary_register_names_.emplace(mips::Register(mips::RA), "ra");
156
157 fp_registers_.push_back(new mips::FRegister(mips::F0));
158 fp_registers_.push_back(new mips::FRegister(mips::F1));
159 fp_registers_.push_back(new mips::FRegister(mips::F2));
160 fp_registers_.push_back(new mips::FRegister(mips::F3));
161 fp_registers_.push_back(new mips::FRegister(mips::F4));
162 fp_registers_.push_back(new mips::FRegister(mips::F5));
163 fp_registers_.push_back(new mips::FRegister(mips::F6));
164 fp_registers_.push_back(new mips::FRegister(mips::F7));
165 fp_registers_.push_back(new mips::FRegister(mips::F8));
166 fp_registers_.push_back(new mips::FRegister(mips::F9));
167 fp_registers_.push_back(new mips::FRegister(mips::F10));
168 fp_registers_.push_back(new mips::FRegister(mips::F11));
169 fp_registers_.push_back(new mips::FRegister(mips::F12));
170 fp_registers_.push_back(new mips::FRegister(mips::F13));
171 fp_registers_.push_back(new mips::FRegister(mips::F14));
172 fp_registers_.push_back(new mips::FRegister(mips::F15));
173 fp_registers_.push_back(new mips::FRegister(mips::F16));
174 fp_registers_.push_back(new mips::FRegister(mips::F17));
175 fp_registers_.push_back(new mips::FRegister(mips::F18));
176 fp_registers_.push_back(new mips::FRegister(mips::F19));
177 fp_registers_.push_back(new mips::FRegister(mips::F20));
178 fp_registers_.push_back(new mips::FRegister(mips::F21));
179 fp_registers_.push_back(new mips::FRegister(mips::F22));
180 fp_registers_.push_back(new mips::FRegister(mips::F23));
181 fp_registers_.push_back(new mips::FRegister(mips::F24));
182 fp_registers_.push_back(new mips::FRegister(mips::F25));
183 fp_registers_.push_back(new mips::FRegister(mips::F26));
184 fp_registers_.push_back(new mips::FRegister(mips::F27));
185 fp_registers_.push_back(new mips::FRegister(mips::F28));
186 fp_registers_.push_back(new mips::FRegister(mips::F29));
187 fp_registers_.push_back(new mips::FRegister(mips::F30));
188 fp_registers_.push_back(new mips::FRegister(mips::F31));
189
190 vec_registers_.push_back(new mips::VectorRegister(mips::W0));
191 vec_registers_.push_back(new mips::VectorRegister(mips::W1));
192 vec_registers_.push_back(new mips::VectorRegister(mips::W2));
193 vec_registers_.push_back(new mips::VectorRegister(mips::W3));
194 vec_registers_.push_back(new mips::VectorRegister(mips::W4));
195 vec_registers_.push_back(new mips::VectorRegister(mips::W5));
196 vec_registers_.push_back(new mips::VectorRegister(mips::W6));
197 vec_registers_.push_back(new mips::VectorRegister(mips::W7));
198 vec_registers_.push_back(new mips::VectorRegister(mips::W8));
199 vec_registers_.push_back(new mips::VectorRegister(mips::W9));
200 vec_registers_.push_back(new mips::VectorRegister(mips::W10));
201 vec_registers_.push_back(new mips::VectorRegister(mips::W11));
202 vec_registers_.push_back(new mips::VectorRegister(mips::W12));
203 vec_registers_.push_back(new mips::VectorRegister(mips::W13));
204 vec_registers_.push_back(new mips::VectorRegister(mips::W14));
205 vec_registers_.push_back(new mips::VectorRegister(mips::W15));
206 vec_registers_.push_back(new mips::VectorRegister(mips::W16));
207 vec_registers_.push_back(new mips::VectorRegister(mips::W17));
208 vec_registers_.push_back(new mips::VectorRegister(mips::W18));
209 vec_registers_.push_back(new mips::VectorRegister(mips::W19));
210 vec_registers_.push_back(new mips::VectorRegister(mips::W20));
211 vec_registers_.push_back(new mips::VectorRegister(mips::W21));
212 vec_registers_.push_back(new mips::VectorRegister(mips::W22));
213 vec_registers_.push_back(new mips::VectorRegister(mips::W23));
214 vec_registers_.push_back(new mips::VectorRegister(mips::W24));
215 vec_registers_.push_back(new mips::VectorRegister(mips::W25));
216 vec_registers_.push_back(new mips::VectorRegister(mips::W26));
217 vec_registers_.push_back(new mips::VectorRegister(mips::W27));
218 vec_registers_.push_back(new mips::VectorRegister(mips::W28));
219 vec_registers_.push_back(new mips::VectorRegister(mips::W29));
220 vec_registers_.push_back(new mips::VectorRegister(mips::W30));
221 vec_registers_.push_back(new mips::VectorRegister(mips::W31));
222 }
223 }
224
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100225 void TearDown() override {
Lena Djokic2e0a7e52017-07-06 11:55:24 +0200226 AssemblerTest::TearDown();
227 STLDeleteElements(&registers_);
228 STLDeleteElements(&fp_registers_);
229 STLDeleteElements(&vec_registers_);
230 }
231
Andreas Gampefa6a1b02018-09-07 08:11:55 -0700232 std::vector<mips::MipsLabel> GetAddresses() override {
Aart Bikcaa31e72017-09-14 17:08:50 -0700233 UNIMPLEMENTED(FATAL) << "Feature not implemented yet";
234 UNREACHABLE();
235 }
236
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100237 std::vector<mips::Register*> GetRegisters() override {
Lena Djokic2e0a7e52017-07-06 11:55:24 +0200238 return registers_;
239 }
240
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100241 std::vector<mips::FRegister*> GetFPRegisters() override {
Lena Djokic2e0a7e52017-07-06 11:55:24 +0200242 return fp_registers_;
243 }
244
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100245 std::vector<mips::VectorRegister*> GetVectorRegisters() override {
Lena Djokic2e0a7e52017-07-06 11:55:24 +0200246 return vec_registers_;
247 }
248
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100249 uint32_t CreateImmediate(int64_t imm_value) override {
Lena Djokic2e0a7e52017-07-06 11:55:24 +0200250 return imm_value;
251 }
252
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100253 std::string GetSecondaryRegisterName(const mips::Register& reg) override {
Lena Djokic2e0a7e52017-07-06 11:55:24 +0200254 CHECK(secondary_register_names_.find(reg) != secondary_register_names_.end());
255 return secondary_register_names_[reg];
256 }
257
258 std::string RepeatInsn(size_t count, const std::string& insn) {
259 std::string result;
260 for (; count != 0u; --count) {
261 result += insn;
262 }
263 return result;
264 }
265
266 private:
267 std::vector<mips::Register*> registers_;
268 std::map<mips::Register, std::string, MIPSCpuRegisterCompare> secondary_register_names_;
269
270 std::vector<mips::FRegister*> fp_registers_;
271 std::vector<mips::VectorRegister*> vec_registers_;
272 std::unique_ptr<const MipsInstructionSetFeatures> instruction_set_features_;
273};
274
275TEST_F(AssemblerMIPS32r5Test, Toolchain) {
276 EXPECT_TRUE(CheckTools());
277}
278
279TEST_F(AssemblerMIPS32r5Test, LoadQFromOffset) {
280 __ LoadQFromOffset(mips::F0, mips::A0, 0);
281 __ LoadQFromOffset(mips::F0, mips::A0, 1);
282 __ LoadQFromOffset(mips::F0, mips::A0, 2);
283 __ LoadQFromOffset(mips::F0, mips::A0, 4);
284 __ LoadQFromOffset(mips::F0, mips::A0, 8);
285 __ LoadQFromOffset(mips::F0, mips::A0, 511);
286 __ LoadQFromOffset(mips::F0, mips::A0, 512);
287 __ LoadQFromOffset(mips::F0, mips::A0, 513);
288 __ LoadQFromOffset(mips::F0, mips::A0, 514);
289 __ LoadQFromOffset(mips::F0, mips::A0, 516);
290 __ LoadQFromOffset(mips::F0, mips::A0, 1022);
291 __ LoadQFromOffset(mips::F0, mips::A0, 1024);
292 __ LoadQFromOffset(mips::F0, mips::A0, 1025);
293 __ LoadQFromOffset(mips::F0, mips::A0, 1026);
294 __ LoadQFromOffset(mips::F0, mips::A0, 1028);
295 __ LoadQFromOffset(mips::F0, mips::A0, 2044);
296 __ LoadQFromOffset(mips::F0, mips::A0, 2048);
297 __ LoadQFromOffset(mips::F0, mips::A0, 2049);
298 __ LoadQFromOffset(mips::F0, mips::A0, 2050);
299 __ LoadQFromOffset(mips::F0, mips::A0, 2052);
300 __ LoadQFromOffset(mips::F0, mips::A0, 4088);
301 __ LoadQFromOffset(mips::F0, mips::A0, 4096);
302 __ LoadQFromOffset(mips::F0, mips::A0, 4097);
303 __ LoadQFromOffset(mips::F0, mips::A0, 4098);
304 __ LoadQFromOffset(mips::F0, mips::A0, 4100);
305 __ LoadQFromOffset(mips::F0, mips::A0, 4104);
306 __ LoadQFromOffset(mips::F0, mips::A0, 0x7FFC);
307 __ LoadQFromOffset(mips::F0, mips::A0, 0x8000);
308 __ LoadQFromOffset(mips::F0, mips::A0, 0x10000);
309 __ LoadQFromOffset(mips::F0, mips::A0, 0x12345678);
310 __ LoadQFromOffset(mips::F0, mips::A0, 0x12350078);
311 __ LoadQFromOffset(mips::F0, mips::A0, -256);
312 __ LoadQFromOffset(mips::F0, mips::A0, -511);
313 __ LoadQFromOffset(mips::F0, mips::A0, -513);
314 __ LoadQFromOffset(mips::F0, mips::A0, -1022);
315 __ LoadQFromOffset(mips::F0, mips::A0, -1026);
316 __ LoadQFromOffset(mips::F0, mips::A0, -2044);
317 __ LoadQFromOffset(mips::F0, mips::A0, -2052);
318 __ LoadQFromOffset(mips::F0, mips::A0, -4096);
319 __ LoadQFromOffset(mips::F0, mips::A0, -4104);
320 __ LoadQFromOffset(mips::F0, mips::A0, -32768);
321 __ LoadQFromOffset(mips::F0, mips::A0, -36856);
322 __ LoadQFromOffset(mips::F0, mips::A0, 36856);
323 __ LoadQFromOffset(mips::F0, mips::A0, -69608);
324 __ LoadQFromOffset(mips::F0, mips::A0, 69608);
325 __ LoadQFromOffset(mips::F0, mips::A0, 0xABCDEF00);
326 __ LoadQFromOffset(mips::F0, mips::A0, 0x7FFFABCD);
327
328 const char* expected =
329 "ld.d $w0, 0($a0)\n"
330 "ld.b $w0, 1($a0)\n"
331 "ld.h $w0, 2($a0)\n"
332 "ld.w $w0, 4($a0)\n"
333 "ld.d $w0, 8($a0)\n"
334 "ld.b $w0, 511($a0)\n"
335 "ld.d $w0, 512($a0)\n"
336 "addiu $at, $a0, 513\n"
337 "ld.b $w0, 0($at)\n"
338 "ld.h $w0, 514($a0)\n"
339 "ld.w $w0, 516($a0)\n"
340 "ld.h $w0, 1022($a0)\n"
341 "ld.d $w0, 1024($a0)\n"
342 "addiu $at, $a0, 1025\n"
343 "ld.b $w0, 0($at)\n"
344 "addiu $at, $a0, 1026\n"
345 "ld.h $w0, 0($at)\n"
346 "ld.w $w0, 1028($a0)\n"
347 "ld.w $w0, 2044($a0)\n"
348 "ld.d $w0, 2048($a0)\n"
349 "addiu $at, $a0, 2049\n"
350 "ld.b $w0, 0($at)\n"
351 "addiu $at, $a0, 2050\n"
352 "ld.h $w0, 0($at)\n"
353 "addiu $at, $a0, 2052\n"
354 "ld.w $w0, 0($at)\n"
355 "ld.d $w0, 4088($a0)\n"
356 "addiu $at, $a0, 4096\n"
357 "ld.d $w0, 0($at)\n"
358 "addiu $at, $a0, 4097\n"
359 "ld.b $w0, 0($at)\n"
360 "addiu $at, $a0, 4098\n"
361 "ld.h $w0, 0($at)\n"
362 "addiu $at, $a0, 4100\n"
363 "ld.w $w0, 0($at)\n"
364 "addiu $at, $a0, 4104\n"
365 "ld.d $w0, 0($at)\n"
366 "addiu $at, $a0, 0x7FFC\n"
367 "ld.w $w0, 0($at)\n"
368 "addiu $at, $a0, 0x7FF8\n"
369 "ld.d $w0, 8($at)\n"
370 "addiu $at, $a0, 32760\n"
371 "addiu $at, $at, 32760\n"
372 "ld.d $w0, 16($at)\n"
373 "lui $at, 4660\n"
374 "addu $at, $at, $a0\n"
375 "addiu $at, $at, 24576\n"
376 "ld.d $w0, -2440($at) # 0xF678\n"
377 "lui $at, 4661\n"
378 "addu $at, $at, $a0\n"
379 "ld.d $w0, 120($at)\n"
380 "ld.d $w0, -256($a0)\n"
381 "ld.b $w0, -511($a0)\n"
382 "addiu $at, $a0, -513\n"
383 "ld.b $w0, 0($at)\n"
384 "ld.h $w0, -1022($a0)\n"
385 "addiu $at, $a0, -1026\n"
386 "ld.h $w0, 0($at)\n"
387 "ld.w $w0, -2044($a0)\n"
388 "addiu $at, $a0, -2052\n"
389 "ld.w $w0, 0($at)\n"
390 "ld.d $w0, -4096($a0)\n"
391 "addiu $at, $a0, -4104\n"
392 "ld.d $w0, 0($at)\n"
393 "addiu $at, $a0, -32768\n"
394 "ld.d $w0, 0($at)\n"
395 "addiu $at, $a0, -32760\n"
396 "addiu $at, $at, -4096\n"
397 "ld.d $w0, 0($at)\n"
398 "addiu $at, $a0, 32760\n"
399 "addiu $at, $at, 4096\n"
400 "ld.d $w0, 0($at)\n"
401 "addiu $at, $a0, -32760\n"
402 "addiu $at, $at, -32760\n"
403 "ld.d $w0, -4088($at)\n"
404 "addiu $at, $a0, 32760\n"
405 "addiu $at, $at, 32760\n"
406 "ld.d $w0, 4088($at)\n"
407 "lui $at, 0xABCE\n"
408 "addu $at, $at, $a0\n"
409 "addiu $at, $at, -8192 # 0xE000\n"
410 "ld.d $w0, 0xF00($at)\n"
411 "lui $at, 0x8000\n"
412 "addu $at, $at, $a0\n"
413 "addiu $at, $at, -21504 # 0xAC00\n"
414 "ld.b $w0, -51($at) # 0xFFCD\n";
415 DriverStr(expected, "LoadQFromOffset");
416}
417
418TEST_F(AssemblerMIPS32r5Test, StoreQToOffset) {
419 __ StoreQToOffset(mips::F0, mips::A0, 0);
420 __ StoreQToOffset(mips::F0, mips::A0, 1);
421 __ StoreQToOffset(mips::F0, mips::A0, 2);
422 __ StoreQToOffset(mips::F0, mips::A0, 4);
423 __ StoreQToOffset(mips::F0, mips::A0, 8);
424 __ StoreQToOffset(mips::F0, mips::A0, 511);
425 __ StoreQToOffset(mips::F0, mips::A0, 512);
426 __ StoreQToOffset(mips::F0, mips::A0, 513);
427 __ StoreQToOffset(mips::F0, mips::A0, 514);
428 __ StoreQToOffset(mips::F0, mips::A0, 516);
429 __ StoreQToOffset(mips::F0, mips::A0, 1022);
430 __ StoreQToOffset(mips::F0, mips::A0, 1024);
431 __ StoreQToOffset(mips::F0, mips::A0, 1025);
432 __ StoreQToOffset(mips::F0, mips::A0, 1026);
433 __ StoreQToOffset(mips::F0, mips::A0, 1028);
434 __ StoreQToOffset(mips::F0, mips::A0, 2044);
435 __ StoreQToOffset(mips::F0, mips::A0, 2048);
436 __ StoreQToOffset(mips::F0, mips::A0, 2049);
437 __ StoreQToOffset(mips::F0, mips::A0, 2050);
438 __ StoreQToOffset(mips::F0, mips::A0, 2052);
439 __ StoreQToOffset(mips::F0, mips::A0, 4088);
440 __ StoreQToOffset(mips::F0, mips::A0, 4096);
441 __ StoreQToOffset(mips::F0, mips::A0, 4097);
442 __ StoreQToOffset(mips::F0, mips::A0, 4098);
443 __ StoreQToOffset(mips::F0, mips::A0, 4100);
444 __ StoreQToOffset(mips::F0, mips::A0, 4104);
445 __ StoreQToOffset(mips::F0, mips::A0, 0x7FFC);
446 __ StoreQToOffset(mips::F0, mips::A0, 0x8000);
447 __ StoreQToOffset(mips::F0, mips::A0, 0x10000);
448 __ StoreQToOffset(mips::F0, mips::A0, 0x12345678);
449 __ StoreQToOffset(mips::F0, mips::A0, 0x12350078);
450 __ StoreQToOffset(mips::F0, mips::A0, -256);
451 __ StoreQToOffset(mips::F0, mips::A0, -511);
452 __ StoreQToOffset(mips::F0, mips::A0, -513);
453 __ StoreQToOffset(mips::F0, mips::A0, -1022);
454 __ StoreQToOffset(mips::F0, mips::A0, -1026);
455 __ StoreQToOffset(mips::F0, mips::A0, -2044);
456 __ StoreQToOffset(mips::F0, mips::A0, -2052);
457 __ StoreQToOffset(mips::F0, mips::A0, -4096);
458 __ StoreQToOffset(mips::F0, mips::A0, -4104);
459 __ StoreQToOffset(mips::F0, mips::A0, -32768);
460 __ StoreQToOffset(mips::F0, mips::A0, -36856);
461 __ StoreQToOffset(mips::F0, mips::A0, 36856);
462 __ StoreQToOffset(mips::F0, mips::A0, -69608);
463 __ StoreQToOffset(mips::F0, mips::A0, 69608);
464 __ StoreQToOffset(mips::F0, mips::A0, 0xABCDEF00);
465 __ StoreQToOffset(mips::F0, mips::A0, 0x7FFFABCD);
466
467 const char* expected =
468 "st.d $w0, 0($a0)\n"
469 "st.b $w0, 1($a0)\n"
470 "st.h $w0, 2($a0)\n"
471 "st.w $w0, 4($a0)\n"
472 "st.d $w0, 8($a0)\n"
473 "st.b $w0, 511($a0)\n"
474 "st.d $w0, 512($a0)\n"
475 "addiu $at, $a0, 513\n"
476 "st.b $w0, 0($at)\n"
477 "st.h $w0, 514($a0)\n"
478 "st.w $w0, 516($a0)\n"
479 "st.h $w0, 1022($a0)\n"
480 "st.d $w0, 1024($a0)\n"
481 "addiu $at, $a0, 1025\n"
482 "st.b $w0, 0($at)\n"
483 "addiu $at, $a0, 1026\n"
484 "st.h $w0, 0($at)\n"
485 "st.w $w0, 1028($a0)\n"
486 "st.w $w0, 2044($a0)\n"
487 "st.d $w0, 2048($a0)\n"
488 "addiu $at, $a0, 2049\n"
489 "st.b $w0, 0($at)\n"
490 "addiu $at, $a0, 2050\n"
491 "st.h $w0, 0($at)\n"
492 "addiu $at, $a0, 2052\n"
493 "st.w $w0, 0($at)\n"
494 "st.d $w0, 4088($a0)\n"
495 "addiu $at, $a0, 4096\n"
496 "st.d $w0, 0($at)\n"
497 "addiu $at, $a0, 4097\n"
498 "st.b $w0, 0($at)\n"
499 "addiu $at, $a0, 4098\n"
500 "st.h $w0, 0($at)\n"
501 "addiu $at, $a0, 4100\n"
502 "st.w $w0, 0($at)\n"
503 "addiu $at, $a0, 4104\n"
504 "st.d $w0, 0($at)\n"
505 "addiu $at, $a0, 0x7FFC\n"
506 "st.w $w0, 0($at)\n"
507 "addiu $at, $a0, 0x7FF8\n"
508 "st.d $w0, 8($at)\n"
509 "addiu $at, $a0, 32760\n"
510 "addiu $at, $at, 32760\n"
511 "st.d $w0, 16($at)\n"
512 "lui $at, 4660\n"
513 "addu $at, $at, $a0\n"
514 "addiu $at, $at, 24576\n"
515 "st.d $w0, -2440($at) # 0xF678\n"
516 "lui $at, 4661\n"
517 "addu $at, $at, $a0\n"
518 "st.d $w0, 120($at)\n"
519 "st.d $w0, -256($a0)\n"
520 "st.b $w0, -511($a0)\n"
521 "addiu $at, $a0, -513\n"
522 "st.b $w0, 0($at)\n"
523 "st.h $w0, -1022($a0)\n"
524 "addiu $at, $a0, -1026\n"
525 "st.h $w0, 0($at)\n"
526 "st.w $w0, -2044($a0)\n"
527 "addiu $at, $a0, -2052\n"
528 "st.w $w0, 0($at)\n"
529 "st.d $w0, -4096($a0)\n"
530 "addiu $at, $a0, -4104\n"
531 "st.d $w0, 0($at)\n"
532 "addiu $at, $a0, -32768\n"
533 "st.d $w0, 0($at)\n"
534 "addiu $at, $a0, -32760\n"
535 "addiu $at, $at, -4096\n"
536 "st.d $w0, 0($at)\n"
537 "addiu $at, $a0, 32760\n"
538 "addiu $at, $at, 4096\n"
539 "st.d $w0, 0($at)\n"
540 "addiu $at, $a0, -32760\n"
541 "addiu $at, $at, -32760\n"
542 "st.d $w0, -4088($at)\n"
543 "addiu $at, $a0, 32760\n"
544 "addiu $at, $at, 32760\n"
545 "st.d $w0, 4088($at)\n"
546 "lui $at, 0xABCE\n"
547 "addu $at, $at, $a0\n"
548 "addiu $at, $at, -8192 # 0xE000\n"
549 "st.d $w0, 0xF00($at)\n"
550 "lui $at, 0x8000\n"
551 "addu $at, $at, $a0\n"
552 "addiu $at, $at, -21504 # 0xAC00\n"
553 "st.b $w0, -51($at) # 0xFFCD\n";
554 DriverStr(expected, "StoreQToOffset");
555}
556
557#undef __
558} // namespace art