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