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