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