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