1/* 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 17#include <dirent.h> 18#include <errno.h> 19#include <fstream> 20#include <map> 21#include <string.h> 22#include <sys/types.h> 23 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 35#ifndef __ANDROID__ 36// 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. 45static constexpr bool kPrintResults = false; 46#endif 47 48void SetAndroidData() { 49 const char* data = getenv("ANDROID_DATA"); 50 if (data == nullptr) { 51 setenv("ANDROID_DATA", "/tmp", 1); 52 } 53} 54 55int 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 68void InitResults() { 69 if (test_results.empty()) { 70 setup_results(); 71 } 72} 73 74std::string GetToolsDir() { 75#ifndef __ANDROID__ 76 // This will only work on the host. There is no as, objcopy or objdump on the device. 77 static std::string toolsdir; 78 79 if (toolsdir.empty()) { 80 setup_results(); 81 toolsdir = CommonRuntimeTest::GetAndroidTargetToolsDir(kThumb2); 82 SetAndroidData(); 83 } 84 85 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) { 92#ifndef __ANDROID__ 93 static std::string toolsdir = GetToolsDir(); 94 95 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 119 char cmd[1024]; 120 121 // Assemble the .S 122 snprintf(cmd, sizeof(cmd), "%sas %s -o %s.o", toolsdir.c_str(), filename, filename); 123 int cmd_result = system(cmd); 124 ASSERT_EQ(cmd_result, 0) << strerror(errno); 125 126 // Remove the $d symbols to prevent the disassembler dumping the instructions 127 // as .word 128 snprintf(cmd, sizeof(cmd), "%sobjcopy -N '$d' %s.o %s.oo", toolsdir.c_str(), filename, filename); 129 int cmd_result2 = system(cmd); 130 ASSERT_EQ(cmd_result2, 0) << strerror(errno); 131 132 // Disassemble. 133 134 snprintf(cmd, sizeof(cmd), "%sobjdump -d %s.oo | grep '^ *[0-9a-f][0-9a-f]*:'", 135 toolsdir.c_str(), filename); 136 if (kPrintResults) { 137 // Print the results only, don't check. This is used to generate new output for inserting 138 // into the .inc file, so let's add the appropriate prefix/suffix needed in the C++ code. 139 strcat(cmd, " | sed '-es/^/ \"/' | sed '-es/$/\\\\n\",/'"); 140 int cmd_result3 = system(cmd); 141 ASSERT_EQ(cmd_result3, 0) << strerror(errno); 142 } else { 143 // Check the results match the appropriate results in the .inc file. 144 FILE *fp = popen(cmd, "r"); 145 ASSERT_TRUE(fp != nullptr); 146 147 uint32_t lineindex = 0; 148 149 while (!feof(fp)) { 150 char testline[256]; 151 char *s = fgets(testline, sizeof(testline), fp); 152 if (s == nullptr) { 153 break; 154 } 155 if (CompareIgnoringSpace(results[lineindex], testline) != 0) { 156 LOG(FATAL) << "Output is not as expected at line: " << lineindex 157 << results[lineindex] << "/" << testline; 158 } 159 ++lineindex; 160 } 161 // Check that we are at the end. 162 ASSERT_TRUE(results[lineindex] == nullptr); 163 fclose(fp); 164 } 165 166 char buf[FILENAME_MAX]; 167 snprintf(buf, sizeof(buf), "%s.o", filename); 168 unlink(buf); 169 170 snprintf(buf, sizeof(buf), "%s.oo", filename); 171 unlink(buf); 172#endif 173} 174 175#define __ assembler-> 176 177void EmitAndCheck(arm::Thumb2Assembler* assembler, const char* testname, 178 const char* const* results) { 179 __ FinalizeCode(); 180 size_t cs = __ CodeSize(); 181 std::vector<uint8_t> managed_code(cs); 182 MemoryRegion code(&managed_code[0], managed_code.size()); 183 __ FinalizeInstructions(code); 184 185 DumpAndCheck(managed_code, testname, results); 186} 187 188void EmitAndCheck(arm::Thumb2Assembler* assembler, const char* testname) { 189 InitResults(); 190 std::map<std::string, const char* const*>::iterator results = test_results.find(testname); 191 ASSERT_NE(results, test_results.end()); 192 193 EmitAndCheck(assembler, testname, results->second); 194} 195 196#undef __ 197 198class Thumb2AssemblerTest : public ::testing::Test { 199 public: 200 Thumb2AssemblerTest() : pool(), arena(&pool), assembler(&arena) { } 201 202 ArenaPool pool; 203 ArenaAllocator arena; 204 arm::Thumb2Assembler assembler; 205}; 206 207#define __ assembler. 208 209TEST_F(Thumb2AssemblerTest, SimpleMov) { 210 __ movs(R0, ShifterOperand(R1)); 211 __ mov(R0, ShifterOperand(R1)); 212 __ mov(R8, ShifterOperand(R9)); 213 214 __ mov(R0, ShifterOperand(1)); 215 __ mov(R8, ShifterOperand(9)); 216 217 EmitAndCheck(&assembler, "SimpleMov"); 218} 219 220TEST_F(Thumb2AssemblerTest, SimpleMov32) { 221 __ Force32Bit(); 222 223 __ mov(R0, ShifterOperand(R1)); 224 __ mov(R8, ShifterOperand(R9)); 225 226 EmitAndCheck(&assembler, "SimpleMov32"); 227} 228 229TEST_F(Thumb2AssemblerTest, SimpleMovAdd) { 230 __ mov(R0, ShifterOperand(R1)); 231 __ adds(R0, R1, ShifterOperand(R2)); 232 __ add(R0, R1, ShifterOperand(0)); 233 234 EmitAndCheck(&assembler, "SimpleMovAdd"); 235} 236 237TEST_F(Thumb2AssemblerTest, DataProcessingRegister) { 238 // 32 bit variants using low registers. 239 __ mvn(R0, ShifterOperand(R1), AL, kCcKeep); 240 __ add(R0, R1, ShifterOperand(R2), AL, kCcKeep); 241 __ sub(R0, R1, ShifterOperand(R2), AL, kCcKeep); 242 __ and_(R0, R1, ShifterOperand(R2), AL, kCcKeep); 243 __ orr(R0, R1, ShifterOperand(R2), AL, kCcKeep); 244 __ orn(R0, R1, ShifterOperand(R2), AL, kCcKeep); 245 __ eor(R0, R1, ShifterOperand(R2), AL, kCcKeep); 246 __ bic(R0, R1, ShifterOperand(R2), AL, kCcKeep); 247 __ adc(R0, R1, ShifterOperand(R2), AL, kCcKeep); 248 __ sbc(R0, R1, ShifterOperand(R2), AL, kCcKeep); 249 __ rsb(R0, R1, ShifterOperand(R2), AL, kCcKeep); 250 __ teq(R0, ShifterOperand(R1)); 251 252 // 16 bit variants using low registers. 253 __ movs(R0, ShifterOperand(R1)); 254 __ mov(R0, ShifterOperand(R1), AL, kCcKeep); 255 __ mvns(R0, ShifterOperand(R1)); 256 __ add(R0, R0, ShifterOperand(R1), AL, kCcKeep); 257 __ adds(R0, R1, ShifterOperand(R2)); 258 __ subs(R0, R1, ShifterOperand(R2)); 259 __ adcs(R0, R0, ShifterOperand(R1)); 260 __ sbcs(R0, R0, ShifterOperand(R1)); 261 __ ands(R0, R0, ShifterOperand(R1)); 262 __ orrs(R0, R0, ShifterOperand(R1)); 263 __ eors(R0, R0, ShifterOperand(R1)); 264 __ bics(R0, R0, ShifterOperand(R1)); 265 __ tst(R0, ShifterOperand(R1)); 266 __ cmp(R0, ShifterOperand(R1)); 267 __ cmn(R0, ShifterOperand(R1)); 268 269 // 16-bit variants using high registers. 270 __ mov(R1, ShifterOperand(R8), AL, kCcKeep); 271 __ mov(R9, ShifterOperand(R0), AL, kCcKeep); 272 __ mov(R8, ShifterOperand(R9), AL, kCcKeep); 273 __ add(R1, R1, ShifterOperand(R8), AL, kCcKeep); 274 __ add(R9, R9, ShifterOperand(R0), AL, kCcKeep); 275 __ add(R8, R8, ShifterOperand(R9), AL, kCcKeep); 276 __ cmp(R0, ShifterOperand(R9)); 277 __ cmp(R8, ShifterOperand(R1)); 278 __ cmp(R9, ShifterOperand(R8)); 279 280 // The 16-bit RSBS Rd, Rn, #0, also known as NEGS Rd, Rn is specified using 281 // an immediate (0) but emitted without any, so we test it here. 282 __ rsbs(R0, R1, ShifterOperand(0)); 283 __ rsbs(R0, R0, ShifterOperand(0)); // Check Rd == Rn code path. 284 285 // 32 bit variants using high registers that would be 16-bit if using low registers. 286 __ movs(R0, ShifterOperand(R8)); 287 __ mvns(R0, ShifterOperand(R8)); 288 __ add(R0, R1, ShifterOperand(R8), AL, kCcKeep); 289 __ adds(R0, R1, ShifterOperand(R8)); 290 __ subs(R0, R1, ShifterOperand(R8)); 291 __ adcs(R0, R0, ShifterOperand(R8)); 292 __ sbcs(R0, R0, ShifterOperand(R8)); 293 __ ands(R0, R0, ShifterOperand(R8)); 294 __ orrs(R0, R0, ShifterOperand(R8)); 295 __ eors(R0, R0, ShifterOperand(R8)); 296 __ bics(R0, R0, ShifterOperand(R8)); 297 __ tst(R0, ShifterOperand(R8)); 298 __ cmn(R0, ShifterOperand(R8)); 299 __ rsbs(R0, R8, ShifterOperand(0)); // Check that this is not emitted as 16-bit. 300 __ rsbs(R8, R8, ShifterOperand(0)); // Check that this is not emitted as 16-bit (Rd == Rn). 301 302 // 32-bit variants of instructions that would be 16-bit outside IT block. 303 __ it(arm::EQ); 304 __ mvns(R0, ShifterOperand(R1), arm::EQ); 305 __ it(arm::EQ); 306 __ adds(R0, R1, ShifterOperand(R2), arm::EQ); 307 __ it(arm::EQ); 308 __ subs(R0, R1, ShifterOperand(R2), arm::EQ); 309 __ it(arm::EQ); 310 __ adcs(R0, R0, ShifterOperand(R1), arm::EQ); 311 __ it(arm::EQ); 312 __ sbcs(R0, R0, ShifterOperand(R1), arm::EQ); 313 __ it(arm::EQ); 314 __ ands(R0, R0, ShifterOperand(R1), arm::EQ); 315 __ it(arm::EQ); 316 __ orrs(R0, R0, ShifterOperand(R1), arm::EQ); 317 __ it(arm::EQ); 318 __ eors(R0, R0, ShifterOperand(R1), arm::EQ); 319 __ it(arm::EQ); 320 __ bics(R0, R0, ShifterOperand(R1), arm::EQ); 321 322 // 16-bit variants of instructions that would be 32-bit outside IT block. 323 __ it(arm::EQ); 324 __ mvn(R0, ShifterOperand(R1), arm::EQ, kCcKeep); 325 __ it(arm::EQ); 326 __ add(R0, R1, ShifterOperand(R2), arm::EQ, kCcKeep); 327 __ it(arm::EQ); 328 __ sub(R0, R1, ShifterOperand(R2), arm::EQ, kCcKeep); 329 __ it(arm::EQ); 330 __ adc(R0, R0, ShifterOperand(R1), arm::EQ, kCcKeep); 331 __ it(arm::EQ); 332 __ sbc(R0, R0, ShifterOperand(R1), arm::EQ, kCcKeep); 333 __ it(arm::EQ); 334 __ and_(R0, R0, ShifterOperand(R1), arm::EQ, kCcKeep); 335 __ it(arm::EQ); 336 __ orr(R0, R0, ShifterOperand(R1), arm::EQ, kCcKeep); 337 __ it(arm::EQ); 338 __ eor(R0, R0, ShifterOperand(R1), arm::EQ, kCcKeep); 339 __ it(arm::EQ); 340 __ bic(R0, R0, ShifterOperand(R1), arm::EQ, kCcKeep); 341 342 // 16 bit variants selected for the default kCcDontCare. 343 __ mov(R0, ShifterOperand(R1)); 344 __ mvn(R0, ShifterOperand(R1)); 345 __ add(R0, R0, ShifterOperand(R1)); 346 __ add(R0, R1, ShifterOperand(R2)); 347 __ sub(R0, R1, ShifterOperand(R2)); 348 __ adc(R0, R0, ShifterOperand(R1)); 349 __ sbc(R0, R0, ShifterOperand(R1)); 350 __ and_(R0, R0, ShifterOperand(R1)); 351 __ orr(R0, R0, ShifterOperand(R1)); 352 __ eor(R0, R0, ShifterOperand(R1)); 353 __ bic(R0, R0, ShifterOperand(R1)); 354 __ mov(R1, ShifterOperand(R8)); 355 __ mov(R9, ShifterOperand(R0)); 356 __ mov(R8, ShifterOperand(R9)); 357 __ add(R1, R1, ShifterOperand(R8)); 358 __ add(R9, R9, ShifterOperand(R0)); 359 __ add(R8, R8, ShifterOperand(R9)); 360 __ rsb(R0, R1, ShifterOperand(0)); 361 __ rsb(R0, R0, ShifterOperand(0)); 362 363 // And an arbitrary 32-bit instruction using IP. 364 __ add(R12, R1, ShifterOperand(R0), AL, kCcKeep); 365 366 EmitAndCheck(&assembler, "DataProcessingRegister"); 367} 368 369TEST_F(Thumb2AssemblerTest, DataProcessingImmediate) { 370 __ mov(R0, ShifterOperand(0x55)); 371 __ mvn(R0, ShifterOperand(0x55)); 372 __ add(R0, R1, ShifterOperand(0x55)); 373 __ sub(R0, R1, ShifterOperand(0x55)); 374 __ and_(R0, R1, ShifterOperand(0x55)); 375 __ orr(R0, R1, ShifterOperand(0x55)); 376 __ orn(R0, R1, ShifterOperand(0x55)); 377 __ eor(R0, R1, ShifterOperand(0x55)); 378 __ bic(R0, R1, ShifterOperand(0x55)); 379 __ adc(R0, R1, ShifterOperand(0x55)); 380 __ sbc(R0, R1, ShifterOperand(0x55)); 381 __ rsb(R0, R1, ShifterOperand(0x55)); 382 383 __ tst(R0, ShifterOperand(0x55)); 384 __ teq(R0, ShifterOperand(0x55)); 385 __ cmp(R0, ShifterOperand(0x55)); 386 __ cmn(R0, ShifterOperand(0x55)); 387 388 __ add(R0, R1, ShifterOperand(5)); 389 __ sub(R0, R1, ShifterOperand(5)); 390 391 __ movs(R0, ShifterOperand(0x55)); 392 __ mvns(R0, ShifterOperand(0x55)); 393 394 __ adds(R0, R1, ShifterOperand(5)); 395 __ subs(R0, R1, ShifterOperand(5)); 396 397 EmitAndCheck(&assembler, "DataProcessingImmediate"); 398} 399 400TEST_F(Thumb2AssemblerTest, DataProcessingModifiedImmediate) { 401 __ mov(R0, ShifterOperand(0x550055)); 402 __ mvn(R0, ShifterOperand(0x550055)); 403 __ add(R0, R1, ShifterOperand(0x550055)); 404 __ sub(R0, R1, ShifterOperand(0x550055)); 405 __ and_(R0, R1, ShifterOperand(0x550055)); 406 __ orr(R0, R1, ShifterOperand(0x550055)); 407 __ orn(R0, R1, ShifterOperand(0x550055)); 408 __ eor(R0, R1, ShifterOperand(0x550055)); 409 __ bic(R0, R1, ShifterOperand(0x550055)); 410 __ adc(R0, R1, ShifterOperand(0x550055)); 411 __ sbc(R0, R1, ShifterOperand(0x550055)); 412 __ rsb(R0, R1, ShifterOperand(0x550055)); 413 414 __ tst(R0, ShifterOperand(0x550055)); 415 __ teq(R0, ShifterOperand(0x550055)); 416 __ cmp(R0, ShifterOperand(0x550055)); 417 __ cmn(R0, ShifterOperand(0x550055)); 418 419 EmitAndCheck(&assembler, "DataProcessingModifiedImmediate"); 420} 421 422 423TEST_F(Thumb2AssemblerTest, DataProcessingModifiedImmediates) { 424 __ mov(R0, ShifterOperand(0x550055)); 425 __ mov(R0, ShifterOperand(0x55005500)); 426 __ mov(R0, ShifterOperand(0x55555555)); 427 __ mov(R0, ShifterOperand(0xd5000000)); // rotated to first position 428 __ mov(R0, ShifterOperand(0x6a000000)); // rotated to second position 429 __ mov(R0, ShifterOperand(0x350)); // rotated to 2nd last position 430 __ mov(R0, ShifterOperand(0x1a8)); // rotated to last position 431 432 EmitAndCheck(&assembler, "DataProcessingModifiedImmediates"); 433} 434 435TEST_F(Thumb2AssemblerTest, DataProcessingShiftedRegister) { 436 // 16-bit variants. 437 __ movs(R3, ShifterOperand(R4, LSL, 4)); 438 __ movs(R3, ShifterOperand(R4, LSR, 5)); 439 __ movs(R3, ShifterOperand(R4, ASR, 6)); 440 441 // 32-bit ROR because ROR immediate doesn't have the same 16-bit version as other shifts. 442 __ movs(R3, ShifterOperand(R4, ROR, 7)); 443 444 // 32-bit RRX because RRX has no 16-bit version. 445 __ movs(R3, ShifterOperand(R4, RRX)); 446 447 // 32 bit variants (not setting condition codes). 448 __ mov(R3, ShifterOperand(R4, LSL, 4), AL, kCcKeep); 449 __ mov(R3, ShifterOperand(R4, LSR, 5), AL, kCcKeep); 450 __ mov(R3, ShifterOperand(R4, ASR, 6), AL, kCcKeep); 451 __ mov(R3, ShifterOperand(R4, ROR, 7), AL, kCcKeep); 452 __ mov(R3, ShifterOperand(R4, RRX), AL, kCcKeep); 453 454 // 32 bit variants (high registers). 455 __ movs(R8, ShifterOperand(R4, LSL, 4)); 456 __ movs(R8, ShifterOperand(R4, LSR, 5)); 457 __ movs(R8, ShifterOperand(R4, ASR, 6)); 458 __ movs(R8, ShifterOperand(R4, ROR, 7)); 459 __ movs(R8, ShifterOperand(R4, RRX)); 460 461 EmitAndCheck(&assembler, "DataProcessingShiftedRegister"); 462} 463 464TEST_F(Thumb2AssemblerTest, ShiftImmediate) { 465 // Note: This test produces the same results as DataProcessingShiftedRegister 466 // but it does so using shift functions instead of mov(). 467 468 // 16-bit variants. 469 __ Lsl(R3, R4, 4); 470 __ Lsr(R3, R4, 5); 471 __ Asr(R3, R4, 6); 472 473 // 32-bit ROR because ROR immediate doesn't have the same 16-bit version as other shifts. 474 __ Ror(R3, R4, 7); 475 476 // 32-bit RRX because RRX has no 16-bit version. 477 __ Rrx(R3, R4); 478 479 // 32 bit variants (not setting condition codes). 480 __ Lsl(R3, R4, 4, AL, kCcKeep); 481 __ Lsr(R3, R4, 5, AL, kCcKeep); 482 __ Asr(R3, R4, 6, AL, kCcKeep); 483 __ Ror(R3, R4, 7, AL, kCcKeep); 484 __ Rrx(R3, R4, AL, kCcKeep); 485 486 // 32 bit variants (high registers). 487 __ Lsls(R8, R4, 4); 488 __ Lsrs(R8, R4, 5); 489 __ Asrs(R8, R4, 6); 490 __ Rors(R8, R4, 7); 491 __ Rrxs(R8, R4); 492 493 EmitAndCheck(&assembler, "ShiftImmediate"); 494} 495 496TEST_F(Thumb2AssemblerTest, BasicLoad) { 497 __ ldr(R3, Address(R4, 24)); 498 __ ldrb(R3, Address(R4, 24)); 499 __ ldrh(R3, Address(R4, 24)); 500 __ ldrsb(R3, Address(R4, 24)); 501 __ ldrsh(R3, Address(R4, 24)); 502 503 __ ldr(R3, Address(SP, 24)); 504 505 // 32 bit variants 506 __ ldr(R8, Address(R4, 24)); 507 __ ldrb(R8, Address(R4, 24)); 508 __ ldrh(R8, Address(R4, 24)); 509 __ ldrsb(R8, Address(R4, 24)); 510 __ ldrsh(R8, Address(R4, 24)); 511 512 EmitAndCheck(&assembler, "BasicLoad"); 513} 514 515 516TEST_F(Thumb2AssemblerTest, BasicStore) { 517 __ str(R3, Address(R4, 24)); 518 __ strb(R3, Address(R4, 24)); 519 __ strh(R3, Address(R4, 24)); 520 521 __ str(R3, Address(SP, 24)); 522 523 // 32 bit variants. 524 __ str(R8, Address(R4, 24)); 525 __ strb(R8, Address(R4, 24)); 526 __ strh(R8, Address(R4, 24)); 527 528 EmitAndCheck(&assembler, "BasicStore"); 529} 530 531TEST_F(Thumb2AssemblerTest, ComplexLoad) { 532 __ ldr(R3, Address(R4, 24, Address::Mode::Offset)); 533 __ ldr(R3, Address(R4, 24, Address::Mode::PreIndex)); 534 __ ldr(R3, Address(R4, 24, Address::Mode::PostIndex)); 535 __ ldr(R3, Address(R4, 24, Address::Mode::NegOffset)); 536 __ ldr(R3, Address(R4, 24, Address::Mode::NegPreIndex)); 537 __ ldr(R3, Address(R4, 24, Address::Mode::NegPostIndex)); 538 539 __ ldrb(R3, Address(R4, 24, Address::Mode::Offset)); 540 __ ldrb(R3, Address(R4, 24, Address::Mode::PreIndex)); 541 __ ldrb(R3, Address(R4, 24, Address::Mode::PostIndex)); 542 __ ldrb(R3, Address(R4, 24, Address::Mode::NegOffset)); 543 __ ldrb(R3, Address(R4, 24, Address::Mode::NegPreIndex)); 544 __ ldrb(R3, Address(R4, 24, Address::Mode::NegPostIndex)); 545 546 __ ldrh(R3, Address(R4, 24, Address::Mode::Offset)); 547 __ ldrh(R3, Address(R4, 24, Address::Mode::PreIndex)); 548 __ ldrh(R3, Address(R4, 24, Address::Mode::PostIndex)); 549 __ ldrh(R3, Address(R4, 24, Address::Mode::NegOffset)); 550 __ ldrh(R3, Address(R4, 24, Address::Mode::NegPreIndex)); 551 __ ldrh(R3, Address(R4, 24, Address::Mode::NegPostIndex)); 552 553 __ ldrsb(R3, Address(R4, 24, Address::Mode::Offset)); 554 __ ldrsb(R3, Address(R4, 24, Address::Mode::PreIndex)); 555 __ ldrsb(R3, Address(R4, 24, Address::Mode::PostIndex)); 556 __ ldrsb(R3, Address(R4, 24, Address::Mode::NegOffset)); 557 __ ldrsb(R3, Address(R4, 24, Address::Mode::NegPreIndex)); 558 __ ldrsb(R3, Address(R4, 24, Address::Mode::NegPostIndex)); 559 560 __ ldrsh(R3, Address(R4, 24, Address::Mode::Offset)); 561 __ ldrsh(R3, Address(R4, 24, Address::Mode::PreIndex)); 562 __ ldrsh(R3, Address(R4, 24, Address::Mode::PostIndex)); 563 __ ldrsh(R3, Address(R4, 24, Address::Mode::NegOffset)); 564 __ ldrsh(R3, Address(R4, 24, Address::Mode::NegPreIndex)); 565 __ ldrsh(R3, Address(R4, 24, Address::Mode::NegPostIndex)); 566 567 EmitAndCheck(&assembler, "ComplexLoad"); 568} 569 570 571TEST_F(Thumb2AssemblerTest, ComplexStore) { 572 __ str(R3, Address(R4, 24, Address::Mode::Offset)); 573 __ str(R3, Address(R4, 24, Address::Mode::PreIndex)); 574 __ str(R3, Address(R4, 24, Address::Mode::PostIndex)); 575 __ str(R3, Address(R4, 24, Address::Mode::NegOffset)); 576 __ str(R3, Address(R4, 24, Address::Mode::NegPreIndex)); 577 __ str(R3, Address(R4, 24, Address::Mode::NegPostIndex)); 578 579 __ strb(R3, Address(R4, 24, Address::Mode::Offset)); 580 __ strb(R3, Address(R4, 24, Address::Mode::PreIndex)); 581 __ strb(R3, Address(R4, 24, Address::Mode::PostIndex)); 582 __ strb(R3, Address(R4, 24, Address::Mode::NegOffset)); 583 __ strb(R3, Address(R4, 24, Address::Mode::NegPreIndex)); 584 __ strb(R3, Address(R4, 24, Address::Mode::NegPostIndex)); 585 586 __ strh(R3, Address(R4, 24, Address::Mode::Offset)); 587 __ strh(R3, Address(R4, 24, Address::Mode::PreIndex)); 588 __ strh(R3, Address(R4, 24, Address::Mode::PostIndex)); 589 __ strh(R3, Address(R4, 24, Address::Mode::NegOffset)); 590 __ strh(R3, Address(R4, 24, Address::Mode::NegPreIndex)); 591 __ strh(R3, Address(R4, 24, Address::Mode::NegPostIndex)); 592 593 EmitAndCheck(&assembler, "ComplexStore"); 594} 595 596TEST_F(Thumb2AssemblerTest, NegativeLoadStore) { 597 __ ldr(R3, Address(R4, -24, Address::Mode::Offset)); 598 __ ldr(R3, Address(R4, -24, Address::Mode::PreIndex)); 599 __ ldr(R3, Address(R4, -24, Address::Mode::PostIndex)); 600 __ ldr(R3, Address(R4, -24, Address::Mode::NegOffset)); 601 __ ldr(R3, Address(R4, -24, Address::Mode::NegPreIndex)); 602 __ ldr(R3, Address(R4, -24, Address::Mode::NegPostIndex)); 603 604 __ ldrb(R3, Address(R4, -24, Address::Mode::Offset)); 605 __ ldrb(R3, Address(R4, -24, Address::Mode::PreIndex)); 606 __ ldrb(R3, Address(R4, -24, Address::Mode::PostIndex)); 607 __ ldrb(R3, Address(R4, -24, Address::Mode::NegOffset)); 608 __ ldrb(R3, Address(R4, -24, Address::Mode::NegPreIndex)); 609 __ ldrb(R3, Address(R4, -24, Address::Mode::NegPostIndex)); 610 611 __ ldrh(R3, Address(R4, -24, Address::Mode::Offset)); 612 __ ldrh(R3, Address(R4, -24, Address::Mode::PreIndex)); 613 __ ldrh(R3, Address(R4, -24, Address::Mode::PostIndex)); 614 __ ldrh(R3, Address(R4, -24, Address::Mode::NegOffset)); 615 __ ldrh(R3, Address(R4, -24, Address::Mode::NegPreIndex)); 616 __ ldrh(R3, Address(R4, -24, Address::Mode::NegPostIndex)); 617 618 __ ldrsb(R3, Address(R4, -24, Address::Mode::Offset)); 619 __ ldrsb(R3, Address(R4, -24, Address::Mode::PreIndex)); 620 __ ldrsb(R3, Address(R4, -24, Address::Mode::PostIndex)); 621 __ ldrsb(R3, Address(R4, -24, Address::Mode::NegOffset)); 622 __ ldrsb(R3, Address(R4, -24, Address::Mode::NegPreIndex)); 623 __ ldrsb(R3, Address(R4, -24, Address::Mode::NegPostIndex)); 624 625 __ ldrsh(R3, Address(R4, -24, Address::Mode::Offset)); 626 __ ldrsh(R3, Address(R4, -24, Address::Mode::PreIndex)); 627 __ ldrsh(R3, Address(R4, -24, Address::Mode::PostIndex)); 628 __ ldrsh(R3, Address(R4, -24, Address::Mode::NegOffset)); 629 __ ldrsh(R3, Address(R4, -24, Address::Mode::NegPreIndex)); 630 __ ldrsh(R3, Address(R4, -24, Address::Mode::NegPostIndex)); 631 632 __ str(R3, Address(R4, -24, Address::Mode::Offset)); 633 __ str(R3, Address(R4, -24, Address::Mode::PreIndex)); 634 __ str(R3, Address(R4, -24, Address::Mode::PostIndex)); 635 __ str(R3, Address(R4, -24, Address::Mode::NegOffset)); 636 __ str(R3, Address(R4, -24, Address::Mode::NegPreIndex)); 637 __ str(R3, Address(R4, -24, Address::Mode::NegPostIndex)); 638 639 __ strb(R3, Address(R4, -24, Address::Mode::Offset)); 640 __ strb(R3, Address(R4, -24, Address::Mode::PreIndex)); 641 __ strb(R3, Address(R4, -24, Address::Mode::PostIndex)); 642 __ strb(R3, Address(R4, -24, Address::Mode::NegOffset)); 643 __ strb(R3, Address(R4, -24, Address::Mode::NegPreIndex)); 644 __ strb(R3, Address(R4, -24, Address::Mode::NegPostIndex)); 645 646 __ strh(R3, Address(R4, -24, Address::Mode::Offset)); 647 __ strh(R3, Address(R4, -24, Address::Mode::PreIndex)); 648 __ strh(R3, Address(R4, -24, Address::Mode::PostIndex)); 649 __ strh(R3, Address(R4, -24, Address::Mode::NegOffset)); 650 __ strh(R3, Address(R4, -24, Address::Mode::NegPreIndex)); 651 __ strh(R3, Address(R4, -24, Address::Mode::NegPostIndex)); 652 653 EmitAndCheck(&assembler, "NegativeLoadStore"); 654} 655 656TEST_F(Thumb2AssemblerTest, SimpleLoadStoreDual) { 657 __ strd(R2, Address(R0, 24, Address::Mode::Offset)); 658 __ ldrd(R2, Address(R0, 24, Address::Mode::Offset)); 659 660 EmitAndCheck(&assembler, "SimpleLoadStoreDual"); 661} 662 663TEST_F(Thumb2AssemblerTest, ComplexLoadStoreDual) { 664 __ strd(R2, Address(R0, 24, Address::Mode::Offset)); 665 __ strd(R2, Address(R0, 24, Address::Mode::PreIndex)); 666 __ strd(R2, Address(R0, 24, Address::Mode::PostIndex)); 667 __ strd(R2, Address(R0, 24, Address::Mode::NegOffset)); 668 __ strd(R2, Address(R0, 24, Address::Mode::NegPreIndex)); 669 __ strd(R2, Address(R0, 24, Address::Mode::NegPostIndex)); 670 671 __ ldrd(R2, Address(R0, 24, Address::Mode::Offset)); 672 __ ldrd(R2, Address(R0, 24, Address::Mode::PreIndex)); 673 __ ldrd(R2, Address(R0, 24, Address::Mode::PostIndex)); 674 __ ldrd(R2, Address(R0, 24, Address::Mode::NegOffset)); 675 __ ldrd(R2, Address(R0, 24, Address::Mode::NegPreIndex)); 676 __ ldrd(R2, Address(R0, 24, Address::Mode::NegPostIndex)); 677 678 EmitAndCheck(&assembler, "ComplexLoadStoreDual"); 679} 680 681TEST_F(Thumb2AssemblerTest, NegativeLoadStoreDual) { 682 __ strd(R2, Address(R0, -24, Address::Mode::Offset)); 683 __ strd(R2, Address(R0, -24, Address::Mode::PreIndex)); 684 __ strd(R2, Address(R0, -24, Address::Mode::PostIndex)); 685 __ strd(R2, Address(R0, -24, Address::Mode::NegOffset)); 686 __ strd(R2, Address(R0, -24, Address::Mode::NegPreIndex)); 687 __ strd(R2, Address(R0, -24, Address::Mode::NegPostIndex)); 688 689 __ ldrd(R2, Address(R0, -24, Address::Mode::Offset)); 690 __ ldrd(R2, Address(R0, -24, Address::Mode::PreIndex)); 691 __ ldrd(R2, Address(R0, -24, Address::Mode::PostIndex)); 692 __ ldrd(R2, Address(R0, -24, Address::Mode::NegOffset)); 693 __ ldrd(R2, Address(R0, -24, Address::Mode::NegPreIndex)); 694 __ ldrd(R2, Address(R0, -24, Address::Mode::NegPostIndex)); 695 696 EmitAndCheck(&assembler, "NegativeLoadStoreDual"); 697} 698 699TEST_F(Thumb2AssemblerTest, SimpleBranch) { 700 Label l1; 701 __ mov(R0, ShifterOperand(2)); 702 __ Bind(&l1); 703 __ mov(R1, ShifterOperand(1)); 704 __ b(&l1); 705 Label l2; 706 __ b(&l2); 707 __ mov(R1, ShifterOperand(2)); 708 __ Bind(&l2); 709 __ mov(R0, ShifterOperand(3)); 710 711 Label l3; 712 __ mov(R0, ShifterOperand(2)); 713 __ Bind(&l3); 714 __ mov(R1, ShifterOperand(1)); 715 __ b(&l3, EQ); 716 717 Label l4; 718 __ b(&l4, EQ); 719 __ mov(R1, ShifterOperand(2)); 720 __ Bind(&l4); 721 __ mov(R0, ShifterOperand(3)); 722 723 // 2 linked labels. 724 Label l5; 725 __ b(&l5); 726 __ mov(R1, ShifterOperand(4)); 727 __ b(&l5); 728 __ mov(R1, ShifterOperand(5)); 729 __ Bind(&l5); 730 __ mov(R0, ShifterOperand(6)); 731 732 EmitAndCheck(&assembler, "SimpleBranch"); 733} 734 735TEST_F(Thumb2AssemblerTest, LongBranch) { 736 __ Force32Bit(); 737 // 32 bit branches. 738 Label l1; 739 __ mov(R0, ShifterOperand(2)); 740 __ Bind(&l1); 741 __ mov(R1, ShifterOperand(1)); 742 __ b(&l1); 743 744 Label l2; 745 __ b(&l2); 746 __ mov(R1, ShifterOperand(2)); 747 __ Bind(&l2); 748 __ mov(R0, ShifterOperand(3)); 749 750 Label l3; 751 __ mov(R0, ShifterOperand(2)); 752 __ Bind(&l3); 753 __ mov(R1, ShifterOperand(1)); 754 __ b(&l3, EQ); 755 756 Label l4; 757 __ b(&l4, EQ); 758 __ mov(R1, ShifterOperand(2)); 759 __ Bind(&l4); 760 __ mov(R0, ShifterOperand(3)); 761 762 // 2 linked labels. 763 Label l5; 764 __ b(&l5); 765 __ mov(R1, ShifterOperand(4)); 766 __ b(&l5); 767 __ mov(R1, ShifterOperand(5)); 768 __ Bind(&l5); 769 __ mov(R0, ShifterOperand(6)); 770 771 EmitAndCheck(&assembler, "LongBranch"); 772} 773 774TEST_F(Thumb2AssemblerTest, LoadMultiple) { 775 // 16 bit. 776 __ ldm(DB_W, R4, (1 << R0 | 1 << R3)); 777 778 // 32 bit. 779 __ ldm(DB_W, R4, (1 << LR | 1 << R11)); 780 __ ldm(DB, R4, (1 << LR | 1 << R11)); 781 782 // Single reg is converted to ldr 783 __ ldm(DB_W, R4, (1 << R5)); 784 785 EmitAndCheck(&assembler, "LoadMultiple"); 786} 787 788TEST_F(Thumb2AssemblerTest, StoreMultiple) { 789 // 16 bit. 790 __ stm(IA_W, R4, (1 << R0 | 1 << R3)); 791 792 // 32 bit. 793 __ stm(IA_W, R4, (1 << LR | 1 << R11)); 794 __ stm(IA, R4, (1 << LR | 1 << R11)); 795 796 // Single reg is converted to str 797 __ stm(IA_W, R4, (1 << R5)); 798 __ stm(IA, R4, (1 << R5)); 799 800 EmitAndCheck(&assembler, "StoreMultiple"); 801} 802 803TEST_F(Thumb2AssemblerTest, MovWMovT) { 804 // Always 32 bit. 805 __ movw(R4, 0); 806 __ movw(R4, 0x34); 807 __ movw(R9, 0x34); 808 __ movw(R3, 0x1234); 809 __ movw(R9, 0xffff); 810 811 // Always 32 bit. 812 __ movt(R0, 0); 813 __ movt(R0, 0x1234); 814 __ movt(R1, 0xffff); 815 816 EmitAndCheck(&assembler, "MovWMovT"); 817} 818 819TEST_F(Thumb2AssemblerTest, SpecialAddSub) { 820 __ add(R2, SP, ShifterOperand(0x50)); // 16 bit. 821 __ add(SP, SP, ShifterOperand(0x50)); // 16 bit. 822 __ add(R8, SP, ShifterOperand(0x50)); // 32 bit. 823 824 __ add(R2, SP, ShifterOperand(0xf00)); // 32 bit due to imm size. 825 __ add(SP, SP, ShifterOperand(0xf00)); // 32 bit due to imm size. 826 __ add(SP, SP, ShifterOperand(0xffc)); // 32 bit due to imm size; encoding T4. 827 828 __ sub(SP, SP, ShifterOperand(0x50)); // 16 bit 829 __ sub(R0, SP, ShifterOperand(0x50)); // 32 bit 830 __ sub(R8, SP, ShifterOperand(0x50)); // 32 bit. 831 832 __ sub(SP, SP, ShifterOperand(0xf00)); // 32 bit due to imm size 833 __ sub(SP, SP, ShifterOperand(0xffc)); // 32 bit due to imm size; encoding T4. 834 835 EmitAndCheck(&assembler, "SpecialAddSub"); 836} 837 838TEST_F(Thumb2AssemblerTest, LoadFromOffset) { 839 __ LoadFromOffset(kLoadWord, R2, R4, 12); 840 __ LoadFromOffset(kLoadWord, R2, R4, 0xfff); 841 __ LoadFromOffset(kLoadWord, R2, R4, 0x1000); 842 __ LoadFromOffset(kLoadWord, R2, R4, 0x1000a4); 843 __ LoadFromOffset(kLoadWord, R2, R4, 0x101000); 844 __ LoadFromOffset(kLoadWord, R4, R4, 0x101000); 845 __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 12); 846 __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0xfff); 847 __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0x1000); 848 __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0x1000a4); 849 __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0x101000); 850 __ LoadFromOffset(kLoadUnsignedHalfword, R4, R4, 0x101000); 851 __ LoadFromOffset(kLoadWordPair, R2, R4, 12); 852 __ LoadFromOffset(kLoadWordPair, R2, R4, 0x3fc); 853 __ LoadFromOffset(kLoadWordPair, R2, R4, 0x400); 854 __ LoadFromOffset(kLoadWordPair, R2, R4, 0x400a4); 855 __ LoadFromOffset(kLoadWordPair, R2, R4, 0x40400); 856 __ LoadFromOffset(kLoadWordPair, R4, R4, 0x40400); 857 858 __ LoadFromOffset(kLoadWord, R0, R12, 12); // 32-bit because of R12. 859 __ LoadFromOffset(kLoadWord, R2, R4, 0xa4 - 0x100000); 860 861 __ LoadFromOffset(kLoadSignedByte, R2, R4, 12); 862 __ LoadFromOffset(kLoadUnsignedByte, R2, R4, 12); 863 __ LoadFromOffset(kLoadSignedHalfword, R2, R4, 12); 864 865 EmitAndCheck(&assembler, "LoadFromOffset"); 866} 867 868TEST_F(Thumb2AssemblerTest, StoreToOffset) { 869 __ StoreToOffset(kStoreWord, R2, R4, 12); 870 __ StoreToOffset(kStoreWord, R2, R4, 0xfff); 871 __ StoreToOffset(kStoreWord, R2, R4, 0x1000); 872 __ StoreToOffset(kStoreWord, R2, R4, 0x1000a4); 873 __ StoreToOffset(kStoreWord, R2, R4, 0x101000); 874 __ StoreToOffset(kStoreWord, R4, R4, 0x101000); 875 __ StoreToOffset(kStoreHalfword, R2, R4, 12); 876 __ StoreToOffset(kStoreHalfword, R2, R4, 0xfff); 877 __ StoreToOffset(kStoreHalfword, R2, R4, 0x1000); 878 __ StoreToOffset(kStoreHalfword, R2, R4, 0x1000a4); 879 __ StoreToOffset(kStoreHalfword, R2, R4, 0x101000); 880 __ StoreToOffset(kStoreHalfword, R4, R4, 0x101000); 881 __ StoreToOffset(kStoreWordPair, R2, R4, 12); 882 __ StoreToOffset(kStoreWordPair, R2, R4, 0x3fc); 883 __ StoreToOffset(kStoreWordPair, R2, R4, 0x400); 884 __ StoreToOffset(kStoreWordPair, R2, R4, 0x400a4); 885 __ StoreToOffset(kStoreWordPair, R2, R4, 0x40400); 886 __ StoreToOffset(kStoreWordPair, R4, R4, 0x40400); 887 888 __ StoreToOffset(kStoreWord, R0, R12, 12); // 32-bit because of R12. 889 __ StoreToOffset(kStoreWord, R2, R4, 0xa4 - 0x100000); 890 891 __ StoreToOffset(kStoreByte, R2, R4, 12); 892 893 EmitAndCheck(&assembler, "StoreToOffset"); 894} 895 896TEST_F(Thumb2AssemblerTest, IfThen) { 897 __ it(EQ); 898 __ mov(R1, ShifterOperand(1), EQ); 899 900 __ it(EQ, kItThen); 901 __ mov(R1, ShifterOperand(1), EQ); 902 __ mov(R2, ShifterOperand(2), EQ); 903 904 __ it(EQ, kItElse); 905 __ mov(R1, ShifterOperand(1), EQ); 906 __ mov(R2, ShifterOperand(2), NE); 907 908 __ it(EQ, kItThen, kItElse); 909 __ mov(R1, ShifterOperand(1), EQ); 910 __ mov(R2, ShifterOperand(2), EQ); 911 __ mov(R3, ShifterOperand(3), NE); 912 913 __ it(EQ, kItElse, kItElse); 914 __ mov(R1, ShifterOperand(1), EQ); 915 __ mov(R2, ShifterOperand(2), NE); 916 __ mov(R3, ShifterOperand(3), NE); 917 918 __ it(EQ, kItThen, kItThen, kItElse); 919 __ mov(R1, ShifterOperand(1), EQ); 920 __ mov(R2, ShifterOperand(2), EQ); 921 __ mov(R3, ShifterOperand(3), EQ); 922 __ mov(R4, ShifterOperand(4), NE); 923 924 EmitAndCheck(&assembler, "IfThen"); 925} 926 927TEST_F(Thumb2AssemblerTest, CbzCbnz) { 928 Label l1; 929 __ cbz(R2, &l1); 930 __ mov(R1, ShifterOperand(3)); 931 __ mov(R2, ShifterOperand(3)); 932 __ Bind(&l1); 933 __ mov(R2, ShifterOperand(4)); 934 935 Label l2; 936 __ cbnz(R2, &l2); 937 __ mov(R8, ShifterOperand(3)); 938 __ mov(R2, ShifterOperand(3)); 939 __ Bind(&l2); 940 __ mov(R2, ShifterOperand(4)); 941 942 EmitAndCheck(&assembler, "CbzCbnz"); 943} 944 945TEST_F(Thumb2AssemblerTest, Multiply) { 946 __ mul(R0, R1, R0); 947 __ mul(R0, R1, R2); 948 __ mul(R8, R9, R8); 949 __ mul(R8, R9, R10); 950 951 __ mla(R0, R1, R2, R3); 952 __ mla(R8, R9, R8, R9); 953 954 __ mls(R0, R1, R2, R3); 955 __ mls(R8, R9, R8, R9); 956 957 __ umull(R0, R1, R2, R3); 958 __ umull(R8, R9, R10, R11); 959 960 EmitAndCheck(&assembler, "Multiply"); 961} 962 963TEST_F(Thumb2AssemblerTest, Divide) { 964 __ sdiv(R0, R1, R2); 965 __ sdiv(R8, R9, R10); 966 967 __ udiv(R0, R1, R2); 968 __ udiv(R8, R9, R10); 969 970 EmitAndCheck(&assembler, "Divide"); 971} 972 973TEST_F(Thumb2AssemblerTest, VMov) { 974 __ vmovs(S1, 1.0); 975 __ vmovd(D1, 1.0); 976 977 __ vmovs(S1, S2); 978 __ vmovd(D1, D2); 979 980 EmitAndCheck(&assembler, "VMov"); 981} 982 983 984TEST_F(Thumb2AssemblerTest, BasicFloatingPoint) { 985 __ vadds(S0, S1, S2); 986 __ vsubs(S0, S1, S2); 987 __ vmuls(S0, S1, S2); 988 __ vmlas(S0, S1, S2); 989 __ vmlss(S0, S1, S2); 990 __ vdivs(S0, S1, S2); 991 __ vabss(S0, S1); 992 __ vnegs(S0, S1); 993 __ vsqrts(S0, S1); 994 995 __ vaddd(D0, D1, D2); 996 __ vsubd(D0, D1, D2); 997 __ vmuld(D0, D1, D2); 998 __ vmlad(D0, D1, D2); 999 __ vmlsd(D0, D1, D2); 1000 __ vdivd(D0, D1, D2); 1001 __ vabsd(D0, D1); 1002 __ vnegd(D0, D1); 1003 __ vsqrtd(D0, D1); 1004 1005 EmitAndCheck(&assembler, "BasicFloatingPoint"); 1006} 1007 1008TEST_F(Thumb2AssemblerTest, FloatingPointConversions) { 1009 __ vcvtsd(S2, D2); 1010 __ vcvtds(D2, S2); 1011 1012 __ vcvtis(S1, S2); 1013 __ vcvtsi(S1, S2); 1014 1015 __ vcvtid(S1, D2); 1016 __ vcvtdi(D1, S2); 1017 1018 __ vcvtus(S1, S2); 1019 __ vcvtsu(S1, S2); 1020 1021 __ vcvtud(S1, D2); 1022 __ vcvtdu(D1, S2); 1023 1024 EmitAndCheck(&assembler, "FloatingPointConversions"); 1025} 1026 1027TEST_F(Thumb2AssemblerTest, FloatingPointComparisons) { 1028 __ vcmps(S0, S1); 1029 __ vcmpd(D0, D1); 1030 1031 __ vcmpsz(S2); 1032 __ vcmpdz(D2); 1033 1034 EmitAndCheck(&assembler, "FloatingPointComparisons"); 1035} 1036 1037TEST_F(Thumb2AssemblerTest, Calls) { 1038 __ blx(LR); 1039 __ bx(LR); 1040 1041 EmitAndCheck(&assembler, "Calls"); 1042} 1043 1044TEST_F(Thumb2AssemblerTest, Breakpoint) { 1045 __ bkpt(0); 1046 1047 EmitAndCheck(&assembler, "Breakpoint"); 1048} 1049 1050TEST_F(Thumb2AssemblerTest, StrR1) { 1051 __ str(R1, Address(SP, 68)); 1052 __ str(R1, Address(SP, 1068)); 1053 1054 EmitAndCheck(&assembler, "StrR1"); 1055} 1056 1057TEST_F(Thumb2AssemblerTest, VPushPop) { 1058 __ vpushs(S2, 4); 1059 __ vpushd(D2, 4); 1060 1061 __ vpops(S2, 4); 1062 __ vpopd(D2, 4); 1063 1064 EmitAndCheck(&assembler, "VPushPop"); 1065} 1066 1067TEST_F(Thumb2AssemblerTest, Max16BitBranch) { 1068 Label l1; 1069 __ b(&l1); 1070 for (int i = 0 ; i < (1 << 11) ; i += 2) { 1071 __ mov(R3, ShifterOperand(i & 0xff)); 1072 } 1073 __ Bind(&l1); 1074 __ mov(R1, ShifterOperand(R2)); 1075 1076 EmitAndCheck(&assembler, "Max16BitBranch"); 1077} 1078 1079TEST_F(Thumb2AssemblerTest, Branch32) { 1080 Label l1; 1081 __ b(&l1); 1082 for (int i = 0 ; i < (1 << 11) + 2 ; i += 2) { 1083 __ mov(R3, ShifterOperand(i & 0xff)); 1084 } 1085 __ Bind(&l1); 1086 __ mov(R1, ShifterOperand(R2)); 1087 1088 EmitAndCheck(&assembler, "Branch32"); 1089} 1090 1091TEST_F(Thumb2AssemblerTest, CompareAndBranchMax) { 1092 Label l1; 1093 __ cbz(R4, &l1); 1094 for (int i = 0 ; i < (1 << 7) ; i += 2) { 1095 __ mov(R3, ShifterOperand(i & 0xff)); 1096 } 1097 __ Bind(&l1); 1098 __ mov(R1, ShifterOperand(R2)); 1099 1100 EmitAndCheck(&assembler, "CompareAndBranchMax"); 1101} 1102 1103TEST_F(Thumb2AssemblerTest, CompareAndBranchRelocation16) { 1104 Label l1; 1105 __ cbz(R4, &l1); 1106 for (int i = 0 ; i < (1 << 7) + 2 ; i += 2) { 1107 __ mov(R3, ShifterOperand(i & 0xff)); 1108 } 1109 __ Bind(&l1); 1110 __ mov(R1, ShifterOperand(R2)); 1111 1112 EmitAndCheck(&assembler, "CompareAndBranchRelocation16"); 1113} 1114 1115TEST_F(Thumb2AssemblerTest, CompareAndBranchRelocation32) { 1116 Label l1; 1117 __ cbz(R4, &l1); 1118 for (int i = 0 ; i < (1 << 11) + 2 ; i += 2) { 1119 __ mov(R3, ShifterOperand(i & 0xff)); 1120 } 1121 __ Bind(&l1); 1122 __ mov(R1, ShifterOperand(R2)); 1123 1124 EmitAndCheck(&assembler, "CompareAndBranchRelocation32"); 1125} 1126 1127TEST_F(Thumb2AssemblerTest, MixedBranch32) { 1128 Label l1; 1129 Label l2; 1130 __ b(&l1); // Forwards. 1131 __ Bind(&l2); 1132 1133 // Space to force relocation. 1134 for (int i = 0 ; i < (1 << 11) + 2 ; i += 2) { 1135 __ mov(R3, ShifterOperand(i & 0xff)); 1136 } 1137 __ b(&l2); // Backwards. 1138 __ Bind(&l1); 1139 __ mov(R1, ShifterOperand(R2)); 1140 1141 EmitAndCheck(&assembler, "MixedBranch32"); 1142} 1143 1144TEST_F(Thumb2AssemblerTest, Shifts) { 1145 // 16 bit selected for CcDontCare. 1146 __ Lsl(R0, R1, 5); 1147 __ Lsr(R0, R1, 5); 1148 __ Asr(R0, R1, 5); 1149 1150 __ Lsl(R0, R0, R1); 1151 __ Lsr(R0, R0, R1); 1152 __ Asr(R0, R0, R1); 1153 __ Ror(R0, R0, R1); 1154 1155 // 16 bit with kCcSet. 1156 __ Lsls(R0, R1, 5); 1157 __ Lsrs(R0, R1, 5); 1158 __ Asrs(R0, R1, 5); 1159 1160 __ Lsls(R0, R0, R1); 1161 __ Lsrs(R0, R0, R1); 1162 __ Asrs(R0, R0, R1); 1163 __ Rors(R0, R0, R1); 1164 1165 // 32-bit with kCcKeep. 1166 __ Lsl(R0, R1, 5, AL, kCcKeep); 1167 __ Lsr(R0, R1, 5, AL, kCcKeep); 1168 __ Asr(R0, R1, 5, AL, kCcKeep); 1169 1170 __ Lsl(R0, R0, R1, AL, kCcKeep); 1171 __ Lsr(R0, R0, R1, AL, kCcKeep); 1172 __ Asr(R0, R0, R1, AL, kCcKeep); 1173 __ Ror(R0, R0, R1, AL, kCcKeep); 1174 1175 // 32-bit because ROR immediate doesn't have a 16-bit version like the other shifts. 1176 __ Ror(R0, R1, 5); 1177 __ Rors(R0, R1, 5); 1178 __ Ror(R0, R1, 5, AL, kCcKeep); 1179 1180 // 32 bit due to high registers. 1181 __ Lsl(R8, R1, 5); 1182 __ Lsr(R0, R8, 5); 1183 __ Asr(R8, R1, 5); 1184 __ Ror(R0, R8, 5); 1185 1186 // 32 bit due to different Rd and Rn. 1187 __ Lsl(R0, R1, R2); 1188 __ Lsr(R0, R1, R2); 1189 __ Asr(R0, R1, R2); 1190 __ Ror(R0, R1, R2); 1191 1192 // 32 bit due to use of high registers. 1193 __ Lsl(R8, R1, R2); 1194 __ Lsr(R0, R8, R2); 1195 __ Asr(R0, R1, R8); 1196 1197 // S bit (all 32 bit) 1198 1199 // 32 bit due to high registers. 1200 __ Lsls(R8, R1, 5); 1201 __ Lsrs(R0, R8, 5); 1202 __ Asrs(R8, R1, 5); 1203 __ Rors(R0, R8, 5); 1204 1205 // 32 bit due to different Rd and Rn. 1206 __ Lsls(R0, R1, R2); 1207 __ Lsrs(R0, R1, R2); 1208 __ Asrs(R0, R1, R2); 1209 __ Rors(R0, R1, R2); 1210 1211 // 32 bit due to use of high registers. 1212 __ Lsls(R8, R1, R2); 1213 __ Lsrs(R0, R8, R2); 1214 __ Asrs(R0, R1, R8); 1215 1216 EmitAndCheck(&assembler, "Shifts"); 1217} 1218 1219TEST_F(Thumb2AssemblerTest, LoadStoreRegOffset) { 1220 // 16 bit. 1221 __ ldr(R0, Address(R1, R2)); 1222 __ str(R0, Address(R1, R2)); 1223 1224 // 32 bit due to shift. 1225 __ ldr(R0, Address(R1, R2, LSL, 1)); 1226 __ str(R0, Address(R1, R2, LSL, 1)); 1227 1228 __ ldr(R0, Address(R1, R2, LSL, 3)); 1229 __ str(R0, Address(R1, R2, LSL, 3)); 1230 1231 // 32 bit due to high register use. 1232 __ ldr(R8, Address(R1, R2)); 1233 __ str(R8, Address(R1, R2)); 1234 1235 __ ldr(R1, Address(R8, R2)); 1236 __ str(R2, Address(R8, R2)); 1237 1238 __ ldr(R0, Address(R1, R8)); 1239 __ str(R0, Address(R1, R8)); 1240 1241 EmitAndCheck(&assembler, "LoadStoreRegOffset"); 1242} 1243 1244TEST_F(Thumb2AssemblerTest, LoadStoreLiteral) { 1245 __ ldr(R0, Address(4)); 1246 __ str(R0, Address(4)); 1247 1248 __ ldr(R0, Address(-8)); 1249 __ str(R0, Address(-8)); 1250 1251 // Limits. 1252 __ ldr(R0, Address(0x3ff)); // 10 bits (16 bit). 1253 __ ldr(R0, Address(0x7ff)); // 11 bits (32 bit). 1254 __ str(R0, Address(0x3ff)); // 32 bit (no 16 bit str(literal)). 1255 __ str(R0, Address(0x7ff)); // 11 bits (32 bit). 1256 1257 EmitAndCheck(&assembler, "LoadStoreLiteral"); 1258} 1259 1260TEST_F(Thumb2AssemblerTest, LoadStoreLimits) { 1261 __ ldr(R0, Address(R4, 124)); // 16 bit. 1262 __ ldr(R0, Address(R4, 128)); // 32 bit. 1263 1264 __ ldrb(R0, Address(R4, 31)); // 16 bit. 1265 __ ldrb(R0, Address(R4, 32)); // 32 bit. 1266 1267 __ ldrh(R0, Address(R4, 62)); // 16 bit. 1268 __ ldrh(R0, Address(R4, 64)); // 32 bit. 1269 1270 __ ldrsb(R0, Address(R4, 31)); // 32 bit. 1271 __ ldrsb(R0, Address(R4, 32)); // 32 bit. 1272 1273 __ ldrsh(R0, Address(R4, 62)); // 32 bit. 1274 __ ldrsh(R0, Address(R4, 64)); // 32 bit. 1275 1276 __ str(R0, Address(R4, 124)); // 16 bit. 1277 __ str(R0, Address(R4, 128)); // 32 bit. 1278 1279 __ strb(R0, Address(R4, 31)); // 16 bit. 1280 __ strb(R0, Address(R4, 32)); // 32 bit. 1281 1282 __ strh(R0, Address(R4, 62)); // 16 bit. 1283 __ strh(R0, Address(R4, 64)); // 32 bit. 1284 1285 EmitAndCheck(&assembler, "LoadStoreLimits"); 1286} 1287 1288TEST_F(Thumb2AssemblerTest, CompareAndBranch) { 1289 Label label; 1290 __ CompareAndBranchIfZero(arm::R0, &label); 1291 __ CompareAndBranchIfZero(arm::R11, &label); 1292 __ CompareAndBranchIfNonZero(arm::R0, &label); 1293 __ CompareAndBranchIfNonZero(arm::R11, &label); 1294 __ Bind(&label); 1295 1296 EmitAndCheck(&assembler, "CompareAndBranch"); 1297} 1298 1299TEST_F(Thumb2AssemblerTest, AddConstant) { 1300 // Low registers, Rd != Rn. 1301 __ AddConstant(R0, R1, 0); // MOV. 1302 __ AddConstant(R0, R1, 1); // 16-bit ADDS, encoding T1. 1303 __ AddConstant(R0, R1, 7); // 16-bit ADDS, encoding T1. 1304 __ AddConstant(R0, R1, 8); // 32-bit ADD, encoding T3. 1305 __ AddConstant(R0, R1, 255); // 32-bit ADD, encoding T3. 1306 __ AddConstant(R0, R1, 256); // 32-bit ADD, encoding T3. 1307 __ AddConstant(R0, R1, 257); // 32-bit ADD, encoding T4. 1308 __ AddConstant(R0, R1, 0xfff); // 32-bit ADD, encoding T4. 1309 __ AddConstant(R0, R1, 0x1000); // 32-bit ADD, encoding T3. 1310 __ AddConstant(R0, R1, 0x1001); // MVN+SUB. 1311 __ AddConstant(R0, R1, 0x1002); // MOVW+ADD. 1312 __ AddConstant(R0, R1, 0xffff); // MOVW+ADD. 1313 __ AddConstant(R0, R1, 0x10000); // 32-bit ADD, encoding T3. 1314 __ AddConstant(R0, R1, 0x10001); // 32-bit ADD, encoding T3. 1315 __ AddConstant(R0, R1, 0x10002); // MVN+SUB. 1316 __ AddConstant(R0, R1, 0x10003); // MOVW+MOVT+ADD. 1317 __ AddConstant(R0, R1, -1); // 16-bit SUBS. 1318 __ AddConstant(R0, R1, -7); // 16-bit SUBS. 1319 __ AddConstant(R0, R1, -8); // 32-bit SUB, encoding T3. 1320 __ AddConstant(R0, R1, -255); // 32-bit SUB, encoding T3. 1321 __ AddConstant(R0, R1, -256); // 32-bit SUB, encoding T3. 1322 __ AddConstant(R0, R1, -257); // 32-bit SUB, encoding T4. 1323 __ AddConstant(R0, R1, -0xfff); // 32-bit SUB, encoding T4. 1324 __ AddConstant(R0, R1, -0x1000); // 32-bit SUB, encoding T3. 1325 __ AddConstant(R0, R1, -0x1001); // MVN+ADD. 1326 __ AddConstant(R0, R1, -0x1002); // MOVW+SUB. 1327 __ AddConstant(R0, R1, -0xffff); // MOVW+SUB. 1328 __ AddConstant(R0, R1, -0x10000); // 32-bit SUB, encoding T3. 1329 __ AddConstant(R0, R1, -0x10001); // 32-bit SUB, encoding T3. 1330 __ AddConstant(R0, R1, -0x10002); // MVN+ADD. 1331 __ AddConstant(R0, R1, -0x10003); // MOVW+MOVT+ADD. 1332 1333 // Low registers, Rd == Rn. 1334 __ AddConstant(R0, R0, 0); // Nothing. 1335 __ AddConstant(R1, R1, 1); // 16-bit ADDS, encoding T2, 1336 __ AddConstant(R0, R0, 7); // 16-bit ADDS, encoding T2. 1337 __ AddConstant(R1, R1, 8); // 16-bit ADDS, encoding T2. 1338 __ AddConstant(R0, R0, 255); // 16-bit ADDS, encoding T2. 1339 __ AddConstant(R1, R1, 256); // 32-bit ADD, encoding T3. 1340 __ AddConstant(R0, R0, 257); // 32-bit ADD, encoding T4. 1341 __ AddConstant(R1, R1, 0xfff); // 32-bit ADD, encoding T4. 1342 __ AddConstant(R0, R0, 0x1000); // 32-bit ADD, encoding T3. 1343 __ AddConstant(R1, R1, 0x1001); // MVN+SUB. 1344 __ AddConstant(R0, R0, 0x1002); // MOVW+ADD. 1345 __ AddConstant(R1, R1, 0xffff); // MOVW+ADD. 1346 __ AddConstant(R0, R0, 0x10000); // 32-bit ADD, encoding T3. 1347 __ AddConstant(R1, R1, 0x10001); // 32-bit ADD, encoding T3. 1348 __ AddConstant(R0, R0, 0x10002); // MVN+SUB. 1349 __ AddConstant(R1, R1, 0x10003); // MOVW+MOVT+ADD. 1350 __ AddConstant(R0, R0, -1); // 16-bit SUBS, encoding T2. 1351 __ AddConstant(R1, R1, -7); // 16-bit SUBS, encoding T2. 1352 __ AddConstant(R0, R0, -8); // 16-bit SUBS, encoding T2. 1353 __ AddConstant(R1, R1, -255); // 16-bit SUBS, encoding T2. 1354 __ AddConstant(R0, R0, -256); // 32-bit SUB, encoding T3. 1355 __ AddConstant(R1, R1, -257); // 32-bit SUB, encoding T4. 1356 __ AddConstant(R0, R0, -0xfff); // 32-bit SUB, encoding T4. 1357 __ AddConstant(R1, R1, -0x1000); // 32-bit SUB, encoding T3. 1358 __ AddConstant(R0, R0, -0x1001); // MVN+ADD. 1359 __ AddConstant(R1, R1, -0x1002); // MOVW+SUB. 1360 __ AddConstant(R0, R0, -0xffff); // MOVW+SUB. 1361 __ AddConstant(R1, R1, -0x10000); // 32-bit SUB, encoding T3. 1362 __ AddConstant(R0, R0, -0x10001); // 32-bit SUB, encoding T3. 1363 __ AddConstant(R1, R1, -0x10002); // MVN+ADD. 1364 __ AddConstant(R0, R0, -0x10003); // MOVW+MOVT+ADD. 1365 1366 // High registers. 1367 __ AddConstant(R8, R8, 0); // Nothing. 1368 __ AddConstant(R8, R1, 1); // 32-bit ADD, encoding T3, 1369 __ AddConstant(R0, R8, 7); // 32-bit ADD, encoding T3. 1370 __ AddConstant(R8, R8, 8); // 32-bit ADD, encoding T3. 1371 __ AddConstant(R8, R1, 255); // 32-bit ADD, encoding T3. 1372 __ AddConstant(R0, R8, 256); // 32-bit ADD, encoding T3. 1373 __ AddConstant(R8, R8, 257); // 32-bit ADD, encoding T4. 1374 __ AddConstant(R8, R1, 0xfff); // 32-bit ADD, encoding T4. 1375 __ AddConstant(R0, R8, 0x1000); // 32-bit ADD, encoding T3. 1376 __ AddConstant(R8, R8, 0x1001); // MVN+SUB. 1377 __ AddConstant(R0, R1, 0x1002); // MOVW+ADD. 1378 __ AddConstant(R0, R8, 0xffff); // MOVW+ADD. 1379 __ AddConstant(R8, R8, 0x10000); // 32-bit ADD, encoding T3. 1380 __ AddConstant(R8, R1, 0x10001); // 32-bit ADD, encoding T3. 1381 __ AddConstant(R0, R8, 0x10002); // MVN+SUB. 1382 __ AddConstant(R0, R8, 0x10003); // MOVW+MOVT+ADD. 1383 __ AddConstant(R8, R8, -1); // 32-bit ADD, encoding T3. 1384 __ AddConstant(R8, R1, -7); // 32-bit SUB, encoding T3. 1385 __ AddConstant(R0, R8, -8); // 32-bit SUB, encoding T3. 1386 __ AddConstant(R8, R8, -255); // 32-bit SUB, encoding T3. 1387 __ AddConstant(R8, R1, -256); // 32-bit SUB, encoding T3. 1388 __ AddConstant(R0, R8, -257); // 32-bit SUB, encoding T4. 1389 __ AddConstant(R8, R8, -0xfff); // 32-bit SUB, encoding T4. 1390 __ AddConstant(R8, R1, -0x1000); // 32-bit SUB, encoding T3. 1391 __ AddConstant(R0, R8, -0x1001); // MVN+ADD. 1392 __ AddConstant(R0, R1, -0x1002); // MOVW+SUB. 1393 __ AddConstant(R8, R1, -0xffff); // MOVW+SUB. 1394 __ AddConstant(R0, R8, -0x10000); // 32-bit SUB, encoding T3. 1395 __ AddConstant(R8, R8, -0x10001); // 32-bit SUB, encoding T3. 1396 __ AddConstant(R8, R1, -0x10002); // MVN+SUB. 1397 __ AddConstant(R0, R8, -0x10003); // MOVW+MOVT+ADD. 1398 1399 // Low registers, Rd != Rn, kCcKeep. 1400 __ AddConstant(R0, R1, 0, AL, kCcKeep); // MOV. 1401 __ AddConstant(R0, R1, 1, AL, kCcKeep); // 32-bit ADD, encoding T3. 1402 __ AddConstant(R0, R1, 7, AL, kCcKeep); // 32-bit ADD, encoding T3. 1403 __ AddConstant(R0, R1, 8, AL, kCcKeep); // 32-bit ADD, encoding T3. 1404 __ AddConstant(R0, R1, 255, AL, kCcKeep); // 32-bit ADD, encoding T3. 1405 __ AddConstant(R0, R1, 256, AL, kCcKeep); // 32-bit ADD, encoding T3. 1406 __ AddConstant(R0, R1, 257, AL, kCcKeep); // 32-bit ADD, encoding T4. 1407 __ AddConstant(R0, R1, 0xfff, AL, kCcKeep); // 32-bit ADD, encoding T4. 1408 __ AddConstant(R0, R1, 0x1000, AL, kCcKeep); // 32-bit ADD, encoding T3. 1409 __ AddConstant(R0, R1, 0x1001, AL, kCcKeep); // MVN+SUB. 1410 __ AddConstant(R0, R1, 0x1002, AL, kCcKeep); // MOVW+ADD. 1411 __ AddConstant(R0, R1, 0xffff, AL, kCcKeep); // MOVW+ADD. 1412 __ AddConstant(R0, R1, 0x10000, AL, kCcKeep); // 32-bit ADD, encoding T3. 1413 __ AddConstant(R0, R1, 0x10001, AL, kCcKeep); // 32-bit ADD, encoding T3. 1414 __ AddConstant(R0, R1, 0x10002, AL, kCcKeep); // MVN+SUB. 1415 __ AddConstant(R0, R1, 0x10003, AL, kCcKeep); // MOVW+MOVT+ADD. 1416 __ AddConstant(R0, R1, -1, AL, kCcKeep); // 32-bit ADD, encoding T3. 1417 __ AddConstant(R0, R1, -7, AL, kCcKeep); // 32-bit SUB, encoding T3. 1418 __ AddConstant(R0, R1, -8, AL, kCcKeep); // 32-bit SUB, encoding T3. 1419 __ AddConstant(R0, R1, -255, AL, kCcKeep); // 32-bit SUB, encoding T3. 1420 __ AddConstant(R0, R1, -256, AL, kCcKeep); // 32-bit SUB, encoding T3. 1421 __ AddConstant(R0, R1, -257, AL, kCcKeep); // 32-bit SUB, encoding T4. 1422 __ AddConstant(R0, R1, -0xfff, AL, kCcKeep); // 32-bit SUB, encoding T4. 1423 __ AddConstant(R0, R1, -0x1000, AL, kCcKeep); // 32-bit SUB, encoding T3. 1424 __ AddConstant(R0, R1, -0x1001, AL, kCcKeep); // MVN+ADD. 1425 __ AddConstant(R0, R1, -0x1002, AL, kCcKeep); // MOVW+SUB. 1426 __ AddConstant(R0, R1, -0xffff, AL, kCcKeep); // MOVW+SUB. 1427 __ AddConstant(R0, R1, -0x10000, AL, kCcKeep); // 32-bit SUB, encoding T3. 1428 __ AddConstant(R0, R1, -0x10001, AL, kCcKeep); // 32-bit SUB, encoding T3. 1429 __ AddConstant(R0, R1, -0x10002, AL, kCcKeep); // MVN+ADD. 1430 __ AddConstant(R0, R1, -0x10003, AL, kCcKeep); // MOVW+MOVT+ADD. 1431 1432 // Low registers, Rd == Rn, kCcKeep. 1433 __ AddConstant(R0, R0, 0, AL, kCcKeep); // Nothing. 1434 __ AddConstant(R1, R1, 1, AL, kCcKeep); // 32-bit ADD, encoding T3. 1435 __ AddConstant(R0, R0, 7, AL, kCcKeep); // 32-bit ADD, encoding T3. 1436 __ AddConstant(R1, R1, 8, AL, kCcKeep); // 32-bit ADD, encoding T3. 1437 __ AddConstant(R0, R0, 255, AL, kCcKeep); // 32-bit ADD, encoding T3. 1438 __ AddConstant(R1, R1, 256, AL, kCcKeep); // 32-bit ADD, encoding T3. 1439 __ AddConstant(R0, R0, 257, AL, kCcKeep); // 32-bit ADD, encoding T4. 1440 __ AddConstant(R1, R1, 0xfff, AL, kCcKeep); // 32-bit ADD, encoding T4. 1441 __ AddConstant(R0, R0, 0x1000, AL, kCcKeep); // 32-bit ADD, encoding T3. 1442 __ AddConstant(R1, R1, 0x1001, AL, kCcKeep); // MVN+SUB. 1443 __ AddConstant(R0, R0, 0x1002, AL, kCcKeep); // MOVW+ADD. 1444 __ AddConstant(R1, R1, 0xffff, AL, kCcKeep); // MOVW+ADD. 1445 __ AddConstant(R0, R0, 0x10000, AL, kCcKeep); // 32-bit ADD, encoding T3. 1446 __ AddConstant(R1, R1, 0x10001, AL, kCcKeep); // 32-bit ADD, encoding T3. 1447 __ AddConstant(R0, R0, 0x10002, AL, kCcKeep); // MVN+SUB. 1448 __ AddConstant(R1, R1, 0x10003, AL, kCcKeep); // MOVW+MOVT+ADD. 1449 __ AddConstant(R0, R0, -1, AL, kCcKeep); // 32-bit ADD, encoding T3. 1450 __ AddConstant(R1, R1, -7, AL, kCcKeep); // 32-bit SUB, encoding T3. 1451 __ AddConstant(R0, R0, -8, AL, kCcKeep); // 32-bit SUB, encoding T3. 1452 __ AddConstant(R1, R1, -255, AL, kCcKeep); // 32-bit SUB, encoding T3. 1453 __ AddConstant(R0, R0, -256, AL, kCcKeep); // 32-bit SUB, encoding T3. 1454 __ AddConstant(R1, R1, -257, AL, kCcKeep); // 32-bit SUB, encoding T4. 1455 __ AddConstant(R0, R0, -0xfff, AL, kCcKeep); // 32-bit SUB, encoding T4. 1456 __ AddConstant(R1, R1, -0x1000, AL, kCcKeep); // 32-bit SUB, encoding T3. 1457 __ AddConstant(R0, R0, -0x1001, AL, kCcKeep); // MVN+ADD. 1458 __ AddConstant(R1, R1, -0x1002, AL, kCcKeep); // MOVW+SUB. 1459 __ AddConstant(R0, R0, -0xffff, AL, kCcKeep); // MOVW+SUB. 1460 __ AddConstant(R1, R1, -0x10000, AL, kCcKeep); // 32-bit SUB, encoding T3. 1461 __ AddConstant(R0, R0, -0x10001, AL, kCcKeep); // 32-bit SUB, encoding T3. 1462 __ AddConstant(R1, R1, -0x10002, AL, kCcKeep); // MVN+ADD. 1463 __ AddConstant(R0, R0, -0x10003, AL, kCcKeep); // MOVW+MOVT+ADD. 1464 1465 // Low registers, Rd != Rn, kCcSet. 1466 __ AddConstant(R0, R1, 0, AL, kCcSet); // 16-bit ADDS. 1467 __ AddConstant(R0, R1, 1, AL, kCcSet); // 16-bit ADDS. 1468 __ AddConstant(R0, R1, 7, AL, kCcSet); // 16-bit ADDS. 1469 __ AddConstant(R0, R1, 8, AL, kCcSet); // 32-bit ADDS, encoding T3. 1470 __ AddConstant(R0, R1, 255, AL, kCcSet); // 32-bit ADDS, encoding T3. 1471 __ AddConstant(R0, R1, 256, AL, kCcSet); // 32-bit ADDS, encoding T3. 1472 __ AddConstant(R0, R1, 257, AL, kCcSet); // MVN+SUBS. 1473 __ AddConstant(R0, R1, 0xfff, AL, kCcSet); // MOVW+ADDS. 1474 __ AddConstant(R0, R1, 0x1000, AL, kCcSet); // 32-bit ADDS, encoding T3. 1475 __ AddConstant(R0, R1, 0x1001, AL, kCcSet); // MVN+SUBS. 1476 __ AddConstant(R0, R1, 0x1002, AL, kCcSet); // MOVW+ADDS. 1477 __ AddConstant(R0, R1, 0xffff, AL, kCcSet); // MOVW+ADDS. 1478 __ AddConstant(R0, R1, 0x10000, AL, kCcSet); // 32-bit ADDS, encoding T3. 1479 __ AddConstant(R0, R1, 0x10001, AL, kCcSet); // 32-bit ADDS, encoding T3. 1480 __ AddConstant(R0, R1, 0x10002, AL, kCcSet); // MVN+SUBS. 1481 __ AddConstant(R0, R1, 0x10003, AL, kCcSet); // MOVW+MOVT+ADDS. 1482 __ AddConstant(R0, R1, -1, AL, kCcSet); // 16-bit SUBS. 1483 __ AddConstant(R0, R1, -7, AL, kCcSet); // 16-bit SUBS. 1484 __ AddConstant(R0, R1, -8, AL, kCcSet); // 32-bit SUBS, encoding T3. 1485 __ AddConstant(R0, R1, -255, AL, kCcSet); // 32-bit SUBS, encoding T3. 1486 __ AddConstant(R0, R1, -256, AL, kCcSet); // 32-bit SUBS, encoding T3. 1487 __ AddConstant(R0, R1, -257, AL, kCcSet); // MVN+ADDS. 1488 __ AddConstant(R0, R1, -0xfff, AL, kCcSet); // MOVW+SUBS. 1489 __ AddConstant(R0, R1, -0x1000, AL, kCcSet); // 32-bit SUBS, encoding T3. 1490 __ AddConstant(R0, R1, -0x1001, AL, kCcSet); // MVN+ADDS. 1491 __ AddConstant(R0, R1, -0x1002, AL, kCcSet); // MOVW+SUBS. 1492 __ AddConstant(R0, R1, -0xffff, AL, kCcSet); // MOVW+SUBS. 1493 __ AddConstant(R0, R1, -0x10000, AL, kCcSet); // 32-bit SUBS, encoding T3. 1494 __ AddConstant(R0, R1, -0x10001, AL, kCcSet); // 32-bit SUBS, encoding T3. 1495 __ AddConstant(R0, R1, -0x10002, AL, kCcSet); // MVN+ADDS. 1496 __ AddConstant(R0, R1, -0x10003, AL, kCcSet); // MOVW+MOVT+ADDS. 1497 1498 // Low registers, Rd == Rn, kCcSet. 1499 __ AddConstant(R0, R0, 0, AL, kCcSet); // 16-bit ADDS, encoding T2. 1500 __ AddConstant(R1, R1, 1, AL, kCcSet); // 16-bit ADDS, encoding T2. 1501 __ AddConstant(R0, R0, 7, AL, kCcSet); // 16-bit ADDS, encoding T2. 1502 __ AddConstant(R1, R1, 8, AL, kCcSet); // 16-bit ADDS, encoding T2. 1503 __ AddConstant(R0, R0, 255, AL, kCcSet); // 16-bit ADDS, encoding T2. 1504 __ AddConstant(R1, R1, 256, AL, kCcSet); // 32-bit ADDS, encoding T3. 1505 __ AddConstant(R0, R0, 257, AL, kCcSet); // MVN+SUBS. 1506 __ AddConstant(R1, R1, 0xfff, AL, kCcSet); // MOVW+ADDS. 1507 __ AddConstant(R0, R0, 0x1000, AL, kCcSet); // 32-bit ADDS, encoding T3. 1508 __ AddConstant(R1, R1, 0x1001, AL, kCcSet); // MVN+SUBS. 1509 __ AddConstant(R0, R0, 0x1002, AL, kCcSet); // MOVW+ADDS. 1510 __ AddConstant(R1, R1, 0xffff, AL, kCcSet); // MOVW+ADDS. 1511 __ AddConstant(R0, R0, 0x10000, AL, kCcSet); // 32-bit ADDS, encoding T3. 1512 __ AddConstant(R1, R1, 0x10001, AL, kCcSet); // 32-bit ADDS, encoding T3. 1513 __ AddConstant(R0, R0, 0x10002, AL, kCcSet); // MVN+SUBS. 1514 __ AddConstant(R1, R1, 0x10003, AL, kCcSet); // MOVW+MOVT+ADDS. 1515 __ AddConstant(R0, R0, -1, AL, kCcSet); // 16-bit SUBS, encoding T2. 1516 __ AddConstant(R1, R1, -7, AL, kCcSet); // 16-bit SUBS, encoding T2. 1517 __ AddConstant(R0, R0, -8, AL, kCcSet); // 16-bit SUBS, encoding T2. 1518 __ AddConstant(R1, R1, -255, AL, kCcSet); // 16-bit SUBS, encoding T2. 1519 __ AddConstant(R0, R0, -256, AL, kCcSet); // 32-bit SUB, encoding T3. 1520 __ AddConstant(R1, R1, -257, AL, kCcSet); // MNV+ADDS. 1521 __ AddConstant(R0, R0, -0xfff, AL, kCcSet); // MOVW+SUBS. 1522 __ AddConstant(R1, R1, -0x1000, AL, kCcSet); // 32-bit SUB, encoding T3. 1523 __ AddConstant(R0, R0, -0x1001, AL, kCcSet); // MVN+ADDS. 1524 __ AddConstant(R1, R1, -0x1002, AL, kCcSet); // MOVW+SUBS. 1525 __ AddConstant(R0, R0, -0xffff, AL, kCcSet); // MOVW+SUBS. 1526 __ AddConstant(R1, R1, -0x10000, AL, kCcSet); // 32-bit SUBS, encoding T3. 1527 __ AddConstant(R0, R0, -0x10001, AL, kCcSet); // 32-bit SUBS, encoding T3. 1528 __ AddConstant(R1, R1, -0x10002, AL, kCcSet); // MVN+ADDS. 1529 __ AddConstant(R0, R0, -0x10003, AL, kCcSet); // MOVW+MOVT+ADDS. 1530 1531 __ it(EQ); 1532 __ AddConstant(R0, R1, 1, EQ, kCcSet); // 32-bit ADDS, encoding T3. 1533 __ it(NE); 1534 __ AddConstant(R0, R1, 1, NE, kCcKeep); // 16-bit ADDS, encoding T1. 1535 __ it(GE); 1536 __ AddConstant(R0, R0, 1, GE, kCcSet); // 32-bit ADDS, encoding T3. 1537 __ it(LE); 1538 __ AddConstant(R0, R0, 1, LE, kCcKeep); // 16-bit ADDS, encoding T2. 1539 1540 EmitAndCheck(&assembler, "AddConstant"); 1541} 1542 1543TEST_F(Thumb2AssemblerTest, CmpConstant) { 1544 __ CmpConstant(R0, 0); // 16-bit CMP. 1545 __ CmpConstant(R1, 1); // 16-bit CMP. 1546 __ CmpConstant(R0, 7); // 16-bit CMP. 1547 __ CmpConstant(R1, 8); // 16-bit CMP. 1548 __ CmpConstant(R0, 255); // 16-bit CMP. 1549 __ CmpConstant(R1, 256); // 32-bit CMP. 1550 __ CmpConstant(R0, 257); // MNV+CMN. 1551 __ CmpConstant(R1, 0xfff); // MOVW+CMP. 1552 __ CmpConstant(R0, 0x1000); // 32-bit CMP. 1553 __ CmpConstant(R1, 0x1001); // MNV+CMN. 1554 __ CmpConstant(R0, 0x1002); // MOVW+CMP. 1555 __ CmpConstant(R1, 0xffff); // MOVW+CMP. 1556 __ CmpConstant(R0, 0x10000); // 32-bit CMP. 1557 __ CmpConstant(R1, 0x10001); // 32-bit CMP. 1558 __ CmpConstant(R0, 0x10002); // MVN+CMN. 1559 __ CmpConstant(R1, 0x10003); // MOVW+MOVT+CMP. 1560 __ CmpConstant(R0, -1); // 32-bit CMP. 1561 __ CmpConstant(R1, -7); // CMN. 1562 __ CmpConstant(R0, -8); // CMN. 1563 __ CmpConstant(R1, -255); // CMN. 1564 __ CmpConstant(R0, -256); // CMN. 1565 __ CmpConstant(R1, -257); // MNV+CMP. 1566 __ CmpConstant(R0, -0xfff); // MOVW+CMN. 1567 __ CmpConstant(R1, -0x1000); // CMN. 1568 __ CmpConstant(R0, -0x1001); // MNV+CMP. 1569 __ CmpConstant(R1, -0x1002); // MOVW+CMN. 1570 __ CmpConstant(R0, -0xffff); // MOVW+CMN. 1571 __ CmpConstant(R1, -0x10000); // CMN. 1572 __ CmpConstant(R0, -0x10001); // CMN. 1573 __ CmpConstant(R1, -0x10002); // MVN+CMP. 1574 __ CmpConstant(R0, -0x10003); // MOVW+MOVT+CMP. 1575 1576 __ CmpConstant(R8, 0); // 32-bit CMP. 1577 __ CmpConstant(R9, 1); // 32-bit CMP. 1578 __ CmpConstant(R8, 7); // 32-bit CMP. 1579 __ CmpConstant(R9, 8); // 32-bit CMP. 1580 __ CmpConstant(R8, 255); // 32-bit CMP. 1581 __ CmpConstant(R9, 256); // 32-bit CMP. 1582 __ CmpConstant(R8, 257); // MNV+CMN 1583 __ CmpConstant(R9, 0xfff); // MOVW+CMP. 1584 __ CmpConstant(R8, 0x1000); // 32-bit CMP. 1585 __ CmpConstant(R9, 0x1001); // MVN+CMN. 1586 __ CmpConstant(R8, 0x1002); // MOVW+CMP. 1587 __ CmpConstant(R9, 0xffff); // MOVW+CMP. 1588 __ CmpConstant(R8, 0x10000); // 32-bit CMP. 1589 __ CmpConstant(R9, 0x10001); // 32-bit CMP. 1590 __ CmpConstant(R8, 0x10002); // MVN+CMN. 1591 __ CmpConstant(R9, 0x10003); // MOVW+MOVT+CMP. 1592 __ CmpConstant(R8, -1); // 32-bit CMP 1593 __ CmpConstant(R9, -7); // CMN. 1594 __ CmpConstant(R8, -8); // CMN. 1595 __ CmpConstant(R9, -255); // CMN. 1596 __ CmpConstant(R8, -256); // CMN. 1597 __ CmpConstant(R9, -257); // MNV+CMP. 1598 __ CmpConstant(R8, -0xfff); // MOVW+CMN. 1599 __ CmpConstant(R9, -0x1000); // CMN. 1600 __ CmpConstant(R8, -0x1001); // MVN+CMP. 1601 __ CmpConstant(R9, -0x1002); // MOVW+CMN. 1602 __ CmpConstant(R8, -0xffff); // MOVW+CMN. 1603 __ CmpConstant(R9, -0x10000); // CMN. 1604 __ CmpConstant(R8, -0x10001); // CMN. 1605 __ CmpConstant(R9, -0x10002); // MVN+CMP. 1606 __ CmpConstant(R8, -0x10003); // MOVW+MOVT+CMP. 1607 1608 EmitAndCheck(&assembler, "CmpConstant"); 1609} 1610 1611#undef __ 1612} // namespace arm 1613} // namespace art 1614