blob: cb01cea8ef6050608bb2e5052c0d07694f10f108 [file] [log] [blame]
Dave Allison65fcc2c2014-04-28 13:45:27 -07001/*
2 * Copyright (C) 2014 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
Nicolas Geoffray96f89a22014-07-11 10:57:49 +010017#include <dirent.h>
Andreas Gampefd114702015-05-13 17:00:41 -070018#include <errno.h>
Dave Allison65fcc2c2014-04-28 13:45:27 -070019#include <fstream>
Nicolas Geoffray96f89a22014-07-11 10:57:49 +010020#include <map>
Andreas Gampefd114702015-05-13 17:00:41 -070021#include <string.h>
22#include <sys/types.h>
Dave Allison65fcc2c2014-04-28 13:45:27 -070023
24#include "gtest/gtest.h"
25#include "utils/arm/assembler_thumb2.h"
26#include "base/hex_dump.h"
27#include "common_runtime_test.h"
28
29namespace art {
30namespace arm {
31
32// Include results file (generated manually)
33#include "assembler_thumb_test_expected.cc.inc"
34
Andreas Gampec60e1b72015-07-30 08:57:50 -070035#ifndef __ANDROID__
Dave Allison45fdb932014-06-25 12:37:10 -070036// This controls whether the results are printed to the
37// screen or compared against the expected output.
38// To generate new expected output, set this to true and
39// copy the output into the .cc.inc file in the form
40// of the other results.
41//
42// When this is false, the results are not printed to the
43// output, but are compared against the expected results
44// in the .cc.inc file.
Dave Allison65fcc2c2014-04-28 13:45:27 -070045static constexpr bool kPrintResults = false;
Dave Allisond20ddb22014-06-05 14:16:30 -070046#endif
Dave Allison65fcc2c2014-04-28 13:45:27 -070047
48void SetAndroidData() {
49 const char* data = getenv("ANDROID_DATA");
50 if (data == nullptr) {
51 setenv("ANDROID_DATA", "/tmp", 1);
52 }
53}
54
Dave Allison45fdb932014-06-25 12:37:10 -070055int CompareIgnoringSpace(const char* s1, const char* s2) {
56 while (*s1 != '\0') {
57 while (isspace(*s1)) ++s1;
58 while (isspace(*s2)) ++s2;
59 if (*s1 == '\0' || *s1 != *s2) {
60 break;
61 }
62 ++s1;
63 ++s2;
64 }
65 return *s1 - *s2;
66}
67
Vladimir Markocf93a5c2015-06-16 11:33:24 +000068void InitResults() {
69 if (test_results.empty()) {
70 setup_results();
71 }
72}
73
74std::string GetToolsDir() {
Andreas Gampec60e1b72015-07-30 08:57:50 -070075#ifndef __ANDROID__
Vladimir Markocf93a5c2015-06-16 11:33:24 +000076 // This will only work on the host. There is no as, objcopy or objdump on the device.
Dave Allison65fcc2c2014-04-28 13:45:27 -070077 static std::string toolsdir;
78
Vladimir Markocf93a5c2015-06-16 11:33:24 +000079 if (toolsdir.empty()) {
Dave Allison65fcc2c2014-04-28 13:45:27 -070080 setup_results();
David Srbecky3e52aa42015-04-12 07:45:18 +010081 toolsdir = CommonRuntimeTest::GetAndroidTargetToolsDir(kThumb2);
Dave Allison65fcc2c2014-04-28 13:45:27 -070082 SetAndroidData();
Dave Allison65fcc2c2014-04-28 13:45:27 -070083 }
84
Vladimir Markocf93a5c2015-06-16 11:33:24 +000085 return toolsdir;
86#else
87 return std::string();
88#endif
89}
90
91void DumpAndCheck(std::vector<uint8_t>& code, const char* testname, const char* const* results) {
Andreas Gampec60e1b72015-07-30 08:57:50 -070092#ifndef __ANDROID__
Vladimir Markocf93a5c2015-06-16 11:33:24 +000093 static std::string toolsdir = GetToolsDir();
94
Dave Allison65fcc2c2014-04-28 13:45:27 -070095 ScratchFile file;
96
97 const char* filename = file.GetFilename().c_str();
98
99 std::ofstream out(filename);
100 if (out) {
101 out << ".section \".text\"\n";
102 out << ".syntax unified\n";
103 out << ".arch armv7-a\n";
104 out << ".thumb\n";
105 out << ".thumb_func\n";
106 out << ".type " << testname << ", #function\n";
107 out << ".global " << testname << "\n";
108 out << testname << ":\n";
109 out << ".fnstart\n";
110
111 for (uint32_t i = 0 ; i < code.size(); ++i) {
112 out << ".byte " << (static_cast<int>(code[i]) & 0xff) << "\n";
113 }
114 out << ".fnend\n";
115 out << ".size " << testname << ", .-" << testname << "\n";
116 }
117 out.close();
118
Andreas Gampe4470c1d2014-07-21 18:32:59 -0700119 char cmd[1024];
Dave Allison65fcc2c2014-04-28 13:45:27 -0700120
121 // Assemble the .S
David Srbecky3e52aa42015-04-12 07:45:18 +0100122 snprintf(cmd, sizeof(cmd), "%sas %s -o %s.o", toolsdir.c_str(), filename, filename);
Andreas Gampefd114702015-05-13 17:00:41 -0700123 int cmd_result = system(cmd);
124 ASSERT_EQ(cmd_result, 0) << strerror(errno);
Dave Allison65fcc2c2014-04-28 13:45:27 -0700125
126 // Remove the $d symbols to prevent the disassembler dumping the instructions
127 // as .word
David Srbecky3e52aa42015-04-12 07:45:18 +0100128 snprintf(cmd, sizeof(cmd), "%sobjcopy -N '$d' %s.o %s.oo", toolsdir.c_str(), filename, filename);
Andreas Gampefd114702015-05-13 17:00:41 -0700129 int cmd_result2 = system(cmd);
130 ASSERT_EQ(cmd_result2, 0) << strerror(errno);
Dave Allison65fcc2c2014-04-28 13:45:27 -0700131
132 // Disassemble.
133
David Srbecky3e52aa42015-04-12 07:45:18 +0100134 snprintf(cmd, sizeof(cmd), "%sobjdump -d %s.oo | grep '^ *[0-9a-f][0-9a-f]*:'",
135 toolsdir.c_str(), filename);
Dave Allison65fcc2c2014-04-28 13:45:27 -0700136 if (kPrintResults) {
137 // Print the results only, don't check. This is used to generate new output for inserting
138 // into the .inc file.
Andreas Gampefd114702015-05-13 17:00:41 -0700139 int cmd_result3 = system(cmd);
140 ASSERT_EQ(cmd_result3, 0) << strerror(errno);
Dave Allison65fcc2c2014-04-28 13:45:27 -0700141 } else {
142 // Check the results match the appropriate results in the .inc file.
143 FILE *fp = popen(cmd, "r");
144 ASSERT_TRUE(fp != nullptr);
145
Dave Allison65fcc2c2014-04-28 13:45:27 -0700146 uint32_t lineindex = 0;
147
148 while (!feof(fp)) {
149 char testline[256];
150 char *s = fgets(testline, sizeof(testline), fp);
151 if (s == nullptr) {
152 break;
153 }
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000154 if (CompareIgnoringSpace(results[lineindex], testline) != 0) {
Dave Allison45fdb932014-06-25 12:37:10 -0700155 LOG(FATAL) << "Output is not as expected at line: " << lineindex
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000156 << results[lineindex] << "/" << testline;
Dave Allison45fdb932014-06-25 12:37:10 -0700157 }
Dave Allison65fcc2c2014-04-28 13:45:27 -0700158 ++lineindex;
159 }
160 // Check that we are at the end.
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000161 ASSERT_TRUE(results[lineindex] == nullptr);
Dave Allison65fcc2c2014-04-28 13:45:27 -0700162 fclose(fp);
163 }
164
165 char buf[FILENAME_MAX];
166 snprintf(buf, sizeof(buf), "%s.o", filename);
167 unlink(buf);
168
169 snprintf(buf, sizeof(buf), "%s.oo", filename);
170 unlink(buf);
171#endif
172}
173
174#define __ assembler->
175
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000176void EmitAndCheck(arm::Thumb2Assembler* assembler, const char* testname,
177 const char* const* results) {
178 __ FinalizeCode();
179 size_t cs = __ CodeSize();
180 std::vector<uint8_t> managed_code(cs);
181 MemoryRegion code(&managed_code[0], managed_code.size());
182 __ FinalizeInstructions(code);
183
184 DumpAndCheck(managed_code, testname, results);
185}
186
187void EmitAndCheck(arm::Thumb2Assembler* assembler, const char* testname) {
188 InitResults();
189 std::map<std::string, const char* const*>::iterator results = test_results.find(testname);
190 ASSERT_NE(results, test_results.end());
191
192 EmitAndCheck(assembler, testname, results->second);
193}
194
195#undef __
196
197#define __ assembler.
198
Dave Allison65fcc2c2014-04-28 13:45:27 -0700199TEST(Thumb2AssemblerTest, SimpleMov) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000200 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700201
202 __ mov(R0, ShifterOperand(R1));
203 __ mov(R8, ShifterOperand(R9));
204
205 __ mov(R0, ShifterOperand(1));
206 __ mov(R8, ShifterOperand(9));
207
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000208 EmitAndCheck(&assembler, "SimpleMov");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700209}
210
211TEST(Thumb2AssemblerTest, SimpleMov32) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000212 arm::Thumb2Assembler assembler;
213 __ Force32Bit();
Dave Allison65fcc2c2014-04-28 13:45:27 -0700214
215 __ mov(R0, ShifterOperand(R1));
216 __ mov(R8, ShifterOperand(R9));
217
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000218 EmitAndCheck(&assembler, "SimpleMov32");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700219}
220
221TEST(Thumb2AssemblerTest, SimpleMovAdd) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000222 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700223
224 __ mov(R0, ShifterOperand(R1));
225 __ add(R0, R1, ShifterOperand(R2));
226 __ add(R0, R1, ShifterOperand());
227
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000228 EmitAndCheck(&assembler, "SimpleMovAdd");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700229}
230
231TEST(Thumb2AssemblerTest, DataProcessingRegister) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000232 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700233
234 __ mov(R0, ShifterOperand(R1));
235 __ mvn(R0, ShifterOperand(R1));
236
237 // 32 bit variants.
238 __ add(R0, R1, ShifterOperand(R2));
239 __ sub(R0, R1, ShifterOperand(R2));
240 __ and_(R0, R1, ShifterOperand(R2));
241 __ orr(R0, R1, ShifterOperand(R2));
242 __ eor(R0, R1, ShifterOperand(R2));
243 __ bic(R0, R1, ShifterOperand(R2));
244 __ adc(R0, R1, ShifterOperand(R2));
245 __ sbc(R0, R1, ShifterOperand(R2));
246 __ rsb(R0, R1, ShifterOperand(R2));
247
248 // 16 bit variants.
249 __ add(R0, R1, ShifterOperand());
250 __ sub(R0, R1, ShifterOperand());
Andreas Gampe7b7e5242015-02-02 19:17:11 -0800251 __ and_(R0, R0, ShifterOperand(R1));
252 __ orr(R0, R0, ShifterOperand(R1));
253 __ eor(R0, R0, ShifterOperand(R1));
254 __ bic(R0, R0, ShifterOperand(R1));
255 __ adc(R0, R0, ShifterOperand(R1));
256 __ sbc(R0, R0, ShifterOperand(R1));
257 __ rsb(R0, R0, ShifterOperand(R1));
Dave Allison65fcc2c2014-04-28 13:45:27 -0700258
259 __ tst(R0, ShifterOperand(R1));
260 __ teq(R0, ShifterOperand(R1));
261 __ cmp(R0, ShifterOperand(R1));
262 __ cmn(R0, ShifterOperand(R1));
263
264 __ movs(R0, ShifterOperand(R1));
265 __ mvns(R0, ShifterOperand(R1));
266
Nicolas Geoffray3c7bb982014-07-23 16:04:16 +0100267 // 32 bit variants.
268 __ add(R12, R1, ShifterOperand(R0));
269
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000270 EmitAndCheck(&assembler, "DataProcessingRegister");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700271}
272
273TEST(Thumb2AssemblerTest, DataProcessingImmediate) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000274 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700275
276 __ mov(R0, ShifterOperand(0x55));
277 __ mvn(R0, ShifterOperand(0x55));
278 __ add(R0, R1, ShifterOperand(0x55));
279 __ sub(R0, R1, ShifterOperand(0x55));
280 __ and_(R0, R1, ShifterOperand(0x55));
281 __ orr(R0, R1, ShifterOperand(0x55));
282 __ eor(R0, R1, ShifterOperand(0x55));
283 __ bic(R0, R1, ShifterOperand(0x55));
284 __ adc(R0, R1, ShifterOperand(0x55));
285 __ sbc(R0, R1, ShifterOperand(0x55));
286 __ rsb(R0, R1, ShifterOperand(0x55));
287
288 __ tst(R0, ShifterOperand(0x55));
289 __ teq(R0, ShifterOperand(0x55));
290 __ cmp(R0, ShifterOperand(0x55));
291 __ cmn(R0, ShifterOperand(0x55));
292
293 __ add(R0, R1, ShifterOperand(5));
294 __ sub(R0, R1, ShifterOperand(5));
295
296 __ movs(R0, ShifterOperand(0x55));
297 __ mvns(R0, ShifterOperand(0x55));
298
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000299 EmitAndCheck(&assembler, "DataProcessingImmediate");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700300}
301
302TEST(Thumb2AssemblerTest, DataProcessingModifiedImmediate) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000303 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700304
305 __ mov(R0, ShifterOperand(0x550055));
306 __ mvn(R0, ShifterOperand(0x550055));
307 __ add(R0, R1, ShifterOperand(0x550055));
308 __ sub(R0, R1, ShifterOperand(0x550055));
309 __ and_(R0, R1, ShifterOperand(0x550055));
310 __ orr(R0, R1, ShifterOperand(0x550055));
311 __ eor(R0, R1, ShifterOperand(0x550055));
312 __ bic(R0, R1, ShifterOperand(0x550055));
313 __ adc(R0, R1, ShifterOperand(0x550055));
314 __ sbc(R0, R1, ShifterOperand(0x550055));
315 __ rsb(R0, R1, ShifterOperand(0x550055));
316
317 __ tst(R0, ShifterOperand(0x550055));
318 __ teq(R0, ShifterOperand(0x550055));
319 __ cmp(R0, ShifterOperand(0x550055));
320 __ cmn(R0, ShifterOperand(0x550055));
321
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000322 EmitAndCheck(&assembler, "DataProcessingModifiedImmediate");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700323}
324
325
326TEST(Thumb2AssemblerTest, DataProcessingModifiedImmediates) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000327 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700328
329 __ mov(R0, ShifterOperand(0x550055));
330 __ mov(R0, ShifterOperand(0x55005500));
331 __ mov(R0, ShifterOperand(0x55555555));
332 __ mov(R0, ShifterOperand(0xd5000000)); // rotated to first position
333 __ mov(R0, ShifterOperand(0x6a000000)); // rotated to second position
334 __ mov(R0, ShifterOperand(0x350)); // rotated to 2nd last position
335 __ mov(R0, ShifterOperand(0x1a8)); // rotated to last position
336
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000337 EmitAndCheck(&assembler, "DataProcessingModifiedImmediates");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700338}
339
340TEST(Thumb2AssemblerTest, DataProcessingShiftedRegister) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000341 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700342
343 __ mov(R3, ShifterOperand(R4, LSL, 4));
344 __ mov(R3, ShifterOperand(R4, LSR, 5));
345 __ mov(R3, ShifterOperand(R4, ASR, 6));
346 __ mov(R3, ShifterOperand(R4, ROR, 7));
347 __ mov(R3, ShifterOperand(R4, ROR));
348
349 // 32 bit variants.
350 __ mov(R8, ShifterOperand(R4, LSL, 4));
351 __ mov(R8, ShifterOperand(R4, LSR, 5));
352 __ mov(R8, ShifterOperand(R4, ASR, 6));
353 __ mov(R8, ShifterOperand(R4, ROR, 7));
354 __ mov(R8, ShifterOperand(R4, RRX));
355
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000356 EmitAndCheck(&assembler, "DataProcessingShiftedRegister");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700357}
358
359
360TEST(Thumb2AssemblerTest, BasicLoad) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000361 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700362
363 __ ldr(R3, Address(R4, 24));
364 __ ldrb(R3, Address(R4, 24));
365 __ ldrh(R3, Address(R4, 24));
366 __ ldrsb(R3, Address(R4, 24));
367 __ ldrsh(R3, Address(R4, 24));
368
369 __ ldr(R3, Address(SP, 24));
370
371 // 32 bit variants
372 __ ldr(R8, Address(R4, 24));
373 __ ldrb(R8, Address(R4, 24));
374 __ ldrh(R8, Address(R4, 24));
375 __ ldrsb(R8, Address(R4, 24));
376 __ ldrsh(R8, Address(R4, 24));
377
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000378 EmitAndCheck(&assembler, "BasicLoad");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700379}
380
381
382TEST(Thumb2AssemblerTest, BasicStore) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000383 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700384
385 __ str(R3, Address(R4, 24));
386 __ strb(R3, Address(R4, 24));
387 __ strh(R3, Address(R4, 24));
388
389 __ str(R3, Address(SP, 24));
390
391 // 32 bit variants.
392 __ str(R8, Address(R4, 24));
393 __ strb(R8, Address(R4, 24));
394 __ strh(R8, Address(R4, 24));
395
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000396 EmitAndCheck(&assembler, "BasicStore");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700397}
398
399TEST(Thumb2AssemblerTest, ComplexLoad) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000400 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700401
402 __ ldr(R3, Address(R4, 24, Address::Mode::Offset));
403 __ ldr(R3, Address(R4, 24, Address::Mode::PreIndex));
404 __ ldr(R3, Address(R4, 24, Address::Mode::PostIndex));
405 __ ldr(R3, Address(R4, 24, Address::Mode::NegOffset));
406 __ ldr(R3, Address(R4, 24, Address::Mode::NegPreIndex));
407 __ ldr(R3, Address(R4, 24, Address::Mode::NegPostIndex));
408
409 __ ldrb(R3, Address(R4, 24, Address::Mode::Offset));
410 __ ldrb(R3, Address(R4, 24, Address::Mode::PreIndex));
411 __ ldrb(R3, Address(R4, 24, Address::Mode::PostIndex));
412 __ ldrb(R3, Address(R4, 24, Address::Mode::NegOffset));
413 __ ldrb(R3, Address(R4, 24, Address::Mode::NegPreIndex));
414 __ ldrb(R3, Address(R4, 24, Address::Mode::NegPostIndex));
415
416 __ ldrh(R3, Address(R4, 24, Address::Mode::Offset));
417 __ ldrh(R3, Address(R4, 24, Address::Mode::PreIndex));
418 __ ldrh(R3, Address(R4, 24, Address::Mode::PostIndex));
419 __ ldrh(R3, Address(R4, 24, Address::Mode::NegOffset));
420 __ ldrh(R3, Address(R4, 24, Address::Mode::NegPreIndex));
421 __ ldrh(R3, Address(R4, 24, Address::Mode::NegPostIndex));
422
423 __ ldrsb(R3, Address(R4, 24, Address::Mode::Offset));
424 __ ldrsb(R3, Address(R4, 24, Address::Mode::PreIndex));
425 __ ldrsb(R3, Address(R4, 24, Address::Mode::PostIndex));
426 __ ldrsb(R3, Address(R4, 24, Address::Mode::NegOffset));
427 __ ldrsb(R3, Address(R4, 24, Address::Mode::NegPreIndex));
428 __ ldrsb(R3, Address(R4, 24, Address::Mode::NegPostIndex));
429
430 __ ldrsh(R3, Address(R4, 24, Address::Mode::Offset));
431 __ ldrsh(R3, Address(R4, 24, Address::Mode::PreIndex));
432 __ ldrsh(R3, Address(R4, 24, Address::Mode::PostIndex));
433 __ ldrsh(R3, Address(R4, 24, Address::Mode::NegOffset));
434 __ ldrsh(R3, Address(R4, 24, Address::Mode::NegPreIndex));
435 __ ldrsh(R3, Address(R4, 24, Address::Mode::NegPostIndex));
436
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000437 EmitAndCheck(&assembler, "ComplexLoad");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700438}
439
440
441TEST(Thumb2AssemblerTest, ComplexStore) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000442 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700443
444 __ str(R3, Address(R4, 24, Address::Mode::Offset));
445 __ str(R3, Address(R4, 24, Address::Mode::PreIndex));
446 __ str(R3, Address(R4, 24, Address::Mode::PostIndex));
447 __ str(R3, Address(R4, 24, Address::Mode::NegOffset));
448 __ str(R3, Address(R4, 24, Address::Mode::NegPreIndex));
449 __ str(R3, Address(R4, 24, Address::Mode::NegPostIndex));
450
451 __ strb(R3, Address(R4, 24, Address::Mode::Offset));
452 __ strb(R3, Address(R4, 24, Address::Mode::PreIndex));
453 __ strb(R3, Address(R4, 24, Address::Mode::PostIndex));
454 __ strb(R3, Address(R4, 24, Address::Mode::NegOffset));
455 __ strb(R3, Address(R4, 24, Address::Mode::NegPreIndex));
456 __ strb(R3, Address(R4, 24, Address::Mode::NegPostIndex));
457
458 __ strh(R3, Address(R4, 24, Address::Mode::Offset));
459 __ strh(R3, Address(R4, 24, Address::Mode::PreIndex));
460 __ strh(R3, Address(R4, 24, Address::Mode::PostIndex));
461 __ strh(R3, Address(R4, 24, Address::Mode::NegOffset));
462 __ strh(R3, Address(R4, 24, Address::Mode::NegPreIndex));
463 __ strh(R3, Address(R4, 24, Address::Mode::NegPostIndex));
464
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000465 EmitAndCheck(&assembler, "ComplexStore");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700466}
467
468TEST(Thumb2AssemblerTest, NegativeLoadStore) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000469 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700470
471 __ ldr(R3, Address(R4, -24, Address::Mode::Offset));
472 __ ldr(R3, Address(R4, -24, Address::Mode::PreIndex));
473 __ ldr(R3, Address(R4, -24, Address::Mode::PostIndex));
474 __ ldr(R3, Address(R4, -24, Address::Mode::NegOffset));
475 __ ldr(R3, Address(R4, -24, Address::Mode::NegPreIndex));
476 __ ldr(R3, Address(R4, -24, Address::Mode::NegPostIndex));
477
478 __ ldrb(R3, Address(R4, -24, Address::Mode::Offset));
479 __ ldrb(R3, Address(R4, -24, Address::Mode::PreIndex));
480 __ ldrb(R3, Address(R4, -24, Address::Mode::PostIndex));
481 __ ldrb(R3, Address(R4, -24, Address::Mode::NegOffset));
482 __ ldrb(R3, Address(R4, -24, Address::Mode::NegPreIndex));
483 __ ldrb(R3, Address(R4, -24, Address::Mode::NegPostIndex));
484
485 __ ldrh(R3, Address(R4, -24, Address::Mode::Offset));
486 __ ldrh(R3, Address(R4, -24, Address::Mode::PreIndex));
487 __ ldrh(R3, Address(R4, -24, Address::Mode::PostIndex));
488 __ ldrh(R3, Address(R4, -24, Address::Mode::NegOffset));
489 __ ldrh(R3, Address(R4, -24, Address::Mode::NegPreIndex));
490 __ ldrh(R3, Address(R4, -24, Address::Mode::NegPostIndex));
491
492 __ ldrsb(R3, Address(R4, -24, Address::Mode::Offset));
493 __ ldrsb(R3, Address(R4, -24, Address::Mode::PreIndex));
494 __ ldrsb(R3, Address(R4, -24, Address::Mode::PostIndex));
495 __ ldrsb(R3, Address(R4, -24, Address::Mode::NegOffset));
496 __ ldrsb(R3, Address(R4, -24, Address::Mode::NegPreIndex));
497 __ ldrsb(R3, Address(R4, -24, Address::Mode::NegPostIndex));
498
499 __ ldrsh(R3, Address(R4, -24, Address::Mode::Offset));
500 __ ldrsh(R3, Address(R4, -24, Address::Mode::PreIndex));
501 __ ldrsh(R3, Address(R4, -24, Address::Mode::PostIndex));
502 __ ldrsh(R3, Address(R4, -24, Address::Mode::NegOffset));
503 __ ldrsh(R3, Address(R4, -24, Address::Mode::NegPreIndex));
504 __ ldrsh(R3, Address(R4, -24, Address::Mode::NegPostIndex));
505
506 __ str(R3, Address(R4, -24, Address::Mode::Offset));
507 __ str(R3, Address(R4, -24, Address::Mode::PreIndex));
508 __ str(R3, Address(R4, -24, Address::Mode::PostIndex));
509 __ str(R3, Address(R4, -24, Address::Mode::NegOffset));
510 __ str(R3, Address(R4, -24, Address::Mode::NegPreIndex));
511 __ str(R3, Address(R4, -24, Address::Mode::NegPostIndex));
512
513 __ strb(R3, Address(R4, -24, Address::Mode::Offset));
514 __ strb(R3, Address(R4, -24, Address::Mode::PreIndex));
515 __ strb(R3, Address(R4, -24, Address::Mode::PostIndex));
516 __ strb(R3, Address(R4, -24, Address::Mode::NegOffset));
517 __ strb(R3, Address(R4, -24, Address::Mode::NegPreIndex));
518 __ strb(R3, Address(R4, -24, Address::Mode::NegPostIndex));
519
520 __ strh(R3, Address(R4, -24, Address::Mode::Offset));
521 __ strh(R3, Address(R4, -24, Address::Mode::PreIndex));
522 __ strh(R3, Address(R4, -24, Address::Mode::PostIndex));
523 __ strh(R3, Address(R4, -24, Address::Mode::NegOffset));
524 __ strh(R3, Address(R4, -24, Address::Mode::NegPreIndex));
525 __ strh(R3, Address(R4, -24, Address::Mode::NegPostIndex));
526
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000527 EmitAndCheck(&assembler, "NegativeLoadStore");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700528}
529
530TEST(Thumb2AssemblerTest, SimpleLoadStoreDual) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000531 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700532
533 __ strd(R2, Address(R0, 24, Address::Mode::Offset));
534 __ ldrd(R2, Address(R0, 24, Address::Mode::Offset));
535
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000536 EmitAndCheck(&assembler, "SimpleLoadStoreDual");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700537}
538
539TEST(Thumb2AssemblerTest, ComplexLoadStoreDual) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000540 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700541
542 __ strd(R2, Address(R0, 24, Address::Mode::Offset));
543 __ strd(R2, Address(R0, 24, Address::Mode::PreIndex));
544 __ strd(R2, Address(R0, 24, Address::Mode::PostIndex));
545 __ strd(R2, Address(R0, 24, Address::Mode::NegOffset));
546 __ strd(R2, Address(R0, 24, Address::Mode::NegPreIndex));
547 __ strd(R2, Address(R0, 24, Address::Mode::NegPostIndex));
548
549 __ ldrd(R2, Address(R0, 24, Address::Mode::Offset));
550 __ ldrd(R2, Address(R0, 24, Address::Mode::PreIndex));
551 __ ldrd(R2, Address(R0, 24, Address::Mode::PostIndex));
552 __ ldrd(R2, Address(R0, 24, Address::Mode::NegOffset));
553 __ ldrd(R2, Address(R0, 24, Address::Mode::NegPreIndex));
554 __ ldrd(R2, Address(R0, 24, Address::Mode::NegPostIndex));
555
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000556 EmitAndCheck(&assembler, "ComplexLoadStoreDual");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700557}
558
559TEST(Thumb2AssemblerTest, NegativeLoadStoreDual) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000560 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700561
562 __ strd(R2, Address(R0, -24, Address::Mode::Offset));
563 __ strd(R2, Address(R0, -24, Address::Mode::PreIndex));
564 __ strd(R2, Address(R0, -24, Address::Mode::PostIndex));
565 __ strd(R2, Address(R0, -24, Address::Mode::NegOffset));
566 __ strd(R2, Address(R0, -24, Address::Mode::NegPreIndex));
567 __ strd(R2, Address(R0, -24, Address::Mode::NegPostIndex));
568
569 __ ldrd(R2, Address(R0, -24, Address::Mode::Offset));
570 __ ldrd(R2, Address(R0, -24, Address::Mode::PreIndex));
571 __ ldrd(R2, Address(R0, -24, Address::Mode::PostIndex));
572 __ ldrd(R2, Address(R0, -24, Address::Mode::NegOffset));
573 __ ldrd(R2, Address(R0, -24, Address::Mode::NegPreIndex));
574 __ ldrd(R2, Address(R0, -24, Address::Mode::NegPostIndex));
575
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000576 EmitAndCheck(&assembler, "NegativeLoadStoreDual");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700577}
578
579TEST(Thumb2AssemblerTest, SimpleBranch) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000580 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700581
582 Label l1;
583 __ mov(R0, ShifterOperand(2));
584 __ Bind(&l1);
585 __ mov(R1, ShifterOperand(1));
586 __ b(&l1);
587 Label l2;
588 __ b(&l2);
589 __ mov(R1, ShifterOperand(2));
590 __ Bind(&l2);
591 __ mov(R0, ShifterOperand(3));
592
593 Label l3;
594 __ mov(R0, ShifterOperand(2));
595 __ Bind(&l3);
596 __ mov(R1, ShifterOperand(1));
597 __ b(&l3, EQ);
598
599 Label l4;
600 __ b(&l4, EQ);
601 __ mov(R1, ShifterOperand(2));
602 __ Bind(&l4);
603 __ mov(R0, ShifterOperand(3));
604
605 // 2 linked labels.
606 Label l5;
607 __ b(&l5);
608 __ mov(R1, ShifterOperand(4));
609 __ b(&l5);
610 __ mov(R1, ShifterOperand(5));
611 __ Bind(&l5);
612 __ mov(R0, ShifterOperand(6));
613
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000614 EmitAndCheck(&assembler, "SimpleBranch");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700615}
616
617TEST(Thumb2AssemblerTest, LongBranch) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000618 arm::Thumb2Assembler assembler;
619 __ Force32Bit();
Dave Allison65fcc2c2014-04-28 13:45:27 -0700620 // 32 bit branches.
621 Label l1;
622 __ mov(R0, ShifterOperand(2));
623 __ Bind(&l1);
624 __ mov(R1, ShifterOperand(1));
625 __ b(&l1);
626
627 Label l2;
628 __ b(&l2);
629 __ mov(R1, ShifterOperand(2));
630 __ Bind(&l2);
631 __ mov(R0, ShifterOperand(3));
632
633 Label l3;
634 __ mov(R0, ShifterOperand(2));
635 __ Bind(&l3);
636 __ mov(R1, ShifterOperand(1));
637 __ b(&l3, EQ);
638
639 Label l4;
640 __ b(&l4, EQ);
641 __ mov(R1, ShifterOperand(2));
642 __ Bind(&l4);
643 __ mov(R0, ShifterOperand(3));
644
645 // 2 linked labels.
646 Label l5;
647 __ b(&l5);
648 __ mov(R1, ShifterOperand(4));
649 __ b(&l5);
650 __ mov(R1, ShifterOperand(5));
651 __ Bind(&l5);
652 __ mov(R0, ShifterOperand(6));
653
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000654 EmitAndCheck(&assembler, "LongBranch");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700655}
656
657TEST(Thumb2AssemblerTest, LoadMultiple) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000658 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700659
660 // 16 bit.
661 __ ldm(DB_W, R4, (1 << R0 | 1 << R3));
662
663 // 32 bit.
664 __ ldm(DB_W, R4, (1 << LR | 1 << R11));
665 __ ldm(DB, R4, (1 << LR | 1 << R11));
666
667 // Single reg is converted to ldr
668 __ ldm(DB_W, R4, (1 << R5));
669
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000670 EmitAndCheck(&assembler, "LoadMultiple");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700671}
672
673TEST(Thumb2AssemblerTest, StoreMultiple) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000674 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700675
676 // 16 bit.
677 __ stm(IA_W, R4, (1 << R0 | 1 << R3));
678
679 // 32 bit.
680 __ stm(IA_W, R4, (1 << LR | 1 << R11));
681 __ stm(IA, R4, (1 << LR | 1 << R11));
682
683 // Single reg is converted to str
684 __ stm(IA_W, R4, (1 << R5));
685 __ stm(IA, R4, (1 << R5));
686
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000687 EmitAndCheck(&assembler, "StoreMultiple");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700688}
689
690TEST(Thumb2AssemblerTest, MovWMovT) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000691 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700692
693 __ movw(R4, 0); // 16 bit.
694 __ movw(R4, 0x34); // 16 bit.
695 __ movw(R9, 0x34); // 32 bit due to high register.
696 __ movw(R3, 0x1234); // 32 bit due to large value.
697 __ movw(R9, 0xffff); // 32 bit due to large value and high register.
698
699 // Always 32 bit.
700 __ movt(R0, 0);
701 __ movt(R0, 0x1234);
702 __ movt(R1, 0xffff);
703
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000704 EmitAndCheck(&assembler, "MovWMovT");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700705}
706
707TEST(Thumb2AssemblerTest, SpecialAddSub) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000708 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700709
710 __ add(R2, SP, ShifterOperand(0x50)); // 16 bit.
711 __ add(SP, SP, ShifterOperand(0x50)); // 16 bit.
712 __ add(R8, SP, ShifterOperand(0x50)); // 32 bit.
713
714 __ add(R2, SP, ShifterOperand(0xf00)); // 32 bit due to imm size.
715 __ add(SP, SP, ShifterOperand(0xf00)); // 32 bit due to imm size.
716
717 __ sub(SP, SP, ShifterOperand(0x50)); // 16 bit
718 __ sub(R0, SP, ShifterOperand(0x50)); // 32 bit
719 __ sub(R8, SP, ShifterOperand(0x50)); // 32 bit.
720
721 __ sub(SP, SP, ShifterOperand(0xf00)); // 32 bit due to imm size
722
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000723 EmitAndCheck(&assembler, "SpecialAddSub");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700724}
725
726TEST(Thumb2AssemblerTest, StoreToOffset) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000727 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700728
729 __ StoreToOffset(kStoreWord, R2, R4, 12); // Simple
730 __ StoreToOffset(kStoreWord, R2, R4, 0x2000); // Offset too big.
Nicolas Geoffray3c7bb982014-07-23 16:04:16 +0100731 __ StoreToOffset(kStoreWord, R0, R12, 12);
732 __ StoreToOffset(kStoreHalfword, R0, R12, 12);
733 __ StoreToOffset(kStoreByte, R2, R12, 12);
Dave Allison65fcc2c2014-04-28 13:45:27 -0700734
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000735 EmitAndCheck(&assembler, "StoreToOffset");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700736}
737
738
739TEST(Thumb2AssemblerTest, IfThen) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000740 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700741
742 __ it(EQ);
743 __ mov(R1, ShifterOperand(1), EQ);
744
745 __ it(EQ, kItThen);
746 __ mov(R1, ShifterOperand(1), EQ);
747 __ mov(R2, ShifterOperand(2), EQ);
748
749 __ it(EQ, kItElse);
750 __ mov(R1, ShifterOperand(1), EQ);
751 __ mov(R2, ShifterOperand(2), NE);
752
753 __ it(EQ, kItThen, kItElse);
754 __ mov(R1, ShifterOperand(1), EQ);
755 __ mov(R2, ShifterOperand(2), EQ);
756 __ mov(R3, ShifterOperand(3), NE);
757
758 __ it(EQ, kItElse, kItElse);
759 __ mov(R1, ShifterOperand(1), EQ);
760 __ mov(R2, ShifterOperand(2), NE);
761 __ mov(R3, ShifterOperand(3), NE);
762
763 __ it(EQ, kItThen, kItThen, kItElse);
764 __ mov(R1, ShifterOperand(1), EQ);
765 __ mov(R2, ShifterOperand(2), EQ);
766 __ mov(R3, ShifterOperand(3), EQ);
767 __ mov(R4, ShifterOperand(4), NE);
768
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000769 EmitAndCheck(&assembler, "IfThen");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700770}
771
772TEST(Thumb2AssemblerTest, CbzCbnz) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000773 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700774
775 Label l1;
776 __ cbz(R2, &l1);
777 __ mov(R1, ShifterOperand(3));
778 __ mov(R2, ShifterOperand(3));
779 __ Bind(&l1);
780 __ mov(R2, ShifterOperand(4));
781
782 Label l2;
783 __ cbnz(R2, &l2);
784 __ mov(R8, ShifterOperand(3));
785 __ mov(R2, ShifterOperand(3));
786 __ Bind(&l2);
787 __ mov(R2, ShifterOperand(4));
788
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000789 EmitAndCheck(&assembler, "CbzCbnz");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700790}
791
792TEST(Thumb2AssemblerTest, Multiply) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000793 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700794
795 __ mul(R0, R1, R0);
796 __ mul(R0, R1, R2);
797 __ mul(R8, R9, R8);
798 __ mul(R8, R9, R10);
799
800 __ mla(R0, R1, R2, R3);
801 __ mla(R8, R9, R8, R9);
802
803 __ mls(R0, R1, R2, R3);
804 __ mls(R8, R9, R8, R9);
805
806 __ umull(R0, R1, R2, R3);
807 __ umull(R8, R9, R10, R11);
808
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000809 EmitAndCheck(&assembler, "Multiply");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700810}
811
812TEST(Thumb2AssemblerTest, Divide) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000813 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700814
815 __ sdiv(R0, R1, R2);
816 __ sdiv(R8, R9, R10);
817
818 __ udiv(R0, R1, R2);
819 __ udiv(R8, R9, R10);
820
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000821 EmitAndCheck(&assembler, "Divide");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700822}
823
824TEST(Thumb2AssemblerTest, VMov) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000825 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700826
827 __ vmovs(S1, 1.0);
828 __ vmovd(D1, 1.0);
829
830 __ vmovs(S1, S2);
831 __ vmovd(D1, D2);
832
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000833 EmitAndCheck(&assembler, "VMov");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700834}
835
836
837TEST(Thumb2AssemblerTest, BasicFloatingPoint) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000838 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700839
840 __ vadds(S0, S1, S2);
841 __ vsubs(S0, S1, S2);
842 __ vmuls(S0, S1, S2);
843 __ vmlas(S0, S1, S2);
844 __ vmlss(S0, S1, S2);
845 __ vdivs(S0, S1, S2);
846 __ vabss(S0, S1);
847 __ vnegs(S0, S1);
848 __ vsqrts(S0, S1);
849
850 __ vaddd(D0, D1, D2);
851 __ vsubd(D0, D1, D2);
852 __ vmuld(D0, D1, D2);
853 __ vmlad(D0, D1, D2);
854 __ vmlsd(D0, D1, D2);
855 __ vdivd(D0, D1, D2);
856 __ vabsd(D0, D1);
857 __ vnegd(D0, D1);
858 __ vsqrtd(D0, D1);
859
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000860 EmitAndCheck(&assembler, "BasicFloatingPoint");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700861}
862
863TEST(Thumb2AssemblerTest, FloatingPointConversions) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000864 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700865
866 __ vcvtsd(S2, D2);
867 __ vcvtds(D2, S2);
868
869 __ vcvtis(S1, S2);
870 __ vcvtsi(S1, S2);
871
872 __ vcvtid(S1, D2);
873 __ vcvtdi(D1, S2);
874
875 __ vcvtus(S1, S2);
876 __ vcvtsu(S1, S2);
877
878 __ vcvtud(S1, D2);
879 __ vcvtdu(D1, S2);
880
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000881 EmitAndCheck(&assembler, "FloatingPointConversions");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700882}
883
884TEST(Thumb2AssemblerTest, FloatingPointComparisons) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000885 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700886
887 __ vcmps(S0, S1);
888 __ vcmpd(D0, D1);
889
890 __ vcmpsz(S2);
891 __ vcmpdz(D2);
892
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000893 EmitAndCheck(&assembler, "FloatingPointComparisons");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700894}
895
896TEST(Thumb2AssemblerTest, Calls) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000897 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700898
899 __ blx(LR);
900 __ bx(LR);
901
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000902 EmitAndCheck(&assembler, "Calls");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700903}
904
905TEST(Thumb2AssemblerTest, Breakpoint) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000906 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700907
908 __ bkpt(0);
909
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000910 EmitAndCheck(&assembler, "Breakpoint");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700911}
912
913TEST(Thumb2AssemblerTest, StrR1) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000914 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700915
916 __ str(R1, Address(SP, 68));
917 __ str(R1, Address(SP, 1068));
918
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000919 EmitAndCheck(&assembler, "StrR1");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700920}
921
922TEST(Thumb2AssemblerTest, VPushPop) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000923 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700924
925 __ vpushs(S2, 4);
926 __ vpushd(D2, 4);
927
928 __ vpops(S2, 4);
929 __ vpopd(D2, 4);
930
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000931 EmitAndCheck(&assembler, "VPushPop");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700932}
933
934TEST(Thumb2AssemblerTest, Max16BitBranch) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000935 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700936
937 Label l1;
938 __ b(&l1);
939 for (int i = 0 ; i < (1 << 11) ; i += 2) {
940 __ mov(R3, ShifterOperand(i & 0xff));
941 }
942 __ Bind(&l1);
943 __ mov(R1, ShifterOperand(R2));
944
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000945 EmitAndCheck(&assembler, "Max16BitBranch");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700946}
947
948TEST(Thumb2AssemblerTest, Branch32) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000949 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700950
951 Label l1;
952 __ b(&l1);
953 for (int i = 0 ; i < (1 << 11) + 2 ; i += 2) {
954 __ mov(R3, ShifterOperand(i & 0xff));
955 }
956 __ Bind(&l1);
957 __ mov(R1, ShifterOperand(R2));
958
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000959 EmitAndCheck(&assembler, "Branch32");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700960}
961
962TEST(Thumb2AssemblerTest, CompareAndBranchMax) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000963 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700964
965 Label l1;
966 __ cbz(R4, &l1);
967 for (int i = 0 ; i < (1 << 7) ; i += 2) {
968 __ mov(R3, ShifterOperand(i & 0xff));
969 }
970 __ Bind(&l1);
971 __ mov(R1, ShifterOperand(R2));
972
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000973 EmitAndCheck(&assembler, "CompareAndBranchMax");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700974}
975
976TEST(Thumb2AssemblerTest, CompareAndBranchRelocation16) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000977 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700978
979 Label l1;
980 __ cbz(R4, &l1);
981 for (int i = 0 ; i < (1 << 7) + 2 ; i += 2) {
982 __ mov(R3, ShifterOperand(i & 0xff));
983 }
984 __ Bind(&l1);
985 __ mov(R1, ShifterOperand(R2));
986
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000987 EmitAndCheck(&assembler, "CompareAndBranchRelocation16");
Dave Allison65fcc2c2014-04-28 13:45:27 -0700988}
989
990TEST(Thumb2AssemblerTest, CompareAndBranchRelocation32) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +0000991 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -0700992
993 Label l1;
994 __ cbz(R4, &l1);
995 for (int i = 0 ; i < (1 << 11) + 2 ; i += 2) {
996 __ mov(R3, ShifterOperand(i & 0xff));
997 }
998 __ Bind(&l1);
999 __ mov(R1, ShifterOperand(R2));
1000
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001001 EmitAndCheck(&assembler, "CompareAndBranchRelocation32");
Dave Allison65fcc2c2014-04-28 13:45:27 -07001002}
1003
1004TEST(Thumb2AssemblerTest, MixedBranch32) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001005 arm::Thumb2Assembler assembler;
Dave Allison65fcc2c2014-04-28 13:45:27 -07001006
1007 Label l1;
1008 Label l2;
1009 __ b(&l1); // Forwards.
1010 __ Bind(&l2);
1011
1012 // Space to force relocation.
1013 for (int i = 0 ; i < (1 << 11) + 2 ; i += 2) {
1014 __ mov(R3, ShifterOperand(i & 0xff));
1015 }
1016 __ b(&l2); // Backwards.
1017 __ Bind(&l1);
1018 __ mov(R1, ShifterOperand(R2));
1019
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001020 EmitAndCheck(&assembler, "MixedBranch32");
Dave Allison65fcc2c2014-04-28 13:45:27 -07001021}
1022
Dave Allison45fdb932014-06-25 12:37:10 -07001023TEST(Thumb2AssemblerTest, Shifts) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001024 arm::Thumb2Assembler assembler;
Dave Allison45fdb932014-06-25 12:37:10 -07001025
1026 // 16 bit
1027 __ Lsl(R0, R1, 5);
1028 __ Lsr(R0, R1, 5);
1029 __ Asr(R0, R1, 5);
1030
1031 __ Lsl(R0, R0, R1);
1032 __ Lsr(R0, R0, R1);
1033 __ Asr(R0, R0, R1);
1034
1035 // 32 bit due to high registers.
1036 __ Lsl(R8, R1, 5);
1037 __ Lsr(R0, R8, 5);
1038 __ Asr(R8, R1, 5);
1039 __ Ror(R0, R8, 5);
1040
1041 // 32 bit due to different Rd and Rn.
1042 __ Lsl(R0, R1, R2);
1043 __ Lsr(R0, R1, R2);
1044 __ Asr(R0, R1, R2);
1045 __ Ror(R0, R1, R2);
1046
1047 // 32 bit due to use of high registers.
1048 __ Lsl(R8, R1, R2);
1049 __ Lsr(R0, R8, R2);
1050 __ Asr(R0, R1, R8);
1051
1052 // S bit (all 32 bit)
1053
1054 // 32 bit due to high registers.
1055 __ Lsl(R8, R1, 5, true);
1056 __ Lsr(R0, R8, 5, true);
1057 __ Asr(R8, R1, 5, true);
1058 __ Ror(R0, R8, 5, true);
1059
1060 // 32 bit due to different Rd and Rn.
1061 __ Lsl(R0, R1, R2, true);
1062 __ Lsr(R0, R1, R2, true);
1063 __ Asr(R0, R1, R2, true);
1064 __ Ror(R0, R1, R2, true);
1065
1066 // 32 bit due to use of high registers.
1067 __ Lsl(R8, R1, R2, true);
1068 __ Lsr(R0, R8, R2, true);
1069 __ Asr(R0, R1, R8, true);
1070
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001071 EmitAndCheck(&assembler, "Shifts");
Dave Allison45fdb932014-06-25 12:37:10 -07001072}
1073
1074TEST(Thumb2AssemblerTest, LoadStoreRegOffset) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001075 arm::Thumb2Assembler assembler;
Dave Allison45fdb932014-06-25 12:37:10 -07001076
1077 // 16 bit.
1078 __ ldr(R0, Address(R1, R2));
1079 __ str(R0, Address(R1, R2));
1080
1081 // 32 bit due to shift.
1082 __ ldr(R0, Address(R1, R2, LSL, 1));
1083 __ str(R0, Address(R1, R2, LSL, 1));
1084
1085 __ ldr(R0, Address(R1, R2, LSL, 3));
1086 __ str(R0, Address(R1, R2, LSL, 3));
1087
1088 // 32 bit due to high register use.
1089 __ ldr(R8, Address(R1, R2));
1090 __ str(R8, Address(R1, R2));
1091
1092 __ ldr(R1, Address(R8, R2));
1093 __ str(R2, Address(R8, R2));
1094
1095 __ ldr(R0, Address(R1, R8));
1096 __ str(R0, Address(R1, R8));
1097
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001098 EmitAndCheck(&assembler, "LoadStoreRegOffset");
Dave Allison45fdb932014-06-25 12:37:10 -07001099}
1100
1101TEST(Thumb2AssemblerTest, LoadStoreLiteral) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001102 arm::Thumb2Assembler assembler;
Dave Allison45fdb932014-06-25 12:37:10 -07001103
1104 __ ldr(R0, Address(4));
1105 __ str(R0, Address(4));
1106
1107 __ ldr(R0, Address(-8));
1108 __ str(R0, Address(-8));
1109
1110 // Limits.
1111 __ ldr(R0, Address(0x3ff)); // 10 bits (16 bit).
1112 __ ldr(R0, Address(0x7ff)); // 11 bits (32 bit).
1113 __ str(R0, Address(0x3ff)); // 32 bit (no 16 bit str(literal)).
1114 __ str(R0, Address(0x7ff)); // 11 bits (32 bit).
1115
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001116 EmitAndCheck(&assembler, "LoadStoreLiteral");
Dave Allison45fdb932014-06-25 12:37:10 -07001117}
1118
Dave Allison0bb9ade2014-06-26 17:57:36 -07001119TEST(Thumb2AssemblerTest, LoadStoreLimits) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001120 arm::Thumb2Assembler assembler;
Dave Allison0bb9ade2014-06-26 17:57:36 -07001121
1122 __ ldr(R0, Address(R4, 124)); // 16 bit.
1123 __ ldr(R0, Address(R4, 128)); // 32 bit.
1124
1125 __ ldrb(R0, Address(R4, 31)); // 16 bit.
1126 __ ldrb(R0, Address(R4, 32)); // 32 bit.
1127
1128 __ ldrh(R0, Address(R4, 62)); // 16 bit.
1129 __ ldrh(R0, Address(R4, 64)); // 32 bit.
1130
1131 __ ldrsb(R0, Address(R4, 31)); // 32 bit.
1132 __ ldrsb(R0, Address(R4, 32)); // 32 bit.
1133
1134 __ ldrsh(R0, Address(R4, 62)); // 32 bit.
1135 __ ldrsh(R0, Address(R4, 64)); // 32 bit.
1136
1137 __ str(R0, Address(R4, 124)); // 16 bit.
1138 __ str(R0, Address(R4, 128)); // 32 bit.
1139
1140 __ strb(R0, Address(R4, 31)); // 16 bit.
1141 __ strb(R0, Address(R4, 32)); // 32 bit.
1142
1143 __ strh(R0, Address(R4, 62)); // 16 bit.
1144 __ strh(R0, Address(R4, 64)); // 32 bit.
1145
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001146 EmitAndCheck(&assembler, "LoadStoreLimits");
Dave Allison0bb9ade2014-06-26 17:57:36 -07001147}
1148
Nicolas Geoffrayd56376c2015-05-21 12:32:34 +00001149TEST(Thumb2AssemblerTest, CompareAndBranch) {
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001150 arm::Thumb2Assembler assembler;
Nicolas Geoffrayd56376c2015-05-21 12:32:34 +00001151
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001152 Label label;
Nicolas Geoffrayd56376c2015-05-21 12:32:34 +00001153 __ CompareAndBranchIfZero(arm::R0, &label);
1154 __ CompareAndBranchIfZero(arm::R11, &label);
1155 __ CompareAndBranchIfNonZero(arm::R0, &label);
1156 __ CompareAndBranchIfNonZero(arm::R11, &label);
1157 __ Bind(&label);
1158
Vladimir Markocf93a5c2015-06-16 11:33:24 +00001159 EmitAndCheck(&assembler, "CompareAndBranch");
Nicolas Geoffrayd56376c2015-05-21 12:32:34 +00001160}
1161
Dave Allison65fcc2c2014-04-28 13:45:27 -07001162#undef __
1163} // namespace arm
1164} // namespace art