1 // Copyright 2017, VIXL authors 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are met: 6 // 7 // * Redistributions of source code must retain the above copyright notice, 8 // this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above copyright 10 // notice, this list of conditions and the following disclaimer in the 11 // documentation and/or other materials provided with the distribution. 12 // * Neither the name of ARM Limited nor the names of its contributors may 13 // be used to endorse or promote products derived from this software 14 // without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 // POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef VIXL_AARCH32_MACRO_ASSEMBLER_AARCH32_H_ 29 #define VIXL_AARCH32_MACRO_ASSEMBLER_AARCH32_H_ 30 31 #include "code-generation-scopes-vixl.h" 32 #include "macro-assembler-interface.h" 33 #include "pool-manager-impl.h" 34 #include "pool-manager.h" 35 #include "utils-vixl.h" 36 37 #include "aarch32/assembler-aarch32.h" 38 #include "aarch32/instructions-aarch32.h" 39 #include "aarch32/operands-aarch32.h" 40 41 namespace vixl { 42 43 namespace aarch32 { 44 45 class UseScratchRegisterScope; 46 47 enum FlagsUpdate { LeaveFlags = 0, SetFlags = 1, DontCare = 2 }; 48 49 // We use a subclass to access the protected `ExactAssemblyScope` constructor 50 // giving us control over the pools, and make the constructor private to limit 51 // usage to code paths emitting pools. 52 class ExactAssemblyScopeWithoutPoolsCheck : public ExactAssemblyScope { 53 private: 54 ExactAssemblyScopeWithoutPoolsCheck(MacroAssembler* masm, 55 size_t size, 56 SizePolicy size_policy = kExactSize); 57 58 friend class MacroAssembler; 59 friend class Label; 60 }; 61 // Macro assembler for aarch32 instruction set. 62 class MacroAssembler : public Assembler, public MacroAssemblerInterface { 63 public: 64 enum FinalizeOption { 65 kFallThrough, // There may be more code to execute after calling Finalize. 66 kUnreachable // Anything generated after calling Finalize is unreachable. 67 }; 68 AsAssemblerBase()69 virtual internal::AssemblerBase* AsAssemblerBase() VIXL_OVERRIDE { 70 return this; 71 } 72 ArePoolsBlocked()73 virtual bool ArePoolsBlocked() const VIXL_OVERRIDE { 74 return pool_manager_.IsBlocked(); 75 } 76 EmitPoolHeader()77 virtual void EmitPoolHeader() VIXL_OVERRIDE { 78 // Check that we have the correct alignment. 79 if (IsUsingT32()) { 80 VIXL_ASSERT(GetBuffer()->Is16bitAligned()); 81 } else { 82 VIXL_ASSERT(GetBuffer()->Is32bitAligned()); 83 } 84 VIXL_ASSERT(pool_end_ == NULL); 85 pool_end_ = new Label(); 86 ExactAssemblyScopeWithoutPoolsCheck guard(this, 87 kMaxInstructionSizeInBytes, 88 ExactAssemblyScope::kMaximumSize); 89 b(pool_end_); 90 } EmitPoolFooter()91 virtual void EmitPoolFooter() VIXL_OVERRIDE { 92 // Align buffer to 4 bytes. 93 GetBuffer()->Align(); 94 if (pool_end_ != NULL) { 95 Bind(pool_end_); 96 delete pool_end_; 97 pool_end_ = NULL; 98 } 99 } EmitPaddingBytes(int n)100 virtual void EmitPaddingBytes(int n) VIXL_OVERRIDE { 101 GetBuffer()->EmitZeroedBytes(n); 102 } EmitNopBytes(int n)103 virtual void EmitNopBytes(int n) VIXL_OVERRIDE { 104 int nops = 0; 105 int nop_size = IsUsingT32() ? k16BitT32InstructionSizeInBytes 106 : kA32InstructionSizeInBytes; 107 VIXL_ASSERT(n % nop_size == 0); 108 nops = n / nop_size; 109 ExactAssemblyScopeWithoutPoolsCheck guard(this, 110 n, 111 ExactAssemblyScope::kExactSize); 112 for (int i = 0; i < nops; ++i) { 113 nop(); 114 } 115 } 116 117 118 private: 119 class MacroEmissionCheckScope : public EmissionCheckScope { 120 public: 121 explicit MacroEmissionCheckScope(MacroAssemblerInterface* masm, 122 PoolPolicy pool_policy = kBlockPools) EmissionCheckScope(masm,kTypicalMacroInstructionMaxSize,kMaximumSize,pool_policy)123 : EmissionCheckScope(masm, 124 kTypicalMacroInstructionMaxSize, 125 kMaximumSize, 126 pool_policy) {} 127 128 private: 129 static const size_t kTypicalMacroInstructionMaxSize = 130 8 * kMaxInstructionSizeInBytes; 131 }; 132 133 class MacroAssemblerContext { 134 public: MacroAssemblerContext()135 MacroAssemblerContext() : count_(0) {} ~MacroAssemblerContext()136 ~MacroAssemblerContext() {} GetRecursiveCount()137 unsigned GetRecursiveCount() const { return count_; } Up(const char * loc)138 void Up(const char* loc) { 139 location_stack_[count_] = loc; 140 count_++; 141 if (count_ >= kMaxRecursion) { 142 printf( 143 "Recursion limit reached; unable to resolve macro assembler " 144 "call.\n"); 145 printf("Macro assembler context stack:\n"); 146 for (unsigned i = 0; i < kMaxRecursion; i++) { 147 printf("%10s %s\n", (i == 0) ? "oldest -> " : "", location_stack_[i]); 148 } 149 VIXL_ABORT(); 150 } 151 } Down()152 void Down() { 153 VIXL_ASSERT((count_ > 0) && (count_ < kMaxRecursion)); 154 count_--; 155 } 156 157 private: 158 unsigned count_; 159 static const uint32_t kMaxRecursion = 6; 160 const char* location_stack_[kMaxRecursion]; 161 }; 162 163 // This scope is used at each Delegate entry to avoid infinite recursion of 164 // Delegate calls. The limit is defined by 165 // MacroAssemblerContext::kMaxRecursion. 166 class ContextScope { 167 public: ContextScope(MacroAssembler * const masm,const char * loc)168 explicit ContextScope(MacroAssembler* const masm, const char* loc) 169 : masm_(masm) { 170 VIXL_ASSERT(masm_->AllowMacroInstructions()); 171 masm_->GetContext()->Up(loc); 172 } ~ContextScope()173 ~ContextScope() { masm_->GetContext()->Down(); } 174 175 private: 176 MacroAssembler* const masm_; 177 }; 178 GetContext()179 MacroAssemblerContext* GetContext() { return &context_; } 180 181 class ITScope { 182 public: 183 ITScope(MacroAssembler* masm, 184 Condition* cond, 185 const MacroEmissionCheckScope& scope, 186 bool can_use_it = false) masm_(masm)187 : masm_(masm), cond_(*cond), can_use_it_(can_use_it) { 188 // The 'scope' argument is used to remind us to only use this scope inside 189 // a MacroEmissionCheckScope. This way, we do not need to check whether 190 // we need to emit the pools or grow the code buffer when emitting the 191 // IT or B instructions. 192 USE(scope); 193 if (!cond_.Is(al) && masm->IsUsingT32()) { 194 if (can_use_it_) { 195 // IT is not deprecated (that implies a 16 bit T32 instruction). 196 // We generate an IT instruction and a conditional instruction. 197 masm->it(cond_); 198 } else { 199 // The usage of IT is deprecated for the instruction. 200 // We generate a conditional branch and an unconditional instruction. 201 // Generate the branch. 202 masm_->b(cond_.Negate(), Narrow, &label_); 203 // Tell the macro-assembler to generate unconditional instructions. 204 *cond = al; 205 } 206 } 207 #ifdef VIXL_DEBUG 208 initial_cursor_offset_ = masm->GetCursorOffset(); 209 #else 210 USE(initial_cursor_offset_); 211 #endif 212 } ~ITScope()213 ~ITScope() { 214 if (label_.IsReferenced()) { 215 // We only use the label for conditional T32 instructions for which we 216 // cannot use IT. 217 VIXL_ASSERT(!cond_.Is(al)); 218 VIXL_ASSERT(masm_->IsUsingT32()); 219 VIXL_ASSERT(!can_use_it_); 220 VIXL_ASSERT(masm_->GetCursorOffset() - initial_cursor_offset_ <= 221 kMaxT32MacroInstructionSizeInBytes); 222 masm_->BindHelper(&label_); 223 } else if (masm_->IsUsingT32() && !cond_.Is(al)) { 224 // If we've generated a conditional T32 instruction but haven't used the 225 // label, we must have used IT. Check that we did not generate a 226 // deprecated sequence. 227 VIXL_ASSERT(can_use_it_); 228 VIXL_ASSERT(masm_->GetCursorOffset() - initial_cursor_offset_ <= 229 k16BitT32InstructionSizeInBytes); 230 } 231 } 232 233 private: 234 MacroAssembler* masm_; 235 Condition cond_; 236 Label label_; 237 bool can_use_it_; 238 uint32_t initial_cursor_offset_; 239 }; 240 241 protected: BlockPools()242 virtual void BlockPools() VIXL_OVERRIDE { pool_manager_.Block(); } ReleasePools()243 virtual void ReleasePools() VIXL_OVERRIDE { 244 pool_manager_.Release(GetCursorOffset()); 245 } 246 virtual void EnsureEmitPoolsFor(size_t size) VIXL_OVERRIDE; 247 248 // Tell whether any of the macro instruction can be used. When false the 249 // MacroAssembler will assert if a method which can emit a variable number 250 // of instructions is called. SetAllowMacroInstructions(bool value)251 virtual void SetAllowMacroInstructions(bool value) VIXL_OVERRIDE { 252 allow_macro_instructions_ = value; 253 } 254 255 void HandleOutOfBoundsImmediate(Condition cond, Register tmp, uint32_t imm); 256 257 public: 258 // TODO: If we change the MacroAssembler to disallow setting a different ISA, 259 // we can change the alignment of the pool in the pool manager constructor to 260 // be 2 bytes for T32. 261 explicit MacroAssembler(InstructionSet isa = kDefaultISA) Assembler(isa)262 : Assembler(isa), 263 available_(r12), 264 current_scratch_scope_(NULL), 265 pool_manager_(4 /*header_size*/, 266 4 /*alignment*/, 267 4 /*buffer_alignment*/), 268 generate_simulator_code_(VIXL_AARCH32_GENERATE_SIMULATOR_CODE), 269 pool_end_(NULL) { 270 #ifdef VIXL_DEBUG 271 SetAllowMacroInstructions( // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall) 272 true); 273 #else 274 USE(allow_macro_instructions_); 275 #endif 276 } 277 explicit MacroAssembler(size_t size, InstructionSet isa = kDefaultISA) Assembler(size,isa)278 : Assembler(size, isa), 279 available_(r12), 280 current_scratch_scope_(NULL), 281 pool_manager_(4 /*header_size*/, 282 4 /*alignment*/, 283 4 /*buffer_alignment*/), 284 generate_simulator_code_(VIXL_AARCH32_GENERATE_SIMULATOR_CODE), 285 pool_end_(NULL) { 286 #ifdef VIXL_DEBUG 287 SetAllowMacroInstructions( // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall) 288 true); 289 #endif 290 } 291 MacroAssembler(byte* buffer, size_t size, InstructionSet isa = kDefaultISA) Assembler(buffer,size,isa)292 : Assembler(buffer, size, isa), 293 available_(r12), 294 current_scratch_scope_(NULL), 295 pool_manager_(4 /*header_size*/, 296 4 /*alignment*/, 297 4 /*buffer_alignment*/), 298 generate_simulator_code_(VIXL_AARCH32_GENERATE_SIMULATOR_CODE), 299 pool_end_(NULL) { 300 #ifdef VIXL_DEBUG 301 SetAllowMacroInstructions( // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall) 302 true); 303 #endif 304 } 305 GenerateSimulatorCode()306 bool GenerateSimulatorCode() const { return generate_simulator_code_; } 307 AllowMacroInstructions()308 virtual bool AllowMacroInstructions() const VIXL_OVERRIDE { 309 return allow_macro_instructions_; 310 } 311 312 void FinalizeCode(FinalizeOption option = kUnreachable) { 313 EmitLiteralPool(option == kUnreachable 314 ? PoolManager<int32_t>::kNoBranchRequired 315 : PoolManager<int32_t>::kBranchRequired); 316 Assembler::FinalizeCode(); 317 } 318 GetScratchRegisterList()319 RegisterList* GetScratchRegisterList() { return &available_; } GetScratchVRegisterList()320 VRegisterList* GetScratchVRegisterList() { return &available_vfp_; } 321 322 // Get or set the current (most-deeply-nested) UseScratchRegisterScope. SetCurrentScratchRegisterScope(UseScratchRegisterScope * scope)323 void SetCurrentScratchRegisterScope(UseScratchRegisterScope* scope) { 324 current_scratch_scope_ = scope; 325 } GetCurrentScratchRegisterScope()326 UseScratchRegisterScope* GetCurrentScratchRegisterScope() { 327 return current_scratch_scope_; 328 } 329 330 // Given an address calculation (Register + immediate), generate code to 331 // partially compute the address. The returned MemOperand will perform any 332 // remaining computation in a subsequent load or store instruction. 333 // 334 // The offset provided should be the offset that would be used in a load or 335 // store instruction (if it had sufficient range). This only matters where 336 // base.Is(pc), since load and store instructions align the pc before 337 // dereferencing it. 338 // 339 // TODO: Improve the handling of negative offsets. They are not implemented 340 // precisely for now because they only have a marginal benefit for the 341 // existing uses (in delegates). 342 MemOperand MemOperandComputationHelper(Condition cond, 343 Register scratch, 344 Register base, 345 uint32_t offset, 346 uint32_t extra_offset_mask = 0); 347 348 MemOperand MemOperandComputationHelper(Register scratch, 349 Register base, 350 uint32_t offset, 351 uint32_t extra_offset_mask = 0) { 352 return MemOperandComputationHelper(al, 353 scratch, 354 base, 355 offset, 356 extra_offset_mask); 357 } 358 MemOperand MemOperandComputationHelper(Condition cond, 359 Register scratch, 360 Location* location, 361 uint32_t extra_offset_mask = 0) { 362 // Check for buffer space _before_ calculating the offset, in case we 363 // generate a pool that affects the offset calculation. 364 CodeBufferCheckScope scope(this, 4 * kMaxInstructionSizeInBytes); 365 Label::Offset offset = 366 location->GetLocation() - 367 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4); 368 return MemOperandComputationHelper(cond, 369 scratch, 370 pc, 371 offset, 372 extra_offset_mask); 373 } 374 MemOperand MemOperandComputationHelper(Register scratch, 375 Location* location, 376 uint32_t extra_offset_mask = 0) { 377 return MemOperandComputationHelper(al, 378 scratch, 379 location, 380 extra_offset_mask); 381 } 382 383 // Determine the appropriate mask to pass into MemOperandComputationHelper. 384 uint32_t GetOffsetMask(InstructionType type, AddrMode addrmode); 385 386 // State and type helpers. IsModifiedImmediate(uint32_t imm)387 bool IsModifiedImmediate(uint32_t imm) { 388 return IsUsingT32() ? ImmediateT32::IsImmediateT32(imm) 389 : ImmediateA32::IsImmediateA32(imm); 390 } 391 Bind(Label * label)392 void Bind(Label* label) { 393 VIXL_ASSERT(allow_macro_instructions_); 394 BindHelper(label); 395 } 396 BindHelper(Label * label)397 virtual void BindHelper(Label* label) VIXL_OVERRIDE { 398 // Assert that we have the correct buffer alignment. 399 if (IsUsingT32()) { 400 VIXL_ASSERT(GetBuffer()->Is16bitAligned()); 401 } else { 402 VIXL_ASSERT(GetBuffer()->Is32bitAligned()); 403 } 404 // If we need to add padding, check if we have to emit the pool. 405 const int32_t cursor = GetCursorOffset(); 406 if (label->Needs16BitPadding(cursor)) { 407 const int kPaddingBytes = 2; 408 if (pool_manager_.MustEmit(cursor, kPaddingBytes)) { 409 int32_t new_cursor = pool_manager_.Emit(this, cursor, kPaddingBytes); 410 USE(new_cursor); 411 VIXL_ASSERT(new_cursor == GetCursorOffset()); 412 } 413 } 414 pool_manager_.Bind(this, label, GetCursorOffset()); 415 } 416 RegisterLiteralReference(RawLiteral * literal)417 void RegisterLiteralReference(RawLiteral* literal) { 418 if (literal->IsManuallyPlaced()) return; 419 RegisterForwardReference(literal); 420 } 421 RegisterForwardReference(Location * location)422 void RegisterForwardReference(Location* location) { 423 if (location->IsBound()) return; 424 VIXL_ASSERT(location->HasForwardReferences()); 425 const Location::ForwardRef& reference = location->GetLastForwardReference(); 426 pool_manager_.AddObjectReference(&reference, location); 427 } 428 429 void CheckEmitPoolForInstruction(const ReferenceInfo* info, 430 Location* location, 431 Condition* cond = NULL) { 432 int size = info->size; 433 int32_t cursor = GetCursorOffset(); 434 // If we need to emit a branch over the instruction, take this into account. 435 if ((cond != NULL) && NeedBranch(cond)) { 436 size += kBranchSize; 437 cursor += kBranchSize; 438 } 439 int32_t from = cursor; 440 from += IsUsingT32() ? kT32PcDelta : kA32PcDelta; 441 if (info->pc_needs_aligning) from = AlignDown(from, 4); 442 int32_t min = from + info->min_offset; 443 int32_t max = from + info->max_offset; 444 ForwardReference<int32_t> temp_ref(cursor, 445 info->size, 446 min, 447 max, 448 info->alignment); 449 if (pool_manager_.MustEmit(GetCursorOffset(), size, &temp_ref, location)) { 450 int32_t new_cursor = pool_manager_.Emit(this, 451 GetCursorOffset(), 452 info->size, 453 &temp_ref, 454 location); 455 USE(new_cursor); 456 VIXL_ASSERT(new_cursor == GetCursorOffset()); 457 } 458 } 459 Place(RawLiteral * literal)460 void Place(RawLiteral* literal) { 461 VIXL_ASSERT(allow_macro_instructions_); 462 VIXL_ASSERT(literal->IsManuallyPlaced()); 463 // Check if we need to emit the pools. Take the alignment of the literal 464 // into account, as well as potential 16-bit padding needed to reach the 465 // minimum accessible location. 466 int alignment = literal->GetMaxAlignment(); 467 int32_t cursor = GetCursorOffset(); 468 int total_size = AlignUp(cursor, alignment) - cursor + literal->GetSize(); 469 if (literal->Needs16BitPadding(cursor)) total_size += 2; 470 if (pool_manager_.MustEmit(cursor, total_size)) { 471 int32_t new_cursor = pool_manager_.Emit(this, cursor, total_size); 472 USE(new_cursor); 473 VIXL_ASSERT(new_cursor == GetCursorOffset()); 474 } 475 pool_manager_.Bind(this, literal, GetCursorOffset()); 476 literal->EmitPoolObject(this); 477 // Align the buffer, to be ready to generate instructions right after 478 // this. 479 GetBuffer()->Align(); 480 } 481 482 void EmitLiteralPool(PoolManager<int32_t>::EmitOption option = 483 PoolManager<int32_t>::kBranchRequired) { 484 VIXL_ASSERT(!ArePoolsBlocked()); 485 int32_t new_pc = 486 pool_manager_.Emit(this, GetCursorOffset(), 0, NULL, NULL, option); 487 VIXL_ASSERT(new_pc == GetCursorOffset()); 488 USE(new_pc); 489 } 490 EnsureEmitFor(uint32_t size)491 void EnsureEmitFor(uint32_t size) { 492 EnsureEmitPoolsFor(size); 493 VIXL_ASSERT(GetBuffer()->HasSpaceFor(size) || GetBuffer()->IsManaged()); 494 GetBuffer()->EnsureSpaceFor(size); 495 } 496 AliasesAvailableScratchRegister(Register reg)497 bool AliasesAvailableScratchRegister(Register reg) { 498 return GetScratchRegisterList()->Includes(reg); 499 } 500 AliasesAvailableScratchRegister(RegisterOrAPSR_nzcv reg)501 bool AliasesAvailableScratchRegister(RegisterOrAPSR_nzcv reg) { 502 if (reg.IsAPSR_nzcv()) return false; 503 return GetScratchRegisterList()->Includes(reg.AsRegister()); 504 } 505 AliasesAvailableScratchRegister(VRegister reg)506 bool AliasesAvailableScratchRegister(VRegister reg) { 507 return GetScratchVRegisterList()->IncludesAliasOf(reg); 508 } 509 AliasesAvailableScratchRegister(const Operand & operand)510 bool AliasesAvailableScratchRegister(const Operand& operand) { 511 if (operand.IsImmediate()) return false; 512 return AliasesAvailableScratchRegister(operand.GetBaseRegister()) || 513 (operand.IsRegisterShiftedRegister() && 514 AliasesAvailableScratchRegister(operand.GetShiftRegister())); 515 } 516 AliasesAvailableScratchRegister(const NeonOperand & operand)517 bool AliasesAvailableScratchRegister(const NeonOperand& operand) { 518 if (operand.IsImmediate()) return false; 519 return AliasesAvailableScratchRegister(operand.GetRegister()); 520 } 521 AliasesAvailableScratchRegister(SRegisterList list)522 bool AliasesAvailableScratchRegister(SRegisterList list) { 523 for (int n = 0; n < list.GetLength(); n++) { 524 if (AliasesAvailableScratchRegister(list.GetSRegister(n))) return true; 525 } 526 return false; 527 } 528 AliasesAvailableScratchRegister(DRegisterList list)529 bool AliasesAvailableScratchRegister(DRegisterList list) { 530 for (int n = 0; n < list.GetLength(); n++) { 531 if (AliasesAvailableScratchRegister(list.GetDRegister(n))) return true; 532 } 533 return false; 534 } 535 AliasesAvailableScratchRegister(NeonRegisterList list)536 bool AliasesAvailableScratchRegister(NeonRegisterList list) { 537 for (int n = 0; n < list.GetLength(); n++) { 538 if (AliasesAvailableScratchRegister(list.GetDRegister(n))) return true; 539 } 540 return false; 541 } 542 AliasesAvailableScratchRegister(RegisterList list)543 bool AliasesAvailableScratchRegister(RegisterList list) { 544 return GetScratchRegisterList()->Overlaps(list); 545 } 546 AliasesAvailableScratchRegister(const MemOperand & operand)547 bool AliasesAvailableScratchRegister(const MemOperand& operand) { 548 return AliasesAvailableScratchRegister(operand.GetBaseRegister()) || 549 (operand.IsShiftedRegister() && 550 AliasesAvailableScratchRegister(operand.GetOffsetRegister())); 551 } 552 553 // Adr with a literal already constructed. Add the literal to the pool if it 554 // is not already done. Adr(Condition cond,Register rd,RawLiteral * literal)555 void Adr(Condition cond, Register rd, RawLiteral* literal) { 556 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 557 VIXL_ASSERT(allow_macro_instructions_); 558 VIXL_ASSERT(OutsideITBlock()); 559 MacroEmissionCheckScope::PoolPolicy pool_policy = 560 MacroEmissionCheckScope::kBlockPools; 561 if (!literal->IsBound()) { 562 const ReferenceInfo* info; 563 bool can_encode = adr_info(cond, Best, rd, literal, &info); 564 VIXL_CHECK(can_encode); 565 CheckEmitPoolForInstruction(info, literal, &cond); 566 // We have already checked for pool emission. 567 pool_policy = MacroEmissionCheckScope::kIgnorePools; 568 } 569 MacroEmissionCheckScope guard(this, pool_policy); 570 ITScope it_scope(this, &cond, guard); 571 adr(cond, Best, rd, literal); 572 RegisterLiteralReference(literal); 573 } Adr(Register rd,RawLiteral * literal)574 void Adr(Register rd, RawLiteral* literal) { Adr(al, rd, literal); } 575 576 // Loads with literals already constructed. Add the literal to the pool 577 // if it is not already done. Ldr(Condition cond,Register rt,RawLiteral * literal)578 void Ldr(Condition cond, Register rt, RawLiteral* literal) { 579 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 580 VIXL_ASSERT(allow_macro_instructions_); 581 VIXL_ASSERT(OutsideITBlock()); 582 MacroEmissionCheckScope::PoolPolicy pool_policy = 583 MacroEmissionCheckScope::kBlockPools; 584 if (!literal->IsBound()) { 585 const ReferenceInfo* info; 586 bool can_encode = ldr_info(cond, Best, rt, literal, &info); 587 VIXL_CHECK(can_encode); 588 CheckEmitPoolForInstruction(info, literal, &cond); 589 // We have already checked for pool emission. 590 pool_policy = MacroEmissionCheckScope::kIgnorePools; 591 } 592 MacroEmissionCheckScope guard(this, pool_policy); 593 ITScope it_scope(this, &cond, guard); 594 ldr(cond, rt, literal); 595 RegisterLiteralReference(literal); 596 } Ldr(Register rt,RawLiteral * literal)597 void Ldr(Register rt, RawLiteral* literal) { Ldr(al, rt, literal); } 598 Ldrb(Condition cond,Register rt,RawLiteral * literal)599 void Ldrb(Condition cond, Register rt, RawLiteral* literal) { 600 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 601 VIXL_ASSERT(allow_macro_instructions_); 602 VIXL_ASSERT(OutsideITBlock()); 603 MacroEmissionCheckScope::PoolPolicy pool_policy = 604 MacroEmissionCheckScope::kBlockPools; 605 if (!literal->IsBound()) { 606 const ReferenceInfo* info; 607 bool can_encode = ldrb_info(cond, rt, literal, &info); 608 VIXL_CHECK(can_encode); 609 CheckEmitPoolForInstruction(info, literal, &cond); 610 // We have already checked for pool emission. 611 pool_policy = MacroEmissionCheckScope::kIgnorePools; 612 } 613 MacroEmissionCheckScope guard(this, pool_policy); 614 ITScope it_scope(this, &cond, guard); 615 ldrb(cond, rt, literal); 616 RegisterLiteralReference(literal); 617 } Ldrb(Register rt,RawLiteral * literal)618 void Ldrb(Register rt, RawLiteral* literal) { Ldrb(al, rt, literal); } 619 Ldrd(Condition cond,Register rt,Register rt2,RawLiteral * literal)620 void Ldrd(Condition cond, Register rt, Register rt2, RawLiteral* literal) { 621 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 622 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt2)); 623 VIXL_ASSERT(allow_macro_instructions_); 624 VIXL_ASSERT(OutsideITBlock()); 625 MacroEmissionCheckScope::PoolPolicy pool_policy = 626 MacroEmissionCheckScope::kBlockPools; 627 if (!literal->IsBound()) { 628 const ReferenceInfo* info; 629 bool can_encode = ldrd_info(cond, rt, rt2, literal, &info); 630 VIXL_CHECK(can_encode); 631 CheckEmitPoolForInstruction(info, literal, &cond); 632 // We have already checked for pool emission. 633 pool_policy = MacroEmissionCheckScope::kIgnorePools; 634 } 635 MacroEmissionCheckScope guard(this, pool_policy); 636 ITScope it_scope(this, &cond, guard); 637 ldrd(cond, rt, rt2, literal); 638 RegisterLiteralReference(literal); 639 } Ldrd(Register rt,Register rt2,RawLiteral * literal)640 void Ldrd(Register rt, Register rt2, RawLiteral* literal) { 641 Ldrd(al, rt, rt2, literal); 642 } 643 Ldrh(Condition cond,Register rt,RawLiteral * literal)644 void Ldrh(Condition cond, Register rt, RawLiteral* literal) { 645 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 646 VIXL_ASSERT(allow_macro_instructions_); 647 VIXL_ASSERT(OutsideITBlock()); 648 MacroEmissionCheckScope::PoolPolicy pool_policy = 649 MacroEmissionCheckScope::kBlockPools; 650 if (!literal->IsBound()) { 651 const ReferenceInfo* info; 652 bool can_encode = ldrh_info(cond, rt, literal, &info); 653 VIXL_CHECK(can_encode); 654 CheckEmitPoolForInstruction(info, literal, &cond); 655 // We have already checked for pool emission. 656 pool_policy = MacroEmissionCheckScope::kIgnorePools; 657 } 658 MacroEmissionCheckScope guard(this, pool_policy); 659 ITScope it_scope(this, &cond, guard); 660 ldrh(cond, rt, literal); 661 RegisterLiteralReference(literal); 662 } Ldrh(Register rt,RawLiteral * literal)663 void Ldrh(Register rt, RawLiteral* literal) { Ldrh(al, rt, literal); } 664 Ldrsb(Condition cond,Register rt,RawLiteral * literal)665 void Ldrsb(Condition cond, Register rt, RawLiteral* literal) { 666 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 667 VIXL_ASSERT(allow_macro_instructions_); 668 VIXL_ASSERT(OutsideITBlock()); 669 MacroEmissionCheckScope::PoolPolicy pool_policy = 670 MacroEmissionCheckScope::kBlockPools; 671 if (!literal->IsBound()) { 672 const ReferenceInfo* info; 673 bool can_encode = ldrsb_info(cond, rt, literal, &info); 674 VIXL_CHECK(can_encode); 675 CheckEmitPoolForInstruction(info, literal, &cond); 676 // We have already checked for pool emission. 677 pool_policy = MacroEmissionCheckScope::kIgnorePools; 678 } 679 MacroEmissionCheckScope guard(this, pool_policy); 680 ITScope it_scope(this, &cond, guard); 681 ldrsb(cond, rt, literal); 682 RegisterLiteralReference(literal); 683 } Ldrsb(Register rt,RawLiteral * literal)684 void Ldrsb(Register rt, RawLiteral* literal) { Ldrsb(al, rt, literal); } 685 Ldrsh(Condition cond,Register rt,RawLiteral * literal)686 void Ldrsh(Condition cond, Register rt, RawLiteral* literal) { 687 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 688 VIXL_ASSERT(allow_macro_instructions_); 689 VIXL_ASSERT(OutsideITBlock()); 690 MacroEmissionCheckScope::PoolPolicy pool_policy = 691 MacroEmissionCheckScope::kBlockPools; 692 if (!literal->IsBound()) { 693 const ReferenceInfo* info; 694 bool can_encode = ldrsh_info(cond, rt, literal, &info); 695 VIXL_CHECK(can_encode); 696 CheckEmitPoolForInstruction(info, literal, &cond); 697 // We have already checked for pool emission. 698 pool_policy = MacroEmissionCheckScope::kIgnorePools; 699 } 700 MacroEmissionCheckScope guard(this, pool_policy); 701 ITScope it_scope(this, &cond, guard); 702 ldrsh(cond, rt, literal); 703 RegisterLiteralReference(literal); 704 } Ldrsh(Register rt,RawLiteral * literal)705 void Ldrsh(Register rt, RawLiteral* literal) { Ldrsh(al, rt, literal); } 706 Vldr(Condition cond,DataType dt,DRegister rd,RawLiteral * literal)707 void Vldr(Condition cond, DataType dt, DRegister rd, RawLiteral* literal) { 708 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 709 VIXL_ASSERT(allow_macro_instructions_); 710 VIXL_ASSERT(OutsideITBlock()); 711 MacroEmissionCheckScope::PoolPolicy pool_policy = 712 MacroEmissionCheckScope::kBlockPools; 713 if (!literal->IsBound()) { 714 const ReferenceInfo* info; 715 bool can_encode = vldr_info(cond, dt, rd, literal, &info); 716 VIXL_CHECK(can_encode); 717 CheckEmitPoolForInstruction(info, literal, &cond); 718 // We have already checked for pool emission. 719 pool_policy = MacroEmissionCheckScope::kIgnorePools; 720 } 721 MacroEmissionCheckScope guard(this, pool_policy); 722 ITScope it_scope(this, &cond, guard); 723 vldr(cond, dt, rd, literal); 724 RegisterLiteralReference(literal); 725 } Vldr(DataType dt,DRegister rd,RawLiteral * literal)726 void Vldr(DataType dt, DRegister rd, RawLiteral* literal) { 727 Vldr(al, dt, rd, literal); 728 } Vldr(Condition cond,DRegister rd,RawLiteral * literal)729 void Vldr(Condition cond, DRegister rd, RawLiteral* literal) { 730 Vldr(cond, Untyped64, rd, literal); 731 } Vldr(DRegister rd,RawLiteral * literal)732 void Vldr(DRegister rd, RawLiteral* literal) { 733 Vldr(al, Untyped64, rd, literal); 734 } 735 Vldr(Condition cond,DataType dt,SRegister rd,RawLiteral * literal)736 void Vldr(Condition cond, DataType dt, SRegister rd, RawLiteral* literal) { 737 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 738 VIXL_ASSERT(allow_macro_instructions_); 739 VIXL_ASSERT(OutsideITBlock()); 740 MacroEmissionCheckScope::PoolPolicy pool_policy = 741 MacroEmissionCheckScope::kBlockPools; 742 if (!literal->IsBound()) { 743 const ReferenceInfo* info; 744 bool can_encode = vldr_info(cond, dt, rd, literal, &info); 745 VIXL_CHECK(can_encode); 746 CheckEmitPoolForInstruction(info, literal, &cond); 747 // We have already checked for pool emission. 748 pool_policy = MacroEmissionCheckScope::kIgnorePools; 749 } 750 MacroEmissionCheckScope guard(this, pool_policy); 751 ITScope it_scope(this, &cond, guard); 752 vldr(cond, dt, rd, literal); 753 RegisterLiteralReference(literal); 754 } Vldr(DataType dt,SRegister rd,RawLiteral * literal)755 void Vldr(DataType dt, SRegister rd, RawLiteral* literal) { 756 Vldr(al, dt, rd, literal); 757 } Vldr(Condition cond,SRegister rd,RawLiteral * literal)758 void Vldr(Condition cond, SRegister rd, RawLiteral* literal) { 759 Vldr(cond, Untyped32, rd, literal); 760 } Vldr(SRegister rd,RawLiteral * literal)761 void Vldr(SRegister rd, RawLiteral* literal) { 762 Vldr(al, Untyped32, rd, literal); 763 } 764 765 // Generic Ldr(register, data) Ldr(Condition cond,Register rt,uint32_t v)766 void Ldr(Condition cond, Register rt, uint32_t v) { 767 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 768 VIXL_ASSERT(allow_macro_instructions_); 769 VIXL_ASSERT(OutsideITBlock()); 770 RawLiteral* literal = 771 new Literal<uint32_t>(v, RawLiteral::kDeletedOnPlacementByPool); 772 Ldr(cond, rt, literal); 773 } 774 template <typename T> Ldr(Register rt,T v)775 void Ldr(Register rt, T v) { 776 Ldr(al, rt, v); 777 } 778 779 // Generic Ldrd(rt, rt2, data) Ldrd(Condition cond,Register rt,Register rt2,uint64_t v)780 void Ldrd(Condition cond, Register rt, Register rt2, uint64_t v) { 781 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 782 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt2)); 783 VIXL_ASSERT(allow_macro_instructions_); 784 VIXL_ASSERT(OutsideITBlock()); 785 RawLiteral* literal = 786 new Literal<uint64_t>(v, RawLiteral::kDeletedOnPlacementByPool); 787 Ldrd(cond, rt, rt2, literal); 788 } 789 template <typename T> Ldrd(Register rt,Register rt2,T v)790 void Ldrd(Register rt, Register rt2, T v) { 791 Ldrd(al, rt, rt2, v); 792 } 793 Vldr(Condition cond,SRegister rd,float v)794 void Vldr(Condition cond, SRegister rd, float v) { 795 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 796 VIXL_ASSERT(allow_macro_instructions_); 797 VIXL_ASSERT(OutsideITBlock()); 798 RawLiteral* literal = 799 new Literal<float>(v, RawLiteral::kDeletedOnPlacementByPool); 800 Vldr(cond, rd, literal); 801 } Vldr(SRegister rd,float v)802 void Vldr(SRegister rd, float v) { Vldr(al, rd, v); } 803 Vldr(Condition cond,DRegister rd,double v)804 void Vldr(Condition cond, DRegister rd, double v) { 805 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 806 VIXL_ASSERT(allow_macro_instructions_); 807 VIXL_ASSERT(OutsideITBlock()); 808 RawLiteral* literal = 809 new Literal<double>(v, RawLiteral::kDeletedOnPlacementByPool); 810 Vldr(cond, rd, literal); 811 } Vldr(DRegister rd,double v)812 void Vldr(DRegister rd, double v) { Vldr(al, rd, v); } 813 Vmov(Condition cond,DRegister rt,double v)814 void Vmov(Condition cond, DRegister rt, double v) { Vmov(cond, F64, rt, v); } Vmov(DRegister rt,double v)815 void Vmov(DRegister rt, double v) { Vmov(al, F64, rt, v); } Vmov(Condition cond,SRegister rt,float v)816 void Vmov(Condition cond, SRegister rt, float v) { Vmov(cond, F32, rt, v); } Vmov(SRegister rt,float v)817 void Vmov(SRegister rt, float v) { Vmov(al, F32, rt, v); } 818 819 // Claim memory on the stack. 820 // Note that the Claim, Drop, and Peek helpers below ensure that offsets used 821 // are multiples of 32 bits to help maintain 32-bit SP alignment. 822 // We could `Align{Up,Down}(size, 4)`, but that's potentially problematic: 823 // Claim(3) 824 // Claim(1) 825 // Drop(4) 826 // would seem correct, when in fact: 827 // Claim(3) -> sp = sp - 4 828 // Claim(1) -> sp = sp - 4 829 // Drop(4) -> sp = sp + 4 830 // Claim(int32_t size)831 void Claim(int32_t size) { 832 if (size == 0) return; 833 // The stack must be kept 32bit aligned. 834 VIXL_ASSERT((size > 0) && ((size % 4) == 0)); 835 Sub(sp, sp, size); 836 } 837 // Release memory on the stack Drop(int32_t size)838 void Drop(int32_t size) { 839 if (size == 0) return; 840 // The stack must be kept 32bit aligned. 841 VIXL_ASSERT((size > 0) && ((size % 4) == 0)); 842 Add(sp, sp, size); 843 } Peek(Register dst,int32_t offset)844 void Peek(Register dst, int32_t offset) { 845 VIXL_ASSERT((offset >= 0) && ((offset % 4) == 0)); 846 Ldr(dst, MemOperand(sp, offset)); 847 } Poke(Register src,int32_t offset)848 void Poke(Register src, int32_t offset) { 849 VIXL_ASSERT((offset >= 0) && ((offset % 4) == 0)); 850 Str(src, MemOperand(sp, offset)); 851 } 852 void Printf(const char* format, 853 CPURegister reg1 = NoReg, 854 CPURegister reg2 = NoReg, 855 CPURegister reg3 = NoReg, 856 CPURegister reg4 = NoReg); 857 // Functions used by Printf for generation. 858 void PushRegister(CPURegister reg); 859 void PreparePrintfArgument(CPURegister reg, 860 int* core_count, 861 int* vfp_count, 862 uint32_t* printf_type); 863 // Handlers for cases not handled by the assembler. 864 // ADD, MOVT, MOVW, SUB, SXTB16, TEQ, UXTB16 865 virtual void Delegate(InstructionType type, 866 InstructionCondROp instruction, 867 Condition cond, 868 Register rn, 869 const Operand& operand) VIXL_OVERRIDE; 870 // CMN, CMP, MOV, MOVS, MVN, MVNS, SXTB, SXTH, TST, UXTB, UXTH 871 virtual void Delegate(InstructionType type, 872 InstructionCondSizeROp instruction, 873 Condition cond, 874 EncodingSize size, 875 Register rn, 876 const Operand& operand) VIXL_OVERRIDE; 877 // ADDW, ORN, ORNS, PKHBT, PKHTB, RSC, RSCS, SUBW, SXTAB, SXTAB16, SXTAH, 878 // UXTAB, UXTAB16, UXTAH 879 virtual void Delegate(InstructionType type, 880 InstructionCondRROp instruction, 881 Condition cond, 882 Register rd, 883 Register rn, 884 const Operand& operand) VIXL_OVERRIDE; 885 // ADC, ADCS, ADD, ADDS, AND, ANDS, ASR, ASRS, BIC, BICS, EOR, EORS, LSL, 886 // LSLS, LSR, LSRS, ORR, ORRS, ROR, RORS, RSB, RSBS, SBC, SBCS, SUB, SUBS 887 virtual void Delegate(InstructionType type, 888 InstructionCondSizeRL instruction, 889 Condition cond, 890 EncodingSize size, 891 Register rd, 892 Location* location) VIXL_OVERRIDE; 893 bool GenerateSplitInstruction(InstructionCondSizeRROp instruction, 894 Condition cond, 895 Register rd, 896 Register rn, 897 uint32_t imm, 898 uint32_t mask); 899 virtual void Delegate(InstructionType type, 900 InstructionCondSizeRROp instruction, 901 Condition cond, 902 EncodingSize size, 903 Register rd, 904 Register rn, 905 const Operand& operand) VIXL_OVERRIDE; 906 // CBNZ, CBZ 907 virtual void Delegate(InstructionType type, 908 InstructionRL instruction, 909 Register rn, 910 Location* location) VIXL_OVERRIDE; 911 // B 912 virtual void Delegate(InstructionType type, 913 InstructionCondSizeL instruction, 914 Condition cond, 915 EncodingSize size, 916 Location* location) VIXL_OVERRIDE; 917 // VMOV 918 virtual void Delegate(InstructionType type, 919 InstructionCondDtSSop instruction, 920 Condition cond, 921 DataType dt, 922 SRegister rd, 923 const SOperand& operand) VIXL_OVERRIDE; 924 // VMOV, VMVN 925 virtual void Delegate(InstructionType type, 926 InstructionCondDtDDop instruction, 927 Condition cond, 928 DataType dt, 929 DRegister rd, 930 const DOperand& operand) VIXL_OVERRIDE; 931 // VMOV, VMVN 932 virtual void Delegate(InstructionType type, 933 InstructionCondDtQQop instruction, 934 Condition cond, 935 DataType dt, 936 QRegister rd, 937 const QOperand& operand) VIXL_OVERRIDE; 938 // LDR, LDRB, LDRH, LDRSB, LDRSH, STR, STRB, STRH 939 virtual void Delegate(InstructionType type, 940 InstructionCondSizeRMop instruction, 941 Condition cond, 942 EncodingSize size, 943 Register rd, 944 const MemOperand& operand) VIXL_OVERRIDE; 945 // LDAEXD, LDRD, LDREXD, STLEX, STLEXB, STLEXH, STRD, STREX, STREXB, STREXH 946 virtual void Delegate(InstructionType type, 947 InstructionCondRL instruction, 948 Condition cond, 949 Register rt, 950 Location* location) VIXL_OVERRIDE; 951 virtual void Delegate(InstructionType type, 952 InstructionCondRRL instruction, 953 Condition cond, 954 Register rt, 955 Register rt2, 956 Location* location) VIXL_OVERRIDE; 957 virtual void Delegate(InstructionType type, 958 InstructionCondRRMop instruction, 959 Condition cond, 960 Register rt, 961 Register rt2, 962 const MemOperand& operand) VIXL_OVERRIDE; 963 // VLDR, VSTR 964 virtual void Delegate(InstructionType type, 965 InstructionCondDtSMop instruction, 966 Condition cond, 967 DataType dt, 968 SRegister rd, 969 const MemOperand& operand) VIXL_OVERRIDE; 970 // VLDR, VSTR 971 virtual void Delegate(InstructionType type, 972 InstructionCondDtDMop instruction, 973 Condition cond, 974 DataType dt, 975 DRegister rd, 976 const MemOperand& operand) VIXL_OVERRIDE; 977 // MSR 978 virtual void Delegate(InstructionType type, 979 InstructionCondMsrOp instruction, 980 Condition cond, 981 MaskedSpecialRegister spec_reg, 982 const Operand& operand) VIXL_OVERRIDE; 983 virtual void Delegate(InstructionType type, 984 InstructionCondDtDL instruction, 985 Condition cond, 986 DataType dt, 987 DRegister rd, 988 Location* location) VIXL_OVERRIDE; 989 virtual void Delegate(InstructionType type, 990 InstructionCondDtSL instruction, 991 Condition cond, 992 DataType dt, 993 SRegister rd, 994 Location* location) VIXL_OVERRIDE; 995 996 // Start of generated code. 997 Adc(Condition cond,Register rd,Register rn,const Operand & operand)998 void Adc(Condition cond, Register rd, Register rn, const Operand& operand) { 999 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1000 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1001 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1002 VIXL_ASSERT(allow_macro_instructions_); 1003 VIXL_ASSERT(OutsideITBlock()); 1004 MacroEmissionCheckScope guard(this); 1005 bool can_use_it = 1006 // ADC<c>{<q>} {<Rdn>,} <Rdn>, <Rm> ; T1 1007 operand.IsPlainRegister() && rn.IsLow() && rd.Is(rn) && 1008 operand.GetBaseRegister().IsLow(); 1009 ITScope it_scope(this, &cond, guard, can_use_it); 1010 adc(cond, rd, rn, operand); 1011 } Adc(Register rd,Register rn,const Operand & operand)1012 void Adc(Register rd, Register rn, const Operand& operand) { 1013 Adc(al, rd, rn, operand); 1014 } Adc(FlagsUpdate flags,Condition cond,Register rd,Register rn,const Operand & operand)1015 void Adc(FlagsUpdate flags, 1016 Condition cond, 1017 Register rd, 1018 Register rn, 1019 const Operand& operand) { 1020 switch (flags) { 1021 case LeaveFlags: 1022 Adc(cond, rd, rn, operand); 1023 break; 1024 case SetFlags: 1025 Adcs(cond, rd, rn, operand); 1026 break; 1027 case DontCare: 1028 bool setflags_is_smaller = IsUsingT32() && cond.Is(al) && rd.IsLow() && 1029 rn.Is(rd) && operand.IsPlainRegister() && 1030 operand.GetBaseRegister().IsLow(); 1031 if (setflags_is_smaller) { 1032 Adcs(cond, rd, rn, operand); 1033 } else { 1034 Adc(cond, rd, rn, operand); 1035 } 1036 break; 1037 } 1038 } Adc(FlagsUpdate flags,Register rd,Register rn,const Operand & operand)1039 void Adc(FlagsUpdate flags, 1040 Register rd, 1041 Register rn, 1042 const Operand& operand) { 1043 Adc(flags, al, rd, rn, operand); 1044 } 1045 Adcs(Condition cond,Register rd,Register rn,const Operand & operand)1046 void Adcs(Condition cond, Register rd, Register rn, const Operand& operand) { 1047 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1048 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1049 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1050 VIXL_ASSERT(allow_macro_instructions_); 1051 VIXL_ASSERT(OutsideITBlock()); 1052 MacroEmissionCheckScope guard(this); 1053 ITScope it_scope(this, &cond, guard); 1054 adcs(cond, rd, rn, operand); 1055 } Adcs(Register rd,Register rn,const Operand & operand)1056 void Adcs(Register rd, Register rn, const Operand& operand) { 1057 Adcs(al, rd, rn, operand); 1058 } 1059 Add(Condition cond,Register rd,Register rn,const Operand & operand)1060 void Add(Condition cond, Register rd, Register rn, const Operand& operand) { 1061 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1062 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1063 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1064 VIXL_ASSERT(allow_macro_instructions_); 1065 VIXL_ASSERT(OutsideITBlock()); 1066 MacroEmissionCheckScope guard(this); 1067 if (cond.Is(al) && rd.Is(rn) && operand.IsImmediate()) { 1068 uint32_t immediate = operand.GetImmediate(); 1069 if (immediate == 0) { 1070 return; 1071 } 1072 } 1073 bool can_use_it = 1074 // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1 1075 (operand.IsImmediate() && (operand.GetImmediate() <= 7) && rn.IsLow() && 1076 rd.IsLow()) || 1077 // ADD<c>{<q>} {<Rdn>,} <Rdn>, #<imm8> ; T2 1078 (operand.IsImmediate() && (operand.GetImmediate() <= 255) && 1079 rd.IsLow() && rn.Is(rd)) || 1080 // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1 1081 (operand.IsImmediate() && (operand.GetImmediate() <= 1020) && 1082 ((operand.GetImmediate() & 0x3) == 0) && rd.IsLow() && rn.IsSP()) || 1083 // ADD<c>{<q>} <Rd>, <Rn>, <Rm> 1084 (operand.IsPlainRegister() && rd.IsLow() && rn.IsLow() && 1085 operand.GetBaseRegister().IsLow()) || 1086 // ADD<c>{<q>} <Rdn>, <Rm> ; T2 1087 (operand.IsPlainRegister() && !rd.IsPC() && rn.Is(rd) && 1088 !operand.GetBaseRegister().IsSP() && 1089 !operand.GetBaseRegister().IsPC()) || 1090 // ADD{<c>}{<q>} {<Rdm>,} SP, <Rdm> ; T1 1091 (operand.IsPlainRegister() && !rd.IsPC() && rn.IsSP() && 1092 operand.GetBaseRegister().Is(rd)); 1093 ITScope it_scope(this, &cond, guard, can_use_it); 1094 add(cond, rd, rn, operand); 1095 } Add(Register rd,Register rn,const Operand & operand)1096 void Add(Register rd, Register rn, const Operand& operand) { 1097 Add(al, rd, rn, operand); 1098 } Add(FlagsUpdate flags,Condition cond,Register rd,Register rn,const Operand & operand)1099 void Add(FlagsUpdate flags, 1100 Condition cond, 1101 Register rd, 1102 Register rn, 1103 const Operand& operand) { 1104 switch (flags) { 1105 case LeaveFlags: 1106 Add(cond, rd, rn, operand); 1107 break; 1108 case SetFlags: 1109 Adds(cond, rd, rn, operand); 1110 break; 1111 case DontCare: 1112 bool setflags_is_smaller = 1113 IsUsingT32() && cond.Is(al) && 1114 ((operand.IsPlainRegister() && rd.IsLow() && rn.IsLow() && 1115 !rd.Is(rn) && operand.GetBaseRegister().IsLow()) || 1116 (operand.IsImmediate() && 1117 ((rd.IsLow() && rn.IsLow() && (operand.GetImmediate() < 8)) || 1118 (rd.IsLow() && rn.Is(rd) && (operand.GetImmediate() < 256))))); 1119 if (setflags_is_smaller) { 1120 Adds(cond, rd, rn, operand); 1121 } else { 1122 bool changed_op_is_smaller = 1123 operand.IsImmediate() && (operand.GetSignedImmediate() < 0) && 1124 ((rd.IsLow() && rn.IsLow() && 1125 (operand.GetSignedImmediate() >= -7)) || 1126 (rd.IsLow() && rn.Is(rd) && 1127 (operand.GetSignedImmediate() >= -255))); 1128 if (changed_op_is_smaller) { 1129 Subs(cond, rd, rn, -operand.GetSignedImmediate()); 1130 } else { 1131 Add(cond, rd, rn, operand); 1132 } 1133 } 1134 break; 1135 } 1136 } Add(FlagsUpdate flags,Register rd,Register rn,const Operand & operand)1137 void Add(FlagsUpdate flags, 1138 Register rd, 1139 Register rn, 1140 const Operand& operand) { 1141 Add(flags, al, rd, rn, operand); 1142 } 1143 Adds(Condition cond,Register rd,Register rn,const Operand & operand)1144 void Adds(Condition cond, Register rd, Register rn, const Operand& operand) { 1145 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1146 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1147 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1148 VIXL_ASSERT(allow_macro_instructions_); 1149 VIXL_ASSERT(OutsideITBlock()); 1150 MacroEmissionCheckScope guard(this); 1151 ITScope it_scope(this, &cond, guard); 1152 adds(cond, rd, rn, operand); 1153 } Adds(Register rd,Register rn,const Operand & operand)1154 void Adds(Register rd, Register rn, const Operand& operand) { 1155 Adds(al, rd, rn, operand); 1156 } 1157 And(Condition cond,Register rd,Register rn,const Operand & operand)1158 void And(Condition cond, Register rd, Register rn, const Operand& operand) { 1159 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1160 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1161 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1162 VIXL_ASSERT(allow_macro_instructions_); 1163 VIXL_ASSERT(OutsideITBlock()); 1164 MacroEmissionCheckScope guard(this); 1165 if (rd.Is(rn) && operand.IsPlainRegister() && 1166 rd.Is(operand.GetBaseRegister())) { 1167 return; 1168 } 1169 if (cond.Is(al) && operand.IsImmediate()) { 1170 uint32_t immediate = operand.GetImmediate(); 1171 if (immediate == 0) { 1172 mov(rd, 0); 1173 return; 1174 } 1175 if ((immediate == 0xffffffff) && rd.Is(rn)) { 1176 return; 1177 } 1178 } 1179 bool can_use_it = 1180 // AND<c>{<q>} {<Rdn>,} <Rdn>, <Rm> ; T1 1181 operand.IsPlainRegister() && rd.Is(rn) && rn.IsLow() && 1182 operand.GetBaseRegister().IsLow(); 1183 ITScope it_scope(this, &cond, guard, can_use_it); 1184 and_(cond, rd, rn, operand); 1185 } And(Register rd,Register rn,const Operand & operand)1186 void And(Register rd, Register rn, const Operand& operand) { 1187 And(al, rd, rn, operand); 1188 } And(FlagsUpdate flags,Condition cond,Register rd,Register rn,const Operand & operand)1189 void And(FlagsUpdate flags, 1190 Condition cond, 1191 Register rd, 1192 Register rn, 1193 const Operand& operand) { 1194 switch (flags) { 1195 case LeaveFlags: 1196 And(cond, rd, rn, operand); 1197 break; 1198 case SetFlags: 1199 Ands(cond, rd, rn, operand); 1200 break; 1201 case DontCare: 1202 if (operand.IsPlainRegister() && rd.Is(rn) && 1203 rd.Is(operand.GetBaseRegister())) { 1204 return; 1205 } 1206 bool setflags_is_smaller = IsUsingT32() && cond.Is(al) && rd.IsLow() && 1207 rn.Is(rd) && operand.IsPlainRegister() && 1208 operand.GetBaseRegister().IsLow(); 1209 if (setflags_is_smaller) { 1210 Ands(cond, rd, rn, operand); 1211 } else { 1212 And(cond, rd, rn, operand); 1213 } 1214 break; 1215 } 1216 } And(FlagsUpdate flags,Register rd,Register rn,const Operand & operand)1217 void And(FlagsUpdate flags, 1218 Register rd, 1219 Register rn, 1220 const Operand& operand) { 1221 And(flags, al, rd, rn, operand); 1222 } 1223 Ands(Condition cond,Register rd,Register rn,const Operand & operand)1224 void Ands(Condition cond, Register rd, Register rn, const Operand& operand) { 1225 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1226 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1227 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1228 VIXL_ASSERT(allow_macro_instructions_); 1229 VIXL_ASSERT(OutsideITBlock()); 1230 MacroEmissionCheckScope guard(this); 1231 ITScope it_scope(this, &cond, guard); 1232 ands(cond, rd, rn, operand); 1233 } Ands(Register rd,Register rn,const Operand & operand)1234 void Ands(Register rd, Register rn, const Operand& operand) { 1235 Ands(al, rd, rn, operand); 1236 } 1237 Asr(Condition cond,Register rd,Register rm,const Operand & operand)1238 void Asr(Condition cond, Register rd, Register rm, const Operand& operand) { 1239 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1240 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1241 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1242 VIXL_ASSERT(allow_macro_instructions_); 1243 VIXL_ASSERT(OutsideITBlock()); 1244 MacroEmissionCheckScope guard(this); 1245 bool can_use_it = 1246 // ASR<c>{<q>} {<Rd>,} <Rm>, #<imm> ; T2 1247 (operand.IsImmediate() && (operand.GetImmediate() >= 1) && 1248 (operand.GetImmediate() <= 32) && rd.IsLow() && rm.IsLow()) || 1249 // ASR<c>{<q>} {<Rdm>,} <Rdm>, <Rs> ; T1 1250 (operand.IsPlainRegister() && rd.Is(rm) && rd.IsLow() && 1251 operand.GetBaseRegister().IsLow()); 1252 ITScope it_scope(this, &cond, guard, can_use_it); 1253 asr(cond, rd, rm, operand); 1254 } Asr(Register rd,Register rm,const Operand & operand)1255 void Asr(Register rd, Register rm, const Operand& operand) { 1256 Asr(al, rd, rm, operand); 1257 } Asr(FlagsUpdate flags,Condition cond,Register rd,Register rm,const Operand & operand)1258 void Asr(FlagsUpdate flags, 1259 Condition cond, 1260 Register rd, 1261 Register rm, 1262 const Operand& operand) { 1263 switch (flags) { 1264 case LeaveFlags: 1265 Asr(cond, rd, rm, operand); 1266 break; 1267 case SetFlags: 1268 Asrs(cond, rd, rm, operand); 1269 break; 1270 case DontCare: 1271 bool setflags_is_smaller = 1272 IsUsingT32() && cond.Is(al) && rd.IsLow() && rm.IsLow() && 1273 ((operand.IsImmediate() && (operand.GetImmediate() >= 1) && 1274 (operand.GetImmediate() <= 32)) || 1275 (operand.IsPlainRegister() && rd.Is(rm))); 1276 if (setflags_is_smaller) { 1277 Asrs(cond, rd, rm, operand); 1278 } else { 1279 Asr(cond, rd, rm, operand); 1280 } 1281 break; 1282 } 1283 } Asr(FlagsUpdate flags,Register rd,Register rm,const Operand & operand)1284 void Asr(FlagsUpdate flags, 1285 Register rd, 1286 Register rm, 1287 const Operand& operand) { 1288 Asr(flags, al, rd, rm, operand); 1289 } 1290 Asrs(Condition cond,Register rd,Register rm,const Operand & operand)1291 void Asrs(Condition cond, Register rd, Register rm, const Operand& operand) { 1292 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1293 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1294 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1295 VIXL_ASSERT(allow_macro_instructions_); 1296 VIXL_ASSERT(OutsideITBlock()); 1297 MacroEmissionCheckScope guard(this); 1298 ITScope it_scope(this, &cond, guard); 1299 asrs(cond, rd, rm, operand); 1300 } Asrs(Register rd,Register rm,const Operand & operand)1301 void Asrs(Register rd, Register rm, const Operand& operand) { 1302 Asrs(al, rd, rm, operand); 1303 } 1304 1305 void B(Condition cond, Label* label, BranchHint hint = kBranchWithoutHint) { 1306 VIXL_ASSERT(allow_macro_instructions_); 1307 VIXL_ASSERT(OutsideITBlock()); 1308 EncodingSize size = Best; 1309 MacroEmissionCheckScope::PoolPolicy pool_policy = 1310 MacroEmissionCheckScope::kBlockPools; 1311 if (!label->IsBound()) { 1312 if (hint == kNear) size = Narrow; 1313 const ReferenceInfo* info; 1314 bool can_encode = b_info(cond, size, label, &info); 1315 VIXL_CHECK(can_encode); 1316 CheckEmitPoolForInstruction(info, label, &cond); 1317 // We have already checked for pool emission. 1318 pool_policy = MacroEmissionCheckScope::kIgnorePools; 1319 } 1320 MacroEmissionCheckScope guard(this, pool_policy); 1321 b(cond, size, label); 1322 RegisterForwardReference(label); 1323 } 1324 void B(Label* label, BranchHint hint = kBranchWithoutHint) { 1325 B(al, label, hint); 1326 } BPreferNear(Condition cond,Label * label)1327 void BPreferNear(Condition cond, Label* label) { B(cond, label, kNear); } BPreferNear(Label * label)1328 void BPreferNear(Label* label) { B(al, label, kNear); } 1329 Bfc(Condition cond,Register rd,uint32_t lsb,uint32_t width)1330 void Bfc(Condition cond, Register rd, uint32_t lsb, uint32_t width) { 1331 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1332 VIXL_ASSERT(allow_macro_instructions_); 1333 VIXL_ASSERT(OutsideITBlock()); 1334 MacroEmissionCheckScope guard(this); 1335 ITScope it_scope(this, &cond, guard); 1336 bfc(cond, rd, lsb, width); 1337 } Bfc(Register rd,uint32_t lsb,uint32_t width)1338 void Bfc(Register rd, uint32_t lsb, uint32_t width) { 1339 Bfc(al, rd, lsb, width); 1340 } 1341 Bfi(Condition cond,Register rd,Register rn,uint32_t lsb,uint32_t width)1342 void Bfi( 1343 Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) { 1344 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1345 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1346 VIXL_ASSERT(allow_macro_instructions_); 1347 VIXL_ASSERT(OutsideITBlock()); 1348 MacroEmissionCheckScope guard(this); 1349 ITScope it_scope(this, &cond, guard); 1350 bfi(cond, rd, rn, lsb, width); 1351 } Bfi(Register rd,Register rn,uint32_t lsb,uint32_t width)1352 void Bfi(Register rd, Register rn, uint32_t lsb, uint32_t width) { 1353 Bfi(al, rd, rn, lsb, width); 1354 } 1355 Bic(Condition cond,Register rd,Register rn,const Operand & operand)1356 void Bic(Condition cond, Register rd, Register rn, const Operand& operand) { 1357 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1358 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1359 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1360 VIXL_ASSERT(allow_macro_instructions_); 1361 VIXL_ASSERT(OutsideITBlock()); 1362 MacroEmissionCheckScope guard(this); 1363 if (cond.Is(al) && operand.IsImmediate()) { 1364 uint32_t immediate = operand.GetImmediate(); 1365 if ((immediate == 0) && rd.Is(rn)) { 1366 return; 1367 } 1368 if (immediate == 0xffffffff) { 1369 mov(rd, 0); 1370 return; 1371 } 1372 } 1373 bool can_use_it = 1374 // BIC<c>{<q>} {<Rdn>,} <Rdn>, <Rm> ; T1 1375 operand.IsPlainRegister() && rd.Is(rn) && rn.IsLow() && 1376 operand.GetBaseRegister().IsLow(); 1377 ITScope it_scope(this, &cond, guard, can_use_it); 1378 bic(cond, rd, rn, operand); 1379 } Bic(Register rd,Register rn,const Operand & operand)1380 void Bic(Register rd, Register rn, const Operand& operand) { 1381 Bic(al, rd, rn, operand); 1382 } Bic(FlagsUpdate flags,Condition cond,Register rd,Register rn,const Operand & operand)1383 void Bic(FlagsUpdate flags, 1384 Condition cond, 1385 Register rd, 1386 Register rn, 1387 const Operand& operand) { 1388 switch (flags) { 1389 case LeaveFlags: 1390 Bic(cond, rd, rn, operand); 1391 break; 1392 case SetFlags: 1393 Bics(cond, rd, rn, operand); 1394 break; 1395 case DontCare: 1396 bool setflags_is_smaller = IsUsingT32() && cond.Is(al) && rd.IsLow() && 1397 rn.Is(rd) && operand.IsPlainRegister() && 1398 operand.GetBaseRegister().IsLow(); 1399 if (setflags_is_smaller) { 1400 Bics(cond, rd, rn, operand); 1401 } else { 1402 Bic(cond, rd, rn, operand); 1403 } 1404 break; 1405 } 1406 } Bic(FlagsUpdate flags,Register rd,Register rn,const Operand & operand)1407 void Bic(FlagsUpdate flags, 1408 Register rd, 1409 Register rn, 1410 const Operand& operand) { 1411 Bic(flags, al, rd, rn, operand); 1412 } 1413 Bics(Condition cond,Register rd,Register rn,const Operand & operand)1414 void Bics(Condition cond, Register rd, Register rn, const Operand& operand) { 1415 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1416 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1417 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1418 VIXL_ASSERT(allow_macro_instructions_); 1419 VIXL_ASSERT(OutsideITBlock()); 1420 MacroEmissionCheckScope guard(this); 1421 ITScope it_scope(this, &cond, guard); 1422 bics(cond, rd, rn, operand); 1423 } Bics(Register rd,Register rn,const Operand & operand)1424 void Bics(Register rd, Register rn, const Operand& operand) { 1425 Bics(al, rd, rn, operand); 1426 } 1427 Bkpt(Condition cond,uint32_t imm)1428 void Bkpt(Condition cond, uint32_t imm) { 1429 VIXL_ASSERT(allow_macro_instructions_); 1430 VIXL_ASSERT(OutsideITBlock()); 1431 MacroEmissionCheckScope guard(this); 1432 ITScope it_scope(this, &cond, guard); 1433 bkpt(cond, imm); 1434 } Bkpt(uint32_t imm)1435 void Bkpt(uint32_t imm) { Bkpt(al, imm); } 1436 Bl(Condition cond,Label * label)1437 void Bl(Condition cond, Label* label) { 1438 VIXL_ASSERT(allow_macro_instructions_); 1439 VIXL_ASSERT(OutsideITBlock()); 1440 MacroEmissionCheckScope::PoolPolicy pool_policy = 1441 MacroEmissionCheckScope::kBlockPools; 1442 if (!label->IsBound()) { 1443 const ReferenceInfo* info; 1444 bool can_encode = bl_info(cond, label, &info); 1445 VIXL_CHECK(can_encode); 1446 CheckEmitPoolForInstruction(info, label, &cond); 1447 // We have already checked for pool emission. 1448 pool_policy = MacroEmissionCheckScope::kIgnorePools; 1449 } 1450 MacroEmissionCheckScope guard(this, pool_policy); 1451 ITScope it_scope(this, &cond, guard); 1452 bl(cond, label); 1453 RegisterForwardReference(label); 1454 } Bl(Label * label)1455 void Bl(Label* label) { Bl(al, label); } 1456 Blx(Condition cond,Label * label)1457 void Blx(Condition cond, Label* label) { 1458 VIXL_ASSERT(allow_macro_instructions_); 1459 VIXL_ASSERT(OutsideITBlock()); 1460 MacroEmissionCheckScope::PoolPolicy pool_policy = 1461 MacroEmissionCheckScope::kBlockPools; 1462 if (!label->IsBound()) { 1463 const ReferenceInfo* info; 1464 bool can_encode = blx_info(cond, label, &info); 1465 VIXL_CHECK(can_encode); 1466 CheckEmitPoolForInstruction(info, label, &cond); 1467 // We have already checked for pool emission. 1468 pool_policy = MacroEmissionCheckScope::kIgnorePools; 1469 } 1470 MacroEmissionCheckScope guard(this, pool_policy); 1471 ITScope it_scope(this, &cond, guard); 1472 blx(cond, label); 1473 RegisterForwardReference(label); 1474 } Blx(Label * label)1475 void Blx(Label* label) { Blx(al, label); } 1476 Blx(Condition cond,Register rm)1477 void Blx(Condition cond, Register rm) { 1478 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1479 VIXL_ASSERT(allow_macro_instructions_); 1480 VIXL_ASSERT(OutsideITBlock()); 1481 MacroEmissionCheckScope guard(this); 1482 bool can_use_it = 1483 // BLX{<c>}{<q>} <Rm> ; T1 1484 !rm.IsPC(); 1485 ITScope it_scope(this, &cond, guard, can_use_it); 1486 blx(cond, rm); 1487 } Blx(Register rm)1488 void Blx(Register rm) { Blx(al, rm); } 1489 Bx(Condition cond,Register rm)1490 void Bx(Condition cond, Register rm) { 1491 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1492 VIXL_ASSERT(allow_macro_instructions_); 1493 VIXL_ASSERT(OutsideITBlock()); 1494 MacroEmissionCheckScope guard(this); 1495 bool can_use_it = 1496 // BX{<c>}{<q>} <Rm> ; T1 1497 !rm.IsPC(); 1498 ITScope it_scope(this, &cond, guard, can_use_it); 1499 bx(cond, rm); 1500 } Bx(Register rm)1501 void Bx(Register rm) { Bx(al, rm); } 1502 Bxj(Condition cond,Register rm)1503 void Bxj(Condition cond, Register rm) { 1504 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1505 VIXL_ASSERT(allow_macro_instructions_); 1506 VIXL_ASSERT(OutsideITBlock()); 1507 MacroEmissionCheckScope guard(this); 1508 ITScope it_scope(this, &cond, guard); 1509 bxj(cond, rm); 1510 } Bxj(Register rm)1511 void Bxj(Register rm) { Bxj(al, rm); } 1512 Cbnz(Register rn,Label * label)1513 void Cbnz(Register rn, Label* label) { 1514 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1515 VIXL_ASSERT(allow_macro_instructions_); 1516 VIXL_ASSERT(OutsideITBlock()); 1517 MacroEmissionCheckScope::PoolPolicy pool_policy = 1518 MacroEmissionCheckScope::kBlockPools; 1519 if (!label->IsBound()) { 1520 const ReferenceInfo* info; 1521 bool can_encode = cbnz_info(rn, label, &info); 1522 VIXL_CHECK(can_encode); 1523 CheckEmitPoolForInstruction(info, label); 1524 // We have already checked for pool emission. 1525 pool_policy = MacroEmissionCheckScope::kIgnorePools; 1526 } 1527 MacroEmissionCheckScope guard(this, pool_policy); 1528 cbnz(rn, label); 1529 RegisterForwardReference(label); 1530 } 1531 Cbz(Register rn,Label * label)1532 void Cbz(Register rn, Label* label) { 1533 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1534 VIXL_ASSERT(allow_macro_instructions_); 1535 VIXL_ASSERT(OutsideITBlock()); 1536 MacroEmissionCheckScope::PoolPolicy pool_policy = 1537 MacroEmissionCheckScope::kBlockPools; 1538 if (!label->IsBound()) { 1539 const ReferenceInfo* info; 1540 bool can_encode = cbz_info(rn, label, &info); 1541 VIXL_CHECK(can_encode); 1542 CheckEmitPoolForInstruction(info, label); 1543 // We have already checked for pool emission. 1544 pool_policy = MacroEmissionCheckScope::kIgnorePools; 1545 } 1546 MacroEmissionCheckScope guard(this, pool_policy); 1547 cbz(rn, label); 1548 RegisterForwardReference(label); 1549 } 1550 Clrex(Condition cond)1551 void Clrex(Condition cond) { 1552 VIXL_ASSERT(allow_macro_instructions_); 1553 VIXL_ASSERT(OutsideITBlock()); 1554 MacroEmissionCheckScope guard(this); 1555 ITScope it_scope(this, &cond, guard); 1556 clrex(cond); 1557 } Clrex()1558 void Clrex() { Clrex(al); } 1559 Clz(Condition cond,Register rd,Register rm)1560 void Clz(Condition cond, Register rd, Register rm) { 1561 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1562 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1563 VIXL_ASSERT(allow_macro_instructions_); 1564 VIXL_ASSERT(OutsideITBlock()); 1565 MacroEmissionCheckScope guard(this); 1566 ITScope it_scope(this, &cond, guard); 1567 clz(cond, rd, rm); 1568 } Clz(Register rd,Register rm)1569 void Clz(Register rd, Register rm) { Clz(al, rd, rm); } 1570 Cmn(Condition cond,Register rn,const Operand & operand)1571 void Cmn(Condition cond, Register rn, const Operand& operand) { 1572 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1573 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1574 VIXL_ASSERT(allow_macro_instructions_); 1575 VIXL_ASSERT(OutsideITBlock()); 1576 MacroEmissionCheckScope guard(this); 1577 bool can_use_it = 1578 // CMN{<c>}{<q>} <Rn>, <Rm> ; T1 1579 operand.IsPlainRegister() && rn.IsLow() && 1580 operand.GetBaseRegister().IsLow(); 1581 ITScope it_scope(this, &cond, guard, can_use_it); 1582 cmn(cond, rn, operand); 1583 } Cmn(Register rn,const Operand & operand)1584 void Cmn(Register rn, const Operand& operand) { Cmn(al, rn, operand); } 1585 Cmp(Condition cond,Register rn,const Operand & operand)1586 void Cmp(Condition cond, Register rn, const Operand& operand) { 1587 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1588 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1589 VIXL_ASSERT(allow_macro_instructions_); 1590 VIXL_ASSERT(OutsideITBlock()); 1591 MacroEmissionCheckScope guard(this); 1592 bool can_use_it = 1593 // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1 1594 (operand.IsImmediate() && (operand.GetImmediate() <= 255) && 1595 rn.IsLow()) || 1596 // CMP{<c>}{<q>} <Rn>, <Rm> ; T1 T2 1597 (operand.IsPlainRegister() && !rn.IsPC() && 1598 !operand.GetBaseRegister().IsPC()); 1599 ITScope it_scope(this, &cond, guard, can_use_it); 1600 cmp(cond, rn, operand); 1601 } Cmp(Register rn,const Operand & operand)1602 void Cmp(Register rn, const Operand& operand) { Cmp(al, rn, operand); } 1603 Crc32b(Condition cond,Register rd,Register rn,Register rm)1604 void Crc32b(Condition cond, Register rd, Register rn, Register rm) { 1605 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1606 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1607 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1608 VIXL_ASSERT(allow_macro_instructions_); 1609 VIXL_ASSERT(OutsideITBlock()); 1610 MacroEmissionCheckScope guard(this); 1611 ITScope it_scope(this, &cond, guard); 1612 crc32b(cond, rd, rn, rm); 1613 } Crc32b(Register rd,Register rn,Register rm)1614 void Crc32b(Register rd, Register rn, Register rm) { Crc32b(al, rd, rn, rm); } 1615 Crc32cb(Condition cond,Register rd,Register rn,Register rm)1616 void Crc32cb(Condition cond, Register rd, Register rn, Register rm) { 1617 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1618 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1619 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1620 VIXL_ASSERT(allow_macro_instructions_); 1621 VIXL_ASSERT(OutsideITBlock()); 1622 MacroEmissionCheckScope guard(this); 1623 ITScope it_scope(this, &cond, guard); 1624 crc32cb(cond, rd, rn, rm); 1625 } Crc32cb(Register rd,Register rn,Register rm)1626 void Crc32cb(Register rd, Register rn, Register rm) { 1627 Crc32cb(al, rd, rn, rm); 1628 } 1629 Crc32ch(Condition cond,Register rd,Register rn,Register rm)1630 void Crc32ch(Condition cond, Register rd, Register rn, Register rm) { 1631 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1632 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1633 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1634 VIXL_ASSERT(allow_macro_instructions_); 1635 VIXL_ASSERT(OutsideITBlock()); 1636 MacroEmissionCheckScope guard(this); 1637 ITScope it_scope(this, &cond, guard); 1638 crc32ch(cond, rd, rn, rm); 1639 } Crc32ch(Register rd,Register rn,Register rm)1640 void Crc32ch(Register rd, Register rn, Register rm) { 1641 Crc32ch(al, rd, rn, rm); 1642 } 1643 Crc32cw(Condition cond,Register rd,Register rn,Register rm)1644 void Crc32cw(Condition cond, Register rd, Register rn, Register rm) { 1645 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1646 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1647 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1648 VIXL_ASSERT(allow_macro_instructions_); 1649 VIXL_ASSERT(OutsideITBlock()); 1650 MacroEmissionCheckScope guard(this); 1651 ITScope it_scope(this, &cond, guard); 1652 crc32cw(cond, rd, rn, rm); 1653 } Crc32cw(Register rd,Register rn,Register rm)1654 void Crc32cw(Register rd, Register rn, Register rm) { 1655 Crc32cw(al, rd, rn, rm); 1656 } 1657 Crc32h(Condition cond,Register rd,Register rn,Register rm)1658 void Crc32h(Condition cond, Register rd, Register rn, Register rm) { 1659 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1660 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1661 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1662 VIXL_ASSERT(allow_macro_instructions_); 1663 VIXL_ASSERT(OutsideITBlock()); 1664 MacroEmissionCheckScope guard(this); 1665 ITScope it_scope(this, &cond, guard); 1666 crc32h(cond, rd, rn, rm); 1667 } Crc32h(Register rd,Register rn,Register rm)1668 void Crc32h(Register rd, Register rn, Register rm) { Crc32h(al, rd, rn, rm); } 1669 Crc32w(Condition cond,Register rd,Register rn,Register rm)1670 void Crc32w(Condition cond, Register rd, Register rn, Register rm) { 1671 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1672 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1673 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 1674 VIXL_ASSERT(allow_macro_instructions_); 1675 VIXL_ASSERT(OutsideITBlock()); 1676 MacroEmissionCheckScope guard(this); 1677 ITScope it_scope(this, &cond, guard); 1678 crc32w(cond, rd, rn, rm); 1679 } Crc32w(Register rd,Register rn,Register rm)1680 void Crc32w(Register rd, Register rn, Register rm) { Crc32w(al, rd, rn, rm); } 1681 Dmb(Condition cond,MemoryBarrier option)1682 void Dmb(Condition cond, MemoryBarrier option) { 1683 VIXL_ASSERT(allow_macro_instructions_); 1684 VIXL_ASSERT(OutsideITBlock()); 1685 MacroEmissionCheckScope guard(this); 1686 ITScope it_scope(this, &cond, guard); 1687 dmb(cond, option); 1688 } Dmb(MemoryBarrier option)1689 void Dmb(MemoryBarrier option) { Dmb(al, option); } 1690 Dsb(Condition cond,MemoryBarrier option)1691 void Dsb(Condition cond, MemoryBarrier option) { 1692 VIXL_ASSERT(allow_macro_instructions_); 1693 VIXL_ASSERT(OutsideITBlock()); 1694 MacroEmissionCheckScope guard(this); 1695 ITScope it_scope(this, &cond, guard); 1696 dsb(cond, option); 1697 } Dsb(MemoryBarrier option)1698 void Dsb(MemoryBarrier option) { Dsb(al, option); } 1699 Eor(Condition cond,Register rd,Register rn,const Operand & operand)1700 void Eor(Condition cond, Register rd, Register rn, const Operand& operand) { 1701 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1702 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1703 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1704 VIXL_ASSERT(allow_macro_instructions_); 1705 VIXL_ASSERT(OutsideITBlock()); 1706 MacroEmissionCheckScope guard(this); 1707 if (cond.Is(al) && rd.Is(rn) && operand.IsImmediate()) { 1708 uint32_t immediate = operand.GetImmediate(); 1709 if (immediate == 0) { 1710 return; 1711 } 1712 if (immediate == 0xffffffff) { 1713 mvn(rd, rn); 1714 return; 1715 } 1716 } 1717 bool can_use_it = 1718 // EOR<c>{<q>} {<Rdn>,} <Rdn>, <Rm> ; T1 1719 operand.IsPlainRegister() && rd.Is(rn) && rn.IsLow() && 1720 operand.GetBaseRegister().IsLow(); 1721 ITScope it_scope(this, &cond, guard, can_use_it); 1722 eor(cond, rd, rn, operand); 1723 } Eor(Register rd,Register rn,const Operand & operand)1724 void Eor(Register rd, Register rn, const Operand& operand) { 1725 Eor(al, rd, rn, operand); 1726 } Eor(FlagsUpdate flags,Condition cond,Register rd,Register rn,const Operand & operand)1727 void Eor(FlagsUpdate flags, 1728 Condition cond, 1729 Register rd, 1730 Register rn, 1731 const Operand& operand) { 1732 switch (flags) { 1733 case LeaveFlags: 1734 Eor(cond, rd, rn, operand); 1735 break; 1736 case SetFlags: 1737 Eors(cond, rd, rn, operand); 1738 break; 1739 case DontCare: 1740 bool setflags_is_smaller = IsUsingT32() && cond.Is(al) && rd.IsLow() && 1741 rn.Is(rd) && operand.IsPlainRegister() && 1742 operand.GetBaseRegister().IsLow(); 1743 if (setflags_is_smaller) { 1744 Eors(cond, rd, rn, operand); 1745 } else { 1746 Eor(cond, rd, rn, operand); 1747 } 1748 break; 1749 } 1750 } Eor(FlagsUpdate flags,Register rd,Register rn,const Operand & operand)1751 void Eor(FlagsUpdate flags, 1752 Register rd, 1753 Register rn, 1754 const Operand& operand) { 1755 Eor(flags, al, rd, rn, operand); 1756 } 1757 Eors(Condition cond,Register rd,Register rn,const Operand & operand)1758 void Eors(Condition cond, Register rd, Register rn, const Operand& operand) { 1759 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 1760 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1761 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1762 VIXL_ASSERT(allow_macro_instructions_); 1763 VIXL_ASSERT(OutsideITBlock()); 1764 MacroEmissionCheckScope guard(this); 1765 ITScope it_scope(this, &cond, guard); 1766 eors(cond, rd, rn, operand); 1767 } Eors(Register rd,Register rn,const Operand & operand)1768 void Eors(Register rd, Register rn, const Operand& operand) { 1769 Eors(al, rd, rn, operand); 1770 } 1771 Fldmdbx(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)1772 void Fldmdbx(Condition cond, 1773 Register rn, 1774 WriteBack write_back, 1775 DRegisterList dreglist) { 1776 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1777 VIXL_ASSERT(!AliasesAvailableScratchRegister(dreglist)); 1778 VIXL_ASSERT(allow_macro_instructions_); 1779 VIXL_ASSERT(OutsideITBlock()); 1780 MacroEmissionCheckScope guard(this); 1781 ITScope it_scope(this, &cond, guard); 1782 fldmdbx(cond, rn, write_back, dreglist); 1783 } Fldmdbx(Register rn,WriteBack write_back,DRegisterList dreglist)1784 void Fldmdbx(Register rn, WriteBack write_back, DRegisterList dreglist) { 1785 Fldmdbx(al, rn, write_back, dreglist); 1786 } 1787 Fldmiax(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)1788 void Fldmiax(Condition cond, 1789 Register rn, 1790 WriteBack write_back, 1791 DRegisterList dreglist) { 1792 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1793 VIXL_ASSERT(!AliasesAvailableScratchRegister(dreglist)); 1794 VIXL_ASSERT(allow_macro_instructions_); 1795 VIXL_ASSERT(OutsideITBlock()); 1796 MacroEmissionCheckScope guard(this); 1797 ITScope it_scope(this, &cond, guard); 1798 fldmiax(cond, rn, write_back, dreglist); 1799 } Fldmiax(Register rn,WriteBack write_back,DRegisterList dreglist)1800 void Fldmiax(Register rn, WriteBack write_back, DRegisterList dreglist) { 1801 Fldmiax(al, rn, write_back, dreglist); 1802 } 1803 Fstmdbx(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)1804 void Fstmdbx(Condition cond, 1805 Register rn, 1806 WriteBack write_back, 1807 DRegisterList dreglist) { 1808 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1809 VIXL_ASSERT(!AliasesAvailableScratchRegister(dreglist)); 1810 VIXL_ASSERT(allow_macro_instructions_); 1811 VIXL_ASSERT(OutsideITBlock()); 1812 MacroEmissionCheckScope guard(this); 1813 ITScope it_scope(this, &cond, guard); 1814 fstmdbx(cond, rn, write_back, dreglist); 1815 } Fstmdbx(Register rn,WriteBack write_back,DRegisterList dreglist)1816 void Fstmdbx(Register rn, WriteBack write_back, DRegisterList dreglist) { 1817 Fstmdbx(al, rn, write_back, dreglist); 1818 } 1819 Fstmiax(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)1820 void Fstmiax(Condition cond, 1821 Register rn, 1822 WriteBack write_back, 1823 DRegisterList dreglist) { 1824 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1825 VIXL_ASSERT(!AliasesAvailableScratchRegister(dreglist)); 1826 VIXL_ASSERT(allow_macro_instructions_); 1827 VIXL_ASSERT(OutsideITBlock()); 1828 MacroEmissionCheckScope guard(this); 1829 ITScope it_scope(this, &cond, guard); 1830 fstmiax(cond, rn, write_back, dreglist); 1831 } Fstmiax(Register rn,WriteBack write_back,DRegisterList dreglist)1832 void Fstmiax(Register rn, WriteBack write_back, DRegisterList dreglist) { 1833 Fstmiax(al, rn, write_back, dreglist); 1834 } 1835 Hlt(Condition cond,uint32_t imm)1836 void Hlt(Condition cond, uint32_t imm) { 1837 VIXL_ASSERT(allow_macro_instructions_); 1838 VIXL_ASSERT(OutsideITBlock()); 1839 MacroEmissionCheckScope guard(this); 1840 ITScope it_scope(this, &cond, guard); 1841 hlt(cond, imm); 1842 } Hlt(uint32_t imm)1843 void Hlt(uint32_t imm) { Hlt(al, imm); } 1844 Hvc(Condition cond,uint32_t imm)1845 void Hvc(Condition cond, uint32_t imm) { 1846 VIXL_ASSERT(allow_macro_instructions_); 1847 VIXL_ASSERT(OutsideITBlock()); 1848 MacroEmissionCheckScope guard(this); 1849 ITScope it_scope(this, &cond, guard); 1850 hvc(cond, imm); 1851 } Hvc(uint32_t imm)1852 void Hvc(uint32_t imm) { Hvc(al, imm); } 1853 Isb(Condition cond,MemoryBarrier option)1854 void Isb(Condition cond, MemoryBarrier option) { 1855 VIXL_ASSERT(allow_macro_instructions_); 1856 VIXL_ASSERT(OutsideITBlock()); 1857 MacroEmissionCheckScope guard(this); 1858 ITScope it_scope(this, &cond, guard); 1859 isb(cond, option); 1860 } Isb(MemoryBarrier option)1861 void Isb(MemoryBarrier option) { Isb(al, option); } 1862 Lda(Condition cond,Register rt,const MemOperand & operand)1863 void Lda(Condition cond, Register rt, const MemOperand& operand) { 1864 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 1865 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1866 VIXL_ASSERT(allow_macro_instructions_); 1867 VIXL_ASSERT(OutsideITBlock()); 1868 MacroEmissionCheckScope guard(this); 1869 ITScope it_scope(this, &cond, guard); 1870 lda(cond, rt, operand); 1871 } Lda(Register rt,const MemOperand & operand)1872 void Lda(Register rt, const MemOperand& operand) { Lda(al, rt, operand); } 1873 Ldab(Condition cond,Register rt,const MemOperand & operand)1874 void Ldab(Condition cond, Register rt, const MemOperand& operand) { 1875 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 1876 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1877 VIXL_ASSERT(allow_macro_instructions_); 1878 VIXL_ASSERT(OutsideITBlock()); 1879 MacroEmissionCheckScope guard(this); 1880 ITScope it_scope(this, &cond, guard); 1881 ldab(cond, rt, operand); 1882 } Ldab(Register rt,const MemOperand & operand)1883 void Ldab(Register rt, const MemOperand& operand) { Ldab(al, rt, operand); } 1884 Ldaex(Condition cond,Register rt,const MemOperand & operand)1885 void Ldaex(Condition cond, Register rt, const MemOperand& operand) { 1886 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 1887 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1888 VIXL_ASSERT(allow_macro_instructions_); 1889 VIXL_ASSERT(OutsideITBlock()); 1890 MacroEmissionCheckScope guard(this); 1891 ITScope it_scope(this, &cond, guard); 1892 ldaex(cond, rt, operand); 1893 } Ldaex(Register rt,const MemOperand & operand)1894 void Ldaex(Register rt, const MemOperand& operand) { Ldaex(al, rt, operand); } 1895 Ldaexb(Condition cond,Register rt,const MemOperand & operand)1896 void Ldaexb(Condition cond, Register rt, const MemOperand& operand) { 1897 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 1898 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1899 VIXL_ASSERT(allow_macro_instructions_); 1900 VIXL_ASSERT(OutsideITBlock()); 1901 MacroEmissionCheckScope guard(this); 1902 ITScope it_scope(this, &cond, guard); 1903 ldaexb(cond, rt, operand); 1904 } Ldaexb(Register rt,const MemOperand & operand)1905 void Ldaexb(Register rt, const MemOperand& operand) { 1906 Ldaexb(al, rt, operand); 1907 } 1908 Ldaexd(Condition cond,Register rt,Register rt2,const MemOperand & operand)1909 void Ldaexd(Condition cond, 1910 Register rt, 1911 Register rt2, 1912 const MemOperand& operand) { 1913 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 1914 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt2)); 1915 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1916 VIXL_ASSERT(allow_macro_instructions_); 1917 VIXL_ASSERT(OutsideITBlock()); 1918 MacroEmissionCheckScope guard(this); 1919 ITScope it_scope(this, &cond, guard); 1920 ldaexd(cond, rt, rt2, operand); 1921 } Ldaexd(Register rt,Register rt2,const MemOperand & operand)1922 void Ldaexd(Register rt, Register rt2, const MemOperand& operand) { 1923 Ldaexd(al, rt, rt2, operand); 1924 } 1925 Ldaexh(Condition cond,Register rt,const MemOperand & operand)1926 void Ldaexh(Condition cond, Register rt, const MemOperand& operand) { 1927 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 1928 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1929 VIXL_ASSERT(allow_macro_instructions_); 1930 VIXL_ASSERT(OutsideITBlock()); 1931 MacroEmissionCheckScope guard(this); 1932 ITScope it_scope(this, &cond, guard); 1933 ldaexh(cond, rt, operand); 1934 } Ldaexh(Register rt,const MemOperand & operand)1935 void Ldaexh(Register rt, const MemOperand& operand) { 1936 Ldaexh(al, rt, operand); 1937 } 1938 Ldah(Condition cond,Register rt,const MemOperand & operand)1939 void Ldah(Condition cond, Register rt, const MemOperand& operand) { 1940 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 1941 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 1942 VIXL_ASSERT(allow_macro_instructions_); 1943 VIXL_ASSERT(OutsideITBlock()); 1944 MacroEmissionCheckScope guard(this); 1945 ITScope it_scope(this, &cond, guard); 1946 ldah(cond, rt, operand); 1947 } Ldah(Register rt,const MemOperand & operand)1948 void Ldah(Register rt, const MemOperand& operand) { Ldah(al, rt, operand); } 1949 Ldm(Condition cond,Register rn,WriteBack write_back,RegisterList registers)1950 void Ldm(Condition cond, 1951 Register rn, 1952 WriteBack write_back, 1953 RegisterList registers) { 1954 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1955 VIXL_ASSERT(!AliasesAvailableScratchRegister(registers)); 1956 VIXL_ASSERT(allow_macro_instructions_); 1957 VIXL_ASSERT(OutsideITBlock()); 1958 MacroEmissionCheckScope guard(this); 1959 ITScope it_scope(this, &cond, guard); 1960 ldm(cond, rn, write_back, registers); 1961 } Ldm(Register rn,WriteBack write_back,RegisterList registers)1962 void Ldm(Register rn, WriteBack write_back, RegisterList registers) { 1963 Ldm(al, rn, write_back, registers); 1964 } 1965 Ldmda(Condition cond,Register rn,WriteBack write_back,RegisterList registers)1966 void Ldmda(Condition cond, 1967 Register rn, 1968 WriteBack write_back, 1969 RegisterList registers) { 1970 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1971 VIXL_ASSERT(!AliasesAvailableScratchRegister(registers)); 1972 VIXL_ASSERT(allow_macro_instructions_); 1973 VIXL_ASSERT(OutsideITBlock()); 1974 MacroEmissionCheckScope guard(this); 1975 ITScope it_scope(this, &cond, guard); 1976 ldmda(cond, rn, write_back, registers); 1977 } Ldmda(Register rn,WriteBack write_back,RegisterList registers)1978 void Ldmda(Register rn, WriteBack write_back, RegisterList registers) { 1979 Ldmda(al, rn, write_back, registers); 1980 } 1981 Ldmdb(Condition cond,Register rn,WriteBack write_back,RegisterList registers)1982 void Ldmdb(Condition cond, 1983 Register rn, 1984 WriteBack write_back, 1985 RegisterList registers) { 1986 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 1987 VIXL_ASSERT(!AliasesAvailableScratchRegister(registers)); 1988 VIXL_ASSERT(allow_macro_instructions_); 1989 VIXL_ASSERT(OutsideITBlock()); 1990 MacroEmissionCheckScope guard(this); 1991 ITScope it_scope(this, &cond, guard); 1992 ldmdb(cond, rn, write_back, registers); 1993 } Ldmdb(Register rn,WriteBack write_back,RegisterList registers)1994 void Ldmdb(Register rn, WriteBack write_back, RegisterList registers) { 1995 Ldmdb(al, rn, write_back, registers); 1996 } 1997 Ldmea(Condition cond,Register rn,WriteBack write_back,RegisterList registers)1998 void Ldmea(Condition cond, 1999 Register rn, 2000 WriteBack write_back, 2001 RegisterList registers) { 2002 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2003 VIXL_ASSERT(!AliasesAvailableScratchRegister(registers)); 2004 VIXL_ASSERT(allow_macro_instructions_); 2005 VIXL_ASSERT(OutsideITBlock()); 2006 MacroEmissionCheckScope guard(this); 2007 ITScope it_scope(this, &cond, guard); 2008 ldmea(cond, rn, write_back, registers); 2009 } Ldmea(Register rn,WriteBack write_back,RegisterList registers)2010 void Ldmea(Register rn, WriteBack write_back, RegisterList registers) { 2011 Ldmea(al, rn, write_back, registers); 2012 } 2013 Ldmed(Condition cond,Register rn,WriteBack write_back,RegisterList registers)2014 void Ldmed(Condition cond, 2015 Register rn, 2016 WriteBack write_back, 2017 RegisterList registers) { 2018 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2019 VIXL_ASSERT(!AliasesAvailableScratchRegister(registers)); 2020 VIXL_ASSERT(allow_macro_instructions_); 2021 VIXL_ASSERT(OutsideITBlock()); 2022 MacroEmissionCheckScope guard(this); 2023 ITScope it_scope(this, &cond, guard); 2024 ldmed(cond, rn, write_back, registers); 2025 } Ldmed(Register rn,WriteBack write_back,RegisterList registers)2026 void Ldmed(Register rn, WriteBack write_back, RegisterList registers) { 2027 Ldmed(al, rn, write_back, registers); 2028 } 2029 Ldmfa(Condition cond,Register rn,WriteBack write_back,RegisterList registers)2030 void Ldmfa(Condition cond, 2031 Register rn, 2032 WriteBack write_back, 2033 RegisterList registers) { 2034 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2035 VIXL_ASSERT(!AliasesAvailableScratchRegister(registers)); 2036 VIXL_ASSERT(allow_macro_instructions_); 2037 VIXL_ASSERT(OutsideITBlock()); 2038 MacroEmissionCheckScope guard(this); 2039 ITScope it_scope(this, &cond, guard); 2040 ldmfa(cond, rn, write_back, registers); 2041 } Ldmfa(Register rn,WriteBack write_back,RegisterList registers)2042 void Ldmfa(Register rn, WriteBack write_back, RegisterList registers) { 2043 Ldmfa(al, rn, write_back, registers); 2044 } 2045 Ldmfd(Condition cond,Register rn,WriteBack write_back,RegisterList registers)2046 void Ldmfd(Condition cond, 2047 Register rn, 2048 WriteBack write_back, 2049 RegisterList registers) { 2050 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2051 VIXL_ASSERT(!AliasesAvailableScratchRegister(registers)); 2052 VIXL_ASSERT(allow_macro_instructions_); 2053 VIXL_ASSERT(OutsideITBlock()); 2054 MacroEmissionCheckScope guard(this); 2055 ITScope it_scope(this, &cond, guard); 2056 ldmfd(cond, rn, write_back, registers); 2057 } Ldmfd(Register rn,WriteBack write_back,RegisterList registers)2058 void Ldmfd(Register rn, WriteBack write_back, RegisterList registers) { 2059 Ldmfd(al, rn, write_back, registers); 2060 } 2061 Ldmib(Condition cond,Register rn,WriteBack write_back,RegisterList registers)2062 void Ldmib(Condition cond, 2063 Register rn, 2064 WriteBack write_back, 2065 RegisterList registers) { 2066 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2067 VIXL_ASSERT(!AliasesAvailableScratchRegister(registers)); 2068 VIXL_ASSERT(allow_macro_instructions_); 2069 VIXL_ASSERT(OutsideITBlock()); 2070 MacroEmissionCheckScope guard(this); 2071 ITScope it_scope(this, &cond, guard); 2072 ldmib(cond, rn, write_back, registers); 2073 } Ldmib(Register rn,WriteBack write_back,RegisterList registers)2074 void Ldmib(Register rn, WriteBack write_back, RegisterList registers) { 2075 Ldmib(al, rn, write_back, registers); 2076 } 2077 Ldr(Condition cond,Register rt,const MemOperand & operand)2078 void Ldr(Condition cond, Register rt, const MemOperand& operand) { 2079 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2080 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2081 VIXL_ASSERT(allow_macro_instructions_); 2082 VIXL_ASSERT(OutsideITBlock()); 2083 MacroEmissionCheckScope guard(this); 2084 bool can_use_it = 2085 // LDR{<c>}{<q>} <Rt>, [<Rn> {, #{+}<imm>}] ; T1 2086 (operand.IsImmediate() && rt.IsLow() && 2087 operand.GetBaseRegister().IsLow() && 2088 operand.IsOffsetImmediateWithinRange(0, 124, 4) && 2089 (operand.GetAddrMode() == Offset)) || 2090 // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2 2091 (operand.IsImmediate() && rt.IsLow() && 2092 operand.GetBaseRegister().IsSP() && 2093 operand.IsOffsetImmediateWithinRange(0, 1020, 4) && 2094 (operand.GetAddrMode() == Offset)) || 2095 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>] ; T1 2096 (operand.IsPlainRegister() && rt.IsLow() && 2097 operand.GetBaseRegister().IsLow() && 2098 operand.GetOffsetRegister().IsLow() && operand.GetSign().IsPlus() && 2099 (operand.GetAddrMode() == Offset)); 2100 ITScope it_scope(this, &cond, guard, can_use_it); 2101 ldr(cond, rt, operand); 2102 } Ldr(Register rt,const MemOperand & operand)2103 void Ldr(Register rt, const MemOperand& operand) { Ldr(al, rt, operand); } 2104 2105 Ldrb(Condition cond,Register rt,const MemOperand & operand)2106 void Ldrb(Condition cond, Register rt, const MemOperand& operand) { 2107 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2108 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2109 VIXL_ASSERT(allow_macro_instructions_); 2110 VIXL_ASSERT(OutsideITBlock()); 2111 MacroEmissionCheckScope guard(this); 2112 bool can_use_it = 2113 // LDRB{<c>}{<q>} <Rt>, [<Rn> {, #{+}<imm>}] ; T1 2114 (operand.IsImmediate() && rt.IsLow() && 2115 operand.GetBaseRegister().IsLow() && 2116 operand.IsOffsetImmediateWithinRange(0, 31) && 2117 (operand.GetAddrMode() == Offset)) || 2118 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>] ; T1 2119 (operand.IsPlainRegister() && rt.IsLow() && 2120 operand.GetBaseRegister().IsLow() && 2121 operand.GetOffsetRegister().IsLow() && operand.GetSign().IsPlus() && 2122 (operand.GetAddrMode() == Offset)); 2123 ITScope it_scope(this, &cond, guard, can_use_it); 2124 ldrb(cond, rt, operand); 2125 } Ldrb(Register rt,const MemOperand & operand)2126 void Ldrb(Register rt, const MemOperand& operand) { Ldrb(al, rt, operand); } 2127 2128 Ldrd(Condition cond,Register rt,Register rt2,const MemOperand & operand)2129 void Ldrd(Condition cond, 2130 Register rt, 2131 Register rt2, 2132 const MemOperand& operand) { 2133 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2134 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt2)); 2135 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2136 VIXL_ASSERT(allow_macro_instructions_); 2137 VIXL_ASSERT(OutsideITBlock()); 2138 MacroEmissionCheckScope guard(this); 2139 ITScope it_scope(this, &cond, guard); 2140 ldrd(cond, rt, rt2, operand); 2141 } Ldrd(Register rt,Register rt2,const MemOperand & operand)2142 void Ldrd(Register rt, Register rt2, const MemOperand& operand) { 2143 Ldrd(al, rt, rt2, operand); 2144 } 2145 2146 Ldrex(Condition cond,Register rt,const MemOperand & operand)2147 void Ldrex(Condition cond, Register rt, const MemOperand& operand) { 2148 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2149 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2150 VIXL_ASSERT(allow_macro_instructions_); 2151 VIXL_ASSERT(OutsideITBlock()); 2152 MacroEmissionCheckScope guard(this); 2153 ITScope it_scope(this, &cond, guard); 2154 ldrex(cond, rt, operand); 2155 } Ldrex(Register rt,const MemOperand & operand)2156 void Ldrex(Register rt, const MemOperand& operand) { Ldrex(al, rt, operand); } 2157 Ldrexb(Condition cond,Register rt,const MemOperand & operand)2158 void Ldrexb(Condition cond, Register rt, const MemOperand& operand) { 2159 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2160 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2161 VIXL_ASSERT(allow_macro_instructions_); 2162 VIXL_ASSERT(OutsideITBlock()); 2163 MacroEmissionCheckScope guard(this); 2164 ITScope it_scope(this, &cond, guard); 2165 ldrexb(cond, rt, operand); 2166 } Ldrexb(Register rt,const MemOperand & operand)2167 void Ldrexb(Register rt, const MemOperand& operand) { 2168 Ldrexb(al, rt, operand); 2169 } 2170 Ldrexd(Condition cond,Register rt,Register rt2,const MemOperand & operand)2171 void Ldrexd(Condition cond, 2172 Register rt, 2173 Register rt2, 2174 const MemOperand& operand) { 2175 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2176 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt2)); 2177 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2178 VIXL_ASSERT(allow_macro_instructions_); 2179 VIXL_ASSERT(OutsideITBlock()); 2180 MacroEmissionCheckScope guard(this); 2181 ITScope it_scope(this, &cond, guard); 2182 ldrexd(cond, rt, rt2, operand); 2183 } Ldrexd(Register rt,Register rt2,const MemOperand & operand)2184 void Ldrexd(Register rt, Register rt2, const MemOperand& operand) { 2185 Ldrexd(al, rt, rt2, operand); 2186 } 2187 Ldrexh(Condition cond,Register rt,const MemOperand & operand)2188 void Ldrexh(Condition cond, Register rt, const MemOperand& operand) { 2189 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2190 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2191 VIXL_ASSERT(allow_macro_instructions_); 2192 VIXL_ASSERT(OutsideITBlock()); 2193 MacroEmissionCheckScope guard(this); 2194 ITScope it_scope(this, &cond, guard); 2195 ldrexh(cond, rt, operand); 2196 } Ldrexh(Register rt,const MemOperand & operand)2197 void Ldrexh(Register rt, const MemOperand& operand) { 2198 Ldrexh(al, rt, operand); 2199 } 2200 Ldrh(Condition cond,Register rt,const MemOperand & operand)2201 void Ldrh(Condition cond, Register rt, const MemOperand& operand) { 2202 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2203 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2204 VIXL_ASSERT(allow_macro_instructions_); 2205 VIXL_ASSERT(OutsideITBlock()); 2206 MacroEmissionCheckScope guard(this); 2207 bool can_use_it = 2208 // LDRH{<c>}{<q>} <Rt>, [<Rn> {, #{+}<imm>}] ; T1 2209 (operand.IsImmediate() && rt.IsLow() && 2210 operand.GetBaseRegister().IsLow() && 2211 operand.IsOffsetImmediateWithinRange(0, 62, 2) && 2212 (operand.GetAddrMode() == Offset)) || 2213 // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>] ; T1 2214 (operand.IsPlainRegister() && rt.IsLow() && 2215 operand.GetBaseRegister().IsLow() && 2216 operand.GetOffsetRegister().IsLow() && operand.GetSign().IsPlus() && 2217 (operand.GetAddrMode() == Offset)); 2218 ITScope it_scope(this, &cond, guard, can_use_it); 2219 ldrh(cond, rt, operand); 2220 } Ldrh(Register rt,const MemOperand & operand)2221 void Ldrh(Register rt, const MemOperand& operand) { Ldrh(al, rt, operand); } 2222 2223 Ldrsb(Condition cond,Register rt,const MemOperand & operand)2224 void Ldrsb(Condition cond, Register rt, const MemOperand& operand) { 2225 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2226 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2227 VIXL_ASSERT(allow_macro_instructions_); 2228 VIXL_ASSERT(OutsideITBlock()); 2229 MacroEmissionCheckScope guard(this); 2230 bool can_use_it = 2231 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>] ; T1 2232 operand.IsPlainRegister() && rt.IsLow() && 2233 operand.GetBaseRegister().IsLow() && 2234 operand.GetOffsetRegister().IsLow() && operand.GetSign().IsPlus() && 2235 (operand.GetAddrMode() == Offset); 2236 ITScope it_scope(this, &cond, guard, can_use_it); 2237 ldrsb(cond, rt, operand); 2238 } Ldrsb(Register rt,const MemOperand & operand)2239 void Ldrsb(Register rt, const MemOperand& operand) { Ldrsb(al, rt, operand); } 2240 2241 Ldrsh(Condition cond,Register rt,const MemOperand & operand)2242 void Ldrsh(Condition cond, Register rt, const MemOperand& operand) { 2243 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2244 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2245 VIXL_ASSERT(allow_macro_instructions_); 2246 VIXL_ASSERT(OutsideITBlock()); 2247 MacroEmissionCheckScope guard(this); 2248 bool can_use_it = 2249 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>] ; T1 2250 operand.IsPlainRegister() && rt.IsLow() && 2251 operand.GetBaseRegister().IsLow() && 2252 operand.GetOffsetRegister().IsLow() && operand.GetSign().IsPlus() && 2253 (operand.GetAddrMode() == Offset); 2254 ITScope it_scope(this, &cond, guard, can_use_it); 2255 ldrsh(cond, rt, operand); 2256 } Ldrsh(Register rt,const MemOperand & operand)2257 void Ldrsh(Register rt, const MemOperand& operand) { Ldrsh(al, rt, operand); } 2258 2259 Lsl(Condition cond,Register rd,Register rm,const Operand & operand)2260 void Lsl(Condition cond, Register rd, Register rm, const Operand& operand) { 2261 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2262 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2263 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2264 VIXL_ASSERT(allow_macro_instructions_); 2265 VIXL_ASSERT(OutsideITBlock()); 2266 MacroEmissionCheckScope guard(this); 2267 bool can_use_it = 2268 // LSL<c>{<q>} {<Rd>,} <Rm>, #<imm> ; T2 2269 (operand.IsImmediate() && (operand.GetImmediate() >= 1) && 2270 (operand.GetImmediate() <= 31) && rd.IsLow() && rm.IsLow()) || 2271 // LSL<c>{<q>} {<Rdm>,} <Rdm>, <Rs> ; T1 2272 (operand.IsPlainRegister() && rd.Is(rm) && rd.IsLow() && 2273 operand.GetBaseRegister().IsLow()); 2274 ITScope it_scope(this, &cond, guard, can_use_it); 2275 lsl(cond, rd, rm, operand); 2276 } Lsl(Register rd,Register rm,const Operand & operand)2277 void Lsl(Register rd, Register rm, const Operand& operand) { 2278 Lsl(al, rd, rm, operand); 2279 } Lsl(FlagsUpdate flags,Condition cond,Register rd,Register rm,const Operand & operand)2280 void Lsl(FlagsUpdate flags, 2281 Condition cond, 2282 Register rd, 2283 Register rm, 2284 const Operand& operand) { 2285 switch (flags) { 2286 case LeaveFlags: 2287 Lsl(cond, rd, rm, operand); 2288 break; 2289 case SetFlags: 2290 Lsls(cond, rd, rm, operand); 2291 break; 2292 case DontCare: 2293 bool setflags_is_smaller = 2294 IsUsingT32() && cond.Is(al) && rd.IsLow() && rm.IsLow() && 2295 ((operand.IsImmediate() && (operand.GetImmediate() >= 1) && 2296 (operand.GetImmediate() < 32)) || 2297 (operand.IsPlainRegister() && rd.Is(rm))); 2298 if (setflags_is_smaller) { 2299 Lsls(cond, rd, rm, operand); 2300 } else { 2301 Lsl(cond, rd, rm, operand); 2302 } 2303 break; 2304 } 2305 } Lsl(FlagsUpdate flags,Register rd,Register rm,const Operand & operand)2306 void Lsl(FlagsUpdate flags, 2307 Register rd, 2308 Register rm, 2309 const Operand& operand) { 2310 Lsl(flags, al, rd, rm, operand); 2311 } 2312 Lsls(Condition cond,Register rd,Register rm,const Operand & operand)2313 void Lsls(Condition cond, Register rd, Register rm, const Operand& operand) { 2314 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2315 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2316 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2317 VIXL_ASSERT(allow_macro_instructions_); 2318 VIXL_ASSERT(OutsideITBlock()); 2319 MacroEmissionCheckScope guard(this); 2320 ITScope it_scope(this, &cond, guard); 2321 lsls(cond, rd, rm, operand); 2322 } Lsls(Register rd,Register rm,const Operand & operand)2323 void Lsls(Register rd, Register rm, const Operand& operand) { 2324 Lsls(al, rd, rm, operand); 2325 } 2326 Lsr(Condition cond,Register rd,Register rm,const Operand & operand)2327 void Lsr(Condition cond, Register rd, Register rm, const Operand& operand) { 2328 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2329 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2330 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2331 VIXL_ASSERT(allow_macro_instructions_); 2332 VIXL_ASSERT(OutsideITBlock()); 2333 MacroEmissionCheckScope guard(this); 2334 bool can_use_it = 2335 // LSR<c>{<q>} {<Rd>,} <Rm>, #<imm> ; T2 2336 (operand.IsImmediate() && (operand.GetImmediate() >= 1) && 2337 (operand.GetImmediate() <= 32) && rd.IsLow() && rm.IsLow()) || 2338 // LSR<c>{<q>} {<Rdm>,} <Rdm>, <Rs> ; T1 2339 (operand.IsPlainRegister() && rd.Is(rm) && rd.IsLow() && 2340 operand.GetBaseRegister().IsLow()); 2341 ITScope it_scope(this, &cond, guard, can_use_it); 2342 lsr(cond, rd, rm, operand); 2343 } Lsr(Register rd,Register rm,const Operand & operand)2344 void Lsr(Register rd, Register rm, const Operand& operand) { 2345 Lsr(al, rd, rm, operand); 2346 } Lsr(FlagsUpdate flags,Condition cond,Register rd,Register rm,const Operand & operand)2347 void Lsr(FlagsUpdate flags, 2348 Condition cond, 2349 Register rd, 2350 Register rm, 2351 const Operand& operand) { 2352 switch (flags) { 2353 case LeaveFlags: 2354 Lsr(cond, rd, rm, operand); 2355 break; 2356 case SetFlags: 2357 Lsrs(cond, rd, rm, operand); 2358 break; 2359 case DontCare: 2360 bool setflags_is_smaller = 2361 IsUsingT32() && cond.Is(al) && rd.IsLow() && rm.IsLow() && 2362 ((operand.IsImmediate() && (operand.GetImmediate() >= 1) && 2363 (operand.GetImmediate() <= 32)) || 2364 (operand.IsPlainRegister() && rd.Is(rm))); 2365 if (setflags_is_smaller) { 2366 Lsrs(cond, rd, rm, operand); 2367 } else { 2368 Lsr(cond, rd, rm, operand); 2369 } 2370 break; 2371 } 2372 } Lsr(FlagsUpdate flags,Register rd,Register rm,const Operand & operand)2373 void Lsr(FlagsUpdate flags, 2374 Register rd, 2375 Register rm, 2376 const Operand& operand) { 2377 Lsr(flags, al, rd, rm, operand); 2378 } 2379 Lsrs(Condition cond,Register rd,Register rm,const Operand & operand)2380 void Lsrs(Condition cond, Register rd, Register rm, const Operand& operand) { 2381 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2382 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2383 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2384 VIXL_ASSERT(allow_macro_instructions_); 2385 VIXL_ASSERT(OutsideITBlock()); 2386 MacroEmissionCheckScope guard(this); 2387 ITScope it_scope(this, &cond, guard); 2388 lsrs(cond, rd, rm, operand); 2389 } Lsrs(Register rd,Register rm,const Operand & operand)2390 void Lsrs(Register rd, Register rm, const Operand& operand) { 2391 Lsrs(al, rd, rm, operand); 2392 } 2393 Mla(Condition cond,Register rd,Register rn,Register rm,Register ra)2394 void Mla(Condition cond, Register rd, Register rn, Register rm, Register ra) { 2395 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2396 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2397 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2398 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 2399 VIXL_ASSERT(allow_macro_instructions_); 2400 VIXL_ASSERT(OutsideITBlock()); 2401 MacroEmissionCheckScope guard(this); 2402 ITScope it_scope(this, &cond, guard); 2403 mla(cond, rd, rn, rm, ra); 2404 } Mla(Register rd,Register rn,Register rm,Register ra)2405 void Mla(Register rd, Register rn, Register rm, Register ra) { 2406 Mla(al, rd, rn, rm, ra); 2407 } Mla(FlagsUpdate flags,Condition cond,Register rd,Register rn,Register rm,Register ra)2408 void Mla(FlagsUpdate flags, 2409 Condition cond, 2410 Register rd, 2411 Register rn, 2412 Register rm, 2413 Register ra) { 2414 switch (flags) { 2415 case LeaveFlags: 2416 Mla(cond, rd, rn, rm, ra); 2417 break; 2418 case SetFlags: 2419 Mlas(cond, rd, rn, rm, ra); 2420 break; 2421 case DontCare: 2422 Mla(cond, rd, rn, rm, ra); 2423 break; 2424 } 2425 } Mla(FlagsUpdate flags,Register rd,Register rn,Register rm,Register ra)2426 void Mla( 2427 FlagsUpdate flags, Register rd, Register rn, Register rm, Register ra) { 2428 Mla(flags, al, rd, rn, rm, ra); 2429 } 2430 Mlas(Condition cond,Register rd,Register rn,Register rm,Register ra)2431 void Mlas( 2432 Condition cond, Register rd, Register rn, Register rm, Register ra) { 2433 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2434 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2435 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2436 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 2437 VIXL_ASSERT(allow_macro_instructions_); 2438 VIXL_ASSERT(OutsideITBlock()); 2439 MacroEmissionCheckScope guard(this); 2440 ITScope it_scope(this, &cond, guard); 2441 mlas(cond, rd, rn, rm, ra); 2442 } Mlas(Register rd,Register rn,Register rm,Register ra)2443 void Mlas(Register rd, Register rn, Register rm, Register ra) { 2444 Mlas(al, rd, rn, rm, ra); 2445 } 2446 Mls(Condition cond,Register rd,Register rn,Register rm,Register ra)2447 void Mls(Condition cond, Register rd, Register rn, Register rm, Register ra) { 2448 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2449 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2450 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2451 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 2452 VIXL_ASSERT(allow_macro_instructions_); 2453 VIXL_ASSERT(OutsideITBlock()); 2454 MacroEmissionCheckScope guard(this); 2455 ITScope it_scope(this, &cond, guard); 2456 mls(cond, rd, rn, rm, ra); 2457 } Mls(Register rd,Register rn,Register rm,Register ra)2458 void Mls(Register rd, Register rn, Register rm, Register ra) { 2459 Mls(al, rd, rn, rm, ra); 2460 } 2461 Mov(Condition cond,Register rd,const Operand & operand)2462 void Mov(Condition cond, Register rd, const Operand& operand) { 2463 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2464 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2465 VIXL_ASSERT(allow_macro_instructions_); 2466 VIXL_ASSERT(OutsideITBlock()); 2467 MacroEmissionCheckScope guard(this); 2468 if (operand.IsPlainRegister() && rd.Is(operand.GetBaseRegister())) { 2469 return; 2470 } 2471 bool can_use_it = 2472 // MOV<c>{<q>} <Rd>, #<imm8> ; T1 2473 (operand.IsImmediate() && rd.IsLow() && 2474 (operand.GetImmediate() <= 255)) || 2475 // MOV{<c>}{<q>} <Rd>, <Rm> ; T1 2476 (operand.IsPlainRegister() && !rd.IsPC() && 2477 !operand.GetBaseRegister().IsPC()) || 2478 // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount>} ; T2 2479 (operand.IsImmediateShiftedRegister() && rd.IsLow() && 2480 operand.GetBaseRegister().IsLow() && 2481 (operand.GetShift().Is(LSL) || operand.GetShift().Is(LSR) || 2482 operand.GetShift().Is(ASR))) || 2483 // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1 2484 // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1 2485 // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1 2486 // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1 2487 (operand.IsRegisterShiftedRegister() && 2488 rd.Is(operand.GetBaseRegister()) && rd.IsLow() && 2489 (operand.GetShift().Is(LSL) || operand.GetShift().Is(LSR) || 2490 operand.GetShift().Is(ASR) || operand.GetShift().Is(ROR)) && 2491 operand.GetShiftRegister().IsLow()); 2492 ITScope it_scope(this, &cond, guard, can_use_it); 2493 mov(cond, rd, operand); 2494 } Mov(Register rd,const Operand & operand)2495 void Mov(Register rd, const Operand& operand) { Mov(al, rd, operand); } Mov(FlagsUpdate flags,Condition cond,Register rd,const Operand & operand)2496 void Mov(FlagsUpdate flags, 2497 Condition cond, 2498 Register rd, 2499 const Operand& operand) { 2500 switch (flags) { 2501 case LeaveFlags: 2502 Mov(cond, rd, operand); 2503 break; 2504 case SetFlags: 2505 Movs(cond, rd, operand); 2506 break; 2507 case DontCare: 2508 if (operand.IsPlainRegister() && rd.Is(operand.GetBaseRegister())) { 2509 return; 2510 } 2511 bool setflags_is_smaller = 2512 IsUsingT32() && cond.Is(al) && 2513 ((operand.IsImmediateShiftedRegister() && rd.IsLow() && 2514 operand.GetBaseRegister().IsLow() && 2515 (operand.GetShiftAmount() >= 1) && 2516 (((operand.GetShiftAmount() <= 32) && 2517 ((operand.GetShift().IsLSR() || operand.GetShift().IsASR()))) || 2518 ((operand.GetShiftAmount() < 32) && 2519 operand.GetShift().IsLSL()))) || 2520 (operand.IsRegisterShiftedRegister() && rd.IsLow() && 2521 operand.GetBaseRegister().Is(rd) && 2522 operand.GetShiftRegister().IsLow() && 2523 (operand.GetShift().IsLSL() || operand.GetShift().IsLSR() || 2524 operand.GetShift().IsASR() || operand.GetShift().IsROR())) || 2525 (operand.IsImmediate() && rd.IsLow() && 2526 (operand.GetImmediate() < 256))); 2527 if (setflags_is_smaller) { 2528 Movs(cond, rd, operand); 2529 } else { 2530 Mov(cond, rd, operand); 2531 } 2532 break; 2533 } 2534 } Mov(FlagsUpdate flags,Register rd,const Operand & operand)2535 void Mov(FlagsUpdate flags, Register rd, const Operand& operand) { 2536 Mov(flags, al, rd, operand); 2537 } 2538 Movs(Condition cond,Register rd,const Operand & operand)2539 void Movs(Condition cond, Register rd, const Operand& operand) { 2540 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2541 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2542 VIXL_ASSERT(allow_macro_instructions_); 2543 VIXL_ASSERT(OutsideITBlock()); 2544 MacroEmissionCheckScope guard(this); 2545 ITScope it_scope(this, &cond, guard); 2546 movs(cond, rd, operand); 2547 } Movs(Register rd,const Operand & operand)2548 void Movs(Register rd, const Operand& operand) { Movs(al, rd, operand); } 2549 Movt(Condition cond,Register rd,const Operand & operand)2550 void Movt(Condition cond, Register rd, const Operand& operand) { 2551 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2552 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2553 VIXL_ASSERT(allow_macro_instructions_); 2554 VIXL_ASSERT(OutsideITBlock()); 2555 MacroEmissionCheckScope guard(this); 2556 ITScope it_scope(this, &cond, guard); 2557 movt(cond, rd, operand); 2558 } Movt(Register rd,const Operand & operand)2559 void Movt(Register rd, const Operand& operand) { Movt(al, rd, operand); } 2560 Mrs(Condition cond,Register rd,SpecialRegister spec_reg)2561 void Mrs(Condition cond, Register rd, SpecialRegister spec_reg) { 2562 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2563 VIXL_ASSERT(allow_macro_instructions_); 2564 VIXL_ASSERT(OutsideITBlock()); 2565 MacroEmissionCheckScope guard(this); 2566 ITScope it_scope(this, &cond, guard); 2567 mrs(cond, rd, spec_reg); 2568 } Mrs(Register rd,SpecialRegister spec_reg)2569 void Mrs(Register rd, SpecialRegister spec_reg) { Mrs(al, rd, spec_reg); } 2570 Msr(Condition cond,MaskedSpecialRegister spec_reg,const Operand & operand)2571 void Msr(Condition cond, 2572 MaskedSpecialRegister spec_reg, 2573 const Operand& operand) { 2574 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2575 VIXL_ASSERT(allow_macro_instructions_); 2576 VIXL_ASSERT(OutsideITBlock()); 2577 MacroEmissionCheckScope guard(this); 2578 ITScope it_scope(this, &cond, guard); 2579 msr(cond, spec_reg, operand); 2580 } Msr(MaskedSpecialRegister spec_reg,const Operand & operand)2581 void Msr(MaskedSpecialRegister spec_reg, const Operand& operand) { 2582 Msr(al, spec_reg, operand); 2583 } 2584 Mul(Condition cond,Register rd,Register rn,Register rm)2585 void Mul(Condition cond, Register rd, Register rn, Register rm) { 2586 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2587 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2588 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2589 VIXL_ASSERT(allow_macro_instructions_); 2590 VIXL_ASSERT(OutsideITBlock()); 2591 MacroEmissionCheckScope guard(this); 2592 bool can_use_it = 2593 // MUL<c>{<q>} <Rdm>, <Rn>{, <Rdm>} ; T1 2594 rd.Is(rm) && rn.IsLow() && rm.IsLow(); 2595 ITScope it_scope(this, &cond, guard, can_use_it); 2596 mul(cond, rd, rn, rm); 2597 } Mul(Register rd,Register rn,Register rm)2598 void Mul(Register rd, Register rn, Register rm) { Mul(al, rd, rn, rm); } Mul(FlagsUpdate flags,Condition cond,Register rd,Register rn,Register rm)2599 void Mul(FlagsUpdate flags, 2600 Condition cond, 2601 Register rd, 2602 Register rn, 2603 Register rm) { 2604 switch (flags) { 2605 case LeaveFlags: 2606 Mul(cond, rd, rn, rm); 2607 break; 2608 case SetFlags: 2609 Muls(cond, rd, rn, rm); 2610 break; 2611 case DontCare: 2612 bool setflags_is_smaller = IsUsingT32() && cond.Is(al) && rd.IsLow() && 2613 rn.IsLow() && rm.Is(rd); 2614 if (setflags_is_smaller) { 2615 Muls(cond, rd, rn, rm); 2616 } else { 2617 Mul(cond, rd, rn, rm); 2618 } 2619 break; 2620 } 2621 } Mul(FlagsUpdate flags,Register rd,Register rn,Register rm)2622 void Mul(FlagsUpdate flags, Register rd, Register rn, Register rm) { 2623 Mul(flags, al, rd, rn, rm); 2624 } 2625 Muls(Condition cond,Register rd,Register rn,Register rm)2626 void Muls(Condition cond, Register rd, Register rn, Register rm) { 2627 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2628 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2629 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2630 VIXL_ASSERT(allow_macro_instructions_); 2631 VIXL_ASSERT(OutsideITBlock()); 2632 MacroEmissionCheckScope guard(this); 2633 ITScope it_scope(this, &cond, guard); 2634 muls(cond, rd, rn, rm); 2635 } Muls(Register rd,Register rn,Register rm)2636 void Muls(Register rd, Register rn, Register rm) { Muls(al, rd, rn, rm); } 2637 Mvn(Condition cond,Register rd,const Operand & operand)2638 void Mvn(Condition cond, Register rd, const Operand& operand) { 2639 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2640 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2641 VIXL_ASSERT(allow_macro_instructions_); 2642 VIXL_ASSERT(OutsideITBlock()); 2643 MacroEmissionCheckScope guard(this); 2644 bool can_use_it = 2645 // MVN<c>{<q>} <Rd>, <Rm> ; T1 2646 operand.IsPlainRegister() && rd.IsLow() && 2647 operand.GetBaseRegister().IsLow(); 2648 ITScope it_scope(this, &cond, guard, can_use_it); 2649 mvn(cond, rd, operand); 2650 } Mvn(Register rd,const Operand & operand)2651 void Mvn(Register rd, const Operand& operand) { Mvn(al, rd, operand); } Mvn(FlagsUpdate flags,Condition cond,Register rd,const Operand & operand)2652 void Mvn(FlagsUpdate flags, 2653 Condition cond, 2654 Register rd, 2655 const Operand& operand) { 2656 switch (flags) { 2657 case LeaveFlags: 2658 Mvn(cond, rd, operand); 2659 break; 2660 case SetFlags: 2661 Mvns(cond, rd, operand); 2662 break; 2663 case DontCare: 2664 bool setflags_is_smaller = IsUsingT32() && cond.Is(al) && rd.IsLow() && 2665 operand.IsPlainRegister() && 2666 operand.GetBaseRegister().IsLow(); 2667 if (setflags_is_smaller) { 2668 Mvns(cond, rd, operand); 2669 } else { 2670 Mvn(cond, rd, operand); 2671 } 2672 break; 2673 } 2674 } Mvn(FlagsUpdate flags,Register rd,const Operand & operand)2675 void Mvn(FlagsUpdate flags, Register rd, const Operand& operand) { 2676 Mvn(flags, al, rd, operand); 2677 } 2678 Mvns(Condition cond,Register rd,const Operand & operand)2679 void Mvns(Condition cond, Register rd, const Operand& operand) { 2680 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2681 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2682 VIXL_ASSERT(allow_macro_instructions_); 2683 VIXL_ASSERT(OutsideITBlock()); 2684 MacroEmissionCheckScope guard(this); 2685 ITScope it_scope(this, &cond, guard); 2686 mvns(cond, rd, operand); 2687 } Mvns(Register rd,const Operand & operand)2688 void Mvns(Register rd, const Operand& operand) { Mvns(al, rd, operand); } 2689 Nop(Condition cond)2690 void Nop(Condition cond) { 2691 VIXL_ASSERT(allow_macro_instructions_); 2692 VIXL_ASSERT(OutsideITBlock()); 2693 MacroEmissionCheckScope guard(this); 2694 ITScope it_scope(this, &cond, guard); 2695 nop(cond); 2696 } Nop()2697 void Nop() { Nop(al); } 2698 Orn(Condition cond,Register rd,Register rn,const Operand & operand)2699 void Orn(Condition cond, Register rd, Register rn, const Operand& operand) { 2700 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2701 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2702 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2703 VIXL_ASSERT(allow_macro_instructions_); 2704 VIXL_ASSERT(OutsideITBlock()); 2705 MacroEmissionCheckScope guard(this); 2706 if (cond.Is(al) && operand.IsImmediate()) { 2707 uint32_t immediate = operand.GetImmediate(); 2708 if (immediate == 0) { 2709 mvn(rd, 0); 2710 return; 2711 } 2712 if ((immediate == 0xffffffff) && rd.Is(rn)) { 2713 return; 2714 } 2715 } 2716 ITScope it_scope(this, &cond, guard); 2717 orn(cond, rd, rn, operand); 2718 } Orn(Register rd,Register rn,const Operand & operand)2719 void Orn(Register rd, Register rn, const Operand& operand) { 2720 Orn(al, rd, rn, operand); 2721 } Orn(FlagsUpdate flags,Condition cond,Register rd,Register rn,const Operand & operand)2722 void Orn(FlagsUpdate flags, 2723 Condition cond, 2724 Register rd, 2725 Register rn, 2726 const Operand& operand) { 2727 switch (flags) { 2728 case LeaveFlags: 2729 Orn(cond, rd, rn, operand); 2730 break; 2731 case SetFlags: 2732 Orns(cond, rd, rn, operand); 2733 break; 2734 case DontCare: 2735 Orn(cond, rd, rn, operand); 2736 break; 2737 } 2738 } Orn(FlagsUpdate flags,Register rd,Register rn,const Operand & operand)2739 void Orn(FlagsUpdate flags, 2740 Register rd, 2741 Register rn, 2742 const Operand& operand) { 2743 Orn(flags, al, rd, rn, operand); 2744 } 2745 Orns(Condition cond,Register rd,Register rn,const Operand & operand)2746 void Orns(Condition cond, Register rd, Register rn, const Operand& operand) { 2747 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2748 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2749 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2750 VIXL_ASSERT(allow_macro_instructions_); 2751 VIXL_ASSERT(OutsideITBlock()); 2752 MacroEmissionCheckScope guard(this); 2753 ITScope it_scope(this, &cond, guard); 2754 orns(cond, rd, rn, operand); 2755 } Orns(Register rd,Register rn,const Operand & operand)2756 void Orns(Register rd, Register rn, const Operand& operand) { 2757 Orns(al, rd, rn, operand); 2758 } 2759 Orr(Condition cond,Register rd,Register rn,const Operand & operand)2760 void Orr(Condition cond, Register rd, Register rn, const Operand& operand) { 2761 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2762 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2763 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2764 VIXL_ASSERT(allow_macro_instructions_); 2765 VIXL_ASSERT(OutsideITBlock()); 2766 MacroEmissionCheckScope guard(this); 2767 if (rd.Is(rn) && operand.IsPlainRegister() && 2768 rd.Is(operand.GetBaseRegister())) { 2769 return; 2770 } 2771 if (cond.Is(al) && operand.IsImmediate()) { 2772 uint32_t immediate = operand.GetImmediate(); 2773 if ((immediate == 0) && rd.Is(rn)) { 2774 return; 2775 } 2776 if (immediate == 0xffffffff) { 2777 mvn(rd, 0); 2778 return; 2779 } 2780 } 2781 bool can_use_it = 2782 // ORR<c>{<q>} {<Rdn>,} <Rdn>, <Rm> ; T1 2783 operand.IsPlainRegister() && rd.Is(rn) && rn.IsLow() && 2784 operand.GetBaseRegister().IsLow(); 2785 ITScope it_scope(this, &cond, guard, can_use_it); 2786 orr(cond, rd, rn, operand); 2787 } Orr(Register rd,Register rn,const Operand & operand)2788 void Orr(Register rd, Register rn, const Operand& operand) { 2789 Orr(al, rd, rn, operand); 2790 } Orr(FlagsUpdate flags,Condition cond,Register rd,Register rn,const Operand & operand)2791 void Orr(FlagsUpdate flags, 2792 Condition cond, 2793 Register rd, 2794 Register rn, 2795 const Operand& operand) { 2796 switch (flags) { 2797 case LeaveFlags: 2798 Orr(cond, rd, rn, operand); 2799 break; 2800 case SetFlags: 2801 Orrs(cond, rd, rn, operand); 2802 break; 2803 case DontCare: 2804 if (operand.IsPlainRegister() && rd.Is(rn) && 2805 rd.Is(operand.GetBaseRegister())) { 2806 return; 2807 } 2808 bool setflags_is_smaller = IsUsingT32() && cond.Is(al) && rd.IsLow() && 2809 rn.Is(rd) && operand.IsPlainRegister() && 2810 operand.GetBaseRegister().IsLow(); 2811 if (setflags_is_smaller) { 2812 Orrs(cond, rd, rn, operand); 2813 } else { 2814 Orr(cond, rd, rn, operand); 2815 } 2816 break; 2817 } 2818 } Orr(FlagsUpdate flags,Register rd,Register rn,const Operand & operand)2819 void Orr(FlagsUpdate flags, 2820 Register rd, 2821 Register rn, 2822 const Operand& operand) { 2823 Orr(flags, al, rd, rn, operand); 2824 } 2825 Orrs(Condition cond,Register rd,Register rn,const Operand & operand)2826 void Orrs(Condition cond, Register rd, Register rn, const Operand& operand) { 2827 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2828 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2829 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2830 VIXL_ASSERT(allow_macro_instructions_); 2831 VIXL_ASSERT(OutsideITBlock()); 2832 MacroEmissionCheckScope guard(this); 2833 ITScope it_scope(this, &cond, guard); 2834 orrs(cond, rd, rn, operand); 2835 } Orrs(Register rd,Register rn,const Operand & operand)2836 void Orrs(Register rd, Register rn, const Operand& operand) { 2837 Orrs(al, rd, rn, operand); 2838 } 2839 Pkhbt(Condition cond,Register rd,Register rn,const Operand & operand)2840 void Pkhbt(Condition cond, Register rd, Register rn, const Operand& operand) { 2841 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2842 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2843 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2844 VIXL_ASSERT(allow_macro_instructions_); 2845 VIXL_ASSERT(OutsideITBlock()); 2846 MacroEmissionCheckScope guard(this); 2847 ITScope it_scope(this, &cond, guard); 2848 pkhbt(cond, rd, rn, operand); 2849 } Pkhbt(Register rd,Register rn,const Operand & operand)2850 void Pkhbt(Register rd, Register rn, const Operand& operand) { 2851 Pkhbt(al, rd, rn, operand); 2852 } 2853 Pkhtb(Condition cond,Register rd,Register rn,const Operand & operand)2854 void Pkhtb(Condition cond, Register rd, Register rn, const Operand& operand) { 2855 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2856 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2857 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2858 VIXL_ASSERT(allow_macro_instructions_); 2859 VIXL_ASSERT(OutsideITBlock()); 2860 MacroEmissionCheckScope guard(this); 2861 ITScope it_scope(this, &cond, guard); 2862 pkhtb(cond, rd, rn, operand); 2863 } Pkhtb(Register rd,Register rn,const Operand & operand)2864 void Pkhtb(Register rd, Register rn, const Operand& operand) { 2865 Pkhtb(al, rd, rn, operand); 2866 } 2867 2868 Pld(Condition cond,const MemOperand & operand)2869 void Pld(Condition cond, const MemOperand& operand) { 2870 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2871 VIXL_ASSERT(allow_macro_instructions_); 2872 VIXL_ASSERT(OutsideITBlock()); 2873 MacroEmissionCheckScope guard(this); 2874 ITScope it_scope(this, &cond, guard); 2875 pld(cond, operand); 2876 } Pld(const MemOperand & operand)2877 void Pld(const MemOperand& operand) { Pld(al, operand); } 2878 Pldw(Condition cond,const MemOperand & operand)2879 void Pldw(Condition cond, const MemOperand& operand) { 2880 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2881 VIXL_ASSERT(allow_macro_instructions_); 2882 VIXL_ASSERT(OutsideITBlock()); 2883 MacroEmissionCheckScope guard(this); 2884 ITScope it_scope(this, &cond, guard); 2885 pldw(cond, operand); 2886 } Pldw(const MemOperand & operand)2887 void Pldw(const MemOperand& operand) { Pldw(al, operand); } 2888 Pli(Condition cond,const MemOperand & operand)2889 void Pli(Condition cond, const MemOperand& operand) { 2890 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 2891 VIXL_ASSERT(allow_macro_instructions_); 2892 VIXL_ASSERT(OutsideITBlock()); 2893 MacroEmissionCheckScope guard(this); 2894 ITScope it_scope(this, &cond, guard); 2895 pli(cond, operand); 2896 } Pli(const MemOperand & operand)2897 void Pli(const MemOperand& operand) { Pli(al, operand); } 2898 2899 Pop(Condition cond,RegisterList registers)2900 void Pop(Condition cond, RegisterList registers) { 2901 VIXL_ASSERT(!AliasesAvailableScratchRegister(registers)); 2902 VIXL_ASSERT(allow_macro_instructions_); 2903 VIXL_ASSERT(OutsideITBlock()); 2904 MacroEmissionCheckScope guard(this); 2905 ITScope it_scope(this, &cond, guard); 2906 if (registers.IsSingleRegister() && 2907 (!IsUsingT32() || !registers.IsR0toR7orPC())) { 2908 pop(cond, registers.GetFirstAvailableRegister()); 2909 } else if (!registers.IsEmpty()) { 2910 pop(cond, registers); 2911 } 2912 } Pop(RegisterList registers)2913 void Pop(RegisterList registers) { Pop(al, registers); } 2914 Pop(Condition cond,Register rt)2915 void Pop(Condition cond, Register rt) { 2916 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2917 VIXL_ASSERT(allow_macro_instructions_); 2918 VIXL_ASSERT(OutsideITBlock()); 2919 MacroEmissionCheckScope guard(this); 2920 ITScope it_scope(this, &cond, guard); 2921 pop(cond, rt); 2922 } Pop(Register rt)2923 void Pop(Register rt) { Pop(al, rt); } 2924 Push(Condition cond,RegisterList registers)2925 void Push(Condition cond, RegisterList registers) { 2926 VIXL_ASSERT(!AliasesAvailableScratchRegister(registers)); 2927 VIXL_ASSERT(allow_macro_instructions_); 2928 VIXL_ASSERT(OutsideITBlock()); 2929 MacroEmissionCheckScope guard(this); 2930 ITScope it_scope(this, &cond, guard); 2931 if (registers.IsSingleRegister() && !registers.Includes(sp) && 2932 (!IsUsingT32() || !registers.IsR0toR7orLR())) { 2933 push(cond, registers.GetFirstAvailableRegister()); 2934 } else if (!registers.IsEmpty()) { 2935 push(cond, registers); 2936 } 2937 } Push(RegisterList registers)2938 void Push(RegisterList registers) { Push(al, registers); } 2939 Push(Condition cond,Register rt)2940 void Push(Condition cond, Register rt) { 2941 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 2942 VIXL_ASSERT(allow_macro_instructions_); 2943 VIXL_ASSERT(OutsideITBlock()); 2944 MacroEmissionCheckScope guard(this); 2945 ITScope it_scope(this, &cond, guard); 2946 if (IsUsingA32() && rt.IsSP()) { 2947 // Only the A32 multiple-register form can push sp. 2948 push(cond, RegisterList(rt)); 2949 } else { 2950 push(cond, rt); 2951 } 2952 } Push(Register rt)2953 void Push(Register rt) { Push(al, rt); } 2954 Qadd(Condition cond,Register rd,Register rm,Register rn)2955 void Qadd(Condition cond, Register rd, Register rm, Register rn) { 2956 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2957 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2958 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2959 VIXL_ASSERT(allow_macro_instructions_); 2960 VIXL_ASSERT(OutsideITBlock()); 2961 MacroEmissionCheckScope guard(this); 2962 ITScope it_scope(this, &cond, guard); 2963 qadd(cond, rd, rm, rn); 2964 } Qadd(Register rd,Register rm,Register rn)2965 void Qadd(Register rd, Register rm, Register rn) { Qadd(al, rd, rm, rn); } 2966 Qadd16(Condition cond,Register rd,Register rn,Register rm)2967 void Qadd16(Condition cond, Register rd, Register rn, Register rm) { 2968 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2969 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2970 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2971 VIXL_ASSERT(allow_macro_instructions_); 2972 VIXL_ASSERT(OutsideITBlock()); 2973 MacroEmissionCheckScope guard(this); 2974 ITScope it_scope(this, &cond, guard); 2975 qadd16(cond, rd, rn, rm); 2976 } Qadd16(Register rd,Register rn,Register rm)2977 void Qadd16(Register rd, Register rn, Register rm) { Qadd16(al, rd, rn, rm); } 2978 Qadd8(Condition cond,Register rd,Register rn,Register rm)2979 void Qadd8(Condition cond, Register rd, Register rn, Register rm) { 2980 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2981 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2982 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2983 VIXL_ASSERT(allow_macro_instructions_); 2984 VIXL_ASSERT(OutsideITBlock()); 2985 MacroEmissionCheckScope guard(this); 2986 ITScope it_scope(this, &cond, guard); 2987 qadd8(cond, rd, rn, rm); 2988 } Qadd8(Register rd,Register rn,Register rm)2989 void Qadd8(Register rd, Register rn, Register rm) { Qadd8(al, rd, rn, rm); } 2990 Qasx(Condition cond,Register rd,Register rn,Register rm)2991 void Qasx(Condition cond, Register rd, Register rn, Register rm) { 2992 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 2993 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 2994 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 2995 VIXL_ASSERT(allow_macro_instructions_); 2996 VIXL_ASSERT(OutsideITBlock()); 2997 MacroEmissionCheckScope guard(this); 2998 ITScope it_scope(this, &cond, guard); 2999 qasx(cond, rd, rn, rm); 3000 } Qasx(Register rd,Register rn,Register rm)3001 void Qasx(Register rd, Register rn, Register rm) { Qasx(al, rd, rn, rm); } 3002 Qdadd(Condition cond,Register rd,Register rm,Register rn)3003 void Qdadd(Condition cond, Register rd, Register rm, Register rn) { 3004 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3005 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3006 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3007 VIXL_ASSERT(allow_macro_instructions_); 3008 VIXL_ASSERT(OutsideITBlock()); 3009 MacroEmissionCheckScope guard(this); 3010 ITScope it_scope(this, &cond, guard); 3011 qdadd(cond, rd, rm, rn); 3012 } Qdadd(Register rd,Register rm,Register rn)3013 void Qdadd(Register rd, Register rm, Register rn) { Qdadd(al, rd, rm, rn); } 3014 Qdsub(Condition cond,Register rd,Register rm,Register rn)3015 void Qdsub(Condition cond, Register rd, Register rm, Register rn) { 3016 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3017 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3018 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3019 VIXL_ASSERT(allow_macro_instructions_); 3020 VIXL_ASSERT(OutsideITBlock()); 3021 MacroEmissionCheckScope guard(this); 3022 ITScope it_scope(this, &cond, guard); 3023 qdsub(cond, rd, rm, rn); 3024 } Qdsub(Register rd,Register rm,Register rn)3025 void Qdsub(Register rd, Register rm, Register rn) { Qdsub(al, rd, rm, rn); } 3026 Qsax(Condition cond,Register rd,Register rn,Register rm)3027 void Qsax(Condition cond, Register rd, Register rn, Register rm) { 3028 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3029 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3030 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3031 VIXL_ASSERT(allow_macro_instructions_); 3032 VIXL_ASSERT(OutsideITBlock()); 3033 MacroEmissionCheckScope guard(this); 3034 ITScope it_scope(this, &cond, guard); 3035 qsax(cond, rd, rn, rm); 3036 } Qsax(Register rd,Register rn,Register rm)3037 void Qsax(Register rd, Register rn, Register rm) { Qsax(al, rd, rn, rm); } 3038 Qsub(Condition cond,Register rd,Register rm,Register rn)3039 void Qsub(Condition cond, Register rd, Register rm, Register rn) { 3040 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3041 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3042 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3043 VIXL_ASSERT(allow_macro_instructions_); 3044 VIXL_ASSERT(OutsideITBlock()); 3045 MacroEmissionCheckScope guard(this); 3046 ITScope it_scope(this, &cond, guard); 3047 qsub(cond, rd, rm, rn); 3048 } Qsub(Register rd,Register rm,Register rn)3049 void Qsub(Register rd, Register rm, Register rn) { Qsub(al, rd, rm, rn); } 3050 Qsub16(Condition cond,Register rd,Register rn,Register rm)3051 void Qsub16(Condition cond, Register rd, Register rn, Register rm) { 3052 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3053 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3054 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3055 VIXL_ASSERT(allow_macro_instructions_); 3056 VIXL_ASSERT(OutsideITBlock()); 3057 MacroEmissionCheckScope guard(this); 3058 ITScope it_scope(this, &cond, guard); 3059 qsub16(cond, rd, rn, rm); 3060 } Qsub16(Register rd,Register rn,Register rm)3061 void Qsub16(Register rd, Register rn, Register rm) { Qsub16(al, rd, rn, rm); } 3062 Qsub8(Condition cond,Register rd,Register rn,Register rm)3063 void Qsub8(Condition cond, Register rd, Register rn, Register rm) { 3064 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3065 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3066 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3067 VIXL_ASSERT(allow_macro_instructions_); 3068 VIXL_ASSERT(OutsideITBlock()); 3069 MacroEmissionCheckScope guard(this); 3070 ITScope it_scope(this, &cond, guard); 3071 qsub8(cond, rd, rn, rm); 3072 } Qsub8(Register rd,Register rn,Register rm)3073 void Qsub8(Register rd, Register rn, Register rm) { Qsub8(al, rd, rn, rm); } 3074 Rbit(Condition cond,Register rd,Register rm)3075 void Rbit(Condition cond, Register rd, Register rm) { 3076 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3077 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3078 VIXL_ASSERT(allow_macro_instructions_); 3079 VIXL_ASSERT(OutsideITBlock()); 3080 MacroEmissionCheckScope guard(this); 3081 ITScope it_scope(this, &cond, guard); 3082 rbit(cond, rd, rm); 3083 } Rbit(Register rd,Register rm)3084 void Rbit(Register rd, Register rm) { Rbit(al, rd, rm); } 3085 Rev(Condition cond,Register rd,Register rm)3086 void Rev(Condition cond, Register rd, Register rm) { 3087 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3088 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3089 VIXL_ASSERT(allow_macro_instructions_); 3090 VIXL_ASSERT(OutsideITBlock()); 3091 MacroEmissionCheckScope guard(this); 3092 ITScope it_scope(this, &cond, guard); 3093 rev(cond, rd, rm); 3094 } Rev(Register rd,Register rm)3095 void Rev(Register rd, Register rm) { Rev(al, rd, rm); } 3096 Rev16(Condition cond,Register rd,Register rm)3097 void Rev16(Condition cond, Register rd, Register rm) { 3098 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3099 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3100 VIXL_ASSERT(allow_macro_instructions_); 3101 VIXL_ASSERT(OutsideITBlock()); 3102 MacroEmissionCheckScope guard(this); 3103 ITScope it_scope(this, &cond, guard); 3104 rev16(cond, rd, rm); 3105 } Rev16(Register rd,Register rm)3106 void Rev16(Register rd, Register rm) { Rev16(al, rd, rm); } 3107 Revsh(Condition cond,Register rd,Register rm)3108 void Revsh(Condition cond, Register rd, Register rm) { 3109 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3110 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3111 VIXL_ASSERT(allow_macro_instructions_); 3112 VIXL_ASSERT(OutsideITBlock()); 3113 MacroEmissionCheckScope guard(this); 3114 ITScope it_scope(this, &cond, guard); 3115 revsh(cond, rd, rm); 3116 } Revsh(Register rd,Register rm)3117 void Revsh(Register rd, Register rm) { Revsh(al, rd, rm); } 3118 Ror(Condition cond,Register rd,Register rm,const Operand & operand)3119 void Ror(Condition cond, Register rd, Register rm, const Operand& operand) { 3120 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3121 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3122 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 3123 VIXL_ASSERT(allow_macro_instructions_); 3124 VIXL_ASSERT(OutsideITBlock()); 3125 MacroEmissionCheckScope guard(this); 3126 bool can_use_it = 3127 // ROR<c>{<q>} {<Rdm>,} <Rdm>, <Rs> ; T1 3128 operand.IsPlainRegister() && rd.Is(rm) && rd.IsLow() && 3129 operand.GetBaseRegister().IsLow(); 3130 ITScope it_scope(this, &cond, guard, can_use_it); 3131 ror(cond, rd, rm, operand); 3132 } Ror(Register rd,Register rm,const Operand & operand)3133 void Ror(Register rd, Register rm, const Operand& operand) { 3134 Ror(al, rd, rm, operand); 3135 } Ror(FlagsUpdate flags,Condition cond,Register rd,Register rm,const Operand & operand)3136 void Ror(FlagsUpdate flags, 3137 Condition cond, 3138 Register rd, 3139 Register rm, 3140 const Operand& operand) { 3141 switch (flags) { 3142 case LeaveFlags: 3143 Ror(cond, rd, rm, operand); 3144 break; 3145 case SetFlags: 3146 Rors(cond, rd, rm, operand); 3147 break; 3148 case DontCare: 3149 bool setflags_is_smaller = IsUsingT32() && cond.Is(al) && rd.IsLow() && 3150 rm.IsLow() && operand.IsPlainRegister() && 3151 rd.Is(rm); 3152 if (setflags_is_smaller) { 3153 Rors(cond, rd, rm, operand); 3154 } else { 3155 Ror(cond, rd, rm, operand); 3156 } 3157 break; 3158 } 3159 } Ror(FlagsUpdate flags,Register rd,Register rm,const Operand & operand)3160 void Ror(FlagsUpdate flags, 3161 Register rd, 3162 Register rm, 3163 const Operand& operand) { 3164 Ror(flags, al, rd, rm, operand); 3165 } 3166 Rors(Condition cond,Register rd,Register rm,const Operand & operand)3167 void Rors(Condition cond, Register rd, Register rm, const Operand& operand) { 3168 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3169 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3170 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 3171 VIXL_ASSERT(allow_macro_instructions_); 3172 VIXL_ASSERT(OutsideITBlock()); 3173 MacroEmissionCheckScope guard(this); 3174 ITScope it_scope(this, &cond, guard); 3175 rors(cond, rd, rm, operand); 3176 } Rors(Register rd,Register rm,const Operand & operand)3177 void Rors(Register rd, Register rm, const Operand& operand) { 3178 Rors(al, rd, rm, operand); 3179 } 3180 Rrx(Condition cond,Register rd,Register rm)3181 void Rrx(Condition cond, Register rd, Register rm) { 3182 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3183 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3184 VIXL_ASSERT(allow_macro_instructions_); 3185 VIXL_ASSERT(OutsideITBlock()); 3186 MacroEmissionCheckScope guard(this); 3187 ITScope it_scope(this, &cond, guard); 3188 rrx(cond, rd, rm); 3189 } Rrx(Register rd,Register rm)3190 void Rrx(Register rd, Register rm) { Rrx(al, rd, rm); } Rrx(FlagsUpdate flags,Condition cond,Register rd,Register rm)3191 void Rrx(FlagsUpdate flags, Condition cond, Register rd, Register rm) { 3192 switch (flags) { 3193 case LeaveFlags: 3194 Rrx(cond, rd, rm); 3195 break; 3196 case SetFlags: 3197 Rrxs(cond, rd, rm); 3198 break; 3199 case DontCare: 3200 Rrx(cond, rd, rm); 3201 break; 3202 } 3203 } Rrx(FlagsUpdate flags,Register rd,Register rm)3204 void Rrx(FlagsUpdate flags, Register rd, Register rm) { 3205 Rrx(flags, al, rd, rm); 3206 } 3207 Rrxs(Condition cond,Register rd,Register rm)3208 void Rrxs(Condition cond, Register rd, Register rm) { 3209 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3210 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3211 VIXL_ASSERT(allow_macro_instructions_); 3212 VIXL_ASSERT(OutsideITBlock()); 3213 MacroEmissionCheckScope guard(this); 3214 ITScope it_scope(this, &cond, guard); 3215 rrxs(cond, rd, rm); 3216 } Rrxs(Register rd,Register rm)3217 void Rrxs(Register rd, Register rm) { Rrxs(al, rd, rm); } 3218 Rsb(Condition cond,Register rd,Register rn,const Operand & operand)3219 void Rsb(Condition cond, Register rd, Register rn, const Operand& operand) { 3220 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3221 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3222 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 3223 VIXL_ASSERT(allow_macro_instructions_); 3224 VIXL_ASSERT(OutsideITBlock()); 3225 MacroEmissionCheckScope guard(this); 3226 bool can_use_it = 3227 // RSB<c>{<q>} {<Rd>, }<Rn>, #0 ; T1 3228 operand.IsImmediate() && rd.IsLow() && rn.IsLow() && 3229 (operand.GetImmediate() == 0); 3230 ITScope it_scope(this, &cond, guard, can_use_it); 3231 rsb(cond, rd, rn, operand); 3232 } Rsb(Register rd,Register rn,const Operand & operand)3233 void Rsb(Register rd, Register rn, const Operand& operand) { 3234 Rsb(al, rd, rn, operand); 3235 } Rsb(FlagsUpdate flags,Condition cond,Register rd,Register rn,const Operand & operand)3236 void Rsb(FlagsUpdate flags, 3237 Condition cond, 3238 Register rd, 3239 Register rn, 3240 const Operand& operand) { 3241 switch (flags) { 3242 case LeaveFlags: 3243 Rsb(cond, rd, rn, operand); 3244 break; 3245 case SetFlags: 3246 Rsbs(cond, rd, rn, operand); 3247 break; 3248 case DontCare: 3249 bool setflags_is_smaller = IsUsingT32() && cond.Is(al) && rd.IsLow() && 3250 rn.IsLow() && operand.IsImmediate() && 3251 (operand.GetImmediate() == 0); 3252 if (setflags_is_smaller) { 3253 Rsbs(cond, rd, rn, operand); 3254 } else { 3255 Rsb(cond, rd, rn, operand); 3256 } 3257 break; 3258 } 3259 } Rsb(FlagsUpdate flags,Register rd,Register rn,const Operand & operand)3260 void Rsb(FlagsUpdate flags, 3261 Register rd, 3262 Register rn, 3263 const Operand& operand) { 3264 Rsb(flags, al, rd, rn, operand); 3265 } 3266 Rsbs(Condition cond,Register rd,Register rn,const Operand & operand)3267 void Rsbs(Condition cond, Register rd, Register rn, const Operand& operand) { 3268 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3269 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3270 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 3271 VIXL_ASSERT(allow_macro_instructions_); 3272 VIXL_ASSERT(OutsideITBlock()); 3273 MacroEmissionCheckScope guard(this); 3274 ITScope it_scope(this, &cond, guard); 3275 rsbs(cond, rd, rn, operand); 3276 } Rsbs(Register rd,Register rn,const Operand & operand)3277 void Rsbs(Register rd, Register rn, const Operand& operand) { 3278 Rsbs(al, rd, rn, operand); 3279 } 3280 Rsc(Condition cond,Register rd,Register rn,const Operand & operand)3281 void Rsc(Condition cond, Register rd, Register rn, const Operand& operand) { 3282 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3283 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3284 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 3285 VIXL_ASSERT(allow_macro_instructions_); 3286 VIXL_ASSERT(OutsideITBlock()); 3287 MacroEmissionCheckScope guard(this); 3288 ITScope it_scope(this, &cond, guard); 3289 rsc(cond, rd, rn, operand); 3290 } Rsc(Register rd,Register rn,const Operand & operand)3291 void Rsc(Register rd, Register rn, const Operand& operand) { 3292 Rsc(al, rd, rn, operand); 3293 } Rsc(FlagsUpdate flags,Condition cond,Register rd,Register rn,const Operand & operand)3294 void Rsc(FlagsUpdate flags, 3295 Condition cond, 3296 Register rd, 3297 Register rn, 3298 const Operand& operand) { 3299 switch (flags) { 3300 case LeaveFlags: 3301 Rsc(cond, rd, rn, operand); 3302 break; 3303 case SetFlags: 3304 Rscs(cond, rd, rn, operand); 3305 break; 3306 case DontCare: 3307 Rsc(cond, rd, rn, operand); 3308 break; 3309 } 3310 } Rsc(FlagsUpdate flags,Register rd,Register rn,const Operand & operand)3311 void Rsc(FlagsUpdate flags, 3312 Register rd, 3313 Register rn, 3314 const Operand& operand) { 3315 Rsc(flags, al, rd, rn, operand); 3316 } 3317 Rscs(Condition cond,Register rd,Register rn,const Operand & operand)3318 void Rscs(Condition cond, Register rd, Register rn, const Operand& operand) { 3319 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3320 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3321 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 3322 VIXL_ASSERT(allow_macro_instructions_); 3323 VIXL_ASSERT(OutsideITBlock()); 3324 MacroEmissionCheckScope guard(this); 3325 ITScope it_scope(this, &cond, guard); 3326 rscs(cond, rd, rn, operand); 3327 } Rscs(Register rd,Register rn,const Operand & operand)3328 void Rscs(Register rd, Register rn, const Operand& operand) { 3329 Rscs(al, rd, rn, operand); 3330 } 3331 Sadd16(Condition cond,Register rd,Register rn,Register rm)3332 void Sadd16(Condition cond, Register rd, Register rn, Register rm) { 3333 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3334 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3335 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3336 VIXL_ASSERT(allow_macro_instructions_); 3337 VIXL_ASSERT(OutsideITBlock()); 3338 MacroEmissionCheckScope guard(this); 3339 ITScope it_scope(this, &cond, guard); 3340 sadd16(cond, rd, rn, rm); 3341 } Sadd16(Register rd,Register rn,Register rm)3342 void Sadd16(Register rd, Register rn, Register rm) { Sadd16(al, rd, rn, rm); } 3343 Sadd8(Condition cond,Register rd,Register rn,Register rm)3344 void Sadd8(Condition cond, Register rd, Register rn, Register rm) { 3345 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3346 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3347 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3348 VIXL_ASSERT(allow_macro_instructions_); 3349 VIXL_ASSERT(OutsideITBlock()); 3350 MacroEmissionCheckScope guard(this); 3351 ITScope it_scope(this, &cond, guard); 3352 sadd8(cond, rd, rn, rm); 3353 } Sadd8(Register rd,Register rn,Register rm)3354 void Sadd8(Register rd, Register rn, Register rm) { Sadd8(al, rd, rn, rm); } 3355 Sasx(Condition cond,Register rd,Register rn,Register rm)3356 void Sasx(Condition cond, Register rd, Register rn, Register rm) { 3357 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3358 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3359 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3360 VIXL_ASSERT(allow_macro_instructions_); 3361 VIXL_ASSERT(OutsideITBlock()); 3362 MacroEmissionCheckScope guard(this); 3363 ITScope it_scope(this, &cond, guard); 3364 sasx(cond, rd, rn, rm); 3365 } Sasx(Register rd,Register rn,Register rm)3366 void Sasx(Register rd, Register rn, Register rm) { Sasx(al, rd, rn, rm); } 3367 Sbc(Condition cond,Register rd,Register rn,const Operand & operand)3368 void Sbc(Condition cond, Register rd, Register rn, const Operand& operand) { 3369 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3370 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3371 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 3372 VIXL_ASSERT(allow_macro_instructions_); 3373 VIXL_ASSERT(OutsideITBlock()); 3374 MacroEmissionCheckScope guard(this); 3375 bool can_use_it = 3376 // SBC<c>{<q>} {<Rdn>,} <Rdn>, <Rm> ; T1 3377 operand.IsPlainRegister() && rn.IsLow() && rd.Is(rn) && 3378 operand.GetBaseRegister().IsLow(); 3379 ITScope it_scope(this, &cond, guard, can_use_it); 3380 sbc(cond, rd, rn, operand); 3381 } Sbc(Register rd,Register rn,const Operand & operand)3382 void Sbc(Register rd, Register rn, const Operand& operand) { 3383 Sbc(al, rd, rn, operand); 3384 } Sbc(FlagsUpdate flags,Condition cond,Register rd,Register rn,const Operand & operand)3385 void Sbc(FlagsUpdate flags, 3386 Condition cond, 3387 Register rd, 3388 Register rn, 3389 const Operand& operand) { 3390 switch (flags) { 3391 case LeaveFlags: 3392 Sbc(cond, rd, rn, operand); 3393 break; 3394 case SetFlags: 3395 Sbcs(cond, rd, rn, operand); 3396 break; 3397 case DontCare: 3398 bool setflags_is_smaller = IsUsingT32() && cond.Is(al) && rd.IsLow() && 3399 rn.Is(rd) && operand.IsPlainRegister() && 3400 operand.GetBaseRegister().IsLow(); 3401 if (setflags_is_smaller) { 3402 Sbcs(cond, rd, rn, operand); 3403 } else { 3404 Sbc(cond, rd, rn, operand); 3405 } 3406 break; 3407 } 3408 } Sbc(FlagsUpdate flags,Register rd,Register rn,const Operand & operand)3409 void Sbc(FlagsUpdate flags, 3410 Register rd, 3411 Register rn, 3412 const Operand& operand) { 3413 Sbc(flags, al, rd, rn, operand); 3414 } 3415 Sbcs(Condition cond,Register rd,Register rn,const Operand & operand)3416 void Sbcs(Condition cond, Register rd, Register rn, const Operand& operand) { 3417 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3418 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3419 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 3420 VIXL_ASSERT(allow_macro_instructions_); 3421 VIXL_ASSERT(OutsideITBlock()); 3422 MacroEmissionCheckScope guard(this); 3423 ITScope it_scope(this, &cond, guard); 3424 sbcs(cond, rd, rn, operand); 3425 } Sbcs(Register rd,Register rn,const Operand & operand)3426 void Sbcs(Register rd, Register rn, const Operand& operand) { 3427 Sbcs(al, rd, rn, operand); 3428 } 3429 Sbfx(Condition cond,Register rd,Register rn,uint32_t lsb,uint32_t width)3430 void Sbfx( 3431 Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) { 3432 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3433 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3434 VIXL_ASSERT(allow_macro_instructions_); 3435 VIXL_ASSERT(OutsideITBlock()); 3436 MacroEmissionCheckScope guard(this); 3437 ITScope it_scope(this, &cond, guard); 3438 sbfx(cond, rd, rn, lsb, width); 3439 } Sbfx(Register rd,Register rn,uint32_t lsb,uint32_t width)3440 void Sbfx(Register rd, Register rn, uint32_t lsb, uint32_t width) { 3441 Sbfx(al, rd, rn, lsb, width); 3442 } 3443 Sdiv(Condition cond,Register rd,Register rn,Register rm)3444 void Sdiv(Condition cond, Register rd, Register rn, Register rm) { 3445 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3446 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3447 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3448 VIXL_ASSERT(allow_macro_instructions_); 3449 VIXL_ASSERT(OutsideITBlock()); 3450 MacroEmissionCheckScope guard(this); 3451 ITScope it_scope(this, &cond, guard); 3452 sdiv(cond, rd, rn, rm); 3453 } Sdiv(Register rd,Register rn,Register rm)3454 void Sdiv(Register rd, Register rn, Register rm) { Sdiv(al, rd, rn, rm); } 3455 Sel(Condition cond,Register rd,Register rn,Register rm)3456 void Sel(Condition cond, Register rd, Register rn, Register rm) { 3457 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3458 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3459 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3460 VIXL_ASSERT(allow_macro_instructions_); 3461 VIXL_ASSERT(OutsideITBlock()); 3462 MacroEmissionCheckScope guard(this); 3463 ITScope it_scope(this, &cond, guard); 3464 sel(cond, rd, rn, rm); 3465 } Sel(Register rd,Register rn,Register rm)3466 void Sel(Register rd, Register rn, Register rm) { Sel(al, rd, rn, rm); } 3467 Shadd16(Condition cond,Register rd,Register rn,Register rm)3468 void Shadd16(Condition cond, Register rd, Register rn, Register rm) { 3469 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3470 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3471 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3472 VIXL_ASSERT(allow_macro_instructions_); 3473 VIXL_ASSERT(OutsideITBlock()); 3474 MacroEmissionCheckScope guard(this); 3475 ITScope it_scope(this, &cond, guard); 3476 shadd16(cond, rd, rn, rm); 3477 } Shadd16(Register rd,Register rn,Register rm)3478 void Shadd16(Register rd, Register rn, Register rm) { 3479 Shadd16(al, rd, rn, rm); 3480 } 3481 Shadd8(Condition cond,Register rd,Register rn,Register rm)3482 void Shadd8(Condition cond, Register rd, Register rn, Register rm) { 3483 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3484 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3485 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3486 VIXL_ASSERT(allow_macro_instructions_); 3487 VIXL_ASSERT(OutsideITBlock()); 3488 MacroEmissionCheckScope guard(this); 3489 ITScope it_scope(this, &cond, guard); 3490 shadd8(cond, rd, rn, rm); 3491 } Shadd8(Register rd,Register rn,Register rm)3492 void Shadd8(Register rd, Register rn, Register rm) { Shadd8(al, rd, rn, rm); } 3493 Shasx(Condition cond,Register rd,Register rn,Register rm)3494 void Shasx(Condition cond, Register rd, Register rn, Register rm) { 3495 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3496 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3497 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3498 VIXL_ASSERT(allow_macro_instructions_); 3499 VIXL_ASSERT(OutsideITBlock()); 3500 MacroEmissionCheckScope guard(this); 3501 ITScope it_scope(this, &cond, guard); 3502 shasx(cond, rd, rn, rm); 3503 } Shasx(Register rd,Register rn,Register rm)3504 void Shasx(Register rd, Register rn, Register rm) { Shasx(al, rd, rn, rm); } 3505 Shsax(Condition cond,Register rd,Register rn,Register rm)3506 void Shsax(Condition cond, Register rd, Register rn, Register rm) { 3507 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3508 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3509 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3510 VIXL_ASSERT(allow_macro_instructions_); 3511 VIXL_ASSERT(OutsideITBlock()); 3512 MacroEmissionCheckScope guard(this); 3513 ITScope it_scope(this, &cond, guard); 3514 shsax(cond, rd, rn, rm); 3515 } Shsax(Register rd,Register rn,Register rm)3516 void Shsax(Register rd, Register rn, Register rm) { Shsax(al, rd, rn, rm); } 3517 Shsub16(Condition cond,Register rd,Register rn,Register rm)3518 void Shsub16(Condition cond, Register rd, Register rn, Register rm) { 3519 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3520 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3521 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3522 VIXL_ASSERT(allow_macro_instructions_); 3523 VIXL_ASSERT(OutsideITBlock()); 3524 MacroEmissionCheckScope guard(this); 3525 ITScope it_scope(this, &cond, guard); 3526 shsub16(cond, rd, rn, rm); 3527 } Shsub16(Register rd,Register rn,Register rm)3528 void Shsub16(Register rd, Register rn, Register rm) { 3529 Shsub16(al, rd, rn, rm); 3530 } 3531 Shsub8(Condition cond,Register rd,Register rn,Register rm)3532 void Shsub8(Condition cond, Register rd, Register rn, Register rm) { 3533 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3534 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3535 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3536 VIXL_ASSERT(allow_macro_instructions_); 3537 VIXL_ASSERT(OutsideITBlock()); 3538 MacroEmissionCheckScope guard(this); 3539 ITScope it_scope(this, &cond, guard); 3540 shsub8(cond, rd, rn, rm); 3541 } Shsub8(Register rd,Register rn,Register rm)3542 void Shsub8(Register rd, Register rn, Register rm) { Shsub8(al, rd, rn, rm); } 3543 Smlabb(Condition cond,Register rd,Register rn,Register rm,Register ra)3544 void Smlabb( 3545 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3546 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3547 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3548 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3549 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3550 VIXL_ASSERT(allow_macro_instructions_); 3551 VIXL_ASSERT(OutsideITBlock()); 3552 MacroEmissionCheckScope guard(this); 3553 ITScope it_scope(this, &cond, guard); 3554 smlabb(cond, rd, rn, rm, ra); 3555 } Smlabb(Register rd,Register rn,Register rm,Register ra)3556 void Smlabb(Register rd, Register rn, Register rm, Register ra) { 3557 Smlabb(al, rd, rn, rm, ra); 3558 } 3559 Smlabt(Condition cond,Register rd,Register rn,Register rm,Register ra)3560 void Smlabt( 3561 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3562 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3563 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3564 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3565 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3566 VIXL_ASSERT(allow_macro_instructions_); 3567 VIXL_ASSERT(OutsideITBlock()); 3568 MacroEmissionCheckScope guard(this); 3569 ITScope it_scope(this, &cond, guard); 3570 smlabt(cond, rd, rn, rm, ra); 3571 } Smlabt(Register rd,Register rn,Register rm,Register ra)3572 void Smlabt(Register rd, Register rn, Register rm, Register ra) { 3573 Smlabt(al, rd, rn, rm, ra); 3574 } 3575 Smlad(Condition cond,Register rd,Register rn,Register rm,Register ra)3576 void Smlad( 3577 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3578 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3579 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3580 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3581 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3582 VIXL_ASSERT(allow_macro_instructions_); 3583 VIXL_ASSERT(OutsideITBlock()); 3584 MacroEmissionCheckScope guard(this); 3585 ITScope it_scope(this, &cond, guard); 3586 smlad(cond, rd, rn, rm, ra); 3587 } Smlad(Register rd,Register rn,Register rm,Register ra)3588 void Smlad(Register rd, Register rn, Register rm, Register ra) { 3589 Smlad(al, rd, rn, rm, ra); 3590 } 3591 Smladx(Condition cond,Register rd,Register rn,Register rm,Register ra)3592 void Smladx( 3593 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3594 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3595 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3596 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3597 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3598 VIXL_ASSERT(allow_macro_instructions_); 3599 VIXL_ASSERT(OutsideITBlock()); 3600 MacroEmissionCheckScope guard(this); 3601 ITScope it_scope(this, &cond, guard); 3602 smladx(cond, rd, rn, rm, ra); 3603 } Smladx(Register rd,Register rn,Register rm,Register ra)3604 void Smladx(Register rd, Register rn, Register rm, Register ra) { 3605 Smladx(al, rd, rn, rm, ra); 3606 } 3607 Smlal(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)3608 void Smlal( 3609 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 3610 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 3611 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 3612 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3613 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3614 VIXL_ASSERT(allow_macro_instructions_); 3615 VIXL_ASSERT(OutsideITBlock()); 3616 MacroEmissionCheckScope guard(this); 3617 ITScope it_scope(this, &cond, guard); 3618 smlal(cond, rdlo, rdhi, rn, rm); 3619 } Smlal(Register rdlo,Register rdhi,Register rn,Register rm)3620 void Smlal(Register rdlo, Register rdhi, Register rn, Register rm) { 3621 Smlal(al, rdlo, rdhi, rn, rm); 3622 } 3623 Smlalbb(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)3624 void Smlalbb( 3625 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 3626 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 3627 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 3628 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3629 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3630 VIXL_ASSERT(allow_macro_instructions_); 3631 VIXL_ASSERT(OutsideITBlock()); 3632 MacroEmissionCheckScope guard(this); 3633 ITScope it_scope(this, &cond, guard); 3634 smlalbb(cond, rdlo, rdhi, rn, rm); 3635 } Smlalbb(Register rdlo,Register rdhi,Register rn,Register rm)3636 void Smlalbb(Register rdlo, Register rdhi, Register rn, Register rm) { 3637 Smlalbb(al, rdlo, rdhi, rn, rm); 3638 } 3639 Smlalbt(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)3640 void Smlalbt( 3641 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 3642 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 3643 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 3644 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3645 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3646 VIXL_ASSERT(allow_macro_instructions_); 3647 VIXL_ASSERT(OutsideITBlock()); 3648 MacroEmissionCheckScope guard(this); 3649 ITScope it_scope(this, &cond, guard); 3650 smlalbt(cond, rdlo, rdhi, rn, rm); 3651 } Smlalbt(Register rdlo,Register rdhi,Register rn,Register rm)3652 void Smlalbt(Register rdlo, Register rdhi, Register rn, Register rm) { 3653 Smlalbt(al, rdlo, rdhi, rn, rm); 3654 } 3655 Smlald(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)3656 void Smlald( 3657 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 3658 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 3659 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 3660 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3661 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3662 VIXL_ASSERT(allow_macro_instructions_); 3663 VIXL_ASSERT(OutsideITBlock()); 3664 MacroEmissionCheckScope guard(this); 3665 ITScope it_scope(this, &cond, guard); 3666 smlald(cond, rdlo, rdhi, rn, rm); 3667 } Smlald(Register rdlo,Register rdhi,Register rn,Register rm)3668 void Smlald(Register rdlo, Register rdhi, Register rn, Register rm) { 3669 Smlald(al, rdlo, rdhi, rn, rm); 3670 } 3671 Smlaldx(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)3672 void Smlaldx( 3673 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 3674 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 3675 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 3676 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3677 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3678 VIXL_ASSERT(allow_macro_instructions_); 3679 VIXL_ASSERT(OutsideITBlock()); 3680 MacroEmissionCheckScope guard(this); 3681 ITScope it_scope(this, &cond, guard); 3682 smlaldx(cond, rdlo, rdhi, rn, rm); 3683 } Smlaldx(Register rdlo,Register rdhi,Register rn,Register rm)3684 void Smlaldx(Register rdlo, Register rdhi, Register rn, Register rm) { 3685 Smlaldx(al, rdlo, rdhi, rn, rm); 3686 } 3687 Smlals(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)3688 void Smlals( 3689 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 3690 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 3691 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 3692 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3693 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3694 VIXL_ASSERT(allow_macro_instructions_); 3695 VIXL_ASSERT(OutsideITBlock()); 3696 MacroEmissionCheckScope guard(this); 3697 ITScope it_scope(this, &cond, guard); 3698 smlals(cond, rdlo, rdhi, rn, rm); 3699 } Smlals(Register rdlo,Register rdhi,Register rn,Register rm)3700 void Smlals(Register rdlo, Register rdhi, Register rn, Register rm) { 3701 Smlals(al, rdlo, rdhi, rn, rm); 3702 } 3703 Smlaltb(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)3704 void Smlaltb( 3705 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 3706 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 3707 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 3708 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3709 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3710 VIXL_ASSERT(allow_macro_instructions_); 3711 VIXL_ASSERT(OutsideITBlock()); 3712 MacroEmissionCheckScope guard(this); 3713 ITScope it_scope(this, &cond, guard); 3714 smlaltb(cond, rdlo, rdhi, rn, rm); 3715 } Smlaltb(Register rdlo,Register rdhi,Register rn,Register rm)3716 void Smlaltb(Register rdlo, Register rdhi, Register rn, Register rm) { 3717 Smlaltb(al, rdlo, rdhi, rn, rm); 3718 } 3719 Smlaltt(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)3720 void Smlaltt( 3721 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 3722 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 3723 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 3724 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3725 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3726 VIXL_ASSERT(allow_macro_instructions_); 3727 VIXL_ASSERT(OutsideITBlock()); 3728 MacroEmissionCheckScope guard(this); 3729 ITScope it_scope(this, &cond, guard); 3730 smlaltt(cond, rdlo, rdhi, rn, rm); 3731 } Smlaltt(Register rdlo,Register rdhi,Register rn,Register rm)3732 void Smlaltt(Register rdlo, Register rdhi, Register rn, Register rm) { 3733 Smlaltt(al, rdlo, rdhi, rn, rm); 3734 } 3735 Smlatb(Condition cond,Register rd,Register rn,Register rm,Register ra)3736 void Smlatb( 3737 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3738 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3739 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3740 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3741 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3742 VIXL_ASSERT(allow_macro_instructions_); 3743 VIXL_ASSERT(OutsideITBlock()); 3744 MacroEmissionCheckScope guard(this); 3745 ITScope it_scope(this, &cond, guard); 3746 smlatb(cond, rd, rn, rm, ra); 3747 } Smlatb(Register rd,Register rn,Register rm,Register ra)3748 void Smlatb(Register rd, Register rn, Register rm, Register ra) { 3749 Smlatb(al, rd, rn, rm, ra); 3750 } 3751 Smlatt(Condition cond,Register rd,Register rn,Register rm,Register ra)3752 void Smlatt( 3753 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3754 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3755 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3756 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3757 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3758 VIXL_ASSERT(allow_macro_instructions_); 3759 VIXL_ASSERT(OutsideITBlock()); 3760 MacroEmissionCheckScope guard(this); 3761 ITScope it_scope(this, &cond, guard); 3762 smlatt(cond, rd, rn, rm, ra); 3763 } Smlatt(Register rd,Register rn,Register rm,Register ra)3764 void Smlatt(Register rd, Register rn, Register rm, Register ra) { 3765 Smlatt(al, rd, rn, rm, ra); 3766 } 3767 Smlawb(Condition cond,Register rd,Register rn,Register rm,Register ra)3768 void Smlawb( 3769 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3770 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3771 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3772 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3773 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3774 VIXL_ASSERT(allow_macro_instructions_); 3775 VIXL_ASSERT(OutsideITBlock()); 3776 MacroEmissionCheckScope guard(this); 3777 ITScope it_scope(this, &cond, guard); 3778 smlawb(cond, rd, rn, rm, ra); 3779 } Smlawb(Register rd,Register rn,Register rm,Register ra)3780 void Smlawb(Register rd, Register rn, Register rm, Register ra) { 3781 Smlawb(al, rd, rn, rm, ra); 3782 } 3783 Smlawt(Condition cond,Register rd,Register rn,Register rm,Register ra)3784 void Smlawt( 3785 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3786 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3787 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3788 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3789 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3790 VIXL_ASSERT(allow_macro_instructions_); 3791 VIXL_ASSERT(OutsideITBlock()); 3792 MacroEmissionCheckScope guard(this); 3793 ITScope it_scope(this, &cond, guard); 3794 smlawt(cond, rd, rn, rm, ra); 3795 } Smlawt(Register rd,Register rn,Register rm,Register ra)3796 void Smlawt(Register rd, Register rn, Register rm, Register ra) { 3797 Smlawt(al, rd, rn, rm, ra); 3798 } 3799 Smlsd(Condition cond,Register rd,Register rn,Register rm,Register ra)3800 void Smlsd( 3801 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3802 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3803 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3804 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3805 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3806 VIXL_ASSERT(allow_macro_instructions_); 3807 VIXL_ASSERT(OutsideITBlock()); 3808 MacroEmissionCheckScope guard(this); 3809 ITScope it_scope(this, &cond, guard); 3810 smlsd(cond, rd, rn, rm, ra); 3811 } Smlsd(Register rd,Register rn,Register rm,Register ra)3812 void Smlsd(Register rd, Register rn, Register rm, Register ra) { 3813 Smlsd(al, rd, rn, rm, ra); 3814 } 3815 Smlsdx(Condition cond,Register rd,Register rn,Register rm,Register ra)3816 void Smlsdx( 3817 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3818 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3819 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3820 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3821 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3822 VIXL_ASSERT(allow_macro_instructions_); 3823 VIXL_ASSERT(OutsideITBlock()); 3824 MacroEmissionCheckScope guard(this); 3825 ITScope it_scope(this, &cond, guard); 3826 smlsdx(cond, rd, rn, rm, ra); 3827 } Smlsdx(Register rd,Register rn,Register rm,Register ra)3828 void Smlsdx(Register rd, Register rn, Register rm, Register ra) { 3829 Smlsdx(al, rd, rn, rm, ra); 3830 } 3831 Smlsld(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)3832 void Smlsld( 3833 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 3834 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 3835 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 3836 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3837 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3838 VIXL_ASSERT(allow_macro_instructions_); 3839 VIXL_ASSERT(OutsideITBlock()); 3840 MacroEmissionCheckScope guard(this); 3841 ITScope it_scope(this, &cond, guard); 3842 smlsld(cond, rdlo, rdhi, rn, rm); 3843 } Smlsld(Register rdlo,Register rdhi,Register rn,Register rm)3844 void Smlsld(Register rdlo, Register rdhi, Register rn, Register rm) { 3845 Smlsld(al, rdlo, rdhi, rn, rm); 3846 } 3847 Smlsldx(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)3848 void Smlsldx( 3849 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 3850 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 3851 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 3852 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3853 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3854 VIXL_ASSERT(allow_macro_instructions_); 3855 VIXL_ASSERT(OutsideITBlock()); 3856 MacroEmissionCheckScope guard(this); 3857 ITScope it_scope(this, &cond, guard); 3858 smlsldx(cond, rdlo, rdhi, rn, rm); 3859 } Smlsldx(Register rdlo,Register rdhi,Register rn,Register rm)3860 void Smlsldx(Register rdlo, Register rdhi, Register rn, Register rm) { 3861 Smlsldx(al, rdlo, rdhi, rn, rm); 3862 } 3863 Smmla(Condition cond,Register rd,Register rn,Register rm,Register ra)3864 void Smmla( 3865 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3866 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3867 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3868 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3869 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3870 VIXL_ASSERT(allow_macro_instructions_); 3871 VIXL_ASSERT(OutsideITBlock()); 3872 MacroEmissionCheckScope guard(this); 3873 ITScope it_scope(this, &cond, guard); 3874 smmla(cond, rd, rn, rm, ra); 3875 } Smmla(Register rd,Register rn,Register rm,Register ra)3876 void Smmla(Register rd, Register rn, Register rm, Register ra) { 3877 Smmla(al, rd, rn, rm, ra); 3878 } 3879 Smmlar(Condition cond,Register rd,Register rn,Register rm,Register ra)3880 void Smmlar( 3881 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3882 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3883 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3884 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3885 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3886 VIXL_ASSERT(allow_macro_instructions_); 3887 VIXL_ASSERT(OutsideITBlock()); 3888 MacroEmissionCheckScope guard(this); 3889 ITScope it_scope(this, &cond, guard); 3890 smmlar(cond, rd, rn, rm, ra); 3891 } Smmlar(Register rd,Register rn,Register rm,Register ra)3892 void Smmlar(Register rd, Register rn, Register rm, Register ra) { 3893 Smmlar(al, rd, rn, rm, ra); 3894 } 3895 Smmls(Condition cond,Register rd,Register rn,Register rm,Register ra)3896 void Smmls( 3897 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3898 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3899 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3900 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3901 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3902 VIXL_ASSERT(allow_macro_instructions_); 3903 VIXL_ASSERT(OutsideITBlock()); 3904 MacroEmissionCheckScope guard(this); 3905 ITScope it_scope(this, &cond, guard); 3906 smmls(cond, rd, rn, rm, ra); 3907 } Smmls(Register rd,Register rn,Register rm,Register ra)3908 void Smmls(Register rd, Register rn, Register rm, Register ra) { 3909 Smmls(al, rd, rn, rm, ra); 3910 } 3911 Smmlsr(Condition cond,Register rd,Register rn,Register rm,Register ra)3912 void Smmlsr( 3913 Condition cond, Register rd, Register rn, Register rm, Register ra) { 3914 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3915 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3916 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3917 VIXL_ASSERT(!AliasesAvailableScratchRegister(ra)); 3918 VIXL_ASSERT(allow_macro_instructions_); 3919 VIXL_ASSERT(OutsideITBlock()); 3920 MacroEmissionCheckScope guard(this); 3921 ITScope it_scope(this, &cond, guard); 3922 smmlsr(cond, rd, rn, rm, ra); 3923 } Smmlsr(Register rd,Register rn,Register rm,Register ra)3924 void Smmlsr(Register rd, Register rn, Register rm, Register ra) { 3925 Smmlsr(al, rd, rn, rm, ra); 3926 } 3927 Smmul(Condition cond,Register rd,Register rn,Register rm)3928 void Smmul(Condition cond, Register rd, Register rn, Register rm) { 3929 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3930 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3931 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3932 VIXL_ASSERT(allow_macro_instructions_); 3933 VIXL_ASSERT(OutsideITBlock()); 3934 MacroEmissionCheckScope guard(this); 3935 ITScope it_scope(this, &cond, guard); 3936 smmul(cond, rd, rn, rm); 3937 } Smmul(Register rd,Register rn,Register rm)3938 void Smmul(Register rd, Register rn, Register rm) { Smmul(al, rd, rn, rm); } 3939 Smmulr(Condition cond,Register rd,Register rn,Register rm)3940 void Smmulr(Condition cond, Register rd, Register rn, Register rm) { 3941 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3942 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3943 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3944 VIXL_ASSERT(allow_macro_instructions_); 3945 VIXL_ASSERT(OutsideITBlock()); 3946 MacroEmissionCheckScope guard(this); 3947 ITScope it_scope(this, &cond, guard); 3948 smmulr(cond, rd, rn, rm); 3949 } Smmulr(Register rd,Register rn,Register rm)3950 void Smmulr(Register rd, Register rn, Register rm) { Smmulr(al, rd, rn, rm); } 3951 Smuad(Condition cond,Register rd,Register rn,Register rm)3952 void Smuad(Condition cond, Register rd, Register rn, Register rm) { 3953 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3954 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3955 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3956 VIXL_ASSERT(allow_macro_instructions_); 3957 VIXL_ASSERT(OutsideITBlock()); 3958 MacroEmissionCheckScope guard(this); 3959 ITScope it_scope(this, &cond, guard); 3960 smuad(cond, rd, rn, rm); 3961 } Smuad(Register rd,Register rn,Register rm)3962 void Smuad(Register rd, Register rn, Register rm) { Smuad(al, rd, rn, rm); } 3963 Smuadx(Condition cond,Register rd,Register rn,Register rm)3964 void Smuadx(Condition cond, Register rd, Register rn, Register rm) { 3965 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3966 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3967 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3968 VIXL_ASSERT(allow_macro_instructions_); 3969 VIXL_ASSERT(OutsideITBlock()); 3970 MacroEmissionCheckScope guard(this); 3971 ITScope it_scope(this, &cond, guard); 3972 smuadx(cond, rd, rn, rm); 3973 } Smuadx(Register rd,Register rn,Register rm)3974 void Smuadx(Register rd, Register rn, Register rm) { Smuadx(al, rd, rn, rm); } 3975 Smulbb(Condition cond,Register rd,Register rn,Register rm)3976 void Smulbb(Condition cond, Register rd, Register rn, Register rm) { 3977 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3978 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3979 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3980 VIXL_ASSERT(allow_macro_instructions_); 3981 VIXL_ASSERT(OutsideITBlock()); 3982 MacroEmissionCheckScope guard(this); 3983 ITScope it_scope(this, &cond, guard); 3984 smulbb(cond, rd, rn, rm); 3985 } Smulbb(Register rd,Register rn,Register rm)3986 void Smulbb(Register rd, Register rn, Register rm) { Smulbb(al, rd, rn, rm); } 3987 Smulbt(Condition cond,Register rd,Register rn,Register rm)3988 void Smulbt(Condition cond, Register rd, Register rn, Register rm) { 3989 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 3990 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 3991 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 3992 VIXL_ASSERT(allow_macro_instructions_); 3993 VIXL_ASSERT(OutsideITBlock()); 3994 MacroEmissionCheckScope guard(this); 3995 ITScope it_scope(this, &cond, guard); 3996 smulbt(cond, rd, rn, rm); 3997 } Smulbt(Register rd,Register rn,Register rm)3998 void Smulbt(Register rd, Register rn, Register rm) { Smulbt(al, rd, rn, rm); } 3999 Smull(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)4000 void Smull( 4001 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 4002 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 4003 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 4004 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4005 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 4006 VIXL_ASSERT(allow_macro_instructions_); 4007 VIXL_ASSERT(OutsideITBlock()); 4008 MacroEmissionCheckScope guard(this); 4009 ITScope it_scope(this, &cond, guard); 4010 smull(cond, rdlo, rdhi, rn, rm); 4011 } Smull(Register rdlo,Register rdhi,Register rn,Register rm)4012 void Smull(Register rdlo, Register rdhi, Register rn, Register rm) { 4013 Smull(al, rdlo, rdhi, rn, rm); 4014 } Smull(FlagsUpdate flags,Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)4015 void Smull(FlagsUpdate flags, 4016 Condition cond, 4017 Register rdlo, 4018 Register rdhi, 4019 Register rn, 4020 Register rm) { 4021 switch (flags) { 4022 case LeaveFlags: 4023 Smull(cond, rdlo, rdhi, rn, rm); 4024 break; 4025 case SetFlags: 4026 Smulls(cond, rdlo, rdhi, rn, rm); 4027 break; 4028 case DontCare: 4029 Smull(cond, rdlo, rdhi, rn, rm); 4030 break; 4031 } 4032 } Smull(FlagsUpdate flags,Register rdlo,Register rdhi,Register rn,Register rm)4033 void Smull(FlagsUpdate flags, 4034 Register rdlo, 4035 Register rdhi, 4036 Register rn, 4037 Register rm) { 4038 Smull(flags, al, rdlo, rdhi, rn, rm); 4039 } 4040 Smulls(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)4041 void Smulls( 4042 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) { 4043 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdlo)); 4044 VIXL_ASSERT(!AliasesAvailableScratchRegister(rdhi)); 4045 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4046 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 4047 VIXL_ASSERT(allow_macro_instructions_); 4048 VIXL_ASSERT(OutsideITBlock()); 4049 MacroEmissionCheckScope guard(this); 4050 ITScope it_scope(this, &cond, guard); 4051 smulls(cond, rdlo, rdhi, rn, rm); 4052 } Smulls(Register rdlo,Register rdhi,Register rn,Register rm)4053 void Smulls(Register rdlo, Register rdhi, Register rn, Register rm) { 4054 Smulls(al, rdlo, rdhi, rn, rm); 4055 } 4056 Smultb(Condition cond,Register rd,Register rn,Register rm)4057 void Smultb(Condition cond, Register rd, Register rn, Register rm) { 4058 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4059 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4060 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 4061 VIXL_ASSERT(allow_macro_instructions_); 4062 VIXL_ASSERT(OutsideITBlock()); 4063 MacroEmissionCheckScope guard(this); 4064 ITScope it_scope(this, &cond, guard); 4065 smultb(cond, rd, rn, rm); 4066 } Smultb(Register rd,Register rn,Register rm)4067 void Smultb(Register rd, Register rn, Register rm) { Smultb(al, rd, rn, rm); } 4068 Smultt(Condition cond,Register rd,Register rn,Register rm)4069 void Smultt(Condition cond, Register rd, Register rn, Register rm) { 4070 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4071 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4072 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 4073 VIXL_ASSERT(allow_macro_instructions_); 4074 VIXL_ASSERT(OutsideITBlock()); 4075 MacroEmissionCheckScope guard(this); 4076 ITScope it_scope(this, &cond, guard); 4077 smultt(cond, rd, rn, rm); 4078 } Smultt(Register rd,Register rn,Register rm)4079 void Smultt(Register rd, Register rn, Register rm) { Smultt(al, rd, rn, rm); } 4080 Smulwb(Condition cond,Register rd,Register rn,Register rm)4081 void Smulwb(Condition cond, Register rd, Register rn, Register rm) { 4082 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4083 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4084 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 4085 VIXL_ASSERT(allow_macro_instructions_); 4086 VIXL_ASSERT(OutsideITBlock()); 4087 MacroEmissionCheckScope guard(this); 4088 ITScope it_scope(this, &cond, guard); 4089 smulwb(cond, rd, rn, rm); 4090 } Smulwb(Register rd,Register rn,Register rm)4091 void Smulwb(Register rd, Register rn, Register rm) { Smulwb(al, rd, rn, rm); } 4092 Smulwt(Condition cond,Register rd,Register rn,Register rm)4093 void Smulwt(Condition cond, Register rd, Register rn, Register rm) { 4094 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4095 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4096 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 4097 VIXL_ASSERT(allow_macro_instructions_); 4098 VIXL_ASSERT(OutsideITBlock()); 4099 MacroEmissionCheckScope guard(this); 4100 ITScope it_scope(this, &cond, guard); 4101 smulwt(cond, rd, rn, rm); 4102 } Smulwt(Register rd,Register rn,Register rm)4103 void Smulwt(Register rd, Register rn, Register rm) { Smulwt(al, rd, rn, rm); } 4104 Smusd(Condition cond,Register rd,Register rn,Register rm)4105 void Smusd(Condition cond, Register rd, Register rn, Register rm) { 4106 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4107 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4108 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 4109 VIXL_ASSERT(allow_macro_instructions_); 4110 VIXL_ASSERT(OutsideITBlock()); 4111 MacroEmissionCheckScope guard(this); 4112 ITScope it_scope(this, &cond, guard); 4113 smusd(cond, rd, rn, rm); 4114 } Smusd(Register rd,Register rn,Register rm)4115 void Smusd(Register rd, Register rn, Register rm) { Smusd(al, rd, rn, rm); } 4116 Smusdx(Condition cond,Register rd,Register rn,Register rm)4117 void Smusdx(Condition cond, Register rd, Register rn, Register rm) { 4118 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4119 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4120 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 4121 VIXL_ASSERT(allow_macro_instructions_); 4122 VIXL_ASSERT(OutsideITBlock()); 4123 MacroEmissionCheckScope guard(this); 4124 ITScope it_scope(this, &cond, guard); 4125 smusdx(cond, rd, rn, rm); 4126 } Smusdx(Register rd,Register rn,Register rm)4127 void Smusdx(Register rd, Register rn, Register rm) { Smusdx(al, rd, rn, rm); } 4128 Ssat(Condition cond,Register rd,uint32_t imm,const Operand & operand)4129 void Ssat(Condition cond, Register rd, uint32_t imm, const Operand& operand) { 4130 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4131 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 4132 VIXL_ASSERT(allow_macro_instructions_); 4133 VIXL_ASSERT(OutsideITBlock()); 4134 MacroEmissionCheckScope guard(this); 4135 ITScope it_scope(this, &cond, guard); 4136 ssat(cond, rd, imm, operand); 4137 } Ssat(Register rd,uint32_t imm,const Operand & operand)4138 void Ssat(Register rd, uint32_t imm, const Operand& operand) { 4139 Ssat(al, rd, imm, operand); 4140 } 4141 Ssat16(Condition cond,Register rd,uint32_t imm,Register rn)4142 void Ssat16(Condition cond, Register rd, uint32_t imm, Register rn) { 4143 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4144 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4145 VIXL_ASSERT(allow_macro_instructions_); 4146 VIXL_ASSERT(OutsideITBlock()); 4147 MacroEmissionCheckScope guard(this); 4148 ITScope it_scope(this, &cond, guard); 4149 ssat16(cond, rd, imm, rn); 4150 } Ssat16(Register rd,uint32_t imm,Register rn)4151 void Ssat16(Register rd, uint32_t imm, Register rn) { 4152 Ssat16(al, rd, imm, rn); 4153 } 4154 Ssax(Condition cond,Register rd,Register rn,Register rm)4155 void Ssax(Condition cond, Register rd, Register rn, Register rm) { 4156 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4157 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4158 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 4159 VIXL_ASSERT(allow_macro_instructions_); 4160 VIXL_ASSERT(OutsideITBlock()); 4161 MacroEmissionCheckScope guard(this); 4162 ITScope it_scope(this, &cond, guard); 4163 ssax(cond, rd, rn, rm); 4164 } Ssax(Register rd,Register rn,Register rm)4165 void Ssax(Register rd, Register rn, Register rm) { Ssax(al, rd, rn, rm); } 4166 Ssub16(Condition cond,Register rd,Register rn,Register rm)4167 void Ssub16(Condition cond, Register rd, Register rn, Register rm) { 4168 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4169 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4170 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 4171 VIXL_ASSERT(allow_macro_instructions_); 4172 VIXL_ASSERT(OutsideITBlock()); 4173 MacroEmissionCheckScope guard(this); 4174 ITScope it_scope(this, &cond, guard); 4175 ssub16(cond, rd, rn, rm); 4176 } Ssub16(Register rd,Register rn,Register rm)4177 void Ssub16(Register rd, Register rn, Register rm) { Ssub16(al, rd, rn, rm); } 4178 Ssub8(Condition cond,Register rd,Register rn,Register rm)4179 void Ssub8(Condition cond, Register rd, Register rn, Register rm) { 4180 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4181 VIXL_ASSERT(!AliasesAvailableScratchRegister(rn)); 4182 VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); 4183 VIXL_ASSERT(allow_macro_instructions_); 4184 VIXL_ASSERT(OutsideITBlock()); 4185 MacroEmissionCheckScope guard(this); 4186 ITScope it_scope(this, &cond, guard); 4187 ssub8(cond, rd, rn, rm); 4188 } Ssub8(Register rd,Register rn,Register rm)4189 void Ssub8(Register rd, Register rn, Register rm) { Ssub8(al, rd, rn, rm); } 4190 Stl(Condition cond,Register rt,const MemOperand & operand)4191 void Stl(Condition cond, Register rt, const MemOperand& operand) { 4192 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 4193 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 4194 VIXL_ASSERT(allow_macro_instructions_); 4195 VIXL_ASSERT(OutsideITBlock()); 4196 MacroEmissionCheckScope guard(this); 4197 ITScope it_scope(this, &cond, guard); 4198 stl(cond, rt, operand); 4199 } Stl(Register rt,const MemOperand & operand)4200 void Stl(Register rt, const MemOperand& operand) { Stl(al, rt, operand); } 4201 Stlb(Condition cond,Register rt,const MemOperand & operand)4202 void Stlb(Condition cond, Register rt, const MemOperand& operand) { 4203 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 4204 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 4205 VIXL_ASSERT(allow_macro_instructions_); 4206 VIXL_ASSERT(OutsideITBlock()); 4207 MacroEmissionCheckScope guard(this); 4208 ITScope it_scope(this, &cond, guard); 4209 stlb(cond, rt, operand); 4210 } Stlb(Register rt,const MemOperand & operand)4211 void Stlb(Register rt, const MemOperand& operand) { Stlb(al, rt, operand); } 4212 Stlex(Condition cond,Register rd,Register rt,const MemOperand & operand)4213 void Stlex(Condition cond, 4214 Register rd, 4215 Register rt, 4216 const MemOperand& operand) { 4217 VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); 4218 VIXL_ASSERT(!AliasesAvailableScratchRegister(rt)); 4219 VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); 4220 VIXL_ASSERT(allow_macro_instructions_); 4221 VIXL_ASSERT(OutsideITBlock()); 4222 MacroEmissionCheckScope guard(this); 4223 ITScope it_scope(this, &cond, guard); 4224 stlex(cond, rd, rt, operand); 4225 } Stlex(Register rd,Register rt,const MemOperand & operand)4226